上海交通大学与字节跳动提出Dockerless系统,无需Docker环境即可判断代码修复正确性,通过主动侦查代码仓库生成验证证据并综合裁决。在多个测试集上达到62.0%问题解决率,超越同类模型,且与真实测试环境训练性能接近。
上交大与字节跳动联手:不用Docker训练顶级代码AI
时间:2026-08-03
浏览:182
文章目录
上海交通大学与字节跳动旗下抖音集团联合完成的研究,于2026年6月26日以预印本形式发布,编号为arXiv:2606.28436。全文可在arXiv上检索该编号获取。
考虑一个场景:假设你运营一个程序员培训班。每次测试学员编写的代码是否正确,都需要为每位学员单独搭建完整的开发环境——安装特定版本的语言运行时、配置专属依赖库、搭建测试基础设施。同时,为每个委托方公司的每套代码库都创建独立的“测试工厂”。这种做法不仅消耗巨大的人力,而且当委托方的代码库为私有、长期未维护或缺乏像样的测试用例时,该流程将完全失效。
这一困境恰恰是当前训练代码AI的关键瓶颈。现有的自动修复GitHub真实软件Bug的智能体,训练时高度依赖“执行验证”机制——让AI生成修复代码后,在项目环境中实际运行测试,根据测试是否通过来评分。该机制要求每个开源项目都必须拥有独立的Docker容器,其中包含精确匹配的依赖库、测试脚本和运行工具。搭建这些环境本身就构成一项庞大工程,即便采用最先进的自动化流水线,也只能覆盖候选代码库中的极小部分。至于企业内部的私有代码库、二十年前的遗留系统,几乎不可能通过这种方式训练AI。
为突破这一痛点,上交大和抖音团队推出了名为Dockerless的系统。名称已经说明其核心理念:不需要Docker,不需要任何特殊运行环境,照样能够验证AI修复的代码是否正确。
一、测试环境为何成为核心难题
理解Dockerless之前,需要明确“测试环境”的重要性为何成为AI训练绕不开的关键。
训练代码AI的流程类似于培训新程序员。首先向AI展示大量“正确修复案例”,使其学习修复Bug的模式——这称为监督微调(SFT)。然后让AI自行尝试修复,修复正确给予奖励,错误则给出惩罚,在反复试错中不断提升——这称为强化学习(RL)。无论哪个阶段,都需要一个可靠的裁判,用于判定“AI这次修复是否有效”。
目前最可靠的裁判就是执行测试:将AI生成的修复代码放入项目环境,运行最新测试用例,全部通过判定为正确,有任何测试失败则判定为错误。这一裁判机制非常准确,但代价高昂。研究人员发现,即便借助自动化工具,也只能对有限比例的代码库成功搭建可用的测试环境。更现实的是,企业内部私有代码、二十年前的遗留系统几乎不可能为AI训练专门构建环境。
换句话说,现有的代码AI训练方法仅适用于那些恰好拥有完整Docker环境和测试套件的开源项目,覆盖范围极为狭窄。现实世界中数量更庞大的“长尾”代码库,这套体系完全失效。
研究团队意识到,解决之道不在于如何更高效地搭建环境,而在于彻底绕开环境依赖。关键突破口在于:能否训练出一个足够智能的“裁判”,仅通过阅读代码本身就能判断修复是否正确——就像一位经验丰富的老工程师,无需运行测试,仅凭代码审视就能判断修改是否可行。
二、现有无环境验证方法的局限
在Dockerless出现之前,学术界已尝试过不依赖测试环境的打分方法,统称为“无环境验证器”(environment-free verifier)。现有方法大致分为两类,但均存在明显缺陷。
第一类方法是直接使用大型语言模型(LLM)作为裁判。将问题描述、参考答案(正确修复代码)和AI生成的修复代码一同输入大模型,让其判断修复是否正确。问题在于,大模型裁判只能看到代码文本,完全不了解整个代码仓库的上下文。这就好比让一个从未进过厨房的人,仅凭菜谱文字来判断一道菜是否做得好——无法得知灶台火候、食材状态等真实情况。
第二类方法是训练专门的验证器模型。部分团队尝试训练用于判断代码修复好坏的专业模型,例如SWE-Gym Verifier、R2E-Gym Verifier、OpenHands Critic和DeepSWE Verifier。这些模型同样存在根本问题:打分时仅依赖表面信息,不会主动查询代码仓库。
有一个典型的反例:假设标准答案使用辅助变量实现某逻辑,而AI答案使用内联三元表达式实现完全相同的逻辑。两种写法功能等价,但代码外观截然不同。单纯比较代码文本,相似度极低,表面层面的评分方法会判定AI答案错误。然而,如果能够深入查阅代码仓库,确认两种写法在实际调用链和边界情况处理上效果一致,才能做出正确判断。
正是基于这一洞察,研究团队设计了Dockerless:一个能够主动“侦查”代码仓库的智能裁判。
三、Dockerless的工作原理:会问问题的侦探
理解Dockerless的工作方式,可以类比侦探破案。优秀侦探判断嫌疑人时,不会只盯着面部反复比对,而是主动外出调查:前往案发现场勘查、查阅档案、访问目击者、收集物证。收集足够线索后,再综合所有证据做出判断。
Dockerless的工作流程完全相同,分为两个阶段。
第一阶段:出题调查
给定一个问题描述、一个参考答案(正确修复代码)和一个待判断的AI修复代码,Dockerless首先从问题描述和参考答案中推导出2到4个“侦查问题”。例如:“修复应发生在代码仓库的哪个位置?”“修改后的代码应实现什么功能?”“什么样的测试或断言能证明修复正确?”“仓库中还有哪些地方可能受到本次修改的影响?”推导出问题后,Dockerless为每个问题派出一个“子侦探”(sub-agent),这些子侦探并行工作,各自通过只读的命令行工具(如find、grep、rg)在代码仓库中翻查线索,每个子侦探最终返回一段包含代码证据的简短回答。
第二阶段:综合判决
所有子侦探返回调查结果后,Dockerless将问题描述、参考答案、待判断的修复代码以及所有问答对,一起提交给最终判决模型。判决模型综合所有证据,输出一个二进制裁决:1表示修复正确,0表示不正确。为了获得更精细的连续评分,研究团队巧妙读取模型输出“1”和“0”两个词的概率值,使用简单公式将其转换为0到1之间的连续分数。分数越高,表明Dockerless对修复正确的置信度越高。
这一设计的精妙之处在于,Dockerless并非比较AI答案与标准答案的相似程度,而是用证据验证AI答案是否真正解决了问题。如同侦探并非在问“嫌疑人长相与目击者描述有多像”,而是在问“全部证据能否指向此人就是真凶”。
四、Dockerless的训练方法
确定了架构设计后,下一个问题是如何让Dockerless掌握这套侦查与判断能力。
训练过程采用“拒绝采样”(rejection sampling)方法,可理解为“留优去劣的示范学习”。研究团队使用一个强大的教师模型(GLM-5)作为初始侦探,在3700个带有执行标签的代码问题上运行整个流程。所谓“有执行标签”,是指这些问题拥有真实测试环境,可以运行测试并获得确定的对错结论——这是训练数据收集阶段唯一用到测试环境的地方。
教师模型在每个问题上完成流程后给出一个裁决。研究团队仅保留那些裁决结论与真实测试结果一致的轨迹,即“教师判对的案例”,丢弃判错的。这一筛选过程确保了训练数据质量——Dockerless只从正确的推理过程中学习,而非从“凑巧说对了”的偶然案例中学习。
为防止正负样本比例严重失衡(错误修复通常远多于正确修复),研究团队将负样本与正样本的比例上限控制在4:1。最终训练数据覆盖3700个独立问题,每个训练案例包含问题生成轨迹、若干子侦探调查轨迹,以及一段最终判决轨迹。整个Dockerless系统使用一个共享神经网络骨干(基于Qwen3.5-9B模型)统一训练,问题生成、子侦探调查、最终判决三个子任务共用同一套参数。训练在验证集上以标准下一词预测损失为目标,最佳检查点大约在150步优化后出现。
五、使用Dockerless训练代码AI:两阶段完整流水线
Dockerless训练完成后,可作为核心裁判,支撑一套完全不依赖Docker环境的代码AI训练流水线。该流水线分为两个阶段,对应代码AI训练的标准步骤。
第一阶段:监督微调
传统做法是让AI在带测试环境的项目上运行,收集测试通过的修复轨迹作为训练数据。新做法是:让AI在一个极简的Linux基础镜像上运行,完全不搭建任何项目专属环境,收集大批量修复尝试轨迹,然后使用Dockerless对每个轨迹的最终修复代码打分,仅保留得分最高的那一批,用于训练AI。
具体而言,研究团队在SWE-Rebench-v2数据集上采用这种方式收集了16000条修复轨迹,然后让Dockerless对所有轨迹打分,仅保留得分最高的4000条作为最终训练数据。每条轨迹会经过2次独立的Dockerless评估,取平均分作为最终得分,以提升评分稳定性。
第二阶段:强化学习
以第一阶段训练好的模型为起点,针对每个代码问题,让AI生成一组8条修复尝试,使用Dockerless对每条修复打分。然后采用GRPO算法,将得分高的修复对应的策略方向强化,得分低的方向弱化。整个过程同样不需要运行测试,也不需要任何项目专属的Docker环境。强化学习阶段总共训练50步,每条修复同样经过2次独立的Dockerless评估取平均。
六、实验结果:数据验证效果
研究团队在三个标准测试集上评估了整套系统:SWE-bench Verified(英文Python代码库测试集)、SWE-bench Multilingual(多语言代码库测试集)和SWE-bench Pro(更难的长周期任务测试集)。评估指标为“问题解决率”,即AI正确修复的真实软件问题百分比。
从验证器性能来看,Dockerless在专门构建的验证器评估基准(776个样本)上,SWE-bench Verified分支达到81.0的AUC分数(AUC衡量分类器判别能力,满分100),Multi-SWE-bench Flash分支达到72.1分。对比之下,最好的开源训练验证器DeepSWE Verifier在两个分支上分别仅为66.7和62.9分,差距超过14分;GPT-5.4、GLM-5等顶级商业大模型零样本作裁判,最高分别只有75.9和63.9,同样明显低于Dockerless。
从下游代码AI性能来看,以Qwen3.5-9B为基础模型,经过两阶段完全无环境训练后得到的Dockerless-RL-9B模型,在三个测试集上分别达到62.0%、50.0%和35.2%的问题解决率,比基础模型分别提升2.4、8.7和2.9个百分点。这一结果超越了所有同等规模(参数量低于100亿)的开源代码AI专项模型:比SWE-Lego-8B高出约20.8、31.0和19.1个百分点,比SWE-Gym-7B和SWE-Dev-7B的差距更加明显。
更值得关注的是横向对比。研究团队特意设计了受控实验,以分离SFT阶段和RL阶段各自的贡献,并与使用真实测试环境的对照组进行比较。
在SFT阶段,“用真实Docker环境筛选轨迹训练的模型”(Env-SFT-9B)在三个测试集上分别达到60.0%、48.3%和33.9%,而“用Dockerless筛选无环境轨迹训练的模型”(Dockerless-SFT-9B)则为60.6%、47.7%和35.3%。两者非常接近,有时无环境版本还略胜一筹。
在RL阶段,以相同SFT模型为起点,分别尝试了三种奖励来源:用Dockerless打分(Dockerless-RL-9B)、用DeepSWE Verifier打分、以及用真实测试执行打分(Test-Execution RL)。结果显示,真实测试执行版本(62.4%、51.3%、35.7%)略好于Dockerless版本(62.0%、50.0%、35.2%),差距在0.4到1.3个百分点之间,属于非常微小的差异。而Dockerless版本则以1.4到2.7个百分点的优势明显胜过DeepSWE Verifier版本。
七、细节探讨:验证问题数量与计算开销
研究团队还仔细研究了一个实用问题:子侦探应调查多少个问题,才能使Dockerless性能最优?
对验证问题数量K从0到8逐一测试,结果揭示了一个清晰规律:K等于0时(完全不调查,直接判断),AUC为78.3分;K从1增加到4时,AUC稳步提升,在K等于4时达到最高的81.0分;K继续增加到6和8时,AUC反而下滑到79.6和80.3。这表明适量调查有助于裁判做出更准确判断,但问题过多后,新增结果往往是冗余甚至带来噪音的,边际收益递减。因此,最终Dockerless在推理时设定生成2到4个验证问题,在准确性和计算效率之间取得平衡。
在计算开销方面,研究团队以7680条强化学习训练轨迹为样本,分析了三种奖励来源下每条轨迹的耗时分解。结果显示,AI生成修复轨迹本身平均耗时约2308秒,是整个流程的绝对主体。奖励计算的额外耗时为:DeepSWE Verifier增加41秒(约1.7%),真实测试执行增加83秒(约3.5%),Dockerless增加180秒(约7.2%)。虽然Dockerless需要主动调查代码库,比简单查表的方法慢一些,但额外开销仅占总时间的7.2%,属于可接受范围。从总耗时分布图来看,三种奖励来源的总耗时分布几乎完全重叠,以2400到3000秒为主体的单峰分布,并伴有向硬超时方向延伸的长尾。这说明整个流程的瓶颈在于那些运行缓慢、接近超时的修复轨迹,而非奖励计算本身。
八、真实案例:相同逻辑,不同写法
论文中一个真实案例生动说明了Dockerless的核心价值。这是一个来自matplotlib(Python数据可视化库)的Bug修复任务,问题在于图表偏移量文字(offsetText)的颜色应使用标签颜色(labelcolor),而非刻度颜色(tick.color)。
参考答案(正确修复)的写法是:先用辅助变量提取正确颜色,再将辅助变量赋值给offsetText。AI生成的候选修复则是:直接用内联三元条件表达式,在赋值的同时完成颜色逻辑判断。两种写法语义完全等价,但代码结构差异明显。
文本相似度比较的结果仅为0.468分(满分1.0),大幅偏低。DeepSWE Verifier给出的分数只有0.035,几乎直接判定为错误修复。而Dockerless派出两个子侦探调查了两个问题:第一个子侦探确认AI的修复同时更新了XAxis和YAxis两个初始化路径,与标准修复一致;第二个子侦探确认AI的修复正确保留了“inherit”继承语义。基于这两条来自代码库的实证线索,Dockerless给出了0.996的高分,与真实测试执行结果(正确,满分1.0)高度吻合。
九、无环境训练的边界:语言差异
当然,没有任何方法是万能的。研究团队通过细致的分语言分析,诚实地指出了无环境训练方法的局限边界。
在Python、Go、JavaScript、Java、PHP、Ruby这些高使用量语言上,有环境训练与无环境训练的效果差异普遍在正负2.5个百分点以内,两者基本旗鼓相当。但在Rust和C这两门语言上,有环境训练的效果分别高出约7.0和13.3个百分点,差距相当显著。
研究团队分析,这一差距的根本原因在于:Rust和C都是强编译型语言,编译器本身就是一个非常强力的调试助手。在有环境的条件下,AI修复代码时能实时看到编译器报出的类型错误、链接失败等信息,这些信息极大地帮助AI在多轮尝试中收敛到正确答案。而在无环境条件下,AI只能从源代码本身推断这些信息,缺失了这一信道。研究团队指出,这个差距的解法可能不在于收集更多有环境的训练数据,而在于设法在无环境流水线中引入某种形式的编译器反馈模拟,这被留作未来工作。
总体而言,Dockerless这项研究证明了一件以前被认为必须依赖测试执行的任务——判断代码修复的正确性——可以通过智能的代码库调查来接近等效地完成。这一结论在工程实践上的意义非常深远。企业里庞大的私有代码仓库、年久失修的遗留系统、没有完整测试套件的开源项目,都可能因此受益于高质量的AI辅助。训练一个好的代码AI,不必再事先为每一个代码库单独搭建一套测试基础设施。
当然,这并不意味着测试执行从此变得不重要。真实的测试环境在某些场景下仍然提供无可替代的精确信号,尤其是编译型语言的强编译器反馈。但Dockerless为那些无法依赖测试环境的大多数场景,提供了一条切实可行的替代路径。
对于关心AI辅助编程未来发展的读者,一个值得思考的问题是:随着这类无环境验证技术的成熟,代码AI的训练数据来源会如何演变?私有企业代码库是否会成为下一批大规模训练语料?企业代码安全与AI训练数据之间的张力,将会如何影响技术的实际落地?这些问题目前尚无定论,但Dockerless的工作无疑推开了这扇大门的一条缝。对这项研究感兴趣的读者,可通过arXiv编号2606.28436查阅完整论文,原文包含完整的提示词模板、训练超参数配置以及更详细的消融实验结果。
Q&A
Q1:Dockerless是什么,它解决了什么问题?
A:Dockerless是由上海交通大学与字节跳动联合研发的代码修复验证器,它能在不搭建任何项目专属Docker测试环境的情况下,判断AI生成的代码修复是否正确。传统方法需要为每个代码库单独配置测试环境,耗时费力且无法覆盖私有或遗留代码库,Dockerless通过主动调查代码仓库内容来替代执行测试,绕开了这一工程瓶颈。
Q2:Dockerless不运行测试,怎么知道代码修复是否正确?
A:Dockerless采用“侦探调查”式的工作方式:先从问题描述中生成2到4个关键侦查问题,再为每个问题派出一个独立的子智能体,在代码仓库中用只读命令行工具查找证据,最后将收集到的所有问答证据交给判决模型综合分析,输出一个0到1之间的置信评分。这种方式让它能识别出功能等价但写法不同的修复,而不是简单比较代码文字相似度。
Q3:Dockerless训练的代码AI和传统方法训练的效果差多少?
A:在SWE-bench Verified、Multilingual和Pro三个标准测试集上,用Dockerless完全无环境流水线训练的Dockerless-RL-9B模型,与用真实测试执行训练的对照模型相比,差距约在0.4到1.3个百分点之间,表现非常接近。但在Rust和C这类强编译型语言上差距更明显,约7到13个百分点,这被认为是编译器反馈信息缺失所致。
实用工具推荐
绿化、压缩、噪点和虚拟水印,自由调节做旧程度。
选择画质和输出格式,预览压缩前后的大小。