进阶
用 LangGraph 搭有状态、可中断恢复的生产级 Agent 工作流(检查点 + 人在回路)
当你的 Agent 任务变长——要跑几十步、中途可能崩、某些步骤必须人点头才能继续——普通的「循环 + prompt」就撑不住了。LangGraph 用有向图把 Agent 步骤建模为节点,支持持久化检查点(断点续跑)、human-in-the-loop 中断(敏感操作等人审)、以及精确的分支与错误恢复。它是复杂长流程生产 Agent 的默认运行时。本教程从零搭一个「可审批、可恢复」的多步骤 Agent 工作流。
🕸️ 本教程适合:写过单 Agent、现在要把它升级成「可靠的生产流程」的开发者。需要会 Python,理解「状态」和「图」的基本概念即可。
先搞懂:为什么长流程要用图?
用一句话理解:LangGraph 把工作流画成一张「有状态的图」——每个节点干一件事,边决定下一步去哪,整个图的进度会被「检查点」存下来,崩了能从断点续,敏感节点能暂停等人。
| 能力 | 解决什么痛点 |
|---|---|
| 持久化检查点 | 崩了从断点续,不从头重跑 |
| Human-in-the-loop | 付款/部署前暂停等人审批 |
| 显式状态管理 | 每步输入输出清晰可查、可回滚 |
| 分支与循环 | 条件路由、重试、错误恢复 |
学习曲线比 CrewAI 陡。图、状态、检查点都要理解。但换来的是「企业级可控」——审计轨迹、回滚点、持久状态,正是监管和行业场景要的。简单任务别硬上 LangGraph。
Step 1:安装与基础图
1 装好,画第一个节点
pip install langgraph langchain-openai
from typing import TypedDict
from langgraph.graph import StateGraph, START, END
class State(TypedDict):
topic: str
draft: str
approved: bool
def plan(state: State):
return {"draft": f"关于 {state['topic']} 的初稿..."}
g = StateGraph(State)
g.add_node("plan", plan)
g.add_edge(START, "plan")
g.add_edge("plan", END)
app = g.compile()
💡 `State` 是整个图的「共享记事本」,每个节点读它、改它。这是 LangGraph 状态管理的基础。
Step 2:加检查点,让图能「断点续跑」
2 把进度存下来
不加检查点时,图跑完即焚;加上 `MemorySaver`,每次状态变更都落盘,崩了能恢复:
from langgraph.checkpoint.memory import MemorySaver
memory = MemorySaver()
app = g.compile(checkpointer=memory)
# 用 thread_id 标识一条「会话」,进度按它存
config = {"configurable": {"thread_id": "task-001"}}
app.invoke({"topic": "AI 客服"}, config)
thread_id 是关键。同一 thread_id 的多次调用共享检查点。生产环境把 MemorySaver 换成持久后端(Postgres / Redis),服务重启也不丢进度。
Step 3:加一个「人审批」中断节点
3 敏感步骤暂停等人
用 `interrupt_before` 在指定节点前暂停,等人确认后再继续——典型的「人在回路」:
def send_email(state: State):
# 真正发邮件的逻辑(敏感操作)
return {"approved": True}
g.add_node("send_email", send_email)
g.add_edge("plan", "send_email")
g.add_edge("send_email", END)
# 在 send_email 前中断,等人审批
app = g.compile(checkpointer=memory, interrupt_before=["send_email"])
app.invoke({"topic": "续费提醒"}, config)
# → 图在 send_email 前停下,等你批准
app.invoke(None, config) # 你点头,继续往下跑
🔑 关键技巧:`interrupt_before` 是合规与安全的命门。凡是「发消息、扣款、部署」这类不可逆操作,都该在前面加一道人审批。
Step 4:加分支与条件路由
4 根据状态决定下一步
def route(state: State):
if state.get("risk") == "high":
return "human_review" # 高风险走人工
return "auto_fix" # 低风险自动修
g.add_conditional_edges("detect", route)
# detect 节点后,按 route 返回值走不同分支
条件边让流程「会思考」。相比线性流水线,图的分支能处理「正常 / 异常 / 高风险」多条路径,错误恢复也更自然。
Step 5:接 LLM 节点做智能决策
5 让某个节点调用模型
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-5.6")
def draft_node(state: State):
msg = llm.invoke(f"写一段关于 {state['topic']} 的简介")
return {"draft": msg.content}
g.add_node("draft_node", draft_node)
g.add_edge(START, "draft_node")
🤖 LangGraph 与 LangChain 生态无缝。模型调用、工具、记忆都是现成积木,重点放在「图的编排」而非底层。
Step 6:加重试与错误恢复
6 崩了别整段重来
def fragile_call(state: State):
# 可能超时的外部调用
return {"result": call_api()}
# 用 try / 检查点配合:失败时回到上一检查点
# LangGraph 的「更新状态」API 还能人工修正后继续
app.update_state(config, {"draft": "修正后的内容"})
🔧 `update_state` 是杀手锏:人可以直接改图里的状态,再让图从断点继续——无需重跑前面所有步骤。
Step 7:可视化与上线
7 先看图,再部署
# 导出流程图,确认结构符合预期
app.get_graph().draw_mermaid_png("flow.png")
# 部署:编译后的 app 就是普通 Python 对象
# 套一层 FastAPI,用 thread_id 区分用户会话即可
from fastapi import FastAPI
api = FastAPI()
@api.post("/run")
def run(topic: str):
return app.invoke({"topic": topic}, {"configurable": {"thread_id": topic}})
🎉 恭喜!你已搭出一个「可审批、可恢复、可分支」的生产级 Agent 工作流。最大收获:长流程不再怕崩、不再怕错,每一步都可审计、可回滚。
常见问题速查
| 你遇到的现象 | 大概率原因 & 解决 |
|---|---|
| 图不续跑 | 没传 checkpointer,或 thread_id 每次都变 |
| 中断后不继续 | 忘记再 invoke(None, config) 放行 |
| 状态字段报错 | State 的 TypedDict 漏字段,节点返回了未声明 key |
| 太复杂学不动 | 先用 CrewAI 出原型,要精确控制再回流 LangGraph |