本站内容由 AI 生成,可能存在错误。如发现问题,欢迎到 GitHub Issues 反馈。

代码 Benchmark

代码 Benchmark

更新于 2026-04-23

开篇:模型说自己能写代码,从函数补全到修 GitHub issue,这些能力怎么评估?

当 OpenAI 发布 Codex 并声称”HumanEval pass@1 达到 28.8%“时,代码生成评估从此有了标准范式。三年后,当 Anthropic 和 OpenAI 在 SWE-bench Verified 上激烈竞争,最优系统的 resolved rate 已超过 70%,评估的含义已经从”能否写出一个函数”演变为”能否修复真实开源项目的 bug”。

上一篇文章中,我们深入了知识与推理 benchmark。现在进入代码评估——LLM 评估中最接近”实际生产力”的维度。本文将回答:

  1. 从 HumanEval 到 SWE-bench,代码 benchmark 经历了怎样的演进?
  2. pass@k 到底是什么意思?它是如何计算的?
  3. HumanEval 已经饱和了,为什么 HumanEval+ 还能发现问题?
  4. SWE-bench 的 Agent 框架到底在评什么?为什么同一个模型在不同框架下分数差异巨大?

演进脉络:从函数补全到项目级软件工程

代码 benchmark 的演进可以用一条清晰的主线串联:评估粒度不断提升

2021 年,HumanEval 和 MBPP 建立了函数级代码补全的评估标准。模型接收函数签名和 docstring,生成函数体,通过测试用例验证正确性。这是最基础的”能写代码吗?“测试。

2023 年,HumanEval+ 发现原版 HumanEval 的测试用例严重不足——增加约 80 倍测试用例后,很多”通过”的代码其实是错误的。这揭示了一个关键问题:评估质量取决于测试质量

2024 年,评估维度发生了质的飞跃。SWE-bench 将粒度从单个函数提升到整个代码仓库:模型需要理解真实开源项目、定位 bug、生成跨文件修复。同年,LiveCodeBench 和 BigCodeBench 分别从动态更新复杂 API 调用两个方向拓展了评估覆盖。

代码 Benchmark 演进时间线
点击节点查看详情,连线表示继承关系
20212022202320242025HumanEvalpass@1 >90%MBPPpass@1 >85%HumanEval+pass@1 ~85%SWE-benchresolved ~50%SWE-bench Verifiedresolved ~77%LiveCodeBenchpass@1 ~65%BigCodeBenchpass@1 ~62%

交互说明:点击任意 benchmark 节点查看详情。连线表示继承关系——例如 HumanEval+ 继承自 HumanEval,BigCodeBench 继承自 MBPP 的”广覆盖”理念。注意 2024 年的爆发式增长:四个新基准同时出现,反映了社区对更真实评估的强烈需求。

评估方式的分化

代码评估方式经历了三代演进:

第一代:文本匹配(已淘汰)

早期尝试用 BLEU(机器翻译指标)评估代码。问题显而易见:for i in range(n)for j in range(n) 在文本上差异很大,但功能完全相同。文本匹配无法衡量代码的语义正确性,已被业界淘汰。

第二代:执行验证(当前主流)

HumanEval 开创了”执行验证”范式:生成的代码在沙箱环境中运行测试用例,只要所有测试通过即为正确。这种方法的核心优势是客观、可重复、不受风格影响

pass@k 的含义与计算

pass@k 概念pass@k 指标直觉对同一问题生成 k=10 个候选方案#1#2#3#4#5#6#7#8#9#10结果: 3 通过 / 7 失败pass@1 = 30%pass@10 = 100%pass@k = k 次尝试中至少 1 次正确的概率

pass@k 是代码评估最核心的指标,但经常被误解。

直觉理解:模型对同一道题生成 k 个候选方案,只要其中至少一个通过所有测试用例,就算”pass”。

精确定义(来自 HumanEval 论文 Chen et al., 2021):

pass@k=Eproblems[1(nck)(nk)]\text{pass@}k = \mathbb{E}_{\text{problems}} \left[ 1 - \frac{\binom{n-c}{k}}{\binom{n}{k}} \right]

其中 nn 是每个问题的总采样数(nkn \geq k),cc 是其中通过测试的样本数。这个公式用无偏估计替代了朴素的重复采样,避免了高方差问题。

