最近开始系统学习 Datawhale 的《Deep Agents in Action》。前两章主要解决两个问题:
Deep Agents 到底是什么?它和 LangChain、LangGraph 有什么区别?
一个最简单的 Deep Agent 是怎么构建和运行起来的?
如果只是看 API,很容易把 Deep Agents 理解成“又一个 Agent 框架”。但学习完前两章后,我目前更倾向于把它理解为:
Deep Agents 的重点不是重新定义 Agent,而是在已有 Agent Framework 和 Runtime 之上,为复杂 Agent 提供一套开箱即用的 Harness。
1. 为什么已经有 LangChain 和 LangGraph,还需要 Deep Agents?
假设现在要开发一个类似 AI Coding Agent 的系统。
它不只是需要调用一次大模型,而需要:
阅读代码文件;
搜索整个项目;
分析问题;
制定修改步骤;
执行多个工具;
保存中间结果;
必要时拆分子任务;
长任务过程中控制上下文;
多轮运行时保存部分状态。
理论上,这些都可以自己基于 LangChain 或 LangGraph 实现。
问题在于:
几乎每开发一个复杂 Agent,都要重复实现这些基础能力。
因此 Deep Agents 的思路不是提供一个更底层的 Agent API,而是把复杂 Agent 中反复出现的工程模式提前封装起来。
2. Agent 技术栈的三个层次
理解 Deep Agents,首先需要区分三个概念:
┌──────────────────────────────┐ │ Agent Harness │ │ Deep Agents │ │ 文件系统 / 子Agent / 上下文管理 │ ├──────────────────────────────┤ │ Agent Framework │ │ LangChain │ │ Model / Tool / Agent Loop │ ├──────────────────────────────┤ │ Agent Runtime │ │ LangGraph │ │ 状态 / 持久化 / 执行 / 恢复 │ └──────────────────────────────┘它们不是竞争关系,而是一个自底向上的技术栈。
2.1 Runtime:Agent 怎么可靠地运行?
代表:LangGraph
Runtime 关注的是执行问题,例如:
Agent 执行到一半失败怎么办?
状态怎么保存?
如何暂停后等待用户确认?
如何恢复任务?
多轮执行中的状态如何管理?
所以 LangGraph 更接近 Agent 的执行引擎。
可以粗略理解为:
LangGraph ≈ Agent 的 Runtime / Workflow Engine它解决的是:
Agent 怎么跑。
而不是具体告诉 Agent 应该具备什么业务能力。
3. Framework:Agent 怎么构建?
代表:LangChain
LangChain 在 Runtime 之上进一步提供:
Model 抽象;
Tool 接口;
Agent Loop;
Middleware;
Prompt;
Tool Calling 等。
例如:
agent = create_agent( model=model, tools=[search, calculator], system_prompt="You are a helpful assistant." )开发者不用再手动实现完整的:
调用模型 ↓ 模型判断是否调用工具 ↓ 调用工具 ↓ 把工具结果返回模型 ↓ 模型继续判断 ↓ 最终回答LangChain 已经帮我们抽象了这个 Agent Loop。
因此我目前的理解是:
LangGraph:负责执行 Agent LangChain:负责构建 Agent4. Harness:Agent 如何真正完成复杂任务?
这就是 Deep Agents 所处的位置。
Deep Agents = Agent Harness
它建立在 LangChain 和 LangGraph 之上,进一步提供复杂 Agent 常见的基础设施,例如:
| 能力 | 作用 |
|---|---|
| 文件系统 | 读取、写入、搜索和编辑文件 |
| Context Management | 控制长任务中的上下文规模 |
| SubAgent | 将子任务委派给其他 Agent |
| Skills | 按需加载专业能力 |
| Memory | 保存长期信息 |
| Todo / Planning | 维护复杂任务计划 |
| Human-in-the-loop | 高风险操作前请求人工确认 |
其中需要特别注意:**Deep Agents v0.7 并不是默认开启所有能力。**例如任务规划需要显式加入TodoListMiddleware,Skills、Memory 和人工审批等能力同样需要按需求配置。
所以三层可以总结成:
| 层次 | 代表 | 核心问题 |
|---|---|---|
| Runtime | LangGraph | Agent 怎么可靠运行? |
| Framework | LangChain | Agent 怎么构建? |
| Harness | Deep Agents | 怎样让 Agent 更容易完成复杂长期任务? |
5. 为什么叫 Harness?
Harness 原意有“装备、套件、控制系统”的意思。
我觉得可以把 Agent 开发想象成开发一个机器人。
LangGraph 给机器人提供:
状态机 执行环境 恢复机制LangChain 给机器人提供:
大脑接口 工具调用接口 Agent Loop而 Deep Agents 则进一步给机器人装备:
文件系统 任务列表 长期记忆 专业技能 子 Agent 上下文管理 权限机制所以 Deep Agents 并不是“另一个更大的 Agent”。
更加准确的说法应该是:
它给 Agent 装上一套完成复杂任务所需要的工程装备。
这也是我认为理解 Harness 最重要的一点。
6. Deep Agents 的核心思想:Context Engineering
这一部分是第一章中我认为最值得关注的内容。
传统 LLM 应用经常采用:
Prompt + 用户问题 + 所有相关资料 + 所有历史记录 + 所有文件全部塞入 Context。
这种方式面对复杂任务会产生几个问题:
Context 越来越大 ↓ Token 消耗增加 ↓ 关键信息被稀释 ↓ 模型越来越难定位真正需要的信息Deep Agents 更强调:
不要把所有信息一直放在上下文里,而是让 Agent 在需要的时候主动获取信息。
例如:
Agent │ ├── read_file() ├── write_file() ├── grep() ├── glob() └── edit_file()需要一个文件时才读取。
需要保存大量中间信息时,就:
write_file(...)需要搜索项目时:
grep(...)大文件则只读取局部内容。
因此:
传统方式: 所有信息 ↓ Prompt ↓ LLM Deep Agents: ┌── File System │ LLM ←──── Context ──── Search │ ├── Memory ├── Skills └── SubAgent这实际上把:
Prompt Engineering
进一步扩展成了:
Context Engineering
核心问题从:
Prompt 怎么写?
变成:
模型在当前时刻到底应该看到什么信息?
Deep Agents 通过虚拟文件系统以及可插拔 Backend,使 Agent 可以按需读取和保存信息,而不是持续把所有信息堆进 Prompt。
7. Tool、Middleware 和 Backend 必须区分
这是理解 Deep Agents 架构时非常重要的一组概念。
可以先简单记:
Tool = Agent 能做什么 Middleware = Agent 的行为如何被增强/控制 Backend = 操作真正在哪里执行和存储例如模型决定:
read_file("main.py")表面上这是一个 Tool Calling。
背后其实是:
LLM ↓ read_file Tool ↓ FilesystemMiddleware ↓ Backend ↓ 真正读取文件因此 Backend 自身并不是 Agent,也不负责思考。
它负责:
文件存在哪里 文件怎么读取 数据如何持久化 是否使用本地磁盘 是否使用数据库 是否使用远程 SandboxMiddleware 则处于 Agent Loop 中,可以在模型调用和工具执行等阶段加入额外逻辑。
8. 第一个 Deep Agent
理解完架构后,第二章开始真正运行 Deep Agent。
安装:
pip install deepagents langchain-openai当前教程要求 Python 3.11+。
最核心的 API 是:
from deepagents import create_deep_agent一个最简单的 Agent 可以写成:
from langchain_openai import ChatOpenAI from deepagents import create_deep_agent model = ChatOpenAI( model="your-model", api_key="your-api-key", base_url="your-base-url" ) def get_weather(city: str) -> str: """Get the weather information of a city.""" return f"The weather in {city} is sunny." agent = create_deep_agent( model=model, tools=[get_weather], system_prompt="You are a helpful assistant." )然后:
result = agent.invoke({ "messages": [ { "role": "user", "content": "北京天气怎么样?" } ] })最终结果可以从:
result["messages"][-1].content获取。
9. create_deep_agent() 到底做了什么?
表面上我们只写了:
agent = create_deep_agent(...)但其内部实际上完成了更复杂的装配。
大致可以理解成:
业务配置 │ ├── Model ├── Tools ├── System Prompt ├── Middleware └── Backend │ ↓ create_deep_agent() │ ↓ 装配 Deep Agent Harness │ ↓ LangChain create_agent() │ ↓ Agent Loop │ ↓ LangGraph Runtime也就是说:
create_deep_agent() 并没有替代 LangChain而是:
在 LangChain Agent 周围装配了一系列 Harness 能力最终仍然由 LangGraph 执行。
这一点非常关键。
10. Tool 本质上是什么?
Deep Agents 中一个普通 Python Function 就可以作为 Tool。
例如:
def search_paper( query: str, max_results: int = 10 ) -> list: """Search papers according to a research query.""" ...对于 Agent 来说,最重要的是三个东西:
1. 参数名称和类型 2. Docstring 3. 默认参数因为 LLM 会根据这些信息判断:
这个工具是干什么的? 什么时候使用? 应该传什么参数? 哪些参数可以省略?因此:
Tool 的 docstring 实际上就是写给 Agent 阅读的 API 文档。
工具描述写得含糊,Agent 的 Tool Calling 质量自然也会下降。
11. agent.invoke() 并不是“调用一次模型”
这一点很容易产生误解。
代码:
agent.invoke(...)看起来只有一次调用。
实际上内部可能发生:
User ↓ LLM ↓ 决定调用 Search ↓ Search Tool ↓ 结果返回 LLM ↓ LLM ↓ 决定读取文件 ↓ read_file ↓ LLM ↓ 决定调用 SubAgent ↓ task() ↓ SubAgent ↓ 返回结果 ↓ LLM ↓ Final Answer所以更准确的结构是:
while True: response = model(context) if response.need_tool: result = tool(response.tool_call) context.add(result) else: return response当然,实际实现比这复杂很多,因为 Middleware 还会介入模型调用、工具执行、上下文处理和审批等环节。
12. 一个 Research Agent 可能怎么工作?
如果给 Agent 一个任务:
调研 LangGraph,并生成一份研究报告假如我们显式开启了 Todo Planning,它可能自己完成:
用户任务 ↓ 1. write_todos() ↓ 2. internet_search() ↓ 3. internet_search() ↓ 4. write_file() ↓ 5. task(SubAgent) ↓ 6. read_file() ↓ 7. 综合信息 ↓ 8. 输出报告这里最有意思的是:
开发者可能只写了一句:
agent.invoke(...)但是 Agent 内部可能进行了十几次模型和工具交互。
Harness 的价值,就是隐藏大量重复的 Agent Engineering 基础设施,同时保留配置能力。
13. Planning 并不是固定工作流
这里还有一个很重要的认识。
例如:
Planning → Search → File → SubAgent → Final Answer只是 Agent可能选择的一条路径。
它不是传统 Workflow:
step1() step2() step3() step4()真正执行的时候,模型可能认为任务很简单,于是直接:
User ↓ Search ↓ Answer也可能:
User ↓ Planning ↓ Search ↓ Search ↓ File ↓ SubAgent ↓ Search ↓ Answer所以 Agent 系统的一个重要特点就是:
开发者定义能力空间,模型在运行时决定具体路径。
这和传统 Workflow Programming 有明显区别。
14. 为什么 Agent 开发必须做 Observability?
普通程序报错通常可以看:
Exception Stack Trace Log但 Agent 出现的问题可能是:
模型为什么没有调用 Search? 为什么调用了错误的 Tool? 为什么参数传错? 为什么 SubAgent 没有被调用? 为什么消耗了大量 Token? 为什么 Agent 循环十几次还没结束?这些问题只看最终输出很难分析。
因此复杂 Agent 开发需要 Trace。
教程中使用 LangSmith,可以查看:
每次模型调用;
Tool Calling;
Tool 参数;
Tool 返回值;
SubAgent 执行;
Token 消耗;
执行耗时;
文件变化等。
所以我目前认为:
LLM Application + Tool Calling + Agent Loop + Trace才构成比较完整的 Agent 开发闭环。
15. 我目前对 Deep Agents 的整体理解
学习前我容易把:
Deep Agents理解成:
一个用于构建 Agent 的新框架。
现在感觉这种理解并不准确。
更合理的是:
Application │ ↓ ┌───────────────┐ │ Deep Agents │ │ Agent Harness │ └───────┬───────┘ │ ┌───────▼───────┐ │ LangChain │ │ Agent Framework│ └───────┬───────┘ │ ┌───────▼───────┐ │ LangGraph │ │ Agent Runtime │ └───────────────┘Deep Agents 真正有价值的地方,是把复杂 Agent 中已经反复被验证有效的工程模式进行了封装。
例如:
Filesystem Planning SubAgent Memory Skills Context Management Human-in-the-loop Sandbox开发者不再需要每做一个 Agent 都从零重新实现。
16. Deep Agents 和 Codex / Claude Code 应该怎么理解?
从 Harness 这个角度,再去理解 Codex、Claude Code 这类产品会清楚很多。
它们并不是:
LLM + 一个 Shell 工具而更接近:
LLM + Agent Loop + Filesystem + Search + Shell + Planning + Context Management + Permission + Sandbox + Observability也就是说:
真正复杂的 Agent 产品,核心竞争力很大一部分其实存在于模型之外的 Harness。
模型决定:
Agent 能有多聪明Harness 决定:
这个聪明的模型能不能稳定地完成复杂任务这是我学习这两章之后最大的认知变化。
17. 两章学习后的知识地图
最后把目前内容压缩成一张知识图:
Deep Agents │ ├── 1. Runtime │ └── LangGraph │ ├── State │ ├── Persistence │ ├── Durable Execution │ └── Human-in-the-loop │ ├── 2. Framework │ └── LangChain │ ├── Model │ ├── Tool │ ├── Agent Loop │ └── Middleware │ └── 3. Harness └── Deep Agents ├── Filesystem ├── Context Engineering ├── SubAgent ├── Planning ├── Skills ├── Memory ├── Backend └── Human-in-the-loop而一次实际运行可以概括成:
User ↓ Deep Agent ↓ Model ↓ 判断下一步 ├───────────────┐ ↓ ↓ Tool Final Answer ↓ Middleware ↓ Backend / External API ↓ Result ↓ 重新进入 Model18. 小结
前两章真正需要掌握的,我认为不是create_deep_agent()这个 API,而是下面几个概念:
第一,区分 Runtime、Framework 和 Harness。
LangGraph → Runtime LangChain → Framework Deep Agents → Harness第二,理解 Deep Agents 为什么强调 Context Engineering。
复杂 Agent 的核心问题已经不仅是 Prompt 怎么写,而是:
什么信息 在什么时间 以什么形式 进入模型 Context第三,理解 Agent 是一个循环,而不是一次 LLM 调用。
Model ↕ Tools会持续交互,直到模型认为任务完成。
第四,理解 Tool、Middleware、Backend 三者职责。
Tool → 能做什么 Middleware → 怎么控制和增强 Backend → 在哪里真正执行和保存第五,Harness 才是复杂 Agent 产品非常关键的工程层。
模型能力当然重要,但一个真正能够长期、稳定执行任务的 Agent,还需要文件系统、上下文管理、权限、规划、子任务委派、Sandbox 和可观测性等大量模型之外的工程能力。
这也是继续学习 Deep Agents 时,我认为最值得保持的一条主线:
不要只学习“怎么调用 Agent API”,而要理解一个复杂 Agent Harness 是如何被设计出来的。
参考资料
Datawhale《Deep Agents in Action》第 1 章:从 Agent Framework 到 Agent Harness
Datawhale《Deep Agents in Action》第 2 章:快速上手——构建第一个 Deep Agent