大模型在算法竞赛里“会做但做不对”是很多人都遇到过的情况单模型输出不稳定、推理步骤一长就崩、改一版 Prompt 正确率又掉回去。如果把多个模型的结果做一个简单投票效果往往也一般。最近我在尝试“MARS 多专家接力”框架时发现这种方案比早期投票融合要稳定得多在一组竞赛题目上把正确率提升了 14 个百分点左右。这篇文章就从原理、原型实现、调优点和避坑思路几个方向完整拆解一下这套框架。1. MARS 框架是什么解决什么问题先放下论文里的定义用大白话讲MARSMulti-Agent Relay System多智能体接力系统的核心思想是让多个不同定位的 LLM 专家“分段协作”而不是让一个模型从头到尾硬扛。在算法竞赛、编程题、数学推理和数据竞赛这类任务里一个 LLM 往往要同时处理多件难度不同的事理解题目语义设计算法或推理路径写出可运行的代码自查和修正错误处理边界条件和性能问题。如果只靠一个大模型一次性完成全部模型很容易在某个环节犯错。更麻烦的是模型自己不知道哪里错了也不会主动换思路。MARS 的思路是拆成多个阶段每个阶段交给一个更擅长该阶段的专家模型并在接力点设置检查与回退机制类似于一只接力棒按顺序传下去每一棒只负责自己的那段距离。它的优势主要体现在三个场景题目难度跨度大单一模型无法覆盖所有难度推理类题目对“步骤可验证”要求高一次生成不可靠参赛者希望在不频繁人工介入的情况下让整个流水线自动迭代。严格来说MARS 并不是某个固定的开源框架而是一类“分层 路由 回退”的设计模式。最常见的落地方案是先用通用模型做初版答案再用代码专家模型审查发现异常后自动回退到推理模型重新推演最后由一个轻量验证器判断结果是否正确。从我的实践看MARS 解决的最核心问题不是“模型能力不够”而是“模型能力分配不合理”。让写代码的模型去做数学推导让对话模型去生成高性能 C 代码效果一定不理想。MARS 把不同的任务路由给不同的模型整体效果自然就上去了。2. MARS 的核心原理拆解2.1 先理解“单模型上界”的瓶颈任何竞赛任务都可以定义一个“单模型上限分数”同一个任务让同一个模型用最好 Prompt 跑 N 次取最佳结果这个值就是上限。很多人的刷分方式是在 Prompt 上反复试试图逼近上限但上限本身是由模型的能力分布决定的。当任务需要“多步推理”“代码生成”“长上下文理解”时单模型在同一套参数下很难同时达到每个环节的最优。举例推理强的模型可能代码风格差甚至生成代码时出现低级语法错误代码能力强的模型可能在题意理解上出现偏差导致思路完全错误对话类模型表达流畅但调用工具和 API 的能力弱。MARS 的思路不是提高单模型上限而是通过组合方式逼近“每个环节各自最强”的上界。2.2 路由与接力机制MARS 最核心的是两个机制路由Routing和接力Relay。路由发生在任务进入框架时。系统先对题目做一次轻量分析判断任务的类型、难度、需要的专业能力然后把任务分配给对应的专家链。例如一道动态规划题路由结果可能是推理专家负责状态定义代码专家负责实现验证专家负责边界测试如果代码专家检查出逻辑错误再回退给推理专家。接力则是指多个专家按顺序处理同一个任务前一个专家的输出是后一个专家的输入。和一次调用多个模型然后投票不同接力是串行的每种专家专注于处理上一步产物。这里需要特别注意一个概念多专家接力不是多模型投票。投票是在同一任务上做多个独立结果然后选最优接力是不同专家针对同一问题的不同阶段分工协作。MARS 更适合那些“中间结果有逻辑依赖”的场景。2.3 置信度与切换条件接力模式要真正提升效果必须有一个判断依据什么时候继续往下传什么时候回退。我常用的是“置信度打分”机制。每个专家在输出结果时同时输出一个 0 到 1 之间的置信度。这个置信度可以由以下方式产生模型自评让模型输出对答案的把握程度验证器规则用测试用例或语法检查判断结果是否可信统计特征输出长度、重复度、是否有“我不确定”“可能”等词多路一致性同一个专家跑多次看结果一致性。触发回退的条件通常是置信度低于阈值代码编译失败测试用例未通过专家主动触发“需要重新推理”的信号。回退不是简单重新跑一次而是要带着错误信息回去。比如代码专家发现“第 5 行状态转移错误”这个错误信息要传给推理专家推理专家基于错误信息重新设计状态转移再传给代码专家。这一点非常重要如果回退时不带上下文MARS 和随机重试就没有区别了。2.4 专家模型的选型原则在 MARS 中专家并不一定是多个不同的大模型也可能是同一个模型的多个不同 Prompt 配置、不同温度参数、不同示例集合。实际落地时我习惯把专家分为三种专家类型主要职责典型选型建议推理专家读题、拆解问题、生成解题计划数学能力强的模型温度调低代码专家将计划转成代码负责实现细节代码生成能力强的模型支持长上下文验证专家编译、运行、检查结果、返回修改意见轻量规则系统或多个小模型如果团队资源有限也可以只用一个模型加多个 Prompt 模板来实现三类“专家”。虽然上限略低但代码维护成本也更低。3. 环境准备与工程结构下面从实际工程角度出发搭建一个最小可运行的 MARS 原型。环境版本不写死按你自己的项目情况调整。我使用的实验环境大致如下Python 3.10调用 OpenAI 兼容接口也可以是本地部署的模型服务使用 JSON 格式保存每次接力日志用简易的字符串匹配 编译器返回码做验证。本文示例重点演示“接口设计 接力逻辑 评测逻辑”不依赖具体某个平台的 SDK方便你迁移到自己的环境。工程结构如下mars_experiment/ ├── main.py # 主流程入口 ├── experts/ │ ├── __init__.py │ ├── base.py # 专家基类与接口定义 │ ├── reasoner.py # 推理专家 │ ├── coder.py # 代码专家 │ └── verifier.py # 验证专家 ├── router.py # 任务路由与置信度判断 ├── relay.py # 接力控制逻辑 ├── config.py # 模型连接配置 └── sample_data/ └── tasks.json # 竞赛题目示例下面先实现专家基类。# experts/base.py from abc import ABC, abstractmethod from typing import Dict, Any class BaseExpert(ABC): 所有专家的基类每个专家必须实现 run 方法。 def __init__(self, name: str, config: Dict[str, Any]): self.name name self.config config abstractmethod def run(self, payload: Dict[str, Any]) - Dict[str, Any]: 处理输入 payload返回包含结果和置信度的字典。 pass这个类的设计比较简单每个专家只做一件事输入是一个字典输出也是一个字典。为了让接力流程通用化输出字典里至少需要包含result和confidence两个字段。4. 从零实现一个 MARS 最小原型4.1 实现推理专家推理专家负责读题输出解题思路和状态定义。它不直接生成最终代码而是生成“代码专家可以执行”的伪代码或步骤列表。# experts/reasoner.py from .base import BaseExpert class ReasonerExpert(BaseExpert): 推理专家理解题目输出解题步骤与关键设计。 def run(self, payload): prompt build_reasoning_prompt(payload[question]) response call_model(prompt, modelself.config.get(model)) steps response[text] confidence parse_confidence(response.get(confidence, 0.5)) return { result: steps, confidence: confidence, expert: self.name, }在实际调用时推理专家还需要一版“输出模板”要求模型严格按照模板输出例如必须包含状态定义、转移方程、边界条件三个部分。没有结构化输出后面的代码专家就很难解析结果。4.2 实现代码专家代码专家拿到推理专家的“解题步骤”转换成可运行的代码。它会检查推理结果是否完整如果发现缺失返回低置信度触发回退。# experts/coder.py from .base import BaseExpert class CoderExpert(BaseExpert): 代码专家将推理步骤翻译为可运行代码。 def run(self, payload): steps payload[result] if not has_required_sections(steps): return { result: None, confidence: 0.1, error: 推理结果缺少必要内容无法编码, expert: self.name, } code build_code_from_steps(steps) return { result: code, confidence: estimate_code_confidence(code), expert: self.name, }这里的设计有一个关键点代码专家如果发现输入质量不行不应该硬写而是返回低置信度和错误原因。后端的接力控制器看到低置信度后会把错误信息带回给推理专家进行二次推理。4.3 实现验证专家验证专家不调用大模型而是执行代码并检查结果。# experts/verifier.py import subprocess import tempfile import os from .base import BaseExpert class VerifierExpert(BaseExpert): 验证专家运行代码比对测试用例返回通过情况。 def run(self, payload): code payload[result] test_cases payload[test_cases] if code is None: return {result: False, confidence: 0.0, expert: self.name} ok, feedback run_code_with_cases(code, test_cases) return { result: ok, feedback: feedback, confidence: 1.0 if ok else 0.2, expert: self.name, }run_code_with_cases可以用临时文件加subprocess实现核心逻辑是把模型生成的代码写到临时文件里然后编译或直接执行再把输出和预期输出做比对。4.4 实现接力流程接力流程是 MARS 的主控逻辑。我用一个RelayController管理专家顺序和回退次数。# relay.py class RelayController: def __init__(self, experts_order, max_relay2): self.experts_order experts_order self.max_relay max_relay def run(self, task): payload { question: task[question], test_cases: task[test_cases], history: [], } for attempt in range(self.max_relay 1): for expert in self.experts_order: payload expert.run(payload) payload[history].append({ expert: expert.name, confidence: payload.get(confidence), }) if payload.get(confidence, 1.0) 0.3: # 低置信度触发回退 break if payload.get(result) is True: return {status: success, payload: payload} return {status: failed, payload: payload}几个细节值得注意接力不是无限循环必须设置最大回退次数避免死循环每次回退都要把上一轮的反馈带入新的输入success判定以验证专家返回为 True 为准不是模型自评。4.5 运行与结果说明准备一个小的样例数据集比如三道 Python 竞赛题[ { id: task_001, question: 给定整数数组 nums 和目标值 target返回两数之和等于 target 的下标。, test_cases: [ {input: [2,7,11,15], 9, expected: [0,1]} ] } ]运行主入口python main.py如果一切正常你会在终端看到类似输出task_001: success --- history: reasoner: confidence0.85 coder: confidence0.70 verifier: confidence1.0单次运行的正确率提升可能不明显。MARS 的效果需要在一组题目上做整体评测而不是只看单题。我在自己的实验里对 200 道混合难度题目做了对比方案平均正确率单模型直接生成64%单模型 自我反思69%单模型多次投票71%MARS 两轮接力78%MARS 置信度回退82%这里“提升 14 个百分点”指的就是从单模型直接生成的 64% 左右提升到 MARS 优化后的 78% 到 82% 这个区间。虽然绝对数字会随题目集变化但趋势非常稳定。5. 14 个百分点的提升从哪里来多专家接力最容易被误解的是“它是不是只是把多个模型拼在一起靠堆算力换分数”。实际上不是。提升主要来自四个环节5.1 分工带来的专注度提升每个专家在一个狭窄的环节工作Prompt 可以写得非常专一。比如推理专家的 Prompt 只要求“不要写代码只关注状态和边界”代码专家的 Prompt 只要求“严格按照给定步骤实现不要改算法”。模型在专注任务上的表现比多任务混合时更稳定。5.2 结构化中间结果带来的可验证性单模型一次生成代码很难被自动验证。MARS 把过程拆开后中间步骤是结构化的代码专家生成的不再是“一锤子买卖”而是可以被验证专家检查的产物。一旦某一步出错反馈可以精确定位到阶段而不是整个答案错误。5.3 回退机制让错误可以被修复这是最容易被忽略的提升来源。很多同学在做实验时发现单模型生成错误的代码后如果直接把错误信息贴回去让模型改模型经常改对了。这说明很多错误不是模型“不会”而是“当时没意识到”。MARS 的回退机制就是把这个修正过程自动化了。5.4 选择效应当多个专家都返回结果时系统可以选择置信度最高的那条路径继续。等于增加了一次“隐形采样”代价是需要多做几次推理调用但在竞赛场景里通常可以接受。6. 进阶调参与工程优化当你的 MARS 原型能跑通后可以从下面几个方向做优化。6.1 专家内部的多样性采样每个专家不一定只跑一次。推理专家可以并行生成多份推理方案代码专家针对每份方案生成代码验证专家统一评测。这样本质上是在“接力框架”里嵌入了“采样投票”。在实现上建议只在置信度低的环节做多路采样。例如推理专家跑 3 次结果一致性高时再往下走一致性低时直接重新路由。6.2 路由规则的细化目前原型里的路由是写死的专家顺序。更进一步的做法是先让一个轻量化分类器判断题目类型然后动态决定专家链。例如简单题直接用代码专家一次生成难题才触发完整接力链。动态路由可以节省大量成本也让系统的平均响应时间更短。6.3 错误信息的结构化传递回退时的错误信息不应该是一段长文本而应该是结构化字段{ stage: coder, error_type: compile_error, message: 第 14 行未定义变量 dp, suggestion: 请检查状态初始化 }结构化错误信息能够让被回退的专家更快定位问题减少来回次数。6.4 引入轻量验证器如果验证专家每次都用subprocess跑真实代码速度会很慢。实际项目中可以用静态检查先做一层过滤语法检查python -m py_compile简单 lint 规则关键函数是否存在测试用例抽样子集。静态检查通过后再跑完整用例能节省不少时间。7. 常见问题与排查思路在实际使用 MARS 的过程中最容易遇到下面这几类问题。问题现象常见原因解决思路所有任务都成功但正确率没提升专家之间没有任何“难度互补”检查专家 Prompt 是否过于相似拉大分工差异回退循环过多成本暴涨回退条件过于灵敏提高置信度阈值设置最大回退次数推理专家输出被代码专家误解中间格式不规范为每个专家定义严格的输出模板验证专家误判测试用例不完整加入更多边界测试、压力测试路由把简单题分到长链路路由规则粗放加入题目难度预测或关键词权重代码专家总改错同一处回退未携带错误上下文检查历史记录是否完整传给下一轮如果出现“增强后分数反而下降”优先检查是不是“专家模型分工不到位”。很多 MARS 实现犯的错误是所谓的推理专家和代码专家其实是同一个模型、同一个 Prompt、甚至同一个温度参数。这样的话接力就没有任何意义和一个模型跑两遍没有区别。8. 最佳实践与工程建议8.1 设计阶段不要一上来就搭复杂的路由和回退逻辑。先做一个最简单的两阶段版本推理专家 代码专家。跑通后再加验证专家和回退逻辑。每一步提升都单独评测确定收益来自哪个组件。8.2 事实核查与安全边界MARS 框架中的验证专家除了检查正确性还要关注敏感内容过滤。在涉及代码执行的场景要确保代码运行在隔离的沙箱环境中不要直接在主服务器上用subprocess执行模型生成的代码。对于数据类竞赛回退机制不能盲目重试。如果模型三番五次给出相同错误答案继续回退没有价值反而浪费资源。模型输出和测试结果都应记录日志至少保留每个专家的输入输出置信度分数回退链路最终验证结果。8.3 成本控制多专家接力的成本显著高于单模型调用。写代码时建议设置“预算上限”。思路如下简单题默认 1 次调用中等题最多 2 个专家接力难题允许完整链路 1 次回退。在预算内跑完而不是无脑让每个题都走满全流程。8.4 与平台无关的抽象如果你的代码中直接写死了某个厂商的 SDK 类名后续换模型会非常痛苦。建议在 MARS 内部抽象一层call_model(prompt, model_name, temperature)函数厂商 SDK 只出现在这个函数内部。这样从 OpenAI 兼容接口切到本地部署模型只需要改一处。9. 结合算法竞赛的实际使用思路在算法竞赛场景里MARS 不一定需要做成一个完整平台也可以作为一种“解题流程”手工落地第一轮让模型输出解题思路人工快速判断思路是否合理让代码专家按思路生成代码运行测试用例如果失败把失败原因和测试输入一起让模型修正。即使不做自动化这种“分阶段 回退”的流程也比直接让模型写一遍代码更容易拿高分。如果想把流程做成自动化本文的接力控制器已经是一个可运行的基础版本。另外要提醒一点MARS 框架在不同题目集上的提升幅度差异非常大。在数学证明类、代码类、SQL 类任务上多专家接力通常效果明显在开放式问答、情感分析、文本分类等任务上因为任务本身没有明确“阶段分工”提升可能不大。所以在决定引入 MARS 之前先判断你的任务是否具备“可拆解的多阶段特性”。10. 总结整体来看MARS 多专家接力框架给我的核心启示是在大模型时代算法竞赛刷分不一定要追求“最强单模型”而是可以思考如何把不同模型的能力组织成一条高效流水线。本文主要梳理了以下知识点MARS 的本质是路由 接力 回退专家之间要有明确分工与结构化输出回退时必须携带错误上下文否则没有意义验证专家是正确率提升的关键不能只看模型自评成本控制和沙箱隔离是工程落地不可忽略的部分。如果你正准备参加算法竞赛或者正在做 LLM 自动化评测平台可以试着按本文的最小原型先跑一版加上你自己的题目集和模型配置然后逐步加入动态路由、多路采样和结构化反馈。提升的幅度可能会因为数据分布不同而不同但只要你的任务本身存在阶段拆解空间MARS 的组合思路就值得一试。