目标:让你在 60 分钟内,从 0 到能写出一个可用的 DeepAgents 应用(含工具、子代理、人工审批中断恢复、记忆、技能、流式输出)。
1. 先建立一个正确心智模型
一句话:
- DeepAgents:高层“开箱即用”Agent Harness(总控框架)
- LangChain:通用能力层(模型/工具/RAG/输出等积木)
- LangGraph:底层运行时(分支、回路、checkpoint、中断恢复)
1.1 先把 Harness 这个词讲透
Harness 可以理解为“总控壳 + 执行骨架”:
它不是单一功能库,而是把 Agent 需要的一整套机制(文件系统、工具、子代理、上下文治理、恢复机制)组织成一个可运行框架。
你可以把它类比成:
- 不是“一个函数库”
- 而是“一个可直接开工的运行底座”
1.2 和 Agent SDK 的类比(帮助你建立直觉)
相同点(心智接近):
- 都强调“任务驱动 + 工具调用 + 文件系统操作 + 长流程执行”
- 都不是只回答问题,而是能执行多步任务
- 都需要在复杂任务里做上下文治理和过程控制
区别点(定位不同):
- Claude Agent SDK / Codex SDK 更偏“可编程 Agent 能力接入”
- DeepAgents 更偏“可编程的 Agent Harness”,你可以深度定制运行逻辑
1.3 竞品视角(2 个)
- Claude Agent SDK
- Codex SDK
1.4 房子比喻(你要求的版本)
- LangChain 像“房子的零部件”:门、窗、管线、开关(模型、工具、RAG、Prompt 等能力件)
- DeepAgents 像“毛坯房 + 施工总包框架”:基础结构先搭好,你可以按业务继续精装
- LangGraph 像“承重结构和施工流程控制”:保证流程能稳定跑、能中断恢复
所以组合关系是:
你用 LangChain 选部件,用 LangGraph 保证结构稳定,用 DeepAgents 快速把“可住的房子”先搭起来。
1.5 Harness 理论(重点)
如果只会“调用模型”,那不是 Harness。
Harness 的核心是把复杂任务变成可控流程,最常见闭环是:
-
Plan(先规划)
先拆任务、定边界、定验收标准,再开始执行。 -
Act(再执行)
按计划调工具、读写文件、调用子代理,逐步推进。 -
Check(持续验证)
每个阶段都做验证(测试、对账、规则校验),避免一路错到底。 -
Recover(可恢复)
中断、超时、审批、重启后能从上一步继续,而不是重跑全流程。
一句话:
Harness = Plan-first + Tool-use + Verification + Recovery 的工程闭环。
flowchart TB
A["DeepAgents(Harness)"] --> B["LangChain(能力积木)"]
B --> C["LangGraph(运行时引擎)"]
你可以把 DeepAgents 理解成:
“把 LangChain + LangGraph 的常见 Agent 能力打包好了,你先用,再按需下沉定制。”
2. 你会学到什么(对应真实客服场景)
我们用这句用户话术贯穿全教程:
上周我买的一个耳机坏了
你会实现:
- 接收用户输入并判断售后意图
- 调工具查订单和质保
- 信息不足时自动追问(多轮)
- 高风险动作(退款)先人工审批(中断)
- 审批后从上一步恢复继续执行(恢复)
- 保存长期偏好/规则(记忆)
3. 10 分钟跑通第一个 Deep Agent
3.1 安装依赖
pnpm add deepagents langchain @langchain/core zod
如果你要联网搜索工具(Tavily):
pnpm add @langchain/tavily
3.2 环境变量
# 二选一示例
setx OPENAI_API_KEY "your-api-key"
setx ANTHROPIC_API_KEY "your-api-key"
3.3 最小可运行代码
import { createDeepAgent } from 'deepagents'
const agent = createDeepAgent({
// provider:model 形式,便于快速切模型
model: 'openai:gpt-5.4',
systemPrompt: '你是一个专业中文客服助手,回答准确、简洁。',
})
const result = await agent.invoke({
messages: [{ role: 'user', content: '上周我买的一个耳机坏了,怎么办?' }],
})
console.log(result.messages[result.messages.length - 1]?.content)
4. 实战:耳机售后 Agent(工具 + 子代理)
下面这段是你可以直接改业务逻辑的骨架。
import { createDeepAgent } from 'deepagents'
import { tool } from 'langchain'
import { z } from 'zod'
// 1) 查订单工具:真实项目里这里接 OMS API
const queryOrder = tool(
async ({ orderId }: { orderId: string }) => {
// 示例:返回订单基本信息
return {
orderId,
productName: '无线蓝牙耳机',
purchaseDate: '2026-04-05',
amount: 699,
}
},
{
name: 'query_order',
description: '根据订单号查询订单详情',
schema: z.object({
orderId: z.string().describe('订单号'),
}),
},
)
// 2) 查质保工具:真实项目里这里接保修系统 API
const queryWarranty = tool(
async ({ orderId }: { orderId: string }) => {
return {
orderId,
inWarranty: true,
policy: '15天换新 + 1年质保维修',
}
},
{
name: 'query_warranty',
description: '查询订单是否在质保范围',
schema: z.object({
orderId: z.string().describe('订单号'),
}),
},
)
// 3) 创建售后工单工具
const createAfterSalesTicket = tool(
async ({ orderId, reason }: { orderId: string; reason: string }) => {
return {
ticketId: `AS-${Date.now()}`,
orderId,
status: 'created',
reason,
}
},
{
name: 'create_after_sales_ticket',
description: '创建售后工单',
schema: z.object({
orderId: z.string(),
reason: z.string(),
}),
},
)
// 4) 子代理:专门做政策判定,减少主代理上下文污染
const policySubagent = {
name: 'policy-expert',
description: '判断当前售后请求应该走退款、换货还是维修',
systemPrompt: `你是售后政策专家。
先判断信息是否齐全(订单号、购买时间、故障描述)。
信息不齐请明确指出缺失字段,不要编造。
信息齐全后,给出建议路径:refund / replace / repair。`,
}
const agent = createDeepAgent({
model: 'openai:gpt-5.4',
systemPrompt: `你是电商平台售后助手。
用户可能只说“耳机坏了”,你要主动收集必要信息后再决策。`,
tools: [queryOrder, queryWarranty, createAfterSalesTicket],
subagents: [policySubagent],
})
const result = await agent.invoke({
messages: [{ role: 'user', content: '上周我买的一个耳机坏了' }],
})
console.log(result.messages[result.messages.length - 1]?.content)
5. 生产关键:人工审批中断与恢复(HITL)
你之前一直问 checkpoint,这块就是核心用法。
import { createDeepAgent } from 'deepagents'
import { tool } from 'langchain'
import { MemorySaver, Command } from '@langchain/langgraph'
import { v7 as uuid7 } from 'uuid'
import { z } from 'zod'
const refund = tool(
async ({ orderId, amount }: { orderId: string; amount: number }) => {
return `Refund submitted: ${orderId}, amount=${amount}`
},
{
name: 'refund',
description: '发起退款',
schema: z.object({
orderId: z.string(),
amount: z.number(),
}),
},
)
const checkpointer = new MemorySaver()
const agent = createDeepAgent({
model: 'openai:gpt-5.4',
tools: [refund],
// 高风险工具启用人工审批
interruptOn: {
refund: { allowedDecisions: ['approve', 'reject', 'edit'] },
},
checkpointer, // HITL 必须有 checkpointer
})
const threadId = uuid7()
const config = { configurable: { thread_id: threadId } }
// 第一次调用:可能在 refund 前被中断
let result = await agent.invoke(
{
messages: [{ role: 'user', content: '给订单 A1001 退款 699 元' }],
},
config,
)
if (result.__interrupt__) {
// 审批系统给出决定,这里示例“批准”
const decisions = [{ type: 'approve' }]
// 关键:用同一个 thread_id 恢复
result = await agent.invoke(new Command({ resume: { decisions } }), config)
}
console.log(result.messages[result.messages.length - 1]?.content)
这段背后的业务意义
- 第一次
invoke走到敏感工具会暂停 - 流程状态已进 checkpoint(可持久化到数据库/存储)
- 审批完成后,用相同
thread_id+Command(resume)继续 - 不会从头跑,直接从中断点继续
6. 记忆(Memory)与技能(Skills)
先记住这一句:
DeepAgents 的 5 个高频生产能力是 虚拟文件系统(VFS)/ 记忆 / 长期记忆 / Skills / 子代理。
6.0 虚拟文件系统(VFS)强解释
这是最容易被低估、但生产最关键的能力之一。
通俗讲:
VFS 就是“给 Agent 一块受控工作区”。
Agent 看起来在操作文件,其实是在你划定的安全边界内操作。
更关键的是:
这个“工作区”背后可以接不同存储,不只本地硬盘。
- 本地目录(开发环境最常见)
- 网络存储/对象存储(团队共享、跨机器)
- 数据库存储(按租户/用户隔离,便于持久化与审计)
- 组合后端(不同路径走不同存储)
这就是 DeepAgents 的便利点:
你上层 Agent 代码几乎不变,只换 backend,就能切换底层存储策略。
为什么重要:
- 安全隔离:限制 Agent 只在指定目录活动
- 可审计:它读了什么、写了什么可以追踪
- 可恢复:中断后可以接着之前文件状态继续
- 可组合:同一 Agent 可以看到不同“投影文件系统”(如 skills 只读区、KB 只读区)
代码示例 1(本地目录 VFS,开发最常用):
import { createDeepAgent, FilesystemBackend } from 'deepagents'
const backend = new FilesystemBackend({
rootDir: 'E:/agent-workspace',
virtualMode: true, // 强制沙箱:路径被约束在 rootDir 下
})
const agent = createDeepAgent({
model: 'openai:gpt-5.4',
backend,
})
代码示例 2(数据库/网络存储 VFS,生产常见):
import { createDeepAgent, StoreBackend } from 'deepagents'
import type { BaseStore } from '@langchain/langgraph-checkpoint'
// 由你的基础设施提供:可接 Redis/DB/云存储封装后的 BaseStore
declare const myStore: BaseStore
const agent = createDeepAgent({
model: 'openai:gpt-5.4',
store: myStore,
// 通过 namespace 做租户/用户隔离(长期持久化)
backend: () =>
new StoreBackend({
namespace: ['memories', 'org-001', 'user-1001', 'filesystem'],
}),
})
代码示例 2.1(PostgreSQL 持久化示例,简化版):
import { createDeepAgent, StoreBackend } from 'deepagents'
import type { BaseStore } from '@langchain/langgraph-checkpoint'
import { Pool } from 'pg'
// 1) 连接 PostgreSQL
const pool = new Pool({
connectionString: process.env.PG_DSN, // 例如: postgres://user:pass@host:5432/agentdb
})
// 2) 你需要一个实现 BaseStore 的 PG 适配器(这里用伪代码表示)
class PgBaseStore implements BaseStore {
constructor(private pool: Pool) {}
// put/get/search/delete ...(按 BaseStore 接口实现)
}
const pgStore = new PgBaseStore(pool)
// 3) 把 PG Store 接到 DeepAgents 的 VFS 后端
const agent = createDeepAgent({
model: 'openai:gpt-5.4',
store: pgStore,
backend: () =>
new StoreBackend({
store: pgStore,
namespace: ['memories', 'org-001', 'user-1001', 'filesystem'],
}),
})
这个示例的价值是:
- 文件语义不变(Agent 仍按“读写文件”思考)
- 底层改为 PostgreSQL 持久化(跨会话、跨实例)
- 天然适合多租户隔离(通过 namespace 分租户/分用户)
代码示例 3(组合后端:热数据本地,长期记忆走持久化):
import { createDeepAgent, CompositeBackend, FilesystemBackend, StoreBackend } from 'deepagents'
import type { BaseStore } from '@langchain/langgraph-checkpoint'
declare const myStore: BaseStore
const agent = createDeepAgent({
model: 'openai:gpt-5.4',
store: myStore,
backend: () =>
new CompositeBackend(
new FilesystemBackend({ rootDir: 'E:/agent-workspace', virtualMode: true }),
{
'/memories/': new StoreBackend({
namespace: ['memories', 'org-001', 'user-1001', 'filesystem'],
}),
},
),
})
你可以把它类比前端:
- 像给前端应用做了严格的“资源沙箱”
- 不是不能读写,而是“只能在授权范围内读写”
6.1 记忆适合存什么
- 用户偏好(例如“回复尽量简短”)
- 业务固定规则(某品类优先换新)
- 团队 SOP(投诉单必须升级)
6.1.1 记忆 vs 长期记忆(一定分清)
- 会话记忆(短期):当前任务上下文,任务结束后价值下降
- 长期记忆(Long-term):跨会话复用的稳定知识,如用户偏好、团队规则、领域事实
判断标准:
“下一次开新会话还要不要用到?”
要用到,就应该进长期记忆。
6.1.2 长期记忆为什么说“框架 API 很方便”
如果你手写,通常要自己做这几件事:
- 读取记忆文件/数据库
- 拼接进 system prompt
- 处理多来源优先级
- 保证跨会话可复用
DeepAgents 给你的便利 API:
memory: string[]:声明要加载的记忆文件路径backend:决定这些记忆来自哪里(本地/数据库/组合)store:接持久化存储(跨会话、跨线程)
你不用自己每轮手拼 prompt,框架会把 memory 作为上下文注入。
代码示例(长期记忆 + 客服场景):
import { createDeepAgent, FilesystemBackend } from 'deepagents'
const backend = new FilesystemBackend({
rootDir: 'E:/after-sales-agent',
virtualMode: true,
})
const agent = createDeepAgent({
model: 'openai:gpt-5.4',
backend,
// 这些文件会在每次启动时被加载到上下文中
memory: ['/memory/user-profile.md', '/memory/after-sales-policy.md'],
})
const result = await agent.invoke({
messages: [{ role: 'user', content: '我耳机坏了,想处理售后' }],
})
这个例子里,user-profile.md 和 after-sales-policy.md 就是长期记忆载体:
下次新会话仍可复用,不需要每次重新喂给模型。
6.2 技能适合存什么
- 某类任务的标准操作步骤(例如“退款审批话术”)
- 某个外部系统的使用说明
- 领域化专家指令(例如“质保判责规范”)
Skills 的核心价值:
- 把“个人经验”变成“团队可复用能力包”
- 让 Agent 在复杂任务里少走弯路
- 保持输出风格和流程一致
DeepAgents 的优势是:
内建了文件系统语义,记忆和技能都能走统一的“文件 + 后端存储”模式。
代码示例(Skills 声明式加载):
import { createDeepAgent, FilesystemBackend } from 'deepagents'
const agent = createDeepAgent({
model: 'openai:gpt-5.4',
backend: new FilesystemBackend({ rootDir: 'E:/agent-workspace', virtualMode: true }),
skills: ['/skills/common/', '/skills/after-sales/'],
})
6.3 子代理(SubAgents)什么时候必须用
子代理不是“炫技”,而是“降复杂度”工具。
适用场景:
- 一个请求里存在明显不同职责(如政策判断、工单创建、风控审计)
- 主代理上下文过大,开始出现混乱和成本上升
- 希望每个角色有独立提示词和工具集
收益:
- 上下文污染降低
- 结果更稳定
- 流程更可维护(类似前端把大组件拆成多个职责清晰的小组件)
代码示例(子代理最小声明):
import { createDeepAgent } from 'deepagents'
const policySubagent = {
name: 'policy-expert',
description: '负责售后规则判定',
systemPrompt: '你是售后政策专家,只做规则判断并返回可执行结论。',
}
const agent = createDeepAgent({
model: 'openai:gpt-5.4',
subagents: [policySubagent],
})
7. 实时流式输出(便于 UI 展示执行过程)
for await (const [namespace, chunk] of await agent.stream(
{
messages: [{ role: 'user', content: '帮我处理耳机售后并给出方案' }],
},
{
streamMode: 'updates',
subgraphs: true, // 包含子代理事件
},
)) {
const source = namespace.length > 0 ? `subagent:${namespace.join('|')}` : 'main'
console.log(source, chunk)
}
你在前端里可以把这类事件渲染成“执行轨迹时间线”。
8. 常见坑(你一定会遇到)
-
interruptOn配了但恢复失败
原因:恢复时没用同一个thread_id -
审批后状态丢失
原因:没配置 checkpointer,或者 checkpointer 没持久化 -
上下文爆炸、费用升高
原因:子任务没下沉到 subagent,大量中间过程污染主上下文 -
技能没生效
原因:skills 路径/backend 映射错误,或技能描述太弱导致匹配不到
9. 60 分钟学习路线(建议)
- 0-10 分钟:跑通第一个
createDeepAgent + invoke - 10-25 分钟:加 2 个工具(查订单/查质保)
- 25-40 分钟:加
interruptOn + checkpointer + resume - 40-50 分钟:加 1 个 subagent 做政策判定
- 50-60 分钟:接
stream,把执行过程打印出来
10. 什么时候该下沉到 LangChain / LangGraph?
- 你要改模型策略、重试、输出结构、检索链路:下沉到 LangChain
- 你要精细控制图路由、回边、复杂中断恢复:下沉到 LangGraph
- 你要先把业务快速跑起来:优先 DeepAgents
11. 你现在可以直接做的下一步
- 把你现有“耳机坏了”流程接成 3 个真实工具:
query_order / query_warranty / create_ticket - 先只给
refund加interruptOn,打通审批恢复闭环 - 再拆一个
policy-expert子代理,让主代理只做协调