这两年,越来越多人开始用 LangGraph 来搭建 Agent 应用。
但不少人一上来就把注意力放在多智能体、复杂编排和各种“高级模式”上,结果学了不少概念,真正动手时反而还是不知道该怎么落。
一种很常见的情况是:刚开始写的时候觉得思路挺顺,节点也不多;可一旦流程里出现分支、重试、人工介入、状态持久化,整个系统马上开始变乱。
这时候你会发现,问题往往不是模型不够聪明,也不是节点不会写,而是你还没有真正进入 LangGraph 的思维方式。
问题往往不在于 LangGraph 太难,而在于学习顺序出了偏差。
LangGraph 最值得先学的,不是某个看起来很厉害的 Agent 结构,而是更底层的一层能力:你怎么把一个原本不稳定、不可控的 LLM 调用,改造成一个可追踪、可恢复、可干预的工作流。
换句话说,LangGraph 的重点不是“让模型更像人”,而是“让 Agent 更像系统”。
LangGraph 到底解决了什么问题
如果只做一次性的问答,普通链式调用其实已经够用了。
但一旦任务开始变复杂,问题就会集中暴露出来:
- 流程不是线性的,执行失败后需要回退重试
- 中间结果很多,状态容易丢
- 一些步骤应该由代码严格控制,不能全交给模型决定
- 高风险动作需要人工确认
- 任务跑到一半中断后,希望下次能接着跑
这正是 LangGraph 的价值所在。
它把 Agent 的执行过程拆成图结构来管理:状态是共享的,节点负责执行,边负责决定下一步怎么走。这样一来,你写的就不再是一段“从头跑到尾”的 Prompt,而是一个可以循环、可分支、可恢复的状态机。
学 LangGraph,先抓住四个关键词
如果你是第一次学,建议先别急着研究多智能体,也别急着背一堆术语,先把下面四个东西吃透。
1. State
State 是整个图运行时的共享数据。
它不是“聊天记录”这么简单,而是当前任务的完整快照。
比如一个工单系统里,状态里可能有:
from typing import Literal, TypedDict
class TicketState(TypedDict):
user_query: str
category: Literal["billing", "tech", "other"]
retrieved_docs: list[str]
answer: str
retry_count: int
很多人学 LangGraph 一开始写不顺,不是因为节点不会写,而是因为 State 没设计清楚。
State 一乱,后面的节点、路由、持久化和调试都会跟着乱。
2. Node
Node 本质上就是函数。
它接收当前状态,做自己的事,然后返回状态更新。
关键不是“每个节点都要调用 LLM”,恰恰相反,能用普通代码解决的逻辑,最好不要交给 LLM。
比如分类结果是 billing 就走账单节点,这种事情用代码判断比让模型自由发挥可靠得多。
3. Edge
Edge 决定流程怎么走。
它可以是固定跳转,也可以是条件路由。
LangGraph 真正强的地方,是你可以把“流程控制权”从模型手里拿回来。
什么时候结束,什么时候重试,什么时候进入人工审核,不必都让模型猜。
4. Cycle
循环能力是 LangGraph 和很多“线性调用”方案最不一样的地方。
举个简单例子:
- 先检索资料
- 再评估结果是否够好
- 不够好就回去继续检索
- 够好了再生成答案
这类“生成 -> 评估 -> 修正”的回路,在真实项目里非常常见。
没有循环,很多 Agent 只能“一把梭”,一错到底。
常见 Agent 模式,别当成固定菜单来背
在讨论 LangGraph 时,大家经常会提到 ReAct、Plan-and-Execute、Reflection、Multi-Agent。
这些概念有用,但更准确的理解方式是:它们是常见设计模式,不是 LangGraph 的固定产品菜单。
ReAct
适合简单任务,边做边看,灵活但不够稳。
如果你只是想快速跑通工具调用流程,它很适合当第一个起点。
不过需要注意的是,按照当前官方文档,LangGraph 自带的 create_react_agent 已经被标记为弃用。
如果你想快速起步,官方现在更推荐使用 LangChain 的 create_agent,底层仍然运行在 LangGraph 之上。
Plan-and-Execute
适合步骤比较长、目标比较清楚的任务。
它的核心思路是先规划,再逐步执行,必要时再重规划。
如果任务一眼看上去就不止两三步,比如复杂调研、长链路处理、代码生成,这种模式通常比纯 ReAct 更稳。
Reflection
它不是单独取代前两者的模式,更像一个质量保险层。
本质上就是在输出前加一个评估节点,不达标就回退重写。
这在“对结果质量很敏感”的场景里特别重要,比如代码生成、正式文稿、规则审查。
Multi-Agent
多智能体不是越早上越好。
它更适合在两个条件同时出现时使用:
- 单个 Agent 的上下文已经太重
- 不同子任务之间确实可以拆开,各自处理
如果只是为了“显得高级”而拆多智能体,最后通常只会得到更复杂的调试成本。
理解这些模式之后,真正重要的问题其实不是“该选哪个名字”,而是:在一个具体项目里,哪些事情应该交给模型判断,哪些事情应该由工作流强约束。
这也是 LangGraph 从 demo 走向工程落地时,最关键的一道分水岭。
企业里更常见的,不是全自主,而是半自主
如果把这段学习过程里最重要的认知提炼成一句话,我会写成:
企业真正常用的,不是让 Agent 无限自由,而是把确定性的部分固化为工作流,只把少量不确定的部分留给模型。
这背后其实是一套很务实的判断逻辑。
能写死的流程,就别让模型猜
比如退款审批、账单查询、权限申请、表单流转,这类业务往往本来就有明确 SOP。
这种场景下,最合理的做法不是做一个“会自由思考的 Agent”,而是做一个可追踪的工作流,让模型只负责抽取参数、补全文本或做局部判断。
路径不固定的步骤,再交给模型做动态规划
但也不是所有问题都能完全 SOP 化。
像故障排查、复杂调研、代码编写,这类任务的执行路径经常会随着中间结果变化。
这时候更合理的方式,是把大框架固定住,把局部步骤放开。
也就是:
- 外层流程是确定的
- 某个节点内部允许模型自主决定怎么完成
- 如果结果不合格,再回到上一步修正
输出风险高时,一定要加人工介入点
LangGraph 的一个重要价值,是它原生支持中断与恢复。
这意味着你可以在关键动作前停下来,等人确认后再继续。
比如:
- 发送外部邮件前
- 删除数据前
- 执行高风险工具前
- 多轮失败后升级人工处理
这类能力在演示项目里可能不起眼,但在生产环境里非常关键。
一个更适合初学者的 Demo:智能客服工单系统
如果你想做一个既适合练手、又能体现企业思路的 LangGraph Demo,我更推荐下面这个方向,而不是一上来就做“万能聊天助手”。
项目名可以很朴素:智能客服工单分发与解决系统。
为什么这个 Demo 值得做
因为它刚好能把 LangGraph 最关键的几件事串起来:
- 有状态
- 有路由
- 有循环
- 有确定性分支
- 有动态处理分支
- 有质量检查
- 有人工接管
这比单纯做一个“会搜索的问答机器人”更接近真实业务。 更重要的是,它的复杂度刚刚好:足够你练到 LangGraph 里最关键的能力,但又不需要一开始就接太多外部系统、太多工具和太长的上下文。
这个图可以怎么设计
可以先把流程收敛成下面这几步:
classifier:先判断问题属于账单、技术故障还是无效输入billing_handler:账单类问题走固定流程researcher:技术问题进入检索、分析、回答环节evaluator:检查回答是否真的解决了问题human_review:连续失败后转人工
一个很实用的执行逻辑是:
START
-> classifier
-> billing_handler -> END
-> researcher -> evaluator
-> 通过 -> END
-> 不通过且重试次数未超限 -> researcher
-> 超过上限 -> human_review
这个 Demo 的好处在于,它几乎把 LangGraph 的核心价值都练到了:
- 用条件边做路由
- 用循环边做重试
- 用状态记录重试次数和处理中间结果
- 用中断或人工接管做安全兜底
如果你是初学者,这类 Demo 的价值就在于,它不是拿来“炫技”的,而是能帮你真正建立工程直觉:什么时候该交给模型,什么时候该交给图,什么时候该留给人。
持久化不是“顺手存个聊天记录”,而是生产能力
很多人刚开始接触持久化时,会把它理解成“把历史消息存起来”。
这当然没错,但对 LangGraph 来说,这个理解还不够。
LangGraph 的持久化更接近“运行时存档”。
官方文档里,图在挂上 checkpointer 之后,会按 thread 保存每一步的 checkpoint。
这带来的不只是“记住对话”,还包括几件更重要的事:
- 任务中断后可以继续跑
- 人工介入后可以恢复执行
- 可以读取当前状态快照
- 可以查看历史状态
- 可以从历史 checkpoint 回放或分叉
一个最基本的思路大概是这样:
from langgraph.checkpoint.memory import InMemorySaver
checkpointer = InMemorySaver()
graph = builder.compile(checkpointer=checkpointer)
config = {"configurable": {"thread_id": "ticket-1001"}}
graph.invoke(input_state, config=config)
snapshot = graph.get_state(config)
history = list(graph.get_state_history(config))
如果只是本地调试,InMemorySaver 就够用。
如果是生产环境,官方文档推荐使用数据库支撑的 checkpointer,比如 Postgres,也提供了 Redis、MongoDB 等方案。
这也是为什么我会说:LangGraph 里真正值得你下功夫的,不只是“会不会写 Agent 节点”,而是你有没有把运行过程当成一个可恢复、可观察、可审计的系统在设计。 如果只记一件事,那就是:LangGraph 的持久化保存的不是“几条聊天记录”,而是整个任务在某个时刻的执行状态。
Human-in-the-loop:别只会加断点,要理解中断
在这部分,很多初学者也容易混淆两个概念:
- 静态断点
- 真正的人机协作中断
官方文档里明确提到,interrupt_before、interrupt_after 这种静态断点存在,但不推荐把它们当成主要的 HITL 实现方式。
更推荐的是在节点内部使用 interrupt(),在真正需要外部输入的时候暂停执行,再通过恢复命令继续往下跑。
这背后的意义很大。
因为它说明 LangGraph 的人工介入,不是“调试时暂停一下”,而是工作流设计的一部分。
当你开始这样理解它时,你写出来的图就不再只是 demo,而是更接近生产系统。
对初学者来说,这一节最重要的不是先把 API 全背下来,而是先建立一个判断:只要任务有风险、有成本,或者失败后果比较重,就要提前设计人工介入点。
一条更顺的学习路线
如果你现在正准备开始学 LangGraph,我更建议按下面这个顺序走。
第一步:先学图,不要先学多智能体
先把 StateGraph、状态设计、节点、条件边、循环跑通。
这一步没吃透,后面谈 Supervisor、Subgraph、Memory 都会飘。
第二步:做一个有明确分支的业务 Demo
最推荐的就是上面的工单系统。
它能让你同时练到分类、路由、循环和状态管理。
第三步:给 Demo 补上自检机制
别让图只会“生成答案”,要让它会“判断答案是否够好”。
一旦评估不通过,就回退重做。
第四步:补上持久化与人工介入
加上 checkpointer、thread_id、历史状态读取、人工审核点。
做到这里,你对 LangGraph 的理解就已经不只是“会写 Hello World”了。
第五步:最后再考虑子图和多智能体
当你真的遇到上下文过重、职责可以拆分的场景,再引入 subgraph 或多智能体。
这样它们会成为解法,而不是装饰。
写在最后
我现在越来越觉得,学 LangGraph 最重要的一次转变,不是学会多少 API,而是意识到一件事:
Agent 开发的重点,正在从“写一段更聪明的提示词”,慢慢转向“设计一个更可靠的状态机”。
这也是为什么我不建议初学者一上来就卷多智能体、卷复杂框架、卷炫技 Demo。
真正能让你快速进步的,通常是一个结构清楚、状态明确、能循环、能恢复、能人工介入的小系统。
当你把这个思路跑通之后,再回头看 ReAct、Plan-and-Execute、Reflection、Multi-Agent,你会发现它们不再是几个孤立名词,而只是同一套图式思维在不同复杂度下的具体展开。
如果现在就准备动手,我的建议很简单:先别追求“大而全”,先做一个带分类、路由、重试、自检和人工接管的小型工单系统。
把这个 Demo 跑顺之后,你对 LangGraph 的理解,往往会比看十篇概念文章更扎实。
参考资料
- LangGraph Overview: docs.langchain.com/oss/python/…
- Graph API: docs.langchain.com/oss/python/…
- Persistence: docs.langchain.com/oss/python/…
- Add Memory: docs.langchain.com/oss/python/…
- Interrupts: docs.langchain.com/oss/python/…
- Time Travel: docs.langchain.com/oss/python/…
- Subgraphs: docs.langchain.com/oss/python/…
- Streaming: docs.langchain.com/oss/python/…
- LangGraph v1 Release Notes: docs.langchain.com/oss/python/…