← 返回 2026-03-17

Code-A1:基于强化学习的代码大模型与测试大模型对抗性协同进化 Code-A1: Adversarial Evolving of Code LLM and Test LLM via Reinforcement Learning

Aozhe Wang, Yuchen Yan, Nan Zhou, Zhengxi Lu, Weiming Lu, Jun Xiao, Yueting Zhuang, Yongliang Shen 📅 2026-03-16 👍 10 2026-07-13 08:36
代码生成 协同进化 对抗学习 强化学习 测试生成

通过对抗性协同进化优化代码和测试生成,消除对人工标注测试的依赖

前置知识

强化学习(Reinforcement Learning)

一种机器学习范式,通过代理与环境交互获得奖励信号来学习最优策略。在代码生成中,奖励来自单元测试通过率,模型生成代码后执行测试,根据通过率调整参数。常用算法包括 PPO、GRPO 等,通过优势函数归一化稳定训练。关键挑战包括稀疏奖励、探索-利用平衡和训练稳定性。

本文使用 GRPO 算法优化 Code LLM 和 Test LLM,理解奖励函数设计和策略更新机制是掌握方法的核心。

自我对弈(Self-Play)

一种通过让智能体与自己博弈来提升能力的方法,常用于围棋、象棋等零和博弈游戏。在代码领域,单一模型同时生成代码和测试,通过黑盒访问防止自我勾结。但面临两难困境:白盒访问导致模型生成简单测试获取奖励,黑盒限制则错过实现特定 bug。

本文指出 Self-Play 的局限性是研究动机,Code-A1 的双模型架构正是为了解决这个核心问题。

经验回放(Experience Replay)

强化学习中存储历史经验并在训练时重复使用的技术,通过打乱时间相关性稳定训练,提高样本效率。常见于 DQN 等算法。本文的 Mistake Book 是一种经验回放缓冲区,存储每个问题历史失败的测试,用于奖励计算和防止灾难性遗忘。

Mistake Book 是 Code-A1 的核心组件,理解经验回放原理有助于掌握其如何稳定对抗训练并防止 Code LLM 遗忘已修复的 bug。

研究动机

代码生成的强化学习依赖单元测试通过率作为奖励信号,但高质量测试套件稀缺。现有数据集如 HumanEval+ 每个问题仅 3-5 个测试用例,无法可靠区分真正正确的解决方案和偶然通过的代码。更严重的是,这些静态金标准测试无法适应模型能力提升:测试太简单时,有缺陷的代码获得不应有的正奖励;测试太严时,接近正确的解被完全惩罚。近期 Self-Play 方法将代码和测试生成统一在单一模型中,但面临根本性两难:白盒访问导致自我勾结(模型生成简单测试获取奖励),黑盒限制则产生通用测试但错过实现特定 bug。

本文的目标是开发一个能够动态适应模型能力演进的代码生成强化学习框架,消除对静态人工标注测试套件的依赖。该框架需要生成既有效又具有挑战性的测试,为 Code LLM 提供精准的学习信号,同时避免自我勾结,确保训练稳定性和最终性能。

与已有工作不同的是,本文的独特切入角度是引入对抗性协同进化,将代码和测试生成解耦为两个具有相反目标的专业模型:Code LLM 通过更多测试获得奖励,Test LLM 通过暴露更多缺陷获得奖励。这种架构分离消除了自我勾结风险,安全地启用了白盒测试生成,同时通过 Mistake Book 机制实现稳定的经验回放,为奖励计算提供稳定的基准。

核心方法

Code-A1 的整体思路是模拟真实软件开发中的对抗关系:开发者努力让代码通过测试,测试员努力发现代码缺陷。通过让 Code LLM 和 Test LLM 持续相互对抗,两者能力同步提升。技术路线上,采用函数级代码生成设定,每个问题 Q 包含函数签名和自然语言规范。Code LLM 生成候选解 $\hat{C} \sim \pi_C(\cdot | Q)$,Test LLM 基于问题和候选代码生成 K 个测试用例 $\hat{T} = \{\hat{t}_1, \ldots, \hat{t}_K\} \sim \pi_T(\cdot | Q, \hat{C})$,格式为 assert func(*args) == answer。两者在沙箱中执行,通过率作为奖励基础。通过 GRPO 算法联合优化两个模型,采用不对称采样平衡计算开销。

