DeepDojo.AI发布 2026-11-12English
Claude Code 自定义只读审查子代理
每次让子代理审查代码,你都要把同一段话再说一遍:只读,不要改文件;每条发现给出文件和行号;别为了凑数罗列风格偏好;没发现问题也要说明查了哪些范围。说到第五次,你开始想,能不能把这些要求固定下来,变成一个随叫随到的审查角色。
Claude Code 支持这样做:在 .claude/agents/ 里放一个 Markdown 文件,开头用 frontmatter 限定它的工具、模型和权限,正文写它的工作方法。难点不在格式,而在边界。几个常见的误会:
- 不写
tools,以为它只会读,实际上继承了主会话的全部工具; - 写了
permissionMode: plan,主会话一切到acceptEdits,它就跟着变了; - 打开持久记忆,只读角色悄悄多了写文件的能力。
所以定义一个可靠的角色,要做到两件事:frontmatter 用最少的工具和合适的模型限定能力,正文写清输入、方法、证据和交付格式。每加一项能力,都回头核对工具和权限。下面用一个 code-reviewer 从头走一遍。
01 什么时候值得定义一个角色
一次调查,临时子代理就可以。等你反复需要同一种审查,每次还要重说角色、工具和结果格式时,再把这些稳定要求保存成自定义代理。例如固定标准的认证审查、失败分析、只读数据库查询或截图验收,反复出现后可以定义角色。
项目代理放在 .claude/agents/,它适合当前仓库,并可以提交到 Git 供团队共同维护。个人跨项目代理放在 ~/.claude/agents/。
遇到同名代理,大致按这个来源顺序选择:
Managed → --agents 临时定义 → 项目 → 用户 → 插件项目内从当前目录往仓库根目录找,较近目录的同名定义优先。frontmatter 的 name 决定代理身份。名称要在范围内保持唯一:Claude Code 的子代理文档说明,同一个 .claude/agents/ 目录下两个文件声明了同一个名字时,只会加载其中一个,按文件系统的读取顺序而不是有文档说明的优先级来选。可用 /doctor 检查。
02 一个只读审查代理的完整定义
以只读审查为例,先想它要取得什么材料。这里由主会话提供 diff 文本或差异文件,代理再用读取工具查相关实现和测试。把这个输入约定和角色限制写进带 YAML frontmatter 的 Markdown 文件:
---
name: code-reviewer
description: 审查已经修改的代码,定位正确性、安全性和回归风险。完成代码改动后主动使用。
tools: Read, Grep, Glob
model: sonnet
permissionMode: plan
maxTurns: 12
color: blue
---
你是一名只读代码审查者。不要修改任何文件。
开始后先确认审查范围和主会话提供的 diff,再读取相关实现和测试。
若没有差异材料,报告缺少输入,不把未审查内容当作已经通过。只报告有证据的问题,
不要为了增加数量罗列纯风格偏好。
每条发现必须包含:
1. 严重程度;
2. 文件和行号;
3. 触发条件与实际影响;
4. 判断依据;
5. 最小修改建议。
如果没有发现问题,明确说明已检查的范围,并列出仍未验证的风险。frontmatter 限定能力,正文说明方法、证据和结果。直接编辑 .claude/agents/ 或让 Claude 按明确要求创建文件。Claude Code 会监视已有的代理目录,修改几秒内生效;会话启动时目录还不存在、你新建了第一个代理文件时,需要重启才能加载。
03 逐个字段看能力边界
几个字段分开看:
| 字段 | 控制什么 |
|---|---|
name | 唯一标识,用小写字母和连字符 |
description | 告诉主会话什么时候委派 |
tools | 可用工具 |
model | 模型别名、完整 ID,或用 inherit 继承 |
permissionMode | 希望使用的模式;可能被主会话覆盖,工具仍需收紧 |
maxTurns | 最多执行多少轮,到达上限时返回标记为未完成的结果 |
color | 列表里的区分颜色,不改变能力 |
必填的只有 name、description。不写 tools,就会继承主会话工具。按职责列出最少需要的工具,更容易看清它能做什么。Claude Code 最佳实践把这个做法说得很清楚:给 .claude/agents/ 里的自定义子代理只配 tools: Read, Grep, Glob,它就成了一个不能编辑任何东西的审查者,而且这个限制由 Claude Code 强制执行,不是在提示词里请求它遵守。
tools 明确列出允许能力;disallowedTools 从继承能力中移除少数工具,例如 Edit、Write。两项都写时,先去掉禁用工具,再按白名单选。官方还提醒,disallowedTools 里写带参数的条目,比如 Bash(git push *),照样会移除整个工具。
只读角色先排除 Edit、Write。需要 Bash,就再用权限、沙箱或 Hook 限制实际命令。仅写 permissionMode: plan 还不够:子代理文档说明,主会话处于 auto、acceptEdits 或 bypassPermissions 时,子代理会跟随主会话的模式,忽略你写的值。各权限模式的区别见Claude Code 六种权限模式怎么选。
描述要同时写清任务类型、触发时机和边界,主会话才能在正确场景委派:
description: 审查已经修改的认证与授权代码,检查正确性、安全性和回归风险。完成相关代码改动后主动使用;不负责直接修改文件。正文补齐输入、必读材料、判断顺序、限制、结果结构和无发现时的报告要求。“资深专家,请仔细工作”没有这些执行信息,无法弥补缺失的主会话背景。
04 按任务选模型,按需预加载 Skill
模型应按任务复杂度和所需能力选择:
| 任务 | 模型思路 |
|---|---|
| 文件定位、简单提取、格式检查 | 优先考虑 Haiku |
| 常规审查、调试和代码理解 | 优先考虑 Sonnet |
| 高风险架构判断、复杂根因分析 | 需要时使用 Opus |
| 与主会话强相关且不确定 | 使用 inherit |
选模型时,先确认它有能力完成任务,再比较速度和成本。能力不足、反复返工,也是在花钱。简单提取用轻量模型很合适,复杂判断就按实际要求选择。
skills 可以在代理启动时预加载专业知识:
skills:
- api-conventions
- security-review预加载会把 Skill 全文加入代理的起始上下文,官方特别注明注入的是完整内容,不只是描述。只加入当前任务需要的方法,避免无关资料占用空间和注意力。
05 三种调用方式
按控制范围选择入口:
| 需求 | 调用方式与边界 |
|---|---|
| 日常委派 | 说“用 code-reviewer 审查认证改动”;主会话仍有选择权 |
| 确保指定代理运行 | 在输入框用 @ 选择,如 @"code-reviewer (agent)" |
| 整段会话使用同一角色 | 启动 claude --agent code-reviewer,将其系统提示、工具和模型作为主线程身份 |
日常委派时,交给它的消息仍要自包含,写法见怎样给子代理交代任务、核对结论。
06 打开持久记忆以后
新建普通子代理,不会自动带上上次的对话;明确恢复已有实例,才接着用它的历史。想跨会话积累项目模式、调试经验或架构决定,可以设 memory 的保存范围:
memory: project三种范围分别是:
| 范围 | 位置 | 适用内容 |
|---|---|---|
user | ~/.claude/agent-memory/<代理名>/ | 跨项目通用的个人经验 |
project | .claude/agent-memory/<代理名>/ | 项目专有且可以与团队共享的知识 |
local | .claude/agent-memory-local/<代理名>/ | 项目专有但不应提交的个人记录 |
开启后,代理的系统提示里会带上记忆目录里 MEMORY.md 的前 200 行或 25KB,先达到哪个限制就停。入口保持短索引,细节按主题放其他文件。
下次仍会影响判断的稳定约束、重复故障和已验证路径,可以保存。整份测试输出、临时分支状态和猜测,留在这次任务里。经验要注明版本、范围与复核位置。旧版“退出漏吊销 token”不能记成持续存在的缺陷,代码变化后及时更新。
开启 memory 会为维护笔记增加读写工具。官方文档写明,开启记忆后 Read、Write、Edit 会自动启用,好让子代理管理自己的记忆文件。原先的只读角色因此获得了写入能力,需要重新检查工具和权限;只允许维护记忆时,把写入范围限定在记忆目录。
开头那段每次都要重说的要求,现在都写进了 code-reviewer.md:工具只有三个读取工具,正文写清了证据和交付格式。以后每给它加一项能力,比如记忆、Bash 或新的 Skill,都回头看一眼它还是不是那个只读审查者。