☰
Claude Code 工程化实战第 5 讲:只读型子代理 SubAgent 配置与 Git Hook 落地
2026/9/29 21:26:58 网站建设 项目流程

1. 为什么只读型 SubAgent 是 Claude Code 工程化的第一块砖

如果你已经在本地用 Claude Code 写过几个小项目,大概率会遇到一个尴尬场景:让 AI 帮忙审查代码,它顺手把文件改了。改得对不对先不说,关键是"审查"和"修改"混在一起,你根本没法判断哪一步是它主动做的、哪一步是你授权的。Claude Code 的 SubAgent 机制就是来解决这个问题的,而只读型子代理(Read-Only SubAgent)是其中最容易落地、风险最低的一类。

只读型子代理的核心特征很朴素:工具白名单里只有 Read、Grep、Glob 三件套,没有 Edit、没有 Write、没有 NotebookEdit。它只能"看",不能"改"。这个约束在工程上意味着什么?意味着你可以放心地把它挂到 Git Hook 里,让它在每次git commit之前自动跑一遍审查,而不用担心"审查顺便把代码改了"这种事故。

本篇聚焦一个具体角色:code-reviewer。我会从它的 frontmatter 骨架写起,接入 TaoToken 的统一 Key/API 通道,然后用 Git Hook 在提交前触发只读审查。目标很明确:在本地仓库跑通一次"提交前自动审查"的完整流程。适合谁?适合已经在用 Claude Code、想把它从"聊天工具"变成"工程流水线一环"的开发者。如果你还没装 Claude Code,建议先跑通基础对话再回来。

2. TaoToken 前置:统一 Key 与 API 通道

Claude Code 默认走 Anthropic 官方通道,但在国内网络环境下,直连经常不稳定。TaoToken 提供的是一个统一的 API 网关,把 Key 管理和通道切换收敛到一个地方。你不需要在每台机器上配不同的环境变量,只需要一个 Key,就能让 Claude Code、Coding Plan、模型对话共用同一条通道。

2.1 获取 API Key

打开 TaoToken 控制台,在 API Keys 页面创建一个新 Key。建议按用途分 Key:一个给 Claude Code 用,一个给脚本用,方便后续排查问题时定位来源。创建后复制 Key,格式通常是sk-开头的一串字符。

2.2 配置 Claude Code 走 TaoToken 通道

Claude Code 读取的是环境变量。在~/.zshrc或~/.bashrc里加两行:

export ANTHROPIC_BASE_URL="https://taotoken.net/api" export ANTHROPIC_API_KEY="sk-你的Key"

保存后source ~/.zshrc让配置生效。验证一下:

echo $ANTHROPIC_BASE_URL # 应该输出 https://taotoken.net/api

注意:ANTHROPIC_BASE_URL不要带末尾斜杠,也不要带 UTM 参数。API 地址就是https://taotoken.net/api,干净利落。

2.3 验证通道连通

在终端里跑一次最简单的请求,确认 Key 和通道都正常:

curl -s https://taotoken.net/api/v1/messages \ -H "x-api-key: $ANTHROPIC_API_KEY" \ -H "anthropic-version: 2023-06-01" \ -H "content-type: application/json" \ -d '{ "model": "claude-sonnet-4-20250514", "max_tokens": 64, "messages": [{"role": "user", "content": "reply with OK"}] }'

如果返回里包含OK字样,说明通道通了。这一步很重要,因为后面 SubAgent 和 Git Hook 都依赖这条通道,通道不通后面全是白搭。

3. 可复制配置:code-reviewer 子代理骨架

Claude Code 的子代理定义放在.claude/agents/目录下,每个子代理是一个.md文件,由 frontmatter(YAML 元数据)和正文(system prompt)两部分组成。下面直接给可复制的配置。

3.1 极简版 code-reviewer

先写一个 20 行的极简版,适合入门理解结构:

--- name: code-reviewer description: Proactively review code changes for quality and security after I modify code, before commit. tools: Read, Grep, Glob model: sonnet --- You are a code reviewer. When invoked, run `git diff` to see recent changes, then report issues by priority: Critical / Warning / Suggestion. You may only read files. Never modify anything.