实际含义

  • pass@1:模型一次就写对的概率。这是最严格的指标,也是目前最常报告的
  • pass@10:10 次尝试中至少对一次。反映模型的”上限”能力
  • pass@100:100 次尝试中至少对一次。早期论文常报告,现在意义不大——因为 pass@1 已经足够高

第三代:repo 级测试验证(新兴)

SWE-bench 将验证从”运行自定义测试用例”提升到”运行项目原有的测试套件”。这更接近真实开发:不是评估者写测试,而是用项目自己的测试来判断修复是否正确。

多语言覆盖

早期代码 benchmark 几乎全是 Python。这有两个问题:

  1. 语言偏差:模型在 Python 上的能力可能无法泛化到其他语言
  2. 训练数据偏差:如果模型在 Python 代码上训练得最多,Python 基准就会高估整体代码能力

MultiPL-E (Cassano et al., 2023) 将 HumanEval 和 MBPP 翻译为 18 种编程语言(包括 Java、C++、Rust、Go、TypeScript 等),揭示了模型的跨语言差距。例如,某些模型 Python pass@1 超过 80%,但 Rust 仅 40%。

Aider Polyglot(社区驱动)在更实际的代码编辑场景中测试多语言能力,使用 Exercism 平台的练习题覆盖多种编程语言,测试语言特定的惯用写法(idioms)。

深潜 1:HumanEval

为什么选 HumanEval 作为深潜对象?

HumanEval 是代码评估的”创世纪”基准。它定义了 pass@k 范式,几乎所有后续代码 benchmark 都继承了它的评估方法论。理解 HumanEval 的设计、优点和缺陷,是理解整个代码评估谱系的基础。

数据集构成

HumanEval (Chen et al., 2021) 包含 164 个 Python 函数补全题,由 OpenAI 工程师手写。每道题包含:

组成部分说明示例
函数签名def has_close_elements(numbers: List[float], threshold: float) -> bool:类型标注完整
Docstring自然语言描述函数功能 + 示例包含输入输出示例
测试用例平均约 7.7 个 assert 语句覆盖基本和边界情况

题目难度从简单的字符串操作(“反转字符串”)到需要算法思维的(“判断括号是否匹配”),整体偏入门级。

评估流程

  1. 模型接收函数签名 + docstring 作为 prompt
  2. 模型生成函数体(可采样多次)
  3. 生成的代码与函数签名拼接为完整文件
  4. 在沙箱中运行测试用例
  5. 统计 pass@k

已知局限

HumanEval 的局限在今天已经非常明显:

  • 题量太小:仅 164 题,统计波动大。改变随机种子可能导致 2-3% 的分数变化
  • 语言单一:仅 Python,无法评估跨语言能力
  • 难度偏低:当前顶级模型 pass@1 超过 90%,完全饱和
  • 测试不足:平均每题仅 7.7 个测试用例,无法充分验证代码正确性

HumanEval+ 的改进

EvalPlus 项目 (Liu et al., 2023) 针对最后一个问题做了系统性修复:

  • 测试用例数量:从平均 7.7 个增加到约 80 倍(超过 600 个/题),使用 LLM + mutation-based 方法自动生成
  • 效果:在 HumanEval+ 上,模型的 pass@k 下降了 19.3% 到 28.9%。大量在 HumanEval 上”通过”的代码在更严格的测试下暴露了错误
  • 排名变化:一些在 HumanEval 上排名靠后的模型,在 HumanEval+ 上反而超越了原本排名更高的模型——说明原始评估存在假阳性

这个结果的启示是深刻的:benchmark 的分辨力取决于测试质量,而非题目数量

深潜 2:SWE-bench

为什么选 SWE-bench?

SWE-bench 代表了代码评估的最新前沿——项目级软件工程能力。它不再测试”能否写一个函数”,而是测试”能否像一个软件工程师那样修复真实 bug”。2024-2025 年间,SWE-bench(特别是 Verified 子集)已成为 AI 编程能力最重要的竞技场。

数据集构成

SWE-bench (Jimenez et al., 2024) 从 12 个流行 Python 开源项目(Django、Flask、scikit-learn、SymPy、Matplotlib 等)中收集了 2,294 个真实 GitHub issue 及其对应的 pull request。

