
这是「Claude Code 通关手册」系列的第 5 篇。从这篇开始,我们进入 Level 3(扩展篇),也是整个系列最能体现“差异化竞争力”的部分。
想象这样一个场景。
你是一个技术负责人,手下有三个专家:一个代码质量专家、一个测试工程师、一个安全顾问。你把一个 PR 链接丢到群里说“审一下”,三个人各自打开代码,从各自的专业角度分析,半小时后各出一份报告汇总到你桌上。
你需要做的,只是看报告,然后做决定。
现在,把“三个专家”换成“三个 AI 子代理”。你对主 Agent 说一句“审查一下这个模块”,三个子代理同时开工——一个查代码质量、一个生成测试、一个扫描安全漏洞。它们各自在独立的上下文窗口里工作,互不干扰,最后把结果汇总回来。
这不是概念演示,这是 Claude Code 的子代理系统现在就能跑通的工作流。
今天,我们就把它讲透——从原理到实操,从创建你的第一个子代理,到为一个真实项目(比如 DevPulse)搭建一个三人“专家团队”。
为什么需要子代理?——突破“全科医生”的天花板
在前四篇内容中,你一直在跟 Claude Code 的“主 Agent”进行一对一对话。它的能力确实很强,但用久了,你会发现三个明显的瓶颈。
瓶颈一:上下文窗口是有限的。
打个比方:你的工作桌就这么大(上下文窗口就这么多 Token)。你让 Claude 同时看 20 个文件、记住你的编码规范、理解项目架构、还要分析性能问题——桌子上很快就堆满了“文件”,它开始翻不过来了,分析质量肉眼可见地下降。
瓶颈二:不同任务需要不同的“专业视角”。
代码审查要关注的点和安全审计要关注的点完全不同。让一个 Agent 同时扮演审查专家和安全专家,就像让一位医生同时做心脏手术和脑科手术——不是绝对做不到,但很难做到极致。
瓶颈三:串行处理,效率存在上限。
主 Agent 处理任务通常是排队的——先做 A,再做 B,最后做 C。但很多开发任务(比如审查代码和编写测试)本质上是可以并行进行的。
子代理系统,正是为了解决这三个问题而设计的:
┌──────────────────────────────────────────────────────────┐
│ 子代理解决的三个核心问题 │
├──────────────────────────────────────────────────────────┤
│ │
│ 问题 子代理的解决方案 │
│ ────────────────────────────────────────── │
│ 上下文窗口不够用 每个子代理有独立的上下文窗口 │
│ → 互不干扰,各自深度分析 │
│ │
│ 缺少专业分工 每个子代理有专属系统提示 │
│ → 代码专家只管代码,安全专家只管安全 │
│ │
│ 串行效率低 最多 7 个子代理并行工作 │
│ → 三份报告同时出,总时间不变 │
│ │
└──────────────────────────────────────────────────────────┘
用一个更直观的比喻:主 Agent 是你公司的“全科医生”——什么都能看,但看不深。子代理是你组建的“专科医生团队”——心内科、骨科、神经科各司其职,每个人在自己的诊室(独立上下文)里进行深度诊断,最后把诊断结果汇总给你这个主治医生。
子代理的运行机制:分工、隔离与协作
在动手创建之前,先花一分钟理解子代理是如何运行的。这不仅有助于后续配置,也能让你更好地规划使用场景。
┌──────────────────────────────────────────────────────────┐
│ 子代理运行流程 │
├──────────────────────────────────────────────────────────┤
│ │
│ 你: “审查 @src/app/api/ 下的所有 API 路由” │
│ ↓ │
│ ┌──────────────────────────────────────┐ │
│ │ 主 Agent(调度中心) │ │
│ │ 分析任务 → 选择合适的子代理 │ │
│ │ 或者:你手动指定用哪个子代理 │ │
│ └──────┬──────────┬──────────┬─────────┘ │
│ ↓ ↓ ↓ │
│ ┌──────────┐┌──────────┐┌──────────┐ │
│ │code ││test ││security │ │
│ │reviewer ││writer ││auditor │ │
│ │ ││ ││ │ │
│ │独立上下文 ││独立上下文 ││独立上下文 │ │
│ │独立权限 ││独立权限 ││独立权限 │ │
│ │专属提示词 ││专属提示词 ││专属提示词 │ │
│ └──────┬───┘└──────┬───┘└──────┬───┘ │
│ ↓ ↓ ↓ │
│ ┌──────────────────────────────────────┐ │
│ │ 主 Agent(汇总结果) │ │
│ │ 整合三份报告 → 呈现给你 │ │
│ └──────────────────────────────────────┘ │
│ │
│ 关键特性: │
│ • 每个子代理有自己的上下文窗口(最大 200K) │
│ • 子代理只接收自己的系统提示,不会继承主 Agent 的全部上下文│
│ • 最多 7 个子代理同时并行 │
│ • 子代理完成后返回摘要给主 Agent │
│ │
└──────────────────────────────────────────────────────────┘
这里最关键的一点是:子代理的上下文是隔离的。它不会继承你与主 Agent 之间冗长的对话历史,只会接收到自己的系统提示和被委派的具体任务。这正是它的优势所在——干净的上下文意味着更聚焦、更深入的分析。
创建你的第一个子代理:从零到一
定义子代理非常简单,跟创建 Slash 命令一样——一个 Markdown 文件就能搞定。
文件存放位置:
.claude/agents/ —— 项目级(建议提交到 Git,团队共享)
~/.claude/agents/ —— 全局个人级(所有项目可用)
最小可行示例:
首先,创建存放子代理的目录。
mkdir -p .claude/agents
接着,创建你的第一个子代理文件 .claude/agents/code-reviewer.md:
---
name: code-reviewer
description: 审查代码质量,关注 TypeScript 类型安全、React 最佳实践和性能问题
tools: Read, Glob, Grep
model: sonnet
---
你是一个严格但公正的代码审查专家,专注于 React + TypeScript 项目。
## 你的审查原则
- 先理解代码意图,再指出问题
- 每个问题必须给出修改建议,不要只说“这里有问题”
- 区分严重程度:🔴 必须修复 / 🟡 建议优化 / 🟢 可选改进
## 审查清单
1. TypeScript 类型安全(any、类型断言、缺失类型)
2. 组件设计(单一职责、Props 接口、Server/Client 划分)
3. 性能隐患(不必要重渲染、缺少 memo、常量提取)
4. 可读性(命名、注释、代码结构)
## 输出格式
按文件逐个分析,每个问题包含:
- 📍 位置(文件名 + 行号范围)
- ❓ 问题描述
- ✅ 修改建议(附代码)
就这样,一个基础但可用的子代理就创建好了。
加载方式: 子代理通常在会话启动时自动加载。如果你在会话中途新建了子代理文件,可以使用 /agents 命令立即加载,无需重启会话。
调用方式:
# 方式1:手动指定调用
使用 code-reviewer 子代理审查 @src/components/ArticleCard.tsx
# 方式2:自然描述,Claude 自动匹配
审查一下 ArticleCard 组件的代码质量
# → Claude 看到“审查”关键词,自动匹配 code-reviewer 子代理
实战:为 DevPulse 项目搭建三人专家团队
现在,让我们为一个假设的 Next.js 项目“DevPulse”创建三个各司其职的子代理,构建一个完整的 AI 专家团队。
子代理一:code-reviewer(代码审查专家)
文件:.claude/agents/code-reviewer.md
---
name: code-reviewer
description: 代码质量审查。检查 TypeScript 类型安全、React/Next.js 最佳实践、性能隐患和代码可读性。
tools: Read, Glob, Grep
model: sonnet
---
你是 DevPulse 项目的代码审查专家。这是一个基于 Next.js 14(App Router)+ TypeScript strict + Tailwind CSS 的技术博客平台。
## 审查优先级(从高到低)
### P0 — 必须修复
- any 类型(用 unknown 或具体类型替代)
- 类型断言(as)没有充分理由
- 服务端组件中误用了 useState/useEffect 等客户端 Hook
- 客户端组件没有标注 ‘use client’
- 缺少错误边界处理
### P1 — 强烈建议
- 组件超过 150 行未拆分
- Props 接口未导出或命名不规范(应为 XxxProps)
- 使用 index 作为列表 key
- 内联定义大型对象或函数(应提取到组件外部)
- 缺少 loading 和 error 状态处理
### P2 — 可选优化
- 可用 React.memo 优化但未使用
- 命名可以更清晰
- 缺少 JSDoc 注释
## 输出格式
对每个文件,输出:
**[文件名]**
| 级别 | 位置 | 问题 | 建议 |
|------|------|------|------|
| 🔴P0 | L15-20 | 使用了 any 类型 | 替换为 ArticleData 接口 |
最后给出整体评分(1-10)和一句话总结。
请注意这里的 tools: Read, Glob, Grep——我们只赋予了它只读权限。审查专家只需要看代码,不需要修改代码,这遵循了最小权限原则。
子代理二:test-writer(测试工程师)
文件:.claude/agents/test-writer.md
---
name: test-writer
description: 为组件和函数编写单元测试和集成测试。使用 Vitest + React Testing Library。
tools: Read, Write, Edit, Glob, Grep, Bash
model: sonnet
---
你是 DevPulse 项目的测试工程师。你的职责是为代码编写高质量的自动化测试。
## 技术栈
- 测试框架:Vitest
- 组件测试:React Testing Library
- HTTP Mock:MSW(Mock Service Worker)
- 断言风格:expect + toBe/toEqual/toHaveBeenCalled
## 测试文件约定
- 位置:与源文件同级的 `__tests__/` 目录
- 命名:ComponentName.test.tsx 或 functionName.test.ts
- 每个 describe 块对应一个组件或函数
## 测试覆盖策略
### 必须覆盖
- 正常渲染路径(传入典型 Props)
- Props 边界值(空字符串、undefined、空数组)
- 用户交互(点击、输入、提交)
- 错误状态(网络失败、无效数据)
### 选择性覆盖
- 不同 Props 组合的排列
- 异步操作的加载/成功/失败三态
- 无障碍属性(role、aria-label)
## 代码规范
- 每个 it/test 前用中文注释说明“测试什么”
- 优先使用 screen.getByRole,其次 getByText
- 禁止使用 getByTestId(除非实在没有语义化选择器)
- Mock 外部依赖,不发真实请求
## 完成后
- 运行 `npx vitest run --reporter=verbose` 验证测试通过
- 报告测试覆盖数据
这个子代理需要 Write 和 Edit 权限来创建和修改测试文件,以及 Bash 权限来运行测试命令。
子代理三:security-auditor(安全审计专家)
文件:.claude/agents/security-auditor.md
---
name: security-auditor
description: 安全漏洞扫描。检查 XSS、注入攻击、认证绕过、敏感信息泄露等安全风险。
tools: Read, Glob, Grep
model: sonnet
---
你是 DevPulse 项目的安全审计专家。你以攻击者的视角审视代码,找出潜在的安全漏洞。
## 扫描范围
### 前端安全
- XSS(跨站脚本):检查 dangerouslySetInnerHTML、未转义的用户输入
- CSRF 防护:表单提交是否有 Token 校验
- 敏感信息泄露:API Key、密码是否出现在客户端代码中
- 客户端存储安全:localStorage 中是否存储了敏感数据
### API 安全
- 注入攻击:SQL 注入、NoSQL 注入、命令注入
- 认证绕过:API 路由是否都检查了 session
- 权限控制:是否存在越权访问的可能
- 输入校验:请求参数是否经过 zod 等工具校验
- 速率限制:是否有暴力攻击防护
### 依赖安全
- 已知漏洞:检查 package.json 中是否有已知 CVE 的依赖
- 供应链风险:是否有不知名或长期未维护的包
## 输出格式
| 风险等级 | 类型 | 位置 | 描述 | 修复方案 |
|---------|------|------|------|---------|
| 🔴 高危 | XSS | Header.tsx L45 | 未转义的用户输入直接渲染 | 使用 DOMPurify 或移除 dangerouslySetInnerHTML |
最后给出安全评分(A-F)和优先修复建议 Top 3。
同样,安全审计专家也只需要只读权限。它的职责是发现问题,而非修复问题。
权限设计哲学:最小权限原则
上面三个子代理的权限差异是经过深思熟虑的:
┌──────────────────────────────────────────────────────────┐
│ 子代理权限对比 │
├────────────────┬──────────────────┬──────────────────────┤
│ 子代理 │ 权限 │ 设计理由 │
├────────────────┼──────────────────┼──────────────────────┤
│ code-reviewer │ Read, Glob, Grep │ 只看不改。审查不应该 │
│ │ (只读) │ 自动修改代码 │
├────────────────┼──────────────────┼──────────────────────┤
│ test-writer │ Read, Write, │ 需要创建测试文件和 │
│ │ Edit, Glob, │ 运行测试命令 │
│ │ Grep, Bash │ │
├────────────────┼──────────────────┼──────────────────────┤
│ security- │ Read, Glob, Grep │ 只看不改。安全审计 │
│ auditor │ (只读) │ 不应该改动任何代码 │
└────────────────┴──────────────────┴──────────────────────┘
原则:最小权限。
每个子代理只给它完成任务所必须的权限,多一个都不给。
为什么需要这么谨慎?因为子代理是独立运行的,你不会实时监控它的每一步操作。如果给安全审计子代理写权限,万一它“好心”帮你修复漏洞但改错了代码呢?只读权限 = 零副作用 = 绝对安全。对于 Claude Code 这类 AI 开发工具来说,权限控制是保障项目安全的第一道防线。
三种调用方式:从明确到智能
方式一:手动指定(最明确)
当你清楚地知道该用哪个专家时,这是最直接的方式。
使用 code-reviewer 子代理审查 @src/app/api/posts/route.ts
用 security-auditor 扫描 @src/app/api/ 目录下所有 API 路由的安全漏洞
让 test-writer 为 @src/components/ArticleCard.tsx 编写单元测试
方式二:自然语言描述,Claude 自动委派
你不需要记住子代理的名字。只要任务描述清晰,Claude 会根据每个子代理的 description 字段自动匹配。
帮我检查这个 API 有没有 SQL 注入风险
→ Claude 自动选择 security-auditor
给 ArticleCard 组件写一套完整的测试
→ Claude 自动选择 test-writer
自动委派的准确度取决于子代理 description 的清晰度。所以,要把描述写得像职位说明书一样具体。
方式三:组合调用,多代理协作
这是最强大的用法,一句话触发多个子代理并行工作。
对 @src/app/api/posts/route.ts 做一次完整审查:
1. 代码质量审查
2. 安全漏洞扫描
3. 补充缺失的测试
Claude 会理解你需要三个维度的分析,分别委派给对应的子代理,然后汇总结果。
你还可以要求有先后顺序的协作:
先让 code-reviewer 审查 @src/components/ArticleCard.tsx,
然后基于审查结果,让 test-writer 补充测试覆盖
这样,测试专家就能参考审查报告,来决定哪些高风险区域需要重点测试。
进阶功能:为子代理赋予持久化记忆
子代理有一个非常有价值的进阶功能——持久化记忆。
正常情况下,子代理每次被调用都是“全新”的,不记得上一次做了什么。但你可以通过 memory 字段让它拥有一个持久化的笔记本:
---
name: code-reviewer
description: 代码质量审查
tools: Read, Glob, Grep
model: sonnet
memory: user
---
你是代码审查专家。
## 重要
- 每次审查前,先读一下你的记忆文件,看看之前发现过什么模式
- 审查完成后,把新发现的项目模式和常见问题记录到记忆中
- 随着时间积累,你的审查会越来越懂这个项目
memory 字段的可选值及其作用:
┌──────────────────────────────────────────────────────────┐
│ memory 作用域 │
├──────────┬───────────────────────────────────────────────┤
│ 值 │ 效果 │
├──────────┼───────────────────────────────────────────────┤
│ user │ 记忆跟用户绑定,跨项目共享(推荐默认) │
│ project │ 记忆跟项目绑定,只在当前项目生效 │
│ local │ 记忆跟本地环境绑定 │
│ 不设置 │ 无记忆,每次调用都是全新的 │
└──────────┴───────────────────────────────────────────────┘
有了记忆之后,你的 code-reviewer 审查得越多,就越了解你的项目。它会记住“这个项目经常出现忘记标注 ‘use client’ 的问题”、“API 路由经常缺少输入校验”这些模式。随着时间推移,审查质量会持续提升。
常见陷阱与最佳实践
❌ 陷阱一:一上来就创建一堆子代理
最佳实践:从 1-2 个最高频的开始,用熟了再加。审查、测试、安全是经过验证的黄金三角组合,覆盖了代码质量的三个核心维度。
❌ 陷阱二:给子代理过宽的权限
test-writer 需要 Bash 权限来运行测试,但 code-reviewer 和 security-auditor 绝对不需要。审查与审计类的子代理,永远只给只读权限。
❌ 陷阱三:系统提示太笼统
“你是一个代码审查专家”——这太空泛了。你需要告诉它的是:这个项目的具体审查标准是什么、什么级别的问题需要什么处理、输出格式长什么样。越具体,结果越好。
✅ 最佳实践一:定义清晰的输出格式
每个子代理都应该有明确的输出格式定义。表格、分级、评分——让输出结构化,方便你快速扫描和决策。
✅ 最佳实践二:先手动调用建立信任
初期阶段手动指定子代理,观察输出质量。满意了再逐步转向自然语言描述,让 Claude 自动委派。信任是需要积累的。
✅ 最佳实践三:把子代理配置提交到 Git
.claude/agents/ 目录应该提交到版本控制。这样团队里的每个人都能使用相同的“专家团队”,保证审查标准和产出格式的一致性。这也是一种高效的团队 技术文档 和知识沉淀方式。
核心总结与通关清单
三个核心收获:
第一,子代理解决了主 Agent 的三个天花板——上下文有限、缺少专业分工、串行效率低。每个子代理拥有独立的上下文窗口、专属的系统提示、独立的权限,最多支持 7 个并行工作。
第二,定义一个子代理极其简单,一个 Markdown 文件即可。name + description 是必填项,tools 控制权限,model 选择模型,memory 开启记忆。创建成本极低,收益极高。
第三,审查(code-reviewer)+ 测试(test-writer)+ 安全(security-auditor)是经过验证的“黄金三角”组合。遵循最小权限原则,审查和安全只给只读权限,测试给读写+执行权限。建议先从这三个开始。
通关检查清单:
- [ ] 理解子代理的运行机制(独立上下文、委派执行、返回摘要)
- [ ] 创建了 code-reviewer 子代理并成功调用
- [ ] 创建了 test-writer 子代理并成功运行测试
- [ ] 创建了 security-auditor 子代理并完成安全扫描
- [ ] 理解最小权限原则(只读 vs 读写 vs 执行)
- [ ] 知道
/agents 命令可用于查看所有可用子代理
- [ ] 尝试过多代理组合调用
全部打勾?那么恭喜你,Level 3 的第一关已成功通过。你已经从“单兵作战”升级为“团队指挥”。在像 云栈社区 这样的技术社群里分享你的“AI专家团队”配置,或许能碰撞出更多有趣的用法。