✦ Puxiaoshuai · Time is a river painted on scrolls · Walk to the water’s end, sit and watch the clouds rise

deepagents2026.09.04 · 29 min read

DeepAgents 开箱即用地搭出深度调研助手

DeepAgents 的 createDeepAgent 搭了一个多 Agent 深度调研助手——主 Agent 列 todo 清单逐步推进,调研、数据分析、报告编辑交给三个子 Agent;没写任何编排基础设施,todo 清单、长期记忆、技能、上下文压缩全是内置、只做配置。这篇拆给你看:哪些能力是开箱即用的

L

Leo

2026.09.04 · Updated 2026.09.04

0 views
DeepAgents 开箱即用地搭出深度调研助手

DeepAgents 开箱即用地搭出深度调研助手

为什么写这篇:多 Agent 的「隐形工作量」到底在哪

单 Agent 好做,多 Agent 才是分水岭。等你真的想做一个「会自己拆任务、分头干活、最后汇总」的 Agent,才发现难点根本不在「调大模型」,而在编排。回想一下要自己手写的东西:

  • 让它列步骤、跟进度:写 tool、改状态、维护一张「待办清单」并在每轮回答前喂回去;
  • 让主 Agent 委派子 Agent:task 工具、子 Agent 的独立上下文、怎么把结果传回来;
  • 让子 Agent 能干自己的活:联网搜索要注册、要跑数值计算还得给它开个代码执行环境;
  • 让它记住你的偏好:每次都得手动把长串规范塞进系统提示;
  • 让它会某项专业技能:技能文本什么时候注入、怎么按需触发;
  • 上下文越聊越长:什么时候该摘要压缩、怎么决定保留哪段历史。

这些问题一个比一个像「地基」。我见过很多人(包括从前的我)把大量精力砸在这些地基上,Agent 的核心能力反而没时间打磨。

这篇文章记录我们最近的一次实践:基于 DeepAgents 的 createDeepAgent,搭了一个多 Agent 架构的深度调研助手。结果相当反直觉——我们没有写多少代码,就把上面这些「地基」全解决了。这篇就拆开看:哪些是框架内置的、哪些只需要写 prompt / 做配置、各是什么原理。你能直接复用这套思路,把「深度调研」换成你自己的业务。

一句话结论放前面:编排与上下文管理这类「横切基础设施」,DeepAgents 全给你内置好了;你要写的主要是分工设计(写 prompt)和少量胶水代码。 这就是它「开箱即用」的价值。


先认识主角:createDeepAgent 是什么

它是什么

createDeepAgent 是 DeepAgents 暴露的工厂函数:调用它返回一个已经编排好、可直接运行的 Agent,而不是让你从零拼工具、拼循环。它内部本质是 createAgent + 一组官方中间件(todo 清单、记忆、技能、文件系统、上下文摘要、子代理委派),所以你拿到手的就是一个功能完整的 Agent,想换哪块再拆。

最大的副产品:它返回的是一个编译好的 LangGraph 图。意味着 stream、subgraphs 子图流式、checkpointer、断点续跑这些 LangGraph 能力全都自然可用,我们 CLI 里就是靠它逐条打印「现在是哪个 Agent、在调什么工具」的实时进度。

一句话版本:createDeepAgent = 一个开箱即用、能挂子 Agent、能配记忆和技能的 Agent 工厂,返回物是 LangGraph 图。

开箱即用能力对照

DeepAgents 内置能力它帮你做了什么你需要做的
Todo 清单内置 write_todos 工具 + todo 中间件,Agent 拆步骤、改状态都有人接在系统提示里「命令」它先列清单
文件系统FilesystemBackend 注入读写文件/目录/搜索等工具,Agent 有了「工作记忆」传一个 backend
长期记忆启动时加载 AGENTS.md 作为记忆上下文memory 指向你的记忆文件
技能扫描技能目录,按需注入技能文本skills 指向目录 + 每个技能一份说明
子 Agent 委派内置 task 工具,可并行开子 Agent,各自独立上下文声明 subagents 数组
上下文压缩超预算时自动摘要、裁剪工具结果几乎不用做;可调阈值
流式/图能力返回 LangGraph 图直接用,不用写图

看着这张表,我们其实只做了一件事:把「分工设计」翻译成系统提示,并声明了 3 个子 Agent。


我们搭的东西长什么样

