首页 › tutorials › 用Subagent搭建专属代码评审团

用Subagent搭建专属代码评审团:自定义Agent与并行编排实战

当你的项目越铺越大,让一个 Claude 在主会话里既读代码、又跑测试、还要写评审,上下文窗口很快就被日志和搜索结果淹没。Subagent(子智能体)就是为这件事而生的——它让每个专家跑在自己独立的上下文里,干完活只把结论交回来。本篇带你从零定义一支"专属代码评审团",并用 Agent SDK + headless -p 把它接进自动化流水线。

一、概述

本教程聚焦 Claude Code 的 Subagent 子智能体体系——这是 Agent 模式自动化的核心拼图。学完你将能够:

适用人群:已经用 Claude Code 跑过交互式会话、了解 -p 基本用法的开发者;想从"单兵作战"升级到"多 Agent 协同 + 自动化"的工程团队。

二、前置条件

三、为什么需要 Subagent:上下文隔离的本质

先厘清三个容易混淆的概念,这是整篇的地基:

机制 上下文 适合场景
主会话(Main) 累积全部历史 需要频繁来回、多阶段共享上下文(规划→实现→测试)
Subagent(子智能体) 全新独立窗口,只接收任务消息 + 自身 system prompt 产出大量中间结果(日志、搜索)但你只需要结论的任务
Skill(技能) 在主会话内展开 可复用的提示词/工作流,不想另开上下文

关键点:子智能体看不到你的对话历史。它只拿到三样东西——自己的 system prompt、Claude 写给它的任务委派消息、以及完整层级的 CLAUDE.md 与 git 快照(内置的 Explore/Plan 例外,它们会跳过这两项)。子智能体干完活,只有最终消息原样回到主会话,中间的工具调用全部留在它自己的上下文里。

这就是"上下文隔离"的价值:让一个专家 Agent 跑十轮测试、读几十个文件,主会话只收到一句"3 个用例失败,根因是 X"。

flowchart LR
    U[用户主会话] -->|"任务委派消息"| SA1[安全评审 Subagent]
    U -->|"任务委派消息"| SA2[性能评审 Subagent]
    U -->|"任务委派消息"| SA3[测试覆盖 Subagent]
    SA1 -->|"verbose 中间过程留在自己窗口"| L1[(独立上下文)]
    SA2 --> L2[(独立上下文)]
    SA3 --> L3[(独立上下文)]
    SA1 -->|"仅返回结论"| U
    SA2 -->|"仅返回结论"| U
    SA3 -->|"仅返回结论"| U
    style U fill:#e8f5e9,stroke:#2e7d32
    style SA1 fill:#fff3e0,stroke:#ef6c00
    style SA2 fill:#fff3e0,stroke:#ef6c00
    style SA3 fill:#fff3e0,stroke:#ef6c00

四、第一步:定义你的第一个 Subagent

操作说明

子智能体就是一个带 YAML frontmatter 的 Markdown 文件。两种创建方式:

方式 A——/agents 向导(推荐入门)。在交互式会话里输入 /agents,切到 Library 标签 → Create new agent → 选 Personal(存到 ~/.claude/agents/)或 Project(存到 .claude/agents/)。选 "Generate with Claude",用一句话描述需求,它帮你生成 name / description / system prompt。

方式 B——手写 Markdown 文件(推荐进阶与版本管理)。在仓库根目录建 .claude/agents/security-reviewer.md:

---
name: security-reviewer
description: 安全评审专家。在代码改动后立即使用,专注漏洞、注入、密钥泄露与权限校验。
tools: Read, Grep, Glob, Bash
model: sonnet
color: red
---

你是一名资深安全评审工程师,确保代码不引入安全风险。

收到任务后:
1. 运行 `git diff` 查看本次改动
2. 聚焦被修改的文件
3. 立即开始评审

检查清单:
- 是否存在 SQL 注入、命令注入、XSS
- 密钥 / Token / API Key 是否硬编码
- 用户输入是否做了校验与转义
- 权限校验是否完整

输出按优先级分组:
- 严重(必须修复)
- 警告(应当修复)
- 建议(可改进)
每个问题给出具体文件:行号与修复示例。

预期结果