核心创新点是将代码和测试生成解耦为两个具有相反目标的专业模型,通过架构分离消除了 Self-Play 的自我勾结风险,同时安全地启用白盒对抗测试生成。Test LLM 可以检查候选代码结构,设计针对特定逻辑弱点的测试,提供更精准的课程式学习信号。第二个关键创新是 Mistake Book 机制,一个按问题维护的经验回放缓冲区,记录历史失败测试。它提供稳定的奖励计算基线,揭示 Test LLM 是否生成渐进更难的测试,并防止灾难性遗忘。第三个核心设计是复合奖励,平衡测试有效性(可执行、正确、唯一)和对抗难度(暴露缺陷),避免生成琐碎或不可能的测试。

方法步骤详情

方法包含四个主要步骤:第一步,代码生成。对于每个问题 Q,Code LLM 生成 M 个候选解 $\{\hat{C}_1, \ldots, \hat{C}_M\}$,采用采样策略增加多样性。第二步,测试生成与验证。对于每个候选解 $\hat{C}_m$,Test LLM 基于问题和候选代码生成 N 个测试套件 $\{\hat{T}_{m,1}, \ldots, \hat{T}_{m,N}\}$。每个测试用例提取函数调用,对真实解 $C_{GT}$ 执行验证。测试有效条件是:函数调用无错误执行、在测试套件中唯一、预测答案正确。对于预测错误的测试,用真实返回值替换预测,保留测试以丰富覆盖。无效测试被丢弃。第三步,代码评估。将每个解与验证后的测试套件拼接,在沙箱环境执行,通过率作为奖励计算基础。第四步,Mistake Book 更新。新测试中当前候选解失败的加入失败集,历史测试中现在通过的从失败集移除。第五步,奖励计算与策略更新。Code LLM 奖励 $R_C(\hat{C}_m) = ?rac{1}{2}(Pass_{hist} + Avg(Pass_{new}))$(历史失败存在时)或 $Pass_{new}$(无历史失败时),平衡历史和新测试通过率。Test LLM 奖励 $R_T(\hat{T}) = ?lpha \cdot R_{val}^T(\hat{T}) + (1-?lpha) \cdot R_{adv}^T(\hat{T})$,其中 $R_{val}^T(\hat{T}) = Valid(\hat{T})$ 是有效性奖励,$R_{adv}^T(\hat{T})$ 是对抗奖励,在 $T_{hist} eq \emptyset$ 时为 $?rac{1}{2}(Pass_{hist} - Pass_{new} + 1)$,否则为 $1 - Pass_{new}$。最后通过 GRPO 更新两个模型,Test LLM 只选择方差最高的前 ℓ 个测试套件组。

技术新颖性

技术新颖性体现在多个层面:首先,将对抗性协同进化引入代码强化学习领域,创造了完全自监督的代码生成训练范式,无需任何人工标注测试。其次,提出了双模型对抗架构,通过解耦代码和测试生成任务,在避免自我勾结的同时实现白盒对抗测试,这是对 Self-Play 框架的根本性改进。第三,设计了领域特定的经验回放机制(Mistake Book),按问题维护历史失败测试,既稳定奖励计算又防止灾难性遗忘,这是对抗训练稳定性的关键贡献。第四,提出了有效性感知的复合奖励设计,平衡测试的有效性和对抗难度,解决了 Test LLM 优化中的根本性张力。最后,展示了对抗性协同进化在参数效率上的优势,3B 模型的测试生成能力超过 7B 基线模型,证明了该方法能更有效地发现 bug 揭示模式。

Overview of the Code-A1 training framework
Figure 2: Overview of the Code-A1 training framework

实验结果

