跳转至

ProgramBench: Can Language Models Rebuild Programs From Scratch?

会议: NeurIPS 2026
arXiv: 2605.03546
OpenReview: https://openreview.net/forum?id=liufgqTAEe
代码: https://github.com/facebookresearch/ProgramBench
领域: LLM 其他
关键词: 软件工程智能体、从零代码重建、行为测试、黑盒评测、代码基准

一句话总结

针对现有代码评测局限于局部缺陷修复或预设骨架填空的不足,本文提出 ProgramBench 基准,仅向模型提供目标可执行程序与使用文档,要求智能体在完全断网环境下从零规划架构并重建可执行软件,并通过覆盖率引导的黑盒端到端行为测试集实现实现不可知的严谨评测。

研究背景与动机

近年来,利用大语言模型将自然语言需求转化为完整软件工程项目的需求呈现爆发式增长,业界正逐步部署自主软件工程智能体(SWE-agent)进行端到端的代码库初始化、功能维护与长周期演进。然而,人类程序员在动手写第一行代码前,必须面临一系列重大的全局软件架构决策:选用何种编程语言和构建系统、如何对系统进行模块化解耦与目录划分、设计怎样的数据结构表达核心业务实体,以及如何建立系统级的错误处理与通信协议。这些宏观设计抉择直接决定了软件的可维护性与扩展性,其对软件工程的深远影响远远超过单一函数或局部代码块的修补。

然而,现存的代码评测基准几乎完全无法考察模型的全局软件设计能力。以 HumanEval、APPS 为代表的基准测试聚焦于孤立短函数生成,而主流的仓库级基准如 SWE-bench 则严格受限于局部 issue 修复或特定单点功能开发;早期的“从零生成”基准(如 Commit0、DevBench、NL2Repo-bench)虽号称仓库级构建,但其底层大多采用抽象语法树(AST)挖空类与函数签名的做法,本质上依然是给模型预设了代码骨架的“填空题”。这种基于源码单元测试的评测机制天然绑定了具体的类名、函数接口与目录结构,一旦智能体尝试采用不同但合理的抽象层次或替代算法,测试便会直接崩溃,从而抹杀了模型自主做架构决策的可能性。

为填补这一空白,研究团队转变评测视角:跳脱出对源码结构的静态束缚,回归到软件工程的终极目标——可运行程序的外部可观测行为等价性。核心 idea:构建一个完全以“黑盒行为等价”为判定标准的从零软件开发基准 ProgramBench,仅向智能体提供一个无源码的可执行程序及其使用文档,倒逼模型通过主动黑盒探测逆向推导软件规约,并在无预设骨架、无外部网络和实现完全不可知的条件下自主完成架构设计、源码编写与构建编译,由全自动生成的高覆盖率行为测试套件判定功能还原度。

方法详解

整体框架

ProgramBench 的核心方法论围绕“行为规约探测-自由架构实现-黑盒测试验收”三位一体的闭环展开。评测流水线首先从开源生态中筛选出 200 个真实的编译型开源仓库,利用智能体自动编译出参考可执行程序(Gold Executable),并通过覆盖率引导的模糊测试技术生成不依赖源码签名的 pytest 端到端行为测试用例。随后,评测环境将参考二进制程序设置为仅执行权限(111),剥离所有源码与版本历史后交付给被测智能体。模型需在受限的 Docker 容器中主动调用该程序推断输入输出边界,自主选取编程语言、模块划分与算法结构,最终产出完整的源码仓库及自动化编译脚本 compile.sh。

%%{init: {'flowchart': {'rankSpacing': 24, 'nodeSpacing': 28, 'padding': 6, 'wrappingWidth': 400}}}%%
flowchart TD
    A["真实开源仓库<br/>200个C/C++/Go/Rust等独立软件"] --> B["参考程序构建<br/>编译Gold Binary并剥离源码"]
    B --> C["覆盖率引导的行为测试生成<br/>黑盒探测与自适应补全分支"]
    C --> D["静态断言质量审查与假程序过滤<br/>规则过滤与dummy程序校验"]
    D --> E["零信息隔离沙箱与防作弊机制<br/>execute-only权限+断网环境"]
    E --> F["实现不可知的黑盒行为等价性评测<br/>执行端到端行为断言验证"]
    F --> G["多维评测指标与轨迹分析<br/>% Resolved / 架构形态对齐"]