子集数量特点
SWE-bench (全集)2,294完整数据集,包含各种难度
SWE-bench Lite300功能性 bug 修复子集,排除文档/重构类
SWE-bench Verified500人工验证的高质量子集,当前最权威的报告标准

SWE-bench Verified 的出现是为了解决全集中的质量问题:部分 issue 描述不清晰、测试覆盖不完整、或者需要外部依赖。人工验证确保了每个实例都是”公平可评测的”。

评估流程

SWE-bench 评估流程SWE-bench 评估流程Issue 描述GitHub Issue1Agent 生成补丁代码修复2应用到仓库git apply3运行测试套件Docker 沙箱4通过/失败Resolved Rate5核心指标:Resolved Rate (%) — 成功修复的 Issue 占比

SWE-bench 的评估流程远比 HumanEval 复杂。下面的流程图展示了一个 Agent 如何处理一个 SWE-bench 实例:

SWE-bench 评估流程
📋1. Issue 描述输入来自真实 GitHub issue🔍2. 搜索与定位Agent 自主探索代码库🧠3. 代码上下文理解理解相关代码的逻辑🔧4. Patch 生成生成 git diff 格式的修复5. 测试验证运行项目原有测试套件

交互说明:点击播放按钮自动推进各步骤,或手动点击单个步骤查看详情。注意第 2 步”搜索与定位”——这一步的策略选择对最终结果影响巨大,也是不同 Agent 框架差异最大的环节。

Agent 框架的角色

SWE-bench 的一个关键特点是:模型分数严重依赖 Agent 框架

什么是 Agent 框架(harness)?它是连接 LLM 与代码仓库的”脚手架”:

  • 定义了模型可以使用哪些工具(文件搜索、grep、bash 命令等)
  • 规定了交互格式(如何传递搜索结果、如何提交 patch)
  • 设计了策略(先搜索还是先定位、搜索多少个文件、如何处理错误等)

同一个模型(如 Claude 3.5 Sonnet)在不同 Agent 框架下,resolved rate 可能相差 20 个百分点以上。这意味着 SWE-bench 分数实际上评估的是 “模型 + Agent 框架”的组合能力,而非纯粹的模型代码能力。

SWE-bench 的当前格局

截至 2026 年初,SWE-bench Verified 的顶级表现已达到约 77%(Claude 4.5 Opus + 高推理配置)。进步速度惊人——SWE-bench Verified 于 2024 年中推出时,初始最佳系统约 33%(Claude 3.5 Sonnet),此后半年多内翻了一倍多。

但这个数字需要谨慎解读:

  • 77% 是在最优 Agent 框架 + 高推理配置下的成绩
  • 简单 Agent 框架下,同一模型的分数可能下降到 50% 以下
  • Verified 子集经过人工筛选,难度分布不同于真实开发中的 bug 分布

已知争议

SWE-bench 社区存在几个值得注意的讨论:

  1. Agent 框架差异:排行榜上的分数包含了框架工程的贡献,很难分离出纯模型能力。一些声称”模型 A 超越模型 B”的对比可能只是框架差异
  2. 数据泄露风险:SWE-bench 的测试实例来自公开 GitHub 仓库,理论上可能被模型训练数据覆盖。Verified 子集部分缓解了这个问题
  3. 评估指标的局限:resolved rate 是二元指标(resolved/not resolved),无法衡量”接近正确”的 patch。一个只差一行的 patch 和一个完全错误的 patch 得到相同的零分
  4. 仓库覆盖偏差:仅 12 个 Python 仓库,全部是知名开源项目。对小型项目、非 Python 语言、私有代码库的泛化能力未知

过渡:代码评估与 Agent 评估的交叉

SWE-bench 已经站在了代码评估和 Agent 评估的交界处——它测试的不仅是”写代码”,更是”自主搜索、理解、决策、修复”的端到端 Agent 能力

这个趋势在 2024 年之后愈发明显:纯粹的”函数补全”已经饱和,新的代码评估越来越像 Agent 评估——需要工具使用、多步推理、环境交互。

下一篇文章 Agent Benchmark 深度剖析 将从这个交叉点出发,深入 BFCL、GAIA、WebArena 等专门评估 Agent 能力的基准,探讨函数调用、网页操作和复杂任务规划的评估方法。