智测 OpenQA

行业与实践研究与基准测试

代码评审多找缺陷,噪声也一起上来

智测团队 · OpenQA(openqa.cn)阅读约 12 分钟

代码评审没有编译那种通过或失败。CR-Bench 从 SWE-Bench 抽出 584 条可在评审时发现的真实缺陷,核验子集 174 条。单次评审的信噪比更高,GPT-5.2 为 5.11,但召回只有 27.01%。逼它再找一轮,召回到 32.76%,信噪比降到 1.95。

本文目录

本文是论文 CR-Bench: Evaluating the Real-World Utility of AI Code Review Agents(arXiv:2603.11078)正文第 1 节至第 9 节的中文译文,由智测团队翻译。附录里的提示词未逐条展开。正文保留了基准规模、分类比例和四种智能体配置的精确率、召回、有用率和信噪比。ReviewTestFuse 是《Automated Software Engineering》上的期刊论文,公开页面打不开全文,因此本批改译这一篇。

1 引言

代码评审很难自动化。它不像编译或单元测试那样有公认的通过或失败信号,也很难验证。难处有两层。第一,评审意见可以是文档、风格或重构,不同团队的做法很主观。第二,同一条意见可以有多种改法,没有唯一正确答案。

问题复杂,代码评审智能体就带上偏差。作者观察到一种根本权衡:要么优先精确率,冒着漏掉关键漏洞;要么优先召回,代价是意见吵、不好执行。工程师对正在运行的智能体,例如 CodeRabbit 和 Gemini Code Assist 的反馈是:意见里噪声一多,就会妨碍开发效率,阻碍智能体进入真实评审。但躲开噪声,又可能漏掉关键缺陷。因此,系统开发和比较代码评审智能体,需要一个标准化、有原则的基准。

现有基准常有两个限制。第一,把客观的逻辑错误和主观的风格偏好混在一起。风格、文档和格式重要,但往往更适合交给静态分析或 lint,而不是昂贵的大模型推理。第二,很多基准依赖合成题或小规模问题,抓不住大仓库里的多文件依赖。作者认为,有效的代码评审智能体应优先做识别缺陷的评审,也就是针对功能、性能、可靠性或安全回归的评审。聚焦这一子集有三个理由:未处理的缺陷会直接引入系统故障;缺陷检测更客观,更适合自动评测;风格或结构改动往往主观,而且随项目、团队和工作组变化。

本文提出 CR-Bench,用来评测代码评审智能体的推理和缺陷检测。另外提出 CR-Evaluator:给它一个拉取请求,以及任意黑盒智能体生成的评审,它判断这些评审的表现,以及对开发者有多有用。CR-Bench 里的拉取请求,重要的是找出底层缺陷。但一个通用评审智能体还会给出额外意见,这些意见可能有用,也可能没用。因此除了找缺陷的精确率、召回和 F1,还引入两个指标:有用率,以及信噪比。它们用来衡量生产工作流里智能体的效用和开发者是否愿意接受,从而理解准确性、可信度和事实性。

实验评了两种智能体。一种是单次大模型:把拉取请求的 diff 放进上下文,直接返回评审。另一种是 Reflexion 智能体:先争论,再迭代地增加或删掉评审,然后才给建议。实验表明,如果逼智能体多找缺陷(像 Reflexion),噪声上升;如果放得太松(像单次模型),有些缺陷会被漏掉。好的智能体应落在这两者之间很窄的一段上。

贡献有三条。CR-Bench:面向真实世界、可在评审时预防的缺陷,并标上缺陷类别、影响和严重度。CR-Evaluator:不只评准确率,还评可信度、开发者可接受性和事实性。用两个前沿大模型评两种互补的提示范式,比较评审覆盖和完整性之间的权衡。

2 相关工作

表 1 比较自动代码评审评测基准。列包括任务数、是否含多个 diff、是否有完整拉取请求上下文、是否分类、是否聚焦缺陷,以及评测方式。

