刚开始接触 LangChain 生态时,经常会同时看到三个名字:LangChain、LangGraph 和 Deep Agents。
它们都可以参与 Agent 开发,但解决的问题并不完全相同。LangChain 提供常用的模型、工具和 Agent 抽象;LangGraph 负责更底层的工作流编排与运行;Deep Agents 则在这些能力之上,进一步提供任务规划、文件系统、子 Agent 等复杂任务所需的基础设施。
如果一开始没有分清这几个层次,很容易陷入 API 对比:create_agent 和 create_deep_agent 有什么区别,什么时候又需要自己写 StateGraph。
一、Agent 应用的基本运行方式
我们先从最简单的 LLM 应用开始。
如果只是让模型生成或总结一段文本,程序通常只有一次模型调用:
用户输入
↓
Prompt
↓
LLM
↓
模型输出
这种结构并不复杂。程序准备输入,将内容发送给模型,然后接收模型返回的结果。
但实际应用很快会遇到另一类任务。
例如:
查询北京今天的天气,并判断是否适合户外跑步。
模型本身并不知道实时天气,因此需要调用天气 API。与此同时,程序还要判断什么时候调用工具、传什么参数,以及得到工具结果后下一步应该做什么。
整个过程开始变成:
用户提出任务
↓
模型判断下一步
↓
调用工具
↓
获取工具结果
↓
再次交给模型
↓
继续执行或返回答案
这类结构通常被称为 模型—工具循环(Model-Tool Loop)。
模型并不是一次性给出答案,而是在执行过程中不断判断当前状态,并决定下一步行动。
当任务进一步复杂以后,还会出现更多问题:
- 如何保存执行过程中的数据;
- 工具调用失败以后怎样处理;
- 某个步骤是否允许重新执行;
- 是否需要人工批准;
- 一个任务是否需要拆给其他 Agent;
- 上下文越来越长以后怎样管理。
LangChain、LangGraph 和 Deep Agents,就是围绕这些问题提供不同层次的解决方案。
二、LangChain 的定位与基本使用
LangChain 是一个开源的 LLM 应用与 Agent 开发框架。
当前官方文档将它定位为一套提供预构建 Agent 架构、模型集成和工具集成的框架。开发者可以使用相对统一的接口连接不同模型和工具,并快速构建 Agent。
如果直接使用不同模型厂商的 SDK,开发者往往需要分别处理消息格式、工具调用格式、模型初始化以及不同供应商之间的接口差异。
LangChain 在这些能力之上增加了一层统一抽象。
一个最简单的 Agent
先安装 LangChain:
pip install -U langchain "langchain[openai]"
然后定义一个工具:
from langchain.agents import create_agent
def get_weather(city: str) -> str:
"""查询指定城市的天气。"""
return f"{city}今天晴,25℃"
agent = create_agent(
model="openai:gpt-5.4",
tools=[get_weather],
system_prompt="你是一名天气助手,请根据工具返回的信息回答问题。",
)
result = agent.invoke(
{
"messages": [
{
"role": "user",
"content": "北京今天天气怎么样?适合跑步吗?",
}
]
}
)
print(result["messages"][-1].content)
官方当前的 Python 文档使用 langchain.agents.create_agent 创建 Agent,并支持通过 provider:model 的形式指定模型。
运行结果
使用真实的模型 API Key,运行上述代码,输出示例如下:
北京今天晴,气温约 25℃。
从天气条件来看比较适合户外跑步。
如果阳光较强,可以避开中午时段,并注意补水。
模型生成内容可能略有不同。
这里比较重要的地方是,我们没有在业务代码里直接写:
get_weather("北京")
Agent 会先读取用户的问题,然后由模型判断是否需要调用 get_weather。
如果决定调用工具,模型会生成工具参数;工具执行完成后,结果重新进入 Agent 的消息上下文,模型再根据这些信息生成最终回答。
这就是 LangChain 帮开发者封装掉的一部分工作。
LangChain Agent 的运行方式
可以把它简化成:
┌──────────┐
│ Model │
└────┬─────┘
│
是否调用工具
↙ ↘
是 否
↓ ↓
Tool 返回
│
└────→ Model
模型可以多次调用工具,直到认为任务已经完成。
LangChain 的 Agent 并不是自己实现了一套完全独立的运行时。官方文档明确说明,LangChain Agent 建立在 LangGraph 之上,因此可以获得持久化、Human-in-the-loop 和 Durable Execution 等运行能力。
实际项目中,如果需求主要是:
用户提出任务
→ Agent 判断
→ 调用若干工具
→ 返回结果
通常从 LangChain 的 create_agent 开始即可,没有必要立即自己编写复杂工作流。
三、LangGraph 的工作流编排机制
LangChain Agent 已经解决了常见的模型—工具循环,但有些应用需要更明确地控制执行流程。
例如一个内容研究系统可能规定:
接收主题
↓
搜索资料
↓
分析资料
↓
质量检查
↓
是否合格
↙ ↘
否 是
↓ ↓
重新搜索 生成文章
这里已经不只是“模型要不要调用工具”。
业务本身存在明确的步骤、分支和循环。
LangGraph 就是针对这类问题设计的。
官方目前将 LangGraph 定义为一个低层级的 Agent 编排框架和 Runtime,用于构建、管理和部署长期运行、具有状态的 Agent。LangGraph 主要关注 Agent Orchestration,而不是替开发者封装所有上层能力。
State、Node 和 Edge
理解 LangGraph,可以先记住三个基本概念。
状态(State),保存整个工作流执行过程中需要持续传递的数据。
节点(Node),执行具体工作,例如调用模型、搜索数据库或者运行普通 Python 函数。
边(Edge),决定一个节点执行完成以后进入哪个节点。
下面先看一个不使用 LLM 的最简单示例:
from typing_extensions import TypedDict
from langgraph.graph import StateGraph, START, END
class State(TypedDict):
topic: str
result: str
def generate_title(state: State):
return {
"result": f"{state['topic']}入门指南"
}
builder = StateGraph(State)
builder.add_node("generate_title", generate_title)
builder.add_edge(START, "generate_title")
builder.add_edge("generate_title", END)
graph = builder.compile()
result = graph.invoke(
{
"topic": "LangGraph",
"result": "",
}
)
print(result)
运行结果
这段代码不依赖模型,但需要安装 LangGraph。按照代码逻辑,其运行结果如下:
{
'topic': 'LangGraph',
'result': 'LangGraph入门指南'
}
执行开始时,State 中保存两个字段:
topic = "LangGraph"
result = ""
工作流进入 generate_title 节点以后,节点根据 topic 生成一个新的 result。
节点返回的内容会更新 State,然后工作流沿着 Edge 进入 END。
这个例子虽然简单,但已经包含了 LangGraph 最主要的结构:
State
↓
START
↓
Node
↓
END
真实项目可以继续添加更多 Node,并通过条件边构建分支和循环。
因此,LangGraph 更关心的不是“模型如何回答”,而是:
整个任务应该以什么顺序执行,以及执行过程中的状态怎样流动。
四、LangGraph 的状态与持久化
如果工作流只有两三个函数,其实直接写 Python 代码也完全可以:
data = search(topic)
analysis = analyze(data)
article = write(analysis)
LangGraph 的价值通常在流程变长以后才会更加明显。
假设一个研究 Agent 已经执行了:
搜索资料
↓
整理资料
↓
提取事实
↓
生成文章
如果执行到最后一步时程序异常退出,一个直接串联函数的实现往往需要自己设计恢复机制。
对于调用多个外部 API、运行时间较长的 Agent,这会逐渐变成一个实际工程问题。
Checkpoint
LangGraph 提供了持久化机制。
当 Graph 编译时配置 Checkpointer,LangGraph 可以在执行过程中保存 Graph State 的快照,也就是 Checkpoint。这些状态按照 Thread 组织。
例如:
from langgraph.checkpoint.memory import InMemorySaver
checkpointer = InMemorySaver()
graph = builder.compile(
checkpointer=checkpointer
)
调用时再指定 thread_id:
config = {
"configurable": {
"thread_id": "research-001"
}
}
result = graph.invoke(
{
"topic": "LangGraph",
"result": "",
},
config=config,
)
运行结果
上述示例与前面的确定性 Graph 相同,其运行结果如下:
{
'topic': 'LangGraph',
'result': 'LangGraph入门指南'
}
区别不在最终输出,而在执行过程中产生了可管理的状态记录。
官方文档将持久化作为多个能力的基础,包括 Human-in-the-loop、Memory、Time Travel 和 Fault Tolerance。
例如一个审批流程可以运行到某个节点暂停:
生成方案
↓
等待人工审核
↓
批准 / 修改
↓
继续执行
程序不需要一直占用一个进程等待用户。
工作流可以把当前状态保存下来,之后在同一个 Thread 上恢复执行。
理解这一点以后,就能看出 LangGraph 中 State 的意义。
它不只是几个 Python 变量,而是整个长期运行工作流的执行上下文。
五、Deep Agents 的定位与主要能力
当 Agent 开始处理开放式、多步骤任务时,单纯拥有模型和工具还不够。
例如让 Agent:
调研某个技术方向,并最终生成一份完整报告。
真正执行起来,可能需要:
理解任务
↓
拆分研究方向
↓
制定计划
↓
搜索资料
↓
保存中间结果
↓
继续补充研究
↓
委托专业子 Agent
↓
整理报告
如果使用 LangChain,这些能力可以逐步自己实现。
但不同复杂 Agent 经常重复遇到类似问题:任务规划、上下文过长、中间文件保存、子任务隔离等。
Deep Agents 就是在这一层提供了更完整的默认能力。
官方将 deepagents 称为一个 Agent Harness。它仍然使用常见的 Tool Calling Loop,但增加了规划、文件系统、Subagent 和上下文管理等能力,并使用 LangGraph Runtime 获得 Durable Execution、Streaming 和 Human-in-the-loop 等底层能力。
创建一个 Deep Agent
先安装:
pip install -U deepagents
然后可以直接创建 Agent:
from deepagents import create_deep_agent
def search_web(query: str) -> str:
"""搜索网络资料。"""
return f"关于 {query} 的搜索结果"
agent = create_deep_agent(
model="openai:gpt-5.4",
tools=[search_web],
system_prompt="""
你是一名技术研究助手。
根据任务需要搜索资料,并整理出结构清晰的研究结果。
""",
)
result = agent.invoke(
{
"messages": [
{
"role": "user",
"content": "研究 LangGraph 的主要使用场景",
}
]
}
)
print(result["messages"][-1].content)
运行结果
上述代码同样需要使用真实模型API Key,运行后,示例输出如下:
LangGraph 主要适合需要显式控制执行流程的复杂 Agent 系统。
常见场景包括:
1. 长时间运行并需要恢复的任务
2. 包含条件分支和循环的工作流
3. 需要人工审批的执行流程
4. 多步骤研究和数据处理任务
5. 需要持久化状态的 Agent 应用
实际输出以及是否调用工具,会受到模型和 Prompt 的影响。
从调用方式看,create_deep_agent 与 LangChain 的 create_agent 很接近。
区别更多体现在 Agent 默认获得了什么能力。
规划与文件系统
Deep Agents 当前提供任务规划能力,并通过文件系统工具处理较大的中间结果。官方提供的文件工具包括读取、写入、编辑、搜索文件等操作。
默认情况下,Deep Agents 使用 StateBackend。文件保存在 LangGraph State 中,并在当前 Thread 内持续存在。也可以根据需求替换成 FilesystemBackend、StoreBackend 或其他 Backend。
这类设计对研究型 Agent 很有用。
例如一个 Agent 搜索了大量网页,与其把所有原始内容持续堆在模型上下文中,不如把部分内容写入文件,需要时再读取。
Subagent
Deep Agents 还可以使用 子 Agent(Subagent)。
主 Agent 可以把某项任务委托给专门的 Agent,例如:
主 Agent
│
├── 技术资料研究 Agent
│
├── 市场数据研究 Agent
│
└── 事实核查 Agent
Subagent 的一个重要作用,是隔离上下文。
官方文档特别指出,当搜索、数据库查询和文件读取返回大量内容时,中间结果很容易使主 Agent 的上下文不断膨胀。Subagent 可以在独立上下文中完成工作,然后只把结果返回给主 Agent。
因此,Deep Agents 并不是单纯增加了“更多工具”。
它主要是在解决复杂任务执行过程中逐渐出现的工程问题。
六、LangChain、LangGraph 与 Deep Agents 的关系
理解了各自的用途以后,三者之间的关系可以简化成:
Deep Agents
↓
LangChain Agent
↓
LangGraph Runtime
Deep Agents 是建立在 LangChain Agent 基础能力之上的 Agent Harness,并使用 LangGraph Runtime。
LangChain 的预构建 Agent 同样建立在 LangGraph 上。
但这并不意味着开发时需要同时手工编写三层代码。
例如使用:
create_agent(...)
时,开发者不需要自己创建 StateGraph。
而使用:
create_deep_agent(...)
时,也不需要自己重新实现规划、文件系统和基本的子 Agent 机制。
可以按照统一维度来看三者的差异:
| 对象 | 抽象层级 | 主要关注点 | 典型场景 |
|---|---|---|---|
| LangChain | 中层 | 模型、工具、Agent Loop | 常规 Tool Calling Agent |
| LangGraph | 底层 | State、Node、流程与运行时 | 可控的复杂工作流 |
| Deep Agents | 高层 | 规划、文件、Subagent、上下文管理 | 开放式多步骤任务 |
这里需要避免一个常见误解:
LangGraph 并不是 LangChain 的“高级版”,Deep Agents 也不是 LangChain 的“替代品”。
三者主要是抽象层级不同。
同一个项目完全可能同时使用它们。
七、实际项目中的技术选择
实际开发时,可以先判断问题的复杂性来自哪里。
如果主要问题是:
模型需要根据用户输入决定调用哪些工具
例如数据库问答、搜索助手、业务 API 助手,可以优先使用 LangChain Agent。
LangChain 已经提供成熟的 Agent Loop,没有必要为了几个工具调用手工搭建 Graph。
如果主要问题是:
业务流程本身存在明确步骤、条件、循环和状态
例如:
生成内容
↓
审核
↓
是否通过
↙ ↘
修改 发布
那么 LangGraph 更合适。
因为开发者需要控制的重点已经不是“模型自己决定下一步”,而是工作流结构。
如果任务具有较强的开放性,例如:
研究一个行业
↓
自行制定计划
↓
搜索几十份资料
↓
拆分多个研究方向
↓
调用不同子 Agent
↓
保存大量中间结果
↓
最终形成报告
可以优先考虑 Deep Agents。
官方当前的 LangChain 概览也给出了类似的选择建议:需要更完整的开箱即用能力时可以从 Deep Agents 开始;普通 Agent 可以直接使用 LangChain;需要结合确定性和 Agent 式工作流并进行底层控制时,再使用 LangGraph。
还有一种更实际的方式:
先从高层抽象开始,确实遇到控制需求以后再下降一层。
例如先用 LangChain 做出第一版 Agent。
当发现某个流程必须人工审批、可恢复或者存在复杂分支时,再把这一部分放到 LangGraph 中。
这种方式通常比一开始就设计一张很大的 StateGraph 更容易维护。
八、总结
本文主要梳理了 LangChain、LangGraph 和 Deep Agents 三者的定位与关系。LangChain 提供模型、工具和 Agent Loop 等常用抽象;LangGraph 负责状态、节点、分支、持久化等工作流编排能力;Deep Agents 则在这些基础之上,进一步提供任务规划、文件系统、上下文管理和 Subagent 等复杂任务所需的能力。
实际开发时,可以先判断复杂性来自哪里。如果主要是让模型自主选择和调用工具,可以从 LangChain 开始;如果业务流程包含明确的步骤、条件、循环和状态,更适合使用 LangGraph;如果任务本身具有较强的开放性,需要长期执行、拆分任务、管理大量上下文或协调多个子 Agent,可以进一步考虑 Deep Agents。
社区讨论
参与讨论
有问题或想法?欢迎继续讨论。