首页
/ LangGraph.js 聊天机器人模板:用 LangGraph Studio 构建、调试并扩展 Agent 项目

LangGraph.js 聊天机器人模板:用 LangGraph Studio 构建、调试并扩展 Agent 项目

2026-09-05 18:50:48作者:贡沫苏Truman

本文基于 libs/cli/js-examples/ 目录下的 LangGraph.js 新项目模板 README,讲解如何搭建一个带持久化会话记忆的最简聊天机器人模板,并在 LangGraph Studio 中完成热重载调试、状态回放与迭代扩展。读完后,你将掌握该模板的完整工程结构(状态注解、StateGraph 图构建、langgraph.json 配置)、本地启动流程,以及接入 LLM、新增节点/工具、编写单元与集成测试的具体做法。

LangGraph Studio 中的图视图界面

模板定位:一个面向 LangGraph Studio 的最简聊天机器人

该模板演示了一个用 LangGraph.js 实现的简单聊天机器人,专为 LangGraph Studio 设计。它维持持久化会话记忆,可以在多轮交互中保持上下文连贯。README 对机器人行为的描述是:

  1. 接收用户 message 作为输入;
  2. 维护对话历史(conversation history);
  3. 返回占位响应,并更新对话历史。

模板的核心逻辑位于 graph.ts,是一个“响应用户提问、同时保留前文上下文”的聊天机器人骨架。README 明确强调:它提供的是一个可轻松定制和扩展的基础,用于构建更复杂的对话型 Agent。官方 JavaScript/TypeScript 文档可作为概念参考,且 LangGraph Studio 与 LangSmith 集成以提供追踪(tracing)与团队协作能力。

工程结构与核心文件

从仓库实际目录看,该模板包含以下关键文件:

文件 作用
src/agent/graph.ts 图的核心逻辑:节点、边、条件路由、导出编译后的 graph
src/agent/state.ts 通过 Annotation.Root 定义图状态与 reducer
langgraph.json LangGraph 应用配置:图入口、Node 版本、env 文件、依赖
package.json 依赖、脚本(build/test/lint)与包管理器声明
.env.example 环境变量文件模板(当前仅注释占位)
tests/agent.test.ts 路由函数单元测试
tests/graph.int.test.ts 整图 invoke 集成测试
jest.config.js ESM + ts-jest 的 Jest 配置
tsconfig.json 严格模式 TypeScript 配置

其中 langgraph.json 是 Studio/CLI 识别应用的入口配置,实际内容如下:

{
  "$schema": "https://langgra.ph/schema.json",
  "node_version": "20",
  "graphs": {
    "agent": "./src/agent/graph.ts:graph"
  },
  "env": ".env",
  "dependencies": ["."]
}

各字段含义:

  • node_version: "20":声明运行该 JS 应用所需的 Node.js 大版本为 20;
  • graphs:名为 agent 的图指向 ./src/agent/graph.ts 模块导出的 graph 符号(文件:导出名 格式,与 graph.tsexport const graph = builder.compile() 对应);
  • env: ".env":声明从根目录 .env 读取环境变量;
  • dependencies: ["."]:依赖根包本身,即由 package.json 管理依赖安装。

package.json 声明了 packageManager: "yarn@1.22.22""type": "module",核心运行时依赖为 @langchain/core ^1.2.4@langchain/langgraph ^1.4.8(并通过 resolutions 锁定 @langchain/langgraph-checkpoint1.0.4)。脚本方面:yarn build 执行 tscyarn test 只跑 *.test.ts(排除 *.int.test.ts);yarn test:int 只跑 *.int.test.tslint:langgraph-json 通过 node scripts/checkLanggraphPaths.js 校验 langgraph.json 中路径;test:all 将单测、集成测试与该校验串联执行。

状态定义:AnnotationmessagesStateReducer

state.ts 定义了模板唯一的状态字段 messages

