LangChain Agent vs Deep Agents vs LangGraph 真实代码对比
下面用同一个业务场景(“研究助手:搜索资料 + 写报告”)三种实现方式对比,让你一眼看出差异。
一、对比总览(先看结论)
| 维度 | LangChain Agent | Deep Agents | LangGraph |
|---|---|---|---|
| 定位 | 标准 ReAct Agent | 开箱即用"豪华版"Agent | 底层流程编排框架 |
| 代码量(最小可用) | ~10 行 | ~5 行 | ~30-50 行 |
| 控制流 | 模型自己决定(隐式循环) | 模型自己决定(带规划) | 你来定义节点和边 |
| 上下文管理 | 全部塞进 messages | 自动压缩 + 虚拟文件系统 | 自定义 State |
| 子 Agent | 不原生支持 | 原生支持subagents | 手动嵌套 graph |
| 适合场景 | 单一任务、工具调用 | 长程任务、复杂研究 | 确定性流程、审批流、多分支 |
| 学习曲线 | 低 | 极低 | 高 |
| 灵活度 | 中 | 中(高层抽象) | 极高 |
二、场景设定
任务:用户问一个问题,Agent 要:
- 搜索网络
- 读取/写入文件做笔记
- 最后输出一份报告
defweb_search(query:str)->str:"""Search the web for the given query."""returnf"results for{query}..."defwrite_note(filename:str,content:str)->str:"""Write content to a file."""withopen(filename,"w")asf:f.write(content)returnf"saved{filename}"三、方案 A:LangChain Agent(标准做法)
fromlangchain.agentsimportcreate_agent agent=create_agent(model="openai:gpt-5.4",tools=[web_search,write_note],system_prompt="You are a research assistant. Search, take notes, then summarize.",)result=agent.invoke({"messages":[{"role":"user","content":"Research LangGraph and write a report."}]})print(result["messages"][-1].content_blocks)特点
- 一个函数搞定:
create_agent把"模型 + 工具 + 提示词"打包成 ReAct 循环 - 隐式循环:模型自己决定调几次工具、何时停止
- 上下文 = messages 数组:所有工具调用结果都堆在 messages 里,长任务容易爆 context
局限
- 不能控制"先搜索再总结"这种顺序
- 工具调用结果太多 → token 爆炸 → 模型遗忘前面的内容
- 没法做"审批"、“分支”、“多 Agent 协作”
四、方案 B:Deep Agents(开箱即用豪华版)
fromdeepagentsimportcreate_deep_agent agent=create_deep_agent(tools=[web_search],instructions="You are a research assistant. Plan, research, and write a report.",)result=agent.invoke({"messages":[{"role":"user","content":"Research LangGraph and write a report."}]})它"白送"给你什么
Deep Agents 在create_agent基础上自动注入了 4 个内置能力:
| 内置能力 | 解决的痛点 |
|---|---|
| 规划工具(write_todos) | Agent 先列计划再执行,不再"想到啥做啥" |
| 虚拟文件系统(ls/read_file/write_file/edit_file) | 长结果存到"文件"里,主对话只保留摘要 → 不爆 context |
| 子 Agent 派生(task) | 主 Agent 可以让子 Agent 干脏活,结果只回传摘要 |
| 专门优化的系统提示词 | 内置 Anthropic Claude Code 风格的 prompt |
典型用法(带子 Agent 配置)
fromdeepagentsimportcreate_deep_agent research_subagent={"name":"research-agent","description":"Used to do deep research on a topic.","prompt":"You are a research expert. Search thoroughly and return findings.","tools":["web_search"],}agent=create_deep_agent(tools=[web_search],instructions="You are the lead researcher. Delegate deep research to subagents.",subagents=[research_subagent],)何时选 Deep Agents
- 长程任务(要跑几十轮工具调用)
- 研究/编码类(结果体量大,需要"暂存"到文件)
- 想要Claude Code / Manus 那种体验,但又不想自己造轮子
五、方案 C:LangGraph(底层流程控制)
LangGraph 是最底层的——你自己画状态机:节点 + 边 + 状态。
fromtypingimportAnnotated,TypedDictfromlanggraph.graphimportStateGraph,START,ENDfromlanggraph.graph.messageimportadd_messagesfromlangchain.chat_modelsimportinit_chat_modelfromlanggraph.prebuiltimportToolNode,tools_conditionclassState(TypedDict):messages:Annotated[list,add_messages]notes:strllm=init_chat_model("openai:gpt-5.4")tools=[web_search,write_note]llm_with_tools=llm.bind_tools(tools)defplanner(state:State):return{"messages":[llm.invoke([{"role":"system","content":"Make a plan first."}]+state["messages"])]}defresearcher(state:State):return{"messages":[llm_with_tools.invoke(state["messages"])]}defsummarizer(state:State):summary=llm.invoke([{"role":"system","content":"Summarize all findings into a report."}]+state["messages"])return{"messages":[summary],"notes":summary.content}graph=StateGraph(State)graph.add_node("planner",planner)graph.add_node("researcher",researcher)graph.add_node("tools",ToolNode(tools))graph.add_node("summarizer",summarizer)graph.add_edge(START,"planner")graph.add_edge("planner","researcher")graph.add_conditional_edges("researcher",tools_condition,{"tools":"tools",END:"summarizer",})graph.add_edge("tools","researcher")graph.add_edge("summarizer",END)app=graph.compile()result=app.invoke({"messages":[{"role":"user","content":"Research LangGraph and write a report."}],"notes":"",})特点
- 流程是写死的:
planner → researcher ↔ tools → summarizer → END - State 自定义:除了 messages 还能挂
notes、step_count、任何业务字段 - 可加人工审批:在某条边上
interrupt(),等人工 approve 再继续 - 天然可持久化:用 checkpointer 一行配好,崩了能续跑
何时必须用 LangGraph
- 需要确定性流程(必须先 A 再 B 再 C)
- 需要人工介入(审批、修改、确认)
- 需要多 Agent 协作但流程要可控(不放心让 LLM 自己调度)
- 需要可恢复执行(任务跑一半 crash 了能续上)
六、三者关系图(一图流)
┌─────────────────────────────────────────────────────┐ │ Deep Agents │ ← 最高层封装 │ (内置规划 + 虚拟FS + 子Agent + 优化prompt) │ ├─────────────────────────────────────────────────────┤ │ LangChain create_agent │ ← 标准 ReAct │ (模型 + 工具 + 循环) │ ├─────────────────────────────────────────────────────┤ │ LangGraph │ ← 底层引擎 │ (StateGraph / Node / Edge / Checkpoint) │ └─────────────────────────────────────────────────────┘关键事实:上面两层都是基于 LangGraph 实现的。
create_agent内部其实就是一个预定义好的 LangGraph:agent_node ↔ tool_node的循环。
Deep Agents 又在create_agent之上注入了文件系统工具和子 Agent 工具。
七、关键差异对照(同一行为)
1. 添加"工具"
# LangChain Agentcreate_agent(model=...,tools=[fn1,fn2])# Deep Agentscreate_deep_agent(tools=[fn1,fn2],instructions=...)# 自动多送你: write_todos / read_file / write_file / edit_file / ls / task# LangGraphToolNode([fn1,fn2])# 还要自己接到图上2. 控制"必须先做 A 再做 B"
# LangChain Agent# ❌ 做不到,只能在 system_prompt 里"求"模型先做 A# Deep Agents# ⚠️ 同上,靠 prompt 引导,但因为有 todo 工具会更稳# LangGraphgraph.add_edge("step_a","step_b")# ✅ 硬约束3. 加"人工审批"
# LangChain Agent / Deep Agents# ❌ 原生不支持(要 hack)# LangGraphfromlanggraph.typesimportinterruptdefapproval_node(state):decision=interrupt({"question":"approve?"})return{"approved":decision}4. 处理"工具结果超长"
# LangChain Agent# ❌ 全塞 messages → 直接爆 context# Deep Agents# ✅ 自动写入虚拟文件系统,messages 里只留 "已保存到 results.md"# LangGraph# ✅ 自己定 State:把长结果存到 state["files"],messages 只放摘要八、怎么选?(决策树)
你的任务是什么? │ ├─ 简单问答 + 几个工具调用就够? │ └─→ LangChain Agent ✅ │ ├─ 长程研究/写代码/写文档,怕爆 context? │ └─→ Deep Agents ✅ │ ├─ 流程必须可控?要审批/分支/可恢复?多 Agent 编排? │ └─→ LangGraph ✅ │ └─ 我全都要? └─→ LangGraph 打底 + create_agent 当节点 + Deep Agents 思路引入虚拟FS九、实战建议
- 从 LangChain Agent 开始练手——先理解工具调用循环
- 遇到 context 爆炸 → 升级到 Deep Agents——白送一堆能力
- 遇到流程失控 / 要上生产 → 落到 LangGraph——用 State + 节点把控
- 三者可以混用:LangGraph 的某个节点内部完全可以跑
create_agent或 Deep Agent
参考文档:
- LangChain Overview
- LangChain Agents
- Deep Agents
- LangGraph