保存后,子智能体在当前会话立即可用(如果你直接改磁盘文件,需要重启会话才能加载——这是新手最常踩的坑)。输入 /agents 在 Library 里能看到它。试着委派:

用 security-reviewer 子智能体审查 src/auth/ 下的改动

Claude 会判断任务匹配 description,自动把任务委派给该子智能体,它在独立窗口跑完,把评审结论交回主会话。

常见问题

五、第二步:作用域优先级——把专家放到正确位置

子智能体按存放位置决定作用域,同名时高优先级覆盖低优先级:

位置 作用域 优先级
受管理的 settings 组织级(管理员下发) 1 最高
--agents CLI 参数 仅本次会话 2
.claude/agents/ 当前项目 3
~/.claude/agents/ 你的所有项目 4
插件的 agents/ 插件启用处 5 最低

实践建议:项目专属的评审团放 .claude/agents/ 并提交到版本库,让全队共享同一套专家;个人通用的(比如你个人的代码风格偏好)放 ~/.claude/agents/。Claude Code 会递归扫描,所以可以用 agents/review/、agents/research/ 子目录组织——但 name 必须整棵树唯一,重名会被静默丢弃其一。

六、第三步:能力边界控制——给评审团套上笼头

操作说明

安全评审不能修改代码、测试 Agent 不能乱删文件,这就靠工具白名单 tools 与黑名单 disallowedTools:

---
name: safe-researcher
description: 只读研究 Agent
tools: Read, Grep, Glob, Bash
---

上面用 tools 做白名单:只允许这四个工具,连 MCP 工具都没有。反过来用黑名单:

---
name: no-writes
description: 继承所有工具但禁止写文件
disallowedTools: Write, Edit
---

两者同时存在时,先应用 disallowedTools,再用 tools 在剩余池里取交集。MCP 工具支持服务级通配:mcp__<server> 或 mcp__<server>__* 授权/撤销某服务的全部工具,mcp__* 在黑名单里表示撤销所有 MCP 工具。

还有几个工具子智能体永远拿不到(因为依赖主会话 UI 状态):AskUserQuestion、EnterPlanMode、ExitPlanMode(除非自身是 plan 模式)、ScheduleWakeup、WaitForMcpServers。

permissionMode 控制权限提示行为:default(标准提示)、acceptEdits(自动接受工作目录内的文件编辑与常见文件命令)、auto(后台分类器审核)、dontAsk(自动拒绝未显式允许的)、bypassPermissions(跳过提示,谨慎用)、plan(只读规划)。注意:父会话若是 bypassPermissions 或 acceptEdits,子智能体无法覆盖;父会话是 auto,子智能体的 permissionMode 会被忽略。

预期结果

一个只读的 security-reviewer(tools 不含 Edit/Write)即便被怂恿去"顺手修掉这个漏洞",也会拒绝改文件——能力边界从结构上锁死。

常见问题

七、第四步:模型分级路由——省钱又保质量

操作说明

不同任务配不同模型,是 Subagent 的"杀手锏"。model 字段接受别名 sonnet / opus / haiku / fable、完整 ID(如 claude-opus-4-8)、或 inherit(继承主会话,默认值)。

典型分级:

---
name: test-runner
description: 跑测试、分析失败、统计覆盖率。频繁调用,用快模型。
tools: Bash, Read, Grep
model: haiku        # 快、便宜,跑测试足够
---
---
name: security-reviewer
description: 安全评审,需要强推理。
tools: Read, Grep, Glob, Bash
model: sonnet       # 平衡能力与成本
---

模型解析优先级顺序(高→低):

  1. 环境变量 CLAUDE_CODE_SUBAGENT_MODEL
  2. 本次调用的 model 参数
  3. 子智能体 frontmatter 的 model
  4. 主会话模型

也就是说,临时想让所有子智能体走 Haiku 压成本,export CLAUDE_CODE_SUBAGENT_MODEL=haiku 一行搞定,无需改任何文件。

八、第五步:给评审团装上持久记忆

操作说明

memory 字段让子智能体拥有跨会话的知识库,能沉淀"这个仓库的代码风格""上次踩过的坑":

---
name: code-reviewer
description: 代码评审,会沉淀项目约定与反复出现的问题
memory: project
---