export const StateAnnotation = Annotation.Root({
  messages: Annotation<BaseMessage[], BaseMessageLike[]>({
    reducer: messagesStateReducer,
    default: () => [],
  }),
});

根据源码注释,StateAnnotation 定义了三件事:

  1. 通道结构:节点间读写哪些“channel”及其类型;
  2. 默认值messages 默认为空数组 []
  3. reducer:决定更新如何应用到状态。这里使用 messagesStateReducer,它会把两列消息按 ID 合并——新消息没有 ID 时 LangGraph 会自动分配一个;默认行为是“追加(append-only)”,除非新消息与已有消息 ID 相同,此时新消息替换旧消息。

messages 字段的类型是 BaseMessage[](读类型),但节点返回值类型放宽为 BaseMessageLike[],即带 role/content 的普通对象也会被 messagesStateReducer 自动转换为 LangChain 消息类——这正是 graph.ts 中直接返回 { role: "assistant", content: ... } 占位消息而无需构造完整消息对象的原因。源码注释还给出了 messages 的典型累积模式:HumanMessage(用户输入)→ 带 .tool_calls 的 AIMessage(选工具)→ ToolMessage(工具结果),循环若干轮后以无工具调用的 AIMessage 收尾,供扩展时参考。

图构建:节点、边与条件路由

graph.ts 展示了 LangGraph.js StateGraph 的最小完整用法,结构如下:

const builder = new StateGraph(StateAnnotation)
  .addNode("callModel", callModel)
  .addEdge("__start__", "callModel")
  .addConditionalEdges("callModel", route);

export const graph = builder.compile();
graph.name = "New Agent";

三个要点(均见 graph.ts 的源码注释):

  1. 节点callModel 承载主要逻辑,签名接收 (state, config),必须返回 StateAnnotation.Update 类型的子集。当前实现打印当前状态并返回一条固定的 assistant 占位消息:

    console.log("Current state:", state);
    return {
      messages: [
        { role: "assistant", content: `Hi there! How are you?` },
      ],
    };
    

    函数体内的大段注释给出了两种接入真实 LLM 的示例:通过 LangChain.js 包装器(npm i @langchain/anthropicnew ChatAnthropic(...)model.invoke(state.messages)),或绕过 LangChain 直接调用 SDK(npm i openaiopenai.chat.completions.create({ messages: [...], model: "gpt-4o-mini" }))。

  2. 普通边addEdge("__start__", "callModel") 表示“节点 A 完成后总是转到节点 B”;__start____end__ 是始终存在的虚拟节点,分别代表图的起点与终点。

  3. 条件边addConditionalEdges("callModel", route) 用路由函数动态决定去向。本模板的 route 逻辑是:若 state.messages.length > 0 返回 "__end__" 结束,否则回到 "callModel"。配合 callModel 总会追加消息的实现,该条件边在首轮执行后即进入 __end__,使每次 invoke 恰好产出一条 assistant 回复。

本地运行:Getting Started

README 的启动流程以“已安装 LangGraph Studio”为前提,共三步:

  1. 创建 .env 文件。模板默认不需要任何环境变量,但定制时通常会添加(例如 ANTHROPIC_API_KEYOPENAI_API_KEY):

    cp .env.example .env
    

    仓库中的 .env.example 当前只有三行注释占位(“Copy this over: cp .env.example .env / Then modify to suit your needs”),印证了“默认为空、按需填充”的设计。

  2. 在 LangGraph Studio 中打开该目录

  3. 按需修改代码

此外,README 中保留了两段由 langgraph template lock 自动生成的 HTML 注释(“Setup instruction auto-generated by langgraph template lock. DO NOT EDIT MANUALLY” 与 “Configuration auto-generated by langgraph template lock”),后者内嵌了该模板的配置 schema:

{
  "config_schemas": {
    "agent": {
      "type": "object",
      "properties": {}
    }
  }
}