深度调研助手是一个主 Agent + 三个子 Agent的团队:

  • 主 Agent(编排者):列 todo 清单、逐步推进;亲自起草报告;把专业活委派下去。
  • 调研员 researcher:负责一个聚焦子主题,联网搜索,把原始资料落盘。
  • 分析师 analyst:负责数值计算/数据分析,用 eval 代码执行环境算,禁止猜数字。
  • 编辑 editor:只读审稿,给修订建议,不亲自改写。

整个架构长这样:

两个细节值得先说清:

  • 子 Agent 也继承了 todo 能力。 调研员处理一个子主题如果也要多步(搜索、整理、写文件),它同样会自己先 write_todos 拆几步、逐步执行、完了把状态标记完成——因为 todo 中间件对每个 Agent 节点都生效。你不需要为「子 Agent 会不会规划」多写任何东西,只要在它的提示里允许它这么做。
  • 技能和子 Agent 是两回事。 我们的 web-research、report-writer 是技能(给同一个 Agent 的写作/流程指南),不是能委派的人。主 Agent 的系统提示里明确写死:这两个只能当指南照着做,禁止当 subagent 去 task——技能是「自己的方法论」,子 Agent 是「另一个人」,这一条分清楚,架构就不乱。

第一个知识点:几十行代码把骨架搭起来

它是什么 / 解决什么

不管 Agent 内部多复杂,对外暴露的入口就一个:createDeepAgent({ ... })。下面的骨架几乎就是这个项目的全部「胶水代码」(真正长的部分只有各 Agent 的系统提示,那属于内容,不属于基础设施):

import path from "node:path";
import { ChatOpenAI } from "@langchain/openai";
import { createCodeInterpreterMiddleware } from "@langchain/quickjs";
import { createDeepAgent, FilesystemBackend } from "deepagents";

const projectDir = /* 你的项目根目录 */;

export function createResearchAgent() {
  const model = new ChatOpenAI({
    model: "gpt-4o",
    temperature: 0,
    apiKey: process.env.OPENAI_API_KEY,
  });

  return createDeepAgent({
    model,
    // 主 Agent 的分工设计:全写在提示里
    systemPrompt: /* 主 Agent 的系统提示:职责、标准流程、委派规则 */,

    // 文件系统作为 Agent 的工作记忆(读/写/搜)
    backend: new FilesystemBackend({ rootDir: projectDir, virtualMode: true }),

    // 长期记忆:启动时加载这份规范
    memory: [path.join(projectDir, "AGENTS.md")],

    // 技能:扫描该目录,按需注入 SKILL.md
    skills: [path.join(projectDir, "skills")],

    // 子 Agent 团队
    subagents: [researcher, editor, analyst],
  });
}

FilesystemBackend 这一行很关键:它让 Agent 拥有读写文件、ls/glob/grep 的能力,子 Agent 之间的信息就靠「把文件写到一个约定的目录,别人去读」来传递——而不是靠把超长对话历史塞给下一个 Agent。文件即工作记忆,Agent 之间靠落盘文件通信,这是它设计里的核心思想。

要点

  • createDeepAgent 是工厂,返回编译好的 LangGraph 图,可 stream、可挂 checkpointer;
  • backend 注入文件系统工具,子 Agent 之间通过文件传信息,不依赖对话历史;
  • memory、skills、subagents 都是声明式配置,机制框架已内置;
  • 真正的系统设计工作在 systemPrompt——分工思路写在提示里,而非写在代码里。

第二个知识点:Todo 清单——让 Agent「列计划、跟进度」

它是什么 / 解决什么

深度调研是多步活:规划 → 分头调研 → 分析 → 起草 → 审阅 → 定稿。没有清单,长 Agent 容易跑飞或忘步骤。todo 清单机制在 createDeepAgent 里是内置的:Agent 可以调 write_todos 列出步骤、逐步执行、每完成一条就更新状态,我们在 CLI 里能实时看到它更新到第几条。

你不需要注册任何东西。只需要在系统提示里告诉主 Agent「按规矩来」,例如:

  • 收到任务后,先用 write_todos 把任务拆成中文步骤;
  • 每一步执行完,把对应 todo 状态改成完成;
  • 不要跳过计划直接开干。