三种作用域:

作用域 存储位置 何时用
user ~/.claude/agent-memory/<agent>/ 跨所有项目积累经验
project .claude/agent-memory/<agent>/ 项目专属、可随版本库分享(推荐默认)
local .claude/agent-memory-local/<agent>/ 项目专属但不想进版本库

开启后:system prompt 自动注入记忆目录前 200 行或 25KB 的 MEMORY.md;Read/Write/Edit 工具会自动启用以便它维护记忆。提示词里写明"开工前先查记忆、收工后更新记忆",知识库就会越用越厚。

九、第六步:三种调用方式——从轻提示到全会话接管

方式 强度 用法
自然语言 由 Claude 决定是否委派 用 security-reviewer 审一下 auth 改动
@mention 保证指定子智能体一定跑 @"security-reviewer (agent)" 看 auth 改动
全会话接管 整个会话换成该 Agent 的 system prompt claude --agent security-reviewer

--agent 最特别:它让主线程本身变成这个子智能体——system prompt 完全替换(和 --system-prompt 一样),但 CLAUDE.md 与项目记忆仍正常加载。想把它设为某项目默认,在 .claude/settings.json 写 "agent": "security-reviewer"。

生产护栏小技巧:用 tools: Agent(worker, researcher), Read, Bash 的 Agent(类型) 白名单语法,限制一个协调型 Agent 只能派生指定子智能体(仅对 claude --agent 跑起来的主线程生效)。

十、第七步:并行调度——让三个专家同时开工

操作说明

并行是 Subagent 最爽的用法:互不依赖的调研同时进行,总耗时等于最慢的那个,而非三者之和。直接对主会话说:

用三个独立的子智能体并行研究:认证模块、数据库模块、API 模块

或者评审团场景:

分别用 security-reviewer、perf-reviewer、test-coverage 三个子智能体并行审查这次改动,最后汇总

每个子智能体独立探索,最后由 Claude 综合结论。

常见问题与注意事项

十一、第八步:Agent SDK 编程式编排——把评审团写进代码

操作说明

交互式调度够用,但要做 CI、要做可复现的批量流程,得上 Agent SDK。核心是 query() 的 agents 参数 + AgentDefinition。

下面是一段可直接运行的 Python 示例——并行调度三专家评审,自动批准所需工具(包括 Agent 本身):

# review_team.py —— 并行子智能体评审团
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions, AgentDefinition

AGENTS = {
    "security-reviewer": AgentDefinition(
        description="安全评审专家。用于漏洞、注入、密钥泄露检查。",
        prompt="""你是资深安全工程师。运行 git diff,聚焦改动,
        检查 SQL/命令注入、硬编码密钥、输入校验。按严重/警告/建议分组输出,附文件:行号。""",
        tools=["Read", "Grep", "Glob", "Bash"],
        model="sonnet",
    ),
    "perf-reviewer": AgentDefinition(
        description="性能评审专家。用于发现 N+1 查询、热循环、内存浪费。",
        prompt="""你是性能工程师。检查改动里的低效模式:N+1 查询、
        不必要的循环、重复计算、大对象拷贝。给出优化建议与预期收益。""",
        tools=["Read", "Grep", "Glob", "Bash"],
        model="sonnet",
    ),
    "test-coverage": AgentDefinition(
        description="测试覆盖检查。用于评估改动是否有对应测试、有无边界用例缺失。",
        prompt="""你是测试工程师。检查本次改动对应的测试是否存在、
        是否覆盖了边界条件与异常分支。列出缺失的测试场景。""",
        tools=["Bash", "Read", "Grep", "Glob"],
        model="haiku",   # 频繁、机械的活儿用快模型
    ),
}

async def main():
    async for message in query(
        prompt="并行使用 security-reviewer、perf-reviewer、test-coverage "
               "三个子智能体审查本次改动,最后汇总成一份评审报告。",
        options=ClaudeAgentOptions(
            # 关键:必须把 "Agent" 放进 allowedTools,否则委派会被拒
            allowed_tools=["Read", "Grep", "Glob", "Bash", "Agent"],
            agents=AGENTS,
        ),
    ):
        if hasattr(message, "result"):
            print(message.result)