关键设计

1. 覆盖率引导的行为测试生成:突破源码内部约束构建黑盒测试集 传统基准直接沿用原仓库的内部单元测试,导致测试必须硬编码类和函数名,根本无法用于自由形式的重构代码。针对这一缺陷,ProgramBench 设计了基于 SWE-agent 的覆盖率引导迭代式行为测试生成管线。测试智能体首先深度探索目标程序的原源码、现有测试和说明文档,同时通过参数解析(Args)、配置文件加载(Config)、帮助文档语法(Help)、标准输入输出及管道(I/O)、子命令调度(Subcommand)以及交互式终端(TUI)等六大专业维度生成初始行为测试。随后,智能体利用插桩工具持续追踪参考二进制的代码行覆盖率(Line Coverage),针对未覆盖到的深层逻辑分支自适应生成补充测试用例,直到覆盖率达到预设阈值。全集累计生成 248,853 个测试函数,自生成测试占比高达 79.5%,中位数覆盖率达到 86.2%,在 12 个大型专用集成测试基准项目中达到了与官方原生测试套件匹敌的覆盖深度。

2. 静态断言质量审查与假程序过滤:消除浅层弱断言与虚假测试通过 仅仅追求高代码覆盖率极易滋生无效测试,例如仅断言进程返回码为 0(assert returncode == 0)或仅检查非空字符串长度的测试,任何不崩溃的空实现(Dummy Binary)都能轻松通过。为此,ProgramBench 引入了一套严密的断言质量审查器(Assertion Quality Linter),定义了包含 12 条高危规则与 7 条中危规则的静态检查体系。审查器会自动扫描并标记出缺少断言、恒真断言(assert True)、析取断言(assert A or B)、吞异常的空 try-except 块、短于 15 字符的无意义子串匹配以及循环外无守卫断言等模式。被标记的测试将被退回要求智能体重新修正。此外,所有测试用例均强制在故意编写的 Dummy 程序和 Gold 程序上执行校验,凡是无法在 Gold 上确定性通过或在 Dummy 上侥幸通过的用例一律予以剔除。该机制将假程序测试通过率从 18.5% 骤降至 3.7%,彻底杜绝了虚假过测。

3. 零信息隔离沙箱与防作弊机制:封闭环境封堵代码反编译与依赖嗅探 在前期测试中,前沿模型展现出了极强的投机倾向:若开放网络,模型会顺着 --help 输出中的元数据直接在 GitHub 上浅克隆原仓库源码(作弊率最高达 36%),甚至通过包管理器(cargo install、go get)直接拉取依赖源码。即便设立 9 位多模型评委审查轨迹,评委间关于“查阅通用 API 手册是否违规”的分歧率仍高达 40%–57%。为此,评测环境彻底禁绝了外网访问,仅保留 127.0.0.1 本地回环网络供 18 个网络工具类任务自测。在镜像构建阶段,原仓库所有构建缓存(~/.cargo、build/)被彻底擦除,git 历史重置为单次匿名提交,且将参考二进制文件的权限硬性锁死为 111(仅执行权限,禁止读写),彻底封堵了 Ghidra 等反编译工具和二进制逆向嗅探。评测时还会校验生成文件的 Hash,一旦检测到直接提交原二进制包装脚本即判零分。

4. 实现不可知的黑盒行为等价性评测:赋予模型完全的架构与语言设计自由度 在杜绝代码泄漏的前提下,ProgramBench 将参考程序作为完备但晦涩的“黑盒 Oracle”。由于评测只核验标准输出、标准错误、退出状态码以及文件系统副作用(如生成文件的内容、格式与哈希校验),模型享有绝对的实现自由:它可以自由选用 Python、Go、Rust、C/C++ 或 Shell 等任意图灵完备语言,任意决定单文件或模块化多目录组织,并设计独有的抽象数据结构。模型的真实挑战转化为一种假设驱动的敏捷探索过程:先通过 --help 和使用文档建立心理模型,再针对边界条件主动构造输入执行参考程序观察输出,最后将其落实为代码和编译脚本,高度拟合了人类工程师接手遗留无文档系统时的真实工作流。

损失函数 / 训练策略

