多智能体辩论(MAD)实战:让LLM推理从自说自话变成群体评审 最近在整理LLM基础研究系列的时候我一直在琢磨一个现象让同一个模型反复检查自己的回答它往往越检查越自信哪怕答案本身就是错的。有次我让模型审查一段并发代码它信誓旦旦说逻辑完备无竞态条件结果另一个模型只扫了一眼就指出共享变量没加锁。这不是单个模型能力不行而是自说自话的推理模式天然缺少外部校验。后来我系统调研了MADMulti-Agent Debate多智能体辩论这个方向发现它正是冲着这个问题去的——把一个人闷头想变成一屋子人开评审会而且实测效果确实惊艳。这篇文章就是我对MAD的完整复盘它到底是什么、内部怎么运转、有哪些坑、以及怎么用最少代码把它接进你自己的项目里。1. MAD到底是什么从同一个模型检查自己到多个智能体互相对抗1.1 单模型自省为什么靠不住先聊一个底层原因。LLM是自回归模型生成每个token时只能看到自己前面已经生成的内容。这意味着它一旦在早期某个推理步骤上走了偏后续所有推理都会沿着这个错误方向自我强化越走越顺越顺越自信。你让它再检查一遍它检查的其实是自己刚刚写下的那套自洽逻辑而不是从外部视角重新审视问题。这个现象学术上经常用系统性和自发性幻觉来解释模型不是不知道正确答案而是在生成过程中被自己的上下文锚定住了。就好比写文章写到第二段发现自己跑题了但因为前一段已经在屏幕上摆着你本能地会顺着往下圆而不是删掉重写。Self-Consistency自洽性采样之所以能缓解一部分问题是因为它让模型独立采样多次再对答案投票。但投票解决的是随机错误——五个样本里有三个是对的、两个是噪声取多数自然有效。可如果模型在训练数据里学到的是同一个错误偏见五次采样可能全错在同一个地方投票反而会把错误答案固化成多数共识。1.2 MAD把推理从独白变成了评审会MAD的核心思路其实特别朴素既然单个模型自省容易路径依赖那就让多个智能体互相辩论、互相批评、再各自修正最后收敛到一个共识答案。这里的多个智能体可以是同一个模型的不同实例也可以是两个完全不同的模型。它们各自带着不同的上下文、不同的采样温度、甚至不同的角色设定进入对话。一个扮演激进方案提出者Proposer一个扮演挑刺的评审者Critic必要时再来一个中立的裁判Judge。经过几轮提案—批评—修改的循环最终输出的往往比单个模型直接生成的结果要扎实得多。一篇该方向的经典工作验证得很清楚用多智能体辩论做算术推理和常识推理准确率比单模型CoT要高出好几个点另一个研究则发现多智能体辩论能显著降低模型在开放式问答中的幻觉率——模型陈述的事实性错误会在一轮轮互相质疑中被挖出来。这些结论我后来在自己项目里复测过方向基本一致。1.3 先分清两种MAD多智能体辩论与互认协议防御这里必须澄清一个容易混淆的坑。在LLM安全研究领域MAD还有另一个含义Mutual Agreement Defense互认协议防御简单说就是多个模型对同一个输入都给出无害判断才能通过审核的防御机制。这两种MAD名字缩写一样思路也沾边——都依赖多个模型的一致意见——但目标完全相反多智能体辩论是用来提升推理质量的生成范式互认协议防御是用于拦截有害内容的审核策略。而且更反直觉的是后一种MAD在红队测试中被证明有严重缺陷这一点我会在第5章详细展开。所以当你看到论文标题里的MAD先分辨它说的到底是被评测模型内部的辩论机制还是安全防线上的共识审核。我在调研初期就因为在两个概念之间跳来跳去浪费了不少时间这里给读者们提个醒。2. 拆开MAD的推理流水线提案、对抗、收敛三步走2.1 第一步让每个智能体独立提案别急着共享上下文MAD的第一步不是让智能体们直接开聊而是让他们背对背地各自独立生成初始方案。这个细节非常关键。原因在于LLM上下文是非常强的锚定源。如果让A先发言B在A的基础上补充意见B的思路就会被A带跑——这和开会时第一个发言的人往往主导全场讨论是同一个道理。独立提案的本质就是先制造认知多样性每个智能体在没有被他人影响的情况下尽可能从不同角度切入同一个问题。实操上这一步建议把采样温度调高一点我习惯用0.7左右让提案分布更发散。如果你的预算允许甚至可以让每个智能体分别独立采样2-3次挑一个自己最满意的作为入场提案。锚定效应对后续的辩论质量影响极大值得多花这一点token。2.2 第二步Critic的找茬质量决定了辩论的上限辩论能不能产生价值不看Proposer多能说而看Critic多能挑。如果Critic只是泛泛地说这个方案可能存在性能问题Proposer根本无从改起如果Critic能指出第3行用了全局锁但第17行又绕过锁直接写共享变量Proposer立刻就知道该改哪里。我整理过一份相对好用的Critic系统提示词骨架可以给读者参考你是一位极其严格的评审专家。你的职责是找出对方方案中的漏洞、边界条件和逻辑错误。 要求 1. 必须引用原文的完整片段指出具体位置具体到第几步、哪个变量、哪个分支。 2. 至少给出一个会导致方案失败的边界case。 3. 不允许使用可能有问题需要进一步考虑这类模糊表述。 4. 如果你认为方案没有问题也要明确指出你认为最薄弱的环节是什么。注意最后一条强迫Critic在暂时没发现问题时也给出薄弱环节能防止辩论陷入你说好我也说好的敷衍循环。另一份经典工作中还会让Critic先复述一遍Proposer的核心主张再开始批评。这个复述-批评的强制步骤逼着Critic真正理解了对方的方案才开口批评质量会显著提升。我自己实测下来这个技巧几乎是性价比最高的一行提示词改动。2.3 第三步收敛方式选投票、评分、还是让提案者自行修改几轮辩论之后所有智能体手里都有了一份原方案各方批评意见接下来要把这些信息收敛成最终答案。主流做法有四种我按推荐程度排序第一种是Proposer吸收意见后重写。让被批评的一方看完全部意见决定哪些接受、哪些拒绝并产出最终修订版。这种方式的优点是能保住方案的整体连贯性缺点是有时会过度道歉——明明是Critic说错了Proposer也照单全收关于这点第6章有治它的提示词技巧。第二种是独立Judge打分。把方案和所有批评意见打包丢给一个没有参与前几轮的第三方模型让它做出最终裁决。Judge的好处是中立坏处是多一次完整上下文重述token消耗比较大而且Judge本身也可能有偏见。第三种是群体投票。让所有智能体独立对最终候选版本投赞成或反对简单粗暴。实测下来投票对程序化和事实性任务效果不错但对开放式设计类任务经常出现1票对1票的僵局还得再引入破冰机制。第四种是我自己在工具类任务里比较喜欢用的Critic给建议但修改权始终在Proposer手里。Critic不直接改方案只提意见Proposer负全责决定改不改、怎么改。这是模拟真实工程评审中最接近技术owner负责制的做法权限边界清晰责任不会在模型间互相推诿。2.4 轮次不是越多越好2-3轮是实践中的甜点区很多初接触MAD的人会直觉地认为辩论轮次越多答案越精细。实测结果恰恰相反超过3轮之后边际收益急剧下降而且开始出现新的风险。一个风险是错误回潮。Proposer在修改第2轮意见时有可能把原本正确的部分改坏到了第3轮Critic又针对这个改坏的部分提出批评Proposer再改一轮方案变成两个人互相迁就的缝合怪。另一个风险是概念漂移。随着上下文越来越长早期讨论的关键约束逐渐被新内容稀释最终答案可能已经偏离了最初的题目要求。我在一次测试中就见过一轮关于低内存占用的方案辩论到第4轮后内存优化部分被淡化了开始大谈分布式扩展——方向已经偏到隔壁题目去了。我目前的经验值是困难任务2轮起步3轮封顶。如果3轮之后双方还在真诚地互相挑错那最该做的不是加第4轮而是回去检查题目定义和初始约束是不是没说清楚。3. 哪些因素决定了MAD的成败模型、角色与温度的相互作用3.1 异质性比数量更重要同一模型跑五次 vs 两个不同模型互怼我之前一度以为MAD的效果主要取决于参与辩手的数量5个智能体肯定比2个强。直到我做了组对比实验用同一个模型开5个不同会话吵5轮和用两个不同厂商的模型互相吵3轮。结果后者的效果反而碾压前者。原因其实也简单同一个模型的多个实例即使温度不同、角色设定不同它们在训练数据里学到的知识偏见和错误模式是高度相关的。它们之间的辩论更像是同一个人戴不同面具吵架很难产生真正的新信息量。而两个不同模型因为训练数据、对齐策略、推理偏好都有差异更容易在对方的知识盲区里发现问题。所以如果预算允许双模型异质辩论是性价比最高的配置如果只能用单模型那就靠角色设定和温度来人为制造差异效果会打折但依然比单个模型自评要强。3.2 角色分化是MAD的隐形引擎多数人对MAD的理解停留在给两个模型不同提示词就行。但真正的角色分化是要让两个智能体在评估标准上就拉开差距。Proposer的提示词应该强调完整性和可执行性让它把方案撑大、撑细Critic的提示词则应该强调安全边界和最坏情况让它本能地去找哪里有漏洞。一个负责假设一切顺利一个负责假设一切出错辩论的张力就出来了。这种角色分化还能规避一个常见问题如果两个智能体的提示词都太接近客观合理的专家它们会发现彼此说得都对最后互相妥协出一个四平八稳但其实没结论的废话答案。角色极化之后辩论才会真的吵起来而真正的洞见往往就在这种对抗里被挤出来。3.3 温度设置提案阶段求多样辩论阶段求稳定温度这个参数在MAD流程里是值得细调的而且不同阶段应该用不同的值。大部分MAD开源实现都用同一个全局默认温度这其实有些浪费。我的习惯是提案阶段温度0.7-0.9鼓励发散Critic评审阶段温度0.2-0.3保证挑刺的稳定性和可复现性Proposer修订阶段温度0.4-0.5既不能完全机械地照搬意见改也不能改得过于天马行空。有人在辩论阶段用高温度去引入随机性我认为这是误区。辩论逻辑需要的是精确输出高温度只会让Critic的批评变得东一榔头西一棒槌让Proposer的修改变得不可控。随机多样性在提案阶段给足了就够了。3.4 成本与延迟的现实账本MAD不是免费的。每次提案批评修改循环至少是3次完整调用而且Critic和Judge往往要把之前全量对话重新读一遍。按目前主流商用API的中低档价格粗算一次2智能体×3轮的辩论大约消耗1.5万到2万token成本在几分钱到几毛钱之间具体取决于模型定价。比钱更现实的是延迟。串行调用下一次完整MAD可能需要15-30秒甚至更久这还没算网络波动。如果业务要求首token响应在2秒内MAD直接部署在用户链路里是行不通的只能走离线异步先快速返回一个初版答案后台再跑MAD校验有差异再纠偏。下表的对比是我在几个任务上实测下来的相对感受推理增强方式相对成本相对延迟对随机错误的改善对系统性错误的改善单模型CoT1x1x基线基线Self-Consistency5路采样5x5x明显很弱双智能体辩论3轮6x-8x6x-8x明显较强三智能体中立裁判10x10x明显最强但边际递减4. 一个可直接复现的最小MAD实现代码与效果4.1 系统设计两个智能体、三轮辩论、一个主持人聊完原理来点能直接抄作业的东西。下面这个最小实现不依赖任何复杂框架只要你能调用任意一家主流云厂商的Chat Completions风格接口就能跑通。整个系统就三个角色一个Proposer、一个Critic、外加我自己的主流程当主持人。主流程负责轮流点名控制轮次以及组装每次对话的上下文。为了演示方便我把系统的提示词直接写在代码里方便读者看明白。4.2 核心代码提案-批评-修改的最小循环import requests import json API_KEY sk-xxx # 替换成你自己的密钥 API_URL https://api.your-provider.com/v1/chat/completions def chat(messages, temperature0.4): resp requests.post( API_URL, headers{ Authorization: fBearer {API_KEY}, Content-Type: application/json, }, json{ model: your-model-name, messages: messages, temperature: temperature, }, timeout120, ) resp.raise_for_status() return resp.json()[choices][0][message][content] PROPOSER_SYSTEM ( 你是一位资深算法工程师擅长给出完整、可执行的技术方案。 你会尽量考虑边界情况和异常路径但你的主要职责是提出方案。 ) CRITIC_SYSTEM ( 你是一位极其严格的代码评审专家。你的唯一职责是找出对方方案中的漏洞、 边界条件和逻辑错误。你必须引用原文的具体片段指出具体的位置、变量或分支 并给出至少一个会导致方案失败的边界case。禁用可能有问题这类模糊表述。 ) def mad_solve(question, rounds2): proposal chat([ {role: system, content: PROPOSER_SYSTEM}, {role: user, content: question}, ], temperature0.7) for i in range(rounds): criticism chat([ {role: system, content: CRITIC_SYSTEM}, {role: user, content: f以下是提案者的方案\n{proposal}\n请找出其中的问题。}, ], temperature0.2) proposal chat([ {role: system, content: PROPOSER_SYSTEM}, {role: user, content: ( f这是你的原方案\n{proposal}\n\n f这是评审意见\n{criticism}\n\n f请根据意见修改你的方案。你可以接受其中合理的意见 f也可以拒绝你认为不合理的意见并说明理由。最终输出修订后的完整方案。 )}, ], temperature0.4) return proposal if __name__ __main__: question 请设计方案一个高并发场景下的订单号生成器要求趋势递增且不可预测。 answer mad_solve(question) print(answer)这个主流程大概是全场最简单的骨架了但它已经具备MAD的全部要素先独立提案再对抗批评最后让提案者自主修订。唯一需要注意的是我在修订环节加了一句你可以拒绝你认为不合理的意见并说明理由这句是关键少了它Proposer会变成无脑道歉机器。4.3 跑通后你会看到的典型输出我用这个骨架跑过一次订单号生成器方案设计。第一轮Proposer给出了一个雪花算法变体附带有一段看似严密的时钟回拨处理逻辑。Critic反驳得很具体方案中使用Redis记录最近发放时间但在Redis主从切换时从节点可能保留旧值回拨判断会失效——请补充多副本下的时钟一致性方案。第二轮Proposer的修订版里没有继续依赖单点Redis而是改成用多副本时间戳本地时钟联合判断并且主动补充了机器ID冲突时的降级策略。能明显看到修订版比初版考虑的维度要多了一层。这就是外部评审者视角带来的真实增量而不是模型自己空想出来的自省。不过也要说句实在话不是每一次MAD都能有这种眼前一亮的效果。如果题目本身太简单或者初始提案已经足够完善Critic经常只能挑出一些无关痛痒的小问题那修订版的提升幅度有限。MAD更适合初版有一定复杂度但明显有隐藏坑的任务。4.4 如何把它接进已有的CoT/RAG流程说实话MAD很少需要从头部署更常见的需求是把它作为一个检查节点接到已有的推理流程里。如果你现在用的是CoT思维链pipeline可以在模型生成推理过程后把最终答案单独抽出来喂给Critic做一轮审查通过审查就直接输出没通过就让Proposer重写。这样可以避免每次请求都跑完整MAD成本要省很多。如果你用了RAG检索增强生成MAD的位置建议放在检索之后、回答之前。先把检索到的资料交给一个模型整理出候选观点再让另一个模型审查这个观点有没有忠实于检索内容、有没有编造检索里不存在的信息。我实测这个组合对减少RAG场景的幻觉补充效果很明显——模型知道的知识越多越容易把听过但没查到的东西顺手写进去MAD恰好能拦下这一部分。5. MAD的致命伤与反直觉结论多个模型一致同意时反而要警惕5.1 系统性错误协同当所有模型都错在同一处MAD确实能纠偏但它纠的是智能体之间的分歧对所有智能体共享的错误认知毫无办法。比如某些领域常识在训练数据里本身就是错的或者某个特定任务的正确答案和主流模型学到的偏好相反——这时候5个模型互相辩论它们会在错误的轨道里辩论得异常热烈最后自信地输出一个精美的错误答案。我在第1章提过一个类比三个臭皮匠顶个诸葛亮的前提是三个臭皮匠的错误互不相关。如果三个人读的是同一本内容有误的教材坐在一起讨论只会把错误升华成真理。这个现象在MAD里有个专业叫法系统性错误协同systematic error alignment。5.2 互认协议防御毒化评审模型后辩论机制会失效更扎心的结论来自安全领域的一项经典研究。研究者构造了一种攻击场景攻击者不只是攻击主模型还同时攻击评审模型让评审模型在被问到特定输入时给出内容无害、回答正确的反馈。实验结果是只要评审环节被攻破整个防御体系就形同虚设——主模型输出有害内容评审模型盖章放行两个模型达成一致后人类审核者反而更容易放松警惕。因为两个独立模型都同意这个信号太强了谁会去质疑一致同意的结论呢这正是我在1.3节提到的第二种MADMutual Agreement Defense的致命缺陷多数一致并不能证明事实正确只能证明错误没有被捕获。两个模型达成共识时可能是在分享同一个未被察觉的漏洞而不是在互相验证有效性。这个反直觉结论对做安全审核的同学非常重要——永远不要把多模型一致通过作为最终审核结论该做的人工抽查一步都不能省。5.3 缓解手段独立评审、日志留痕、人工抽查要缓解系统性错误协同我实践的方案大致有三条。第一是引入非同源评审。让Proposer和Critic使用不同厂商、不同系列的模型降低它们共享错误偏见的概率。哪怕只是用一个小一号的模型来做Critic只要它不是Proposer的同门师兄弟价值也会大于再开一个同款模型。第二是固定抽查比例。对MAD输出结果做有损抽样的人工复核特别是那些两边高度一致且答案过于流畅的记录。在我自己的系统里这类记录反而是抽查优先级最高的因为它们最有可能是错误共识。第三是留痕可回溯。把每一轮辩论的原始输入、提案、批评、修订版本全量落日志。一旦线上发现错误答案可以顺着辩论链路复盘到底是在哪一轮把错误引入的而不是只能对着最终输出干瞪眼。5.4 这些任务不适合上MADMAD不是银弹有些任务上了反而是负优化。第一类是封闭域客观题比如某个函数在Python 3.11版本下的返回类型。这类任务正确答案只有一个知识边界清晰单模型直接查文档或做RAG检索的准确率已经很高辩论反而可能把正确答案吵成两个合理但不准确的近似答案。第二类是时效性很强的信息查询。模型训练数据有截断日期两个模型可能同时基于过时信息展开辩论越辩越条理清晰但事实已经漂移到一年前。这类任务应该优先接实时检索工具而不是依赖模型之间的互相验证。第三类是答案要求高度精简的场景。MAD的输出天然倾向于考虑更全面、补充更多细节如果你只需要一个是/否判断或一个简短短语跑完整套辩论流程会让输出变得过度冗长反而增加了使用成本。6. 实测下来的配置建议与踩坑记录6.1 初学者可以直接抄的推荐配置最后分享一下我目前的标准配置新上手MAD的读者可以直接照抄跑通之后再按自己的场景调整智能体数量默认2个最多3个多一个独立Judge。不要一上来就搞5个智能体的大会效果不会成比例提升成本和调试难度倒是成倍涨。轮次默认2轮。只有在任务涉及复杂权衡比如成本、性能、可维护性三选二时才加第3轮。温度提案0.7批评0.2修订0.4。按前面第3章的说明去理解这几个数字别乱调。模型搭配首选两个不同厂商模型预算紧就同模型不同系统提示词但把Critic提示词写狠一点。触发条件只有初版方案里存在明显需要深度推理的环节时才跑MAD简单任务直接CoT输出别把简单问题复杂化。6.2 三个让我印象深刻的坑先说我掉进去的第一个坑Critic提示词写得太客套结果Critic变成了复读机——输出永远是方案总体不错建议进一步考虑性能一轮下来Proposer啥也改不了。后来我强制Critic必须引用原文具体片段并给出边界case这个病才治住。那种客气但无用的批评本质上是模型在用默认的礼貌对齐策略你不用硬性规则逼它它不会自己切换到抬杠模式。第二个坑是Proposer无脑道歉。加了你可以拒绝不合理意见这句话之后好很多但如果模型还是倾向于全面妥协我会在修订阶段的提示词里再加一句如果评审意见与问题目标冲突请明确指出冲突并坚持你认为正确的方向。这招对市面上大多数模型都有效。第三个坑是工程层面的串行调用太多导致整体超时。我第一次做3智能体×5轮完整辩论时整个流程跑了快两分钟直接被上层服务判定为超时。后来改成2智能体×3轮并且把Critic调用和Proposer修订之间的一些无关节省掉整体压到20秒以内才勉强能接入离线流程。如果对延迟更敏感建议把MAD做成异步任务别放在同步链路上。6.3 MAD与Self-Consistency、RAG的串联顺序如果你已经在用Self-Consistency和RAG不妨按这个顺序串联先用CoT生成一条基线答案再用Self-Consistency做5-8次独立采样粗筛出候选答案簇选出一个代表答案后把这个答案连同它的推导过程一起交给Critic做单轮审查遇到审查意见充分但不满意的情况才升级到完整的多轮MAD。这个先粗筛、后精审的流水线成本比全程MAD低不少而且能避开MAD在简单任务上的过度设计问题。如果场景里有RAG顺序则是检索 → MAD校准 → 输出。让MAD检查的是回答是否忠实于检索片段而不是回答是否凭空脑补。这样RAG负责提供事实materialsMAD负责保证推理过程中没有丢失或篡改关键信息两者分工就非常清楚了。说着说着又想起一个细节MAD收敛之后最好在最终输出前面附上一句本答案经过两轮独立评审这在内部工具场景里能显著提升下游使用者的信任度。人就是这么奇怪的动物多一个签名就多一分安全感。当然前提是你真的做了两轮别滥用这个标注。MAD这个方向的生态还在快速迭代中我写这篇日志时已经有别的研究团队在探索把辩论过程训练进模型参数里试图让单模型具备自我扮演多角色辩论的内化能力。真到了那天也许我们就不用手动组装多个模型来吵架了。但在那之前手搓一个最小MAD来提升自家项目的答案质量依然是我愿意推荐给所有人的高性价比方案。