asyncio.run(main())

预期结果

pip install claude-agent-sdk
python review_team.py

输出是一份综合评审报告——三个专家的结论已经被主 Agent 汇总。注意 allowed_tools 里务必包含 "Agent",否则子智能体调用会落到 canUseTool 回调或被 dontAsk 直接拒绝,这是排查"Claude 不委派"的头号原因。

动态工厂模式

评审严格度可按运行时条件动态生成定义——高危改动用 Opus,常规用 Sonnet:

def make_security_agent(level: str) -> AgentDefinition:
    strict = level == "strict"
    return AgentDefinition(
        description="安全评审",
        prompt=f"你是{'严格' if strict else '均衡'}的安全评审……",
        tools=["Read", "Grep", "Glob"],
        model="opus" if strict else "sonnet",  # 高风险用强模型
    )

十二、第九步:断点续跑——让评审 Agent 接着干

操作说明

子智能体每次调用都是新实例。要接着上次的上下文继续,靠 agentId 续跑。子智能体完成时,Agent 工具结果里会带 agentId: <id>(内置 Explore/Plan 是一次性的,不返回 agentId,要续跑就用自定义或 general-purpose)。

续跑三步:

  1. 第一次 query 时捕获 session_id
  2. 从 Agent 工具结果文本里正则提取 agentId: <id>
  3. 第二次 query 传 resume=session_id,并在 prompt 里带上 agentId
import re
from claude_agent_sdk import query, ClaudeAgentOptions, AgentDefinition, ToolResultBlock

AGENTS = {
    "endpoint-finder": AgentDefinition(
        description="定位并编目代码库里的 API 端点。",
        prompt="你负责找出并记录每个 API 端点的路径、方法、处理器。",
        tools=["Read", "Grep", "Glob"],
    )
}

def extract_agent_id(block):
    parts = block.content if isinstance(block.content, list) else [{"text": block.content}]
    for p in parts:
        if m := re.search(r"agentId:\s*([\w-]+)", p.get("text") or ""):
            return m.group(1)
    return None

async def main():
    agent_id = session_id = None
    async for msg in query(
        prompt="用 endpoint-finder 找出所有 API 端点",
        options=ClaudeAgentOptions(allowed_tools=["Read","Grep","Glob","Agent"], agents=AGENTS),
    ):
        if hasattr(msg, "session_id"):
            session_id = msg.session_id
        for b in getattr(msg, "content", None) or []:
            if isinstance(b, ToolResultBlock):
                agent_id = extract_agent_id(b) or agent_id
        if hasattr(msg, "result"):
            print(msg.result)

    if agent_id and session_id:
        async for msg in query(
            prompt=f"恢复 agent {agent_id},列出最复杂的 3 个端点",
            options=ClaudeAgentOptions(
                allowed_tools=["Read","Grep","Glob","Agent"],
                agents=AGENTS, resume=session_id,
            ),
        ):
            if hasattr(msg, "result"):
                print(msg.result)

asyncio.run(main())

子智能体的 transcript 独立持久化:主会话压缩(compaction)不影响它;重启 Claude Code 后只要恢复同一 session 就能继续;默认 30 天(cleanupPeriodDays)后清理。

十三、第十步:headless -p 自动化——把评审团接进 CI

操作说明

把整套评审团变成 CI 里的一道检查,用 claude -p 的 --agents(传 JSON)+ --bare(跳过本地配置,保证每台机器一致)+ --output-format json(拿结构化结果)。

--bare 会跳过 hooks、skills、plugins、MCP、auto memory、CLAUDE.md 的自动发现——CI 里要的就是这种"干净、可复现"。需要的上下文全部用 flag 显式传入:

# CI 里跑评审团,bare 模式 + agents 内联定义 + 结构化输出
claude --bare -p "对本次改动做安全/性能/测试三方面并行评审,输出 JSON 报告" \
  --allowedTools "Read,Grep,Glob,Bash,Agent" \
  --agents '{
    "security-reviewer": {
      "description": "安全评审专家。改动后立即使用。",
      "prompt": "你是安全工程师,检查注入、密钥、输入校验,按严重度分组输出。",
      "tools": ["Read", "Grep", "Glob", "Bash"],
      "model": "sonnet"
    },
    "perf-reviewer": {
      "description": "性能评审专家。改动后立即使用。",
      "prompt": "你是性能工程师,检查 N+1、热循环、内存浪费。",
      "tools": ["Read", "Grep", "Glob", "Bash"],
      "model": "sonnet"
    }
  }' \
  --output-format json | jq '.result'

