第06章:LangGraph 入门
版本:LangChain v1.3.7 | 讲师:汤姆小白
1. LangGraph 是什么
LangGraph 是 LangChain 生态的底层编排运行时,专门用于构建有状态、长时间运行的 Agent。
简单理解:LangChain 做"零件",LangGraph 做"组装线"。
三者关系
| 产品 | 定位 | 适用场景 |
|---|---|---|
| LangChain | 基础构件(LLM、Tools、Retrieval) | 提供标准化的组件 |
| LangGraph | 编排运行时 | 复杂工作流、多步推理、持久化 |
| Deep Agents | 开箱即用 Agent 套件 | 高级 Agent,内置规划/子代理 |
create_agent底层就是基于 LangGraph 实现的。学 LangGraph 就是学 Agent 的底层原理。
安装
pip install langgraph
2. StateGraph:定义工作流
2.1 最简单的图
from langgraph.graph import StateGraph, MessagesState, START, END
from langchain.chat_models import init_chat_model
model = init_chat_model("openai:gpt-4o-mini")
def call_model(state: MessagesState):
"""节点函数:调用模型"""
response = model.invoke(state["messages"])
return {"messages": [response]}
# 创建图
graph = StateGraph(MessagesState)
# 添加节点
graph.add_node("model", call_model)
# 添加边
graph.add_edge(START, "model")
graph.add_edge("model", END)
# 编译并执行
app = graph.compile()
result = app.invoke({"messages": [{"role": "user", "content": "你好!"}]})
print(result["messages"][-1].content)
2.2 StateGraph 核心概念
| 概念 | 说明 |
|---|---|
| StateGraph | 图的容器,定义工作流的状态类型 |
| State | 在节点间传递的共享数据(如 MessagesState 是预定义的消息列表状态) |
| Node(节点) | 一个可执行的函数,接收 State 并返回 State 的部分更新 |
| Edge(边) | 节点之间的连接,定义执行顺序 |
| START / END | 特殊内置节点,表示图的起点和终点 |
2.3 自定义 State
from typing import TypedDict, Annotated
from langgraph.graph import StateGraph, START, END
class MyState(TypedDict):
messages: list
counter: int
final_answer: str
def step1(state: MyState):
return {"counter": state["counter"] + 1}
def step2(state: MyState):
return {"final_answer": f"执行了 {state['counter']} 步"}
graph = StateGraph(MyState)
graph.add_node("step1", step1)
graph.add_node("step2", step2)
graph.add_edge(START, "step1")
graph.add_edge("step1", "step2")
graph.add_edge("step2", END)
app = graph.compile()
result = app.invoke({"messages": [], "counter": 0, "final_answer": ""})
print(result["final_answer"]) # 执行了 1 步
3. 条件边:根据状态选择路径
条件边让工作流能根据运行时状态动态决定下一步。
import random
from langgraph.graph import StateGraph, MessagesState, START, END
model = init_chat_model("openai:gpt-4o-mini")
def call_model(state: MessagesState):
response = model.invoke(state["messages"])
return {"messages": [response]}
def should_continue(state: MessagesState) -> str:
"""条件判断函数:返回下一个节点名"""
last_message = state["messages"][-1]
# 检查是否需要工具调用
if hasattr(last_message, "tool_calls") and last_message.tool_calls:
return "tools"
return END
def call_tools(state: MessagesState):
"""执行工具"""
last_message = state["messages"][-1]
# 这里简化处理
return {"messages": [{"role": "tool", "content": "工具结果"}]}
graph = StateGraph(MessagesState)
graph.add_node("model", call_model)
graph.add_node("tools", call_tools)
graph.add_edge(START, "model")
graph.add_conditional_edges("model", should_continue, {
"tools": "tools",
END: END,
})
graph.add_edge("tools", "model") # 工具结果返回模型
app = graph.compile()
条件边的三个参数:(源节点, 判断函数, 路由映射)。判断函数返回的字符串必须在路由映射中存在。
4. 持久化:断点恢复
Agent 执行中可能因网络、API 限流等原因中断。持久化让 Agent 能从断点继续,不丢失进度。
from langgraph.checkpoint.memory import MemorySaver
# 创建内存检查点(生产环境推荐用 SqliteSaver 或 PostgresSaver)
checkpointer = MemorySaver()
graph = StateGraph(MessagesState)
# ... 添加节点和边 ...
app = graph.compile(checkpointer=checkpointer)
# 执行时指定 thread_id
config = {"configurable": {"thread_id": "user_123"}}
# 第一次调用
result1 = app.invoke(
{"messages": [{"role": "user", "content": "列出3个Python框架"}]},
config=config
)
# 即使程序崩溃重启,用同一个 thread_id 继续
result2 = app.invoke(
{"messages": [{"role": "user", "content": "详细说明第一个"}]},
config=config # 同一个 thread_id,自动加载历史
)
5. 人机协同:关键节点人工审批
在敏感操作(如删除文件、发送邮件)前暂停,等待人工确认。
from langgraph.types import interrupt
def sensitive_operation(state: MessagesState):
"""需要人工审批的节点"""
# 暂停并询问用户
approval = interrupt("即将删除重要数据,是否继续?")
if approval == "yes":
# 执行操作
return {"messages": [{"role": "ai", "content": "操作已执行"}]}
else:
return {"messages": [{"role": "ai", "content": "操作已取消"}]}
# 在图中使用
graph.add_node("sensitive_op", sensitive_operation)
app = graph.compile(checkpointer=checkpointer)
# 第一次调用:会在 interrupt() 处暂停
result = app.invoke(input_data, config)
# 此时 result 包含中断信息
# 用户确认后,恢复执行
app.invoke(
None, # 无新输入
config,
# 传入用户确认的 Command
)
6. Stream:实时监控执行过程
# 流式输出每个节点的结果
for event in app.stream(
{"messages": [{"role": "user", "content": "你好"}]},
config={"configurable": {"thread_id": "1"}},
stream_mode="values",
):
# event 是当前完整状态
last_msg = event["messages"][-1]
print(f"[{last_msg.get('role', 'node')}] {last_msg.get('content', '')}")
7. LangGraph 与 create_agent 的关系
create_agent 本质上就是预先配置好的 LangGraph:
# create_agent 内部做的事 ≈
from langgraph.prebuilt import create_react_agent
# create_agent 自动创建了:
# - model 节点
# - tools 节点
# - 条件边(有工具调用→继续,无→结束)
# - 中间件机制
# - 流式支持
理解 LangGraph 后,你就能:
- 在
create_agent不够灵活时,用 LangGraph 自定义 Agent 行为 - 添加自定义逻辑到 Agent 循环中
- 实现复杂的多 Agent 协作
本章小结
| 概念 | 作用 |
|---|---|
| StateGraph | 定义工作流图的容器 |
| Node | 可执行函数,操作 State |
| Edge | 节点间的执行顺序 |
| Conditional Edge | 根据状态动态路由 |
| Checkpointer | 持久化状态,断点恢复 |
| interrupt | 暂停等待人工审批 |
| stream | 实时监控图执行 |
LangGraph 是 Agent 的"骨架",create_agent 是 LangGraph 的"快捷方式"。先学 create_agent 快速上手,再用 LangGraph 深入定制。