LabHub

博客

AI 代码评审到底能不能用 — 测量证据揭示的准确率与误报

한국어English日本語中文

引言 — 「AI 找到了 N% 的 bug」这句话为什么单独看毫无意义

先说结论。截至 2026 年 7 月,由与厂商无关的一方在真实生产环境中测得的通用 AI 代码评审器精确率·误报率数字,公开的实际上并不存在。公开的只有三种 — 厂商自己造的基准测试、用「开发者是否对评论做出反应」来代替测量的代理指标,以及只有一家公司的案例研究。本文把这三种各自拆开来看。

而这个事实本身对实务就很重要。「AI 评审器抓住了 N% 的 bug」这样的主张,不同时给出两样东西就无从判断。

  1. 在哪个数据集上测的,标准答案(ground truth)是谁、用什么方式造出来的
  2. 误报率是多少 — 也就是为了拿到那个 N%,开发者得读掉多少条废话

缺了第二条的召回率(recall),可以免费做到 100%。给每一行代码都留一条「这里说不定有 bug」的评论就行了。评审工具的价值不在于它抓到了什么,而在于抓的同时没有制造出来的噪声。所以下文每次看到数字,都会先确认分母和标准答案的出处。

本文是把在 AI 编程模型评测中分辨信号与噪声一文的问题意识搬到代码评审上。那边的对象是基准测试,这边是评审评论,仅此而已 — 「先问数字在测什么」这条原则是同一个。

AI 评审评论实际被采纳多少 — 0.9% 还是 73.8%

使用最广的代理指标是「开发者有没有照着那条评论改代码」。用这个指标测出来的公开数据有两份,而且正面相撞。

测量 A — 开源(Gan 等,arXiv 2508.18771)。研究选取了 16 款用于 GitHub 工作流的 AI 代码评审 Action,在 PR 数量不少于 50 的成熟仓库 178 个里,收集了 AI 生成的评审评论 22,326 条。其中 5,652 条用 GPT-4.1 做有效性判定,3,955 条被归类为「有效(具体且可执行)」,再用 o3-mini 判定是否被实际采纳。结果如下。

测量 B — 一家企业内部(Cihan 等,arXiv 2412.18531)。这是跨国家电企业 Beko 引入基于开源 Qodo PR-Agent 的评审机器人(GPT-4 Turbo)的案例。10 个项目的 238 人拥有访问权限,研究分析了其中 3 个项目的 4,335 个 PR(挂上自动评审的是 1,568 个)。机器人评论共 4,408 条,经过滤后统计的是挂在已合并 PR 上的 1,408 条,结果如下。

同一个名字的指标,横在 0.9% 和 73.8% 之间。最大差 80 倍。哪一边都没有错 — 它们只是在测不同的东西。

为什么同一个指标能差出 80 倍

差距不是来自工具性能,而是来自测量条件。有四处不同。

第一,分母不同。测量 B 的 73.8% 只统计挂在已合并 PR 上的评论。挂在被弃置 PR 上的评论从一开始就不进统计。评审太糟导致 PR 死掉的情况进不了分母,所以这个数字在结构上向上偏。测量 A 相反,看的是成熟开源仓库全体的有效评论。

第二,制造标签的力量不同。在 Beko,要合并 PR,开发者必须显式确定所有评审评论的状态。也就是说,「Resolved」不只是自发的认同,也是为了通过合并条件的流程动作。开源贡献者身上没有这种强制。

第三,制造标准答案的主体不同。测量 A 的「已采纳」标签不是人打的,而是 LLM(GPT-4.1 + o3-mini)看着提交推断出来的(论文说明用人工标注的子集做了验证)。测量 B 是开发者本人打的标签。

第四,工具和模型不同。测量 A 是 16 款 GitHub Action,测量 B 只有 Qodo PR-Agent 一个。

从这里能得到的实务规则很简单。看到「评论采纳率 N%」这样的数字,先问三件事:是不是只统计了已合并的 PR,标签是不是被强制打的,标准答案是谁造的。不知道这三点,这个数字就没法和别的组织的数字比较,连和你自己团队的数字都没法比较。

误报有多贵 — 腾讯的 76%

