Skip to content

LangGraph 从入门到实战

如果说 LangChain 更像快速搭 Agent 能力的高层框架,那么 LangGraph 更像把复杂 Agent 系统“管起来、编排起来、跑稳定”的底层工作流框架。这一篇会从最基础的状态图直觉讲起,带你逐步理解线程、检查点、人工介入、可恢复执行这些真正工程化的概念。

先别急着记 API,先建立 LangGraph 的直觉。

如果说 LangChain 更像“把模型能力快速拼起来”的高层框架,那么 LangGraph 更像“把复杂流程管起来”的状态图框架。它最重要的价值不是多一个类库,而是把状态、节点、边、线程、检查点、可恢复执行、人工介入这些工程化能力纳入同一套运行模型。 你可以先把它想成:给 AI 应用画流程图,但这张流程图不是 PPT,而是真的可以跑、可以停、可以继续、可以回放、可以插人进去处理

图 1:LangGraph 最适合解决的问题 任务不止一步:规划、执行、校验、修正 ↓ 中途可能失败、等待、被人工拦下 ↓ 后面还要基于旧状态继续往下跑 ↓ 这时就不再是“简单链式调用”,而是图式编排 一句最实用的话 当你的 AI 应用开始出现“要不要分支”“中断后怎么恢复”“人工审核后怎么继续”“同一个任务怎么带着状态跑很多步”这些问题时,LangGraph 才真正开始变得有价值。

02. 为什么有了 LangChain 还要 LangGraph

这个问题几乎每个初学者都会问,而且必须讲透。不然你会觉得自己在学两个差不多的东西。其实它们不是替代关系,更像上下层关系。

问题LangChain 更擅长LangGraph 更擅长
快速接模型和工具可以,但不是重点
快速做一个单链路 Agent可以,但更底层
复杂分支流程控制一般强项
中断后恢复继续依赖更底层配合强项
人工审批 / 人工修改后继续不自然强项
长时带状态运行有压力强项

2.1 什么时候你已经开始“需要图”了

  • 任务不是一步完成,而是多步协作完成。
  • 不同条件下要走不同分支。
  • 一个节点失败后不能简单整体重来。
  • 流程中间要停住,等人点确认。
  • 你开始在代码里堆越来越多的 if else 和状态变量。

适合只用 LangChain 的场景

Prompt → Model → Parser 这类单主链场景,偶尔加个 Tool 或 Retriever,通常没必要一开始就上图。

适合进入 LangGraph 的场景

审批、计划执行、循环修正、长流程恢复、人工介入、多节点协作,这些都是 LangGraph 的主场。

03. State / Node / Edge 一次搞懂

LangGraph 真正的核心不是某个 API 名字,而是几个概念:State、Node、Edge。只要这三个想清楚,后面的图就不会乱。

概念你可以怎么理解它在图里扮演什么角色
State任务当前携带的全部上下文图在流转时不断被读写的“任务背包”
Node做一件具体事的步骤读取状态,产出状态更新
Edge从一个步骤走向下一个步骤的规则决定流程往哪走
START / END图的开始和结束让一条执行链有明确起点和终点
Thread同一条任务的执行身份让系统知道“这次恢复的是哪条任务”
Checkpoint某个时刻的状态快照用于暂停、恢复、回溯

图 2:把 LangGraph 看成“带状态的流程图”

State:任务背包 → Node:做一步事 → Edge:决定下一步去哪 → Checkpoint:关键时刻可暂停、可恢复

3.1 State 为什么是第一主角

很多人学 LangGraph 时只看节点函数,结果越写越乱。真正决定图是否清晰的,往往不是节点数量,而是状态设计得好不好。因为节点只是“处理状态”,而状态才是整条任务真正携带的信息。

状态里可能放什么示例
用户输入原始问题、工单内容、上传文件摘要
阶段结果分类结果、检索结果、工具返回、审核意见
控制信息当前步骤、重试次数、是否通过审批、是否结束
日志信息执行痕迹、节点耗时、错误原因

初学者最容易踩的坑。

状态不是越多越好。把什么都往 state 里塞,图会越来越重、越来越难懂。状态应该服务于“流程往下走需要知道什么”,而不是把所有中间对象都长期背着跑。

