在本章中,我们将深入讨论 Deep Agents。Deep Agents 指的是这样一类 agent:它们有能力、真正有用,并且被设计来执行多种任务,尤其是那些需要在多个步骤中持续推理与行动的长时程任务(long-horizon tasks) 。像 Claude Code、Cursor CLI,以及 LangChain Deep Agents 这样的编码 agent,都属于这一类。这些系统并不局限于单步工具调用;它们运行在更长的工作流之上,会持续做决策、调整计划、反复执行,直到更大的目标被完成。
我们会先对 Deep Agents 进行分类学梳理,明确什么样的 agent 才算“deep”,以及哪些关键特征让它们区别于更简单的 agent 模式。然后,我们会从高层定义:究竟什么使一个 agent 成为 deep agent,并分析支撑长时程执行的那些核心属性。
这也能让我们对 Claude Code 这样的前沿编码 agent 在工程上是如何实现的,建立一个更贴近现实的理解。
本章将涵盖以下主题:
- 生产系统中的 agent 分类学
- 什么让一个 agent 成为 deep agent
生产系统中的 Agent 分类学
在讨论 Deep Agents 之前,我们首先需要建立一套分类框架,弄清楚:当前整个行业在生产环境里实际在使用哪些类型的 agent。这里我会做一些简化,并用我自己的方式来描述这个版图。
图 11.1 —— Agent 分类图,展示编码 agent 属于 Deep Agents
在最宽泛的层级上,我们先有一个“agents”领域。这个领域包含了当前真实系统中部署的所有类型 agent。它们可以是完全自主的 agent,也可以是 agentic applications。一个常见例子是:混合式 RAG 架构,其中由 LLM 来决定下一步该执行什么。
图 11.2 —— 由 LLM 编排的混合式 RAG 工作流
模型可能会决定:要不要先做搜索、要不要在检索前改写查询、或者要不要执行其他操作。此时,LLM 本质上就是在编排预定义工作流中的下一步动作。
图 11.3 —— 将 LLM 与外部工具连接起来的 ReAct 循环
在这个大伞之下,我们会看到 ReAct(Reason and Act)agent。在 ReAct agent 中,LLM 会决定是否使用某个工具。如果选中了工具,系统就执行它,并把结果作为一个 observation 返回。然后,LLM 再决定:现在的信息是否已经足够给出最终回答。如果还不够,它就继续这个循环:再选一个工具、再接收新的 observation,不断迭代,直到得到答案。
正是这个 ReAct 循环,开启了更广义的 agent 范式。如今绝大多数现代 agent 架构,都可以追溯到这一算法结构。这个方法最初提出于论文 “ReAct: Synergizing Reasoning and Acting in Language Models” 中:https://arxiv.org/abs/2210.03629
Shallow Agents 及其局限
在这套分类中,我会把 ReAct agent 归为 shallow agent。原因并不是说它没有价值,而是说:它不具备真正深入下去的能力。
设想一个需要做全面、长时间深入研究的任务。即便这个 agent 有搜索工具、wiki 工具,或者 Tavily 工具,它往往仍然很难做到足够深入的研究。这个限制既来自架构设计本身,也来自现代 LLM 的现实条件。
这种 agent 依赖 function calling。在每一个决策点上,LLM 会通过函数调用来选择要执行的工具。函数调用本身并没有什么错,虽然它确实有一些取舍。但这里真正的核心限制,其实是:context window。
在这个循环中的每一次迭代,都会继续往上下文里加信息。LLM 做出决策,工具被执行,结果再被注入 prompt,下一轮继续。前一两轮时,这还是可控的;可一旦迭代次数变多,上下文就会越来越大。
这种增长最终会带来 context rot。我们开始看到:
- context confusion(上下文混淆)
- context contradiction(上下文冲突)
- context pollution(上下文污染)
时间一长,性能会退化,agent 甚至可能彻底跑偏。
图 11.4 —— 在迭代式工具调用工作流中的上下文累积
当面对复杂、长时间运行的任务时,这个限制就会变得致命。比如:
- 实现一个功能
- 对某个主题做深度研究
- 执行一个需要持续推理与收集信息的多阶段工作流
这些任务从根本上就不同于“帮我订张机票”这种简单请求。
除了质量下降,成本也会持续上升。因为每一次 LLM 调用都变得更重,带着更多 token。token 越多,延迟越高,价格也越贵。所以,虽然 ReAct 架构是基础性的、强大的,但它并不适合处理复杂、长时程任务。
当然,shallow agents 对于只需要少数几轮迭代的任务,仍然非常有效。很多生产系统都在成功使用这一架构。在大量真实世界场景里,这种模式已经够用了,并不一定需要更复杂的东西。
Deep Agents
回到这张分类图,我们现在从 shallow agents 继续往下,来到 Deep Agents。
Deep Agents 是被设计来处理 long-horizon tasks 的。这类任务通常复杂、需要很多轮迭代,并且伴随大量推理与处理。Deep Agents 是长时间运行的系统。它们可能会运行数分钟、数小时,甚至数天。它们可以暂停执行、请求用户输入,然后在拿到输入后继续恢复执行。
深度研究 agent 就是一个常见例子。像 Perplexity 这类系统提供 deep research 功能时,本质上就是触发了一次 deep agent 运行。现在很多厂商都在提供类似的研究能力。Claude Code 有 research 选项。ChatGPT 也有 research 选项。每一种背后都对应某种 deep agent 实现,只不过不同厂商的内部设计并不相同。
也有开源 deep research agent。GPT Researcher(https://github.com/assafelovic/gpt-researcher)就是这一类里最流行的开源项目之一。我自己还围绕它做过课程,课程在这里:
https://www.udemy.com/course/langchain/?srsltid=AfmBOopb6uyyf5oNvX1gvDus-Nqdln5B-bwZtJAW1NLsv7z7ggPJLX9A
编码 Agent 作为 Deep Agents
Deep Agents 的另一个重要子集,就是 coding agents。例如 Claude Code、Devin、Cursor、Gemini CLI,都属于这里。编码 agent 是 Deep Agents 最有说服力的案例之一,因为它们已经在行业里被广泛采用,并被数百万开发者使用。
正如你已经看到的,这本书主要围绕 Claude Code 展开。写作本书时,Claude Code 是最受欢迎的编码 agent 之一。Claude Code 能力非常强,足以处理大量需要“深度”与“规模”的长时间任务。
我们可以要求这样的 agent 去实现一个应用或某个功能。它不只是生成代码而已。它还能:
- 跑测试
- 执行应用
- 打开浏览器
- 截图
- 做很多软件工程师原本要手工完成的事情
因此,coding agents 实际上是 Deep Agents 的一个专门化子集,专门为软件开发工作流量身定制。
应用层的创新
目前,这个领域的大部分创新,实际上都发生在 Deep Agents 身上。
LLM 本体仍然在持续进步,但这种进步是渐进式的:推理质量提高了,能力在扩展了,但总体上是增量改进,而不是指数式跃迁。
与此同时,构建在 LLM 之上的应用层进展却非常快。通过在 agent 之上继续叠抽象,并把 agent 编排成系统,我们就能构建出能力极强的机器,去自动化复杂的人类推理任务。这一应用层通常被称作 Agent Harness。
一个 Agent Harness,就是一个可直接使用的 AI agent 构建环境。它位于运行 agent 的工具与系统之上,预先帮你配好了各种东西:默认 prompt、工具处理、planning、文件访问等等。框架提供的是原始积木;runtime 管理的是执行过程;而 harness 则帮你把大量脏活累活都做好,让你不用从零开始搭环境。
五年前,如果有人说:一个 AI 系统能够从零开始生成一个功能完整、而且视觉上也挺像样的应用,而且几乎不需要人工介入,这听起来会非常不现实。但今天,这已经变成现实了。
而真正的驱动力,不只是底层模型进步了,更在于:我们作为开发者,是如何去 harness 它们的(harness engineering) 。创新,正在发生在应用层,发生在我们如何实现和编排 Deep Agents 上。
什么让一个 Agent 成为 Deep 的?
其实并没有一个严格、形式化的定义,规定什么叫 deep agent。
在实践中,我会认为:如果一个 agent 能够以足够高的质量和可靠性,执行复杂、长时间运行的任务,那它就算 deep。
为了做到这一点,Deep Agents 必须拥有一些能力,用来解决上下文膨胀与累积的问题。核心挑战会变成:上下文工程与智能上下文管理。没有这些能力,长时程执行迟早会崩掉。
绝大多数 Deep Agents 都会实现几个共同思想:
- 规划工具(planning tool) :agent 会先计划自己要做什么,再开始执行
- sub-agent 能力:系统会 spawn 出一些在隔离上下文中运行的专门化 worker。这样就能并发执行,而不会把单一共享上下文撑爆
- 用于中间状态的文件系统:中间结果和共享状态会被写到磁盘,而不是全塞进 LLM 上下文里。这样可以避免上下文失控增长
- 一个大型 system prompt:Deep Agents 通常依赖一个很完整的 system prompt,其中编码了指令、约束与操作指导
如果我们去看现代 deep agent 的各种实现,通常都会在某种形式上看到这四个思想。接下来,我们就逐个展开它们,并看一些具体实现。
图 11.5 —— Deep agent 架构的核心组成部分。改编自 LangChain Blog《Deep Agents》:https://blog.langchain.com/deep-agents/
Deep Agents 中的 Planning Tool
虽然 “Deep Agents” 只是一个总称,但 LangChain 团队在分析多个 deep agent 实现之后,把这个概念讲得很清楚:每一个 deep agent 都包含一个 planning tool。
当我们运行这个工具时,通常会看到一个任务列表:有些任务已经完成,有一个可能正在进行,还有一些还在队列里等待执行。这里看到的并不是模型内部通过 chain-of-thought 隐式完成的 planning;相反,Deep Agents 依赖的是显式规划工具。
这种规划机制通常会被实现成一个 Markdown 格式的 to-do list。agent 会在执行步骤之间不断回头检查并更新这个计划。计划不是静态的,而是动态变化的:任务会被标记为 pending、in progress 或 completed。如果一个任务失败了,agent 不会像原始 ReAct 循环那样盲目重试,而是会借助 planning tool 更有控制地修正执行方向。
这个 plan 会被持续更新,用户甚至也可以影响任务列表。在 Claude Code 中,planning tool 本身是内部实现,我们没法直接看到它的具体代码。但在实践里,我们能看到 TodoWrite 和 TodoRead 这样的动作被触发。TodoWrite 用来创建和更新 to-do list,它接收一个 { todos: Todo[] } 参数;TodoRead 用来读取当前列表。这些调用会更新任务清单,从而反映执行计划的变化。虽然内部推理过程不可见,但类似 TodoWrite 和 TodoRead 这样的动作,已经足以帮助我们理解:agent 是如何在做任务时动态调整计划的。
这个 deep agent 会不断更新这份 to-do list,这会显著提升可靠性,并增加复杂任务最终被正确完成的概率。从概念上讲,这其实非常符合直觉:当人类处理复杂工作时,也会先拆成小任务,并随着时间追踪进度。planning tool 就是在 agent 架构里,把这种模式正式化了。
Subagents 与层级式委派
前面我们讨论了 planning tool,也就是 to-do list 工具。Deep Agents 的另一个决定性特征,就是 subagent 能力。
Deep Agents 会使用 subagents 来实现层级式委派(hierarchical delegation) 。主 agent 可以 spawn 出自己的新实例,但这些实例会被专门化,用来处理聚焦任务。每个 subagent 都有自己的 system prompt、自己的 description,以及自己的一组工具,如下图所示:
图 11.6 —— 通过 subagents 实现的层级式委派
这种设计其实和现实世界里的委派很像。你把一项工作委托出去时,仅仅把任务派给别人还不够;被委托的人必须有正确技能,也必须有正确工具。与此同时,你还得把需求说清楚。
举个现实例子。假设某个任务需要特定工艺技能,例如修复房屋里的某个结构性问题。如果自己没有对应能力,就必须把任务委派给一个真正有合适技能和工具的人。那个人会带着自己的设备来,独立完成工作,然后把最终结果交回来。至于中间每一步具体是怎么干的,对原始委托方来说其实并不重要,重要的是最后结果。
这个类比非常适合理解 subagent。主 agent 通过一个清晰 description 去委派任务。subagent 带着自己的工具和内部指令独立执行工作,然后返回结果。在执行过程中,subagent 是在隔离环境中运行的。主 agent 并不会看到它每一步中间推理,它只会拿到最终输出。
从系统层面看,这意味着:subagents 运行在各自独立的 context window 中。它们不会污染主 agent 的上下文。每个 subagent 还可以有不同的 system prompt、不同的工具集合,以匹配自己的专长方向。这既带来了扩展性,也通过把职责分配给更聚焦的 agent,提高了结果质量。
从内部实现看,subagent 自己也会跑一套工具调用循环,包括它自己的 ReAct 风格循环。执行结束之后,它只把最终响应返回,而不会把所有中间 observation 都带回主线程。这个 delegation pattern 带来了上下文隔离,避免了专门任务把主 agent 上下文撑大,同时还支持任务并发执行。因此,效率和深度都会提升。
在实践中,我们已经能在 Claude Code 这类系统中看到这种模式。看下面这个例子:
图 11.7 —— Claude Code spawn 出一个 subagent,用来探索认证模式
在这个例子里,Claude Code 启动了一个 exploration agent,用来搜索认证模式。这个 exploration agent 会并发运行,独立执行自己的搜索,而主 agent 则继续自己的执行流程。这就展示了系统内建的 subagent 支持,以及层级式委派机制。
到这里为止,我们讨论的重点仍然是概念和架构逻辑,而不是具体实现细节。这里的目的,是先把概念结构讲清楚,并把这些能力与我们平时工作流中使用到的工具联系起来。
这也直接承接了我们在第 7 章中的讨论:subagents 如何防止上下文膨胀、如何实现上下文隔离,以及为什么它们最终能带来更好的结果。
Deep Agents 中的 Filesystem Access
Deep Agents 的另一个关键特征,是拥有文件系统访问能力。Deep Agents 会配备一整套工具,用于查找文件、读取文件、更新文件、删除文件,以及整体上掌控一个文件系统。这项能力在管理长时程任务中的上下文时,起着核心作用。
在 Claude Code 中,这体现为一组文件操作工具。
图 11.8 —— Claude Code 中 agent 可用的文件操作工具
正如你所看到的,这里有:
Read工具:读取文件内容Write工具:创建文件或覆盖文件Edit工具:做精确字符串替换
除此之外,Claude Code 还提供:
Glob:按模式查找文件Grep:在文件内容中搜索
如果再去看 LangChain 的 Deep Agents 文档,也能看到类似接口:ls、read_file、write_file、edit_file、glob、grep。也就是说,Deep Agents 暴露的是一套接口,而不是某种固定实现。这意味着底层存储方式是可变的。比如,这个文件系统可以建立在 Google Cloud 的 Firestore 上,也可以建立在 AWS 的 DynamoDB 上。接口不变,实现可以灵活替换。
为什么文件系统对长时程任务如此重要
前面已经讲过,随着对话越来越长,context window 也会越来越大。这会带来一系列问题,最终形成 context rot。而 context rot 会导致 LLM 输出质量下降。这种退化可能来自上下文冲突、上下文混淆,或者 prompt 中噪声过多。
LangChain 的一篇博客里有一张图,把 agent 的上下文工程问题讲得非常到位。这里展示的图,正是受那篇文章启发而来。
图 11.9 —— 可用上下文 vs 被选中的上下文 vs 实际所需信息。来源:LangChain Blog《How agents can use filesystems for context engineering》:https://blog.langchain.com/how-agents-can-use-filesystems-for-context-engineering/
可以想象:
- 一个很大的蓝色矩形(Box 1),表示所有可用上下文:代码库、文档、网页搜索结果、文件、数据库等等。这个空间往往很大,而且混乱。
- 在它里面,还有一个 Box 2,表示 agent 为当前某一步任务,从中选出来并拉进 context window 的那部分信息。也就是 agent 决定去读、去查找的东西。
- 最后,还有一个 Box 3,表示 agent 真正需要来完成任务的信息。
只要红圈和绿圈没对齐,就会出现各种失败模式:
- Under-retrieval:agent 只取回了 Box 2 中的一部分,遗漏了真正必要的信息
- Over-retrieval:Box 2 太大,把大量噪声一起带进来,信号被稀释
- Misaligned retrieval:agent 在错误地方搜索,导致 Box 1 和 Box 2 基本不重叠
- Context window limits:紫色框本身是有限的,不可能把所有东西都装进去;一旦太大,性能就会下降
上下文工程的目标,就是让红圈尽可能小,同时又能完整覆盖绿圈。这个选择过程几乎会在 agent 的每一个迭代步骤里发生:每一步都在优化“应该把什么装进上下文窗口”。
所以,对 agent 来说,信息是如何被组织、如何被检索、如何被排序的,往往比 prompt 本身更重要。agent 的质量,直接取决于:真正正确的信息有没有进入 context window。哪怕模型本身推理能力再强,如果上下文不对或不完整,它仍然会得出错误结果,甚至根本无法完成任务。
文件系统作为 Context Engine
这也正是为什么 deep agent 的文件系统会变得如此关键。文件系统本身,就是那个帮助 agent 抵达“正确上下文”的引擎。
从概念上看,整个文件系统就对应前面那个“可用信息”的蓝色大矩形:
第一,文件系统允许 agent 把上下文写入持久化存储。临时结果、中间输出、检索到的信息,都可以先写进文件,而不是直接把它们塞满 context window。
第二,文件系统还提供了选择相关上下文的机制。像 glob 这样的工具,可以按模式找到文件;而 grep 可以用正则搜索文件内容。这些工具能让 agent 精确拿到下一步真正需要的信息。
所以,文件系统实际上实现了上下文工程中的两条核心原则(见第 1 章):
- 把上下文写入持久化存储
- 按需检索相关上下文
它正是支撑这两件事的机制,也是 Deep Agents 能够在长时程任务中避免 context bloat 的基础。
System Prompt
在 AI 工程里,说一句“system prompt 很重要”,几乎已经成了老生常谈。但只要你真的去看行业头部团队的做法,就会发现:这一部分的重要性其实远远超出直觉。我们已经看到了很多 system prompt,本身就长达数百行,而且里面还注入了大量工具说明。
各家公司都投入了巨大工程资源,不断迭代地整理、优化和更新这些 prompt,以跟上 LLM 自身的演化。对于一个 deep agent 来说,system prompt 就是它推理方式、身份认知和边界的基础架构。
一个高质量 system prompt,会尽可能利用当前最先进 LLM 最擅长的事情:模式识别,以及把一般规则应用到具体、全新情境中。一个精心设计的 system prompt 通常会做到下面这些事:
- 建立清晰的身份与边界:通过明确说明 agent 是什么(例如“处理基础订单问题的客服”)和不是什么(例如“不是销售也不是市场”),prompt 会立即确立工作边界
- 赋能,而不是束缚:它不会硬编码“什么时候必须调用哪个工具”,而是定义一个目标(例如“高效解决问题”),让 agent 自主选择合适工具
- 提供的是推理框架,而不是流程图:它不靠刚性的 If/Then 分支逻辑,而是提供一套可以反复适用的方法论(例如:1. 识别核心问题,2. 收集上下文,3. 给出解决方案,4. 确认满意度)。这等于是在教模型“如何处理问题”,从而让它在面对全新场景时仍然能工作
- 使用启发式边界:它依赖被压缩过的原则,而不是穷举式清单。例如,要求模型“始终选择最简单的方案”,这就像一个贪心算法启发式,可以在数千种边界情况中提供行为导向,同时不浪费 token 空间
- 保持语言效率:好的 prompt 不会浪费字词,不会堆重复和相互重叠的指令,因为那样只会让 LLM 困惑,甚至导致矛盾行为
下面这段,就是 LangChain Deep Agents 自带的 system prompt。它可以在官方仓库中找到:
https://github.com/langchain-ai/deepagents/blob/main/libs/deepagents/deepagents/base_prompt.md
该仓库采用 MIT License。
You are a Deep Agent, an AI assistant that helps users accomplish tasks using tools. You respond with text and tool calls. The user can see your responses and tool outputs in real time.
## Core Behavior
- Be concise and direct. Don't over-explain unless asked.
- NEVER add unnecessary preamble ("Sure!", "Great question!", "I'll now...").
- Don't say "I'll now do X" — just do it.
- If the request is ambiguous, ask questions before acting.
- If asked how to approach something, explain first, then act.
## Professional Objectivity
- Prioritize accuracy over validating the user's beliefs
- Disagree respectfully when the user is incorrect
- Avoid unnecessary superlatives, praise, or emotional validation
## Following Conventions
- Read files before editing — understand existing content before making changes
- Mimic existing style, naming conventions, and patterns
## Doing Tasks
When the user asks you to do something:
1. **Understand first** — read relevant files, check existing patterns. Quick but thorough — gather enough evidence to start, then iterate.
2. **Act** — implement the solution. Work quickly but accurately.
3. **Verify** — check your work against what was asked, not against your own output. Your first attempt is rarely correct — iterate.
Keep working until the task is fully complete. Don't stop partway and explain what you would do — just do it. Only yield back to the user when the task is done or you're genuinely blocked.
**When things go wrong:**
- If something fails repeatedly, stop and analyze *why* — don't keep retrying the same approach.
- If you're blocked, tell the user what's wrong and ask for guidance.
## Tool Usage
- Use specialized tools over shell equivalents when available (e.g., `read_file` over `cat`, `edit_file` over `sed`)
- When performing multiple independent operations, make all tool calls in a single response — don't make sequential calls when parallel is possible.
## File Reading Best Practices
When reading multiple files or exploring large files, use pagination to prevent context overflow.
- Start with `read_file(path, limit=100)` to scan structure
- Read targeted sections with offset/limit
- Only read full files when necessary for editing
## Progress Updates
For longer tasks, provide brief progress updates at reasonable intervals — a concise sentence recapping what you've done and what's next.
你可以看到,system prompt 本身就是认知基线。
如果你过于具体地去硬编码,它会破坏模型的推理能力;如果你又太模糊,就会导致混乱和不一致。
总结
在本章中,我们先建立了一套生产环境中的 agent 分类框架,指出了 shallow agents 在面对 context bloat 和长时程工作流时的局限,然后定义了什么让一个 agent 成为“deep”。接着,我们分析了支撑 deep execution 的几个核心构件:
- 通过动态 to-do list 实现的显式 planning
- 通过专门化 subagent 和隔离上下文实现的层级式委派
- 通过文件系统实现的持久状态管理与精准上下文选择
同时,我们也把这些构件与 Claude Code 和 LangChain DeepAgents harness 这样的真实系统联系起来,把讨论落到了具体实现上。