案例背景
某团队一周提交了 200 个 PR,需要代码审查。传统流程:
- 高级工程师 2 人,每人审 100 个
- 单 PR 平均 6 分钟(读 diff + 思考 + 评论)
- 8 小时/人 = 16 人时
- 而且人审久了会疲劳,后 50 个质量明显下降
目标:用 AI 做初筛,把 200 个 PR 缩到 20 个"需人复审"的清单,让人只审这 20 个。
工具链
- Claude Code:批量执行审查逻辑
- GitHub MCP:拉 PR 列表、diff、评论
- Prompt 模板复用:参数化审查模板,不同语言/模块复用
工作流程
Phase 1:拉取 PR 数据(2 分钟)
Prompt:
用 GitHub MCP 拉取本周所有 PR:
- 标题、作者、改的文件、+/- 行数、是否含测试
输出 JSON 清单
AI 自动:
- 调 GitHub MCP 列出 PR
- 对每个 PR 拉 diff 统计
- 输出 200 行 JSON
| PR | 作者 | 文件 | +/- | 有测试 |
|---|---|---|---|---|
| #101 | 张三 | auth.ts | +50/-12 | ✅ |
| #102 | 李四 | db.ts | +200/-5 | ❌ |
| ... | ... | ... | ... | ... |
Phase 2:批量初筛(10 分钟)
这是核心。用 参数化模板 让审查逻辑可复用。
审查模板定义
你是资深{{language}}工程师。请审查以下 PR diff:
{{diff}}
PR 信息:{{pr_meta}}
审查维度(每项打 0-3 分):
1. 安全风险(SQL 注入 / 越权 / 敏感信息泄露)
2. 性能问题(N+1 / 大循环 / 慢查询)
3. 逻辑正确性(边界 / 空值 / 并发)
4. 可维护性(命名 / 复杂度 / 重复)
5. 测试覆盖(是否补了测试)
输出:
- 风险总分(0-15)
- 高风险项清单(带行号与原因)
- 是否建议人工复审(总分 > 6 或单项 = 3)
{{language}} 和 {{diff}} 参数化,TypeScript/Python/Go 各语言复用同一模板。
批量执行
import json
from pathlib import Path
prs = json.loads(Path("prs.json").read_text())
results = []
for pr in prs:
# 按文件扩展名定 language
lang = detect_language(pr["files"])
# 参数化调用审查模板
review = call_llm(
template="code-review-v2",
language=lang,
diff=pr["diff"],
pr_meta=f"{pr['title']} by {pr['author']}"
)
results.append({
"pr": pr["number"],
"score": review["total_score"],
"high_risks": review["high_risk_items"],
"needs_human": review["needs_review"]
})
# 排序,高风险在前
results.sort(key=lambda x: x["score"], reverse=True)
Path("review_results.json").write_text(json.dumps(results, ensure_ascii=False, indent=2))
200 个 PR,每个约 3 秒,总计 10 分钟。
初筛输出
| PR | 分数 | 高风险项 | 建议 |
|---|---|---|---|
| #134 | 11 | SQL 拼接 + 无测试 | 🔴 必审 |
| #187 | 9 | N+1 查询 | 🔴 必审 |
| #102 | 8 | 大循环 + 无测试 | 🟡 复审 |
| ... | ... | ... | ... |
| #145 | 2 | 无 | 🟢 自动通过 |
筛选结果:
- 🔴 必审(分数 > 8):5 个
- 🟡 复审(分数 6-8):15 个
- 🟢 自动通过(分数 < 6):180 个
Phase 3:人工复审(2 小时)
工程师只看 20 个高风险 PR。
AI 辅助复审
对每个高风险 PR,AI 不只给分数,还输出:
PR #134:在 auth.ts 第 45 行拼接 SQL
user_input 直接进 query → SQL 注入风险
建议改写:
const result = await db.query(
'SELECT * FROM users WHERE email = $1',
[user_input] // 参数化查询
)
依据:OWASP A03:2021
工程师:
- 看 AI 的高风险标注 → 确认是否真问题
- 看 AI 的修复建议 → 决定是否采纳
- 补充 AI 漏掉的架构层面问题(AI 看不到全局)
每个 PR 复审约 6 分钟,20 个 = 2 小时。
关键 Prompt 复盘
Prompt 1:参数化审查模板
你是资深{{language}}工程师。
审查维度:安全/性能/逻辑/可维护/测试
每项 0-3 分,总分 > 6 建议复审
为什么有效:参数化让一个模板适配多语言,不用每种语言重写审查逻辑。配合 模板复用 的思想,团队审查标准统一。
Prompt 2:高风险项必须带行号
高风险项清单:每项含文件名、行号、问题描述、修复建议
为什么有效:行号让工程师定位精准,不用从头读 diff。修复建议降低工程师思考成本。
Prompt 3:明确"是否建议复审"判断
总分 > 6 或 任一维度 = 3 → 建议人工复审
为什么有效:量化阈值让筛选可自动化,不靠 AI 主观判断"要不要人看"。
踩过的坑
坑 1:AI 漏掉跨文件问题
PR 改了 db.ts 的查询函数,但调用方 user.ts 没改
AI 只审 db.ts 单文件 → 漏掉调用方影响
解决:审查模板加一步"识别改动函数的调用方",配合 Filesystem MCP 读调用方代码。
坑 2:误报风格问题为高风险
AI 把"变量名太短"打成 3 分高风险
拉低了对真正高风险(SQL 注入)的注意力
解决:模板明确风险分级——安全/性能 = 高,风格 = 低。打分维度分离。
坑 3:大 diff 截断
某 PR 2000 行 diff → 超 context → AI 只审了前半
解决:分文件审,单文件 > 500 行再分块。配合 Prompt 缓存 降成本。
坑 4:AI 不知道项目约定
AI 把团队约定的"用 dayjs 不用 moment"判成"建议用 moment"
→ 误报
解决:审查模板注入项目规范文档(CONTRIBUTING.md),让 AI 按团队标准审。
坑 5:批量调用成本
200 PR × 平均 3000 token = 60 万 token
按 $3/百万 = $1.8,可接受
但首日没加缓存 → system prompt 重复传输
解决:Prompt 缓存 固化审查模板 + 项目规范,成本降 70%。
效率对比
| 环节 | 传统 | AI 辅助 | 提速 |
|---|---|---|---|
| 数据拉取 | 1 小时 | 2 分钟 | 30x |
| 初筛 200 PR | 8 小时 × 2 人 | 10 分钟 | 96x |
| 复审 20 PR | 已含 | 2 小时 × 1 人 | - |
| 合计 | 16 人时 | 2.3 人时 | 7x |
哪些环节 AI 真省时间
- ✅ 批量初筛:200 个 PR 同一标准过一遍,人不疲劳
- ✅ 风险打分:量化让筛选可自动化
- ✅ 定位行号:精准到行,省去人翻 diff
哪些环节还得靠人
- ⚠️ 架构层问题:AI 看不到全局,耦合/分层问题人更准
- ⚠️ 业务正确性:AI 不懂业务规则,需人判断逻辑是否符合需求
- ⚠️ 权衡决策:技术债 vs 上线速度,AI 不能替人做
- ⚠️ 误报甄别:AI 约 15% 误报,需人确认
质量保障
发布前必查:
- 高风险 PR 100% 人工复审
- AI 标注的行号与实际 diff 对应
- 安全风险项有真实修复建议(非空话)
- 自动通过的 PR 抽 5% 复审,确认 AI 没漏判
小结
这个案例最大的启示:代码审查的瓶颈不是"审",而是"从 200 个里找出值得审的 20 个"。AI 把初筛自动化了,人只做需要人脑的高风险判断。
下次 PR 堆积如山时,别硬扛——用 参数化模板 + GitHub MCP 批量初筛,把 200 个 PR 压成 20 个清单,你会发现真正需要你动脑的可能就 5 个。