「LangChain」LangGraph 的核心优势?更适配哪些 Agent 场景?

0 前言

本文内容整理自公众号「小林面试笔记」的文章 10. LangGraph 相比于 LangChain 有哪些核心优势?更适配哪些 Agent 场景?,用于记录与总结 LangChain 框架相关的核心面试知识点。

LangGraph 相比于 LangChain 有哪些核心优势?更适配哪些 Agent 场景?」,可以这样作答:

先说前提:两者不是互斥的两套 Agent 框架。LangChain v1 提供模型、工具、中间件和预构建的 Agent loop,create_agent 本身就运行在 LangGraph 之上;LangGraph 是更底层的编排框架与运行时,让开发者直接控制状态、节点、边、路由、并行、子图、中断与恢复。所谓核心优势,不是「LangChain 没有这些能力」,而是把复杂 Agent 运行变成显式、可持久化、可观察、可恢复的状态机:确定性规则与模型决策在同一个执行拓扑里各就各位;Checkpointer 按 thread_id 保存检查点、Store 保存跨线程知识,任务可在服务重启后从保存状态继续;interrupt() 让外部系统在节点内任意位置介入;Retry/Timeout/Error Handler 三层容错、只重试失败分支、Time Travel 回放,让失败不必整段重跑。因此更适配长任务、人工审批、故障恢复、并行研究、多 Agent 协作这类场景;简单循环优先 create_agent,复杂业务拓扑才直接使用 LangGraph——且常把 LangChain Agent 作为图中的节点或子图复用。一句话:LangChain 负责把 Agent 开箱即用,LangGraph 负责让系统按你设计的路线可靠地走完。

这道题的雷区是把它答成「LangGraph 比 LangChain 强在哪」的武器对比——上一篇文章我们定过位:LangChain 定协议,LangGraph 跑状态,两者是上下层而不是竞争对手。今天按面试官真的想听的来答:直接使用 LangGraph 时,到底多了哪些控制能力?它们分别解决什么工程问题?哪些场景为此值得放弃高层 API?这篇从显式状态机、持久化与人工介入、容错与恢复、并行与子图、流式与生产逐条展开,最后用采购审批的例子串起来。


1 先说前提:LangGraph 不是 LangChain 的对手

先拉平一个常见误解:很多人一听说「LangGraph 是低层框架」,就默认它是 LangChain 的替代品甚至升级版——这就像拿一台装配好的汽车和它底盘的线控平台比谁更好开,两者根本不在一层。

截至 2026 年 7 月,官方定位非常明确:

  • LangChain v1 是高层 Agent 框架:提供模型、工具、常见 Agent 循环和 middleware,目标是让你快速得到一个能用的 Agent;
  • LangGraph 是低层编排框架与运行时:负责有状态的流程如何执行、如何暂停、如何恢复,create_agent 返回的「编译后的图」本质上就是一个 LangGraph。

整车与底盘比喻:LangChain 像装好方向盘和导航的整车,LangGraph 像开放的控制底盘,车辆内部线路由你决定

用汽车的比喻说:LangChain 像装好方向盘、刹车和导航的整车,调调座椅就能上路;LangGraph 像是把底盘和动力控制系统开放出来,转向、刹车、油门怎么联动、信号往哪走,你来接线。所以「核心优势」这个词要小心用——持久化、流式输出、人工介入不是 LangChain 无法获得的能力create_agent 通过底层运行时全都具备。真正的优势在于控制粒度:直接使用 LangGraph 时,是你来决定这些能力放在哪个节点、围绕哪些状态生效、失败后从哪里恢复、子流程如何组合

还要注意,LangGraph 不是 LangChain 的附属品:它能用 LangChain 的模型和工具组件,但不强制依赖,也可以直接接其他模型的 SDK 或普通 Python 函数。它是一个独立的编排运行时,LangChain 只是常见的「零件供应商」之一。


2 摊开流程与状态:显式状态机