这样主 Agent 每轮决策前都会先「看一眼清单、决定下一步」,长任务就有了节奏感。而我们的主提示里甚至规定了每一步该写什么,例如「撰写调研计划」「委派调研员调研 LangGraph」这种粒度——清单既是进度条,也是给模型当「下一步提示词」用的。

要点

  • todo 是内置机制 + 工具,主 Agent 按你提示里的规矩使用;
  • 步骤粒度写细一点,能帮模型自己找到「现在该干哪步」;
  • 清单写进文件系统,整个流程可追溯、可断点续跑;
  • 子 Agent 同样是 todo 中间件的受益者(见下节)。

第三个知识点:子 Agent——把活委派给「各有能力」的人

它是什么 / 解决什么

主 Agent 不可能擅长一切。联网搜索、跑代码算数、当编辑挑错,这些都是不同工种。createDeepAgent 让子 Agent 是一等公民:你在 subagents 里声明几个「人」,每个可以自带工具、自带中间件、自带系统提示;主 Agent 通过内置的 task 工具把任务委派出去,每个子 Agent 有独立上下文窗口,不会互相污染。

调研员的样子大概是:

const researcher = {
  name: "researcher",
  description:
    "通过联网搜索调研单一子主题。每次只分配一个子主题;多个独立子主题可并行多个调研员。",
  systemPrompt: `
    你是一名专业调研员,负责调研**一个**分配给你的子主题。
    可选:先 write_todos 列出至多 3 条中文步骤,再按步骤执行。
    最多调用 3 次联网搜索(硬性上限)。
    把整理结果写入任务指定路径的调研文件,**只写一次**,写完整理即结束,不要再搜索或更新 todo。
  `,
  tools: [webSearch], // 它比别的子 Agent 多一把「联网搜索」的刀
};

分析师则靠给子 Agent 挂中间件获得另一种超能力——代码执行:

import { createCodeInterpreterMiddleware } from "@langchain/quickjs";

const analyst = {
  name: "analyst",
  description: "使用 eval 代码环境进行数值计算与结构化数据分析。",
  systemPrompt: `
    你是一名数据分析师。所有计算必须通过 eval 环境完成,禁止猜测数字。
    读取数据 → 在环境里写 JS 算出结果 → 把计算逻辑与结论存成分析文件。
  `,
  middleware: [createCodeInterpreterMiddleware()], // 这给子 Agent 装了代码执行器
};

编辑更「纯粹」——不带任何工具,系统提示只要求它读草稿、返回意见、不亲手改:

const editor = {
  name: "editor",
  description: "审阅报告草稿的准确性、结构与完整性,在草稿写好后使用。",
  systemPrompt: `
    你是资深情报编辑,负责**审阅**草稿——不要亲自改写。
    检查:是否回答了原始问题?结构是否清晰?是否引用来源?有无无依据断言?
    返回简洁的审阅意见与可操作修改建议,不写入任何文件。
  `,
};

三个人,三种配法,一览:

子 Agent关键能力如何获得该能力职责
researcher 调研员联网搜索tools: [webSearch]单子主题搜索 + 整理落盘
analyst 分析师eval 代码执行middleware: [createCodeInterpreterMiddleware()]数值计算、数据分析
editor 编辑无工具(只读)只写系统提示审稿、给修改建议

要点

  • 子 Agent = subagents 数组里的一个对象,各配各的工具/中间件/提示;
  • 委派走内置 task 工具,主 Agent 提示里约定好「最多并行几个、最多开几个」;
  • 子 Agent 独立上下文,靠文件落盘交接产物;
  • 想给子 Agent 新能力 = 给它加工具或加中间件,不需要改编排代码。

第四个知识点:子 Agent 的多步活——它自己也会列 todo

它是什么 / 解决什么

很多人以为「todo 清单」只管主 Agent。其实 todo 中间件挂在每个 Agent 节点上,子 Agent 一旦被委派去干一件也要分几步的事,它同样会「先列步骤、逐步执行、更新状态」。

调研员就是这样:它被派去调研「某个框架」时,可能觉得要先搜官方文档、再搜社区评价、最后整理写入文件——那它就自己 write_todos 这三步,一步步走完再收尾。我们在调研员的系统提示里专门写了一节「write_todos 使用规则」,告诉它:

  • 至多 3 条、用中文;
  • 只拆它自己这一步的活,不要重复主 Agent 已做过的总体规划;
  • 最后一条必须是「写入 findings 文件」,写完把所有 todo 标为完成就结束。

