LangGraph 是 LangChain 生态下面向大模型复杂流程的有状态有向图编排框架,底层基于可迭代状态机实现,原生支持分支、循环、状态持久、人工介入,解决传统线性 Chain 无法处理长流程、自主 Agent 的问题。
一、核心概念(分层梳理)
1. 基础四元组(图的最小组成)
(1)State 全局状态
整张图唯一的全局数据容器,所有节点共享读写,是数据流转的核心载体。
- 定义方式:使用
TypedDict约束字段名、数据类型,配合Annotated+归约函数 (Reducer)定义字段合并规则。 - 两种更新规则:
- 默认:覆盖,新值直接替换旧值;
Annotated[list, operator.add]:列表追加,多轮对话标准用法;
- 扩展:搭配
Checkpointer可序列化持久化到内存 / Redis / 数据库,实现断点续跑、跨会话记忆。
python
运行
from typing import TypedDict, Annotated import operator class GraphState(TypedDict): query: str messages: Annotated[list[str], operator.add](2)Node 节点
图中最小执行单元,代表一段独立逻辑(调用 LLM、工具、数据处理、规则判断)。
- 本质:普通 Python 函数;
- 入参:当前全局
State; - 出参:局部更新字典(只返回需要修改的字段,不用返回完整 State);
- 特性:节点本身无状态,纯计算逻辑,数据全部托管在全局 State。
python
运行
def llm_node(state: GraphState) -> dict: return {"messages": ["LLM 执行完成"]}(3)Edge 边
定义节点间的执行流向,分两类,是实现线性 / 分支 / 循环的关键:
- 普通边(add_edge)固定跳转,A 执行完成 → 强制走到 B,用于线性串行流程。
- 条件边(add_conditional_edges)动态路由:根据State 内容执行路由函数,返回目标节点名,再通过
path_map映射跳转,用于分支、循环。
(4)Graph 状态图实例
由State + Node + Edge组装而成的可执行对象。
- 内置两个特殊标记:
START节点(流程唯一入口)、END节点(流程终止节点); - 生命周期:定义结构 → 编译 (compile) → 执行 (invoke/stream)。
2. 高阶核心组件
(1)Checkpointer 检查点
状态持久化中间件:
- 每一步执行后自动快照全局 State;
- 结合
thread_id实现多会话隔离、服务重启恢复、历史回溯。
(2)Human-in-the-Loop 人在回路
原生流程暂停机制:
- 编译时通过
interrupt_before / interrupt_after指定暂停点; - 流程走到目标位置自动挂起,允许外部读取 / 修改 State,再恢复执行。
(3)Reducer 归约函数
配合Annotated使用,定义同字段多份更新内容的合并策略:
- 内置:
operator.add(列表拼接); - 支持自定义函数,实现去重、保留最新、条件合并等逻辑。
二、底层整体实现机制
LangGraph 底层不是一次性执行的代码脚本,而是循环驱动的迭代式状态机。 整体运行范式:
读取当前节点 → 执行节点逻辑→ 合并更新 State → 根据边路由选择下一节点→ 循环,直到命中 END
1. 整体执行流程(底层通用逻辑)
初始化阶段接收外部入参,基于
TypedDict初始化全局 State;若开启 Checkpointer,优先从持久化存储恢复历史状态。主调度循环(核心)框架维护一个执行指针,不断推进:
- 取出当前待执行节点;
- 执行节点函数,得到「局部更新字典」;
- 根据字段绑定的 Reducer 规则,合并新旧 State;
- 匹配当前节点的 Edge(普通边 / 条件边),计算出下一个节点;
- 若下一节点是
END,终止循环;否则切换指针,进入下一轮迭代。
结束阶段退出循环,返回最终 State;开启 Checkpointer 则保存最终状态快照。
2. 细分场景底层机制
(1)状态合并机制(Annotated + Reducer)
这是 LangGraph 区别于普通传参的核心:
- 多个节点同时更新同一个字段,或单节点多次更新;
- 框架识别字段上绑定的归约函数;
- 旧 State 值 + 新更新值,按照 Reducer 规则合并,而非简单覆盖;
- 最终生成一份全新 State 供后续节点使用。
典型场景:多轮对话
messages列表不断追加历史消息。
(2)线性流程实现(普通边)
plaintext
START → NodeA → NodeB → END- 指针从
START指向 NodeA,执行并更新 State; - 匹配普通边,固定跳转至 NodeB;
- 执行 NodeB,匹配边指向
END,循环终止。
(3)分支流程实现(条件边)
plaintext
START → NodeA → 路由判断 → 分支1 / 分支2 → END- NodeA 执行完毕,State 产生标记字段;
- 调用路由函数读取 State,返回字符串标记;
- 通过
path_map映射到目标分支节点; - 分支节点执行完成,走向终点。
(4)循环流程实现(有环图)
LangGraph允许图存在环路(线性 Chain 不支持),循环本质 =条件边 + 回跳上游节点:
plaintext
START → NodeA → NodeB → 路由判断 ↑ ↓ └──── 条件成立(循环) ────┘ 条件不成立 → END- 一轮逻辑执行完成后,路由判断不走向 END,而是跳回上游节点;
- 执行指针回退,复用原有节点逻辑,开启新一轮迭代;
- 直到判断条件满足,才退出循环。
应用:Agent 「思考→工具调用→再思考」迭代推理。
(5)人在回路(流程暂停)底层机制
- 编译阶段:标记暂停节点
interrupt_before=["node_name"]; - 运行阶段:执行指针走到目标节点之前,主动打断主调度循环;
- 框架保存当前完整 State 和执行位置,对外暴露
get_state/update_stateAPI; - 人工修改状态后,再次调用
invoke(None),从断点位置恢复调度循环。
(6)状态持久化(Checkpointer)机制
- 每一轮节点执行完成后,自动对当前 State 做序列化快照;
- 以
thread_id作为会话唯一标识,区分不同用户 / 会话; - 重启 / 断线后,通过
thread_id加载快照,恢复执行指针与 State,实现断点续跑。
三、LangGraph 与 LangChain 线性 Chain 底层本质差异
表格
| 维度 | LangChain Chain(LCEL) | LangGraph 状态图 |
|---|---|---|
| 底层模型 | 线性管道、无环单向数据流 | 有向图、原生支持环 / 分支 |
| 数据传递 | 上下游逐级传参,无统一容器 | 全局 State 统一托管数据 |
| 流程控制 | 顺序硬编码,无法动态跳转 | 边 + 路由函数,动态计算流向 |
| 循环能力 | 无原生支持,需手写代码循环 | 原生有环图,框架层实现循环 |
| 暂停 / 介入 | 无原生暂停能力 | 框架层支持挂起、人工修改状态 |
| 执行模式 | 一次性串行执行 | 迭代式状态机,分步推进 |
四、核心总结(精简记忆版)
- 核心定位:LangGraph =面向 LLM 的迭代式有状态有向图状态机。
- 四大核心概念
State:全局数据容器,靠 TypedDict + Reducer 做结构与合并规则;Node:业务执行单元(纯函数、无全局状态);Edge:流程控制线(普通边 = 串行,条件边 = 分支 / 循环);Graph:图容器,负责整体调度。
- 底层核心机制
- 整体:节点执行 → 状态合并 → 路由跳转的无限迭代,直到遇见
END; - 循环:条件边回跳上游节点;
- 多轮对话:Reducer 列表追加 + Checkpointer 状态持久;
- 人在回路:调度循环主动暂停 + 外部修改状态 + 断点恢复。
- 整体:节点执行 → 状态合并 → 路由跳转的无限迭代,直到遇见