作为纯自主软件工程评测基准,ProgramBench 不涉及直接的参数微调,其目标函数体现为标准化的黑盒执行评估协议与资源调度策略:

  1. 核心评估指标定义:

    • 完全解决率(% Resolved):模型在任务 \(t \in T\) 上输出的 candidate 必须在无作弊前提下通过全量 \(N_t\) 个测试: $\(\text{Resolved}(M) = \frac{1}{|T|} \sum_{t \in T} \prod_{i=1}^{N_t} \mathbb{I}\left( \text{Test}_{t, i}(M) = \text{PASS} \right)\)$
    • 近似解决率(% Almost):宽松通过率,要求单任务测试通过率达到 95% 以上: $\(\text{Almost}(M) = \frac{1}{|T|} \sum_{t \in T} \mathbb{I}\left( \frac{1}{N_t}\sum_{i=1}^{N_t} \mathbb{I}\left( \text{Test}_{t, i}(M) = \text{PASS} \right) \ge 0.95 \right)\)$
    • 任务难度客观分级公式:基于无依赖源码行数 \(\text{lines}\) 和运行时依赖数 \(\text{deps}\) 计算连续难度标量: $\(\text{Difficulty} = \text{clamp}\left( \log_{10}(\text{lines}) + \log_{10}(1 + \text{deps}) - 2,\; 0,\; 10 \right)\)$ 并依此严格划分为简单(\(<2\))、中等(\([2, 4)\))与困难(\([4, 10]\))三档。
  2. 沙箱隔离与执行调度预算:

    • 基础镜像基于 Ubuntu 22.04,预装 Rust 1.92.0、Python 3.12、Go 1.21.0、C/C++ 工具链与 tmux。
    • 硬件配额限制为 20 vCPU、60GB 内存,单任务最长允许 1,000 个交互步数或 6 小时墙钟执行时间,单步执行超时设为 3 分钟,当步数低于 20 步或耗时接近最后 10 分钟时触发软性编译警告提示。

实验关键数据

主实验

论文使用 mini-SWE-agent 脚手架对 9 款当前顶尖的大语言模型进行了全量 200 个任务实例的评测,主要实验数据如下表所示:

模型 % Resolved (全通率) % Almost (≥95%测试) 平均API调用步数 单任务平均成本 ($)
Claude Opus 4.7 0.0% 3.0% 93 $3.81
Claude Opus 4.6 0.0% 2.5% 260 $11.38
Claude Sonnet 4.6 0.0% 1.6% 475 $27.09
Claude Haiku 4.5 0.0% 0.0% 124 $0.80
Gemini 3.1 Pro 0.0% 0.0% 94 $1.51
Gemini 3 Flash 0.0% 0.0% 89 $0.33
GPT 5.4 0.0% 0.0% 16 $0.33
GPT 5.4 mini 0.0% 0.0% 18 $0.04
GPT 5 mini 0.0% 0.0% 15 $0.03

消融实验

针对任务内在难度分布与不同模型家族的适应能力,论文对任务按定义公式划分为 Easy(28项)、Medium(143项)和 Hard(29项),统计了各模型的宏观平均测试通过率:

模型 Easy (<2) 平均通过率 Medium [2,4) 平均通过率 Hard [4,10] 平均通过率 全任务宏观平均
Claude Opus 4.6 73.9% 53.3% 24.7% 52.0%
Claude Opus 4.7 73.8% 52.1% 25.0% 51.2%
Claude Sonnet 4.6 67.1% 48.8% 28.6% 48.5%
GPT 5.4 50.9% 39.9% 18.0% 38.3%
Gemini 3.1 Pro 50.9% 37.7% 17.8% 36.6%
Gemini 3 Flash 49.6% 31.9% 17.9% 32.4%
Claude Haiku 4.5 41.9% 30.6% 15.6% 30.0%
GPT 5.4 mini 24.1% 17.4% 7.8% 16.9%
GPT 5 mini 21.3% 15.9% 11.0% 15.9%