实验在 Qwen2.5-Coder 模型的三个规模(1.5B、3B、7B)上进行,训练数据为 KodCode-V1 的 9,688 个高难度问题。代码生成在 HumanEval+、MBPP+、BigCodeBench 上评估,测试生成在 UnLeakedTestBench 的 10% 子集上评估。主要发现是 Code-A1 在所有规模上均达到最高平均分数,超越使用人工标注金标准测试的基线和 Self-Play 方法。在 1.5B 模型上,Code-A1 平均准确率 56.95%,比 Golden Tests 的 56.23% 高 0.72 个百分点,比 Self-Play 的 55.88% 高 1.07 个百分点。优势在小规模上最明显,说明白盒对抗测试提供的丰富学习信号对参数受限的模型特别有价值。在测试生成上,Code-A1 显著超越 Base 和 SFT 模型。最 striking 的是效率提升:3B 模型的 Mul 评分达到 15.29,超过 7B Base 模型的 14.72。所有规模都有持续改进(1.5B:7.14 vs 4.35,提升 64.1%;3B:15.29 vs 8.53,提升 79.3%;7B:19.74 vs 14.60,提升 35.2%),证实动态对抗压力对发展判别性测试生成能力至关重要。消融研究验证了关键设计:α = 0.5 达到最优,平衡验证性和对抗性。移除候选代码访问使 HumanEval+ 从 72.69% 降到 68.66%(4.01% 下降),证明白盒访问的调试优势。移除 Mistake Book 使 HumanEval+ 降到 69.66%(3.03% 下降),但 Test LLM 的 Mul 仅从 7.14 降到 6.99(2.1% 下降),说明主要作用是防止 Code LLM 灾难性遗忘。生成测试作为金标准测试时,Code-A1 生成的测试训练的 Code LLM 在 HumanEval+ 达到 71.67%,MBPP+ 达到 64.42%,超过人工标注基线(71.15% 和 63.30%)和 SFT 生成测试(71.49% 和 64.24%),证明对抗性协同进化生成的测试质量足以替代昂贵的人工标注。测试时缩放实验显示,Code-A1 的 Test LLM 有卓越判别能力:验证 Base Code LLM 时达到 65.82%,而 Base 自验证仅 65.13%。完整组合(Code-A1 Code LLM + Code-A1 Test LLM)达到 67.81%,是最高整体性能。

Performance comparison of Code LLMs
Table 1: Performance comparison of Code LLMs
Performance comparison of Test LLMs
Table 2: Performance comparison of Test LLMs
Ablation study: removing referable code, predicted answer, or Mistake Book each degrades performance
Table 3: Ablation study: removing referable code, predicted answer, or Mistake Book each degrades performance
Performance comparison of Code LLMs on three benchmarks using Qwen2.5-Coder-1.5B-Instruct as the base model and employing Golden Tests from various sources for RLVR
Table 4: Performance comparison of Code LLMs on three benchmarks using Qwen2.5-Coder-1.5B-Instruct as the base model and employing Golden Tests from various sources for RLVR
Performance of different combinations under parallel test-time scaling
Table 5: Performance of different combinations under parallel test-time scaling
Impact of trade-off weight α on model capabilities
Figure 3: Impact of trade-off weight α on model capabilities
Effect of Mistake Book
Figure 4: Effect of Mistake Book
Training dynamics (Code Reward and Test Reward) over training steps
Figure 5: Training dynamics (Code Reward and Test Reward) over training steps
查看结构化数据
任务指标本文基线提升
代码生成 avg@32 (HumanEval+/MBPP+/BigCodeBench 平均) 56.95% (1.5B), 66.15% (3B), 70.72% (7B) Golden Tests: 56.23% (1.5B), 65.14% (3B), 70.37% (7B); Self-Play: 55.88% (1.5B), 64.67% (3B), 70.39% (7B) 1.27% vs Golden Tests (1.5B), 1.55% vs Golden Tests (3B), 0.50% vs Golden Tests (7B)
测试生成 Mul (pass@5 × mut@5) 7.14 (1.5B), 15.29 (3B), 19.74 (7B) SFT: 4.35 (1.5B), 8.53 (3B), 14.60 (7B); Base: 3.63 (1.5B), 8.91 (3B), 14.72 (7B) 64.1% vs SFT (1.5B), 79.3% vs SFT (3B), 35.2% vs SFT (7B)
生成测试作为金标准 avg@32 (HumanEval+/MBPP+/BigCodeBench 平均) 56.75% (1.5B Base + Code-A1 Test) 56.23% (人工标注), 55.40% (Base Test), 56.22% (SFT Test) 0.92% vs 人工标注
测试时缩放 Avg (HumanEval+/MBPP+/BigCodeBench 平均) 67.81% (Code-A1 Code LLM + Code-A1 Test LLM) 66.15% (Code-A1 Code LLM 单独), 65.13% (Base Code LLM + Base Test LLM) 4.20% vs Code-A1 Code LLM 单独

