《深入理解 LangGraph:构建可持久化、多智能体的 LLM 工作流》
摘要:本文系统解析 LangGraph 框架的核心设计理念与工程实践,详解其图式架构、状态管理机制及高级应用场景,包括持久化内存、人机协同、多智能体系统与规划执行模式,助你构建复杂可靠的 LLM 应用。
- [《深入理解 LangGraph:构建可持久化、多智能体的 LLM 工作流》](#《深入理解 LangGraph:构建可持久化、多智能体的 LLM 工作流》)
-
- [一、引言:LangGraph 的诞生背景与工程价值](#一、引言:LangGraph 的诞生背景与工程价值)
- [二、LangGraph 核心组件:图、状态、节点与边](#二、LangGraph 核心组件:图、状态、节点与边)
-
- [2.1 Graph(图):工作流的骨架与执行引擎](#2.1 Graph(图):工作流的骨架与执行引擎)
- [2.2 State(状态):工作流的记忆与上下文载体](#2.2 State(状态):工作流的记忆与上下文载体)
-
- [2.2.1 模式(Schema)定义](#2.2.1 模式(Schema)定义)
- [2.2.2 归约器(Reducers)机制](#2.2.2 归约器(Reducers)机制)
- [2.3 Nodes(节点):工作流的执行单元](#2.3 Nodes(节点):工作流的执行单元)
- [2.4 Edges(边):工作流的控制流](#2.4 Edges(边):工作流的控制流)
- [三、持久化与人机交互:构建生产级 LLM 应用](#三、持久化与人机交互:构建生产级 LLM 应用)
-
- [3.1 Persistence(持久化):跨会话记忆与错误恢复](#3.1 Persistence(持久化):跨会话记忆与错误恢复)
-
- [3.1.1 检查点实现原理](#3.1.1 检查点实现原理)
- [3.1.2 线程(Thread)概念](#3.1.2 线程(Thread)概念)
- [3.1.3 完整示例:带持久记忆的天气查询代理](#3.1.3 完整示例:带持久记忆的天气查询代理)
- [3.2 Human-in-the-loop(人机交互):关键决策的人工审核](#3.2 Human-in-the-loop(人机交互):关键决策的人工审核)
-
- [3.2.1 断点机制原理](#3.2.1 断点机制原理)
- [3.2.2 交互流程详解](#3.2.2 交互流程详解)
- 四、高级应用场景:多智能体系统与规划执行
-
- [4.1 Multi-Agent Systems(多智能体系统)](#4.1 Multi-Agent Systems(多智能体系统))
-
- [4.1.1 案例:研究者与图表生成器协作](#4.1.1 案例:研究者与图表生成器协作)
- [4.2 Plan-and-Execute(规划与执行)模式](#4.2 Plan-and-Execute(规划与执行)模式)
-
- [4.2.1 状态设计](#4.2.1 状态设计)
- [4.2.2 规划与重规划机制](#4.2.2 规划与重规划机制)
- 五、总结与工程实践
-
- [5.1 核心价值与定位](#5.1 核心价值与定位)
- [5.2 最佳工程实践](#5.2 最佳工程实践)
- [5.3 未来演进方向](#5.3 未来演进方向)
一、引言:LangGraph 的诞生背景与工程价值
在 LLM 应用开发领域,传统框架如 LangChain 的 AgentExecutor 面对复杂场景时往往力不从心:缺乏循环能力、状态管理粗糙、难以实现多角色协作。当我们的应用需要跨多轮保持对话上下文 、在循环中调用工具 、在关键操作前等待人工审核 ,或多个专业 Agent 协作解决复杂问题时,线性链式结构很快会变得难以维护和调试。
LangGraph 的出现并非偶然,它由 LangChain Inc(LangChain 创建者)打造,设计灵感源自 Google Pregel (图计算模型)与 Apache Beam (数据流系统),同时在接口设计上借鉴了 NetworkX 的图论 API。这种设计哲学使 LangGraph 成为一个"底层但强大"的框架,如官方文档所述:
"LangGraph 允许您定义涉及循环的流程,这对于大多数代理架构至关重要。作为一种非常底层的框架,它提供了对应用程序的流程和状态的精细控制,这对创建可靠的代理至关重要。此外,LangGraph 包含内置的持久性,可以实现高级的'人机交互'和内存功能。"
本文将从工程视角,结合官方设计文档与实战经验,系统剖析 LangGraph 的架构精髓与应用场景,助你跨越从"简单 Agent"到"工程级智能系统"的关键门槛。
二、LangGraph 核心组件:图、状态、节点与边
LangGraph 将智能体工作流建模为一个有状态的图 ,其能力构建于四个核心抽象之上:Graph、State、Node、Edge 。理解这些组件是掌握 LangGraph 的基础。

2.1 Graph(图):工作流的骨架与执行引擎
在 LangGraph 中,StateGraph 是最核心的图类型,它由用户定义的状态对象参数化,负责协调节点执行和状态流转。一个典型的构建流程如下:
python
from langgraph.graph import StateGraph, START, END
from typing_extensions import TypedDict
# 定义状态模式
class MyState(TypedDict):
messages: list
data: dict
# 创建状态图构建器
builder = StateGraph(MyState)
# 添加节点和边
builder.add_node("step_1", step_1_function)
builder.add_edge(START, "step_1")
builder.add_edge("step_1", END)
# 编译图(关键步骤!)
graph = builder.compile()
编译过程是 LangGraph 的重要环节,它:
- 验证图结构完整性(无孤立节点、有明确入口/出口)
- 构建内部消息通道(channels)网络
- 注册节点和边的执行逻辑
- 准备检查点和断点机制
- 将图转换为 LangChain Runnable,支持标准调用接口(
.invoke()、.stream()、.batch())
编译后的图对象包含复杂的内部结构,例如:
nodes={
'__start__': PregelNode(...),
'my_node': PregelNode(...)
}
channels={
'__root__': <LastValue object>,
'__start__': <EphemeralValue object>,
'my_node': <EphemeralValue object>,
'start:my_node': <EphemeralValue object>
}
这一结构使 LangGraph 能够高效管理节点执行顺序和状态流转,为复杂工作流提供底层支持。
2.2 State(状态):工作流的记忆与上下文载体
状态是 LangGraph 中最核心的概念,它表示应用程序在任何给定时刻的完整快照。每次图执行都会创建一个状态,该状态在节点间传递,每个节点执行后使用其返回值更新此内部状态。
2.2.1 模式(Schema)定义
LangGraph 支持两种主要的状态模式定义方式:
TypedDict 方式(推荐):
python
from typing import Annotated, TypedDict
from langgraph.graph.message import add_messages
from langchain_core.messages import BaseMessage
class State(TypedDict):
messages: Annotated[list[BaseMessage], add_messages]
sender: str
context: dict
Pydantic BaseModel 方式(支持默认值和验证):
python
from pydantic import BaseModel, Field
class State(BaseModel):
messages: list[BaseMessage] = Field(default_factory=list)
sender: str = ""
context: dict = Field(default_factory=dict)
2.2.2 归约器(Reducers)机制
归约器是理解状态更新的关键。每个状态键可指定独立的归约函数,决定如何将新值与旧值合并。LangGraph 提供多层次的归约策略。
默认归约器:简单覆盖
python
# 初始状态
state = {"foo": 1, "bar": ["hi"]}
# 节点1返回更新
node1_update = {"foo": 2} # 应用后: {"foo": 2, "bar": ["hi"]}
# 节点2返回更新
node2_update = {"bar": ["bye"]} # 应用后: {"foo": 2, "bar": ["bye"]}
自定义归约器 :如 add_messages 用于消息列表
python
class State(TypedDict):
messages: Annotated[list[BaseMessage], add_messages]
当节点返回 {"messages": [new_message]} 时,add_messages 会将新消息追加到现有列表,而非覆盖整个列表。这种设计使对话上下文得以持续积累,是构建多轮对话系统的基础。
2.3 Nodes(节点):工作流的执行单元
节点是执行具体工作的 Python 函数,接收状态为输入,返回更新后的状态。在 LangGraph 中,有两种特殊节点:
START 节点:虚拟入口点
python
from langgraph.graph import START
graph.add_edge(START, "my_first_node")
END 节点:虚拟终端节点
python
from langgraph.graph import END
graph.add_edge("last_node", END)
节点函数遵循特定签名,可接收当前状态和配置参数:
python
from langchain_core.runnables import RunnableConfig
def my_node(state: dict, config: RunnableConfig):
# 从配置中获取可定制参数
user_id = config["configurable"]["user_id"]
print(f"Processing for user: {user_id}")
# 更新状态
return {
"results": f"Hello, {state['input']}!",
"processed_by": "my_node"
}
在底层,LangGraph 将普通函数转换为 RunnableLambda,自动添加批处理、异步支持、跟踪和调试能力,大幅提升开发体验。
2.4 Edges(边):工作流的控制流
边定义了节点间的执行顺序和条件分支,是工作流控制逻辑的核心。LangGraph 支持四种主要类型的边:
普通边:直接从一个节点到另一个节点
python
graph.add_edge("node_a", "node_b")
条件边:基于函数返回值决定下一个节点
python
def routing_function(state) -> Literal["node_b", "node_c"]:
return "node_b" if state["flag"] else "node_c"
graph.add_conditional_edges("node_a", routing_function)
条件映射:将路由函数输出映射到节点名称
python
graph.add_conditional_edges(
"node_a",
routing_function,
{True: "node_b", False: "node_c"}
)
入口点与条件入口点:定义工作流起点
python
# 固定入口点
graph.add_edge(START, "first_node")
# 条件入口点
def entry_router(state):
return "research_node" if "data" in state["query"] else "chart_node"
graph.add_conditional_edges(START, entry_router)
并行执行机制 :
当一个节点有多个输出边时,目标节点将在下一个超级步骤(superstep)中并行执行:
python
# 此设置将使node_b和node_c并行执行
graph.add_conditional_edges("node_a", lambda s: ["node_b", "node_c"])
超级步骤(Superstep)概念 :
LangGraph 的执行模型基于"超级步骤"概念,受 Google 的 Pregel 系统启发:
- 每个超级步骤包含一组可以并行执行的节点
- 节点执行完毕后,根据输出决定下一超级步骤的节点
- 当没有活跃节点且无消息传输时,执行终止
三、持久化与人机交互:构建生产级 LLM 应用
3.1 Persistence(持久化):跨会话记忆与错误恢复
检查点机制是 LangGraph 区别于其他框架的核心特性,通过在每个超级步骤后保存状态,实现一系列高级功能。
3.1.1 检查点实现原理
LangGraph 提供 MemorySaver 作为默认的内存中检查点实现:
python
from langgraph.checkpoint.memory import MemorySaver
memory = MemorySaver()
graph = workflow.compile(checkpointer=memory)
当启用检查点时,LangGraph 在每个节点执行后:
- 捕获当前完整状态
- 为状态生成唯一标识(thread_id)
- 将状态存储在检查点存储中
- 记录执行历史和元数据
3.1.2 线程(Thread)概念
线程是持久化的关键抽象,表示一个会话或工作流实例:
python
config = {"configurable": {"thread_id": "42"}}
相同 thread_id 的调用共享相同状态历史,实现跨请求记忆。不同 thread_id 则启动全新会话。
3.1.3 完整示例:带持久记忆的天气查询代理
python
# 定义状态类
class State(TypedDict):
messages: Annotated[list, add_messages]
# 初始化工具
@tool
def search(query: str):
"""模拟一个搜索工具"""
if "上海" in query.lower() or "Shanghai" in query.lower():
return "现在30度,有雾."
return "现在是35度,阳光明媚。"
# 创建工具节点
tool_node = ToolNode([search])
# 初始化模型
model = ChatOpenAI(model="gpt-4o", temperature=0).bind_tools([search])
# 定义节点函数
def call_model(state: State):
response = model.invoke(state["messages"])
return {"messages": [response]}
# 路由逻辑
def should_continue(state: State) -> Literal["tools", END]:
last_message = state["messages"][-1]
if last_message.tool_calls:
return "tools"
return END
# 构建工作流
workflow = StateGraph(State)
workflow.add_node("agent", call_model)
workflow.add_node("tools", tool_node)
workflow.set_entry_point("agent")
workflow.add_conditional_edges("agent", should_continue)
workflow.add_edge("tools", "agent")
# 添加持久化
memory = MemorySaver()
app = workflow.compile(checkpointer=memory)
# 交互示例
config = {"configurable": {"thread_id": "42"}}
response1 = app.invoke({"messages": [HumanMessage(content="上海的天气怎么样?")]}, config)
response2 = app.invoke({"messages": [HumanMessage(content="我问的那个城市?")]}, config)
print(response1["messages"][-1].content) # "上海现在的天气是30度,有雾。"
print(response2["messages"][-1].content) # "你问的是上海的天气。上海现在的天气是30度,有雾。"
通过共享相同的 thread_id,系统在两次查询间保留完整对话上下文,实现真正连贯的多轮对话。这一机制使 LangGraph 成为构建对话型 Agent 的理想选择。
3.2 Human-in-the-loop(人机交互):关键决策的人工审核
在许多场景中,LLM 的决策需要人类审核,特别是在处理敏感操作时。LangGraph 通过断点机制实现了无缝的人机交互。
3.2.1 断点机制原理
断点允许在特定节点执行前或后暂停工作流,等待人工干预:
python
graph = builder.compile(
checkpointer=memory,
interrupt_before=["critical_action"] # 在执行前中断
)
3.2.2 交互流程详解
- 初始执行:图执行直到断点
- 人工审核:检查当前状态,决定是否继续
- 恢复执行 :传入
None继续流程 - 状态修改:在恢复前修改状态
完整断点示例:
python
class State(TypedDict):
input: str
def step_1(state):
print("---Step 1---")
pass
def step_2(state):
print("---Step 2---")
pass
def step_3(state):
print("---Step 3---")
pass
builder = StateGraph(State)
builder.add_node("step_1", step_1)
builder.add_node("step_2", step_2)
builder.add_node("step_3", step_3)
builder.add_edge(START, "step_1")
builder.add_edge("step_1", "step_2")
builder.add_edge("step_2", "step_3")
builder.add_edge("step_3", END)
# 设置断点
memory = MemorySaver()
graph = builder.compile(checkpointer=memory, interrupt_before=["step_3"])
# 初始执行
initial_input = {"input": "hello world"}
thread = {"configurable": {"thread_id": "1"}}
for event in graph.stream(initial_input, thread, stream_mode="values"):
print(event)
# 人工批准
user_approval = input("Do you want to go to Step 3? (yes/no): ")
if user_approval.lower() == "yes":
# 恢复执行
for event in graph.stream(None, thread, stream_mode="values"):
print(event)
else:
print("Operation cancelled by user.")
这种能力在金融交易审批、医疗诊断辅助、法律文档生成等高风险场景中至关重要,为 LLM 应用提供了必要的安全网。

四、高级应用场景:多智能体系统与规划执行
4.1 Multi-Agent Systems(多智能体系统)
单一 Agent 在面对复杂任务时往往力不从心,而多 Agent 协作可以将问题分解,各司其职,大幅提升解决复杂问题的能力。

4.1.1 案例:研究者与图表生成器协作
python
class AgentState(TypedDict):
messages: Annotated[Sequence[BaseMessage], operator.add]
sender: str
# 创建专用 Agent
research_agent = create_agent(
llm,
[tavily_tool],
system_message="你应该提供准确的数据供chart_generator使用,确保数据完整且格式正确。"
)
chart_agent = create_agent(
llm,
[python_repl],
system_message="你负责根据提供的数据生成Python代码绘制图表,任何展示的图表都将对用户可见。"
)
# 创建 Agent 节点
research_node = functools.partial(agent_node, agent=research_agent, name="Researcher")
chart_node = functools.partial(agent_node, agent=chart_agent, name="chart_generator")
# 路由逻辑
def router(state) -> Literal["call_tool", "__end__", "continue"]:
last_message = state["messages"][-1]
if last_message.tool_calls:
return "call_tool"
if "FINAL ANSWER" in last_message.content:
return "__end__"
return "continue"
# 构建协作图
workflow = StateGraph(AgentState)
workflow.add_node("Researcher", research_node)
workflow.add_node("chart_generator", chart_node)
workflow.add_node("call_tool", tool_node)
# 添加条件边
workflow.add_conditional_edges(
"Researcher",
router,
{"continue": "chart_generator", "call_tool": "call_tool", "__end__": END}
)
workflow.add_conditional_edges(
"chart_generator",
router,
{"continue": "Researcher", "call_tool": "call_tool", "__end__": END}
)
# 工具调用路由
workflow.add_conditional_edges(
"call_tool",
lambda x: x["sender"],
{"Researcher": "Researcher", "chart_generator": "chart_generator"}
)
# 设置入口点
workflow.add_edge(START, "Researcher")
graph = workflow.compile()
# 调用示例
events = graph.stream({
"messages": [HumanMessage(
content="获取过去5年AI软件市场规模,然后绘制一条折线图。一旦你编写好代码,完成任务。"
)],
}, {"recursion_limit": 150})
for s in events:
print(s)
print("----")

通信机制详解:
- 用户输入首先路由给 Researcher
- Researcher 搜集数据,通过消息传递给 chart_generator
- chart_generator 生成图表代码,可能需要调用工具
- 工具结果路由回原始调用者
- 任一 Agent 可在消息中包含 "FINAL ANSWER" 标记结束流程
这种架构使系统能够处理需要多专业知识的任务,如市场分析与数据可视化,大幅提升解决复杂问题的能力。
4.2 Plan-and-Execute(规划与执行)模式
传统 ReAct 模式一次只思考一步,而规划执行模式先制定完整计划,再逐步执行,更适合复杂任务。

4.2.1 状态设计
python
class PlanExecute(TypedDict):
input: str # 用户原始输入
plan: List[str] # 待执行步骤列表
past_steps: Annotated[List[Tuple], operator.add] # (步骤, 结果)元组列表
response: str # 最终响应
4.2.2 规划与重规划机制
规划步骤:
python
class Plan(BaseModel):
"""未来要执行的计划"""
steps: List[str] = Field(description="需要执行的不同步骤,应该按顺序排列")
planner_prompt = ChatPromptTemplate.from_messages([
("system", """对于给定的目标,提出一个简单的逐步计划。这个计划应该包含独立的任务,如果正确执行将得出正确的答案。不要添加任何多余的步骤。最后一步的结果应该是最终答案。确保每一步都有所有必要的信息-不要跳过步骤。"""),
("placeholder", "{messages}"),
])
planner = planner_prompt | ChatOpenAI(model="gpt-4o", temperature=0).with_structured_output(Plan)
完整工作流构建:
python
workflow = StateGraph(PlanExecute)
workflow.add_node("planner", plan_step) # 生成初始计划
workflow.add_node("agent", execute_step) # 执行计划步骤
workflow.add_node("replan", replan_step) # 重新规划
# 连接节点
workflow.add_edge(START, "planner")
workflow.add_edge("planner", "agent")
workflow.add_edge("agent", "replan")
workflow.add_conditional_edges(
"replan",
should_end, # 决定是否结束或继续
{"agent": "agent", "__end__": END}
)
app = workflow.compile()
# 调用示例
inputs = {"input": "2024年巴黎奥运会100米自由泳决赛冠军的家乡是哪里?请用中文答复"}
async for event in app.astream(inputs, config={"recursion_limit": 50}):
for k, v in event.items():
if k != "__end__":
print(v)
执行流程:
- 规划器生成计划:["查找2024年巴黎奥运会100米自由泳决赛冠军的名字", "查找该冠军的家乡"]
- 执行器执行第一步,返回"潘展乐"
- 重规划器更新计划:["查找潘展乐的家乡"]
- 执行器执行第二步,返回"浙江温州"
- 重规划器判断任务完成,返回最终响应
五、总结与工程实践
5.1 核心价值与定位
LangGraph 代表了 LLM 应用开发范式的重大演进,其核心价值在于提供工程级控制能力,解决了传统 Agent 框架的固有局限:
- 状态驱动架构:通过精细的状态管理与归约机制,实现复杂工作流的精确控制
- 图式执行模型:支持循环、分支与并行执行,突破线性链式结构的局限
- 生产级特性:内置持久化与人机协同能力,满足企业级应用的可靠性要求
不同于高层抽象框架,LangGraph 作为底层基础设施,提供了构建可靠、复杂 LLM 应用所需的原语与保障,使开发者能够将 Agent 系统从"原型"提升至"生产系统"。
5.2 最佳工程实践
在 LangGraph 项目实施中,遵循以下关键原则可显著提升系统可靠性与可维护性:
状态与节点设计:
- 保持状态最小化,仅保留必要上下文;为每个状态字段明确定义归约策略
- 遵循单一职责原则设计节点,确保每个节点具有清晰的输入/输出契约
- 优先使用纯函数实现节点逻辑,减少副作用,增强可测试性
生产环境部署:
- 启用检查点机制实现错误恢复与审计追踪,为关键操作配置断点
- 采用分层线程ID策略(如
user_id:session_id),支持灵活的会话管理 - 集成 LangSmith 进行全链路监控,捕获执行轨迹与性能指标
5.3 未来演进方向
随着 LLM 应用复杂度持续提升,LangGraph 生态将向以下方向演进:
- 工程化增强:可视化工作流设计器、分布式执行引擎、状态版本控制
- 自适应能力:基于执行反馈动态优化图结构,实现真正意义上的自适应工作流
- 企业级集成:与现有业务系统深度集成,支持事务性操作与合规性要求
LangGraph 不仅是一个技术框架,更是一种系统化思考复杂 AI 应用的新范式。它将 LLM 从"一次性推理引擎"转变为"持续演化的智能系统",为构建下一代企业级 AI 应用奠定了坚实基础。正如分布式系统通过状态机复制实现可靠性,LangGraph 通过有状态的图式执行,为 LLM 应用带来了工程化所需的确定性与可预测性。
工程箴言:在 LangGraph 中,复杂性不在于框架本身,而在于如何将业务问题分解为状态转换图。从最小可行工作流开始,逐步演进,让图结构成为你表达业务逻辑的清晰语言,而非复杂性的来源。