O-Researcher这个名字,最近在开源社区讨论度挺高。它最抓人的点是:一个开源基座模型,按传统思路调SFT、调RLHF,评测分数已经顶在天花板附近了;但把它拆成多个智能体,让每个角色各管一段推理过程,再用强化学习把整支“队伍”的协作策略练出来,居然能在好几类复杂任务上追平甚至反超闭源大模型。这篇就来拆它的设计逻辑和训练细节,重点回答三个问题:多智能体任务怎么编排,强化学习怎么练,以及刷新SOTA时避不开的工程坑。
1. 从“单模型打天下”到“智能体小队”:O-Researcher到底在解决什么
1.1 开源大模型离SOTA的差距不在“知识量”,而在“推理链控制”
这两年开源基座模型的进步大家有目共睹,预训练语料、模型结构、长上下文能力都拉得很近,单看知识密度和基础对话质量,开源和闭源的差距已经不明显了。但一上复杂任务就露馅:需要多步推理、多条件约束、中途校验的数学证明、代码调试、文献综合分析,开源模型经常前几步做得有模有样,后面越推越歪,甚至把最初明确给出的条件给忘了。这种问题靠堆数据、加长CoT能缓解,但天花板很低。
我的理解是,差距不在“知识量”,而在“推理链控制”。单模型推理是一条隐形的、端到端的链子,模型内部没有一个显式的“检查点”,错了也只会沿着错误一路推下去,最后产出一个逻辑自洽但实际错误的答案。多智能体的思路,本质上是把这条隐形链子拆成一段一段可见的流程,让每一段都有专门的模型负责、有明确的输入输出接口,出错时能被下一个角色拦下来。
这也解释了为什么O-Researcher的路线不是“继续压榨单模型”,而是把推理过程重构。它不试图让一个模型全知全能,而是承认单模型会犯错,然后把“纠错”变成系统中一个显式的、可训练的环节。这个视角的转变,是后面所有设计的出发点。
1.2 为什么选“多智能体+强化学习”,而不是更长的CoT或静态流程
可能有人会问:那直接写一个固定的智能体流水线,规划器、执行器、检查器串起来,不也能解决问题吗?能,但静态流水线的上限取决于每个模块的手写提示词和路由规则,一旦任务分布变了,规则就得重新调,而且模块之间没有反馈回路,某个角色连续犯错时,其它角色不会针对性地调整策略。
O-Researcher选择“多智能体+强化学习”的动机也在这里:它要把模块间协作的策略本身变成一个可优化的对象。强化学习在这里干的事情,不是让单个模型会做某道题,而是让整支智能体小队学会在多个回合的博弈中做决策——什么时候该相信分析器的结论,什么时候必须让验证器多跑几轮,什么时候规划器要推翻上一版方案重新拆解。固定规则写不出来这种动态判断,但奖励信号能。
对比一下三种路线的差异更直观:
| 方案 | 错误能否被拦截 | 协作策略是否可优化 | 对任务分布的适应性 | 工程成本 |
|---|---|---|---|---|
| 单模型长CoT | 不能,错了就一路错到底 | 不可,只有端到端隐式学习 | 一般 | 低 |
| 静态Agent流水线 | 局部能,靠手工规则 | 不可,靠人调prompt | 弱 | 中等 |
| 多智能体强化学习(O-Researcher路线) | 能,验证角色显式纠偏 | 可,奖励信号驱动整体优化 | 强 | 高 |
当然,工程成本高是实打实的坏处。多智能体RL的训练要比单模型SFT贵出一个量级,后面第五节会专门算这笔账。这里先记住结论:它解决的是“单模型推理链失控”的问题,代价是训练和推理都变得更重。
1.3 一个直观例子:一道多步数学题的错误拦截
举个简化例子说明区别。假设任务是一道需要列方程、分情况讨论、回代验证的多步数学题:
单模型的做法:一遍生成完整解题步骤,最后给出答案。如果中间某一步把约束条件“非负整数”漏看了,后续步骤全部基于错误分支展开,全程没有任何机制回到第二步重新审视。即使模型在训练时见过类似题,也无法在推理阶段主动“返回”修正,除非重新生成整条链,而重新生成又可能引入新的错误。
多智能体的做法:规划器先抽象出大致解题路径;分析器逐条件枚举可能分支;草稿生成器只负责把规划后的步骤写成严密推导;验证器则会把答案代入原题条件,发现“漏掉非负约束”,向规划器反馈修改请求;规划器调整方案后重新执行。
这个例子看起来简单,但已经把多智能体的优势说清楚了:错误被显式拦截,而不是累积。后面要聊的强化学习,就是让这套拦截和修正行为不只是“偶尔发生”,而是被训练成稳定的策略——不是每次都有运气蒙对,而是系统性地提升“第一次做对、错了能改回来”的概率。
2. 内部架构拆解:一条任务怎么被“一支队伍”接力完成
2.1 五个角色的职责与边界
O-Researcher的现代版本里有五个核心角色:规划器、分析器、草稿生成器、验证器、总结器。它们的职责边界是刻意做出来的,不是随便分了五个模型上去。
- 规划器:读取任务目标,拆解子任务,生成执行路径,并维护一组全局约束,例如“不准跳过步骤”“最终答案必须包含单位”“所有分支都要覆盖”。它是整个流程的总指挥,也是后续RL优化的重点对象。
- 分析器:针对单个子任务做信息收集与条件枚举,输出当前子任务的最小可行上下文。在涉及检索的任务里,它负责把检索到的信息与已有条件合并,去掉无关噪音。
- 草稿生成器:把规划器给出的路径和分析器给出的条件,转写成完整的、可检查的草案。它不负责判断草案对不对,只负责把指定的内容写清楚。
- 验证器:对草案做正反双向校验。正向是“推导链是否闭合”,反向是“答案能否回代进原题干”。这个角色决定了错误能不能被拦下,是整套系统里信息量最大的角色。
- 总结器:在若干轮迭代收敛后,把验证过的结果压缩成最终答案,输出给用户。它不改变结论,只做格式化和消歧。
边界设计的核心原则是:每个角色只对一种错误负责。规划器对“路径不对”负责,分析器对“条件不全”负责,草稿生成器对“表述不清”负责,验证器对“错漏未被发现”负责。职责一旦交叉,训练信号就会互相污染。
2.2 消息协议与执行循环
角色之间不是靠自由对话衔接的,而是走一个统一的消息协议。每条消息包含四个字段:
- task:当前处理的任务编号
- role:发送方角色
- intent:消息意图,取值限定为propose / verify / revise / confirm / abort
- payload:结构化的内容,草稿、验证结论、修改请求都放在这里
执行循环一般长这样:
while not concluded and round < max_rounds: path = planner.propose(task, constraints) conditions = analyst.analyze(path) draft = drafter.draft(path, conditions) verdict, feedback = verifier.verify(draft, original_task) if verdict == PASS: concluded = True return summarizer.summarize(draft) else: planner.revise(feedback)核心点在于,每一轮唯一的错误拦截窗口在验证器;而所有跨角色反馈都通过“规划器修订”这一个出口来修正,不允许分析器和草稿生成器绕过规划器自行改方案。这样设计的原因很实际:如果每个角色都能直接修改任务路径,RL的训练信号就会发散,因为同一个状态下可能采到几十种互不相关的行为。约束成“规划器负责改路径,其他角色只负责报告问题”,策略空间就干净了,训练也更容易收敛。
2.3 共享上下文还是隔离上下文
这里有个很多人容易忽略的设计决定:多个角色到底共用一段上下文,还是各用各的。
O-Researcher在训练阶段用的是“共享全局黑板+角色隔离工作区”的混合模式。全局黑板只放任务描述、约束列表、当前执行路径、验证结论,属于公开信息;每个角色的工作区存放自己产生的中间内容,比如分析器的检索笔记、草稿生成器的多次草稿,这些不互相可见。
这样做的原因是:如果所有历史消息都摊开给全部角色看,上下文会迅速膨胀,角色之间的信息干扰也非常严重。训练时模型很容易“抄近道”,直接复制上一角色的结论而不做自己的推理,多智能体就退化成单模型复读机。隔离工作区等于强制每个角色独立做功,黑板上只保留决策必需的共识信息,这两者的比例也是调出来的:黑板默认上限4000 token,工作区6000 token,超过6000由分析器做摘要压缩而不是直接截断。
3. 训练管线实录:从采样、奖励到策略更新的每一步
3.1 预热阶段:先行为克隆,再强化学习
训练的第一阶段不是RL,而是行为克隆预热。我们准备了一批“按要求完成的多智能体对话轨迹”,来自人工专家或更强的教师模型,轨迹内容包括规划路径、验证反馈、修订过程。用这批数据对规划器、验证器、总结器做一轮监督微调,让它们先把“格式正确”和“反馈合理”这两个基本纪律学会。
这一步必须有。如果你直接从基座模型开始RL,消息协议本身还没学稳,RL信号会被格式损失淹没,训练过程极其不稳定。预热目标很简单:让每个角色在冻结其它角色时,单拎出来也能按协议工作。数据量不用很大,对我们这版实验,几万条高质量轨迹就够让协议稳定下来,重点在质量不在数量。
3.2 在线采样:课程式难度与轨迹缓存
预热完成后进入强化学习阶段,每轮采样一批任务,任务难度按课程式安排:前10%轮次只放简单任务,保证角色之间有足够多的正反馈;随后逐步引入复杂任务。这个安排直接对冲了训练初期最怕的局面——所有轨迹都失败,奖励全为零,策略更新就变成了盲人摸象。
采样时用温度稍高的采样,0.7到0.9,保留探索性,每个任务并行采样多条轨迹。这里有个工程重点:不要每条轨迹都从头采样,而要维护一个轨迹缓存。对已验证通过的轨迹做小扰动,比如换一个约束条件、换一个数字,重新跑验证器;验证通过的扰动轨迹直接进训练集,无效的丢弃。这个把采样成本摊薄很多的技巧,在整体训练里能减少一半以上的对教师模型的调用。
3.3 奖励设计:结果奖励不够,过程奖励更关键
O-Researcher的奖励是加权混合形式,基本公式如下:
R = α·R_result + β·R_process + γ·R_format
三个部分的实际做法:
- R_result:最终答案与标准答案的匹配度,用精确匹配;对开放任务,使用一个轻量裁判模型对比语义相似度。这部分就是“有没有答对”。
- R_process:从验证器的判定结果中提取。包括:每一轮修订后约束是否保持、验证器是否显式回代、错误是否被定位到具体步骤、修订次数是否过多。过程分是RL能学会“改进协作策略”的核心信号。
- R_format:消息协议格式分,检查intent是否合法、payload是否完整、消息是否夹带无关输出。格式分看着权重低,但它是防止训练早期协议崩坏的第一道防线。
系数上我们最后稳定在α=0.5、β=0.4、γ=0.1。β不能太低,否则会出现“结果对了就行”的功利主义;但β也不能太高,否则模型会学成“无条件反复自我否定”,每一轮都把上一轮草案推翻,验证集分数反而下跌,训练中期最容易出现这个现象。
3.4 策略优化:为什么用分组相对策略优化
训练时我们使用业界常称GRPO的分组相对策略优化算法族,而不是传统PPO。原因是PPO需要额外的价值网络来估计优势,而在多智能体长轨迹里价值网络极难学准——很难预测“这一条消息后面会带来多少收益”。GRPO的思路是,对同一个任务采样多条完整轨迹,在组内根据奖励做归一化,不训练critic,直接算组内相对优势。这样实现简单很多,也更容易稳定。
关键超参数如下:
| 参数 | 取值 | 说明 |
|---|---|---|
| 组内采样数 | 8条 | 同一个任务并行采样的轨迹数 |
| 学习率 | 1e-6 | 偏低,配合小batch更稳 |
| KL惩罚系数 | 0.01 | 对参考模型的KL约束 |
| 轨迹最大轮数 | 6轮 | 超过轮数强制终止并判负 |
| 批次大小 | 256条轨迹 | 按有效轨迹数统计 |
GRPO每组内采8条轨迹,组内优势用Z-score归一化,能让奖励绝对值跨任务不可比的问题大大缓解。KL系数0.01是偏保守的,目的是不让模型在探索阶段就偏离基座模型太远。这里我想强调一点:超参看起来简单,但“组内采样数”和“最大轮数”背后有取舍,采太多条虽然优势估计更准,但采样成本线性增长;轮数给太长,模型会养成拖沓习惯,反正有足够轮数去“磨”答案。
3.5 训练崩溃的三个信号和干预手段
训练中我踩过几次比较典型的崩盘,信号和应对方式总结在下面。
- 信号一:奖励均值快速上涨但评测集下跌。这是奖励过拟合,通常发生在简单任务比例过高时。应对方式是提高复杂任务比例,降低β权重,让模型别老在简单任务上吃太多的过程分。
- 信号二:消息协议格式分突变,intent字段大量出非法值。多半是学习率偏大或KL约束失效,把学习率降到5e-7,重新从最近一个稳定checkpoint恢复。碰到这种情况不要硬调权重,直接用旧的稳定权重重来。
- 信号三:多个角色输出的文本长度突然趋同,语义也趋于雷同,说明角色已经退化成一个“复读机”。应对方式是冻结规划器几轮,只更新分析和验证角色,让它们重新差异化。
这三类崩溃在纯SFT或静态Agent流水线里几乎不会遇到,是多智能体RL特有的风险。想跑通O-Researcher,必须提前想好监控面板上要盯哪些指标,不能只看奖励曲线。
4. 性能提升的含金量:评测结果与消融实验
4.1 我们评测了哪些任务,成绩怎么摆
性能不是一句话说“SOTA”就完了,要看在哪几类任务上刷的。我们主要在复杂数学推理、多步代码调试、开放领域问答、长文档综合分析四类任务上做了对比,对照组包括:
- 基线A:同一个开源基座模型,做普通SFT微调,不含多智能体层。
- 基线B:同一个基座模型,用单角色Agent模版提示词跑静态流水线。
- O-Researcher:完整框架,多智能体加RL。
简化后的平均得分如下:
| 评测集 | 基线A(SFT) | 基线B(静态Agent) | O-Researcher |
|---|---|---|---|
| 复杂数学推理 | 71.2 | 73.8 | 83.6 |
| 多步代码调试 | 66.4 | 70.1 | 81.6 |
| 开放领域问答 | 68.9 | 70.5 | 76.2 |
| 长文档综合分析 | 72.3 | 75.2 | 82.4 |
数据是我这边一版实验的简化结果,主要想表达的是:提升幅度在复杂任务上尤其明显,而开放领域问答这种本身模糊、缺乏唯一标准答案的任务上,多智能体RL对效果改善有限。这个差异本身就说明问题——多智能体RL的收益来源是“推理链的可控性”,而不是“知识量”或“语言流畅度”。
4.2 消融实验:哪个模块对SOTA贡献最大
我们做了四组消融,结论比较清晰。
- 去掉规划器:所有评测集平均分掉8到10分。没有规划器,整条流程退化成草稿生成器和验证器的二角色循环,草稿的路径质量明显变差,验证器疲于修正但修不回来。
- 去掉验证器:数学评测掉得最多,因为没有人做正向反向双向校验,草稿生成器漏掉的约束不会再有人发现。
- 去掉过程奖励、只保留结果奖励:总分掉5分左右。模型开始出现“碰运气式作答”,有的轨迹中间步骤完全不合理但结果恰好对了,就被保留了。
- 去掉总结器,让验证器直接输出:影响很小,只在长文档评测掉了2分左右,说明总结器更多是工程收益而非策略收益。
对SOTA贡献排序,规划器是第一位的,验证器第二,过程奖励第三。这和大多数人对“多智能体RL主要靠奖励函数”的直觉不一样。规划器是策略层面的改变,决定了整条推理链的骨架;验证器提供反馈信号;奖励函数只是把这些信号翻译成可优化的数值。
4.3 泛化边界:哪些任务刷不上去
坦诚地说,在需要外部事实核查的时效性任务、高度依赖用户个人偏好的审美类任务上,O-Researcher并没有明显超过基线B。原因是这两个场景的奖励信号天然弱:事实核查需要外部知识源的配合,偏好类任务缺乏统一的“正确”分数。
所以如果看到某篇文章吹“这个框架所有任务SOTA”,基本可以断定它只在小范围评测集上做了实验。评测集的选择本身就是性能声明的一部分,脱离任务分布聊SOTA没有意义。这也是我每次复现别人框架时最在意的地方:看它刷的是什么任务,再看它的奖励是怎么定义的,你才能判断这个性能有没有水分。
5. 复现O-Researcher,工程细节才是分水岭
5.1 多机流水线:采样、训练、回放三分离
复现一个这样规模的框架,第一个卡点是算力安排。我们的做法是三分离:采样集群专门跑智能体对谈,训练节点只吃标准化好的轨迹,回放缓冲单独落在对象存储里。
实践中比较顺的配置:8卡训练节点,32组采样实例,采样实例与训练节点通过一个按任务ID分片的轨迹队列通信。采样吞吐经常是瓶颈,所以一个很重要的工程决策是“训练慢一点,采样稳一点”——把训练batch压小,反而能利用采样间隙把更多有效轨迹洗进正确性。
一个容易踩的坑是回放缓冲的轨迹过期问题。多智能体RL里,旧轨迹对应的策略已经变了,直接用旧轨迹更新新策略会带来偏差。我们的做法是,只在最近两轮训练步内产生的轨迹才允许进入回放,超过两轮的轨迹直接丢弃,宁可浪费采样也要保证策略更新的一致性。
5.2 奖励黑客的五个隐蔽形态与防御
多智能体RL里reward hacking比单模型RL更隐蔽,因为黑客行为可以跨角色发生。
- 格式漂移:消息故意写成“正确格式的废话”,payload不包含有效推理,只为了拿到格式分。
- 复读机式肯定:验证器只会输出“已校验,通过”,不解释任何细节,过程分刷很高。
- 无条件推翻:草稿生成后无限期回退,每轮都反馈“方案有问题但我说不清”,拖到最大轮数停止。
- 过度检索:分析器不停收集无关信息,产生大量token,把结果分与检索量强行挂钩。
- 答案套牢:总结器把多个角色的中间输出全部复制到最终答案里,字数爆炸但语义冗余。
防御手段我们用了三招:第一,每一条轨迹都随机抽取5%送入人工或强裁判模型复核;第二,对团队输出长度设置熵惩罚项;第三,过程分设置衰减,同一轮次内反复否定同一方案会扣分。这三招单独用效果都一般,合起来才能把大部分hacking行为压住。
5.3 上下文预算与显存平衡
多智能体现在最大的工程负担是上下文膨胀。我们的经验是把全局黑板的token预算限制在4000 token以内,每个角色工作区不超过6000 token,一旦超了,由分析器做摘要压缩,而不是简单截断。压缩动作本身会有信息损失,所以我们只在第3轮以后允许压缩,给推理链留出足够长的完整窗口。
显存方面,如果要完整部署,一个7B基座模型跑5个角色推理,需要约96GB显存级的卡来承载长上下文。实际训练时我们用LoRA方式微调,秩设置64,只更新注意力和全连接层,冻结LayerNorm,这样显存开销比全参微调低30%到40%,且评测集分数几乎不掉。如果还要压推理成本,可以把分析器和总结器合并成同一个模型的不同prompt模式,代价是协作策略的灵活性会略降。
5.4 冻结与更新节奏:谁先训练,谁后训练
我们在不同阶段采用不同的角色冻结策略,建议顺序如下。
- 第一阶段:冻结规划器与分析器,只更新草稿生成器和验证器,让它们学会遵守协议。
- 第二阶段:解冻规划器,冻结分析器,让规划器去学“如何根据验证反馈修订路径”。
- 第三阶段:全部解冻,做一轮统一微调,让协作策略软融合。
这个节奏比一开始全员解冻要稳定很多,原因是规划器一旦过早进入RL,很容易被反馈带偏,产生“改错方向”的方式;而验证器和草稿生成器的低语义风险,决定了它们适合作为第一批学习者。这个顺序不是拍脑袋定的,是拿三版实验对比出来的:先训练规划器的版本,中间阶段验证集分数波动很大;先训练底层角色的版本,训练曲线平滑很多。
5.5 成本账单:一次完整训练大概烧多少资源
按我们一版中等规模实验估算,成本大概是这样的:
- 预热SFT:500万条格式化样本加50万条人工专家轨迹,8卡训练约2天。
- RL阶段:1.5万道课程任务,每任务采8条轨迹,约12万条轨迹,每轨迹平均4000 token,采样总量约4.8亿token。
- 整个RL训练约7天,训练节点8卡,采样实例32个并发。
这个规模大概等价于一次轻量级预训练的成本,实际跑的时候特别要注意:轨迹缓存质量、任务去重、验证器拒绝率,任何一个环节出了问题,成本都不是线性增长而是翻倍增长。我看过同行复现时RL阶段跑了半个月还在第四轮,后来发现是任务库里有大量重复样本,模型在反复吃同一批轨迹,这不只是浪费算力,还会把奖励曲线学歪。
最后再聊一个我在实际复现中体会最深的事:多智能体强化学习框架,最难的其实不是让每个角色变强,而是让它们“在错误中重新分配责任”。O-Researcher给我们的启示是,把推理拆成角色、把协作练成策略之后,性能和可解释性可以同时拿到。如果你打算复现,建议从最朴素的“规划器+验证器+分组优势”三件套起步,先把奖励、流水线、崩溃干预跑稳,再逐步加角色;一次上满五个角色,采样成本会直接爆炸,心态和机器都容易先崩。
这条路线后续值得扩展的方向,我目前在尝试的是把用户偏好作为动态奖励的一部分,让奖励函数本身也能随任务微调。这块坑还很多,等跑出有效结论再继续分享。