去中心化的群议:P2P 共识协议与多智能体辩论 (MAD)
What(本文讲什么)
“P2P 共识”在多 agent 语境里经常被混用成两件完全不同的东西:
- 工程一致性(Distributed Consensus):让多副本状态机对同一串操作达成一致,例如 Raft/PBFT 的日志复制与提交规则。
- 认知一致性(Cognitive Consensus):让多个推理体对同一问题达成“观点收敛”,例如 Multi-Agent Debate(MAD)与投票聚合。
这篇文章要做的事情是把边界钉死:
- 什么时候你需要 Raft/PBFT 这类“状态机一致性”。
- 什么时候你需要 MAD 这类“观点一致性”。
- 两者如何组合进一个能长期运行的系统:超时、重试、幂等、并发、回滚、隔离、权限、审计、观测、降级必须一开始就设计进去。
Problem(要解决的工程问题)
多 agent 的 P2P 协作最常见的失败不是“没达成共识”,而是“共识过程失控”:
- 辩论死循环: 没有退出条件,token 被烧干(重试风暴)。
- 双写副作用: 多个 agent 同时做写操作,没有幂等与提交记录,造成重复提交(幂等、并发)。
- 状态撕裂: A 以为某步已提交,B 以为未提交,最终回滚与补偿变成灾难(回滚、审计)。
- 组团幻觉: 多个模型互相强化错误结论,形成 groupthink(观测不足)。
- 归因失败: 发生事故后无法回答“是谁提议、谁同意、谁执行、谁审核”,无法追责与复盘(审计、观测)。
所以核心目标不是“让大家讨论”,而是把讨论与提交变成可治理的协议。
Principle(两种共识:状态机共识 vs 观点共识)
1) 状态机共识:Raft(崩溃容错)要解决什么
Raft 的对象不是“观点”,而是“操作日志”:
- leader election: 选出一个 leader 负责提议日志顺序。
- log replication: 把日志复制到多数派。
- commit rule: 达到提交条件后才对外宣布“已提交”。
它的价值是:在存在宕机与网络分区的世界里,系统仍然能对“哪些操作已经发生”达成一致。
一手资料入口:
- Raft 论文 PDF: https://raft.github.io/raft.pdf
- Raft 官网: https://raft.github.io/index.html
2) 拜占庭共识:PBFT 要解决什么
PBFT 的对象同样是“操作顺序与提交”,但它假设更强的敌对环境:节点可能作恶。它提供一套能容忍拜占庭故障的复制协议。
一手资料入口:
3) 观点共识:MAD(多智能体辩论)要解决什么
MAD 的对象是“观点与证据”,它常被用于:
- fact verification: 多视角互审,降低单体幻觉概率。
- 方案权衡: 多个角色从不同约束出发提出反例与风险。
- 结构化评审: 让结论带上证据、反证与未决问题。
但 MAD 不等价于 Raft/PBFT,因为它不提供“操作日志提交”的硬语义。你可以用 MAD 得出一个“建议”,但你不能用 MAD 来宣称“某个写操作已经被提交且全局一致”。
Usage(怎么用:把 P2P 共识接进 agent runtime)
下面给一个最实用的拆分:把“讨论层”与“提交层”分离。
1) 讨论层(MAD):只产出提案,不做提交
讨论层的输出必须是结构化提案(proposal),而不是自由散文:
plan: 拟执行步骤列表。risks: 工程风险点(超时、重试、幂等、隔离、权限、并发、回滚、审计、观测、降级)。evidence: 引用的文件/日志/URL。stop_conditions: 退出条件与人工介入条件。
并且讨论层必须有退出机制:
- 最大轮次上限(重试)。
- 预算上限(token budget)。
- 收敛判定:投票阈值或“差异度 < 阈值”。
2) 提交层(Commit):只做一件事,保证副作用可控
提交层的责任是:
- 对提案做 schema 校验与权限检查(权限)。
- 把写操作收口为“可审计提交点”(例如 patch 提交,或事务提交)。
- 给每个提交生成幂等 key,并写入 WAL(幂等、审计)。
- 执行超时控制与重试策略(超时、重试),失败时走回滚/补偿(回滚、降级)。
这意味着即使你是 P2P 讨论,最终落到系统副作用上也必须有一个“唯一提交者”或“确定性提交协议”,否则必然并发冲突。
3) 一个最小可行的“提案-提交”协议
{
"proposal_id": "p-20260421-001",
"task_id": "t-xxx",
"plan": [
{"step": "read", "target": "file:src/foo.ts"},
{"step": "patch", "target": "file:src/foo.ts", "patch_id": "patch-abc"},
{"step": "test", "cmd": "npm test", "timeout_ms": 600000}
],
"risks": ["超时", "重试", "幂等", "并发", "回滚", "审计", "观测", "降级"],
"stop_conditions": ["budget_exceeded", "test_failed_twice", "permission_denied"],
"votes": [
{"agent": "A", "decision": "approve", "notes": "risk ok"},
{"agent": "B", "decision": "approve", "notes": "needs timeout cap"},
{"agent": "C", "decision": "reject", "notes": "missing idempotency key"}
],
"decision": {"threshold": "2/3", "result": "approved"}
}
注意:即使投票通过,也只是“允许进入提交层”。真正的写操作仍然要被提交层门禁控制。
Design(设计取舍:为什么要把“共识”做成协议)
没有协议的 P2P,会变成“聊天室”。聊天室的失败模式是:
- 永远在讨论,没有行动(退出条件缺失)。
- 每个人都行动,结果互相覆盖(并发)。
- 失败后都重试,副作用倍增(幂等缺失)。
协议的价值是:让系统可以机械地执行与阻断,而不是靠模型“自觉”。
Pitfall(常见坑与防错)
- 把 MAD 当成分布式一致性: 观点一致不等于日志一致。
- 没有幂等 key: 重试会制造重复副作用(幂等、重试)。
- 没有超时: 讨论或提交卡死导致资源释放失败(超时、资源释放)。
- 没有审计: 无法归因、无法回滚、无法复盘(审计、观测)。
- 权限传递污染: 一个 agent 获得权限后在 P2P 中被传播,形成越权(权限、隔离)。
Debug(排查 P2P 协作故障)
排查时先回答三个问题:
- 失败发生在讨论层还是提交层?
- 是否存在重复提交?(查幂等 key 与 WAL)
- 是否存在并发冲突?(查同一资源是否被多个提交者写入)
然后再去看“讨论内容是否合理”。否则你会在语义层纠结很久,最后发现真正的问题是缺少超时/幂等/审计。
Source(资料来源)
- Raft 论文: https://raft.github.io/raft.pdf
- Raft 官网: https://raft.github.io/index.html
- PBFT(OSDI 99): https://www.usenix.org/conference/osdi-99/practical-byzantine-fault-tolerance
- MAD 框架综述入口: https://www.emergentmind.com/topics/multi-agent-debate-mad-frameworks
- MAD 用于事实核验(示例论文入口): https://www.sciencedirect.com/science/article/pii/S0957417425037194
工程落点:把“共识结果”变成可执行动作
很多系统停在“讨论得出结论”这一步,但工程真正需要的是“可执行变更”。建议把共识输出统一成两种工件:
proposal.json:讨论层产出的提案(计划、风险、证据、退出条件、投票)。commit_record.json:提交层产出的提交记录(WAL),包含幂等 key、资源目标、实际执行结果与回滚信息。
这样你才能做到:
- 审计: 回答“是谁同意了这个提交”(审计)。
- 观测: 聚合失败原因与延迟(观测)。
- 回滚: 当结果不对时,能沿着 commit_record 做补偿(回滚)。
一条必须强调的底线:副作用只能有一个提交者
无论你前面有多少 P2P agent 在讨论,只要进入副作用世界(写文件、改 DB、发请求),就必须有一个“唯一提交者”:
- 由 leader 负责提交(类似 Raft 的 leader 思路)。
- 或由外部 orchestrator 作为提交者。
否则“并发写”会让任何辩论结论失去意义,最后你会在回滚与补偿上消耗掉系统全部预算(并发、回滚、降级)。
这不是保守,这是把系统从“聊天”升级成“可运行系统”的必要条件。
退出机制(避免“共识系统”变成燃烧室)
无论是状态机共识还是 MAD,都必须设计退出机制。一个可落地的退出策略至少包含:
- 最大轮次: MAD 辩论最多 N 轮,超过则进入裁判/人工介入(重试、降级)。
- 最大时间: 每轮讨论与提交都有超时,超时后停止并写审计记录(超时、审计)。
- 最大成本: token 预算上限,超过则禁止继续调用大模型(降级)。
- 最大并发: 对同一资源的提交并发必须受限,避免互相覆盖(并发)。
退出机制的本质是把“无限讨论/无限重试”变成可控的状态机,否则系统只会越来越贵、越来越不稳定。
观测与审计字段(建议固定成 schema)
为了让 P2P 协作可复盘,你至少需要这些字段:
task_id/proposal_id/commit_idagent_id/role(提案者/审计者/提交者)idempotency_key(幂等)attempt/retry_reason(重试)timeout_ms/latency_ms(超时)resource_targets(写入的资源集合)result/error_code(结果)
这些字段一旦固定,你就能做“失败原因分布”“回滚频率”“并发冲突率”等指标,否则只能靠读日志猜。