预期结果

常见问题

十四、实战案例:可复现的 AI 代码评审流水线

把前面拼成一条真实可用的 GitHub Actions 片段。每次 PR 触发,三专家并行评审,结论写进 PR 评论,成本记录到日志:

# .github/workflows/ai-review.yml
name: AI Code Review
on: { pull_request: }
jobs:
  review:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with: { fetch-depth: 0 }
      - name: Install Claude Code
        run: npm install -g @anthropic-ai/claude-code
      - name: Run review team
        env:
          ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
        run: |
          set -o pipefail
          gh pr diff ${{ github.event.pull_request.number }} > /tmp/pr.diff
          cat /tmp/pr.diff | claude --bare -p \
            --append-system-prompt "你正在评审一个 PR diff。并行使用内置评审能力,从安全、性能、测试三方面给出结论。" \
            --allowedTools "Read,Grep,Glob,Bash,Agent" \
            --permission-mode dontAsk \
            --output-format json > /tmp/report.json
          jq -r '.result' /tmp/report.json > /tmp/comment.md
          echo "## 本次评审花费 \$$(jq -r '.total_cost_usd' /tmp/report.json)" >> /tmp/comment.md
          gh pr comment ${{ github.event.pull_request.number }} \
            --body-file /tmp/comment.md
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

这条流水线体现了四个工程要点:--bare 保证可复现、dontAsk 锁死只读、--output-format json 拿成本与结论、--append-system-prompt 注入角色而不覆盖默认行为。

十五、整体工作流程

flowchart TD
    PR[PR / 本地改动] --> DIFF[git diff]
    DIFF --> PIPE{调度方式}
    PIPE -->|交互式| INT[主会话: 自然语言 / @mention]
    PIPE -->|编程式| SDK[Agent SDK: agents 参数 + AgentDefinition]
    PIPE -->|CI 自动化| CLI[claude --bare -p --agents JSON]
    INT --> AG1[security-reviewer<br/>model: sonnet]
    INT --> AG2[perf-reviewer<br/>model: sonnet]
    INT --> AG3[test-coverage<br/>model: haiku]
    SDK --> AG1
    SDK --> AG2
    SDK --> AG3
    CLI --> AG1
    CLI --> AG2
    AG1 -.->|独立上下文隔离| CTX1[(各自窗口)]
    AG2 -.-> CTX2[(各自窗口)]
    AG3 -.-> CTX3[(各自窗口)]
    AG1 --> SYN[主 Agent 汇总]
    AG2 --> SYN
    AG3 --> SYN
    SYN --> RPT[评审报告 / PR 评论]
    style SYN fill:#e8f5e9,stroke:#2e7d32
    style RPT fill:#e3f2fd,stroke:#1565c0

十六、何时该用 Subagent,何时换别的

延伸阅读

训练营适用性评估

参考来源

  1. Create custom subagents — Claude Code Docs — 官方子智能体定义、frontmatter 字段、作用域、记忆、fork 全量说明
  2. Subagents in the SDK — Claude Code Docs — Agent SDK 的 agents 参数、AgentDefinition、并行调度与断点续跑编程范式
  3. Run Claude Code programmatically — Claude Code Docs — -p / --bare / 结构化输出 / --agents JSON / 续会话的 headless 自动化文档
  4. Claude Code Subagents: The Complete Guide — ComputingForGeeks — frontmatter schema、自动委派、并行工作流的社区实战解读
  5. awesome-claude-code-subagents — GitHub — 开源社区子智能体合集,可作为评审团成员的灵感模板库

本文由「51学通信」原创整理,聚焦通信与 AI 工程化的落地实战。更多硬核内容欢迎关注站长「爱卫生」(微信:gprshome201101),一起把 AI Agent 真正跑进研发流水线。

[!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 等场景全覆盖。

51学通信知识星球海报-扫码加入