方法任务数多个 diff完整拉取请求分类聚焦缺陷评测
Tufano 等,20211718否否否否精确匹配或 BLEU
Tufano 等,2022147533否否否否精确匹配或 BLEU
Thongtanunam 等,2022约 1.7 万否否否否精确匹配
Li 等,20225.4 万否否否否CodeBLEU
Zeng 等,2025b1000是是是否大模型裁判(精确率、召回、F1)
CR-Bench584是是是是大模型裁判(精确率、召回、F1、有用率、信噪比)
CR-Bench-Verified174是是是是同上

代码评审智能体从简单的代码精炼和评论生成,发展到能多步推理、跨文件交互和使用工具。商业平台如 CodeRabbit、Cursor Bugbot 会分析架构影响、建议复杂改动,甚至对接外部项目管理工具。前沿模型如 Gemini Code Assist 和 Claude Code 也有评审工具。开源的 PR-Agent 把这些能力进一步放开。它们已经从实验室工具变成生产组件,因此需要正确评测,也就需要高质量基准。

早期方法训练循环网络和 Transformer,把有缺陷的方法翻译成修好的方法。这些工作停在方法级,依赖代码抽象或截断,丢掉跨文件上下文,并用 BLEU 这类文本相似度,抓不住功能正确性。CodeReviewer 专门为 diff 片段预训练,但仍限于局部上下文和静态评测。SWR-Bench 提供完整拉取请求上下文,并用大模型当裁判来评评论。但它主要对照人工核验过的改动点算命中,因此会把很主观的改动也算进去。CR-Bench 则只聚焦客观的缺陷检测,并带完整拉取请求上下文。

3 形式化

代码评审是一种异步的同行评估,用来评估基线代码状态 B 的质量,并建议改进。它从一个拉取请求开始。拉取请求是把一串代码修改合进目标代码库的提案。形式上,拉取请求是三元组 (C, Δ, M)。C 是一组离散提交,Δ 是累计代码 diff,M 是元数据,例如标题、描述和作者。每个提交是仓库状态的一个密码学快照。

评审过程的输出是 m 个评审块。每个块有自然语言建议 r_n,指出具体缺陷或改进,以及代码级的解决办法 r_δ。智能体的任务是输入 (拉取请求, 基线状态),生成 m 条评审。

偏差–方差权衡。文档检查、编码风格和结构一致性往往很主观。一次改动可以有多种合法解释,仓库越大越复杂,变数越大。过保守的智能体会漏掉重要问题,过宽松的会产出过多或低质量反馈。这是自动代码评审的中心设计难题。

范围。本文优先做识别缺陷的评审,针对功能、性能、可靠性或安全回归。理由与引言相同:未处理的逻辑错误会直接引入故障;缺陷检测更客观;风格偏好更适合 lint 或人的判断。

4 CR-Bench

图 2 概括数据集和评测器。CR-Bench 把真实软件缺陷变成带完整拉取请求上下文的客观评审基准,并有类别、影响、严重度三个维度。CR-Evaluator 同时测性能和开发者是否接受。

数据集从 SWE-Bench 导出。SWE-Bench 含仓库规模的真实 GitHub Issue,以及修好它们的拉取请求。代码评审看的是拉取请求:评审者事先不知道缺陷在哪、会引入什么问题。构建时做了若干校验,保证纳入的缺陷在代码评审里是现实可发现的。每条实例按缺陷类别、影响和严重度标注。两个变体:从 SWE-Bench 来的 CR-Bench,以及从 SWE-Bench Verified 来的 CR-Bench-Verified。后者还经作者人工核验质量。

4.1 从 SWE-Bench 变换过来

算法 1 的过程如下。对每条实例,检出基线提交,对 SWE-Bench 补丁里被删掉的那些行做 git blame,抽出加入这些行的提交编号。再用 GitHub 接口取与该提交关联的拉取请求。若关联的拉取请求不是恰好一个,就丢掉,因为问题不可能在单次拉取请求里被识别。然后用大模型判断缺陷在当初的评审里是否可发现。可发现是指:缺陷来自当时引入的毛病,通过逻辑检查、边界测试或遵守接口契约,可以合理地在原始评审中看出来。不可预防的缺陷丢掉。最后把 SWE-Bench 的问题描述改写成缺陷描述,作为评审评论。用户也可以再按自己的评测习惯改写。

这套做法不会穷尽某个拉取请求上的全部问题。优先的是高质量、已核验、没有被错误纳入的缺陷。

4.2 分类

三个桶:类别、影响、严重度。类别是缺陷的根因,影响是缺陷可能造成的后续效应,严重度是对系统影响的程度。类别采用 Beizer 的分类:结构缺陷;接口、集成与系统缺陷(IIS);需求、特性与功能缺陷(RFF);数据缺陷;并发缺陷;内存缺陷;安全缺陷;编码缺陷。影响采用 ISO/IEC 25010:功能适合性、性能效率、兼容性、可用性、可靠性、安全性、可维护性、可移植性。严重度分为低、中、高。标签由大模型根据问题描述和修复补丁生成,提示里写明每个桶的定义。统计在第 7.1 节。

5 CR-Evaluator

评测器用大模型当裁判,零样本把候选评审模型的每条评审,对照历史上的黄金缺陷分成三类。输入是已知缺陷描述、最终修复改过的文件,以及候选评论。三类互斥,合起来覆盖全部评审。

缺陷命中。准确指出或直接关系到地面真值里描述的那个逻辑错误。

有效建议。建设性反馈,例如风格改进、性能优化或边界处理。技术上站得住、也重要,但与地面真值里的主要缺陷无关。

噪声。事实错误、与代码改动无关,或无足轻重,常常是模型幻觉。

召回衡量缺陷覆盖:全部缺陷命中数除以全部缺陷数。

精确率衡量预测准确性:全部缺陷命中数除以全部评审数。

F1 是二者的调和平均。

有用率把有效建议也算进收益:分子是缺陷命中加有效建议,分母是全部评审。有用率高于精确率,因为它计入发现缺陷之外的好处。

信噪比是有益信号除以噪声:(缺陷命中 + 有效建议)除以噪声条数。高信噪比是开发者信任的主要代理,量化可执行信号相对干扰性幻觉的比例。它用来诊断那些靠大量输出换高召回的智能体。比例低会让开发者疲劳,最终在生产里放弃工具。

6 实验

两种智能体。

单次语言模型。零样本,根据拉取请求的 diff 和描述,一次找出潜在缺陷、逻辑问题和漏洞。要求简洁的 JSON,标出文件路径和行号,不再迭代。它松散地基于 PR-Agent,用来看模型的原始直觉。

Reflexion 智能体。按 Reflexion 框架,先做初始分析,再迭代自我改进。提示明确要求发现漏掉的缺陷(假阴性)并精炼已有评论。优先彻底性和诊断准确性,在定稿前再看一遍代码,找被忽略的逻辑错误、安全缺陷或资源泄漏。

两个智能体都用 GPT-5.2 和 GPT-5-mini,跑在 CR-Bench-Verified 上。当裁判的大模型是 Claude Sonnet 4.5。

7 结果

7.1 数据集统计

最终语料:CR-Bench-Verified 174 条,CR-Bench 584 条高保真拉取请求任务。锚定在 django/django、sympy/sympy,以及 astropy/astropy、scikit-learn/scikit-learn 这类成熟、长期维护的代码库。表 3 是每条实例的平均统计。

数据集修复行数拉取请求评论数描述长度
CR-Bench10.2841.03906.63
CR-Bench-Verified8.6935.83893.59

图 3(a) 中,Verified 子集明显偏向结构缺陷,占 79.9%。这些是代码安排或逻辑流上的复杂错误,简单静态分析常常抓不住。主要影响是功能适合性和可靠性。93.1% 的缺陷被标为中或高严重度。高严重度主要连到可靠性和功能适合性,若被合并,很可能造成系统回归。174 条看起来比表 1 里其他数据集少,但重点是质量和逻辑边界上的加压评测。这个子集里有些类别和影响是缺的。

扩到完整的 584 条后,统计功效增加,高风险性质还在。图 3(b) 里,90.2% 的缺陷被标为中、高或严重。表 2 的严重度只有低、中、高,图 3(b) 的正文写成「中、高或严重」。两处用词不完全一样,按各自原文照录。完整集里出现了 Verified 子集缺少的可维护性、安全性等影响,各类比例也有小幅调整。

7.2 性能

表 4 是 CR-Bench-Verified 上两种技术、两个模型的比较。

智能体模型召回精确率F1有用率信噪比
单次GPT-5.227.01%3.56%6.30%83.63%5.11
单次GPT-5-mini18.39%3.51%5.90%74.29%2.89
ReflexionGPT-5.232.76%5.10%8.83%66.10%1.95
ReflexionGPT-5-mini27.59%3.19%5.72%47.72%0.91

智能体之间的比较。单次方法和 Reflexion 之间,是发现覆盖和有用反馈密度的权衡。单次方法的信号更完整,尤其是 GPT-5.2。信噪比 5.11,误报少,开发者信任更高。代价是召回只有 27.01%,单次往往漏掉细微的跨文件错误。Reflexion 被要求去找假阴性,把 GPT-5.2 的召回提到 32.76%。这更适合安全关键审计或高风险重构,宁可花时间也要找出那根针。但信噪比降到 1.95。正文写成「信噪比下降 1.95」。表 4 的两端是 5.11 和 1.95,差值是 3.16,不是 1.95。译文以表上的两个数为准。另外,单次智能体精确率更低,有用率却更高。作者认为这是因为 Reflexion 的结构更深,更盯着找缺陷。

模型规模。GPT-5.2 在 Reflexion 的压力下仍能把信噪比维持在 1.95。GPT-5-mini 的信噪比掉到 0.91,说明反思时逻辑落地可能不稳。它单次时信噪比还有 2.89,一上 Reflexion 就塌到 0.91。较小模型配 Reflexion,幻觉可能更高:迭代追问要找出更多问题,小模型可能不敢说「没有更多问题」,于是用噪声来回应。

7.3 分类上的召回

按根因。四种配置都比较能找出结构缺陷和 IIS(接口、集成与系统)缺陷。内存问题的召回对所有智能体都是 0。作者认为这说得通,因为内存问题通常要靠执行时的系统追踪,而不是只看 diff。Reflexion 的最大增益在结构和数据类。对 GPT-5.2,迭代重读复杂逻辑流,能揭出初次启发式扫描漏掉的更深层算法错误。GPT-5-mini 在 RFF、IIS 和结构缺陷上有明显天花板,单次时更差。数据类缺陷上,只有单次 GPT-5.2 的表现还可以。

按下游影响。对照 ISO/IEC 25010,所有配置在性能效率和可靠性上最高。这类缺陷常有明显代码特征,例如低效循环或缺少错误处理,和前沿模型的模式匹配对得上。可用性和功能适合性上有下跌。这些缺陷常常需要外部环境知识或上游依赖,而拉取请求的 diff 里没有。这是当前封闭上下文评审智能体的根本限制:看不到更广的系统状态。兼容性问题上,除了单次 GPT-5.2,其他配置都较好。

按严重度。所有智能体对高严重度缺陷的召回都明显高于低或中。GPT-5.2 的 Reflexion 在高严重度上发现率最高,说明严重缺陷需要推理深度。低严重度在所有范式里召回最低。智能体更适合当重大回归的安全网,不太适合抓开发者也许觉得可以接受的小逻辑毛病。

8 结论

CR-Bench 用来缩小合成基准和真实自动代码评审之间的差距。它把 SWE-Bench 里高保真的软件失败变成评审语料:174 条经核验,584 条标准。智能体要在事先不知道缺陷的情况下做盲审。CR-Evaluator 把评测从精确率、召回、准确率,延伸到开发者视角的有用率和信噪比。

系统评测揭出一种设计权衡。Reflexion 显著提高发现召回,同时损害信号完整性。结论正文写成「信号完整性付出陡峭代价,同时信噪比高」。表 4 里 Reflexion 的信噪比是下降的,GPT-5.2 从 5.11 到 1.95,GPT-5-mini 从 2.89 到 0.91。这个效应在 GPT-5-mini 这类轻量模型上最明显。CR-Bench 和 CR-Evaluator 一起,为真实代码评审智能体的评测打下设计基础。

9 未来工作

本文只考虑了四种基于大模型的配置。未来计划评更多模型和智能体架构,并探索 GRPO 等后训练方法。还打算把 CR-Bench 扩到更多编程语言和领域专用框架,看语言约束如何影响信噪比和召回画像。

觉得有用,转给同事

微信扫码

用微信扫一扫,在手机上打开后即可转发。

用 RSS 订阅

提交勘误