Claude Code Subagent 是什么?从零搞懂这个核心概念
- 一个让我困惑了很久的问题
- Claude Code 里的「Agent」其实有 4 种含义
- Subagent 为什么存在?
- 构建第一个 Subagent
- Subagent vs Skill:最容易被混淆的边界
- 最佳实践
- Agent Teams:更上一层
- 什么时候不该用 Subagent
- 值得关注的细节
一个让我困惑了很久的问题
第一次看到 Claude Code 启动 subagent 时,我的第一反应是:这不就是跑了个更精准的 Prompt 吗?
看着它在十几个文件里穿梭,最后返回一份干净的摘要,很酷,但我其实没搞懂到底发生了什么。后来我发现很多人都有类似的困惑——他们把 subagent 理解成「带额外步骤的 Skill」,甚至是「写得更聪明的 Prompt」。
这个认知模型是错的。
Agent 确实和 Skill 一样用 Prompt 驱动,但关键区别在于:Agent 不在你的主会话里运行。 它有自己的上下文窗口、自己的系统 Prompt、自己的工具权限、自己的运行环境。它独立工作,然后返回结果。
这篇文章从零开始讲清楚 Claude Code subagent——它到底是什么、怎么构建、什么时候该用、什么时候不该用。
Claude Code 里的「Agent」其实有 4 种含义
在深入之前,必须先理清概念。Claude Code 语境下,「Agent」这个词至少指 4 种不同的东西:
1. Claude Code 本身就是一个 Agentic 环境。 Anthropic 把 Claude Code 定义为 agentic coding assistant——有工具、有执行循环、能跨多步自主规划和操作。你在用它的时候,就已经身处一个 Agent 环境了。
2. Subagent 是可自定义的 Agent 原语。 当从业者说「我在 Claude Code 里构建了一个 Agent」时,几乎都是在指 subagent。它有专属的上下文窗口、自定义系统 Prompt、独立工具权限。
3. Agent Teams 是独立的多会话特性。 Subagent 在单个会话内工作;Agent teams 跨多个会话协调。它们是独立的 Claude Code 实例,通过共享任务列表和消息通信。目前处于实验阶段,默认关闭。
4. Claude Agent SDK 是第四层。 是 Claude Code 底层工具循环的 Python/TypeScript 可编程接口,用于构建自定义 Agent 应用。
本文聚焦的是 subagent(第 2 点)。
Subagent 为什么存在?
核心原因只有一个:LLM 的上下文窗口是有限的。
每一个工具调用、每一次文件读取、每一次分析和中间结果——全都会落在上下文窗口里。随着会话增长,窗口里塞满了中间产物。这些产物在生成结果时需要,但生成完成后就成了噪声。这种噪声会降低模型性能——这就是所谓的 Context Rot(上下文腐烂)。
Subagent 就是为了解决这个问题而存在的。
一个 subagent 在自己的上下文窗口里运行,消耗自己的 Token 预算。主会话只收到一份摘要。官方文档说得很直白:
Subagent 可能读取几十个文件或运行大量搜索,但你的主会话只收到一份摘要。因为 subagent 的工作不消耗主会话上下文。
举个例子:你要排查测试套件为什么挂了。在主会话里做这个排查意味着要读 20 个文件、grep 错误模式、检查测试配置、扫描最近的提交——所有这些都会塞进你的上下文窗口。等排查完了,你已经消耗了成千上万 Token,而且大部分中间信息对你接下来的工作毫无帮助。
Subagent 改变了这个问题的结构。它在自己的上下文里跑完整个排查流程,返回一条干净的结果:「测试失败原因是 CI 配置中缺少环境变量。受影响的 3 个测试和修复方案如下。」主线程从未被搜索上下文撑爆。
上下文隔离是首要原因,还有三个次级原因:
- 专业化:Subagent 有自己的系统 Prompt。一个专注于代码评审的 Agent,配以团队标准指令,比一个什么都知道的通用助手更可靠。
- 约束执行:你可以精确指定 subagent 能用的工具。一个只读的研究 Agent 不能写文件、不能跑命令——风险轮廓和主助手完全不同。
- 成本控制:Subagent 可以使用不同的模型。把轻量任务路由到 Haiku 而主会话用 Sonnet,是很多人在被账单吓到之后才会发现的实用技巧。
构建第一个 Subagent
一个 subagent 就是一个带 YAML frontmatter 的 Markdown 文件。
它存放在两个位置之一:
.claude/agents/(项目目录)—— 团队可共享的 Agent~/.claude/agents/(用户目录)—— 个人跨项目 Agent
最小示例
---
name: code-reviewer
description: Re一次代码变更的质量、安全和最佳实践。在重大代码变更后主动使用。
tools: Read, Glob, Grep
model: sonnet
---
You are a code reviewer. When invoked, read the changed files and provide
specific, actionable feedback on code quality, security, and best practices.
Focus on what matters. Don't restate what the code does — say what's wrong
or good about it. Flag security issues first, then logic problems, then style.
字段说明
- name:唯一标识符,小写,只能连字符。用于日志和内部引用。
- description:最重要的字段。 Claude 依据它来决定是否把任务委派给这个 Agent。用行为式语言描述——Agent 做什么、什么时候用。
Use proactively是一个关键信号——告诉 Claude 无需用户明确请求即可主动激活。不加这个短语的话,Agent 只在被直接调用时响应。 - tools:限制该 Agent 能访问的工具。上面的评审者只能读取文件和搜索——不能编辑、不能跑命令、不能发网络请求。这是有意的设计。只读评审者不会意外修改它正在审查的代码。
- model:将 Agent 路由到特定模型。可选值:
sonnet、opus、haiku,或完整模型 ID。省略则默认inherit(继承主会话模型)。
完整的可选前置字段还包括:permissionMode、maxTurns、skills、mcpServers、effort、memory、hooks、disallowedTools、color 等。
Subagent vs Skill:最容易被混淆的边界
如果你觉得上面的 subagent 看起来很像一个 Skill——你既对也不对。
相同点: 都是用 YAML frontmatter + Markdown body 定义的文件,都可以指定 tools 和模型。
核心区别:
| 维度 | Skill | Subagent |
|---|---|---|
| 运行位置 | 主会话上下文 | 独立上下文窗口 |
| 上下文消耗 | 占用主会话 Token | 不占用主会话 Token |
| 工具权限 | 继承主会话 | 独立声明和限制 |
| 返回结果 | 直接注入对话流 | 返回摘要到主会话 |
| 系统 Prompt | 与主 Prompt 融合 | 完全隔离的独立 Prompt |
| 适用场景 | 格式塔式的简单任务 | 需要大量文件交互的复杂任务 |
一个实用的判断标准:如果任务需要读 5 个以上文件、做多步搜索、或者需要完全隔离的上下文——用 subagent。如果只是格式转换、模板生成、单文件分析——用 Skill。
最佳实践
Description 怎么写?
这是最容易被低估的字段。好的 description 应该是行为式的,像这样:
Reviews PR diffs before merge. Calling this means the caller
wants a thorough review with security-first analysis.
Use proactively after any significant code change.
而不是描述式的:
A code review tool.
Claude 会读取 description 来决定是否把任务委派给这个 Agent。写得越清晰、越行为化,它在正确时刻被调用的概率就越高。
工具限制为什么重要
只授予 Agent 实际需要的工具,有两个原因:
- 安全性:一个只读 Agent 不能意外破坏代码
- 可预测性:工具越少,行为越可控
代码评审 Agent 只需要 Read, Glob, Grep;数据库迁移 Agent 可能需要 Write, Bash, Read;研究 Agent 可能需要 Read, Glob, Grep, Search。
Context 隔离
Subagent 的最佳使用模式是:把大量文件读取和搜索操作塞进 subagent,主会话只处理结果。
看一个实际的例子。用 subagent 做端到端测试分析:
The subagent reads 15-20 test files, checks CI logs,
grep for error patterns. Returns a 3-paragraph summary.
Main session: uses the summary to decide next steps.
主会话从未接触那 20 个文件的上下文负担。这是 subagent 最核心的价值。
Agent Teams:更上一层
Subagent 在单会话内工作。当任务需要跨多个文件、跨多个步骤、甚至跨多个代码库时,Agent Teams 可能更合适。
Agent Teams 是独立的 Claude Code 实例,它们通过共享任务列表和消息相互通信。当前处于实验阶段(通过 ANTHROPIC_AGENT_TEAMS=1 环境变量启用),但已经可以看到它的价值所在。
什么时候该用 Agent Teams?你的任务需要多个专业角色并行工作时——比如一个 Agent 在重构后端,另一个在更新前端类型,第三个在写文档。它们各自运行在自己的会话中,共享一个任务蓝图,相互通知进度。
什么时候不该用 Subagent
Subagent 不是万能的。以下场景请谨慎:
任务太简单。 如果只需要单文件分析或格式转换,一个 Skill 就够了。引入 subagent 的上下文切换开销不划算。
需要实时交互。 Subagent 独立运行,你无法在它执行过程中插手。如果任务需要反复确认方向,留在主会话更合适。
对延迟敏感。 Subagent 启动有固定开销(加载上下文、初始化工具)。毫秒级响应的场景不适合。
频率极高的重复任务。 如果每 30 秒就要跑一次的监控检查,subagent 的上下文创建成本会累积。
值得关注的细节
最让我认同的一个判断是:Subagent 不是「更聪明的 Skill」,而是一种架构模式——上下文隔离。 理解了这个本质区别,很多决策就变得清晰了。
不过我也注意到一个被弱化的问题:Subagent 的调试比主会话更困难。 它在自己的黑箱里运行,你无法看到它的中间推理过程。如果返回的结果质量不符合预期,排查原因比在主会话中要费劲得多。
另一个容易被忽略的点:Description 字段的战术价值。 很多人把它当作可有可无的副注,实际上它是决定你 Agent 被 Claude 主动发现和调用的关键入口。写得好,你的 Agent 会在恰当时刻被自动激活;写得差,再强大的逻辑也无人问津。
目前我的建议是:从代码评审 Agent 开始入手体验——限制工具为只读,提供明确的评审标准,观察它如何独立分析代码变更。这是理解 subagent 最佳实践的最短路径。