Dockerless:不跑测试、不搭环境,也能给 Coding Agent 的修复打分?
做 Coding Agent 训练和研发的团队,大概都绕不开一个又脏又累的环节:搭环境。
不管是给 SFT 筛选高质量轨迹,还是给 RL 提供奖励信号,都需要一个 verifier(验证器)来判断 Agent 生成的 patch 是否真正解决了 issue。
现阶段,最可靠的验证方式仍然是跑测试。为每个仓库构建专属 Docker 镜像、安装依赖,定位相关测试,编写测试流程和结果解析逻辑,最后在隔离环境中运行单元测试。测试通过,便判断这个 patch 有效。
这套流程准是准,但它有一个问题就是贵。每个仓库都要单独搭建环境,即使接入自动化流水线,这个过程也很难保证成功率。不仅如此,很多实际生产中的代码库——私有仓库、企业遗留系统——根本没有可复现的环境,甚至连完整测试套件都没有。对于这些仓库,上面这套基于执行的验证方式不只有成本问题,更重要的是缺少实现条件。
今天这篇来自上海交通大学和抖音团队的论文【Dockerless: Environment-Free Program Verifier for Coding Agents】提供了一个可行方案,即verifier 不执行代码,也可以判断修复对不对——只要让它像人类 reviewer 一样,自己去仓库里翻代码找证据。
现有 verifier 的两难
论文开头先分析了现有 verifier 的两类主流方案。
第一种是基于 Docker 的测试执行。这种方式的优点是准确性较高,缺点是要为每个仓库搭建独立环境,成本高,也难以大规模扩展。
第二种是 LLM scorer。它的优点是会直接让模型根据 issue、reference patch 和 candidate patch 进行判断,不用搭建运行环境,因此扩展成本更低。但它的缺点也很明显,一般模型只能看到输入文本和 patch diff,缺少对真实代码库上下文的理解。
比如,要判断两个 patch 是否等价,系统得知道问题路径是否真的会调用被修改的函数;不同实现方式的 patch 是否都能和周围模块正确协作。这些信息,仅依靠 diff 文本很难准确判断。
图 1:三类 verifier 的对比
正如上图所示,基于 Docker 的测试执行准确但依赖昂贵的仓库级环境;LLM scorer 不依赖环境,但缺少代码库上下文;Dockerless 通过主动探索代码库,在无需环境的同时,让验证过程建立在真实代码库证据之上。
Dockerless 的工作原理
Dockerless 的输入包括三部分:issue 描述、reference patch(已知正确的修复版本)以及 candidate patch(Agent 生成的待验证 patch)。整个验证过程分为两个阶段。
图 2:Dockerless 的整体架构
第一阶段:生成验证问题与**并行**探索。verifier 会先根据 issue 和 reference patch 生成 2~4 个验证问题。这些问题主要覆盖四类信息:修复应该位于仓库中的哪个位置(Location)、修改后代码应该表现出什么行为(Behavior)、哪些测试或断言可以验证修复正确性(Test Evidence),以及这个改动可能影响哪些边缘场景(Edge Cases)。
接着,分配一个独立的子 Agent 给每个验证问题,并由子 Agent 并行探索代码库。子 Agent 只拥有只读 shell 工具,例如 find、grep、rg 等,会按照 ReAct 流程反复执行命令、查看输出、继续搜索,最终返回一份简短的探索结果,并标注找到的关键证据,包括对应的文件路径和代码行号。
第二阶段:汇总裁决。judge 模型接收 issue、两个 patch,以及所有子 Agent 收集到的证据,输出一个二值裁决 token:0 表示 patch 未解决问题,1 表示 patch 已解决问题。
在计算评分时,Dockerless 并不直接使用这个二值结果,而是提取两个 token 对应的 logits,再通过 softmax 转换成 0~1 之间的连续分数。这样,这个分数既可以用作 SFT 阶段的筛选和排序训练轨迹,也能作为 RL 阶段的稠密奖励信号。
如何训练
Dockerless verifier 本身是基于 Qwen3.5-9B,通过 rejection sampling 方法训练得到的。
图 3:Dockerless 的训练流水线、
具体的训练过程是,从 SWE-Gym 和 Multi-SWE-RL 中选取 3.7K 个带执行标签的 issue。这样就保证了每个 candidate patch 都是经过真实测试验证,并拥有对应的真实结果。接着,用更强的教师模型(Teacher Model)GLM-5,按照 Dockerless 的完整验证流程生成训练轨迹:先生成验证问题,再由探索 Agent 收集代码库证据,最后进行裁决,形成 question-answer-judge 三部分轨迹。
当中的筛选规则是,只有教师模型的最终裁决与真实测试结果一致时,这条轨迹才会被保留下来用于训练;如果结果不一致,该条轨迹会被直接丢弃。通过这种方式,模型不只学习到了 patch 文本之间的表面关联,还学习到一套基于代码库证据进行分析和判断的验证过程。同时,为缓解数据类别不平衡的问题,论文将负样本与正样本的比例控制在了 4:1 以内。
在训练阶段,问题生成、子 Agent 探索和最终裁决三个环节会共享同一个 backbone,并使用标准的 next-token cross-entropy 目标进行联合训练。
实验数据
先看 Dockerless 作为独立 verifier 的验证能力。论文构建了一个平衡的 verifier 评测基准,共包含 776 个样本,其中正负样本各占一半,并使用 AUC 作为评价指标。
对比对象有两类:一类是直接进行 zero-shot 判断的前沿模型,包括 DeepSeek-V3.2、Kimi-K2.5、GLM-5 和 GPT-5.4;另一类是经过训练的开源 verifier,包括 SWE-Gym Verifier、R2E-Gym Verifier、OpenHands Critic 和 DeepSWE Verifier。
图 4:各 verifier 在 trajectory-level 评测基准上的 AUC
实验结果显示,Dockerless 在 SWE-bench Verified 分组取得 81.0 AUC,在 Multi-SWE-bench Flash 分组取得 72.1 AUC,两个分组均排名第一。相比表现最好的开源训练 verifier(66.7 和 62.9),分别提升 14.3 和 9.2 个百分点;相比表现最好的前沿模型裁判 GPT-5.4(75.9 AUC),也提升了 5.1 个百分点。
这说明在 patch 验证任务中,模型能否获取并利用真实代码库上下文,可能比单纯依赖模型规模带来更大的收益。
无需环境的后训练流水线
verifier 只是整个方案中的一环,论文真正想解决的是后训练流程的扩展性问题。有了 Dockerless,SFT 和 RL 两个阶段都可以摆脱针对每个仓库单独构建环境的依赖。
图 5:无需环境的后训练流水线
SFT 阶段(env-free RFT):Agent 的 rollout 在一个最小化 Ubuntu 镜像中完成,环境准备阶段只需要 checkout 仓库代码,不安装项目依赖,也不配置测试环境。通过这种方式,论文以低成本收集了 16K 条轨迹,再用 Dockerless 对这些轨迹最终生成的 patch 进行评分,并按照分数排序后选取 top 4K 轨迹用于 SFT。
RL 阶段:rollout 仍然在同一个最小化环境中进行,Dockerless 输出的连续分数直接作为 reward,并用于 GRPO 算法的组内归一化优化。为了提高 reward 稳定性,每个 patch 会独立评估两次并取平均值。
整个流程中,我们不用再为每个仓库单独构建 Docker 环境了。
实验结果
Dockerless-RL-9B 在 env-based 标准评测中的表现为:SWE-bench Verified 62.0%、Multilingual 50.0%、Pro 35.2%。相比 Qwen3.5-9B 基线,三个 benchmark 分别提升 2.4、8.7 和 2.9 个百分点,同时也超过了多个同规模的开源 SWE 专用模型。
图 6:SWE-bench Verified、Multilingual 和 Pro 上的 resolve rate 主结果。加粗行为本文主模型,灰色行为用于隔离 SFT 数据来源和 RL reward 来源影响的控制实验。
不过,更能说明 Dockerless 价值的是论文设计的两组控制实验。
图 7:不同 SFT 数据过滤方式对下游 resolve rate 的影响。模型骨干和训练流程保持一致,仅调整训练数据的筛选方式。
第一组实验只调整 SFT 阶段的数据来源。论文比较了两种训练方式:一种是使用 Docker 环境收集并筛选轨迹得到的 Env-SFT-9B;另一种是使用 env-free 轨迹,再通过 Dockerless 进行过滤得到的 Dockerless-SFT-9B。两者在 SWE-bench Verified、Multilingual 和 Pro 上的结果分别为 60.6 vs 60.0、47.7 vs 48.3、35.3 vs 33.9,整体表现基本接近,并没有出现明显差距。
第二组实验只调整 RL 阶段的 reward 来源(数据参考图 6)。使用真实测试执行结果作为 reward 的版本(oracle test-execution 信号)取得 62.4 / 51.3 / 35.7;使用 Dockerless reward 的版本取得 62.0 / 50.0 / 35.2,两者差距控制在 1.3 个百分点以内。而使用另一个不探索代码库的训练 verifier(DeepSWE Verifier)作为 reward 时,性能进一步下降 1.1~2.7 个百分点。
此外,论文还给出了一个反向实验:如果不经过任何过滤,直接使用全部 16K 条 env-free 轨迹进行 SFT,最终成绩只有 58.8 / 41.3 / 31.9,甚至低于基线。这个结果说明,env-free rollout 本身并不是主要问题,关键在于是否有可靠的 verifier 对生成轨迹进行筛选。Dockerless 证明了一个基于代码库证据的 verifier,可以成为支撑 env-free 后训练流程的重要组成部分。
几个工程细节
验证问题数量与 verifier 性能的关系
当验证问题数量 K 从 0 增加到 4 时,verifier 的 AUC 从 78.3 提升到 81.0。但后面增加到 6 个和 8 个问题后,AUC 反而下降到 79.6 和 80.3。论文认为,过多的问题会带来重复探索和噪声证据。因此,推理阶段默认生成 2~4 个验证问题,在验证效果和探索成本之间取得平衡。
图 8:验证问题数量 K 与 verifier AUC 的关系
验证成本
Dockerless 每次评分都需要执行多轮代码库探索,看起来可能会引入较高延迟。但论文对 RL 训练中的 rollout 时间进行了拆解:Agent 本身完成一次 rollout 平均需要 2,308 秒,而 Dockerless reward 评估额外增加约 180 秒,占整体时间的 7.2%。因此,训练过程中的主要耗时仍然来自 Agent 自身的任务执行,而不是 verifier。
图 9:RL 训练中单次 rollout 的耗时拆解
典型案例
论文展示了一个 matplotlib 的 offsetText 颜色修复案例。candidate patch 实际能够通过测试,但它与 reference patch 的实现方式存在明显差异:一种方案使用内联条件表达式,另一种方案则提取了辅助变量。由于表面文本差异较大,两者的文本相似度只有 0.468,DeepSWE Verifier 也只给出了 0.035 的分数。
Dockerless 则通过子 Agent 探索代码库,确认该修改同时覆盖了 XAxis 和 YAxis 的初始化路径,并保持了 inherit 语义的一致性,最终给出 0.996 的评分,与真实测试结果一致。这个案例说明,仅比较 patch 表面形式并不足以判断修复质量,不同实现方式同样可能达到正确结果。
图 10:matplotlib offsetText 案例
方法边界
Dockerless 也有自己的适用范围。首先,它依赖 reference patch 作为验证依据,因此更适合用于训练阶段的数据筛选和批量评估,而不是没有标准答案的线上代码审查场景。
其次,env-free 路线在部分编译型语言上仍存在差距。由于缺少真实编译环境提供的类型检查、链接错误等反馈,Rust、C 等语言上的效果仍弱于基于环境执行的方案。如何在不搭建完整环境的情况下引入类似编译器反馈,是后续需要解决的问题。
不过,论文也验证了 Agent rollout 本身对环境依赖并不强:去掉执行环境后,多个前沿模型的任务完成率下降有限。因此,Dockerless 认为当前 env-free 路线的主要挑战并不在任务执行,而在于如何提供可靠的验证信号
小结
这篇论文可以用一句话概括:把 verifier 从“打分函数”升级成“会查证的 Agent”,就能把 Coding Agent 的整条后训练流水线从 Docker 环境里解放出来。
它的核心设计其实很朴素——提问、分头找证据、基于证据裁决,跟一个负责任的人类 reviewer 审 PR 的流程差不多。工程上的启发有两点:一是对需要深上下文的判断任务,让模型主动探索比塞更多静态上下文更有效;二是 env-free 路线的瓶颈从来不在 rollout 采集,而在正确性信号,verifier 做好了,那些搭不起环境、没有测试的长尾仓库就都能进训练池了。
对于在做 Coding Agent 训练、又被环境搭建成本卡住的团队来说,这是一个值得认真参考的方案。
