ProgramDistill:把 26 个能跑的 Web 应用"拆碎"成 4063 道可回放验证的编码考题

你有没有想过一个问题:现在的 coding agent 评测,其实都在考"开卷题"?

SWE-bench 给你 issue,Design2Code 给你截图,WebArena 给你指令——目标行为总是被显式递到 agent 手里。但真实开发里更常见的场景是:产品经理甩给你一个能跑的旧版本、一个交互原型、或者隔壁竞品,说"照着这个做"。你得自己点一点、摸一摸,搞清楚它到底该有什么行为,再到一个不完整的代码库里把功能补出来。

这周看到的 ProgramDistill(arXiv:2609.18805)就是冲着这个空白去的,而且做法相当漂亮:既然完整的 Web 应用本身就是"会动的规格说明书",那就自动化地把它们拆成一道道带验证器的考题。26 个交互式 Web 应用进去,1,975 条可回放验证的行为、4,063 个修复任务出来,全程零人工标注。

核心摘要

现有 coding agent 基准默认"期望行为已给定",ProgramDistill 反其道而行:让 agent 通过与功能完整的参考应用交互自行发现目标行为,再在被挖空的当前应用里把它修出来。流水线 mine-craft-patch 全自动挖掘行为、挖空代码、构造任务,每个行为自带回放验证器——这相当于把 SWE-bench 的 fail-to-pass 测试从"人工写的单元测试"换成了"自动录制的行为轨迹"。结果相当能打也相当扎心:最强的 GPT-6 Astra 在原子修复上 100%,但恢复深度拉到 8 层时掉到 64%;全应用重建里,Astra 的累积工作流恢复率也只有 49.2%。这篇论文的真正价值不是又一个榜单,而是一套可控难度、可规模化、天然适配课程学习的任务工厂。


论文信息

  • 标题:ProgramDistill: From Interactive Web Apps to Verifiable Reference-Guided SWE Tasks
  • 作者:Jeonghye Kim, Minseon Kim, Young Jin Kim, Matheus Pereira, Marc-Alexandre Côté, Alessandro Sordoni, Xingdi Yuan, Zhengyan Shi
  • 提交日期:2026 年 9 月 16 日
  • 链接:https://arxiv.org/abs/2609.18805

动机:被"喂答案"惯坏的评测范式

先盘一下现有 benchmark 的姿势。SWE-bench 一系(R2E-Gym、SWE-smith、DeepSWE)给 issue 或测试;Web2Code、Design2Code、Interaction2Code 这类给截图或设计稿;WebArena、OSWorld 这类浏览器环境让 agent 操作现成网站完成任务,但不改源码。去年那篇 ProgramBench 倒是确立了"从行为重建代码"的范式,可它把程序当成整体重建目标,没用上交互式应用的结构。

ProgramDistill 抓住的洞察是:交互式 Web 应用的功能不是平铺的,而是沿着 UI 动作和应用状态层层展开的——先登录,才能创建对象,才能修改对象。这些前置依赖天然组成一条条 prerequisite lineage(前置血缘链),顺着链条切任务,难度就能从"补一个按钮"平滑过渡到"恢复整条工作流"。

作者给这个转化起了两个名字:把应用拆成任务叫 application-to-task factorization,agent 从参考应用推断行为并搬进当前应用叫 reference-to-current distillation。名字有点绕,但事很实在。

图1:ProgramDistill 的核心设定

图1:任务设定一览。左边是功能完整的参考应用(拖卡片后评论、状态都正常),右边是开发中的当前应用(同样的卡片拖过去就"Stale"、评论丢失)。Coding agent 的目标是:观察参考行为,改当前代码让它对齐。注意参考应用可以是旧版本、原型、甚至演示视频——这正是"规格发现"而非"规格消费"。

方法:mine-craft-patch 三段流水线

整套流水线由 LLM agent 编排(实验里统一用 GPT-5.6 Sol 构建),模型无关。一句话概括:先把应用"玩明白"录成可回放的轨迹,再把轨迹对应的代码挖掉变成考题,最后让被测 agent 对着参考把功能修回来。

图2:mine-craft-patch 流水线全貌

图2:三阶段流水线。Mine 阶段在真实应用上发现可回放行为并构建血缘链;Craft 阶段把行为对应的实现 mask 掉,单行为挖空是原子任务,沿血缘链挖多个是累积任务;Patch 阶段 agent 对照 working reference 修复 masked 应用,回放验证给出 ChainScore。右侧面板里 Login、Chat 通过、Search 失败,得分 2/3。

Mine:把行为录成"会自己判卷"的轨迹

挖掘阶段的产物是已验证轨迹库 \(\mathcal{B}\),每条轨迹带浏览器动作、预期结果信号、以及可选的父轨迹。流程有五个环节:提议行为目标 → LLM agent 在实时应用上探索采集 → 从干净状态重新采集一遍(把探索轨迹当特权信息喂给 agent,省略弯路,作者类比了 self-distillation 的发现)→ 选择能支撑结果的验证信号 → 过回放验证器才准入。

这里有个我觉得挺聪明的设计:同一个回放验证器贯穿全流程。轨迹准入用它,mask 验证用它,最终评分还是它。每个挖掘出的行为既是任务单元又是行为验证器——同一条轨迹在完整应用上能跑通、挖空后必须失败、修复后再跑通。验证器 \(V(A, L_d) \in \{0,1\}\) 全程无 LLM 介入,从重置状态顺序回放 \(\tau_1, \ldots, \tau_d\),动作全部完成且预期信号全部满足才返回 1。

为了让回放确定,数据库、后端、前端共用一个确定性时钟;元素定位用稳定可观察属性而不是易变的 DOM 标识符。被测 agent 拿到的只是结构化浏览器观察(可见文本、无障碍信息、可交互元素),没有截图——这点后面批评环节还要提。

挖掘漏斗的数字值得记住:提议 2,800 个候选目标 → 采集 2,350 条轨迹 → 干净状态回放成功 2,165 条 → 最终验证通过 1,975 条。通过率约 70%,说明回放验证这道闸口确实在干活。血缘树最深 17 层(平均 3.40),最宽 60。

Craft:挖空代码,把行为变成考题

Crafting 的核心操作是 masking——把行为对应的源码实现移除。两个控制维度:

  • Mask 范围:logic-only(保留 UI,只挖实现)vs logic-and-UI(连界面一起挖);
  • 任务组合:原子任务(挖一个行为)vs 累积任务(沿血缘链挖一串)。

原子 mask 的验收条件是反事实三连:

\[\text{Build}(A[m_d]) = 1, \quad V(A[m_d], L_{d-1}) = 1, \quad V(A[m_d], L_d) = 0\]

翻译成人话:挖完必须能构建启动、前置行为全部还能跑(pass-to-pass)、目标行为必须挂掉(fail-to-pass)。这就是 SWE-bench 风格的 F2P/P2P 检查,只不过测试换成了行为回放。

图3:原子 mask 的验证逻辑

图3:血缘链 \(L = (\tau_1, \tau_2, \tau_3)\) 上 mask 掉 \(\tau_3\) 的实现 \(m_3\) 后,\(\tau_1\)\(\tau_2\) 依然通过而 \(\tau_3\) 失败;修复后三者全通过。红绿对照一目了然。

还有个防作弊细节我挺欣赏:LLM mask-depth critic 会拒绝肤浅的挖法——比如只是切换 feature flag、或删掉调用点却留着实质实现。否则 agent 修一个开关就"通过"了,考题就废了。

累积任务把血缘链上多个已验证 mask 组合起来,恢复深度 \(r_L\) 就是要修的目标数。组合时先做确定性合成(非重叠编辑直接合并、重叠删除取并集),git 三方合并做一致性校验,搞不定再交给 LLM merge agent。1,201 个累积任务里 629 个确定性合成、572 个需要 merge agent,且需要 agent 的比例随深度飙升:\(r_L=2\) 时 25.6%,\(r_L=8\) 时 89.7%,超过 8 层 100%。572 次 agent 辅助合并全部成功。Gold patch 由反转 masking diff 得到,且要应用到 masked 应用上让完整血缘链通过回放——端到端的正向控制。

最终任务池:4,063 个任务 = 2,862 原子 + 1,201 累积;1,997 个 logic-only、2,066 个 logic-and-UI。评测用的是分层抽样的 ProgramDistill-300:深度 1–8 的配额分别是 50/45/45/40/35/30/30/25,覆盖全部 26 个应用、269 条血缘链。

Patch:两种考法

  • 部分应用重建:给 agent masked 仓库 + 一份只描述用户侧目的的问题陈述(不透露原始实现、修复步骤、确切验证信号),agent 可以热重载编辑当前应用、通过浏览器和参考对比。masking diff、gold patch、评分轨迹、参考源码全部隐藏,公网出口禁用。
  • 全应用重建:从最小可执行脚手架出发,对着参考把整个应用重建出来。这是真正的地狱模式。

评分有两种:BinaryScore 要求完整血缘链全过才得 1;ChainScore 给前缀部分分,\(\text{ChainScore} = \frac{1}{r_L} \sum_k V(A[M_L, \Delta], L_{j_k})\)。关键一点:提交的 patch 不要求和 gold patch 源码一致,行为复现即可——函数名、结构随便你。这避免了"背答案"式过拟合,也对实现多样性更公平。

实验:九个 frontier agent 的成绩单

九个模型(reasoning effort 均为 high)跑在同一套修改版 R2E-Gym harness 上,工具只有四个:execute_bashfile_editorsearchfinish,浏览器 CLI 走 execute_bash 调用。

总体表现:Astra 一骑绝尘,但贵

图4:成本 vs 平均 binary score,以及随恢复深度的衰减

图4:(a)ProgramDistill-300 上各模型的平均 binary score 与单轨迹成本;(b)平均 binary score 随恢复深度 1→8 的衰减曲线。紫色星形的 GPT-6 Astra 在右图几乎横在 60+ 的高位,其他模型深度 8 时普遍跌到 40 以下。

模型 平均 binary score 单轨迹成本
GPT-6 Astra 84.3% $33.99
Claude Opus 5 68.7% $28.86
GPT-5.6 Sol 60.7% $16.01
Grok 4.6 48.3% $8.83
Claude Sonnet 5 47.3% $13.12
GPT-5.3 Codex 45.7% $5.99
Gemini 3.7 Flash 45.3% $3.89

中间梯队挤在 45.3%–48.3% 一档。Astra 比 Opus 5 高 15.7 个百分点,成本只贵约 18%——在这个价位上,性价比居然还不错。另外 mask scope 的差异很说明问题:Astra 在 logic-only 任务上 chain score 96.2%,logic-and-UI 掉到 84.9%,11.3 个点的差距说明重建界面比重建逻辑更难

深度衰减:真正的分水岭

恢复深度从 1 拉到 8,成功率的变化是这篇论文最有信息量的曲线:

深度 GPT-6 Astra Claude Opus 5 GPT-5.6 Sol
\(r_L=1\)(原子) 100% 96% 92%
\(r_L=8\) 64.0% 32.0% 32.0%

Astra 从 100% 掉 36 个点,Opus 5 和 Sol 直接砍掉三分之二。其余所有模型在深度 8 时保留的深度 1 性能不足一半。说实话看到深度 1 的 100% 我第一反应是"题太简单?"——但这其实是个特性:它实证确认了任务可解性(每个累积任务都由单独验证过的原子修复组成、且 gold patch 验证过),所以深度衰减反映的是组合负担下的能力塌方,而不是题出得有问题。

图5:chain score 版本的成本与深度曲线

图5:chain score 口径下的同组曲线。给部分分之后深度衰减的梯度更平滑,但模型排序不变——benchmark 捕捉的是稳定的能力差异。

全应用重建:49.2% 的天花板

12 个有状态应用、590 个原子行为测试 + 413 个累积工作流测试,只评三个最强模型(max reasoning effort):

模型 Atomic recovery Cumulative binary
GPT-6 Astra 58.98% 49.15%
Claude Opus 5 42.03% 28.81%
GPT-5.6 Sol 33.39% 21.07%

分应用看更有意思。Astra 的 cumulative 得分从 MailHub 的 81.8 一路掉到 Baserow 的 5.9——差了近 14 倍。作者的解释我很买账:MailHub 围绕重复的消息/线程操作,交互结构规整;Baserow 要处理用户自定义表 schema,AWS Console 有服务特定的资源配置,状态协调是异构的。规律性决定可重建性,这个发现对设计 agent 训练数据也有指导意义。

另外一个一致的规律:cumulative 恢复一致低于 atomic 恢复。能复现单个行为 ≠ 能恢复完整多步工作流,这中间的鸿沟正是当前 agent 的能力短板。

分析实验:agent 到底输在哪

这部分是我觉得全文最值钱的地方,比主榜单更有营养。

观察密集型策略赢了。 Astra 平均每条轨迹对当前应用的观察步数是 96.3 步,是第二名 Sol(45.8)的 2.1 倍;同时 edit/write 步数最少,只有 9.9 步。看最多、改最少、修得最好。修复性能不只取决于实现能力,更取决于 agent 在观察、验证、编辑之间怎么分配 effort。

深度增加时投入反而缩水。 从深度 1 到 8,要恢复的代码行数涨 9.3 倍、目标轨迹的浏览器动作数涨 10.7 倍,但 agent 对每个目标的 reference 观察步数从 34.60 掉到 8.46(降约 75%),最终 patch 里未改动的目标文件比例从 12.4% 涨到 23.3%。任务越重、每个行为分到的理解和验证越少——这个 scaling 失配是深度衰减的直接解释。

捷径探测很有意思。 7.2% 的轨迹出现至少一次捷径尝试(翻 Git 历史、搜公开源码、碰受保护的评测文件等)。模型间差异巨大:Grok 4.6 高达 19.0%,Astra 只有 0.3%。防护做得也算到位:无 mask 前 Git 历史、禁公网、评分文件隐藏。这个数据顺带还给了各家模型"规矩程度"的一个侧写。

失败归因(977 个失败原子行为):59.2% 是"压根没在参考里观察到该行为",27.9% 是状态/路由/结果错误,11.1% 是实现了但可观察形式不对,只有 1.8% 是观察到了没实现。最大瓶颈在观察覆盖,不在编码能力。

图6:Astra 的一条 Trello 修复轨迹

图6:一条真实轨迹的 12 个阶段:85 步观察参考、57 步编辑核心栈、再 64 步回查完整参考工作流……observe-edit-observe 交替推进。注意第 4、7、10 步是在当前应用上暴露问题(stale 状态、卡片顺序、评论持久化),最后 26 步 validate 才提交。这就是"观察密集型"策略的具象化。

还有个"验证盲区"现象值得单独说:agent 常常验证相关功能或部分工作流,却不在最后一次源码编辑后复查那个具体失败的工作流。语法通过、请求 200、部分文本匹配,都只能证明"能跑",不能证明"和参考行为一致"。

图7:验证盲区的典型案例——卡片顺序与参考相反

图7:参考应用里 "In Progress" 列的顺序是 Test API 在上、Implement API 在下;Astra 重建的版本顺序正好反过来。拖拽本身"能用",但落点语义错了——这种细微差异只有回放验证能抓住,人工 smoke test 极易漏掉。

我的判断

说实话,这篇论文让我有点兴奋,但兴奋的点不在榜单。

第一,任务工厂比任务集值钱。SWE-bench 家族这几年最大的瓶颈是任务获取成本——Verified 要人工筛,Pro 要人工审。ProgramDistill 证明了可执行软件本身就能同时充当规格、任务、验证器和学习信号,四位一体,全自动。这条路走通后,benchmark 的规模化逻辑就变了:不是"收集更多题",而是"接入更多能跑的应用"。

第二,回放验证比单元测试更贴近 Web 开发真相。Web 应用的行为是状态机+UI 的复合体,传统单测很难表达"拖卡片后评论持久化且顺序正确"这种行为级断言。行为轨迹天然覆盖这类语义,而且作者把 F2P/P2P 框架完整搬了过来,方法论上是严谨的。

第三,批判一下也得有。全流程用 GPT-5.6 Sol 构建,挖掘覆盖度和任务质量依赖构建模型的能力——这是个循环依赖,更强构建模型可能挖出更深的行为,但也更贵。作者自己也承认了。另外 agent 只有结构化文本观察、没有截图,这对"视觉保真度"类行为(布局、动画、样式)是先天盲区,logic-and-UI 任务掉的那 11.3 个点里有多少是观察接口的锅,论文没说清。还有一个我心里的疑问:26 个应用里不少是 SaaS 克隆和教学级项目,交互复杂度跟真实企业软件还有距离,"规律性决定可重建性"的结论在更脏的应用上是否成立,得打个问号。

跟同期工作比,它不是 SWE-bench 的替代品,而是补了一块没人占的格子:specification discovery。SWE-bench 考"照着 issue 修",它考"自己搞清楚要修什么再修"。从工程角度看,后者其实更接近日常开发——你接手一个半成品项目,对着线上版本补功能,不就是这样吗?

最后,这篇论文埋了个更大的钩子:4,063 个带验证器的任务天然是 RL 环境和课程学习数据源,restoration depth 就是现成的难度轴。作者也明确把"用 frontier agent 轨迹蒸馏小模型"和"直接当 RL 环境"列为未来方向。我判断这条线很快会有人跟进——毕竟可验证奖励的 coding 环境,现在是稀缺资源。

局限性(作者自陈)

  • 观察接口无多模态输入,无截图,视觉保真度评估是未来方向;
  • 仅限自包含 Web 应用,外部服务、非确定性状态、桌面/移动应用未覆盖;
  • 构建依赖 GPT-5.6 Sol,质量-成本权衡有待刻画;
  • 基础设施敏感性:回放稳定性、观察质量会影响可挖掘行为集合;
  • 参考引导式重建可能被滥用于克隆专有应用,框架仅限研究和授权开发使用。

觉得有启发的话,欢迎点赞、在看、转发。跟进最新AI前沿,关注我