详解 Claude Code 三种扩展点(Skill/Subagent/Tool)的区别,Subagent 适用于并行、隔离、长时间运行的任务,可节省主会话上下文预算。
大多数 Claude Code 会话变得缓慢和杂乱,原因都是一样的:每一次探索性的 grep、每一次日志转储、每一次「让我再看一个文件」,都会永远留在主对话里。
Subagent 正是为解决这个问题而生的。它是 Claude Code 内置的 agent 原语之一,用于处理嘈杂的、可并行的工作——一种把混乱推入隔离窗口、只带回来关键摘要的方式。
Subagent 不是更聪明的 Claude,也和 Skill 不是一回事。它是一个独立的推理 agent,有自己的上下文窗口、自己的工具许可列表,除非你显式 fork,否则不会记住当前对话。理解这个区别,就是区分「安静地帮你节省上下文配额」和「徒增延迟毫无收益」两种 subagent 设置的关键。
Claude Code 给了你三个扩展点来解决不同的问题,但它们经常被混为一谈,因为三种方式在技术上都能「帮助完成任务」。
一个有用的经验法则:hook 用来强制执行硬性约束,Skill 用来给主 agent 增添内联能力,而 subagent 则用于你希望委托出去、完全不进入主上下文的工作。如果一个 Skill 的职责是编排一个还不存在的工具,这通常意味着你需要的是 MCP server,而不是 subagent。Claude Code 并非独有这种形态——OpenCode 的生态系统中也有类似的想法,即 specialized agents,它以类似的方式将规划、研究和审查分配给不同的专用角色。
三个属性定义了 Claude Code 的 subagent,三者都会影响你如何使用它:
隔离的上下文。 Subagent 从一个全新的窗口开始。它看不到你的对话历史,除非你显式 fork 它,这样就能避免它的输出被你在三个回合前讨论的内容污染。
受限的工具许可列表。 Subagent 只能使用父会话已有工具的子集——它们无法给自己授予新的能力,一个设计良好的 subagent 应该只获得其任务所需的工具(例如,只读工具给研究 agent)。
跨 subagent 不可见。 Subagent 无法看到彼此的进行中的工作。如果任务 B 确实需要任务 A 的输出,那是顺序依赖关系,不是你能用两个 subagent 并行化的东西。
启用 subagent 的触发条件不是「这个任务很难」,而是「这个任务很嘈杂」——那种会产生大量中间输出的工作(如读取几十个文件、查看长日志、在整个仓库做探索性 grep),这些中间材料都不需要保留到下一个对话回合。
适合的场景: 大改动之前的代码库探索、自动化测试运行(你只关心通过/失败和失败摘要)、安全或风格审查,以及任何多步骤研究任务——否则其原始输出会淹没你的主会话。
不适合的场景: 两秒钟的查询(「这个函数返回什么」)、任何需要紧密来回迭代的工作,以及你 tempting 去「并行化」但第二个任务需要第一个任务结果的依赖任务。用 subagent 处理一个trivial的查询只会带来启动全新上下文窗口的开销,没有任何实际的隔离收益。
subagent 的价值主张在量化之前是抽象的。以一个常见任务为例:在约 500 个文件的服务中 grep 出所有仍在读取已废弃配置键的地方,然后报告精确的 file:line 匹配。
对于那个步骤,你的主会话需要携带的内容大约减少了 15-20 倍——这就是「subagent 保持会话快速」的实际机制——不是魔法,而是上下文压根就不会被加载。
成本方面同样如此复利。使用 Claude Code 定价明细中的价格,在 Opus($5/MTok 输入,$25/MTok 输出)上运行同样的探索步骤,仅 ~40K 输入 token 的成本大约是 $0.20-0.25。路由到 Haiku($1/MTok 输入,$5/MTok 输出)将其降至 $0.04-0.05——而且主会话的 Opus 预算从未被探索 token 触及,因为它只看到 ~2K token 的摘要。
自定义 subagent 作为带 YAML frontmatter 的 Markdown 文件存在,可以是项目级的(放在 .claude/agents/,提交到仓库,全队共享)或用户级的(放在 ~/.claude/agents/,个人工具,随项目携带)。
---
name: code-reviewer
description: >
Reviews staged changes for bugs, security issues, and style violations
before commit. Use when the user asks to review, audit, or check
changes prior to committing or opening a PR.
tools: Read, Grep, Glob
model: sonnet
skills:
- security-checklist
---
You are a careful code reviewer. Read the staged diff, flag concrete
issues with file:line references, and end with a short pass/fail summary.
Do not modify any files.
description 字段是文件中最重要的一行。它是父会话的路由逻辑用来决定这个 subagent 是否适合当前任务的关键。写它的时候要像写职位描述一样——明确命名触发条件,而不是模糊的「帮助处理代码」。模糊的描述会被自动路由跳过或误用。
tools 字段是你的隔离边界。给一个研究 subagent 提供 Read、Grep 和 Glob,除此之外什么都不要;给它所有可用的工具会破坏在受限沙箱中运行它的整个目的。可选的 skills 字段会将命名 Skill 的完整内容预加载到 subagent 的启动上下文中——当 subagent 需要领域知识但不想在任务中途花一个回合去发现和加载它时,这很有用。
Subagent 也是成本控制变得真实的地方。将文件发现、日志扫描和其他廉价验证工作路由到 Haiku,把 Sonnet 或 Opus 留给推理密集型的步骤——架构决策、模糊的调试、任何出错代价高昂的事情。Haiku 每个 token 比 Opus 便宜约 15 倍,而在 subagent 所针对的那种嘈杂探索中,这个差距在真实工作会话中会快速累积。
对于复杂的、多步骤的工作,实践中行之有效的模式是 Explore、Plan、Execute——用廉价的 subagent 来处理产生噪音的部分,并把人工审核门禁放在真正需要它的唯一地方。
participant You
participant Main as Main session
participant Explore as Explore subagent (Haiku)
participant Execute as Execute agent (Sonnet/Opus)
You->>Main: Describe the task
Main->>Explore: Delegate codebase exploration
Explore-->>Main: Return summarized findings
Main->>Main: Enter Plan mode, propose approach
Main->>You: Show plan for review
You->>Main: Approve or adjust
Main->>Execute: Hand off approved plan
Execute-->>Main: Apply changes, run tests
Main-->>You: Report results
人们经常搞反的关键细节是审核门禁应该放在哪里。探索是廉价的,所以让 subagent 自由读取,不需要先请求许可。规划是分析性的,所以让 agent 自行设计方法。但在任何 agent 修改文件之前,你希望看到计划并批准它——这就是 Claude Code 的 plan 模式(permissionMode: plan)的用途,这也与更广泛的 vibe coding 最佳实践原则一致:在任何 diff 落地之前都要审核。
一旦团队开始编写自定义 subagent,有几个错误会反复出现:
模糊的描述。「帮助处理代码」永远不会正确路由。要明确命名具体的触发条件。
工具访问过于宽泛。 给只读研究 subagent 提供 write 和 bash 访问权限,会移除最初创建它的隔离保证。
并行化依赖任务。 如果任务 B 需要任务 A 的完成输出,顺序运行它们——subagent 无法像共享编排器那样在任务中途相互协调。对于真正需要在任务中途让 agent 相互对话的工作流程,那是不同形态的问题;如果你在构建生产系统而不是单仓库工作流,请参阅 multi-agent orchestration patterns。
用 subagent 处理 trivial 工作。「格式化这个 JSON」或「运行这一个命令」不需要全新的上下文窗口;直接做就行。
假设你希望每个 nontrivial 的 commit 在落地之前都经过审查。把前面展示的 code-reviewer 定义放入 .claude/agents/code-reviewer.md,提交它让全队共享同一个审查者,然后用自然语言调用,比如「review my staged changes before I commit」。Claude Code 将你的请求与 subagent 的 description 匹配,用只有 Read、Grep 和 Glob 的权限启动它,它会回来带着 file:line 引用的发现和 pass/fail 摘要——到达结论过程中产生的文件级噪音绝对不会触及你的主会话。
在主 transcript 中标注后的样子是这样的:
You: review my staged changes before I commit
Main: [dispatches code-reviewer subagent — 6 files read, 1 grep pass,
zero of it shown here]
Main: code-reviewer findings:
- auth/session.go:142 — token refresh path doesn't handle expired
refresh token; falls through to nil dereference
- auth/session.go:203 — style: error wrapped without %w
PASS/FAIL: FAIL (1 blocking issue)
六次文件读取和一次 grep 通过发生了,而你主会话实际为之付出的代价只有四行。那个差距——subagent 所做的一切对比你实际看到的三行摘要——就是这个机制在一份 transcript 中的全部价值主张。
如果你的团队也使用 Spec-Driven Development 脚手架,审查 subagent 可以自然地嵌入验证步骤;请参阅 GitHub Spec Kit vs Kiro vs Claude Code SDD Workflows 来了解该审查门禁在不同便携式和 IDE 集成 SDD 设置之间的比较。
不是第一天就要做。内置的通用 subagent 已经覆盖了大多数探索和研究委托工作,不需要你写一个 YAML 文件,单次 Explore-Plan-Execute 流程对大多数日常工作就够了。只有当你手工委托同一任务三次之后,才写一个自定义的 .claude/agents/*.md 文件——比如代码审查者、测试运行分诊员、特定内部库的文档查找 agent。第一周就写五个 subagent 的团队通常最终会有五个没人更新的过期 description 字段,这会在几个月后悄悄破坏自动路由。从零个自定义 subagent 开始,一次加一个,而且只有当重复——而非理论上的用处——需要它的时候才加。
无法递归委托。 Subagent 无法生成自己的 subagent。如果一个任务确实需要第二层委托,那意味着你需要不同的编排形态——请参阅 multi-agent orchestration patterns 了解在单个 Claude Code 会话之外这是什么样子。
跨调用无记忆。 每次派发都从零开始,即使五分钟前你在一个相关任务上调用了同一个 subagent。没有内置机制让 subagent 记住上一次运行。
隔离是工具许可列表,不是沙箱。 有 Bash 访问权限的 subagent 仍然可以像任何其他工具调用一样访问文件系统和网络。限制工具会减少爆炸半径;不会创建硬性安全边界。
Subagent 从不触发。 Description 几乎总是问题所在。围绕具体的触发条件重写它,而不是通用能力声明,并仔细检查文件是否在 .claude/agents/(项目级)或 ~/.claude/agents/(用户级)且扩展名正确。
Subagent 还是烧了太多上下文。 检查工具许可列表——过于宽泛的工具集会导致过于宽泛的探索。还要检查这个任务是否应该被拆成两个 subagent 而不是一个大包大揽。
列出的 Skill 没有在 subagent 内加载。 Claude Code 跳过缺失或已禁用的 Skill 而不是让运行失败,并在调试输出中记录一行(从主会话运行 /debug,然后重现该派发)——类似 skill "security-checklist" not found, skipping。之后运行 /doctor 确认其余设置健康。
结果在运行之间感觉不一致。 这通常是模型路由问题,不是 subagent 设计问题——分配给廉价模型的推理密集型工作会有更大差异。把它移到 Sonnet 或 Opus,把 Haiku 留给确定性、低歧义性的步骤。
Subagent 是一个更大工具箱中的一个组成部分;如果你在比较 Claude Code 与 AI 开发者工具生态系统中的其他工具然后再投入这个工作流,那个概述是一个很好的下一步。