在如今 vibe coding 大行其道的时代,对于如何保证代码质量变的尤为重要,很多公司都陆续引入 AI code review 来减少对人工审核的依赖,然后实际上review 的效果到底怎么样,只能说是一个主观的印象,我个人的体验是还不错。但是我有时候也想优化 review skill,但是又没有实际的数据做对比,寻遍了互联网也没有想过的 repo,于是乎就自己来设计这个评估 AI review 的 benchmark。
对于这次的 PR 数据均来自于互联网上知名的仓库的真实 PR。我通过两个高级模型相互 review pr结合部分人工 review 查找出每个 PR 真实存在的需要处理的问题(GOLD),对于那么P2 级别的问题,并没有在我的统计之中,根据我的工程经验,几乎每次 review 都会存在不同级别的 P2 问题,所以在本文里面,并不关心 PR review P2 级别的问题。
这篇文章不准备讨论"AI 会不会取代 Reviewer"这种大问题,只回答几个更实际的问题:同一个模型换 Prompt 有没有用,不同模型用同一个 Prompt 差多少,多模型交叉 Review 能补多少盲区,以及怎么在时间和准确率之间做取舍。
实验是怎么做的
这次使用 35 个真实历史 PR,来自 Lottie、OkHttp、Coil、Retrofit、Bitwarden、Firefox、Now in Android 等项目。里面有 32 个正样本 PR,一共 48 条 owner-adjudicated P0/P1 Gold,另外 3 个 PR 没有 P0/P1,用来观察模型会不会强行找问题。
在看结果之前,先把文章里反复出现的几个指标解释一下。它们名字看起来像算法论文,其实放到 Code Review 场景里并不复杂。
TP、FN 和 No-credit 是什么
TP(True Positive)可以理解为"命中"。模型报出一个 high/critical 问题,并且根因和某条 P0/P1 Gold 相同,就记为 1 个 TP。
FN(False Negative)是"漏掉"。Gold 里有一个真实 P0/P1,但模型没有以 high/critical 找到它,就记为 FN。
No-credit 是模型报成 high/critical、但没有匹配到 P0/P1 Gold 的 finding。这里我没有直接写 FP,因为 No-credit 不一定已经证明是误报。Gold 只收录 P0/P1,它也可能是合理的 P2/P3,只是在这项严格评分里不得分。
Precision:报出来的问题有多准
Precision = TP /(TP + No-credit)
假设模型报了 10 条高优问题,其中 6 条命中 Gold,Precision 就是 60%。
Precision 高,意味着 Reviewer 收到的噪音更少。对于每天 PR 很多的团队,这个指标很重要,否则 AI 一次发十几条似是而非的评论,最后只是把阅读成本转移给人。
Recall:真实问题找回了多少
Recall = TP /(TP + FN)
假设数据集里一共有 12 条真实 P0/P1,模型找到了 6 条,Recall 就是 50%。
Recall 高,意味着更不容易漏掉严重 Bug。Release、支付、权限、数据迁移这类 PR 通常更在意 Recall,因为漏掉一条问题的代价可能远高于多检查几条评论。
F1:Precision 和 Recall 的折中
F1 = 2 × Precision × Recall /(Precision + Recall)
F1 是 Precision 和 Recall 的调和平均。它不是简单取平均,其中一项很低时,F1 会被明显拉低。
例如 Precision 是 90%、Recall 只有 10%,普通平均数是 50%,但 F1 只有 18%。这比较符合 Review 的直觉:一个模型虽然报得很准,但十个真实问题只能找到一个,不能算整体效果好。
所以 F1 适合用来观察综合表现,但不能代替 Precision 和 Recall。团队如果更怕漏报,就应该额外看 Recall;如果 Reviewer 已经被 AI 评论淹没,就应该优先看 Precision。
严格 P0/P1 和任意严重度找回
本文还同时保留两套口径。
严格 P0/P1 要求模型不仅找到同一个根因,还必须把它输出为 critical/high。模型找到问题却只判成 medium/low,严格指标仍然不计分。
任意严重度根因找回不看模型给出的等级。只要根因和 Gold 相同,就算找回。这个指标更接近"模型有没有看懂 Bug"。
这两个指标一定要放在一起看。只看严格 F1,会把严重度校准差误认为完全没找到;只看根因覆盖,又会掩盖模型把严重问题写成普通建议的情况。
同一个模型,不同 Prompt 差多少
先看固定模型后的 A/B。
| 模型 | Prompt | Precision | Recall | F1 | 任意严重度找回 | 平均耗时 |
|---|---|---|---|---|---|---|
| GPT-5.6-sol | OpenCodeReview Skill | 47.6% | 62.5% | 54.1% | 38/48(79.2%) | 6m22s |
| GPT-5.6-sol | 完整 Skill | 66.7% | 29.2% | 40.6% | 35/48(72.9%) | 4m46s |
| GPT-5.6-sol | 简单 Prompt | 62.5% | 41.7% | 50.0% | 34/48(70.8%) | 4m39s |
| GPT-5.6-luna | 完整 Skill | 38.9% | 58.3% | 46.7% | 30/48(62.5%) | 5m55s |
| GPT-5.6-luna | 简单 Prompt | 56.8% | 43.8% | 49.4% | 28/48(58.3%) | 4m48s |
| DeepSeek V4 Flash | 完整 Skill | 54.2% | 27.1% | 36.1% | 37/48(77.1%) | 5m26s |
| DeepSeek V4 Flash | 简单 Prompt | 60.0% | 43.8% | 50.6% | 32/48(66.7%) | 5m37s |
| DeepSeek V4 Flash | 极简 Prompt | 66.7% | 50.0% | 57.1% | 34/48(70.8%) | 4m31s |
备注 DeepSeek V4 Flash 运行在 claude code 内,GLM/ZCode
GPT-5.6-sol 的 Skill 比简单 Prompt 多找回 1 条 Gold,但严格 Recall 少了 12.5 个百分点。说明 Skill 让它看到了问题,却没有把高风险问题判到正确等级。
Luna 更明显。Skill 把 Recall 从 43.8% 拉到 58.3%,但 Precision 从 56.8% 掉到 38.9%。它变成了一个更积极的 Finder,但不是一个更好的 Gatekeeper。
DeepSeek 是最有意思的一组。完整 Skill 的任意严重度覆盖最高,达到 77.1%,但严格 F1 最低。也就是说,它理解了不少根因,最后却把很多 P0/P1 写成了中低优问题。反而是极简 Prompt 得到最高 F1 和最短耗时。
虽然在准确率 Precision 这个指标上 使用 Skill review 发挥不是很稳定,但是在覆盖率这个指标上是达到一致趋势,说明 skill 是可以发现问题,但是如何优化 review 上报优先级,每个模型似乎有着自己的看法。
GLM-5.2 的方向完全相反:
| GLM-5.2 内部 A/B | Precision | Recall | F1 | Findings | 任意严重度找回 |
|---|---|---|---|---|---|
| 完整 Skill | 83.9% | 72.2% | 77.6% | 64 | 38/48 |
| 简单 Prompt | 66.7% | 50.0% | 57.1% | 88 | 32/48 |
Skill 不仅多找回 6 条 Gold,还把 finding 数量从 88 降到 64。这个结果不是"写得越多越容易撞中",而是更少、更集中。
结合上面的数据我们可以得到如下结论
- 不要把一份 Prompt 复制到所有模型,然后期待同样的收益。Skill 不是通用补丁,它和模型本身存在很强的交互。
- Skill review 的单位耗时要比简单 prompt 多不少。
- Skill review 的覆盖面很广,但是在有些模型上会存在误报等问题。
不同模型,同一个 Prompt 谁更强?
跨模型比较时,我更愿意看任意严重度根因覆盖,因为它们都明确使用 48 条 Gold 作为分母。
| 模型 | 完整 Skill 找回 | Findings/PR | 简单 Prompt 找回 | Findings/PR |
|---|---|---|---|---|
| GPT-5.6-sol | 35/48(72.9%) | 3.34 | 34/48(70.8%) | 2.97 |
| GPT-5.6-luna | 30/48(62.5%) | 2.94 | 28/48(58.3%) | 2.69 |
| DeepSeek V4 Flash | 37/48(77.1%) | 3.29 | 32/48(66.7%) | 3.06 |
| GLM-5.2 | 38/48(79.2%) | 1.83 | 32/48(66.7%) | 2.51 |
用完整 Skill 时,最高和最低之间相差 8 条 Gold;用简单 Prompt 时,相差 6 条。有些差距,但没有大到"高级模型碾压其他模型"。
GLM-5.2 的结果尤其值得看:只输出 64 条 finding,平均每个 PR 1.83 条,却找回 38 条 Gold。GPT-5.6-sol 输出 117 条,找回 35 条。在这里我们先不比较模型的好坏,但是可以看出来模型 review 结果的多少并不能代表最后的效果。
当然这里也需要注意的是 GLM 模型跑在 Zcode 里面,拥有 1M 的上下文,可能存在额外的加持。
多模型交叉 Review 是否靠谱?
在日常的 code review 流程中,大家都会有一个工程上的经验,即让不同的 model 来 review 代码,以此来保证 review 工作的准确性,这在工作中被证明了有效,但是实际情况是怎么样,我们通过数据来观摩一下。
我把各 arm 命中的 gold_id 做了交集和并集,没有让模型互相看对方的答案。
| 组合 | 各自覆盖 | 并集覆盖 | 重叠 | A 独有 / B 独有 |
|---|---|---|---|---|
| Sol Skill + Luna Skill | 35 / 30 | 38/48(79.2%) | 27 | 8 / 3 |
| Sol Skill + GLM Skill | 35 / 38 | 43/48(89.6%) | 30 | 5 / 8 |
| GLM Skill + OpenCodeReview | 38 / 38 | 42/48(87.5%) | 34 | 4 / 4 |
| DeepSeek Skill + Sol Skill | 37 / 35 | 41/48(85.4%) | 31 | 6 / 4 |
四个模型都使用完整 Skill 时,并集达到 44/48,也就是 91.7%;但四个模型交集的只有 20/48,也就是 41.7%。
综上所述说明交叉 Review 可行,而且价值来自"盲区不同",不是简单重复。 值得注意的事同样是 38/48 的 GLM Skill 和 OpenCodeReview,仍然各自有 4 条对方没找到的问题,在 GPT 家族的模型之间取并集覆盖率提升非常有限,说明需要交叉 review 最好选择不同供应商之间的模型进行 review。
随着 review 模型增加,收益会快速递减。把所有模型、所有 Prompt 和 OpenCodeReview 全部合起来,上限是 46/48(95.8%),仍然有两条所有配置都没找到,当然由于 Gold 的标准也是模型评判出来的,自然存在误差,在这里面我们把覆盖率达到 85% 都视为可接受的结果。
高级模型和低参数模型,差别到底在哪里?
很多人会自然认为参数更大、推理更强的模型一定更会 Review。这个数据不支持这么简单的结论。
先说明一下,各家并没有公开一套可以直接比较的有效参数口径,所以我不会编一个参数量排行榜。这里更准确的说法是:高能力模型和速度/成本导向模型的行为差异。
这轮里我看到三种风格:
- GPT-5.6-sol 更保守。它的 Skill Precision 高,但会把一部分真实 P0/P1 降级,导致严格 Recall 低。
- DeepSeek V4 Flash 很会发现根因,但严重度校准不稳定。Skill 找回 77.1%,严格 Recall 只有 27.1%。
- GLM-5.2 在匹配的 Skill 下输出更少、更集中,内部 A/B 提升很大。
对 Review 来说,"有没有能力理解代码"只是第一层。后面还有是否愿意报、会不会把相关症状合并、严重度是否稳定、能不能遵守只报 changed line 等行为约束。小模型配到合适的 Skill,可能比高级模型套一个不合适的 Skill 更有效。
换句话说,Prompt 和模型不是两个可以独立优化的按钮。换模型后,Prompt 应该重新做 A/B。
Alibaba OpenCodeReview:更高召回,But what cost?
在同一个 GPT-5.6-sol 基线上,我还测了 OpenCodeReview delegation mode。
| Arm | Precision | Recall | F1 | 任意严重度找回 | 平均耗时 |
|---|---|---|---|---|---|
| Simple Prompt | 62.5% | 41.7% | 50.0% | 70.8% | 4m39s |
| Review Skill | 66.7% | 29.2% | 40.6% | 72.9% | 4m46s |
| OpenCodeReview | 47.6% | 62.5% | 54.1% | 79.2% | 6m22s |
OpenCodeReview 相比简单 Prompt,多找回 4 条 Gold,严格 Recall 提升 20.8 个百分点,但每个 PR 多花约 1 分 43 秒,Precision 下降 14.9 个百分点。
如果目标是 Release 前尽可能别漏掉高风险问题,这个交换可以接受。如果是每个小 PR 都默认跑,Reviewer 会收到更多需要人工排除的 finding,成本也会增加约 37%。
我更倾向把它放在第二层,而不是所有 PR 的默认第一层。
怎么平衡效率和准确率
根据这轮数据,我最后会把流程做成一个分层漏斗。
第一层:单模型快速 Review
普通 PR 先跑经过本模型 A/B 验证的 Prompt,不要默认使用最长的 Skill。
如果使用 GPT-5.6-sol,简单 Prompt 在严格 F1 和耗时上都比当前 Skill 更合适;如果使用 GLM-5.2,当前 Skill 的收益明显,应该保留。
第二层:只升级高风险 PR
出现下面情况再触发第二模型或 OpenCodeReview:
- 改到并发、缓存一致性、权限、存储迁移。
- 涉及 Android API level、反射、JNI、R8 或二进制兼容。
- Diff 很大,跨多个模块。
- 第一模型发现了可疑根因,但置信度或严重度不稳定。
- Release/Hotfix 分支,漏报成本远高于多花几分钟。
这样可以把交叉 Review 的 85%~90% 根因覆盖用在真正值得的地方,而不是把所有 PR 的成本直接翻倍。
第三层:把发现和定级拆开
DeepSeek 的结果说明,模型可能已经找到根因,只是严重度放错了。我会让第一阶段负责找问题,第二阶段只做一件事:根据 trigger、broken invariant 和 material impact 重新排序,选出最多 3~5 条阻塞项。
这比让两个模型都从头读一遍 PR 更省,也更容易控制噪音。
第四层:强制证据门槛
每条 finding 至少要有:
- changed line;
- 可复现 trigger;
- 被破坏的 contract/invariant;
- 实际 impact;
- 为什么附近代码、调用方或测试不能否定它。
没有这几个字段,就不要直接发到 PR。模型写得像真的,不代表它已经证明了。
我现在会怎么配
如果让我把这轮实验转成日常配置,我会这样做:
- 普通 PR:一个经过 A/B 的主模型,最多输出 3~5 条高置信 finding。
- 高风险 PR:主模型 + 一个行为差异明显的第二模型,不选两个高度相似的配置。
- Release PR:再加 OpenCodeReview 或专门的兼容性/并发 Skill。
- 严重度:单独做一次 rerank,不完全相信第一次输出。
- 结果评估:同时保留严格 P0/P1 和任意严重度根因覆盖,不能只看一个 F1。
- Prompt 变更:每次改 Skill 都在固定 PR 集合回归,不凭"看起来更专业"上线。
还有一个很实用的原则:不要奖励模型多报。GLM Skill 用 64 条 finding 找回 38 条 Gold,GPT Skill 用 117 条找回 35 条。Review 的目标不是生成更多文字,而是减少 Reviewer 的判断负担。
局限
这不是一个官方排行榜,现阶段只能算本地研究性 benchmark。
- 只有 35 个 PR,单次运行,没有做多次采样和置信区间。
- Gold 是 owner-adjudicated,不是独立双人标注。
- 语义匹配使用一个 LLM judge,和部分被测模型并不完全独立。
- ZCode 的部分证据参与过 Gold adjudication,不是干净的 held-out evaluation。
- No-credit 不等于已证明误报,因为 P2/P3 不在 Gold 范围内。
- GLM 批次缺少有效耗时记录,严格指标分母也需要重新统一。
所以我更看重方向性结论:Prompt 和模型存在强交互,严重度校准是独立瓶颈,多模型确实互补,但收益和成本都不是线性的。
结尾
做完这轮实验,我对 AI Review 的看法比之前更务实了。
它不是"装一个 Skill 就得到资深 Reviewer",也不是"换成最贵的模型就不会漏 Bug"。真正有效的方案,需要固定数据集做回归,针对每个模型调 Prompt,把发现和定级拆开,并且只在高风险 PR 上交叉 Review。
AI Review 最适合做的事情,是先帮人缩小搜索空间。最后是否阻塞合并,仍然要回到代码路径、测试和工程师自己的判断。
后续我还会继续补充多次采样、统一 judge,以及 API compatibility、并发和 Compose 三类专项集。到那时候,才能更接近回答另一个问题:什么样的 Review Skill,是真的可以长期放进团队 CI 里的。
最后由于本人时间和精力有限,测试轮次较少,测试过程难免存在疏漏,希望理解。