云计算百科
云计算领域专业知识百科平台

让 AI 自己辩论,裁判说停才停——多 Agent 对抗辩论系统

在这里插入图片描述

TL;DR(30 秒速览)

  • 单 Agent 分析容易"一边倒"——要么过度看多,要么过度看空。解决方案:让 AI 自己辩论
  • 三角色模型:**Judge(裁判)**负责流程和个性化 Prompt、**Participants(参与者)**对抗辩论、Judge 自主判断收敛
  • 不是固定轮次——Judge 通过结构化 JSON {"converged": true/false} 自主决定何时达成共识
  • 裁判使用中立编排 Prompt(剥离人设),防止不自觉地偏向某个参与者
  • 开源地址:github.com/haibingzhao/easyai

前情提要:在上一篇文章中,我们聊了 DAG Swarm 编排——用 Kahn 算法实现多 Agent 的分层并行执行。但同一层里的多个 Agent 各说各话,谁来综合判断?答案是 Deliberation——对抗辩论 + 裁判裁决。


一个 Agent 的盲区

让一个 AI 分析苹果公司的投资价值,它可能会说:

“苹果基本面强劲,iPhone 销量稳健,服务业务增长迅猛,建议买入。”

听起来很有道理。但你问它风险因素,它也能列出一堆:

“估值偏高,中美关系存在不确定性,创新放缓。”

然后呢?它又告诉你"综合来看仍然值得买入"。

这就是单 Agent 的盲区——它不是没有看到反面论据,而是看到了也会合理化掉。LLM 天然倾向于给出一个"自洽"的结论,而不是真正对抗性地审视自己的观点。

核心矛盾: 单 Agent 能看到正反两面的信息,但缺乏结构性对抗——没有人逼它认真对待反面论据。


灵感来自法庭

