LangGraph 为什么适合做 Agent 编排?它和 LangChain 到底差在哪?
过去很多人做大模型应用,第一反应就是用 LangChain。
因为 LangChain 把模型调用、Prompt、工具调用、RAG、Agent 都封装好了。做一个简单 Demo 很快,几行代码就能让大模型调用工具、回答问题、查资料。
但是当你真正开始做一个复杂 Agent 系统时,很快就会遇到这些问题:
1. Agent 执行过程不是一条直线,而是会循环、分支、重试。 2. 工具调用后,结果还要继续喂给模型判断下一步。 3. 一个任务可能要执行很久,中途失败后希望能从上一步恢复。 4. 有些关键步骤需要人工确认,比如删除文件、执行 SQL、发送邮件。 5. 多 Agent 协作时,需要明确每个 Agent 的职责和状态流转。 6. 你希望看到 Agent 当前执行到哪一步,而不是一个黑盒。这时候,仅仅用普通的 Chain 或者简单 Agent 抽象,就会显得不够用了。
这也是 LangGraph 出现的原因。
一句话总结:
LangChain 更像是大模型应用开发工具箱,LangGraph 更像是 Agent 编排运行时。
LangChain 官方文档也明确说明,LangChain 提供预构建 Agent 架构和模型、工具集成,适合快速构建 LLM 应用;而 LangGraph 是更底层的编排框架,适合处理确定性流程和 Agent 动态流程混合的复杂场景。并且,当前 LangChain 的 Agent 本身也是构建在 LangGraph 之上的,用来获得持久化执行、人工介入、状态持久化等能力。
一、先说结论:LangChain 和 LangGraph 不是替代关系
很多人会问:
有了 LangGraph,是不是就不用 LangChain 了?不是。
它们不是简单的替代关系,而是分层关系。
可以这样理解:
LangChain:组件层 / 应用开发层 LangGraph:编排层 / 状态机运行时更具体一点:
LangChain 负责: - 对接模型 - 对接工具 - 构造 Prompt - 快速创建 Agent - 做 RAG - 做结构化输出 - 提供大量生态集成 LangGraph 负责: - 定义节点 - 定义状态 - 定义边 - 定义条件分支 - 控制循环 - 保存执行状态 - 支持中断和恢复 - 支持人工审批 - 支持多 Agent 编排所以你可以在 LangGraph 的节点里面继续使用 LangChain 的模型、工具、Retriever、PromptTemplate。
也就是说:
LangChain 负责“能力组件”,LangGraph 负责“流程控制”。
二、为什么普通 Chain 不适合复杂 Agent?
早期很多 LLM 应用都是 Chain 思维。
比如:
用户输入 ↓ Prompt 模板 ↓ 调用模型 ↓ 返回结果稍微复杂一点:
用户输入 ↓ 检索知识库 ↓ 拼接 Prompt ↓ 调用模型 ↓ 输出答案这类流程是典型的线性流程。
它适合:
总结文章 翻译文本 生成标题 RAG 问答 结构化抽取 简单工具调用但是 Agent 不是这样。
Agent 的核心问题是:下一步不一定提前固定,而是要根据当前状态动态决定。
比如一个浏览器 Agent:
用户:帮我查一下某商品价格,并整理成表格。 Agent 可能需要: 1. 打开浏览器 2. 搜索商品 3. 进入网页 4. 发现页面加载失败 5. 换一个站点 6. 抽取价格 7. 判断价格信息是否完整 8. 如果不完整,继续打开其他页面 9. 最后生成表格这个过程不是简单的:
A → B → C → D而更像:
A → B → 判断 ↓ 成功 → C ↓ 失败 → 重试 / 换工具 / 走人工确认这就是图结构更适合 Agent 的原因。
三、LangGraph 的核心思想:把 Agent 变成一个状态图
LangGraph 最重要的思想是:
把 Agent 的执行过程建模成一个有状态的图。
图里面有几个关键概念:
State:状态 Node:节点 Edge:边 Conditional Edge:条件边 Checkpoint:检查点你可以把它想象成一个后端状态机。
例如:
START ↓ 理解用户意图 ↓ 是否需要工具? ├── 是 → 调用工具 → 整理工具结果 → 是否继续? │ ├── 是 → 再次调用模型 │ └── 否 → 输出最终答案 └── 否 → 直接回答 ↓ END这个结构天然适合 Agent。
因为 Agent 的执行过程本来就是:
状态变化 + 条件判断 + 循环执行 + 工具调用LangGraph 官方文档也把 LangGraph 定位为适合长时间运行、有状态工作流和 Agent 的底层基础设施,核心能力包括 durable execution、streaming、human-in-the-loop、memory、persistence 等。
四、LangChain 和 LangGraph 的真正区别
下面这张表可以直接看出差异。
对比项 LangChain LangGraph
核心定位 LLM 应用开发框架 Agent 编排运行时
使用方式 组件组合、快速开发 图结构、状态机、流程控制
适合场景 简单 Agent、RAG、工具调用、模型封装 复杂 Agent、多步骤任务、多 Agent、长任务
状态管理 高层封装为主 State 是核心概念
分支控制 可以做,但复杂后不直观 原生支持条件边
循环能力 简单 Agent 内部封装 原生支持循环图
失败恢复 不是核心重点 通过 checkpoint 支持恢复
人工介入 可以集成 原生强调 human-in-the-loop
多 Agent 协作 可以做 更适合表达多节点、多角色协作
控制度 更偏开箱即用 更偏精细控制
简单说:
想快速做一个能用的 Agent:LangChain 更快。 想做一个可控、可恢复、可观测的复杂 Agent:LangGraph 更合适。五、为什么 Agent 编排需要“状态”?
做 Agent 最容易踩的坑,就是把它当成一次普通函数调用。
比如:
result=agent.run(user_input)这看起来很简单,但真实 Agent 执行时,中间会产生大量状态:
用户原始问题 当前任务目标 模型思考结果 工具调用记录 工具返回结果 当前执行步骤 失败次数 是否需要人工确认 已生成的文件 已打开的网页 当前浏览器页面 中间产物 最终答案如果没有统一的状态对象,这些内容就会散落在代码里:
session 里一部分 数据库里一部分 内存变量里一部分 工具结果里一部分 prompt 里一部分系统越做越乱。
LangGraph 的做法是:先定义 State。
例如:
fromtypingimportTypedDict,Optional,Literalfromlanggraph.graphimportStateGraph,START,ENDclassAgentState(TypedDict):user_input:strintent:Optional[str]need_tool:booltool_result:Optional[str]final_answer:Optional[str]这个 State 就是 Agent 执行过程中的“上下文快照”。
每个节点接收 state,然后返回对 state 的更新。
例如:
defanalyze_intent(state:AgentState):user_input=state["user_input"]if"计算"inuser_inputor"查询"inuser_input:return{"inte