局限与改进

作者承认的局限性包括:计算开销高,需要同时训练两个模型并进行对抗性 rollout;超参数敏感,特别是 α 权重需要仔细调节;方法针对代码生成设计,迁移到其他领域的可行性未充分探索。我观察到的额外局限性:Test LLM 的质量依赖于基础 Code LLM 的能力,如果初始 Code LLM 太弱,Test LLM 可能难以生成有意义的测试;代码覆盖性未充分评估,生成的测试可能只覆盖特定路径;长期动态稳定性的理论保证缺失,对抗训练可能陷入局部平衡;安全性考虑不足,对抗性测试生成可能被滥用于攻击。

独立分析的弱点

第一个弱点是计算开销大,同时训练两个模型并进行对抗性 rollout 的成本是单一模型的两倍以上。改进方向是引入高效的采样策略和并行化,或者探索参数共享的变体。第二个弱点是超参数敏感,α 权重、Mistake Book 更新频率等需要针对不同模型规模调节。改进方向是开发自适应的超参数调节机制,基于训练动态自动调整。第三个弱点是 Test LLM 质量依赖 Code LLM 能力,初始阶段可能陷入弱-弱平衡。改进方向是引入课程学习,先用高质量预训练测试初始化,逐步过渡到完全对抗。第四个弱点是代码覆盖性未评估,生成测试可能遗漏重要路径。改进方向是在奖励函数中引入覆盖性指标,鼓励 Test LLM 生成多样化测试。第五个弱点是安全性和鲁棒性考虑不足。改进方向是添加安全约束,防止 Test LLM 生成恶意测试,同时添加对抗防御,防止 Code LLM 过拟合特定测试模式。

未来方向

作者提出的未来方向包括:探索架构变体,如三模型系统(Code、Test、Oracle)以进一步提高稳定性;长期动态分析,研究对抗平衡的收敛条件和稳定性;迁移到其他领域,如数学推理、多模态生成等。基于成果可延伸的方向:引入多模型协同进化,一个 Code LLM 对抗多个 Test LLM,提高测试多样性;发展长期记忆机制,让 Mistake Book 跨问题共享失败模式,加速学习;探索组合对抗,Test LLM 不仅生成输入还生成代码注入,测试更复杂的漏洞;研究理论保证,分析对抗平衡的收敛条件和稳定条件;开发更全面的评估指标,除了正确性还考虑效率、安全性、可维护性。

复现评估

论文开源了代码(https://github.com/ZJU-REAL/Code-A1),提供了详细的实现描述。使用 Qwen2.5-Coder-Instruct 模型作为基础,训练数据集 KodCode-V1 包含 9,688 个高难度问题,数据充足但未公开具体问题列表。计算资源需求高,完整训练需要多张 GPU 数天时间,具体资源需求未明确说明。实现细节包括:两个模型每个问题采样 8 个响应,温度 1.0;Test LLM 每个响应生成 K = 5 个测试用例;训练 111 步使用 GRPO;不对称采样,Code LLM 生成 M 个解,Test LLM 生成 M × N 个测试套件,选择方差最高的前 ℓ 个测试套件组用于更新;α = 0.5。部分实现细节(如具体的提示设计、沙箱配置、Mistake Book 的具体数据结构)在附录中提供,但可能仍有一些细节需要实验验证。整体复现难度中等,主要挑战是计算资源和一些未完全公开的实现细节。