「误报占了成本的大头」这种话经常有人说,但真正测出来的数字很少。有一个来自腾讯(arXiv 2601.18844,2026 年 1 月)。

腾讯把自研的静态分析器 BkCheck 跑在广告与营销服务(AMS)事业部的代码库上。从 2024 年 9 月到 2025 年 6 月的真实告警中,筛出代码上下文完整的部分,构建了 433 条的数据集。构成是关键。

为什么会这么高?论文的解释是一个设计上的选择 — 企业用静态分析器为了不漏掉 bug,把召回率排在精确率前面。于是连不可执行的路径也保守地告警,结果误报率比开源分析器还要高。

做一下算术,成本结构就浮出来了。100 条告警里有 76 条是空的,按每条 10~20 分钟算,光是空告警就要吃掉 12.7~25.3 小时。抓到的那 24 条的价值得超过这些时间,工具才算赚。真正的损益表不是「找到了 N 个 bug」,而是这道减法。

把 LLM 当误报过滤器用会发生什么

同一篇论文接着测了一件有意思的事。问 LLM「这条告警是真的吗」,会发生什么。下面是只给基本提示词的情况。

技法模型准确率精确率召回率F1
基本提示词GPT-4o0.500.280.660.39
基本提示词Claude-Opus-40.400.260.830.40
基本提示词Qwen-3-Coder0.550.290.620.40
基本提示词DeepSeek-R10.430.270.840.41
LLM4PFA (结合静态分析)GPT-4o0.930.930.750.83
LLM4PFA (结合静态分析)Claude-Opus-40.930.830.880.85
LLM4PFA (结合静态分析)Qwen-3-Coder0.940.930.790.86
LLM4PFA (结合静态分析)DeepSeek-R10.930.840.860.85

请看基本提示词那几行的精确率:0.26 到 0.29 之间。而在这个数据集里,真实 bug 的基础比率是 105/433 = 24.2%。也就是说,对所有告警都回答「是真的」的无脑分类器,精确率就是 24.2%。四个最新模型只比基础比率好 2~5 个百分点。这更接近噪声,而不是信号。

反过来,把从静态分析中提取的路径约束(path constraint)结合进 LLM 推理的 LLM4PFA,准确率跳到 0.93~0.94。按论文的表述,它消除了误报的 94~98%。重要的是,这不是换模型换来的结果,而是改结构换来的结果。

不过,摘要里「在保持高召回率的同时」这句话,对照表格得小心读。LLM4PFA 的召回率是 0.75~0.88。意思是有 12~25% 的真实 bug 会被过滤器拦下、悄无声息地消失。论文作者们也知道这一点,所以写道:企业优先召回率,因此 Claude(0.88)或 DeepSeek-R1(0.86)的组合在实务上更合适。误报过滤器不是免费的,它是和漏报之间的交换

成本是每条告警 2.1~109.5 秒,换成钱是 0.0011~0.12 美元。和人要花 10~20 分钟相比,差着数量级。局限也很清楚 — 数据仅限腾讯的 C/C++ 代码,而且出于保密,数据集没有公开

Google 近 20 年来是怎么管理这个问题的

关于误报治理,至今最具体的公开资料来自 LLM 之前的时代:Google 的 Tricorder 论文(Sadowski 等,Communications of the ACM 2018 年 4 月号,第 61 卷第 4 期)。里面一行都没提 LLM,但就本文的主题而言,反而是这边更精准。

核心是名为实效误报(effective false positive)的定义。把论文的定义搬过来是这样 — 开发者看到那个问题却没有采取任何行动,那它就是实效误报。分析器指错了,但开发者出于可读性反正把代码改了,那就不算实效误报;反过来,分析器准确指出了真实缺陷,但开发者没看懂、跳了过去,那就是实效误报。论文把这样区分的理由写得很明白 — 决定一款工具误报率的不是工具作者,而是开发者

在此之上,Google 立了规则。

以 2018 年 1 月为准的规模也一并公开了。每天分析约 50,000 个代码评审变更,峰值时每秒跑 3 次分析。评审者每天点「Please Fix」超过 5,000 次,自动修复每天应用约 3,000 次,「Not useful」每天被点 250 次。250 除以 5,000 是 5% — 低于他们自己定的 10% 阈值。数字和政策对得上。