这背后的设计意图是:给子 Agent 的提示里必须设「刹车」——搜几次是上限、写几次文件是上限、什么时候必须停。多 Agent 系统最常见的失控,就是子 Agent 拿到任务后无限循环地「再搜一下、再补一点」。把上限写进它的提示,配合 todo 的「完成即停」,运行才收敛。

要点

  • todo 机制对主 Agent、子 Agent 一视同仁,因为它挂在 Agent 节点上;
  • 想让子 Agent 也会拆步骤,只需在它的提示里「允许它用 write_todos」;
  • 更要紧的是写清刹车条件:调用上限、文件写入次数、结束标志;
  • 子 Agent 列 todo 是「战术拆解」,主 Agent 列 todo 是「战略规划」,职责别混。

第五个知识点:技能——放一个目录进去就能「按需加载方法论」

它是什么 / 解决什么

「会联网调研」「会写报告」这种是可复用的方法论,不该写死在系统提示里(那样换任务就得改代码)。DeepAgents 的技能机制是:你准备一个技能目录,每个技能一个子目录 + 一份带 frontmatter 的说明,框架会在 Agent 运行到相关场景时按需把技能内容注入。

skills 指向目录即可,机制全内置。一份技能的说明长这样:

---
name: report-writer
description: 将调研结果整理为结构清晰、专业的中文情报报告
---

# 报告撰写技能

把调研 findings 综合为最终交付物时使用。

## 报告结构
1. 标题   2. 执行摘要(3-5 条)   3. 背景   4. 核心发现
5. 分析   6. 结论   7. 参考资料(编号列表 + 链接)

## 写作规范
- 全文中文、第三人称专业表述
- 关键论断附带来源引用
- 每节内容充实,避免一句话带过

我们的两个技能 web-research(怎么规划子主题、怎么并行委派调研员)和 report-writer(报告结构 + 写作规范),就是主 Agent 的「操作手册」:干活前它被注入这套指南照着做。改报告风格 = 改这份文件,不用动代码。

再强调一次容易混的点——技能不是子 Agent:

技能是「给同一个 Agent 加载的说明文档」,子 Agent 是「委派给另一个上下文的人」。我们特意在提示里禁止把技能名当成 subagent 去调,防止架构退化成一团乱麻。

要点

  • 技能 = 目录 + 一份说明,放进去即被框架管理,按需注入;
  • 一个技能目录可以放任意多个技能,命名/描述写清楚便于框架触发;
  • 技能承载「方法论文档」,改风格改流程都改文件不改代码;
  • 严格区分「技能(自己的指南)」与「子 Agent(委派的人)」。

第六个知识点:长期记忆——AGENTS.md 一放,偏好就记住了

它是什么 / 解决什么

不想把「报告要用中文、要有执行摘要、必须列参考资料」这类稳定偏好每次写进提示词?DeepAgents 支持 AGENTS.md 规范:框架启动时会把这份文件作为记忆加载进上下文。

注册方式已经出现在骨架里:memory: [path.join(projectDir, "AGENTS.md")]。文件内容就是你与 Agent 的「契约」,随便写一点示意:

# 深度调研助手 · 用户偏好

## 报告偏好
- 所有报告、任务列表均使用中文
- 报告顶部包含「执行摘要」(3-5 条要点)
- 每份报告末尾必须有「参考资料」章节,列出所有引用 URL

## 调研标准
- 重要结论尽量用两个以上独立来源交叉验证
- 明确标注信息冲突,区分事实与推测

于是所有子 Agent 产出的中文、报告结构、调研纪律,都不用逐条写进提示——它们共享同一份记忆规范。AGENTS.md 也因此成了「调 Agent 行为」最便宜的地方。

要点

  • AGENTS.md 是启动即加载的长期记忆,memory 数组可放多个;
  • 稳定的偏好与规范放这里,高频变化的流程放技能,各司其职;
  • 改行为 = 改这份文件,记忆对所有 Agent(含子 Agent)生效。

第七个知识点:上下文压缩——聊长了它自己会「归档」

它是什么 / 解决什么

深度调研跑下来消息会非常长:十几轮模型调用、工具结果、子 Agent 的产物摘要……不处理迟早爆上下文。上下文压缩是 createDeepAgent 的内置功能:上下文超过预算时,它会自动把早期消息做摘要、裁剪工具结果,让对话「瘦身」后继续跑——就像人聊到一半把前面的笔记归档成几行要点。