保存到.claude/agents/code-reviewer.md。四个 frontmatter 字段的含义:

name是子代理的身份证,主对话里用@code-reviewer引用。命名用小写字母加连字符,反映角色而不是技术栈。

description是最关键的字段,它决定"什么时候自动触发"。写成"何时触发"而不是"做什么"。上面这版写的是"after I modify code, before commit",Claude 看到你刚改完代码就会自动调起它。

tools是工具白名单。只读三件套 Read、Grep、Glob。注意:不写这个字段等于继承主对话的全部工具,那就失去只读约束了,千万别留空。

model选 sonnet,质量和成本平衡。关键审计场景可以换 opus,高频探索类可以换 haiku。

3.2 瑞士军刀版 code-reviewer

工程化团队用这个版本,覆盖质量、安全、性能、测试覆盖四个维度:

--- name: code-reviewer description: Proactively review code changes for quality, security, performance, and test coverage after I modify code, before commit. tools: Read, Grep, Glob, Bash model: sonnet --- You are a senior Python code reviewer with 10+ years of production experience in backend systems handling financial transactions. # 角色 - Default focus: code quality (readability, naming, duplication, obvious bugs) - Always-on: security (SQLi, XSS, SSRF, hardcoded secrets, auth checks) - If file path matches `src/orders/`, `src/payments/`, `src/billing/`: also check performance - If file path matches `tests/`: also check test coverage gaps # 硬约束 - You may only READ files. Never use Edit or Write tools. - Bash is allowed only for: `git diff`, `git log`, `git show`, `pytest --co`, `ruff check`. - Do NOT run: `pytest` (full), `rm`, `mv`, `cp`, or any state-changing command. - If you need something outside your scope, report it; do not improvise. # 报告格式(必须用这个结构)

Code Review: <branch 或 file>

Critical (must fix before merge) file:line — issue — suggested fix

Warning (should fix) file:line — issue — suggested fix

Suggestion (nice to have) file:line — issue — suggested fix

Summary Total issues: N (Critical N, Warning N, Suggestion N) Verdict: APPROVE / REQUEST_CHANGES / COMMENT

注意这里tools多了 Bash,但 system prompt 里明确限制了 Bash 只能跑git diff、git log、git show、pytest --co、ruff check这几个命令。这是"物理层白名单 + 语言层约束"的双保险。

3.3 settings.json 骨架

子代理定义好了,还需要在.claude/settings.json里配置 Hook,让它在git commit前自动触发:

{ "hooks": { "PreToolUse": [ { "matcher": "Bash", "hooks": [ { "type": "command", "command": "bash .claude/hooks/pre-commit-review.sh" } ] } ] } }

这个配置的意思是:当 Claude Code 准备调用 Bash 工具时,先跑一遍pre-commit-review.sh脚本。脚本里判断是不是git commit命令,是的话就调起 code-reviewer 审查当前 diff。

3.4 Hook 脚本

创建.claude/hooks/pre-commit-review.sh:

#!/usr/bin/env bash # 拦截 git commit,自动调起 code-reviewer 子代理审查 diff COMMAND="$1" # 1. 只在 git commit 时触发 if [[ "$COMMAND" != *"git commit"* ]]; then exit 0 fi # 2. 看当前 staged diff DIFF=$(git diff --cached) if [ -z "$DIFF" ]; then exit 0 fi # 3. 调起 code-reviewer 子代理 RESULT=$(claude --headless --agent code-reviewer \ --task "审查以下 git diff,按 APPROVE/REQUEST_CHANGES 给结论:$DIFF" 2>&1) # 4. 翻译结果为 exit code if echo "$RESULT" | grep -q "REQUEST_CHANGES"; then echo "code-reviewer 拒绝本次 commit:" echo "$RESULT" exit 2 fi if echo "$RESULT" | grep -q "Critical"; then echo "code-reviewer 发现 Critical 问题:" echo "$RESULT" exit 2 fi echo "code-reviewer 审查通过" exit 0

给脚本加执行权限:

chmod +x .claude/hooks/pre-commit-review.sh

4. 验证请求与成功结果

配置写完了,得验证它真的能跑通。分三步。

4.1 验证子代理能被调起

在 Claude Code 主对话里输入:

@code-reviewer 审查一下 src/orders/timeout.py

预期结果:code-reviewer 返回一份带 Critical / Warning / Suggestion 分级的报告。如果它说"找不到子代理",检查.claude/agents/code-reviewer.md路径对不对。

4.2 验证只读约束生效

在主对话里故意让它改文件:

@code-reviewer 在 src/orders/timeout.py 第 42 行加一行 print("debug")

预期结果:code-reviewer 拒绝,说"我没有 Edit 工具"或"我只能读文件"。如果它居然改了,说明tools字段配置错了,立即停用检查。

4.3 验证 Git Hook 触发

在仓库里改一个文件,git add之后执行git commit -m "test"。预期结果:commit 被拦截,终端输出 code-reviewer 的审查报告。如果审查通过,commit 正常执行;如果有 Critical 问题,commit 被阻止,exit code 为 2。

实测下来,第一次跑通这个流程大概需要 10 分钟,主要是等子代理审查 diff 的时间。如果 diff 很大(超过 500 行),审查会慢一些,可以考虑在 Hook 里加一个 diff 行数上限,超过就跳过自动审查、只提示手动跑。

5. 本篇常见错排查

5.1 description 写成"做什么"而不是"何时触发"

这是触发率低的头号原因。description: A senior code reviewer描述的是角色,Claude 不知道"用户什么时候需要我"。正确写法是Proactively review code changes after I modify code, before commit,把触发时机写清楚。判断标准:把 description 拿给一个新来的工程师看,问他"你在什么情况下会用这个子代理",答不上来就是写错了。

5.2 tools 给了 Bash 但没限制危险命令

只读子代理如果给了 Bash 工具,就开了一个后门。子代理理论上可以跑rm、mv、curl下载执行任意脚本。正确做法是在 system prompt 里明确列出允许的命令前缀,其他全部拒绝。判断标准:有 Bash 工具但没有命令白名单,等于没设防。

5.3 system prompt 只写角色不写硬约束

新人常踩的坑:system prompt 写得很"哲学","你是一个严谨的代码审查员,关注代码质量、安全、可维护性",但没写"你不能做什么"。结果子代理会"漂":看到明显 SQL 注入不拦、想顺手优化一下。判断标准:system prompt 里有没有Never、You may only、Do NOT这些明确的禁止词。全是"应该""最好"就是软约束,会漂。

5.4 Hook 脚本 exit code 写错

Git Hook 靠 exit code 判断放行还是阻止。exit 0 放行,非 0 阻止。常见错误是脚本里所有分支都 exit 0,导致审查发现问题也放行。检查方法:故意写一段有 SQL 注入的代码,git commit,看是否被拦截。没拦截就是 exit code 逻辑有问题。

5.5 子代理审查完直接 commit 绕过人工

危险的反模式:Hook 里 code-reviewer 审查通过后直接git commit合入,跳过人工 review。这等于让 AI 单独决定代码能不能进 main。正确做法是 Hook 只做审查、不做决策,AI 给意见,人看意见后自己点 commit。流程应该是:AI 审查 → 人看报告 → 人决定 commit / 改 / 拒绝。

6. 把只读审查嵌进你的日常流程

只读型 SubAgent 是 Claude Code 工程化的"零号工程"。三件套定义角色,三段式稳定行为,四场景覆盖大部分审查需求,Git Hook 让审查从"偶尔想起来才跑"变成"每次提交都跑"。

如果你想把这条流程跑得更顺,建议把 Key 管理和通道切换收敛到 TaoToken。一个 Key 同时给 Claude Code、Coding Plan、模型对话用,排查问题时不用在多个环境变量之间来回切。接入文档里有完整的配置说明,API Keys 页面可以直接创建和管理 Key。长期做编码和 Agent 场景的话,Coding Plan 的额度模型比按次调用更划算,适合把审查、测试、文档生成这些高频动作都挂上去。

下一步可以尝试把 security-auditor 和 test-coverage-reviewer 也写成只读子代理,在 Hook 里串行跑一遍。四个子代理各管一摊,主对话按需调起,或者统一在 commit 前触发。思维模型和本篇完全一样,只是工具白名单和 system prompt 的差异。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询