04. 第一个最小图

先看一个非常小的例子,不追求业务复杂,只追求把图的基本骨架看清楚。

python
from typing import TypedDict
from langgraph.graph import StateGraph, START, END

class MyState(TypedDict):
    question: str
    answer: str

def draft_answer(state: MyState):
    return {"answer": f"你问的是:{state['question']}"}

builder = StateGraph(MyState)
builder.add_node("draft", draft_answer)
builder.add_edge(START, "draft")
builder.add_edge("draft", END)

graph = builder.compile()
result = graph.invoke({"question": "什么是 LangGraph?"})
print(result)

4.1 这段代码逐行在做什么

代码部分作用
MyState声明这条任务会携带哪些状态字段
draft_answer定义一个节点:吃入状态,返回状态更新
StateGraph(MyState)告诉 LangGraph:我要构建一张以这个状态结构为核心的图
add_node把具体节点注册进图
add_edge规定执行顺序
compile()把这张图编译成可运行对象
invoke()真正运行一次图

4.2 为什么这个例子很重要

因为它把 LangGraph 的最小骨架暴露得非常清楚:先有状态,再有节点,再有边,最后编译和执行。你以后写复杂图,骨架也还是这个骨架,只是节点更多、边更复杂、状态更丰富。

05. 常见编排模式

学框架不能只看 API,真正有用的是模式。下面这些模式,是 LangGraph 场景里最常见、最值得掌握的。

5.1 Router 模式:先分类,再走不同分支

适合什么场景例子关键状态
同一入口,不同问题走不同处理链售后、退款、物流、咨询分流intent / route

用户请求 → 意图识别节点 → 不同业务分支 → 统一收口

5.2 Loop 模式:做一轮,不满意就再来一轮

适合什么场景例子关键状态
需要迭代修正计划-执行-检查-修正attempt、score、max_rounds

Loop 很常见,但也很危险。因为只要退出条件没写清,就可能无限循环。所以状态里通常要带 max_rounds、当前轮次、是否达标这类控制字段。

5.3 Plan-Execute-Review 模式

步骤作用
Plan先把任务拆成计划
Execute按计划执行,每一步可能调用工具
Review检查结果是否合格,不合格再补救

5.4 Human Review 模式

当流程中有高风险动作,比如退款、发公告、删数据、审批工单时,经常不是让 Agent 自己一把梭,而是生成建议后交给人确认。这时 LangGraph 的 interrupt / resume 模式就特别有价值。

06. 持久化、线程与记忆

LangGraph 真正和“普通流程脚本”拉开差距的地方,就是持久化。因为图不是一次性跑完就算了,它可能跑到一半停住,过几分钟、几小时甚至几天之后再继续。这就要求系统不仅记得“执行到哪了”,还得记得“当时的状态是什么”。

概念你可以怎么理解
Thread同一条任务的身份标识,相当于“这一摊事是谁的”
Checkpoint这条任务某一时刻的状态快照
Resume下次从上次停住的地方继续跑

图 3:为什么要有 checkpoint 任务跑到第 3 步 ↓ 等待人工审核,先停住 ↓ 系统把当前状态保存成 checkpoint ↓ 审核通过后,从原位置继续跑,而不是整条重来

6.1 这和 LangChain 里的“memory”有什么不同

LangChain 更偏“应用运行时如何组织上下文”;LangGraph 这里讲的持久化,更偏“工作流执行到哪一步、状态怎么保存、以后怎么继续”。前者更接近对话和上下文,后者更接近流程编排和工程状态。

测试视角提醒。

只要系统支持恢复继续,你就要补测:恢复后是不是从正确节点继续、恢复时状态有没有丢、恢复后会不会重复执行已经执行过的动作。

07. interrupt 与人工介入

这是 LangGraph 很有辨识度的能力。很多真实业务场景都不能“让 Agent 自己做完所有决定”,而是做到某一步时停住,把当前结果交给人看,人确认后再继续。interrupt 的意义就在这里。

7.1 一个很典型的审批场景

用户提交退款申请 → Agent 生成建议处理意见 → 人工审核节点 interrupt → 审核通过后继续执行退款动作

7.2 为什么人工介入不是“框架不够智能”

