定义
LangGraph 是 LangChain 团队开发的有向图(Directed Graph)驱动的Agent编排框架,将Agent工作流建模为节点(Node)与边(Edge)构成的状态机,支持循环、分支、并行执行,以及持久化检查点(Checkpoint)和人工介入(Human-in-the-Loop)。
核心概念
| 概念 | 定义 |
| StateGraph | 状态驱动的有向图,每个节点接收并返回全局状态对象 |
| Node(节点) | 图中可调用的函数/可运行对象,输入当前状态,输出更新到状态 |
| Edge(边) | 节点之间的连接线,决定执行流向 |
| Conditional Edge | 条件分支边,根据状态内容动态选择下一节点 |
| State(状态) | 贯穿整个图的全局数据对象,TypedDict 或 Pydantic 定义 |
| Checkpoint(检查点) | 每次节点执行后的状态快照,支持断点续跑和时间旅行 |
| Persistence(持久化) | 检查点的存储后端,支持内存、SQLite、PostgreSQL |
架构模型
有向图 vs 线性链
LangChain 的 Chain 是线性的依次执行序列,LangGraph 采用有向图:
| 特性 | Chain(线性链) | LangGraph(有向图) |
| 执行流 | 固定顺序 | 任意拓扑(循环/分支/并行) |
| 状态管理 | 隐式传递 | 显式全局状态对象 |
| 循环 | 不支持 | 原生支持 |
| 条件分支 | 需外部包装 | Conditional Edge 原生支持 |
| 可中断性 | 无 | Checkpoint 支持任意点中断/恢复 |
| 并行 | 不支持 | 支持 Fan-out 并行 |
图结构
LangGraph 的图由以下元素构成:
- 输入节点:图执行的入口点(__start__)
- 处理节点:执行具体逻辑的函数节点(LLM调用、工具执行、数据转换等)
- 条件节点:根据状态值决定流向的分支点(Conditional Edge)
- 输出节点:图执行的终点(__end__)
__start__ → [LLM节点]
↓
条件分支节点
↙ ↘
[工具节点] [输出节点]
↓
[LLM节点] ←←←
↓
条件分支(循环直到无需工具)
↓
__end__
State 设计模式
State 是 LangGraph 的核心数据模型,采用 reducer 模式管理字段更新:
| Reducer 类型 | 行为 | 适用场景 |
| 默认覆盖 | 新值直接覆盖旧值 | 单一值字段(如 query) |
| operator.add | 新旧列表拼接 | 消息历史追加(messages) |
| 自定义 Reducer | 函数定义合并逻辑 | 复杂对象合并 |
from typing import TypedDict, Annotated, Sequence
import operator
class AgentState(TypedDict):
query: str
messages: Annotated[Sequence, operator.add]
next_step: str
intermediate_results: list
节点类型与生命周期
内置节点类型
| 节点类型 | 描述 | 示例 |
| 函数节点 | 普通 Python 函数 | call_llm, execute_tool |
| Runnable 节点 | LangChain Runnable 对象 | Chain, PromptTemplate |
| Subgraph 节点 | 嵌套的 LangGraph | 子任务分解 |
生命周期钩子
- pre-hook:节点执行前调用,可修改输入状态
- post-hook:节点执行后调用,可处理/过滤输出
- CheckpointEvent:节点执行后自动保存检查点
Checkpoint 与持久化
每个节点执行完毕后,LangGraph 自动保存状态快照(Checkpoint)。Checkpoint 包含完整的状态对象及执行上下文元数据。
| 存储后端 | 适用场景 | 特性 |
| MemorySaver | 开发/测试 | 进程内内存,重启丢失 |
| SqliteSaver | 单机持久化 | 文件级存储,进程安全 |
| PostgresSaver | 生产分布式 | 事务支持,多实例共享 |
Checkpoint 支持的操作
- 中断(Interrupt):在指定节点前暂停执行,等待人工输入
- 恢复(Resume):从中断点继续执行
- 回放(Replay):从历史检查点重新执行部分路径
- 时间旅行(Time Travel):回滚到任意历史状态
边类型
| 边类型 | 方法 | 行为 |
| 普通边 | add_edge() | 上一个节点执行完毕后固定走到下一个节点 |
| 条件边 | add_conditional_edges() | 根据函数返回值动态选择目标节点 |
| 入口边 | set_entry_point() | 指定图执行入口节点(默认 __start__) |
| 出口边 | set_finish_point() | 指定图结束节点(默认 __end__) |
并行执行支持
LangGraph 通过 Fan-out / Fan-in 模式实现节点级并行:
- Fan-out:一个节点输出分发给多个下游节点并行处理
- Fan-in:多个并行节点的结果合并到下一个节点
- Send API:动态创建并行分支,每个分支处理不同的输入片段
# Fan-out 并行结构示意
[文档拆分] → Send → [摘要LLM-1]
Send → [摘要LLM-2]
Send → [摘要LLM-3]
↓ (Fan-in 合并)
[汇总节点]
Human-in-the-Loop 机制
LangGraph 原生支持三种人工介入模式:
| 模式 | 实现方式 | 适用场景 |
| 前置审批 | Interrupt before 指定节点 | 工具调用前人工确认 |
| 后置审核 | Interrupt after 指定节点 | LLM输出后人工审查 |
| 动态介入 | 条件边判断状态触发 Interrupt | 置信度低时转人工 |
与主流框架的关系
| 框架 | 图模型 | 状态管理 | 持久化 | 循环支持 |
| LangGraph | 有向图 | 显式 TypedDict | 原生支持 | 原生 |
| CrewAI | 层次链 | 隐式上下文传递 | 不支持 | 有限 |
| AutoGen | 对话图 | 消息历史 | 基础 | 通过对话 |
| Semantic Kernel | Pipeline | 上下文对象 | 不支持 | 不支持 |
应用场景
- ReAct Agent:LLM思考→工具调用→观察结果的循环,由条件边控制退出
- 多步推理:问题分解→子问题求解→结果整合的图结构流程
- Agent Supervisor:主管Agent协调多个子Agent,分支并行+结果汇聚
- 数据流水线:ETL中的条件分支、并行处理、异常重试
- 对话系统:多轮对话中的状态追踪、上下文维护、中断恢复
局限性
- 学习曲线:State / Reducer / Conditional Edge 等概念需要理解成本
- 调试难度:图结构的错误追踪比线性代码复杂
- 编排复杂度:超大规模图(数百节点)的可读性和维护性下降
- 与LangChain绑定:大量示例和工具函数依赖LangChain生态