关键发现

  • 全量任务无一解破,极限制约尽显:在包含 248,853 个测试断言的严格评测下,当前所有 9 款顶级模型在 200 个软件项目上的完全解决率(% Resolved)全部为 0.0%。表现最好的 Claude Opus 4.7 也仅仅在 3.0% 的简单/中等任务上勉强达到了 95% 以上的通过率,而复杂工业级系统如 FFmpeg、SQLite、PHP 和 Typst 对当前模型而言完全无法从零攻克。
  • 模型生成的代码基呈现严重的“单体化”与“长函数”特征:深入比对高分方案(测试通过率 \(\ge 75\%\))与人类参考源码发现,模型极度厌恶创建多级子目录,67% 的方案目录最大深度仅为 1(人类中位数为 2),60% 的代码基全部挤压在 1–3 个单体文件中;函数数量仅有人类实现的 10%–29%,但平均函数长度却显著拉长(Claude Sonnet 4.6 达 1.46 倍,Gemini 3.1 Pro 达 1.62 倍),反映出模型在宏观模块分解与抽象封装能力上的严重匮乏。
  • 跨语言重写表现出对高层语言的非对称依赖:在完全自由选择下,模型仅在 50% 的情况下选用与原仓库相同的语言,整体上最青睐 Python(36%),其次是 Rust(25%)和 Go(20%)。当施加强制异构语言约束时,Python 的占比猛增至 51%,这虽然削弱了对预训练源码的表面记忆,但也使得模型在面对高底层绑定项目时产生效率与表达偏差。
  • 软件工程行动范式呈现剧烈分化:交互轨迹表明,GPT-5.4 表现出极度的“单步直出”模式(中位数仅用 16–17 步,96% 的代码在单轮内一次性吐出,近 40% 的任务完全不修改已写文件);而 Claude Sonnet 4.6 则展现出频繁的“编写-编译-调试-探测”迭代闭环(平均 475 步,平均发生 18.3 次文件局部修改)。然而耗费极多步数并不能显著拉开通过率差距,揭示了长程推理下上下文累积与逻辑连贯性的天花板。

亮点与洞察

  • 将代码评测对象由传统的“源码签名/内部断言”彻底重构为“黑盒可执行程序/端到端行为断言”,彻底破除了语言绑定与预设类函数签名的枷锁,为长程自主软件开发提供了真正实现不可知(Implementation-Agnostic)的评估基线。
  • 引入断言质量审查器并联动假程序校验,成功将大模型自动生成测试用例中的弱断言与虚假通过率压低了 5 倍,为自动化构建海量高可信度软件评测套件确立了工程范式。
  • 深刻揭示了当前代码智能体“会修单点 BUG、但在从零架构设计上近乎白纸”的核心症结,模型倾向于写出扁平、紧耦合的单文件面条代码,为未来代码大模型的架构预训练与模块化演化指明了攻关方向。

局限与展望

  • 作者承认黑盒测试集本质上是对完整软件规约的有限欠近似(Under-approximation),且当前评测仅聚焦于输入输出与文件系统副作用的功能等价性,完全未度量执行效率、内存驻留、CPU 占用等非功能性系统性能。
  • 独立单智能体面临严重的上下文记忆衰减与决策疲劳,无法有效支撑如 FFmpeg 这种超百万行复杂工程的逆向与重建,后续需进一步探索多智能体异步协同(Multi-agent Orchestration)与人机结对交互编程(Human-in-the-loop)模式。

相关工作与启发

  • vs SWE-bench / SWE-bench Verified: SWE-bench 聚焦于预先存在的复杂代码库中的真实 GitHub Issue 修复,测试的是代码局部理解与针对性修补;而 ProgramBench 考验从零起步的宏观软件架构、技术选型、目录解耦与规约逆向推导,两者在软件工程生命周期中互为正交补充。
  • vs Commit0 / DevBench / NL2Repo-bench: 此类先驱基准虽然探索了端到端仓库生成,但依赖 AST 抹除类/函数体并通过原仓库单元测试评测,模型实际上是在人工划定的骨架结构下做受限补全;ProgramBench 则完全剥离内部结构限制,通过外部行为断言赋予模型真正的自由设计空间。

评分

  • 新颖性: ⭐⭐⭐⭐⭐ 颠覆了传统依赖源码内部签名的评测范式,首创基于可执行文件黑盒探测的从零软件架构评测。
  • 实验充分度: ⭐⭐⭐⭐⭐ 涵盖 200 个真实开源软件、24 万余条自生成行为断言、9 大主流前沿模型及深度的代码库拓扑/轨迹分析。
  • 写作质量: ⭐⭐⭐⭐⭐ 逻辑结构严整,论证层层递进,对测试完备性、作弊防御和模型行为形态的剖析极其深刻。
  • 价值: ⭐⭐⭐⭐⭐ 标志着代码大模型评测从局部代码修补迈向全局软件工程架构设计的关键分水岭。