用 Claude Code 建立团队级代码审查流程
用 Claude Code 做风险导向 PR 审查,覆盖模板、CI Gate、CODEOWNERS 与证据化提示词。
把 Claude Code 放进代码审查流程,不是为了替代人类 reviewer,而是为了先整理 PR 风险、暴露遗漏点、统一审查口径。真正需要人判断的仍然是架构取舍、业务意图、权限边界和上线责任。
团队落地时,不建议只在需要时随手问一句。更稳的做法是把 PR 模板、CLAUDE.md 审查规则、diff 大小检查、GitHub Actions、CODEOWNERS 和固定审查提示词连起来。官方资料可以参考 Claude Code common workflows、GitHub pull request 文档、CODEOWNERS、GitHub Actions workflow syntax,安全审查可补充阅读 OWASP Code Review Guide。
流程设计
风险导向审查指的是:不是每一行代码都用同样力度看,而是把注意力优先放在认证、授权、计费、数据迁移、性能和测试缺口上。diff scope 是“这次 PR 实际变更的范围”。CI gate 是“自动阻止或提示风险 PR 的检查”。hallucinated finding 是“AI 编造出来、但 diff 中没有证据的审查结论”。
flowchart LR
A["PR template"] --> B["Diff size gate"]
B --> C["Claude Code review"]
C --> D["Code owner review"]
D --> E["CI tests and merge"]
C --> F["Questions before fixes"]
关键原则是:Claude Code 做审查时不要静默重写代码。如果业务意图、数据契约或权限边界不清楚,它应该提出问题,而不是猜一个结论。
真实使用场景
第一个场景是认证与授权变更。登录、session、角色、管理后台和 API key 相关 PR,应让 Claude Code 重点检查授权遗漏、权限提升、secret 泄露和审计日志缺失。人类 reviewer 决定业务规则是否成立。更深入的安全流程可参考安全审计自动化。
第二个场景是性能敏感变更。搜索页、列表页、缓存、图片处理和批处理很容易隐藏 N+1 查询、重复渲染、缓存键冲突和大 payload。Claude Code 的好评论应该说明“什么输入规模会变慢”和“如何测量”,而不是只说“可能有性能问题”。
第三个场景是测试与数据迁移。schema、migration、seed、校验规则和 backfill 都需要确认回滚方案、现有数据、nullable 字段、唯一约束和失败后重跑行为。Claude Code 可以先列出缺失测试和迁移边界,再交给数据负责人判断。
第四个场景是过大的 PR。超过 800 到 1000 行的 diff,审查质量通常下降。CI 可以先提示或阻止,Claude Code 则负责给出按行为、迁移、UI、测试拆分的建议。
PR 模板
把下面内容保存为 .github/pull_request_template.md。
## Change summary
- What changed:
- Why it changed:
- User-visible impact:
## Risk review
- [ ] Security impact checked
- [ ] Performance impact checked
- [ ] Test coverage added or explained
- [ ] Data migration or rollback plan checked
- [ ] No secrets, tokens, or personal data included
## Claude Code review request
Please review this PR by diff scope only.
Focus on:
- Security: auth, authorization, injection, secret leakage
- Performance: N+1 queries, cache keys, unnecessary work
- Tests: missing unit, integration, and migration tests
- Data: schema changes, rollback, backfill safety
For each finding, include:
- file and line
- why it matters
- evidence from the diff
- suggested fix or question for the author
这里最重要的是 diff scope only。它能减少泛泛而谈的架构建议,让 Claude Code 只围绕本 PR 的证据发言。
CLAUDE.md 规则
在仓库根目录的 CLAUDE.md 中加入团队审查规则。它相当于 Claude Code 的项目记忆,能减少每次提示词中的重复说明。更多写法可看 CLAUDE.md 最佳实践。
## Code review rules
Review only the current diff unless the user asks for wider context.
Severity:
- Must fix: security bug, data loss, broken build, failed test, migration risk
- Should fix: likely production bug, missing important test, measurable performance issue
- Nice to have: naming, small cleanup, optional refactor
Evidence rule:
- Every finding must cite a file and line.
- If the evidence is uncertain, ask a question instead of asserting a bug.
- Do not invent dependencies, routes, database columns, or team policies.
Security checks:
- Authentication and authorization
- SQL or command injection
- XSS and unsafe HTML
- Secret leakage
- Missing audit log for privileged actions
Data checks:
- Migration rollback path
- Backfill failure behavior
- Existing nullable and unique constraints
- PII handling and retention
“不确定就提问”要写进规则。比如“这个删除操作是否只允许管理员执行?”是问题;“这里有权限漏洞”则必须给出文件、行号和证据。
Diff Gate 脚本
把脚本保存为 scripts/review-diff-gate.mjs,用于检查文件数、变更行数和高风险路径。
#!/usr/bin/env node
import { execSync } from "node:child_process";
const baseRef = process.env.BASE_REF || "origin/main";
const maxFiles = Number(process.env.MAX_REVIEW_FILES || 25);
const maxLines = Number(process.env.MAX_REVIEW_LINES || 800);
function git(command) {
return execSync(command, { encoding: "utf8" }).trim();
}
const files = git(`git diff --name-only ${baseRef}...HEAD`)
.split(/\r?\n/)
.filter(Boolean);
const numstat = git(`git diff --numstat ${baseRef}...HEAD`);
const changedLines = numstat
.split(/\r?\n/)
.filter(Boolean)
.reduce((total, line) => {
const [added, deleted] = line.split(/\s+/);
return total + (Number(added) || 0) + (Number(deleted) || 0);
}, 0);
const riskyPatterns = [
/^src\/auth\//,
/^src\/billing\//,
/^db\/migrations\//,
/^infra\//,
/^\.github\/workflows\//,
];
const riskyFiles = files.filter((file) =>
riskyPatterns.some((pattern) => pattern.test(file))
);
let failed = false;
if (files.length > maxFiles) {
console.error(`Too many files changed: ${files.length} > ${maxFiles}`);
failed = true;
}
if (changedLines > maxLines) {
console.error(`Too many changed lines: ${changedLines} > ${maxLines}`);
failed = true;
}
if (riskyFiles.length > 0) {
console.log("Risk-sensitive files changed:");
for (const file of riskyFiles) console.log(`- ${file}`);
}
if (failed) {
console.error("Split the PR or add a reviewer-approved exception.");
process.exit(1);
}
console.log(`Review gate passed: ${files.length} files, ${changedLines} lines.`);
本地运行:
BASE_REF=origin/main MAX_REVIEW_FILES=25 MAX_REVIEW_LINES=800 node scripts/review-diff-gate.mjs
GitHub Actions 与 CODEOWNERS
把同一脚本放进 .github/workflows/review-gate.yml。
name: review-gate
on:
pull_request:
types: [opened, synchronize, reopened]
jobs:
diff-gate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-node@v4
with:
node-version: "22"
- name: Run diff size gate
env:
BASE_REF: origin/${{ github.base_ref }}
MAX_REVIEW_FILES: "25"
MAX_REVIEW_LINES: "800"
run: node scripts/review-diff-gate.mjs
再用 .github/CODEOWNERS 把高风险目录交给正确的人。
# .github/CODEOWNERS
/src/auth/ @example-org/security
/src/billing/ @example-org/payments
/db/migrations/ @example-org/backend-leads
/.github/workflows/ @example-org/platform
/infra/ @example-org/platform
CI/CD 的完整设计可以继续看 CI/CD 设置指南,PR 质量治理可看提升 PR 质量。
审查提示词
Review the current PR diff against main.
Rules:
1. Stay inside the diff scope unless a referenced file is required.
2. Do not rewrite code silently.
3. For each finding, include file, line, severity, evidence, and suggested action.
4. If business intent or data contract is unclear, ask a question instead of guessing.
5. Ignore style-only preferences unless they break CLAUDE.md or project conventions.
Focus areas:
- Security: auth, authorization, injection, XSS, secrets, audit logs
- Performance: N+1 queries, cache invalidation, repeated rendering, large payloads
- Tests: missing coverage for changed behavior, migrations, and edge cases
- Data migration: rollback, backfill, nullable fields, unique constraints
- CI and ownership: required checks, CODEOWNERS, risky paths
Output:
## Must fix
## Should fix
## Questions
## No issue found in
Questions 很重要。它能把不确定的业务意图和真正的 bug 分开,避免 Claude Code 给出看似自信但没有证据的结论。
常见坑与验证记录
第一个坑是让 Claude Code “审查并直接修复全部问题”。这样会在确认问题前扩大 diff。建议先审查,再由人选择要修的项,最后运行测试。
第二个坑是忽视 migration。测试通过不代表生产数据安全。要看现有 NULL、重复值、锁表时间、回滚限制和 backfill 失败后的重试。
第三个坑是第一天就把 gate 设得过严。更实际的做法是先 warning 一周,看数据后再把高风险路径设为必需。
本文示例按一个最小仓库流程验证:Node 脚本只依赖 Git 与 Node 22,GitHub Actions 调用同一脚本,PR 模板和 CLAUDE.md 让 Claude Code 必须基于 diff 证据发言。团队导入时,请先替换风险目录、负责人和测试命令,再用一个真实 PR 试运行。下一步可参考提交前 review gate 检查。
免费 PDF: Claude Code 速查表
输入邮箱即可获取一页 PDF,整理常用命令、审查习惯和安全工作流。
我们会妥善保护你的信息,不发送垃圾邮件。
把 Claude Code 变成真正能带来结果的工作流
先领取中文说明的免费 PDF,再进入英文商品页选择合适的教材。如果你需要团队落地、流程设计或内容变现支持,也可以直接咨询。
关于作者
Masa
专注 Claude Code 实务流程、团队导入和内容转化的工程师。
相关文章
Claude Code权限安全阶梯:逐步放开访问而不失控
从只读到有限编辑、验证命令和部署检查的 Claude Code 权限升级流程。
Claude Code 小PR证据包:让小改动真正可审查
用差异、验证命令、公开URL、CTA路径和回滚说明,把Claude Code的小PR变得可审查。
Claude Code 提交前 Review Gate:同时检查差异、测试、公开 URL 和 CTA
提交前用 Claude Code 审查差异范围、build、公开 URL、Gumroad 链接、咨询 CTA、缺少测试和无关文件。