LangGraph 对复杂业务最根本的优势,是把「流程」和「状态」从模型对话的暗盒里摊开成一张可以修改、可以检查的图

先看它提供的原语:

  • State:整个工作流共享的数据结构,分输入、输出、内部通道,节点只返回局部更新;
  • Node:一个执行单元,可以是模型调用、规则函数,也可以是完全不用 LLM 的普通代码;
  • Edge:节点之间的流转关系,条件边根据 State 决定下一步去哪;
  • Reducer:规定并行节点对同一字段的多次写入如何合并(比如「追加」而不是「覆盖」);
  • Command:让一个节点既更新状态、又指定下一步去哪;
  • Send:在运行时才知道任务数量时,动态地把任务分发给多个节点实例。

把它想成一份采购申请单:State 是不断补充内容的申请单(金额、审批意见、检查结果),Node 是窗口(预算窗口、合规窗口、审批窗口),Edge 规定这张单子下一步送去哪里,reducer 约定几个窗口同时填同一栏时怎么落笔——是追加到末尾,还是后写的覆盖先写的。图长什么样,执行就怎么走:哪些节点能并行、哪些必须等前置完成、哪份状态被保存、恢复后从哪继续,全写在图里。

1
2
订单校验 -> [预算检查 | 合规检查] -> 人工审批 --通过--> 执行采购系统
\--拒绝--> 流程结束

对应在 State 里,并行写入的合并规则必须显式声明,比如「多路证据追加到列表,而不是互相覆盖」:

1
2
3
4
5
6
7
from operator import add
from typing import Annotated, TypedDict


class ResearchState(TypedDict, total=False):
# 并行研究节点共同写入的字段:声明为追加合并,而不是后写覆盖先写
evidences: Annotated[list[str], add]

工程上的直接好处是:输入、输出和内部状态可以分离,测试可以只喂输入断言输出,调试可以盯着某一步的状态变化。但自由度意味着责任——错误的 State 设计会造成状态膨胀、并发覆盖、难以维护。这一节的记忆点是:让确定性规则与模型决策各就各位:需要模型判断的步骤交给 Agent,需要严格执行的权限、金额阈值、审批顺序写成节点与边,而不是靠模型「自觉」遵守提示词。


3 两条编排 API:Graph API 与 Functional API