你几乎不用配。唯一常动的是触发阈值,它由模型的 profile.maxInputTokens 控制,触发点按这个值的一定比例计算:

// 想更早触发压缩,就调小这个值(示意:让模型暴露一个较小的 maxInputTokens)
Object.defineProperty(chatModel, "profile", {
  get: () => ({ maxInputTokens: 8_000 }),
});

也就是说:压缩是否触发、何时触发,取决于 maxInputTokens;把值调小 = 更早触发摘要压缩。我们把它当「灵敏度旋钮」用:长任务怕爆上下文就调小些,短任务想少打扰就保持默认。

要点

  • 上下文自动压缩是内置的:超预算 → 摘要历史、裁剪工具结果;
  • 触发阈值看 profile.maxInputTokens,按它的比例计算触发点;
  • 调小 = 更早压缩,把它当灵敏度旋钮即可;
  • 这条你甚至可以完全不管——默认就能保证长任务不爆上下文。

没有写很多代码,但得到了什么

复盘一下,我们实际写的东西:

  • 一份主 Agent 的系统提示(分工 + 流程 + 委派规则);
  • 三个子 Agent 的定义(提示 + 各自工具/中间件);
  • 一份 AGENTS.md 记忆、两个技能的说明文件;
  • 一个封装了模型与文件后端的工厂函数、一个打印进度的 CLI。

我们没有写的东西:todo 清单与状态机、task 委派与子 Agent 生命周期、技能加载器、AGENTS.md 记忆注入、上下文摘要压缩、文件系统后端——全由 createDeepAgent 内置。

把「如果要自己搭」的开销摊开看,差距就很直观:

需求自研工作量createDeepAgent
多步规划 + 进度跟踪写工具、维护状态、每轮拼历史内置 todo,写句「先列清单」
子 Agent 委派 + 隔离上下文自己编 graph、管上下文subagents 数组声明
子 Agent 各配能力写工具/环境接入加 tools 或挂中间件
方法论文档化自己写动态注入逻辑放技能目录即用
长期记忆自己管理启动加载memory 指个文件
上下文压缩自己写摘要策略内置,调个阈值

需要提醒的是,「没写很多代码」不等于「不花心思」。省下来的是基础设施代码,真正决定这个 Agent 好不好用的,是设计:每个工种怎么分工、子 Agent 的刹车条件、技能与子 Agent 的边界、todo 步骤的粒度……这些全部以提示工程的形式沉淀了下来。DeepAgents 把「如何让 Agent 能干活」的地基打好了,于是我们可以把精力全部放在「让 Agent 干得聪明」上。


怎么选、怎么用:一张速查图 + 决策表

把整个运行时串起来看,主 Agent 每轮大约都在这几个状态间流转:

落到「我该把 XX 放哪」的决策,用这张表就够了:

想解决的事该用的机制例子
Agent 需要稳定偏好/纪律长期记忆 AGENTS.md中文输出、引用规范
Agent 需要一套可复用方法论技能报告怎么写、调研怎么规划
有一类需要独立上下文的脏活累活子 Agent联网搜索、跑代码、审稿
需要给某子 Agent 一种专属能力给它加工具 / 挂中间件web_search、eval 代码执行
长任务怕上下文爆内置压缩,调 maxInputTokens把阈值调小早压缩

收尾

我们从「要做一个多 Agent 深度调研助手」到「跑通」,最深的体会是:当框架把 todo、记忆、技能、子 Agent、上下文压缩这些横切能力全部开箱内置后,多 Agent 的门槛就落回到了设计能力,而不是工程能力。你写的 prompt 决定 Agent 多聪明,框架负责让这个「聪明」能持续跑下去、不失控、不爆上下文。

DeepAgents 并不是唯一的选择——但「编排与上下文管理不该成为你的日常」这个思路,值得在任何 Agent 项目里坚持。下次再想「要不要自己手搓一个多 Agent 编排器」的时候,先想想:这件事,框架是不是已经替我做好了?

L

Leo

Blogger

Independent developer / Blogger and the maintainer of the original blog “大道至简”. Migrating years of posts and shiyu from WordPress to Next.js.

Reader comments

COMMENTS · 0

Leave a comment

Comments are shown after moderation · be kind0/100