当 Agent 框架开始「交钥匙」——DeepAgents 系列之一

一句话价值:写一个能跑的 Agent 不难,难的是让它别把上下文撑爆、别让子任务互相污染、别跑两轮就失忆 。LangChain 的 createAgent 给了你一个干净的循环,剩下这些生产环境的脏活全得自己干。DeepAgents 做的事,就是把这些脏活预先焊进框架里------它不是更聪明的模型,而是更省事的脚手架。


先看一个现实的坑

假设你要做一个"能查资料、能写文件、能分步办事"的研究助手。用最朴素的 createAgent 起手:

js 复制代码
const agent = createAgent({
  model,
  tools: [webSearch],        // 只有搜索
  systemPrompt: "你是一个研究助手"
});

跑起来很快就能发现问题------它只会搜索,不会记笔记。

于是你把搜索到的东西全塞进对话历史里。跑个十几轮,messages 数组越来越长,token 消耗直线飙升,最后撞上限。

再往下走,你想把这活儿拆开并行做:A 查框架甲、B 查框架乙。但两个子任务塞在同一个对话里,甲的资料会污染乙的判断。你开始手工给子任务开新会话、传结果......

到这里你会发现:你要写的东西,跟业务一点关系都没有。 全是 Agent 的"基建"------上下文怎么管、子任务怎么隔离、跨会话怎么记住。

DeepAgents 就是冲着这批基建来的。


三层生态:积木、蓝图、半成品

很多人第一次看 LangChain 全家桶会懵:LangChain、LangGraph、DeepAgents 到底啥关系?

复制代码
┌──────────────────────────────────────────────────────────────┐
│  DeepAgents    半成品 Agent 框架(精装房)                    │
│                预装:文件系统 / 记忆 / 技能 / 子代理 / 摘要   │
│    ↑ 复用 middleware 机制,把内置能力写成一个个中间件         │
├──────────────────────────────────────────────────────────────┤
│  LangGraph     底层运行时蓝图                                 │
│                状态管理 / 循环路由 / 持久化执行 / 流式        │
│    ↑ createAgent 把 middleware 编排成一张图                   │
├──────────────────────────────────────────────────────────────┤
│  LangChain     积木层                                         │
│                chat model / tool / 消息类型 / createMiddleware │
│                定义了 middleware + hooks 机制(关键)         │
└──────────────────────────────────────────────────────────────┘

换成一句更好记的话:

层 比喻 回答的问题
LangChain 一堆 AI 开发积木 有哪些零件?
LangGraph 搭建复杂工作流的底层蓝图 零件怎么连成图?
DeepAgents 半成品 Agent 框架 复杂 Agent 怎么少写重复代码?

关键认知:DeepAgents 不是另一个从零写的运行时。它架在 LangChain + LangGraph 之上------LangChain 出积木、LangGraph 出运行时,它则在这之上加了一层"开箱即用"。

它同时有 Python 版(PyPI 的 deepagents)和 JS/TS 版(npm 的 deepagents),API 几乎一一对应。

⚠️ 一个小提醒:搜 "deepagents" 会同时出现两个东西------Deep Agents (这个库)和 Deep Agents Code(一个 CLI 工具)。别混淆。


createAgent 到底给了你什么

在聊 DeepAgents 之前,得先看清它替代的那个东西。

先说没有 agent 的日子:你直接调 LLM(ChatOpenAI),它是一问一答------你说话,它回话,仅此而已,它不能做事。

Agent 的本质,是给 LLM 装上"手脚":

scss 复制代码
agent = 模型(大脑) + 工具(手脚) + 一个循环(自主决策)

那个循环是这样跑的:

arduino 复制代码
模型说"我要调用工具 A"
      ↓
框架执行工具 A
      ↓
把结果塞回消息
      ↓
模型看结果,决定下一步
      ↓
......直到模型说"任务完成"

这个循环,就是 agent 区别于聊天机器人的全部秘密------它让模型能"自主地、分多步地"把一件真事办成。

createAgent 干的活,就是帮你把这个循环搭好。你不再需要手写:怎么把工具定义喂给模型、怎么解析模型返回的工具调用、怎么执行工具、怎么判断结束。你只传三样:

js 复制代码
const agent = createAgent({ model, tools, systemPrompt });

就得到一个能自主干活的 agent。它背后是 LangGraph 编译出来的一张图。

但它给的是光溜溜的循环------除了"模型 ↔ 工具"这个骨架,什么都没有。


DeepAgents 要解决的三个痛点

一旦任务变长变复杂,光溜溜的循环立刻暴露三个问题:

痛点 具体表现 DeepAgents 的答案
上下文越跑越长 撞 token 上限、成本失控 虚拟文件系统 + 摘要/上下文卸载:中间结果写进文件,而不是塞进 prompt
大任务没法并行 子任务互相污染上下文 subagent 派发,每个子代理跑在隔离的上下文窗口里
跑几轮就"失忆" 换会话重来 长期记忆 + skills,按需加载

三个痛点指向同一个核心思路:

用文件系统当上下文管理的载体------"文件系统即记忆"。

这是个很值得品的设计判断。大多数人的第一反应是"上下文不够就上向量库",但 DeepAgents 选了更朴素的路:把中间结果写成文件,需要时再读回来。原因很简单------文件是结构化、可寻址、可增量读写的,而塞进 prompt 的每个 token 都要反复付费,还挤占推理空间。

它的能力被官方分成四大支柱:

markdown 复制代码
1. Execution environment   执行环境
   ├─ 自定义 tool / LangChain tool / MCP 工具
   ├─ 虚拟文件系统(可插拔 backend + 声明式权限)
   └─ 沙盒执行、进程内 JS 解释器、事件流式

2. Context management      上下文管理(四层)
   ├─ Skills          按需加载的能力片段
   ├─ Memory          跨会话长期记忆
   ├─ Summarization   摘要 + 大结果卸载到文件
   └─ Prompt caching  省 token

3. Delegation              委派
   ├─ 内置 task 工具,派发隔离上下文的子代理
   └─ TodoListMiddleware(write_todos)结构化任务清单

4. Steering                引导
   └─ human-in-the-loop:关键决策点暂停、等人类审批

一个函数就搞定:createDeepAgent

回到开头那个"只会搜索"的助手。同样的需求,DeepAgents 的写法是:

js 复制代码
import { createDeepAgent, FilesystemBackend } from "deepagents";

const agent = createDeepAgent({
  model,
  systemPrompt: "你是一个研究助手,用文件系统记录中间结果",
  backend: new FilesystemBackend({
    rootDir: workspaceDir,
    virtualMode: true,
  }),
});

注意------没有 middleware 数组 。就传了个 backend。

对比一下要达成同样效果,createAgent 得写什么:

js 复制代码
// createAgent 版:手动组装
const agent = createAgent({
  model,
  tools: [],
  systemPrompt: "...",
  middleware: [
    createFilesystemMiddleware({
      backend: new FilesystemBackend({
        rootDir: workspaceDir,
        virtualMode: true,
      })
    })
  ]
});

两个版本我都跑过(代码在 demo/src/deepagents/ 下),实际效果对照:

中间件 状态 提供的能力
FilesystemMiddleware 自动(必需) ls / read_file / write_file / edit_file / glob / grep
SubAgentMiddleware 自动(必需) task 工具,派发子代理
SummarizationMiddleware 自动 长对话自动摘要
TodoListMiddleware ⚠️ 需 opt-in write_todos 任务规划

前三个是"开箱即用"的核心。这就是 createDeepAgent 相对 createAgent 的本质差别:一个给你空循环,一个给你预装好生产插件的循环。

跑完之后最直观的验证不是看控制台,而是去看磁盘------工作区目录里会真实出现 agent 用 write_file 写的文件。这时候你就知道"文件系统即记忆"不是说说而已。

⚠️ 这里有个后面会反复踩的坑:TodoListMiddleware 那一行我标了"需 opt-in"。它不是自动挂的 ,而且不挂的时候不报错------直到你写提示词让模型用 write_todos,才会发现它压根没这个工具。第三篇会细讲。


一个必要的概念澄清:谁是什么

理解这套体系时,有个很容易搞混的地方:这些组件哪个才是 Runnable?

LangChain 里 Runnable 是一套接口协议,承诺三件事:

scss 复制代码
任何 Runnable 都:
  .invoke()   能调用
  .stream()   能流式
  .pipe()     能组合(LCEL 的核心)

于是很自然的一个推断是:agent、middleware、backend 是不是层层继承 Runnable?

不是。 只有 agent 是。

bash 复制代码
Runnable 协议(invoke/stream/pipe)
   ↑ ✅ 是 Runnable
Agent  ←  createAgent 返回,背后是 LangGraph 编译好的图
   ↑ ❌ 不是 Runnable,是"插件/钩子集合"
Middleware  ←  createMiddleware 返回,只是配置对象
   ↑ ❌ 不是 Runnable,是"实现细节"
Backend  ←  文件系统的落地实现

判断标准特别简单:能 .invoke() 的才是 Runnable 。middleware 和 backend 你能 .invoke() 它吗?不能。

那 middleware 到底是什么?准确说:middleware 的 hooks 会在 createAgent 编译 agent 图的时候,被"织进"这个 Runnable 里------变成图里的节点和边。所以是 middleware「参与构成」Runnable,而不是「继承」Runnable。

顺带纠正另一个说法:解耦靠的是**「协议 + 组合 + 依赖注入」**,不是「继承基类」。而且这里其实混了两种不同类型的解耦:

bash 复制代码
① Runnable 的组合式解耦(横向串能力)
   LLM | prompt | tool | agent   ← 用 .pipe() 串成一条链

② middleware/backend 的插件式解耦(纵向抽横切)
   agent 核心循环
      ├─ loggingMiddleware       ← 可观测性,插拔不影响核心
      ├─ filesystemMiddleware    ← 文件能力
      │     └─ FilesystemBackend ← 落地实现,可换成内存/云
      └─ ...

小结

  • DeepAgents 是 LangChain 官方的 agent harness:架在 LangChain + LangGraph 之上,不重造轮子。
  • 三层定位:LangChain 积木 → LangGraph 蓝图 → DeepAgents 半成品框架。
  • 它解决三个生产痛点:上下文爆炸、子任务污染、跨会话失忆。核心思路是"文件系统即记忆"。
  • createDeepAgent vs createAgent:一个预装插件,一个空循环。
  • 只有 agent 是 Runnable,middleware 是被织进图里的插件。

但这里还留了个没说透的问题:DeepAgents 那些"开箱即用"的能力,到底是怎么挂上去的?

答案就藏在一个词里------middleware。下一篇我们从零手写一个中间件,把它的机制彻底拆开。


系列导航

序号 标题 主题
01 当 Agent 框架开始「交钥匙」 定位、痛点、createAgent vs createDeepAgent
02 六种 Hook 与两种范式 middleware 机制:节点式 vs 包裹式
03 一个中间件就是一项能力 内置中间件拆解:文件系统、记忆、技能、子代理
04 参数拼错不报错 生产避坑:静默失效、流式观测与调试
相关推荐
光影少年2 小时前
langchain与langgraph区别以及学习路线
elasticsearch·langchain·llm
不好听6132 小时前
六种 Hook 与两种范式——DeepAgents 系列之二
langchain
光依旧20 小时前
PageIndex没翻车,翻车的是我的解析器
docker·langchain·大模型·向量数据库·pdf解析·rag·pageindex
打工仔折腾 AI21 小时前
从BPE到SentencePiece:Transformer分词原理与Python实战对比
android·人工智能·python·深度学习·langchain·transformer·ai agent 实战
东方芷兰1 天前
Agent 技术摘要 06 —— Harness、原生视觉、Jev、mmproj、dsh
人工智能·笔记·python·ai·langchain·ai编程
桃西西呀1 天前
LangChain 之三:模型与消息抽象
人工智能·langchain·llm
用户3134672143541 天前
Agent实践5-无 Function Call 的结构化通用 Agent
langchain·agent
minji...1 天前
LangGraph-AI智能体开发框架 - LangGraph 入门案例1 : 智能快递配送系统
人工智能·python·ai·langchain·大语言模型·agent·langgraph
用户3134672143542 天前
Agent相关-FAISS 与 LangChain 在文档检索中的分工
langchain