从这里可以带走两样东西。一是10% 这条具体的基准线已经存在,二是基准线要有关停机制才有意义。今天没有任何一家 AI 评审厂商会说「我们工具的实效误报率是 X%,超过就自动关闭检查」。

诚实地补一句:Google 的这个定义有一个后面会看到的弱点 — 实效误报是用开发者的行为来定义的,而开发者的行为并不总是质量判断。

评审机器人在杀死 PR 吗 — 噪声与 PR 弃置

最新的测量是发表在 MSR '26 的研究(arXiv 2604.03196,DOI 10.1145/3793302.3793614)。从 AIDev 数据集的 19,450 条 PR 评审评论中,提取出由真实代码评审代理(CRA)评审过的 3,109 个 PR,查看了其中处于「Commented」状态的 2,456 个。

评审者构成PR 数合并率关闭(弃置)率
CRA 单独28145.20% (127 个)34.88% (98 个)
人类单独1,17668.37% (804 个)21.60% (254 个)

差距是 23.17 个百分点;卡方检验给出接近 84 的统计量(83.0319,自由度 8),p 值小于 0.001。

接着,作者们把被弃置的 98 个 CRA 单独 PR 的评论按「信噪比」做了分类。把运行时错误、崩溃、编译失败、API 破坏、安全漏洞列为一级信号,把架构、性能、可维护性问题列为二级信号,然后计算信号评论占全部评论的比例(两名研究者独立分类,Cohen's kappa 0.75)。

数字很扎眼,但把这项研究的局限原样搬过来同样重要。先说论文自己写进「威胁」一节的。

还有一点论文没写,我来补上。测量信号比例的对象只有那 98 个「被弃置」的 PR。已合并的 127 个 CRA 单独 PR 的信号比例没有被测量。没有对照组,「低信号比例是弃置的原因」这个结论就得不到数据支持 — 因为已合并 PR 的信号比例也可能同样低。这项研究确凿显示的是两件事:「只有 CRA 评审的 PR 被弃置得更多」和「被弃置 PR 的评论大多是低信号的」;把两者连起来的那支箭头,目前还是假设。

这篇论文瞄准的业界主张也需要核实一下。论文写道:「业界报告主张,开启 CRA 后 80% 的 PR 不需要人类评论」。原始出处是 Qodo 的 2025 State of AI Code Quality 报告。

厂商的数字在测什么

直接翻开 Qodo 的报告,结构是这样的。

还有一个可以核实的事实。这份报告全文中,「false positive」「precision」「recall」这几个词出现的次数是 0。一份讨论质量的厂商代表性报告里,既没有精确率,也没有误报率。

这里有两件事要公平地补上。一件是 MSR 论文那边的夸大。「没有人类评论」和「不需要人就能处理」不是一回事 — 没有评论就被批准的 PR 也是人看过的。批评厂商主张的论文,把那个主张稍微吹大了一点再引用。两边都得小心读。

另一件是给 Qodo 的信用。Qodo 在那份报告之外另行运营着一个公开了方法论的基准测试(2026 年 2 月 4 日公开,3 月 12 日修订)。

Qodo 基准测试 — 有方法论是一回事,值得信任是另一回事

方法是这样的。拿来实际合并过的生产级开源 PR,用 LLM 注入缺陷。先按仓库提取最佳实践规则、种入合规性违例,再额外种入 1~3 个逻辑错误、边界情况、竞态条件、资源泄漏之类的功能性 bug。对就这样造出的 100 个 PR、580 个问题,让 8 款工具(Qodo + 竞品 7 款)以默认设置各跑一遍,用 LLM-as-a-judge 评分。基准测试仓库确实公开在 GitHub 上(cal.com、tauri、redis、Ghost、aspnetcore 等的 fork)。

结果是 Qodo 以 F1 60.1% 排名第一。这是厂商自测。

这个数字该怎么读。首先,光是公开了方法论和数据这一点,就已经比大多数竞品要好。但设计上有结构性的问题。

即便如此,这个基准测试里最值得引用的事实是另一个:在自己设计、自己评分的基准测试里,第一名的 F1 是 60.1%。这个数字和那句营销话术(「80% 的 PR 不需要人」)出自同一家公司。而且按照 Qodo 自己的观察,其余工具大多聚在精确率高、召回率极低的那一头 — 只指出最显而易见的问题、其余时候保持安静的策略。

测量本身崩塌的地方 — 「已解决」不是标准答案

到目前为止的测量,几乎全部依赖「开发者有没有对评论做出反应」。Google 的实效误报如此,Gan 等的采纳率如此,Cihan 等的 73.8% 也如此。那么,这个标签本身可信吗。

2026 年 4 月的一篇论文恰好验证了这一点(arXiv 2604.24525)。对象是前面出现过的 Beko 的同一批数据。对开发者标注为 fixed/wontFix 的 2,604 条机器人评论(fixed 1,733 条约 66%,wontFix 871 条约 34%),分别以二元和李克特(Likert)两种方式运行 G-Eval 和 LLM-as-a-Judge,测量它们与开发者标签的一致程度。

模型G-Eval 二元G-Eval 李克特Judge 二元Judge 李克特
GPT-5.20.450.590.440.58
GPT-4.1-mini0.480.620.570.61
Gemini-2.5-pro0.510.570.530.55

一致率 0.44~0.62。最高成绩是 G-Eval 李克特 + GPT-4.1-mini 的 0.62。有意思的是,最新最强的 GPT-5.2 并不是最好的那个。

那套最高配置的细分指标,是本文最重要的一段。

指标GPT-5.2GPT-4.1-miniGemini-2.5-pro
一致率0.590.620.57
F10.720.760.68
精确率0.670.660.67
召回率0.780.900.69
MCC-0.0020-0.05900.0106

F1 0.76 看着像模像样,一致率 62% 看着也不坏。可是 MCC(马修斯相关系数)全部在 0 附近,有的还是负数。MCC 是校正了类别不平衡的相关系数,为 0 意味着和标准答案毫无相关。照论文的原话说:只看一致率和 F1,会高估评判者的可靠性。

拿论文报告的数字直接做算术,事情会更清楚。标准答案的 66.5% 是「fixed」,所以对每条评论都无条件回答「有用」的无脑评判者,成绩会是这样。

无脑基线 (永远回答「有用」):
  精确率 = 1733/2604      = 0.665
  召回率 = 1.0
  F1     = 2(0.665)(1.0)/(0.665+1.0) = 0.799
  一致率 = 0.665
  MCC    = 0

成绩最高的 LLM 评判者 (G-Eval 李克特 + GPT-4.1-mini):
  精确率 = 0.66   召回率 = 0.90
  F1     = 0.76   一致率 = 0.62   MCC = -0.059

无脑基线在 F1 上(0.799 对 0.76)、在一致率上(0.665 对 0.62)都赢过了最好的 LLM 评判者。这是我用论文的公开数字算出来的,不是论文明说的句子。不过它和论文特意报告 MCC 的理由(「因为数据集不平衡」)指向完全相同。

更根本的问题是为什么会这样。论文认为,开发者标签本身就不是标准答案。

论文的结论是这样 — 开发者的行为(解决/无视)反映的不只是评论质量,还叠加了上下文约束、优先级决策和工作流动力学,因此不能当成客观的标准答案。

这就绕回到 Google 的定义。Google 的实效误报被定义为「开发者没有采取行动」。Beko 研究显示,这个定义把组织压力也一并测了进去。这不是说 Google 的定义错了 — Google 是为了测开发者感知才有意那样定义的,对于决定要不要关掉一款工具,它恰恰是对的指标。只是这个数字不能拿去做组织间比较,也不能读成「准确率」。

到这里,本文整体的骨架就露出来了。廉价地、自动地测量评审评论有用性的方法,目前还不存在。代理指标被组织压力污染,LLM 评判赢不了基础比率。所以「AI 评审对我们团队有没有帮助」这个问题,眼下除了抽样让人亲自去读之外,没有可信的办法

那么,团队实际该怎么配置

综合公开的证据,跑得顺的配置有共同点。下面每一条都以上文引用的测量为依据。

1. 配置得窄。通用的「帮我评审这个 PR」最糟糕。腾讯那边基本提示词 LLM 的精确率停在基础比率水平(0.26~0.29 对 0.242),说的就是这件事。反过来,结合静态分析的路径约束、收窄判断范围的 LLM4PFA 升到了准确率 0.93~0.94。这是改结构而不是改模型的结果。

2. 把评论钉在代码位置上。Gan 等的测量里,hunk 级 Action 的采纳率(6.5~19.2%)一贯高于文件级 Action(0.9~4.2%)。同一研究还发现,简洁且带代码片段的评论被采纳得更好。

3. 手动触发好过自动触发。同样是 Gan 等的结果。人主动请求时,评论采纳率更高。不请自来硬塞的反馈没人好好读。

4. 定好误报预算,超了就关。Google 的 10% 是唯一被验证过的基准线。重要的不是数字,而是关停机制 — 「Not useful」按钮、自动路由给负责团队、超过阈值就停用。这三样不齐,10% 就只是幻灯片上的一个数。

5. 抽样让人来读。照搬 Beko 后续研究的建议 — 把自动分数当弱信号而不是标准答案,只用在决定先检查什么的分诊(triage)上,别用在批准/否决的决策上。而且每次换模型或提示词都要重新评估(同一篇论文:一致率随模型和评分标准在 0.44 到 0.62 之间晃)。

6. 不把人抽走。MSR 研究的实务建议是:CRA 应当补强而非替代人类评审者。同一批数据里,人参与的混合评审(61.09~67.99%)比起 CRA 单独(45.20%),要接近人类单独(68.37%)得多。

什么时候不该用

诚实地列出不该用的情况。

决策规则

我不打算用「视情况而定」收尾。请这么做。

  1. 先从一条窄检查开始。安全规则也好、代码风格也好,找标准答案能被机械地确认的那种。用通用评审器起步的话,头两周的噪声就会耗尽团队的信任,然后就结束了。
  2. 开启之前把误报预算写成文档。把 Google 的 10% 当默认值。要用别的数字,就把依据写下来。
  3. 关停机制要在同一天建好。相当于「Not useful」的按钮、负责人、超过阈值就停用的规则。没有这个,第 1、2 条都是空谈。
  4. 不要用自动分数下判断。花 4 周随机抽 50~100 条评论,让人亲自读、标上有用/没用。那份样本是你唯一可信的数据。如果想搭 LLM 评判流水线,先确认那个评判者能不能赢过多数类基线。在 Beko 数据上它没赢。
  5. 用缺陷而不是速度来论证。时间节省没有证据。用抓到的缺陷数乘以它流入生产环境时的代价,再减去开发者读噪声耗掉的时间。这个数是正的,才有继续开着的理由。
  6. 扩大范围要等第 5 条得数为正之后

压缩成一句话就是:AI 代码评审当「评审者」用会失败,当「窄且随时可关的检查」用才值回成本

结语

本文开头的问题是「AI 代码评审能不能用」。把公开的测量值全摆到一起看,答案不是「能/不能」,而是下面这样。

证据很薄。只是薄得有特定的形状。研究不算少,方向也大体一致 — 开源上 AI 评论采纳率(0.9~19.2%)远不及人类(60%),静态分析告警的 76% 是空的,只有评审机器人光顾的 PR 被弃置得更多。缺的是由与厂商无关的一方测得的、通用 AI 评审器的生产环境精确率与误报率。占着那个位置的,是厂商在自家基准测试里给自己评出的第一名 F1 60.1%、被组织压力污染的代理指标,以及连基础比率都赢不了的 LLM 评判者。

所以下次看到「AI 评审器抓住了 N% 的 bug」的幻灯片,只问两件事就够了。用的是什么数据集,以及误报率是多少。两个问题有一个没有答案,那个 N% 就什么都没说。

而且这两个问题不是只拿去问厂商的。4 周后出现在你们团队仪表盘上的数字,也要照样问一遍。

参考资料

评论

还没有评论。

登录后即可发表评论