本教程聚焦 Claude Code Agent 模式下最被低估的扩展能力——自定义子代理(Custom Subagents)。你将学会在 .claude/agents/ 目录下用一份 Markdown + YAML 文件定义一个"专家角色",给它裁剪工具权限、指定模型档位、撰写专职系统提示,然后让主代理在自动化任务中按需委派或并行调度。学完后,你能把一个臃肿的单线程任务拆成若干"上下文隔离、权限受限、各司其职"的子代理,让批量审查、多维度调研这类重活不再撑爆主对话窗口。适用人群:已跑通过 -p 模式或 Hooks、想进一步把 Agent 自动化做"专"做"稳"的开发者。
claude --version 有输出)Read / Edit / Bash / Grep / Glob 这几类内置工具的用途很多人把"子代理"和"再开一个 Claude 会话"混为一谈,于是觉得这功能可有可无。二者的本质差别在两点隔离:
第一是上下文隔离。 主代理跑长任务时,上下文里会堆积大量你再也不需要的东西——几十个文件的全文、一堆 grep 命中行、跑挂的日志。这些"垃圾上下文"不仅占地方,还会让模型被噪声带偏。子代理跑在独立的上下文窗口里,它读了一百个文件、执行了二十次搜索,这些过程全部留在它自己的窗口里,最终只把一段精炼的结论回传给主代理。主对话窗口因此保持干净。
第二是能力隔离。 一个子代理文件里可以写死 tools: Read, Grep, Glob——这意味着它只能看,不能改。哪怕它的系统提示词里写错了、哪怕它"想"帮你顺手改个 bug,工具层就把它拦住了。这是子代理最硬核的价值:用工具白名单实现最小权限,把"专业分工"从口头约定变成可执行的护栏。
flowchart LR
Main["主代理<br/>(主上下文窗口)"] --> |委派任务| Sub1["子代理A<br/>tools: Read,Grep<br/>model: opus"]
Main --> |并行委派| Sub2["子代理B<br/>tools: Bash<br/>model: haiku"]
Main --> |并行委派| Sub3["子代理C<br/>tools: Read,Glob<br/>model: sonnet"]
Sub1 --> |仅回传结论| Main
Sub2 --> |仅回传结论| Main
Sub3 --> |仅回传结论| Main
style Main fill:#2d6a4f,color:#fff
style Sub1 fill:#40916c,color:#fff
style Sub2 fill:#40916c,color:#fff
style Sub3 fill:#40916c,color:#fff
记住这张图,后面所有配置都围绕"如何定义子代理的边界"展开。
子代理就是放在约定目录下的一个 .md 文件,没有魔法。目录有两个层级:
<仓库>/.claude/agents/*.md——只对这个项目生效,适合放进 Git 让团队共享~/.claude/agents/*.md——对你所有项目生效,适合放个人常用角色(如通用代码评审员)先在项目根目录建一个最简单的子代理,命名为 complexity-scout(圈复杂度侦察兵):
mkdir -p .claude/agents
然后新建 .claude/agents/complexity-scout.md,内容如下:
---
name: complexity-scout
description: Use proactively to find overly complex functions (high cyclomatic complexity, deep nesting, long methods) in recently changed files. Triggers when the user asks to "check complexity", "find complex code", or after a large refactor.
tools: Read, Grep, Glob, Bash
model: sonnet
---
You are a code-complexity scout. You ONLY report problems; you never edit files.
For each function that looks too complex, report:
- file:line
- a one-line complexity smell (deep nesting / long method / too many branches)
- a concrete simplification suggestion
End with a short ranked list of the top 3 worst offenders. Be terse.
预期结果:保存后无需重启,Claude Code 在下一次对话中就能识别这个子代理。你可以验证它是否被加载——在对话里直接输入"用 complexity-scout 侦察 src/ 目录的复杂度",或更隐式地触发自动委派。
常见问题:
| 现象 | 原因 | 解决 |
|---|---|---|
| 子代理完全不触发 | description 太空泛或缺 "proactively" |
在 description 里写清"何时用"+"什么关键词触发" |
| 报错 "unknown tool" | tools 里写了不存在的工具名 |
工具名要精确匹配(Read 不是 read) |
| 不在预期项目生效 | 文件放错目录层级 | 项目级放 .claude/agents/,别放到子目录里 |
frontmatter 那几行 YAML 是子代理的灵魂。逐一拆开看:
name(必需)security-auditor,不是 Security Auditor)description(必需,触发命门)这是最重要也最容易被写废的字段。它不给人看,是给主代理看的"委派说明书"。三条写法铁律:
proactively / whenever / triggers when 这类词,让主代理知道在满足条件时主动委派,而不是等你点名反例(写了等于没写):
description: Code review agent. # ❌ 太空泛,永远不会被自动委派
正例:
description: Use proactively to review code changes for security vulnerabilities (injection, auth bypass, hardcoded secrets, unsafe deserialization). Triggers when security-sensitive paths (auth/, crypto/, payments/, user input handling) are modified or when the user mentions "security", "vulnerable", or "OWASP".
tools(可选,安全护栏)逗号分隔的工具白名单。省略时继承主代理的全部工具(等于没有护栏)。强烈建议显式写白名单,遵循最小权限:
tools: Read, Grep, Glob, Bashtools: Read, Edit, Write, Bashtools: WebSearch, WebFetch, Readflowchart TD
A["想给子代理 tools 字段"] --> B{任务要改文件吗?}
B --> |否,只分析| C["只读: Read,Grep,Glob,Bash"]
B --> |是,要修改| D["读写: Read,Edit,Write,Bash"]
C --> E["哪怕提示词写错也无法误删代码"]
D --> F["务必配 description 精准触发,避免误伤"]
style C fill:#1b4332,color:#fff
style E fill:#1b4332,color:#fff
一个小技巧:把 Bash 留给确实需要跑命令(测试、grep 大文件)的代理;纯静态分析代理连 Bash 都可以不给,进一步收窄攻击面。
model(可选,成本与能力的旋钮)控制这个子代理用哪个模型档位。可选值随版本演进,常见为:
inherit(默认)——继承主会话的模型sonnet——性价比档,适合大多数分析、搜索类任务opus——强推理档,留给安全审计、架构决策这种需要深度判断的活haiku——快且便宜,适合"格式化输出、批量分类"这种机械活省钱心法:把贵的 opus 只用在少数高价值只读代理上(如 security-auditor),让大量机械活(如"把这 50 个文件按主题分类")跑 haiku。一个会话里多代理混搭,能在不牺牲关键质量的前提下显著压低 token 成本。
子代理被加载后有两种启动方式:
显式调用——你在对话里点名:
"用 complexity-scout 把 src/ 跑一遍"
"let the security-auditor review my last commit"
自动委派——主代理读到你 description 里的触发条件,自己决定委派。你只要正常说话,比如"我改了 auth/login.ts,帮我看看有没有问题",主代理就可能自动把活派给 security-auditor。
能否自动委派,完全取决于 description 写得好不好。这再次印证上一节的铁律:description 是子代理的"搜索引擎"和"路由表"。
在自动化(-p 模式 / Headless)场景里,这两种方式尤其关键:你的批处理脚本里没法人工点名,全靠 description 让主代理自动分派。所以面向自动化的子代理,description 必须写得像一份精确的路由规则。
主代理委派子代理时,默认是前台(同步阻塞):派一个、等结果、再继续。这对有先后依赖的任务是对的(reviewer 先发现问题,fixer 才有得修)。
但当几个子代理互不依赖时,前台一个个排队能把人急死。这时要让主代理并行委派(后台):
"用 security-auditor、perf-reviewer、complexity-scout 同时并行审查这次改动,分别给我三份报告。"
主代理会理解"同时并行"并把三个子代理一起派出去。它们的独立上下文窗口互不干扰,CPU/token 并发跑,墙钟时间约等于最慢的那个,而非三者之和。
判断该不该并行的唯一标准:任务之间有没有数据依赖。
子代理的结论会回传主代理,主代理可以再据此委派下一个子代理,形成流水线。典型组合是 只读 reviewer 发现问题 → 主代理汇总 → 读写 fixer 落地修复:
sequenceDiagram
participant U as 用户/批处理
participant M as 主代理
participant R as security-auditor<br/>(只读, opus)
participant F as security-fixer<br/>(读写, sonnet)
U->>M: 审查并修复 auth/ 的安全问题
M->>R: 委派: 审查 auth/ 全部漏洞
R-->>M: 回传: 3个高危清单(含file:line)
M->>F: 委派: 按清单逐项修复
F-->>M: 回传: 已改2处,1处需人工
M-->>U: 汇总报告 + 改动diff
这条链路把"找问题的人"和"改问题的人"用不同权限、不同模型彻底分开:
security-auditor:tools: Read, Grep, Glob, Bash,model: opus——只负责找,找不到就空手而归,永远碰不到 Editsecurity-fixer:tools: Read, Edit, Bash,model: sonnet——只负责改,且必须严格按 auditor 给的清单改这是子代理"能力隔离"在实战中的最高级用法:把信任分级。审计这一步用最贵最强的脑子但零修改权限;修复这一步放开写入但用便宜的脑子并限定范围。
不用从头造轮子。Claude Code 自带几个通用子代理,主代理会按需委派:
写自定义子代理时,先问自己:这个需求是不是 Explore/general-purpose 已经能干? 如果是,就没必要造。自定义子代理的真正价值在于:给特定领域配专职提示词 + 收窄工具 + 选合适模型——这三样内置通用代理给不了。
把前面所有概念串起来,构建一个可复用的"多维并行代码审查团队"。目标:每次大改动后,三个专家并行从不同维度审查,主代理汇总成一份报告。三个子代理全部只读,保证审查过程零副作用。
文件1:.claude/agents/security-auditor.md
---
name: security-auditor
description: Use proactively to review code changes for security vulnerabilities—injection, auth bypass, hardcoded secrets, unsafe deserialization, path traversal. Triggers when security-sensitive code (auth, crypto, file handling, user input) is touched or when the user says "security", "vulnerable", "OWASP".
tools: Read, Grep, Glob, Bash
model: opus
---
You are a senior application-security reviewer. You have READ-ONLY tools and must not modify anything.
For each finding output: severity (CRITICAL/HIGH/MED/LOW) | file:line | vulnerability type | one-line proof | concrete fix suggestion.
Sort by severity. If you find nothing, say "No security issues found." Do not pad.
文件2:.claude/agents/perf-reviewer.md
---
name: perf-reviewer
description: Use proactively to flag performance regressions—N+1 queries, unnecessary allocations in hot loops, missing indexes, sync I/O on critical paths, O(n²) where O(n) is possible. Triggers on "performance", "slow", "optimize", or after DB/loop-heavy changes.
tools: Read, Grep, Glob, Bash
model: sonnet
---
You are a performance engineer with read-only access. Hunt for the worst-case complexity and obvious bottlenecks.
For each finding: file:line | smell | expected impact | suggested optimization. Keep it blunt.
文件3:.claude/agents/test-coverage-checker.md
---
name: test-coverage-checker
description: Use proactively to verify that changed code has corresponding tests. Triggers after a feature is added, when the user says "are there tests for this", or when reviewing a PR.
tools: Read, Grep, Glob, Bash
model: sonnet
---
You are a test-coverage auditor. For each public function or handler changed in the diff, check whether a test exercises it.
Output a table: changed symbol | has test (Y/N) | test file:line if Y. End with a coverage percentage estimate.
编排这一步交给主代理(你只要在对话里这样说,或在 -p 批处理脚本里这样写):
对本次 git diff 涉及的改动,同时并行调用 security-auditor、perf-reviewer、
test-coverage-checker 三个子代理,各自独立审查。三份结果都回来后,
汇总成一份分级报告(按 CRITICAL→LOW 排序),并在末尾给出 top-3 必修项。
预期产出:
# 变更审查报告(三代理并行)
## 🔴 CRITICAL
- security-auditor: src/auth/login.ts:42 — SQL 注入风险(拼接用户输入)
## 🟡 HIGH
- perf-reviewer: src/api/feed.ts:88 — 循环内 N+1 查询,预计 100 条数据 +99 次 DB 往返
- test-coverage-checker: src/auth/login.ts — login() 改动无对应测试 ❌
## ✅ LOW
- perf-reviewer: src/utils/fmt.ts:15 — 可用字符串拼接替代模板(微优化)
## 必修 Top 3
1. 修复 login.ts:42 注入(用参数化查询)
2. 给 login() 补单测
3. feed.ts 批量预加载关联数据
三个子代理并行跑,主对话窗口里只留下最终汇总——过程中 security-auditor 可能读了 30 个文件、grep 了上百行,这些噪声全部被隔离在它的上下文里,没有泄漏到主对话。这就是子代理模式相对"一个大 prompt 干到底"的核心收益。
flowchart TD
A["1. 确定角色边界<br/>这个代理解决什么独立子问题?"] --> B["2. 写 .claude/agents/xxx.md"]
B --> C["3. frontmatter 四件套<br/>name / description / tools / model"]
C --> D["4. 撰写专职系统提示词<br/>(含输出格式约定)"]
D --> E{"5. 任务模式?"}
E -->|独立无依赖| F["并行委派(后台)<br/>墙钟≈最慢者"]
E -->|有先后依赖| G["串行链式<br/>reviewer→fixer"]
F --> H["6. 各代理独立上下文<br/>只回传结论"]
G --> H
H --> I["7. 主代理汇总<br/>主窗口保持干净"]
I --> J["8. 最小权限校验<br/>只读代理确实改不了文件"]
style C fill:#2d6a4f,color:#fff
style H fill:#40916c,color:#fff
style J fill:#1b4332,color:#fff
写好 description 是八成功力。 它既是搜索引擎又是路由表。第一句讲用途,第二句讲"何时主动触发",第三句列触发关键词。自动化场景下这尤其重要——-p 脚本里没人帮你点名。
工具白名单一定要显式写。 省略 = 继承全部工具 = 没有护栏。养成习惯:分析型一律给只读集合,修复型才给 Edit/Write。这是把"专业分工"落成"可执行护栏"的唯一手段。
模型档位按任务价值分配。 opus 只给少数高价值只读代理(安全审计、架构判断);机械活(分类、格式化)丢给 haiku;多数分析用 sonnet。多代理混搭是降本关键。
不要委派琐碎任务。 子代理有启动开销(独立上下文、工具协商)。一个"改一行错别字"的任务,直接做比委派快得多。规则:只有当子任务会产生大量中间噪声(搜索结果、日志、多文件内容)时,才值得委派。
不要委派需要全局上下文的任务。 子代理看不到主对话历史。如果你要它"按我们之前讨论的设计文档改代码",它根本不知道那份文档——你必须在委派时把关键上下文塞进 prompt,或者让它先去读那个文件。
紧耦合任务别拆成子代理。 两个任务要频繁来回沟通才能推进时,它们应该在一个代理里完成,而不是拆成两个子代理互相传话——子代理之间不能直接对话,只能通过主代理中转,延迟和上下文损耗都很高。
并行前确认"真的独立"。 假并行(其实有隐藏依赖)会导致后启动的代理拿到不完整信息。判断标准:把任务顺序打乱,结果是否一样?一样才能放心并行。
-p 批处理如何与子代理自动委派配合| 维度 | 评估 |
|---|---|
| 适合的训练营类型 | 中高级 Agent 自动化营——学员已会 -p/Hooks,需把"单兵作战"升级为"团队分工"。不适合零基础营(要先理解上下文窗口与工具系统) |
| 建议教学时长 | 2.5–3 小时(含动手)。讲概念 30 分钟 + 手写 3 个子代理 60 分钟 + 编排实战 60 分钟 + 调试 description 30 分钟 |
| 关键考核点 | ①能独立写出让主代理自动触发的 description ②能为不同角色配出最小权限 tools 白名单 ③能把 3 个只读代理并行跑出汇总报告 |
| 易错点密集区 | description 太空泛不触发、tools 拼错、把依赖型任务误并行、忘记子代理拿不到主对话上下文 |
| 衔接后续课程 | 本节是"多代理编排"的地基,后续可接 Agent SDK 编程式编排(用代码而非自然语言控制委派)和 Hooks + 子代理的确定性流水线 |
[!tip] 51学通信知识星球 星主:爱卫生(微信:gprshome201101)——公众号「51学通信」创办者,19 年通信行业运维与讲师经验,著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书(各大电商平台有售)。 星球定位:深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域,主打运维岗位与信令分析。 当前规模:5200 篇主题 / 990 个回答,198 元/年。 加入福利:加入星球后请加爱卫生微信,拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题,另有群内分享。 AI 加持:51学通信知识星球已作为 skill 接入 WorkBuddy,使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例,做总结、找文档和 PPT 等场景全覆盖。
