转写说明

本文基于已校验的公开原文进行结构化转写与事实梳理,非原文转载。 转写保留可核验的技术事实,并将工程建议与来源观点明确分开。

核心结论

多 Agent 拆分本质是 token 开销与信息干扰的工程权衡。LangChain 负责线性工作流编排和基础模块,LangGraph 专注于网状工作流编排,处理多 Agent 协作中的分支、循环、状态持久化和人工中断场景。两者的关系是配合而非替代。

LangGraph 的核心架构由 State、节点、边三要素构成:State 声明状态 schema 并定义 reducer 规则,节点是返回部分状态更新的普通函数,边负责连接节点并控制流转方向。

能力机制

State 声明:通过 Annotation.Root 定义状态结构,字段级 reducer 决定状态合并方式,default 提供初始值。新值覆盖旧值是常见的 reducer 实现模式。

分支路由:在节点内完成条件判断并将结果写入 state,条件边根据 state 中的路由标识将执行流导向对应节点。关注点分离使判断逻辑与业务逻辑解耦。

循环实现:没有专门的循环 API,条件边指向自身即形成自环。需要配合计数器和终止条件避免死循环,三要素为自环、计数、终止条件。

状态持久化:通过 compile 时挂载 checkpointer 实现,invoke 时传入 thread_id 标识会话。同一个 thread_id 连续调用会累加状态,换 thread_id 则从初始值重新开始。MemorySaver 存储在内存中,失败后可恢复;生产环境可替换为 sqlite、redis 等持久化方案。

人工中断:节点内调用 interrupt() 暂停执行并抛出 payload,调用方从返回结果的 __interrupt__ 字段读取中断信息,使用 Command({resume}) 配合同一 thread_id 恢复执行。interrupt 依赖 checkpointer 保存暂停状态。

快速开始

最小图的构建流程:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import { Annotation, StateGraph, START, END } from '@langchain/langgraph'

const StateAnnotation = Annotation.Root({
  text: Annotation({
    reducer: (_prev, next) => next,
    default: () => "",
  }),
})

const step1 = (state) => ({ text: `${state.text} -> step1` })
const step2 = (state) => ({ text: `${state.text} -> step2` })

const graph = new StateGraph(StateAnnotation)
  .addNode("step1", step1)
  .addNode("step2", step2)
  .addEdge(START, "step1")
  .addEdge("step1", "step2")
  .addEdge("step2", END)
  .compile()

// 可视化导出
const drawable = await graph.getGraphAsync()
console.log(drawable.drawMermaid({ withStyles: true }))

// 执行
const result = await graph.invoke({ text: "hello" })

持久化需要挂载 checkpointer:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
import { MemorySaver } from '@langchain/langgraph'

const checkpointer = new MemorySaver()
const graph = new StateGraph(StateAnnotation)
  .addNode("visit", visit)
  .addEdge(START, "visit")
  .addEdge("visit", END)
  .compile({ checkpointer })

const config = { configurable: { thread_id: "用户_小张" } }
await graph.invoke({}, config)

中断恢复示例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
const waitConfirm = (state) => {
  const text = interrupt({
    hint: "输入确认或备注后回车",
    actionSummary: state.actionSummary,
  })
  return { useInput: String(text) }
}

const paused = await graph.invoke({}, config)
const line = await readLine() // 人工确认
const done = await graph.invoke(new Command({ resume: line }), config)

适用边界

LangGraph 适用于需要多 Agent 协作的工作流,每个 Agent 可携带精简 prompt 减少 token 消耗并降低干扰。网状编排能力适合包含分支判断、重试逻辑、长期状态维护和人工审批节点的应用场景。

不适合纯线性任务,LangChain 的链式结构已能覆盖的场景无需引入 LangGraph 的额外复杂度。

interrupt 机制要求调用方具备接收暂停、读取状态、等待人工输入、恢复执行的能力,纯粹的自动化流程无法直接使用该特性。

状态持久化依赖 checkpointer,缺少该配置时中断后无法恢复。MemorySaver 仅存储在内存中,服务重启会丢失状态。

所有示例代码均为静态整理,未经过运行验证。实际使用需要根据 LangGraph 版本调整 API 调用方式。

核验清单

  • State 的每个字段都定义了 reducer 和 default
  • 节点返回值是部分状态更新,而非完整 state
  • 条件函数返回值与映射表 key 一一对应
  • 自环包含终止条件,不会形成死循环
  • 需要持久化的图已挂载 checkpointer,invoke 时携带 thread_id
  • interrupt 恢复使用同一 thread_id 配合 new Command({resume})
  • drawMermaid 输出可导入 mermaid 渲染器验证图结构

来源与核验

  • 原始文章
  • 页面事实以原始来源及其引用的官方资料为准;版本、星标和模型能力会随时间变化。
  • AI Stack 不公开抓取到的全文快照,只发布独立转写与来源入口。

站内链接

相关文章