说到「用 LangGraph」,实际有两条入口,别只记得 StateGraph

  • Graph API(StateGraph:显式声明节点和边,适合复杂分支、并行汇合、多 Agent 路由——拓扑清晰,便于可视化和评审;
  • Functional API:通过 @entrypoint@task 装饰器在普通 Python 流程上增加检查点、任务恢复和人工暂停,改造成本低。

两者的定位差异,官方总结过一张选型表,核心结论可以浓缩成下面的对照:

需求特征 更自然的入口 原因
分支和循环很多,需要看清完整拓扑 Graph API 节点、边和共享 State 显式,便于可视化与评审
多路并行后汇合,或多 Agent 交接 Graph API 并发关系、Reducer 和子图边界更容易建模
已有过程式代码,希望少改代码 Functional API 保留普通 Python 控制流,用装饰器增加运行时能力
线性流程加少量条件和人工确认 Functional API 局部变量与函数作用域更自然,样板代码更少
不同子流程复杂度差异很大 混合使用 外层图负责调度,内部函数工作流负责局部步骤

Functional API 的样子,一句话就能看出它为什么适合改造存量代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from langgraph.func import entrypoint, task


@task
def call_llm(question: str) -> str:
# 被 @task 装饰的普通函数:自动获得检查点与任务恢复能力
return llm.invoke(question) # 由项目按实际模型实现


@entrypoint(checkpointer=saver)
def assistant(question: str) -> str:
# 保留普通 if/for 的直写控制流,运行时为其加持久化与恢复
answer = call_llm(question)
return answer

还支持混合使用:外层 StateGraph 负责调度和并行,内部节点调用 Functional API 工作流负责局部步骤。面试时能说出「不是二选一,而是按子流程复杂度选入口」,比只背 API 名字强得多。


4 流程跨小时不丢:持久化与检查点

让长任务「跑着跑着换个班还能继续」,是 LangGraph 被生产系统选中的招牌能力——Persistence(持久化)

机制不复杂:图执行过程中把每一次状态变更保存为 checkpoint,按 thread_id 组织线程状态。有了它,运行可以暂停、服务重启后可以从已保存的状态恢复。这里有两个易混淆的概念,回答时一定要分清:

  • Checkpointer:保存某个线程的图状态快照——回答的是「这次任务走到哪里」;
  • Store:保存图状态之外的应用数据——用户偏好、事实、共享知识,回答的是「以后其他任务还要记住什么」。

Checkpointer 与 Store 分工:线程内的检查点回答这次任务走到哪里,跨线程的 Store 回答以后还要记住什么

像看书:Checkpointer 是夹在书页里的书签,告诉你读到第几页;Store 是旁边的笔记本,记着「这本书是给谁买的」这种不随阅读进度变化的事。持久化不是简单的「把数据存进数据库」——有一个认知必须提前立住:durable execution 不是数据库开关。恢复时,节点代码可能重新执行,模型调用和 API 请求会再次发生,所以外部副作用必须有幂等保护:幂等键、upsert、发送记录、先查后写。否则「恢复」可能变成「重复发邮件、重复扣款」。(Checkpointer 与 Store 的完整机制在「长短期记忆」那篇讲过,这里只强调它们在长任务里的角色。)


5 人工随时进场:interrupt()

很多流程的难点不是「模型不会」,而是「人必须在中间搭一把手」——审批、补充材料、纠偏。LangGraph 的 interrupt() 允许在节点内部的任意位置暂停流程。

它的大致用法是:触发时保存状态,并把一个可序列化的中断载荷交给外部系统(比如审批平台);之后用相同的 thread_idCommand(resume=...) 恢复执行,外部输入会成为 interrupt()返回值,流程继续往下走。

1
2
3
节点开始 -> 中断前逻辑 -> interrupt(载荷) -> 保存 checkpoint
-> 外部审核系统审批 -> Command(resume=审批结果) -> 同一线程恢复
-> 后续路由(注意:节点从头重新执行,而非从 interrupt 处继续)

这比只支持「确认或取消」的审批灵活得多:可以批准、拒绝、修改金额、补充证据,外部系统拿到的是完整的上下文,交回的也是任意结构化数据。

interrupt 与 resume 流程:节点内任意位置暂停,外部系统审批后携带结果恢复,恢复时节点从头执行

两个重要的工程提醒:

  1. 选型:LangChain v1 的 HumanInTheLoopMiddleware 对「审批敏感工具调用」更省事;LangGraph 的优势在审批对象不是标准工具调用(比如审批的是结构化决策)、或暂停点要嵌进更长业务流的时候。
  2. :节点恢复时是从节点开头重新执行,不是从 interrupt() 那一行继续——中断的副作用同样要幂等,否则每次恢复都会重复执行一遍。

面试加分句:「interrupt() 把暂停点从『大门安检』升级成『全程设卡』,每个业务节点都能停下来等外部系统。」


6 失败后不必整段重跑:容错与时间旅行

传统脚本(哪怕有重试)的失败处理是:整段重跑,或手工改数据库再祈祷流程能继续。LangGraph 把失败处理变成工作流的一部分,拆成三层:

  1. Retry Policy:按异常类型和退避策略重试单次失败;
  2. Timeout:限制单次尝试的时间上限;
  3. Error Handler:重试耗尽后接管错误,可以返回 Command 一边更新错误状态、一边把流程送往降级、补偿或人工处理节点。

特别要强调并行节点的失败处理——这是最容易在面试里出彩的点:LangGraph 会保存同一步中已经成功完成节点的结果。恢复时,成功分支不必全部重跑,只重试失败的部分。 对并行抓取多个数据源的深度研究场景,这直接省下真金白银——否则「一个慢接口失败,就让其他已经成功的请求也重新付费」。

再往上还有 Time Travel(时间旅行):通过状态历史找到旧 checkpoint,可以从旧位置重新执行(Replay),或者修改旧状态后分叉出另一条时间线(Fork)——非常适合「模型走错路线,回退到错误发生前重新来」的调试场景。

Time Travel 的 Replay 与 Fork:从旧检查点重演或修改状态后分叉,但不会撤销现实中已发生的外部操作

但要避免夸大——「Time travel 不是把程序时光倒流后原样播放录像」:checkpoint 之前的节点会跳过,之后的节点会重新执行,模型输出、网络响应和外部副作用可能不一样。恢复、重试、时间旅行本质上都会导致代码重复执行,所以这一节和上一节的坑是同一个:所有带副作用的调用都要能安全地执行多次


7 复杂任务并行又汇合:Send、Reducer 与子图

深度研究类任务为什么天生适合图?拆主题 → 并行搜索多个来源 → 交叉验证、合并证据 → 发现空白后继续补搜 → 统一写报告。这类任务的核心矛盾是:分支数量在运行时才知道——Planner 拆出几个主题,取决于输入的问题。

三个机制配齐了才能跑好这种结构:

  • Graph API 支持把任务拆成多条并行分支再汇合:fan-out 从同一节点扇出,fan-in 等所有分支都完成再前进;
  • Send 动态创建分支:运行时才知道任务数量时,按状态内容直接向节点实例分发任务,而不是预先画死并行条数;
  • Reducer 合并写回:并行节点更新同一 State 字段时必须规定合并方式——「不能指望最后写入者碰巧正确」。

深度研究中 Send、Reducer 与子图的分工:Planner 用 Send 分发分支,证据用 Reducer 合并,子图选择 per-thread 或 per-invocation 记忆范围

子图解决的是模块化:一个完整的 LangChain create_agent 返回的本来就是图,可以直接作为外层 StateGraph 的节点或子图——不同团队可以分别维护研究、合规、财务子图。注意子图的记忆范围要显式选择:一次性子任务每次调用从新状态开始(per-invocation);需要连续记忆的子 Agent 才在同线程多次调用间积累状态(per-thread)。

这一节的克制提醒很有必要:多 Agent 不等于效果更好。角色越多,提示词、上下文交接、错误定位和 Token 成本越高。只有角色需要不同工具、不同状态结构、独立生命周期或确实需要并行时,子图才值得引入。


8 全程可见:流式输出来源

生产系统对黑盒运行深恶痛绝,而 LangGraph 的流式输出不只有模型 Token 一种:每一步 State 更新、模型消息、自定义进度、checkpoint 和任务状态都能以事件流的形式输出。

产品上的直接收益是进度可见:界面上可以展示「正在查询政策库」「已完成 3/5 个来源」「等待财务审批」;开发上的收益是可观测:能看到哪个节点更新了什么、哪个任务失败、何时写入检查点。这就像外卖订单:不只在「已接单」和「已送达」之间干等,而是能看到出餐、取餐、配送中的每一步。

需要再厘清一次与 LangChain 的关系:LangChain Agent 运行在 LangGraph 上,同样具备底层流式能力;直接使用 LangGraph 的优势在于——节点和业务阶段由我们定义,流式事件能与产品的进度条、审计日志和告警规则精确对应。配合 LangSmith 的 tracing 和 Studio,还能查看实际走过的节点路径、状态变更和耗时,比「看日志猜流程」可靠得多。


9 走向生产:记忆与部署边界

长任务上生产,绕不开两个问题:记忆怎么存、服务怎么部署。LangGraph 的答案是把记忆分两层:

  • 短期记忆:跟随 State 和 Checkpointer,由 thread_id 隔离——当前会话消息、已完成步骤、审批上下文都在这层;
  • 长期记忆:进入 Store,按 namespace 与 key 组织——用户偏好、历史事实、共享知识。生产环境必须使用数据库后端,并补齐租户隔离、保留期限、删除更正与敏感信息治理。

LangGraph 生产部署架构:图运行时与 Agent Server、Postgres、Redis 等基础设施的组合关系

部署边界也要讲清楚:开源 LangGraph 是编排框架和运行时,不等于托管服务。可以自行托管,自己接 Checkpointer、Store 和任务队列;也可以使用托管的 Agent Server,把图、持久化数据库与任务队列组合成服务。面试时的加分话术是主动破除误区:别说出「用了 LangGraph 就自动高可用」——自托管时,数据库、任务队列、Worker 扩缩容、重试策略、监控和数据保留仍然是团队自己的责任。


10 一个完整例子:采购审批 Agent

把前面的能力串起来,看官方风格的「采购审批」示例——它有四件事值得我们注意:

  1. 业务拓扑是显式的StateGraph 声明节点和边,谁先谁后、谁并行一清二楚;
  2. 两项检查能并行且有明确汇合点:从 normalize 扇出到两个检查节点,两项都完成后才进入人工审批;
  3. 人工审批可以跨时间暂停interrupt() 把载荷交给审核系统,Command(resume=...) 带回结果;
  4. 执行动作有业务幂等键request_id 既是线程标识的一部分,也用来防止恢复或重试造成重复采购。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
from typing import Literal, TypedDict

from langgraph.checkpoint.memory import InMemorySaver
from langgraph.graph import END, START, StateGraph
from langgraph.types import Command, interrupt


class PurchaseState(TypedDict, total=False):
# request_id 也可作为外部采购接口的幂等键
request_id: str
amount: float
budget_ok: bool
compliance_ok: bool
approved: bool
result: str


def normalize_request(state: PurchaseState) -> dict:
# 真实项目应在这里完成字段校验和权限检查
return {"amount": round(state["amount"], 2)}


def check_budget(state: PurchaseState) -> dict:
# 该节点可以替换为预算系统查询,并配置重试与超时
return {"budget_ok": state["amount"] <= 100_000}


def check_compliance(state: PurchaseState) -> dict:
# 与预算检查写入不同字段,因此两个节点可以安全并行
return {"compliance_ok": True}


def human_review(state: PurchaseState) -> dict:
# 暂停流程,将两项检查结果交给审核系统
review = interrupt(
{
"request_id": state["request_id"],
"budget_ok": state["budget_ok"],
"compliance_ok": state["compliance_ok"],
}
)
return {"approved": bool(review["approved"])}


def route_after_review(state: PurchaseState) -> Literal["execute", "reject"]:
# 审批结果决定后续确定性路径
return "execute" if state["approved"] else "reject"


def execute_purchase(state: PurchaseState) -> dict:
# 真实调用必须携带 request_id,防止恢复或重试造成重复采购
return {"result": f"采购申请 {state['request_id']} 已执行"}


def reject_purchase(state: PurchaseState) -> dict:
# 拒绝路径不触发外部采购副作用
return {"result": "采购申请未通过"}


builder = StateGraph(PurchaseState)
builder.add_node("normalize", normalize_request)
builder.add_node("budget", check_budget)
builder.add_node("compliance", check_compliance)
builder.add_node("human_review", human_review)
builder.add_node("execute", execute_purchase)
builder.add_node("reject", reject_purchase)

builder.add_edge(START, "normalize")
# 从同一节点扇出,预算和合规检查进入并行分支
builder.add_edge("normalize", "budget")
builder.add_edge("normalize", "compliance")
# 使用多起点边做 fan-in,两项检查都完成后才进入人工审批
builder.add_edge(["budget", "compliance"], "human_review")
builder.add_conditional_edges("human_review", route_after_review)
builder.add_edge("execute", END)
builder.add_edge("reject", END)

# 内存检查点仅用于示例,生产环境应替换为数据库后端
graph = builder.compile(checkpointer=InMemorySaver())

# thread_id 是暂停、恢复和状态历史的定位依据
config = {"configurable": {"thread_id": "purchase-2026-001"}}
graph.invoke(
{"request_id": "PO-001", "amount": 58_000},
config=config,
)

# 审核员稍后提交结果,图从同一线程的中断点恢复
final_state = graph.invoke(
Command(resume={"approved": True}),
config=config,
)
print(final_state["result"])

生产化还差三步:给外部查询(预算系统、合规系统)增加 Retry Policy 与 Timeout;给执行失败设计补偿或人工接管路径;把 InMemorySaver 换成持久化实现。而和 LangChain 的自然组合是:用 create_agent 做「材料理解」或「异常解释」这类靠模型的节点,外层采购流程仍由 StateGraph 控制——这正是前面说的「把 LangChain Agent 作为图中的节点或子图」。


11 选型:哪些场景该用、哪些不必用

回答最后一个问题:什么时候值得直接上 LangGraph? 面试官想听的判断标准只有一句话——

这个系统最难的是「让模型会用工具」,还是「让整个任务可靠地走完一条复杂路线」?前者留在 LangChain,后者交给 LangGraph。

适合 LangGraph 的四类场景:

  1. 业务顺序不能交给模型自由发挥:理赔、退款、采购、合同审核、生产变更——明确阶段、权限与审批点,模型只能参与理解和判断,真正的路线由确定性规则控制;
  2. 跨时间运行的任务:深度研究、报表生成、代码迁移、跨系统工单,持续数十分钟到数天,需要 checkpoint、interrupt 和 durable execution 保住进度;
  3. 长出并行分支的任务:Planner 临时拆出多个研究主题,各分支搜索、抽取、验证,用 Reducer 汇总;多 Agent 因不同工具、状态或团队边界组成子图;
  4. 需要干预中间状态的调试场景:复杂 RAG 证据不足时改写查询重检索,模型走错路线时查看 checkpoint、修改状态后重放。

不必要用 LangGraph 的三类:

  1. 标准工具调用 Agent:查天气、查订单、总结文档,create_agent 更快、更短,也符合团队认知;
  2. middleware 能解决的:动态提示词、模型切换、工具过滤、消息摘要、重试、护栏、敏感工具审批,先看 LangChain middleware;
  3. 固定流程:只有固定的 Prompt、模型和解析器,普通函数、LCEL 或一个队列任务可能就够了。

选型对照可以浓缩成一张表:

判断问题 优先 LangChain create_agent 考虑直接使用 LangGraph
主流程 常见模型与工具循环 多阶段业务工作流
路由由谁决定 模型 模型 + 确定性规则混合
状态复杂度 简单 复杂共享状态
运行时长 单次交互或短任务 跨小时、跨天
人工介入 审批敏感工具调用 任意阶段补充、修改、审批、改道
并行结构 少量并行 动态 fan-out / fan-in / map-reduce
角色数量 单 Agent 多 Agent / 子图 / handoff
故障处理 通用重试 节点级恢复、补偿、历史分叉
团队成本 快速交付 愿意维护图、状态与恢复语义

渐进式选型路径(这是官方推荐,也是面试的收尾答案):先用 LangChain 搭出能工作的 Agent;当 middleware 已承担不了业务路由、状态字段越来越多、任务必须跨时间恢复时,把外围流程下沉到 LangGraph;已有 Agent 直接成为图里的节点或子图。最后破除一个误区:图越复杂,不代表系统越智能——节点过细会增加 checkpoint、序列化与维护成本,节点过粗会降低恢复粒度;边界应该按副作用、重试、人工介入和可观测性划分,而不是越大越显得高级。


12 面试总结

回答这道题,最大的雷是把它答成「LangGraph 是 LangChain 的替代品」的能力对比。先避开几个误区:

误区 正解
LangGraph 相比 LangChain 的优势是持久化、流式、人工审批「它有而对方没有」 create_agent 运行在 LangGraph 上,这些能力两边都有;真正的优势是控制粒度——能力放在哪个节点、围绕哪些状态、失败从哪恢复
LangGraph 必须配合 LangChain 使用 不强制依赖,可接其他模型 SDK 或普通 Python 函数;LangChain 只是常见零件供应商
用 LangGraph 就等于自动高可用 开源 LangGraph 只是编排运行时;数据库、队列、扩缩容、监控仍是自托管团队的责任
多 Agent / 大图 = 更智能 角色越多成本越高;图越复杂不代表系统越智能,节点粒度应按副作用、重试、人工介入和可观测性划分
持久化 = 数据存进数据库 durable execution 恢复时会重新执行节点,外部副作用必须幂等;Time Travel 也不会撤销现实中已发生的操作
所有 Agent 项目都应该下沉 LangGraph 标准工具调用循环用 create_agent + middleware 更快;成熟方案是渐进式下沉,LangChain Agent 作为节点或子图复用

再按「控制、可靠、工程化」三条主线组织答案(按面试原题《LangGraph 相比于 LangChain 有哪些核心优势》):

主线 机制 解决什么问题
控制 State、Node、Edge、条件路由显式化 确定性规则与模型决策在同一个执行拓扑里各就各位
控制 Reducer 声明合并、Command 边改状态边改道、Send 动态分发 并行写入、动态分支、运行期才知道的任务量
控制 两种编排 API:Graph API 与 Functional API 按拓扑复杂度选入口,存量过程式代码低成本改造
可靠 Checkpointer 按 thread_id 保存检查点 长任务可暂停、服务重启可恢复
可靠 interrupt() + Command(resume=...) 外部系统在节点内任意位置介入、携带结构化结果返回
可靠 Retry/Timeout/Error Handler + 只重试失败分支 + Time Travel 失败不必整段重跑,支持补偿、降级与历史分叉
工程化 流式事件(State 更新、进度、task 状态) 进度可见、审计对齐、配合 LangSmith 定位问题
工程化 短期/长期记忆分层 + 自托管或 Agent Server 有状态、长时间运行的生产系统

追问预案

  • 「LangGraph 的核心优势到底怎么概括?」——把复杂 Agent 运行变成显式、可持久化、可观察、可恢复的状态机;LangChain 与 LangGraph 都有这些能力,差别在直接使用 LangGraph 时由开发者决定这些能力的位置和控制粒度。
  • 「持久化和记忆怎么区分?」——Checkpointer 按 thread_id 保存线程级状态快照(这次任务走到哪里);Store 保存跨线程的应用数据(以后还要记住什么);两者都可用数据库后端生产化。
  • 「人工介入只能审批工具调用吗?」——interrupt() 可在节点内任意位置暂停,载荷与恢复值都是结构化数据,支持批准、拒绝、修改金额、补充证据;LangChain 的 HumanInTheLoopMiddleware 更省事但只面向标准工具调用。
  • 「失败恢复会不会重复执行副作用?」——会。恢复、重试、时间旅行都会让节点代码重新执行,外部副作用必须有幂等键、upsert 或先查后写等幂等保护。
  • 「什么时候用 Functional API?」——已有过程式代码、线性流程加少量条件或人工确认时;复杂分支并行适合 Graph API,两者可混合使用。
  • 「LangGraph 和 LangChain 怎么配合?」——create_agent 返回的图可作为外层 StateGraph 的节点或子图,middleware 跟着一起工作;真实项目常见方案不是二选一,而是让 LangChain Agent 成为 LangGraph 中可复用的节点或子图。

参考

本文图片均来源于公众号「小林面试笔记」,版权归原作者所有。


「LangChain」LangGraph 的核心优势?更适配哪些 Agent 场景?
https://marisamagic.github.io/2026/08/27/20260827_LangGraph核心优势/
作者
MarisaMagic
发布于
2026年8月27日
许可协议