第 01 章
认识 Deep Agents
构建能规划任务、使用子 Agent 并利用文件系统完成复杂任务的智能体
从"简单工具调用"到"自主任务规划"的关键一步为什么需要它
你有没有试过用普通 Agent 处理需要多步骤规划的复杂任务?
普通 Agent 的困境
- 多步骤任务全靠 prompt 硬编码,没有自动规划
- 上下文一长就爆窗口,没有上下文管理机制
- 所有信息塞在对话历史里,无法持久化中间结果
- 复杂任务无法拆分给子 Agent,主 Agent 上下文越来越臃肿
- 想控制 Agent 能读写哪些文件?没有权限系统
Deep Agents 的解法
- 内置
write_todos工具,自动规划和跟踪任务步骤 - 文件系统工具 + 自动摘要,上下文永不溢出
- 可插拔后端(内存、磁盘、沙箱),灵活存储
- 内置
task工具生成子 Agent,上下文隔离 - 声明式权限规则,精确控制文件访问
问题核心:当你需要 Agent 处理的不是"回答一个问题"而是"完成一整个项目"——规划、搜索、编码、测试、审查——你就需要一套完整的工程化基础设施。Deep Agents 就是那套基础设施。
开始之前
你需要会什么
- TypeScript / JavaScript 基础(函数、类型、async/await)
- 了解 LLM 的基本概念(prompt、token、tool calling)
- 会用 npm 初始化项目、安装依赖
- 了解 LangChain 核心模块的基本用法
读完后你应该能
- 说清 Deep Agents 是什么、解决什么问题
- 写出第一个能跑的 Deep Agent
- 理解规划、文件系统、子 Agent 三大核心概念
- 知道什么时候该用 Deep Agents,什么时候用 LangGraph
- 掌握核心能力的概览,为后续章节打好基础
本章不会深入
- 自定义和配置的详细选项
- 各种文件系统后端的实现细节
- 沙箱、解释器的深入用法
- 生产环境部署方案
环境准备:确保你有一个 Node.js 项目。安装命令:
$ npm install deepagents langchain @langchain/core
定义与架构
一种"Agent Harness"——在工具调用循环之上,内置了规划、文件系统和子 Agent 等完整能力
说白了,Deep Agents 帮你把一个复杂的 AI 任务交给一个能自主规划的智能体。
它会自己拆步骤、把中间结果存到文件系统、需要深入处理时生成子 Agent、上下文太长时自动摘要压缩。
整个执行过程可追踪、可控权限。
# 安装依赖
$ npm install deepagents langchain @langchain/core
// 最简 Deep Agent —— 只需要 createDeepAgent
import * as z from "zod";
import { createDeepAgent } from "deepagents";
import { tool } from "langchain";
// 用 tool() 定义一个自定义工具:查询城市天气
// 第一个参数是执行函数,第二个参数是工具的元数据
const getWeather = tool(
({ city }) => `It's always sunny in ${city}!`,
{
name: "get_weather", // 工具名称,Agent 通过它调用
description: "Get the weather for a given city", // 描述帮助 LLM 判断何时调用
schema: z.object({
city: z.string(), // 用 Zod 定义参数类型
}),
},
);
// createDeepAgent 返回一个 LangGraph graph,内置规划、文件系统等能力
const agent = createDeepAgent({
model: "anthropic:claude-sonnet-4-6",
tools: [getWeather], // 传入自定义工具数组
systemPrompt: "You are a helpful assistant", // 系统提示词,引导 Agent 行为
});
// invoke() 同步执行 Agent,等待完整结果后返回
const result = await agent.invoke({
messages: [{ role: "user", content: "What's the weather in Tokyo?" }],
});
如果看到报错:
Cannot find module 'deepagents'→ 先安装依赖:$ npm install deepagents langchain @langchain/coreERR_MODULE_NOT_FOUND→ 确认使用 ESM("type": "module"inpackage.json)或用.mjs后缀
一个函数就够了:
createDeepAgent 接收工具和系统提示词,返回一个可调用的 Agent。底层是 LangGraph 的工具调用循环,但内置了规划、文件系统、子 Agent 等能力。
LangSmith Engine 提示:LangSmith Engine 可以检测你的 Deep Agents 追踪记录中的问题并提出修复建议。你可以直接从 Issues 标签页打开一个包含修复建议的 Pull Request。
了解 LangSmith Engine →
了解 LangSmith Engine →
核心能力
Deep Agents 不是抽象你的提示词,而是提供完整的工程化能力
| 能力 | 它做了什么 | 举例 | 什么时候需要 |
|---|---|---|---|
| 任务规划 | 内置 write_todos 工具,Agent 自动把大目标拆成可追踪的小步骤,完成后打勾,遇到变化还能动态调整计划查看 write_todos 文档 → |
类似 CI/CD pipeline 的 stage 划分:build → test → deploy,每步有状态和依赖 | "帮我重构整个模块"这类多步骤复杂任务 |
| 上下文管理 | 六个文件系统工具(ls、read_file、write_file、edit_file、glob、grep)让 Agent 按需读写文件,加上自动摘要压缩旧消息,防止上下文窗口溢出查看文件系统工具文档 → · 查看摘要机制文档 → |
类似操作系统的虚拟内存:内存放不下时换页到磁盘,需要时再加载回来 | 读 20 个源码文件再写报告——上下文会超长的情况 |
| Shell 执行 | 沙箱后端下使用 execute 工具运行 Shell 命令,在隔离环境中安全执行查看沙箱后端文档 → |
类似 Docker 容器:隔离的执行环境,跑完销毁,不影响宿主机 | 需要运行 npm test、git commit、构建部署等系统操作 |
| 子 Agent | 内置 task 工具,主 Agent 可以生成专门的子 Agent 来处理子任务。子 Agent 有独立的上下文窗口,完成后只返回结果摘要——主 Agent 不会被子任务的细节淹没 |
类似进程 fork:子进程有独立地址空间,通过 IPC 返回结果,父进程继续调度 | "分析这个文件里的所有 bug"——主 Agent 让子 Agent 深入分析,自己继续推进其他步骤 |
| 可插拔后端 | 同一套代码,底层可以自由切换:内存(测试用)、本地磁盘、LangGraph Store、沙箱、自定义后端 查看后端配置文档 → |
类似 ORM 的数据库抽象层:代码写一次,底层切 MySQL / PostgreSQL / SQLite 都行 | 开发时用内存后端快速迭代,上线切到 LangGraph Store 持久化 |
| 文件系统权限 | 声明式权限规则,精确控制 Agent 可以读写哪些文件和目录——读允许、写拒绝、目录白名单都支持 查看权限规则文档 → |
类似 Linux 的 chmod + chroot:限定进程可访问的文件范围和操作权限 |
只让 Agent 读写 /workspace 目录,防止误操作系统文件 |
| Human-in-the-loop | Agent 在执行敏感操作(删除文件、发送邮件)前自动暂停,等人类审批后继续执行或取消 查看 HITL 文档 → |
类似 Git 的 code review 流程:PR 不能自动 merge,至少一个 reviewer approve 后才能合入 | "删除旧文件前先让我看看"这类需要人工把关的操作 |
| 长期记忆 | 基于 LangGraph Memory Store,Agent 可以跨对话线程保留信息。线程 A 里记住的"用户喜欢深色模式",线程 B 里也能查到 查看 Memory Store 文档 → |
类似 Redis 持久化存储:多个进程/服务共享同一个数据源,key-value 按命名空间组织 | 跨会话记住用户偏好、项目约定、历史决策 |
| 解释器 | 在内存运行时中执行 JavaScript 代码,可以编程方式组合多个工具调用结果、转换数据格式、实现复杂逻辑——不需要完整 Shell 环境 查看解释器文档 → |
类似浏览器的 DevTools Console:快速执行脚本片段,处理数据,不需要搭建完整运行环境 | 把搜索结果过滤排序、把 JSON 转成 CSV、计算统计数据 |
| 技能(Skills) | 可复用的技能模块,封装了专门的工作流、领域知识和自定义指令。写一次,多个 Agent 共用 查看技能文档 → |
类似 npm 包:封装一组功能,发布后任何项目 npm install 就能复用 |
封装"代码审查"工作流,让不同项目的 Agent 都遵循同一套审查规范 |
关键区别:LangGraph 提供的是底层编排原语(节点、边、状态),你需要自己组装。Deep Agents 在 LangGraph 之上提供了一层"开箱即用的 Agent Harness"——规划、文件系统、子 Agent 全都内置好了。
何时使用
Deep Agents 适合复杂场景,简单场景有更轻量的选择
适合用 Deep Agents
考虑更轻量的方案
- 简单的问答或单次工具调用
- 不需要规划的单步骤任务
- 上下文很短、不会溢出窗口
- 不需要子 Agent 或文件系统
替代方案:
LangChain createAgent— 简单 AgentLangGraph StateGraph— 自定义工作流
LangChain 层级关系
| 框架 | 定位 | 复杂度 |
|---|---|---|
| LangChain | 核心构建模块(模型、工具、提示词) | 基础 |
| LangGraph | 低级编排运行时(节点、边、状态) | 中等 |
| Deep Agents | 高级 Agent Harness(规划、文件系统、子 Agent) | 高级 |
Deep Agents 仓库包含
- Deep Agents SDK — 构建 Agent 的包
- Deep Agents Code — 终端编程 Agent
- ACP 集成 — 在 Zed 等编辑器中使用
框架 vs 运行时 vs Harness:LangChain 是提供核心构建模块的框架;LangGraph 是低级编排的运行时(节点、边、状态);Deep Agents 是在它们之上构建的Agent Harness——内置规划、文件系统、子 Agent 等完整能力。要深入了解三者区别,请参阅框架、运行时和 Harness 概念说明。要与其他框架对比,请参阅Deep Agents 与 Claude Agent SDK 对比。
创建 Agent
一个 createDeepAgent 调用就够了——让我们看看细节
import * as z from "zod";
import { createDeepAgent } from "deepagents";
import { tool } from "langchain";
// 1. 定义你的自定义工具
// 工具一:搜索文档 —— Agent 会根据 description 判断何时调用
const searchDocs = tool(
async ({ query }) => {
// 实际实现中调用你的搜索 API
return `搜索结果:找到 3 篇与"${query}"相关的文档`;
},
{
name: "search_docs",
description: "Search the documentation for relevant information",
schema: z.object({
query: z.string().describe("The search query"),
}),
},
);
// 工具二:创建工单 —— LLM 会自动提取 title 和 description 参数
const createTicket = tool(
async ({ title, description }) => {
return `Ticket #123 created: ${title}`;
},
{
name: "create_ticket",
description: "Create a support ticket",
schema: z.object({
title: z.string(),
description: z.string(),
}),
},
);
// 2. 创建 Deep Agent —— 传入工具和系统提示词即可
const agent = createDeepAgent({
model: "anthropic:claude-sonnet-4-6",
tools: [searchDocs, createTicket], // Agent 会自主选择调用哪个工具
systemPrompt: `你是一个技术支持助手。
收到用户问题时,先搜索文档找答案。
如果找不到,创建一个工单并通知用户。`,
});
// 3. 调用 Agent —— invoke() 返回完整对话历史
const result = await agent.invoke({
messages: [
{ role: "user", content: "怎么配置 OAuth2 登录?" }
],
});
createDeepAgent 参数
| 参数 | 类型 | 说明 |
|---|---|---|
tools | Tool[] | 自定义工具数组(LangChain tool 格式) |
systemPrompt | string | 系统提示词,定义 Agent 的行为 |
Agent 自动获得的能力
write_todos— 任务规划和进度跟踪ls / read_file / write_file / edit_file / glob / grep— 文件系统操作task— 生成子 Agent- 自动摘要 — 上下文过长时压缩历史消息
文件系统
虚拟文件系统——Agent 的"工作台",可插拔后端自由切换
Deep Agents 内置六个文件系统工具,让 Agent 可以把大量上下文卸载到文件而非塞在对话历史里。
底层通过可插拔后端驱动,根据场景切换。
| 工具 | 作用 | 典型用法 |
|---|---|---|
ls | 列出目录内容 | 查看有哪些文件、发现项目结构 |
read_file | 读取文件内容 | 查看代码、配置文件、文档 |
write_file | 创建或覆盖文件 | 生成代码、写入配置、保存中间结果 |
edit_file | 精确编辑文件片段 | 修改代码中的特定行、替换配置值 |
glob | 按通配符匹配文件路径 | 批量查找符合模式的文件 |
grep | 按内容正则搜索 | 在文件内容中查找匹配的文本 |
可插拔后端
- 内存状态 — 默认,适合测试和短期任务
- 本地磁盘 — 直接读写真实文件系统
- LangGraph Store — 跨线程持久化
- 沙箱 — Modal、Daytona、Deno,隔离执行代码
- 自定义后端 — 实现你自己的存储逻辑
- 复合路由 — 组合多个后端
为什么需要文件系统?
普通 Agent 把所有信息塞在对话消息里。一旦任务复杂——读 20 个文件、写 10 个文件——上下文窗口就会溢出。
文件系统让 Agent 按需读写:读的时候加载,用完就放回文件。配合自动摘要,Agent 可以处理任意长度
常见误区:不要把文件系统当成"真实磁盘"来理解。它是虚拟的——内存后端下文件只存在于当次会话。如果需要持久化,要用磁盘或 LangGraph Store 后端。
子 Agent 与记忆
让 Agent 能委派工作和记住过去——复杂任务的两把钥匙
子 Agent(task 工具)
当主 Agent 遇到需要深入处理的子任务时,可以生成一个专门的子 Agent 来处理。
- 子 Agent 拥有独立的上下文窗口,不污染主 Agent
- 处理完成后,子 Agent 将结果摘要返回给主 Agent
- 子 Agent 可继承或覆盖父级的权限规则
- 支持同步和异步两种模式
长期记忆(Memory Store)
基于 LangGraph 的 Memory Store,Agent 可以跨线程保留信息。
- 短期记忆 — 线程内的对话历史
- 长期记忆 — 跨会话、跨线程的持久化信息
- 可以保存用户偏好、项目知识、历史决策
- 下次对话时 Agent 能检索和使用之前的记忆
// 子 Agent 工作流示例(伪代码,展示概念)
// 主 Agent 接到任务:"重构 src/utils.ts"
// 1. 主 Agent 用 write_todos 规划任务,将大目标拆成可追踪的小步骤
// write_todos: [
// { task: "阅读现有代码", status: "in_progress" },
// { task: "识别重构点", status: "pending" },
// { task: "执行重构", status: "pending" },
// { task: "运行测试", status: "pending" },
// ]
// 2. 遇到需要深入分析的部分,通过 task 工具生成子 Agent
// task("分析 src/utils.ts 中的重复代码模式")
// → 子 Agent 在独立上下文中运行,主 Agent 上下文保持干净
// → 子 Agent 执行完毕后,只返回分析结果摘要给主 Agent
// 3. 主 Agent 根据子 Agent 的结果继续工作
// edit_file: 重构 src/utils.ts (精确修改文件片段)
// execute: npm test (在沙箱后端中运行测试)
核心价值:子 Agent 解决的是"上下文隔离"问题——主 Agent 不会被子任务的细节淹没。长期记忆解决的是"跨会话连续性"问题——Agent 能从之前的经验中学习。
权限与审批
声明式权限规则 + Human-in-the-loop——让 Agent 可控又安全
文件系统权限
通过声明式规则,精确控制 Agent 可以读写哪些文件和目录。
- 允许读取:指定可读的路径模式
- 允许写入:指定可写的路径模式
- 子 Agent 继承:子 Agent 默认继承父级规则
- 可覆盖:子 Agent 可自定义更严格或更宽松的规则
Human-in-the-loop
基于 LangGraph 的中断功能,为敏感操作配置人工审批。
- 暂停执行:指定工具在执行前需要确认
- 人工审批:允许、拒绝或修改操作
- 恢复执行:审批后 Agent 继续工作
- 灵活配置:不同工具可设置不同审批策略
// 权限规则概念示例
// 用 glob 模式匹配路径,精确控制 Agent 可访问的文件范围
const permissions = {
read: ["src/**", "package.json", "tsconfig.json"], // 只允许读取 src 目录和配置文件
write: ["src/output/**"], // 只允许写入 src/output 目录
};
// Human-in-the-loop:配置哪些工具需要人工确认后才执行
// 例如:所有写操作和 Shell 命令执行前暂停,等人审批
const hitlConfig = {
requireApproval: ["write_file", "edit_file", "execute"],
};
安全提示:在生产环境中,始终配置权限规则。不要让 Agent 有权访问敏感文件(如 .env、密钥文件、数据库配置)。沙箱后端可以提供额外的隔离层。
技能与扩展
用可复用技能扩展 Agent,用解释器组合工具,用智能默认值开箱即用
技能(Skills)
技能是可复用的模块,为 Agent 提供专门的工作流、领域知识和自定义指令。
- 封装特定领域的知识和流程
- 可以在多个 Agent 之间复用
- 类似"插件"的概念,按需加载
解释器(Interpreters)
在内存运行时中执行 JavaScript,让 Agent 能以编程方式组合工具。
- 编排子 Agent,不需要完整 Shell 环境
- 转换结构化数据(JSON 解析、格式转换)
- 基于 QuickJS 的安全沙箱
智能默认值
Deep Agents 附带精心设计的系统提示,教会模型如何有效使用工具。
- 先规划再行动
- 验证工作结果
- 主动管理上下文
- 可根据需要自定义或替换
设计哲学:Deep Agents 的默认值是"最佳实践"而非"最低配置"。开箱即用就能写出好 Agent,高级用户可以逐步自定义每个部分。
动手练习
设计一个代码审查 Agent——用 Deep Agents 的能力组合解决实际问题
现在轮到你了。停下来,思考如何用 Deep Agents 构建一个代码审查 Agent。需求如下:
智能体应该:
1. 接收一个 Git 仓库路径
2. 读取最近的代码变更(diff)
3. 分析变更的影响范围和风险等级
4. 检查代码风格和最佳实践
5. 生成审查意见
6. 如果发现高风险问题,暂停等待人工确认
7. 输出最终的审查报告
任务 1:选择能力
- 需要哪些内置能力?(规划、文件系统、子 Agent、权限...)
- 需要哪些自定义工具?
- 系统提示词应该怎么写?
任务 2:设计流程
- Agent 会如何自动规划这个任务?
- 哪些步骤适合交给子 Agent?
- 文件系统怎么用?存什么中间结果?
任务 3:安全设计
- 需要配置什么权限规则?
- 哪些操作需要 Human-in-the-loop?
- 用什么后端最合适?
提示:不用写完整代码,重点想清楚"Agent 需要什么能力、流程怎么拆、安全怎么控"。可以参考前面的架构图来组织你的思路。
参考答案
一种可行的设计方案——不是唯一答案,但逻辑合理
import * as z from "zod";
import { createDeepAgent } from "deepagents";
import { tool } from "langchain";
// 自定义工具一:获取 Git diff —— 让 Agent 能读取代码变更
const getGitDiff = tool(
async ({ repoPath, range }) => {
// 实际实现:运行 git diff 命令
return "diff content here...";
},
{
name: "get_git_diff",
description: "Get the git diff for recent changes",
schema: z.object({
repoPath: z.string(), // 仓库路径
range: z.string().optional(), // 可选的 commit 范围,如 HEAD~3
}),
},
);
// 自定义工具二:检查代码风格 —— 返回 lint 结果供 Agent 分析
const lintCode = tool(
async ({ filePath, content }) => {
// 实际实现:运行 linter(如 ESLint)
return { errors: 0, warnings: 2, details: "..." };
},
{
name: "lint_code",
description: "Lint code for style issues",
schema: z.object({
filePath: z.string(), // 要检查的文件路径
content: z.string(), // 文件内容
}),
},
);
// 创建代码审查 Agent —— 系统提示词引导 Agent 的工作流程
const reviewAgent = createDeepAgent({
model: "anthropic:claude-sonnet-4-6",
tools: [getGitDiff, lintCode],
systemPrompt: `你是一个代码审查助手。
收到审查请求后:
1. 先用 get_git_diff 获取变更
2. 分析影响范围和风险
3. 用 lint_code 检查风格问题
4. 将中间结果写入文件系统 ← 利用内置的文件系统工具
5. 生成审查报告
如果发现高风险问题,暂停等待确认。 ← 利用 Human-in-the-loop`,
});
能力组合
- 任务规划 — 自动拆解审查步骤
- 文件系统 — 存储 diff 和中间分析结果
- 子 Agent — 深入分析特定文件
- 权限 — 只允许读取指定仓库目录
安全策略
- 后端 — 沙箱后端,隔离代码执行
- 权限 — 只读源码目录,不写
- HITL — 高风险变更需人工确认
- 记忆 — 记住项目的编码规范偏好
你的方案可能不一样——这很正常。关键不是"答案是否一致",而是你能不能解释清楚:为什么选这些能力、为什么这样拆流程、为什么这样配权限。Deep Agents 的价值在于能力组合而非单一功能。
本章回顾
到这里,你已经掌握了 Deep Agents 的全貌
你学到了什么
- Deep Agents 是一种Agent Harness,内置规划、文件系统、子 Agent
createDeepAgent一个函数就能创建完整的 Agent- 文件系统工具让 Agent 可以卸载上下文到虚拟文件
- 可插拔后端:内存、磁盘、Store、沙箱、自定义
- 子 Agent 通过
task工具实现上下文隔离 - 权限规则 + HITL 让 Agent 可控又安全
- 技能、解释器、智能默认值提供可扩展性
后续章节预告
- 快速上手 — 完整实现一个 Deep Agent
- 自定义 — 深入配置选项和系统提示词
- 模型配置 — 选择和配置模型供应商
- 后端详解 — 各种文件系统后端的深入用法
- 子 Agent — 同步和异步子 Agent 的完整指南
- 沙箱与权限 — 安全执行和访问控制
- 记忆与技能 — 长期记忆和可复用技能
核心结论:Deep Agents 不是让你"少写代码"的工具,而是让你"处理更复杂的任务"的框架。当你的 Agent 需要自主规划、管理上下文、委派子任务、控制权限时,Deep Agents 提供的就是这些"自主性"的底层支撑。
延伸阅读
继续本课程
- 下一章:快速上手 — 完整实现你的第一个 Deep Agent
- 自定义指南 — 深入配置选项
- Deep Agents vs Claude Agent SDK — 框架对比
官方文档
- deepagents npm 包 — 安装和 API 参考
- GitHub 仓库 — 源码和示例
- LangSmith — 追踪调试和部署平台
相关资源
- LangChain 文档索引 — 完整的文档导航
- LangGraph.js 文档 — 底层运行时
- 框架、运行时和 Harness 的区别 — 理解技术栈层级