恰恰相反,它说明你开始按真实业务规则设计系统了。现实世界里很多动作本来就不该全自动:权限审批、金额确认、对外发送、风险控制、法律合规,这些都需要人兜底。

# 伪代码:思路示意,不是完整可运行示例
if need_human_review:
    interrupt({
        "reason": "高风险动作需要人工审核",
        "draft": current_result,
    })

# 人审核后,系统再 resume 继续往下走

7.3 interrupt 场景的测试重点

人工介入测试清单

  • 该停的时候有没有真的停住。
  • 停住时带给人工看的信息是否足够。
  • 人工修改了状态后,后续节点是否正确读取。
  • 恢复后会不会重复执行上一步动作。
  • 人工拒绝时,流程是否能优雅收口。

08. 典型业务场景

下面挑几个非常典型的业务场景,你可以感受一下 LangGraph 为什么在这些地方比普通链式调用更顺手。

8.1 场景一:多阶段客服助手

阶段节点示例为什么像图
意图识别router不同问题分流到不同链
资料收集follow_up字段不全时要循环追问
处理建议draft_solution需要生成建议而不是直接执行
人工审核review高风险单必须人工确认

8.2 场景二:报告生成与复核

先搜集资料,再生成草稿,再校验格式,再让人看一眼。任何一步不过关都可能回退重试。这就是很典型的 plan-execute-review 图。

8.3 场景三:工具链较长的 Agent

比如“查库存 → 算运费 → 判断是否满足活动 → 生成推荐话术”,每一步都有自己的输入输出,还可能有失败重试和人工确认。此时状态图比一长串 if else 更清晰。

LangGraph 在这些场景里的价值

不只是“能跑”,而是“更容易看清流程、保存状态、恢复执行、插入人工、分层测试”。

测试同学能得到什么

更明确的节点边界、更清楚的状态快照、更容易做分支覆盖和恢复测试。

09. 常见坑与设计建议

常见坑为什么会出事建议
状态设计太胖每个节点都在读写一大坨状态,越来越难维护只保留流程推进真正需要的信息
没有明确终止条件循环分支很容易跑飞用 max_rounds、status、done 标志收口
节点副作用过重恢复执行时可能重复发消息、重复下单关键动作做幂等设计
人工介入信息不全人不知道该怎么判断停住时把理由、上下文、候选动作一起给出来
只测 happy path真正难点都在分支、中断、恢复按节点和分支逐层补测试

一句非常现实的提醒。

LangGraph 不是让你把一切都图化,而是当“流程复杂度已经客观存在”时,给你一套更可控的组织方式。为了用图而上图,最后只会增加维护成本。

10. 它如何和 LangChain 配合

学到这里,你应该把二者关系重新理顺了:LangChain 更像“节点里的能力积木”,LangGraph 更像“节点之间的流程编排器”。

层次LangChain 往往负责LangGraph 往往负责
节点内部Prompt、Model、Tool、Parser、Retriever通常不管这么细
节点之间简单串联可以做复杂状态流转和分支控制是强项
运行时控制基础执行线程、检查点、中断恢复、人工介入

图 4:一个典型配合方式 LangGraph 节点 A:调用 LangChain 做分类 ↓ LangGraph 节点 B:调用 LangChain 的 Retriever 做检索 ↓ LangGraph 节点 C:调用 LangChain Tool 执行业务动作 ↓ LangGraph 负责整个任务何时停、何时转、何时恢复

11. 设计一个真实工作流

前面我们讲了概念和模式,这里把它落到一个真实一点的业务场景:售后工单处理流。这个场景很适合教学,因为它天然带分支、带状态、带人工审核、带恢复继续。

阶段节点状态里至少要有什么
问题进入receive_ticketticket_id、user_input、attachments
意图路由route_ticketintent、priority
补资料collect_missing_infomissing_fields、retry_count
处理建议draft_solutionproposal、confidence
人工审核human_reviewreview_status、review_comment
执行动作execute_actionaction_result、done

图 5:一个很典型的 LangGraph 业务流

收单 → 分类分流 → 补资料或给建议 → 人工审核 / 自动执行 / 结束

11.1 设计工作流时最先问的 4 个问题

  • 这条任务真正的开始和结束是什么?
  • 中间有哪些必须分支的条件?
  • 哪些节点有副作用,不能重复执行?
  • 哪些地方必须支持人工介入或恢复继续?

11.2 为什么这个场景用 LangGraph 比 if else 更稳

因为这类流程最麻烦的地方,不是“顺着跑一遍”,而是补资料、重试、审核打回、恢复继续、错误回收这些边边角角。用图来思考,会让这些分支和状态边界更清楚。

12. 测试与排障怎么做

LangGraph 这种带状态的图,测试方法和普通接口页不完全一样。最值钱的测试,往往不是 happy path,而是:分支有没有走对、恢复有没有从正确位置继续、人工介入后状态有没有被正确读写。

12.1 最适合 LangGraph 的测试维度

维度要测什么
节点测试单个节点吃入状态后,是否产生正确状态更新
边测试同一状态在不同条件下是否走对分支
恢复测试checkpoint 后 resume 是否从正确位置继续
人工介入测试人工修改状态后,后续节点是否正确使用
幂等测试副作用节点重复执行时是否会出事故

12.2 一套很实用的排障顺序

  1. 先确认当前 thread 是不是你以为的那条任务。
  2. 再看最近一个 checkpoint 里的 state 到底长什么样。
  3. 确认当前节点读到了哪些字段,缺了哪些字段。
  4. 看边的条件判断是不是和设计一致。
  5. 最后才看模型或 Tool 本身是不是出错。

一句经验。

很多“图跑错了”的问题,根因不是模型,而是状态设计不清、条件分支不清、恢复点不清。LangGraph 项目里,状态就是第一调试对象。

12.3 适合新手照着写的回归模板

测试对象:售后工单 LangGraph 工作流
范围:router / collect_missing_info / draft_solution / human_review / execute_action
核心关注:
1. 不同 intent 是否走对分支
2. 缺字段时是否进入补资料循环
3. human_review interrupt 后是否能正确 resume
4. execute_action 是否具备幂等保护
5. 打回后是否回到正确节点而不是整图重跑

13. 练习题与自查

这一页最怕“概念听着懂,真让你画图就不会”。下面这些题,适合你自己答,也适合带新人时用。

问题你至少要答到什么程度
State 和普通函数参数有什么不同?State 是整条任务共享的上下文,不是某一步的临时局部变量
为什么 checkpoint 很关键?因为长流程可能要暂停、恢复、回放,不能每次从头重来
interrupt 的价值是什么?让人工可以在高风险节点插入决策,而不是强行全自动
为什么副作用节点要做幂等?因为恢复或重试时可能再次执行,不能重复发消息、重复下单

本页自测标准

  • 你能不能自己画出一个“分类 → 分支 → 人审 → 执行”的最小图。
  • 你能不能说清 thread、checkpoint、resume 三者关系。
  • 你能不能说明为什么 LangGraph 比一长串 if else 更适合复杂流程。
  • 你能不能给出 3 条和恢复执行有关的测试点。

14. 学习顺序与官方资料

LangGraph 不适合“空学”。最稳的学习顺序,是先把 LangChain 的单链路积木玩明白,再用 LangGraph 去解决真正复杂的状态图问题。

先学什么

先把 LangChain 的 Prompt、Tool、RAG、Structured Output 理顺。

再学什么

再上 LangGraph,重点盯 State、Node、Edge、Thread、Checkpoint。

怎么练最有效

挑一个真实流程:比如“分类 → 检索 → 生成人工审核草稿 → 审核通过后执行动作”。 学完本页,你至少应该能回答这些问题

  • 为什么 LangGraph 不是“另一个 LangChain”。
  • State、Node、Edge 各自是什么。
  • 为什么 Thread 和 Checkpoint 对恢复执行很关键。
  • 什么时候该引入 interrupt 和人工介入。
  • 复杂工作流为什么更适合图式编排。
  • LangChain 和 LangGraph 在一个项目里各自负责哪一层。

补充参考答案要点

  • 练习题与自查里最关键的是能画清状态流转图,说明每个节点的输入、输出和下一跳条件。
  • 带分支、重试和人工介入的图,要重点验证状态是否被正确保留,失败后是否回到预期节点。
  • 如果图变复杂,优先做节点级断言、边级断言和状态快照,而不是只看最终回答。