前言
Deep Agents 复杂智能体开发框架,langchain公司下现在排名第一的项目。
想象一下,你要做一个 AI 助手,通常需要自己组装很多零件:prompt、工具、上下文管理等等。但 Deep Agents 帮你把这些都准备好了,你只需要少量的步骤,就能得到一个功能强大的 AI Agent。
并非颠覆性的技术创新,而是将业界验证过的最佳实践打包成开箱即用的框架,灵感来源于Claude code/ Deep Search/Manus等应用,这些应用验证了三个关键点:
Agent关键点
1、Agent需要规划能力
不能上来就开干,要先分解任务;
2、Agent需要文件系统
长对话中,中间结果需要有存放的地方;
3、Agent需要子Agent协作
单体Agent会被上下文撑爆;
所以"深度 Agent"可以做更多:
- 规划 - 使用 write_todos 工具来分解任务、跟踪进度
- 文件系统访问 - 读取、写入、编辑文件,搜索代码
- Shell 执行 - 运行命令(带沙箱隔离)
- 子 Agent - 使用 task 工具委托工作给专门的子 Agent
- 智能默认 - 内置的 prompt 教模型如何有效使用这些工具
- 上下文管理 - 自动摘要长对话,大输出保存到文件
DeepAgents项目框架
deepagents/
├── libs/
│ ├── deepagents/ # 核心 SDK(Python)
│ ├── cli/ # 命令行工具
│ ├── acp/ # Agent Context Protocol 支持
│ ├── evals/ # 评估套件
│ └── partners/ # 第三方集成
├── examples/ # 示例项目
└── .github/ # CI/CD 配置
核心组件详解
Deep Agents SDK (libs/deepagents/)这是整个项目的心脏。它是一个 Python 包,提供了创建"深度 Agent"的所有能力。
SDK 的代码结构:
deepagents/
├── graph.py # 创建 Agent 的主入口 (create_deep_agent)
├── _models.py # 模型解析 (resolve_model, get_default_model)
├── base_prompt.md # 基础提示词模板
├── middleware/ # 中间件(核心逻辑)
│ ├── init.py # 导出和中间件工厂函数
│ ├── _utils.py # 工具函数
│ ├── filesystem.py # 文件系统工具 (ls, read, write, edit, glob, grep)
│ ├── memory.py # 记忆系统 (AGENTS.md)
│ ├── skills.py # 技能系统 (SKILL.md)
│ ├── subagents.py # 同步子 Agent 管理
│ ├── async_subagents.py # 异步子 Agent 管理
│ ├── summarization.py # 上下文摘要(长对话压缩)
│ └── patch_tool_calls.py # 工具调用修补
└── backends/ # 后端实现
├── init.py # 导出和后端工厂
├── protocol.py # 协议定义 (BackendProtocol, SandboxBackendProtocol)
├── state.py # 内存状态后端
├── filesystem.py # 真实文件系统后端
├── sandbox.py # 沙箱执行后端 (支持 execute 命令)
├── local_shell.py # 本地 Shell 后端
├── composite.py # 组合后端
├── langsmith.py # LangSmith 后端
├── store.py # 持久化存储后端
└── utils.py # 后端工具函数
核心文件说明:
|-----------------------------|--------------------------|
| 文件 | 作用 |
| graph.py | create_deep_agent() 入口函数 |
| middleware/filesystem.py | 提供文件操作和执行命令工具 |
| middleware/subagents.py | 提供 task 工具调用子代理 |
| middleware/summarization.py | 自动压缩长对话 |
| backends/protocol.py | 定义后端接口规范 |
| backends/sandbox.py | 远程沙箱执行环境 |
核心入口:create_deep_agent
所有 Magic 从 create_deep_agent 函数开始。打开 graph.py,我们来看这个核心函数。
python
def create_deep_agent(
model: str | BaseChatModel | None = None,
tools: Sequence[BaseTool | Callable | dict[str, Any]] | None = None,
*,
system_prompt: str | SystemMessage | None = None,
middleware: Sequence[AgentMiddleware] = (),
subagents: Sequence[SubAgent | CompiledSubAgent | AsyncSubAgent] | None = None,
skills: list[str] | None = None,
memory: list[str] | None = None,
response_format: ResponseFormat | None = None,
context_schema: type[Any] | None = None,
checkpointer: Checkpointer | None = None,
store: BaseStore | None = None,
backend: BackendProtocol | BackendFactory | None = None,
interrupt_on: dict[str, bool | InterruptOnConfig] | None = None,
debug: bool = False,
name: str | None = None,
cache: BaseCache | None = None,
) -> CompiledStateGraph:
这个函数接受很多参数,但不要被吓到------它们都有合理的默认值。
参数详解
backend
决定了智能体如何执行 ls、read_file、write_file等文件操作,以及这些数据的存储位置和生命周期
基础系统提示
Deep Agents 有一个精心设计的基础系统提示,定义了 Agent 的核心行为:
python
BASE_AGENT_PROMPT = """你是一个 Deep Agent,一个使用工具帮助用户完成任务的 AI 助手。你通过文本和工具调用来回复。用户可以实时看到你的回复和工具输出。
## 核心行为规范
- 简洁直接。除非被要求,否则不要过度解释。
- 永远不要添加不必要的开场白(如 "好的!"、"好问题!"、"我现在...")。
- 不要说 "我现在来做 X" --- 直接去做。
- 如果请求不明确,在行动前先提问。
- 如果被问及如何处理某事,先解释再行动。
## 专业客观
- 重视准确性而非验证用户的信念
- 当用户错误时礼貌地不同意
- 避免不必要的夸张、赞美或情感认同
## 执行任务
当用户让你做某事时:
1. **先理解** --- 阅读相关文件,检查现有模式。
2. **行动** --- 实现解决方案。
3. **验证** --- 检查你的工作是否符合要求。
持续工作直到任务完全完成。不要中途停止。"""
这个提示定义了 Agent 的行为准则:
- 简洁直接
- 不说废话
- 先理解再行动
- 验证自己的工作
中间件系统
Deep Agents 里最核心的设计;
1. 什么是中间件?
想象一下:你和 LLM 之间有一个"关卡",每次你发送消息给 LLM,或者收到 LLM 的响应时,都会经过这个关卡。
中间件就是这个关卡上的"拦截器"。
它可以在:
- 消息发送给 LLM 之前拦截并修改
- LLM 响应回来 之后拦截并处理
- 工具被调用 之前/之后做额外处理
2. 为什么需要中间件?
普通的工具函数只能在 LLM 调用时被触发。但中间件可以在 LLM 调用之前拦截请求,做很多事情:
- 动态过滤工具 - 比如 FilesystemMiddleware 根据后端类型决定是否暴露 execute 工具
- 注入系统提示 - 比如 MemoryMiddleware 和 SkillsMiddleware 在每次调用时注入相关指令
- 转换消息 - 比如 SummarizationMiddleware 统计 token 数、截断旧内容、用摘要替换历史
- 维护跨轮状态 - 中间件可以读写跨 Agent 轮次持久化的状态字典
3. Deep Agents 的中间件架构
所有中间件都继承自 AgentMiddleware:
python
class AgentMiddleware(Generic[ContextT, ModelRequest, ModelResponse, ResponseT]):
def wrap_model_request(self, request: ModelRequest) -> ModelRequest:
"""在请求发送给 LLM 之前调用"""
return request
def wrap_model_response(self, response: ModelResponse) -> ModelResponse:
"""在收到 LLM 响应后调用"""
return response
def wrap_tool_calls(self, tool_calls: list[ToolCallRequest]) -> list[ToolCallRequest]:
"""在工具调用执行前调用"""
return tool_calls
def wrap_tool_result(self, tool_name: str, result: Any) -> Any:
"""在工具执行后调用"""
return result
AgentMiddleware 提供了多个钩子:

4. 中间件栈的构建
这是整个函数最复杂的部分。中间件的执行顺序非常关键。
++4.1 主Agent的中间件栈:++
python
主 Agent:
1. TodoListMiddleware # 任务规划
2. SkillsMiddleware # 技能系统(如果启用)
3. FilesystemMiddleware # 文件操作
4. SubAgentMiddleware # 子 Agent
5. SummarizationMiddleware # 上下文摘要
6. PatchToolCallsMiddleware # 工具调用修补
7. AnthropicPromptCachingMiddleware # 提示缓存
8. MemoryMiddleware # 记忆系统(如果启用)
9. HumanInTheLoopMiddleware # 人在环中(如果启用)
python
deepagent_middleware: list[AgentMiddleware[Any, Any, Any]] = [
TodoListMiddleware(),
]
if skills is not None:
deepagent_middleware.append(SkillsMiddleware(backend=backend, sources=skills))
deepagent_middleware.extend([
FilesystemMiddleware(backend=backend),
SubAgentMiddleware(backend=backend, subagents=inline_subagents),
create_summarization_middleware(model, backend),
PatchToolCallsMiddleware(),
])
if async_subagents:
deepagent_middleware.append(AsyncSubAgentMiddleware(async_subagents=async_subagents))
if middleware:
deepagent_middleware.extend(middleware)
# 缓存和记忆放在最后
# 原因:记忆更新不应该使 Anthropic 提示缓存前缀失效
deepagent_middleware.append(AnthropicPromptCachingMiddleware(...))
if memory is not None:
deepagent_middleware.append(MemoryMiddleware(backend=backend, sources=memory))
if interrupt_on is not None:
deepagent_middleware.append(HumanInTheLoopMiddleware(interrupt_on=interrupt_on))
++4.2 通用子 Agent 的中间件栈++
python
gp_middleware: list[AgentMiddleware[Any, Any, Any]] = [
TodoListMiddleware(), # 任务规划
FilesystemMiddleware(backend=backend), # 文件系统
create_summarization_middleware(model, backend), # 摘要
PatchToolCallsMiddleware(), # 工具调用修补
]
if skills is not None:
gp_middleware.append(SkillsMiddleware(backend=backend, sources=skills))
gp_middleware.append(AnthropicPromptCachingMiddleware(...))
if interrupt_on is not None:
gp_middleware.append(HumanInTheLoopMiddleware(interrupt_on=interrupt_on))
中间件详解
1. TodoListMiddleware
功能:提供任务规划能力
提供的工具:
write_todos- 创建、更新、删除待办事项
工作原理:
- 维护一个待办事项列表在 Agent 状态中
- 每次 LLM 调用时,将待办事项注入系统提示
- 工具调用后更新状态
注入到系统提示词的内容(动态生成):
python
## 待办事项
你的当前待办列表:
- [ ] 阅读现有代码库
- [ ] 实现新功能
- [ ] 编写测试
使用 `write_todos` 工具更新你的待办列表.
每次 LLM 调用时,会将当前待办事项列表格式化后注入到系统提示中,让 Agent 随时了解任务进度。
2. FilesystemMiddleware
**功能:**提供文件系统操作能力
提供的工具:
- ls - 列出目录
- read_file - 读取文件
- write_file - 写入文件
- edit_file - 编辑文件
- glob - 文件名匹配
- grep - 文本搜索
- execute - 执行命令(需要沙箱后端)
工作原理:
- 根据后端类型动态决定提供哪些工具
- 使用后端协议与实际存储交互
- 处理文件路径验证、权限检查
大结果驱逐机制:
当工具返回结果过大时(超过 20000 token),自动将结果写入文件系统
注入到系统提示词的内容
python
## 遵循惯例
- 编辑前先阅读文件 --- 在做出更改之前了解现有内容
- 模仿现有的风格、命名约定和模式
## 文件系统工具 `ls`, `read_file`, `write_file`, `edit_file`, `glob`, `grep`
你可以使用这些工具与文件系统交互。所有文件路径必须以 / 开头。
- ls: 列出目录中的文件(需要绝对路径)
- read_file: 从文件系统读取文件
- write_file: 向文件系统写入文件
- edit_file: 编辑文件系统中的文件
- glob: 查找匹配模式的文件(如 "**/*.py")
- grep: 在文件中搜索文本
## 大型工具结果
当工具结果太大时,可能会被卸载到文件系统而不是内联返回。在这种情况下,使用 `read_file` 分块检查保存的结果,或在 `/large_tool_results/` 中使用 `grep`。
当后端支持执行时额外注入:
python
## 执行工具 `execute`
你有一个 `execute` 工具用于在沙箱环境中运行 shell 命令。
使用此工具运行命令、脚本、测试、构建和其他 shell 操作。
3. SubAgentMiddleware
功能:提供子 Agent 委托能力
提供的工具:
task- 调用子 Agent
工作原理:
- 在系统提示中注入可用子 Agent 的描述
- 拦截
task工具调用 - 创建并运行子 Agent
- 将结果作为 ToolMessage 返回给主 Agent
注入到系统提示词的内容:
python
## `task`(子代理生成器)
你有一个 `task` 工具来启动处理独立任务的短生命周期子代理。这些代理是临时的------它们只存在于任务期间并返回单个结果。
何时使用 task 工具:
- 当任务复杂且多步骤,可以完全独立委托时
- 当任务独立于其他任务,可以并行运行时
- 当任务需要集中推理或大量 token/上下文使用时
子代理生命周期:
1. 生成 → 提供清晰的角色、指令和预期输出
2. 运行 → 子代理自主完成任务
3. 返回 → 子代理提供单个结构化结果
4. 调和 → 将结果合并到主线程
可用子代理类型:
- general-purpose: 用于研究复杂问题的通用代理
- researcher: 用于搜索和收集信息的研究代理
4. SummarizationMiddleware
功能:管理长上下文
工作原理:
- 跟踪对话的 token 数量
- 当接近上下文窗口限制时:
- 调用 LLM 生成历史摘要
- 用摘要替换原始历史
- 继续处理当前请求
触发阈值:默认 80% 上下文使用率
注入到系统提示词的内容:
python
## 压缩对话工具 `compact_conversation`
你有一个 `compact_conversation` 工具。这个工具刷新你的上下文窗口以减少上下文膨胀和成本。
你应该何时使用这个工具:
- 当用户要求完全转向新任务,且之前的上下文可能无关时
- 当你已完成结果提取或综合,且之前的上下文不再需要时
5. SkillsMiddleware
功能:提供技能系统
工作原理:
- 扫描指定目录查找
SKILL.md文件 - 解析 YAML frontmatter 获取技能元数据
- 在系统提示中注入可用技能列表(渐进式披露)
- 按需读取完整技能内容
注入到系统提示词的内容:
python
## 技能系统
你有一个技能库,提供专业能力和领域知识。
**技能位置**:
- **用户技能**: `/skills/user/`
- **项目技能**: `/skills/project/`(更高优先级)
**可用技能**:
- **web-research**: 进行深入网络研究的结构化方法
-> 可用工具: search, fetch
-> 阅读 `/skills/user/web-research/SKILL.md` 获取完整说明
**如何使用技能(渐进式披露)**:
1. 识别技能何时适用:检查用户任务是否匹配技能描述
2. 阅读技能的完整说明:使用上面技能列表中的路径
3. 按照技能的说明执行:SKILL.md 包含分步工作流、最佳实践和示例
4. 访问支持文件:技能可能包含辅助脚本、配置或参考文档
技能元数据结构:
python
class SkillMetadata(TypedDict):
path: str # SKILL.md 文件路径
name: str # 技能名称(1-64 字符)
description: str # 技能描述(1-1024 字符)
license: str | None
compatibility: str | None
metadata: dict[str, str]
allowed_tools: list[str]
6. MemoryMiddleware
功能:提供持久记忆
工作原理:
- 加载
AGENTS.md文件 - 在系统提示中注入记忆内容
- 每次请求时自动包含
注入到系统提示词的内容:
python
<agent_memory>
~/.deepagents/AGENTS.md
# 项目指南
- 所有新代码使用 TypeScript
- 遵循 src/ 中的现有代码风格
- 提交前运行测试
./project/AGENTS.md
# Agent 上下文
这是一个使用 Next.js 14 的 React 项目。
API 路由在 src/app/api/ 中
</agent_memory>
<memory_guidelines>
上面的 <agent_memory> 是从文件系统中的文件加载的。当你在与用户的交互中学习时,你可以通过调用 `edit_file` 工具保存新知识。
**从反馈中学习:**
- 你最主要的任务之一是从与用户的交互中学习。
- 当你需要记住某些东西时,更新记忆必须是你的第一个、立即的行动。
- 当用户说某些东西更好/更差时,捕获原因并将其编码为模式。
**何时更新记忆:**
- 当用户明确要求你记住某些东西时
- 当用户描述你的角色或你应该如何行为时
- 当用户对你的工作提供反馈时
- 当用户提供工具使用所需的信息时
**何时不更新记忆:**
- 当信息是临时的或短暂的时
- 当信息是一次性任务请求时
- 永远不要在任何文件或记忆中存储 API 密钥、访问令牌、密码
</memory_guidelines>
7. PatchToolCallsMiddleware
功能:修补工具调用
工作原理:
- 规范化工具参数
- 处理参数类型转换
- 添加默认参数值
是否修改系统提示词:否(该中间件只处理工具调用参数,不涉及提示词注入)
8. AnthropicPromptCachingMiddleware
**功能:**优化 Anthropic 模型的提示缓存
工作原理:
- 检测静态内容(系统提示、工具定义)
- 使用 Anthropic 的提示缓存 API
- 减少重复传输的 token
是否修改系统提示词:否(该中间件使用 API 层面的缓存机制,不修改提示词内容)
9. HumanInTheLoopMiddleware
功能:人在环中审批
工作原理:
- 配置哪些工具需要审批
- 执行前暂停 Agent
- 等待人类批准或修改
- 继续执行或拒绝
是否修改系统提示词:否(该中间件在运行时拦截工具调用,不修改提示词)
10. AsyncSubAgentMiddleware
**功能:**提供异步子 Agent(远程 LangGraph 服务器)
工作原理:
- 在远程 LangGraph 服务器上启动后台任务
- 提供异步任务管理工具
- 支持任务状态检查、更新、取消
提供的工具:
- start_async_task - 启动后台任务
- check_async_task - 检查任务状态
- update_async_task - 更新任务指令
- cancel_async_task - 取消任务
- list_async_tasks - 列出所有任务
注入到系统提示词的内容:
python
## 异步子代理(远程 LangGraph 服务器)
你有一个异步子代理工具,可以在远程 LangGraph 服务器上启动后台任务。
#### 工具:
- `start_async_task`: 启动新的后台任务。立即返回任务 ID。
- `check_async_task`: 获取任务的当前状态和结果。
- `update_async_task`: 向正在运行的任务发送新指令。
- `cancel_async_task`: 停止正在运行的任务。
- `list_async_tasks`: 列出所有跟踪的任务及其实时状态。
#### 关键规则:
- 启动后,始终立即将控制权返回给用户。启动后永远不要自动检查。
- 永远不要循环轮询 `check_async_task`。
- 对话历史中的任务状态始终是过时的------始终调用工具获取当前状态。
可用异步子代理类型:
- my-agent: 异步子代理的描述
最终系统提示词结构
python
[用户自定义 system_prompt]
你是一个 Deep Agent,一个使用工具帮助用户完成任务的 AI 助手。用户可以实时看到你的回复和工具输出...
## 核心行为规范
- 简洁直接。除非被要求,否则不要过度解释。
- 永远不要添加不必要的开场白(如 "好的!"、"好问题!"、"我现在...")。
- 如果请求不明确,在行动前先提问。
- 如果被问及如何处理某事,先解释再行动。
## 专业客观
- 重视准确性而非验证用户的信念
- 当用户错误时礼貌地不同意
- 避免不必要的夸张、赞美或情感认同
## 执行任务
当用户让你做某事时...
## 待办事项
你的当前待办列表:
- [ ] 任务 1
- [ ] 任务 2
使用 `write_todos` 工具更新你的待办列表。
## 技能系统
你有一个技能库,提供专业能力和领域知识。
**技能位置**:
- **用户技能**: `/skills/user/`
- **项目技能**: `/skills/project/`(更高优先级)
**可用技能**:
- **web-research**: 进行深入网络研究的结构化方法
-> 可用工具: search, fetch
-> 阅读 `/skills/user/web-research/SKILL.md` 获取完整说明
**如何使用技能(渐进式披露)**:
1. 识别技能何时适用:检查用户任务是否匹配技能描述
2. 阅读技能的完整说明:使用上面技能列表中的路径
3. 按照技能的说明执行:SKILL.md 包含分步工作流、最佳实践和示例
4. 访问支持文件:技能可能包含辅助脚本、配置或参考文档
## 遵循惯例
- 编辑前先阅读文件 --- 在做出更改之前了解现有内容
- 模仿现有的风格、命名约定和模式
## 文件系统工具 `ls`, `read_file`, `write_file`, `edit_file`, `glob`, `grep`
你可以使用这些工具与文件系统交互。所有文件路径必须以 / 开头。
- ls: 列出目录中的文件(需要绝对路径)
- read_file: 从文件系统读取文件
- write_file: 向文件系统写入文件
- edit_file: 编辑文件系统中的文件
- glob: 查找匹配模式的文件(如 "**/*.py")
- grep: 在文件中搜索文本
## 大型工具结果
当工具结果太大时,可能会被卸载到文件系统而不是内联返回。在这种情况下,使用 `read_file` 分块检查保存的结果,或在 `/large_tool_results/` 中使用 `grep`。
## `task`(子代理生成器)
你有一个 `task` 工具来启动处理独立任务的短生命周期子代理。这些代理是临时的------它们只存在于任务期间并返回单个结果。
何时使用 task 工具:
- 当任务复杂且多步骤,可以完全独立委托时
- 当任务独立于其他任务,可以并行运行时
- 当任务需要集中推理或大量 token/上下文使用时
子代理生命周期:
1. 生成 → 提供清晰的角色、指令和预期输出
2. 运行 → 子代理自主完成任务
3. 返回 → 子代理提供单个结构化结果
4. 调和 → 将结果合并到主线程
可用子代理类型:
- general-purpose: 用于研究复杂问题的通用代理
## 压缩对话工具 `compact_conversation`
你有一个 `compact_conversation` 工具。这个工具刷新你的上下文窗口以减少上下文膨胀和成本。
你应该何时使用这个工具:
- 当用户要求完全转向新任务,且之前的上下文可能无关时
- 当你已完成结果提取或综合,且之前的上下文不再需要时
<agent_memory>
[memory 内容]
</agent_memory>
<memory_guidelines>
上面的 <agent_memory> 是从文件系统中的文件加载的。当你在与用户的交互中学习时,你可以通过调用 `edit_file` 工具保存新知识。
**从反馈中学习:**
- 你最主要的任务之一是从与用户的交互中学习。
- 当你需要记住某些东西时,更新记忆必须是你的第一个、立即的行动。
- 当用户说某些东西更好/更差时,捕获原因并将其编码为模式。
**何时更新记忆:**
- 当用户明确要求你记住某些东西时
- 当用户描述你的角色或你应该如何行为时
- 当用户对你的工作提供反馈时
- 当用户提供工具使用所需的信息时
**何时不更新记忆:**
- 当信息是临时的或短暂的时
- 当信息是一次性任务请求时
- 永远不要在任何文件或记忆中存储 API 密钥、访问令牌、密码
</memory_guidelines>
提示词组装顺序:
- 用户自定义 system_prompt(如有)
- BASE_AGENT_PROMPT - Deep Agent 核心行为规范
- TodoListMiddleware - 待办事项(动态)
- SkillsMiddleware - 技能系统(如果有 skills 配置)
- FilesystemMiddleware - 文件系统工具说明
- SubAgentMiddleware - 子 Agent 工具说明
- SummarizationMiddleware - 上下文压缩工具
- AnthropicPromptCachingMiddleware - 缓存标记(API 层面)
- MemoryMiddleware - 记忆内容(如果有 memory 配置)
每个中间件通过 modify_request 或 wrap_model_call 方法将内容追加到系统消息末尾。
默认工具
创建 Deep Agent 时,你不需要手动添加任何工具------以下工具默认可用:
1. 任务规划
write_todos- 管理待办事项列表
2. 文件操作
ls - 列出目录内容
read_file - 读取文件
write_file - 写入文件
edit_file - 编辑文件
glob - 文件名模式匹配
grep - 文本搜索
3. Shell 执行
execute - 运行 Shell 命令(需要支持沙箱的后端)
4. 子 Agent
task - 调用子 Agent
参考: