引言
在人工智能飞速发展的版图中,代码生成已成为“杀手级应用”之一。像 GitHub Copilot 和 ChatGPT 这样的工具彻底改变了开发者编写软件的方式,能够在几秒钟内生成函数、类甚至整个应用程序。然而,这种能力引入了一个关键却常被忽视的瓶颈: 评估 。
我们如何知道 AI 写的代码是否真的好用?
历史上,我们主要依赖两种方法: 针对单元测试运行代码 (但这要求先编写测试) ,或者将代码文本与“正确”的参考方案进行比对 (使用 BLEU 等指标) 。这两种方法都有严重的局限性。现实世界的任务往往缺乏测试用例,而正确的代码可能有成千上万种写法,这使得文本比对变得不可靠。
CODEJUDGE 应运而生。
在最近的一篇论文中,研究人员介绍了一种新的框架,它从根本上改变了我们给 AI 生成的代码打分的方式。CODEJUDGE 不再依赖死板的测试用例或肤浅的文本匹配,而是利用大语言模型 (LLM) 自身的推理能力。通过强制评估模型进行“慢思考”——即模仿人类代码审查的逐步分析过程——CODEJUDGE 在评估代码正确性方面达到了最先进的性能。
在这篇文章中,我们将剖析当前评估指标的局限性,探索 CODEJUDGE 的“慢思考”架构,并查看数据证据,了解为什么这可能代表了自动化代码审查的未来。
评估瓶颈
要理解为什么需要 CODEJUDGE,我们需要先看看为什么现有的方法正在失效。
测试用例的问题
检查代码的黄金标准是 pass@k——生成 \(k\) 个解决方案,看是否有任何一个能通过一套单元测试。虽然准确,但这既昂贵又死板。它要求人类为每一个问题编写全面的测试用例。在网页抓取、UI 设计或对象序列化等领域,搭建“测试环境” (模拟对象 mocks、存根 stubs、环境配置) 往往比编写实际代码还要难。如果你没有测试用例,就无法使用这个指标。
文本匹配的问题
当没有测试用例时,研究人员通常会退而求其次,使用像 BLEU 或 CodeBLEU 这样的基于 Token 的指标。这些指标将 AI 生成的代码与“基准真相 (Ground Truth) ”参考代码进行比较,根据重叠的单词或 n-gram 计算相似度。
问题在于?代码不是自然语言。
考虑一个简单的任务: “对单词列表进行排序。”
- 方案 A 可能使用
for循环和冒泡排序。 - 方案 B 可能使用内置的
.sort()方法。 - 方案 C 可能使用函数式的 Map/Reduce 方法。
这三种在语义上都是正确的,但在文本上看起来完全不同。基于 Token 的指标可能会查看方案 C,发现它与方案 A (参考代码) 共享的单词很少,因此将其判定为“错误”。反之,它可能会给那些看起来像参考代码但包含关键漏洞 (如无限循环) 的代码打高分。
研究人员清楚地强调了这一失败之处。他们将各种指标与不同代码片段的人类判断进行了比较。

如上方的 Table 1 所示,请看 Fig. 1(e) 这一列。这代表“实现方式不同但正确的代码”。
- BLEU 给出的分数为
0.231(非常低) 。 - CodeBLEU 给出的分数为
0.851。 - CODEJUDGE (本论文提出的方法) 正确地将其识别为
1(正确) 。
相反,看看 Fig. 1(b) , 即“部分正确的代码”。传统指标给出了非常高的分数 (例如,CodeBERTScore 给出了 0.990) ,基本上未能惩罚错误。CODEJUDGE 正确地将其识别为有缺陷 (根据模式不同,评分为 0 或 0.50) 。
CODEJUDGE 解决方案: 系统 2 思维
CODEJUDGE 的核心洞察在于,评估代码需要推理,而不仅仅是匹配。它从丹尼尔·卡尼曼的《思考,快与慢》这一概念中汲取灵感。
- 快思考 (系统 1) : 直觉的、即时的。 (例如,“这代码看起来差不多是对的。”)
- 慢思考 (系统 2) : 分析的、逻辑的、逐步的。 (例如,“让我们追踪一下变量
x在循环中的变化,看看它是否会导致索引错误。”)
现有的基于 LLM 的评估器往往陷入“快思考”陷阱。它们被提示简单地“给这段代码打 1 到 5 分”,这助长了幻觉和浅层评估。CODEJUDGE 通过两个独特的工作流,强制 LLM 使用系统 2 思维。

如 Figure 2 所示,该框架将评估分为结构化的步骤。让我们分解这两种主要的操作模式。
1. 先分析再总结 (二元评估)
这种模式旨在回答一个简单的问题: 代码正确吗? (是/否) 。
CODEJUDGE 不会立即要求答案,而是将任务分解:
- 分析子任务: 模型会收到任务描述和生成的代码 (可选择性地提供参考方案) 。它被指示执行逐步分析。它必须识别所需的功能并逐行检查逻辑。
- 总结子任务: 模型获取其在第 1 步的分析结果,并将其总结为最终的二元决定。
这模仿了人类高级工程师进行代码审查的方式。他们不会立刻说“LGTM” (看起来不错) ;他们会先解释为什么它看起来好或坏,然后做出决定。这一中间步骤显著减少了误报。
2. 分类学引导的故障定位 (部分正确性)
现实世界的编码并不总是非黑即白的。有时代码大体正确,但遗漏了一个边缘情况。为了处理这种情况,CODEJUDGE 使用了一种更细粒度的方法,称为分类学引导的故障定位 。
研究人员开发了一套常见编码错误的分类体系,并按严重程度进行了分类。

如 Table 2 所示,错误是有权重的:
- Negligible (可忽略) : 缺少导入或轻微的风格问题。 (这些不应该严重影响分数) 。
- Small (轻微) : 未能处理边缘情况。
- Major (重大) : 导致结果错误的逻辑错误。
- Fatal (致命) : 语法错误、未定义的变量或导致代码无法运行的幻觉。
在这种模式下,LLM 被指示从列表中识别特定的不一致之处。最终得分不是随意的“5 星好评”,而是根据发现故障的严重程度通过数学公式计算出来的。

评分公式 (如上所示) 从满分开始,并根据错误类型减去加权后的惩罚分。这确保了“致命”错误 (如调用不存在的函数) 比“轻微”错误 (如缺少输入验证) 对分数的惩罚要重得多。
实验结果
研究人员在一系列数据集 (HumanEval-X, APPS, CoNaLa, BigCodeBench) 上对 CODEJUDGE 进行了评估,并将其与传统指标和其他基于 LLM 的评估器 (如 ICE-Score) 进行了比较。
与人类判断的相关性
这里成功的首要指标是相关性 。 如果人类评委说“这代码是好的”或“这代码是坏的”,自动化指标是否认同?

Table 12 提供了 HumanEval-X 数据集上的准确率快照。
- VANILLA (即直接问 GPT-3.5 “这正确吗?”) 根据语言不同,准确率大约在 60-70%。
- CODEJUDGE 显著提升了这一点,在使用高端模型时,Python 的准确率达到 81.57% , Java 达到 81.31% 。
特别令人印象深刻的是 “w/o REF” (无参考) 这几行。即使在没有展示正确答案的情况下,CODEJUDGE 也能达到 73-80% 的准确率。这证实了模型实际上是在对代码逻辑进行“推理”,而不仅仅是与标准答案作弊条进行比对。
效率与模型大小
人们可能认为需要庞大的 GPT-4 或 Claude 3.5 Sonnet 才能进行这种复杂的推理。然而,CODEJUDGE 证明即使在开源模型上也同样高效。

Table 6 揭示了一个有趣的发现。当使用较小的 Llama-3-8B-Instruct 模型时,CODEJUDGE 在 CoNaLa 数据集上实现了 0.523 的 Kendall’s Tau 相关系数。这与使用庞大得多的 GPT-3.5 Turbo 的其他方法相比具有竞争力,甚至往往更好。
这意味着提示词的结构 (“慢思考”工作流) 与模型的原始智能同样重要。通过引导较小的模型逐步思考,你可以胜过那些仅做瞬间判断的大型模型。
提示工程 vs. 框架设计
CODEJUDGE 仅仅是花哨的提示工程吗?研究人员将他们的方法与标准的思维链 (Chain-of-Thought, CoT) 和少样本提示 (Few-Shot prompting) 进行了比较。

Table 7 显示,简单地加上“让我们一步步思考” (CoT) 或提供示例 (Few-shot) 并不能产生与完整 CODEJUDGE 框架相同的结果。
- 标准 CoT 准确率: 77.65%
- CODEJUDGE 准确率: 81.63%
研究人员指出,标准的 CoT 经常导致模型幻想出一个代码“修复版”,然后对修复后的版本而不是原始版本进行评分。CODEJUDGE 对“分析”和“总结”的严格分离防止了这种偏离。
为什么这很重要
CODEJUDGE 的意义不仅仅在于学术基准测试。
1. 评估“非受控”任务: 目前,我们只能在存在测试用例的 LeetCode 风格问题上可靠地测试 AI 编码智能体。CODEJUDGE 打开了在开放式任务上评估智能体的大门——比如“编写一个脚本分析这个 CSV 文件”或“为一个登录表单创建一个 React 组件”——而在这些任务中,基准参考代码可能并不存在。
2. 人机协同调试: 因为 CODEJUDGE 会生成分析轨迹 (“分析”步骤) 和错误分类 (“故障定位”步骤) ,所以它不仅仅是给出一个分数,它还提供反馈。这可以集成到 IDE 中,向开发者解释为什么他们的代码 (或 AI 的代码) 可能是错的,指出具体的逻辑缺陷或遗漏的边缘情况。
3. 降低成本: CODEJUDGE 能够在 Llama-3-8B (一个小到可以在消费级硬件上运行的模型) 上表现良好,这表明高质量的代码评估不需要昂贵的大型专有模型 API 调用。
结论与未来展望
评估生成的代码长期以来一直是 AI 编程领域“房间里的大象”。我们拥有能比我们阅读速度更快地编写代码的模型,但我们一直难以自动地为这些工作打分。
CODEJUDGE 证明了解决方案不一定是更好的测试套件或更花哨的字符串匹配算法。解决方案是元认知——利用 AI 来批判其自身。通过强迫模型慢下来,分析需求,分类错误,然后做出判断,我们可以实现与人类专业知识紧密一致的评估系统。
尽管仍存在局限性 (论文指出模型在 APPS 数据集中极其复杂的竞赛级逻辑上仍有困难) ,但像 CODEJUDGE 这样的框架是迈向自主软件工程智能体的必要一步,这些智能体不仅能编写代码,还能验证代码。
](https://deep-paper.org/en/paper/2410.02184/images/cover.png)