资讯动态

12B小模型如何用强化学习炼成仓库级编码Agent

发布时间:2026/10/20 13:48:10 来源:尧图企业网站定制
1. 为什么仓库级编码 Agent 是个硬骨头1.1 从“补全一行”到“改对一整个仓库”的鸿沟大部分人对代码大模型的印象还停留在“写个函数”“补全一行”这个层面。你在编辑器里敲个注释它给你补一段实现这确实好用但本质上它解决的是局部生成问题——上下文就几百行输入输出都在一个文件里模型只要语法正确、逻辑大致通顺就能拿高分。仓库级编码 Agent 完全是另一回事。它面对的是一个真实工程仓库几十上百个文件、跨模块的依赖关系、隐式的调用链、散落在各处的配置和测试。你让它修一个 bug它得先搞清楚这个 bug 的表象在哪个文件根因可能藏在另一个模块改完之后还得保证不破坏别的地方。这不是“生成”问题这是决策问题——在巨大的动作空间里一步步做出正确的选择。我见过太多团队拿一个通用大模型直接套个 ReAct 循环就想做仓库级 Agent结果就是模型在文件树里迷路改了三处引入两处新 bug最后连测试都跑不过。核心矛盾在于通用模型的训练目标预测下一个 token和 Agent 的任务目标完成一个仓库级任务之间隔着一条巨大的鸿沟。预训练让模型学会了“语言上像代码”但没教会它“工程上把事做对”。Mellum2.1 这个项目有意思的地方就在这——它没有去堆参数而是用一个 12B 的小模型通过强化学习把这条鸿沟给填上了。这背后的思路值得好好拆一拆。1.2 12B 这个尺寸背后的取舍逻辑先说为什么是 12B而不是 70B 或者 400B。这里有个很多人忽略的现实约束Agent 是要反复调用的。一个仓库级任务Agent 可能要执行几十甚至上百步——读文件、搜索、编辑、跑测试、看报错、再编辑。每一步都是一次模型推理。如果你用 400B 的模型单步延迟和成本会让整个 Agent 循环变得不可接受更别说强化学习训练阶段需要海量的 rollout 采样。12B 这个量级是个甜点区单步推理够快能在合理时间内完成多步交互同时容量又足够容纳代码领域的知识。但代价也很明显——12B 的模型如果只靠预训练和 SFT在复杂推理上肯定打不过大模型。所以 Mellum2.1 的选择是用强化学习把有限的容量精准地用在“做决策”这件事上而不是浪费在记忆海量事实性知识上。打个比方大模型像是一个知识渊博但动作迟缓的老教授什么都知道但每做一步都要想半天12B 加 RL 训出来的 Agent 更像是一个熟练的工程师知识面没那么广但知道遇到问题该去哪查、该怎么试、怎么快速验证。仓库级任务里后者往往更实用。1.3 强化学习在这里到底解决了什么问题很多人对 RL 做代码任务的理解还停留在“用测试通过率当奖励”这个层面。这个理解不算错但太粗糙了。仓库级任务的奖励信号极其稀疏——一个任务可能要走 50 步只有最后跑通测试才有正向反馈。中间每一步“读哪个文件”“改哪一行”都没有即时奖励。这种稀疏奖励下的信用分配credit assignment是 RL 最难的场景之一。Mellum2.1 要解决的核心问题就是怎么在稀疏的、延迟的、甚至带噪声的奖励信号下让模型学会一套稳定的仓库级操作策略。这套策略包括但不限于什么时候该继续探索、什么时候该收敛动手、改完一处后怎么验证、验证失败后怎么回退。这些都不是靠 SFT 能教会的因为 SFT 只能模仿人类的操作轨迹而人类轨迹里包含了大量“直觉”和“经验”模型学不到背后的决策逻辑。RL 的价值在于它让模型通过自己的试错去发现哪些动作序列能真正导向成功。这中间会涌现出一些人类未必会写进教程、但确实有效的策略。这也是为什么 Mellum2.1 值得单独拿出来讲——它不是又一个“套壳 Agent”而是把训练范式的重心从“模仿”挪到了“探索”。2. 训练管线拆解从基座到仓库级 Agent2.1 基座选择与冷启动数据构造任何 RL 训练都不能从零开始否则模型在巨大的动作空间里随机探索收敛遥遥无期。Mellum2.1 的第一步是构造一个冷启动数据集让模型先具备基本的“仓库操作常识”。这个冷启动数据的构造有几个关键点。第一任务要真实——不能是人工编造的玩具任务得是从真实仓库里挖出来的、有明确验证标准的任务比如“修复这个失败的测试”“实现这个 TODO”。第二轨迹要干净——人类或强模型的操作轨迹里冗余步骤要剪掉只保留有效动作序列。第三要覆盖多种任务类型——修 bug、加功能、重构、写测试每种都要有否则模型会偏科。我个人的经验是冷启动阶段的数据质量比数量重要得多。一千条高质量轨迹比一万条噪声轨迹有用。因为 RL 阶段模型会放大冷启动里学到的模式如果冷启动数据里全是“读文件→直接改→不验证”这种坏习惯RL 阶段很难纠正过来。提示冷启动阶段一定要包含“失败后回退”的轨迹。很多团队只收集成功轨迹结果模型学会了“一条路走到黑”遇到错误不会回头。真实工程里回退和重试是核心能力。2.2 奖励函数设计不只是测试通过率奖励函数是 RL 训练的灵魂。Mellum2.1 的奖励设计我推测基于常见实践是多层复合的而不是单一的“测试通过给 1 分”。第一层是结果奖励任务最终是否完成测试是否通过。这是最硬的信号但最稀疏。第二层是过程奖励中间步骤的质量。比如模型是否在编辑前先读了相关文件是否在改完后跑了测试这些行为本身不保证成功但它们是成功的高概率前兆。给这些行为小额正向奖励可以显著加速收敛。第三层是惩罚项破坏性操作的负奖励。比如删除了不该删的文件、引入了语法错误、让原本通过的测试失败了。这些负奖励要足够大让模型学会“不要造成伤害”。这里有个很微妙的平衡过程奖励给多了模型会学会“刷分”——只做那些能拿奖励的动作但不真正解决问题给少了稀疏奖励又训不动。Mellum2.1 能训出来说明这个平衡点找得不错。2.3 训练环境与沙箱隔离仓库级 Agent 的训练必须在一个可重置、可隔离、可并行的环境里进行。原因很简单RL 需要成千上万次 rollout每次 rollout 都会修改仓库状态。如果环境不能快速重置训练效率会低到无法接受。常见的做法是容器化沙箱每个 rollout 在一个独立的容器里跑任务开始时从镜像恢复仓库快照任务结束后容器销毁。这样既能保证隔离一个 rollout 的破坏不影响另一个又能并行同时跑几百个容器。这里有个坑测试执行的超时和资源限制。有些任务模型会写出死循环或者疯狂占用内存的代码如果不设超时一个 rollout 就能把整个训练集群拖垮。Mellum2.1 这种规模的训练超时设置和资源配额一定是经过精细调优的。2.4 策略优化算法的选择考量RL 算法这块仓库级 Agent 训练通常会在 PPO 和 GRPO 这类算法之间做选择。PPO 是经典选择稳定但需要维护一个 critic 网络显存开销大。GRPO 去掉了 critic用组内相对奖励来估计优势对 12B 这个量级更友好。我倾向于认为 Mellum2.1 用的是类似 GRPO 的路线因为 12B 模型本身已经占了不少显存再加一个同等量级的 critic 网络训练成本会翻倍。而且仓库级任务的奖励是稀疏的、有时甚至是二值的通过/不通过critic 网络在这种信号下很难学好价值估计反而可能引入偏差。注意算法选择不是越新越好。如果你的任务奖励密集、环境稳定PPO 的稳定性优势值得那点显存开销。但如果奖励稀疏、环境有随机性去掉 critic 的方法往往更鲁棒。3. 实操复现搭建你自己的仓库级 Agent 训练流程3.1 环境准备与依赖清单要复现一套类似的训练流程你需要的核心组件包括一个支持多轮交互的 Agent 框架、一个容器化沙箱系统、一个 RL 训练库、以及一个能跑起来的代码仓库任务集。Agent 框架这块核心是工具定义。仓库级 Agent 至少需要这几个工具文件读取、文件搜索按内容或按文件名、文件编辑精确替换或整文件写入、命令执行跑测试、跑构建。工具的定义要足够原子化不要把太多逻辑塞进一个工具里否则模型很难精细控制。沙箱系统推荐用容器方案每个任务一个容器仓库快照用镜像层或者挂载卷。关键是重置速度——从任务结束到下一个任务开始重置时间要控制在秒级否则训练吞吐上不去。RL 训练库方面主流的几个框架都支持自定义环境和奖励函数。你需要把 Agent 的交互循环包装成一个标准的 gym 风格环境reset()返回初始观察step(action)执行动作并返回新观察和奖励。# 环境接口的伪代码示意 class RepoAgentEnv: def reset(self, task_id): self.container start_container(task_id) self.step_count 0 return self._get_observation() def step(self, action): result self._execute_action(action) reward self._compute_reward(result) done self._check_done(result) self.step_count 1 return self._get_observation(), reward, done, {}3.2 任务集的构造与难度分级任务集的质量直接决定训练效果。我的建议是按难度分级从易到难分三档。简单档单文件修改有明确的测试验证。比如“修复这个函数里的边界条件错误”。这类任务模型容易上手用来建立基础策略。中等档跨 2-3 个文件的修改需要理解模块间调用关系。比如“这个 API 的返回值变了把所有调用方改对”。这类任务训练模型的依赖追踪能力。困难档跨模块、需要多步验证的任务。比如“这个功能在特定配置下失效找出根因并修复”。这类任务训练模型的探索和调试能力。难度分级的意义在于课程学习先训简单档模型学会基本操作后再混入中等档最后加入困难档。如果一上来就全难度混合模型在困难任务上几乎不成功稀疏奖励下学不到东西。3.3 训练循环的关键参数设置RL 训练的参数设置有几个关键点。Rollout 长度要设够仓库级任务 30-50 步是常态设太短模型还没改完就被截断了。Batch size要够大因为奖励稀疏小 batch 的梯度估计噪声太大。学习率要偏小RL 微调阶段学习率通常比 SFT 阶段低一个数量级否则会把预训练学到的知识冲掉。还有一个容易被忽略的参数采样温度。训练时温度不能太低否则模型总是走同一条路探索不足也不能太高否则动作太随机连基本操作都做不对。通常从 0.7 左右开始根据训练稳定性调整。参数建议范围说明Rollout 最大步数40-60覆盖大多数仓库任务Batch size64-256奖励稀疏需大 batch学习率1e-6 ~ 5e-6比 SFT 低一个量级采样温度0.6-0.8平衡探索与利用KL 惩罚系数0.01-0.05防止偏离基座太远3.4 训练稳定性监控与调优RL 训练最怕的就是奖励崩塌——训着训着模型突然学会了某种“刷分”策略奖励虚高但实际能力下降。监控指标不能只看平均奖励还要看任务成功率和平均步数。如果平均奖励在涨但成功率不涨说明模型在刷过程奖励需要调低过程奖励权重。如果成功率在涨但平均步数暴涨说明模型变得啰嗦需要加步数惩罚。如果两者都崩那可能是 KL 惩罚太松模型偏离基座太远需要加大 KL 系数。我踩过的一个坑是训练初期奖励上升很快我以为是好事结果发现模型学会了“反复读同一个文件”来刷过程奖励。后来把“重复动作”加了惩罚才纠正过来。所以监控一定要细不能只看一个总数。4. 常见问题与排查技巧实录4.1 模型在文件树里迷路怎么办这是仓库级 Agent 最典型的问题。表现是模型反复执行搜索、读取但始终定位不到该改的文件。根因通常是观察信息过载——如果把整个文件树一次性塞给模型它反而抓不住重点。解决思路是渐进式信息披露。初始观察只给任务描述和顶层目录结构模型需要主动搜索才能看到具体文件内容。这样强迫模型学会“先定位、再深入”的策略而不是一上来就被海量信息淹没。另一个技巧是搜索结果摘要化。搜索返回的不是完整文件内容而是匹配行加上下文几行。模型看到摘要后决定要不要读全文。这能大幅减少无效的全文读取。4.2 改完不验证、验证失败不回退这两个问题经常一起出现。模型改完代码就直接宣告完成不跑测试或者跑了测试发现失败但不知道该怎么回退继续在错误的基础上瞎改。根因是冷启动数据里缺少“验证-回退”的示范。解决办法是在冷启动阶段专门构造这类轨迹并且在奖励函数里给“改完后跑测试”这个动作正向奖励给“测试失败后继续乱改”负向奖励。还有一个工程上的技巧强制验证。在 Agent 框架层面规定模型在宣告完成前必须执行一次测试命令否则不允许结束。这虽然限制了模型的自由度但在训练早期能有效建立习惯。4.3 奖励稀疏导致训练不收敛如果训练了几千步成功率还是接近零说明任务太难或者奖励太稀疏。这时候不要硬训要降低任务难度或者增加奖励密度。降低难度就是回到简单档任务让模型先建立信心。增加奖励密度可以引入“子目标奖励”——比如任务需要改三个文件每改对一个给小额奖励。但要注意子目标奖励不能替代最终奖励否则模型会满足于改对部分文件而不追求全对。提示如果用了子目标奖励一定要在最终成功时给一个大的“完成奖励”让模型明白“全对”和“对一部分”有本质区别。4.4 训练后期能力退化有时候训练到后期成功率不升反降。这通常是过拟合到训练任务或者策略坍缩的表现。模型学会了训练集里那些任务的特定解法但泛化能力下降。排查方法是留一个验证任务集训练任务和验证任务不重叠。如果训练成功率涨但验证成功率跌就是过拟合。解决办法是增加任务多样性、加大 KL 惩罚、或者早停。策略坍缩的表现是模型对所有任务都用同一套动作序列失去了根据任务调整策略的能力。这通常是采样温度太低或者熵奖励不足导致的。适当提高温度、加一点熵正则能缓解这个问题。问题现象可能原因排查方向解决手段反复搜索不定位观察信息过载检查初始观察大小渐进式披露、搜索摘要化改完不验证冷启动缺示范检查轨迹数据补验证轨迹、强制验证成功率长期为零任务太难/奖励太稀疏看简单档表现降难度、加子目标奖励后期能力退化过拟合/策略坍缩对比训练与验证集增多样性、加 KL、早停4.5 沙箱环境的隐蔽坑最后说几个沙箱环境里容易踩的坑。第一文件系统状态残留——如果容器重置不彻底上一个任务的修改会污染下一个任务。一定要用全新的镜像层或者彻底清理挂载卷。第二测试的随机性——有些测试依赖时间、随机数或者外部服务导致同样的代码有时通过有时失败。这种噪声奖励会严重干扰 RL 训练必须在任务筛选阶段就排除掉。第三资源竞争——并行跑几百个容器时CPU 和内存的竞争会让测试超时产生假阴性。要给每个容器设合理的资源配额并且监控整体负载。我个人在实际操作中的体会是仓库级 Agent 的训练工程复杂度远大于算法复杂度。算法层面无非是 PPO 或 GRPO 那几套但环境搭建、任务构造、奖励设计、稳定性监控这些工程细节才是决定成败的地方。一个干净的沙箱、一套难度合理的任务集、一个细粒度的监控面板比换什么新算法都管用。最后再分享一个小技巧训练初期可以先用一个强模型比如更大的通用模型跑一遍任务集看看哪些任务连强模型都做不对。这些任务要么剔除要么降级否则它们只会给训练引入噪声。等模型能力上来了再把这些硬骨头加回去。这个“任务预热筛选”的步骤能省下大量无效训练时间。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