法庭是怎么接近真相的?不是让一个法官自己去调查,而是:

  • 控方全力论证被告有罪
  • 辩方全力论证被告无罪
  • 法官居中主持,确保程序公正
  • 双方多轮对抗,互相质疑
  • 最终法官基于完整辩论做出裁决
  • EasyAI 的 Deliberation 机制就是这个思路: 在这里插入图片描述

    Judge(裁判)
    ├── 生成开场 Prompt → 所有参与者响应
    ├── 审阅完整历史 → 为每位参与者生成个性化 Prompt
    ├── 自主判断是否收敛 → 未收敛则继续下一轮
    └── 收敛后 → 输出最终裁决

    Participant 1(多头)
    └── 接收个性化 Prompt → 输出论点

    Participant 2(空头)
    └── 接收个性化 Prompt → 输出论点


    四个关键设计决策

    在这里插入图片描述

    一句话概括: Deliberation 的核心不是"让多个 AI 说话",而是谁来决定说什么、什么时候停、怎么避免偏见。

    决策 1:裁判的中立性——剥离人设

    这是最关键的设计。如果 Judge 本身是一个"投资分析师",它在主持辩论时会不自觉地偏向某种分析框架。

    解决方案:在编排阶段,替换 Judge 的 System Prompt 为中立编排 Prompt。

    // DeliberationTaskExecutor.kt
    val ORCHESTRATOR_SYSTEM_PROMPT = """
    |You are the orchestrator of a multi-agent deliberation session.
    |
    |Your responsibilities:
    |1. Generate clear, balanced prompts that guide participants
    | through structured discussion
    |2. Objectively assess whether consensus has been reached
    |3. When generating personalized prompts, reference specific
    | prior arguments and direct participants to address
    | unresolved points
    |
    |Be neutral, fair, and focused on productive deliberation.
    |Do not inject your own opinions or expertise — your role
    |is to facilitate the discussion, not participate in it.
    """
    .trimMargin()

    注意最后一句:“Do not inject your own opinions — your role is to facilitate, not participate.” Judge 在编排阶段是纯粹的流程管理者,不带任何观点倾向。

    但在最终裁决(Verdict)阶段,Judge 恢复自己的人设——因为裁决本身就是需要专业判断的。

    决策 2:个性化 Prompt——每轮量身定制

    第 1 轮:所有参与者收到 Judge 生成的同一个开场 Prompt。

    第 2 轮起:Judge 审阅完整辩论历史后,为每位参与者单独生成 Prompt:

    {
    "converged": false,
    "reason": "多头尚未回应空头关于估值泡沫的质疑",
    "prompts": [
    {
    "participantId": "BullResearcher",
    "prompt": "空头指出 PE 35x 远超历史均值。请从增长预期角度回应这一估值质疑。你的前两轮论证(agent=BullResearcher)强调了服务业务增长,请具体量化。"
    },
    {
    "participantId": "BearResearcher",
    "prompt": "多头认为服务业务可以支撑高估值。请从历史估值回归的角度,具体分析服务业务的天花板。"
    }
    ]
    }

    每个 Prompt 都:

    • 引用了具体的历史论点(“空头指出 PE 35x”)
    • 指向未解决的问题(“估值质疑”)
    • 提醒参与者自己的身份(“你的前两轮论证”)

    决策 3:自主收敛——不是固定轮次

    传统做法是固定辩论 3 轮就结束。但有些议题 2 轮就够了,有些可能需要 5 轮。

    EasyAI 的方案:Judge 通过结构化 JSON 自主判断收敛。

    // JSON Schema 约束 Judge 的输出
    val ROUND_PROMPTS_SCHEMA = """
    {
    "type": "object",
    "properties": {
    "converged": { "type": "boolean" },
    "reason": { "type": "string" },
    "prompts": {
    "type": "array",
    "items": {
    "type": "object",
    "properties": {
    "participantId": { "type": "string" },
    "prompt": { "type": "string" }
    },
    "required": ["participantId", "prompt"]
    }
    }
    },
    "required": ["converged", "reason"]
    }
    """

    当 converged = true 时,辩论结束,进入裁决。当 converged = false 时,Judge 必须为每位参与者生成下一轮的个性化 Prompt。

    安全网: maxRounds(默认 3)是硬性上限,防止无限辩论。

    for (round in startRound..deliberation.maxRounds) {
    // Judge 生成个性化 Prompt 或判断收敛
    val generatedPrompts = generateRoundPrompts(...)
    if (generatedPrompts == null) {
    // converged = true → 进入裁决
    break
    }
    // 每位参与者响应
    for (participantId in speakers) {
    // …
    }
    }
    // 裁决阶段
    val verdict = workerExecutor.executeWorker(judgeSpec, verdictPrompt, ...)

    决策 4:参与者 Prompt 互相隔离

    参与者 P1 看不到 P2 的 System Prompt(人设),只能看到 P2 的发言内容。

    辩论历史用 XML 标签格式化,清晰区分每个参与者的发言:

    <deliberation_history>
    <entry agent="BullResearcher" round="1">
    苹果服务业务年增长 20%,护城河深厚…
    </entry>
    <entry agent="BearResearcher" round="1">
    PE 35x 远超历史均值 22x,估值泡沫明显…
    </entry>
    </deliberation_history>

    这确保了信息对称——每个参与者知道对方说了什么,但不知道对方的"内心想法"(System Prompt)。就像法庭上,控辩双方可以互相质证,但不能读对方的内心。


    完整的执行流程

    把四个决策串起来,一次完整的 Deliberation 执行流程是:

    ┌─ 开场阶段 ──────────────────────────────────────────┐
    │ Judge(中立编排 Prompt)→ 生成开场 Prompt │
    │ 所有参与者收到同一个开场 Prompt → 各自响应 │
    └──────────────────────────────────────────────────────┘

    ┌─ 辩论循环(Round 2..maxRounds)─────────────────────┐
    │ Judge 审阅完整历史 → 输出 JSON: │
    │ converged=true → 进入裁决 │
    │ converged=false → 为每位参与者生成个性化 Prompt │
    │ 每位参与者收到自己的 Prompt → 各自响应 │
    │ 每轮结束后持久化 DeliberationEntry │
    └──────────────────────────────────────────────────────┘

    ┌─ 裁决阶段 ──────────────────────────────────────────┐
    │ Judge(恢复自身人设)→ 收到完整辩论历史 │
    │ → 输出最终裁决(结论 + 理由 + 置信度) │
    └──────────────────────────────────────────────────────┘


    断点恢复:辩论到一半服务重启了怎么办

    辩论可能持续 10-20 分钟。如果第 3 轮结束时服务重启了,前 2 轮的 token 和讨论内容不能丢。

    方案:每个发言者完成后立即持久化。

    // 每个参与者响应后立即写入数据库
    history.add(DeliberationEntry(
    agentId = participantId,
    round = round,
    response = result.summary,
    inputTokens = result.inputTokens,
    outputTokens = result.outputTokens,
    // …
    ))
    // 增量持久化
    store?.saveDeliberationHistory(run.id, task.id, history.toList())

    恢复时,从数据库加载历史记录,重建 token 计数器,找到最后一个完整轮次,从下一轮继续:

    // 从持久化历史重建 token 计数器
    for (entry in history) {
    total.input += entry.inputTokens
    total.output += entry.outputTokens
    }
    // 找到最后完成的轮次
    val lastCompletedRound = /* 找到所有参与者都完成的最后轮次 */
    val startRound = lastCompletedRound + 1

    关键细节: token 计数器必须从持久化数据重建,不能从内存恢复——因为进程重启后内存已经清空了。


    消除偏见的四道防线

    偏见来源消除手段代码位置
    Judge 自身人设泄漏 编排阶段替换为中立 Prompt ORCHESTRATOR_SYSTEM_PROMPT
    参与者互相影响人设 Prompt 互相隔离,只共享发言内容 formatDeliberationHistoryText()
    LLM 跑题或"人身攻击" JSON Schema 约束输出格式 ROUND_PROMPTS_SCHEMA
    无限辩论 maxRounds 硬性上限 for (round in 1..maxRounds)

    前端可视化

    辩论过程在前端以轮次卡片的形式展示:

    • 轮次选择器:顶部横栏,点击切换不同轮次
    • 参与者卡片:每轮中每个参与者的发言独立展示,可折叠
    • 开场 Prompt / 轮次 Prompt:可查看 Judge 为每轮生成的 Prompt(理解"为什么这么问")
    • 收敛状态指示器:实时显示辩论是否已收敛
    • 最终裁决区:独立展示 Judge 的最终裁决,支持 Markdown 渲染

    运行中的辩论通过轮询(3 秒间隔)自动刷新——每当有新的 DeliberationEntry 写入数据库,前端就能看到。


    实战案例

    案例 1:多空辩论(投资分析)

    participants: [BullResearcher, BearResearcher]
    judge: ResearchManager
    maxRounds: 3

    多头看到利好数据,空头看到风险因素,裁判综合裁决。经过 2-3 轮对抗,通常能收敛到一个带有明确评级(买入/持有/卖出)的投资方案。

    案例 2:三方风险辩论

    participants: [AggressiveAnalyst, ConservativeAnalyst, NeutralAnalyst]
    judge: PortfolioManager
    maxRounds: 3

    在多空辩论之后,再加一轮三方辩论——激进派主张重仓、保守派主张轻仓、中立派平衡——最终由 Portfolio Manager 给出交易决策。

    案例 3:代码方案评审

    participants: [MicroserviceAdvocate, MonolithAdvocate]
    judge: TechLead
    maxRounds: 2

    一个 Agent 主张微服务架构,另一个主张单体——裁判给出技术推荐。通常 2 轮就够了。


    踩坑记录

    三个坑,每个都和"LLM 不听话"有关。

    坑 1:Judge 的人设泄漏。 最初没有替换 System Prompt,Judge 在生成个性化 Prompt 时会不自觉地偏向某个参与者——比如给多头生成"请继续论证增长逻辑",给空头生成"请简要说明风险"。修复:引入 ORCHESTRATOR_SYSTEM_PROMPT,在编排阶段完全剥离人设。

    坑 2:LLM 偷懒提前收敛。 有时 Judge 在第 1 轮就返回 converged: true,理由是"双方观点已经很清晰"。实际上参与者还没来得及互相质疑。修复:增加 reason 字段的检查——如果 reasoning 太短或没有引用具体论点,使用 fallback Prompt 强制继续。

    坑 3:持久化遗漏 token 用量。 最初 DeliberationEntry 不包含 token 字段,断点恢复后无法统计成本——因为内存中的计数器丢了。修复:每个 Entry 记录 inputTokens、outputTokens、cacheReadTokens、cacheWriteTokens、durationMs,恢复时逐项累加重建。


    写在最后

    单 Agent 分析像一个人自己下棋——他能看到好几种走法,但最终会选自己最喜欢的那一种。多 Agent 辩论像两个高手对弈——每一步都会被对手挑战,最终的结果更接近真相。

    维度单 Agent 分析Deliberation 辩论
    偏见控制 依赖 Prompt 工程 结构性对抗
    反面论据 看到但可能合理化 被对手强制提出
    收敛判断 Agent 自己说了算 Judge 独立判断
    输出质量 自洽但可能偏颇 经过对抗检验
    成本 1 次 LLM 调用 N 轮 × M 参与者 + 裁决

    EasyAI 的 DeliberationTaskExecutor 用 604 行 Kotlin 代码实现了完整的对抗辩论系统——中立裁判、个性化 Prompt、自主收敛、断点恢复、增量持久化。核心思想只有一个:让 AI 像法庭一样接近真相。

    下一篇,我们聊聊 EasyAI 的 TEAM Agent——Leader 如何自动分解任务并协调 6 个专业成员并行工作。


    开源地址:https://github.com/haibingzhao/easyai

    欢迎 Star、Issue 和 PR。

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » 让 AI 自己辩论,裁判说停才停——多 Agent 对抗辩论系统
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!