从该 schema 结构看,agent 图当前未向 Studio 暴露任何可配置参数(properties 为空),即图的全部行为由代码决定。注释同时提醒该块内容禁止手动编辑,应通过模板工具链再生成。

在 LangGraph Studio 中调试与迭代

README 的 Development 章节描述了模板在 Studio 中的迭代工作方式:

  • 编辑历史状态重跑:调试特定节点时,可以编辑过往状态(edit past state)并从该状态重新运行应用;
  • 热重载:本地代码变更会自动生效(hot reload),修改 graph.ts 后无需重启;
  • 线程语义:后续请求会追加到同一线程(thread),会话历史随之累积;点击界面右上角的 + 按钮可以新建一个完全清空历史的新线程;
  • 推荐实验:修改系统提示词赋予聊天机器人独特个性、为更复杂的对话流新增节点、实现条件逻辑以处理不同用户输入;
  • LangSmith 集成:Studio 与 LangSmith 集成后可做更深入的全链路追踪与团队协作分析。

结合模板代码可推断调试路径:由于占位节点会把 console.log("Current state:", state) 打到服务端日志,在 Studio 中观察线程消息变化配合日志即可验证“状态 → 节点 → 更新”的完整闭环;而“编辑过去状态重跑”能力依赖于 LangGraph 的 checkpoint 机制(模板通过 resolutions 固定了 @langchain/langgraph-checkpoint 版本,见 package.json)。

扩展模板的四个方向

README 的 “How to customize” 给出了明确的扩展路径:

  1. 接入 LLM 调用:从 LangChain.js 生态选择并安装一个聊天模型包装器(如上文注释中的 @langchain/anthropic),或者完全不用 LangChain.js、直接调用模型 SDK;
  2. 扩展图结构:修改 graph.ts 增加节点、边,或改变对话流程——这是模板的核心定制点;
  3. 添加工具/函数:接入自定义 tools 增强机器人能力;
  4. 实现 RAG:集成外部 API 或数据库实现检索增强生成,使回答更定制化;
  5. 业务分支:为特定类型的用户查询或任务实现额外处理逻辑。

测试体系:路由单测与整图集成测试

模板内置两类测试,可直接作为扩展时的回归基线:

  • 路由单元测试 tests/agent.test.ts:直接导入 route 函数,断言空消息状态下 route({ messages: [] }) 返回 "callModel",验证“无消息时回环”的分支;
  • 整图集成测试 tests/graph.int.test.ts:以 "What is the capital of France?" 为输入调用 graph.invoke({ input }),断言结果对象包含非空 messages 数组,且最后一条消息内容包含 "hi"(对应占位响应 “Hi there! How are you?”),超时设为 30 秒。

测试运行环境由 jest.config.js 决定:ts-jest 的 ESM 预设、extensionsToTreatAsEsm: [".ts"]moduleNameMapper./xx.js 映射到 ./xx(适配 ESM 下 .ts 源文件导入 .js 后缀的写法)、setupFiles: ["dotenv/config"] 加载环境变量、全局 testTimeout 20 秒。tsconfig.json 则开启了 strictnoUnusedLocalsnoUnusedParameters 等严格选项,模块体系为 NodeNext

小结与适用边界

该模板的价值在于把“LangGraph Studio 可运行的最简 JS 应用”压到了最小文件集:一份 langgraph.json 入口配置、一个 state.ts 状态定义、一个 graph.ts 图定义,加上单测/集成测试与 ESLint/Prettier/Jest 全套工程配置。其适用前提是本地已安装 LangGraph Studio 与 Node.js 20 环境;默认不依赖任何外部 API Key。在此骨架上替换占位节点为真实 LLM 调用、按需扩展 StateAnnotation 字段(源码注释也预留了 additionalField 示例)与图拓扑,即可获得一个可持续迭代的对话型 Agent 工程。

登录后查看全文
热门项目推荐
相关项目推荐