围绕「让两个 LLM Agent 就一个话题打辩论」这一需求,深度对比 4 个开源项目的架构、代码、可维护性与适用场景,并附一场实跑辩论 Demo。
一眼看清 4 个项目的关键差异。数据来自 GitHub API 实时抓取与源码阅读。
| 维度 | cultural_debate | DebateBox | MAD | AutoGen |
|---|---|---|---|---|
| 定位 | 学术论文复现(文化对齐) | 概念演示/原型 | 学术研究(思维发散) | 通用多Agent框架 |
| Star ⭐ | 9 | 1 | 596 | 59,602 |
| Agent 数 | 2(无裁判) | 可配(默认3) | 3(正/反/主持)+兜底Judge | 2+可选Judge |
| 有裁判机制 | 无 | 无 | 有(Moderator+Judge) | 有(可配) |
| LLM 后端 | 本地 transformers | 仅 OpenAI(旧SDK) | 仅 OpenAI(旧SDK) | OpenAI/Anthropic/本地 |
| License | 未声明 | Apache-2.0 | GPL-3.0 | MIT |
| 最近更新 | 2026-04 | 2023-06停滞 | 2025-01 | 2026-04维护模式 |
| 在线 Demo | 无 | 无 | 已下线 | Colab + Studio |
| 代码量 | 中等(21个组合文件) | 极小(~200行) | 小(~250行) | 大(框架级) |
| 上手难度 | 中 | 低 | 低 | 高 |
ACL 2025 Oral 配套代码 —— 让两个开源小模型辩论,在文化对齐任务上达到大模型效果。
# [1] 正方初判
prompt1_1 = prompts["prompt_1"].replace("{{story}}", story)
outputs = model1.generate(**tokenizer1(prompt1_1, return_tensors="pt").to("cuda"),
max_new_tokens=1024, temperature=0.0)
generation1_1 = parse_response(tokenizer1.decode(outputs[0]), "Answer:")
# [3] 正方看到反方答案后给反馈
prompt1_2 = prompts["prompt_2"].replace("{{other_response}}", generation2_1) \
.replace("{{your_response}}", generation1_1)
# [5] 正方综合反馈后给最终答案
prompt1_3 = prompts["prompt_3"].replace("{{feedback}}", generation2_2)
generation1_3 = parse_final_answer(generation1_3) # 归一化为 Yes/No/Neither
line["gemma_final"] = generation1_3
line["seallm_final"] = generation2_3
~200 行的最小辩论实现,融合 Constitutional AI 的自我批评机制。
character(人设)和 principles(批评原则)openai<1.0 的 ChatCompletion.create),默认 gpt-4,temperature=1.0def debating_loop(self, seed_message, max_rounds, steps, mode):
for debater in self.protagonists[1:]:
debater.append_to_chat(seed_message)
msg = seed_message
for _ in range(max_rounds):
if mode == "sequential":
debaters = self.protagonists
elif mode == "random_no_repeat":
debaters = random.sample(self.protagonists, k=len(self.protagonists))
for debater in debaters:
# 回复的 role 是 "assistant",传给下一个 agent 前被改成 "user"
msg = self.debating_step(msg, debater, steps)
def debating_step(self, input_msg, character, steps):
input_msg["role"] = "user" # 视角切换
output_msg = character.reply(input_msg, steps=steps)
return output_msg
def reply(self, user_msg, steps=["critique", "revision"]):
self.chat_step(user_msg) # 先正常回复
refined = self.self_improve(steps) # 再自我批评+修订
return refined
def self_improve(self, steps):
for principle in self.principles:
if "critique" in steps:
self.chat_step({"role":"user","content": principle["critique"]})
if "revision" in steps:
self.chat_step({"role":"user","content": principle["revision"]})
return self.chat[-1]
多智能体辩论的"开山之作",提出针对"思维退化"的针锋相对机制。
python interactive.py 交互def run(self):
for round in range(self.max_round - 1):
if self.mod_ans["debate_translation"] != '':
break # 主持人已定论,早停
# 正方读到反方上轮发言后反驳
self.affirmative.add_event(
self.save_file['debate_prompt'].replace('##oppo_ans##', self.neg_ans))
self.aff_ans = self.affirmative.ask()
self.affirmative.add_memory(self.aff_ans)
# 反方反驳
self.negative.add_event(
self.save_file['debate_prompt'].replace('##oppo_ans##', self.aff_ans))
self.neg_ans = self.negative.ask()
self.negative.add_memory(self.neg_ans)
# 主持人裁决
self.moderator.add_event(self.save_file['moderator_prompt']
.replace('##aff_ans##', self.aff_ans)
.replace('##neg_ans##', self.neg_ans))
self.mod_ans = eval(self.moderator.ask()) # ⚠️ eval 解析 JSON
if self.mod_ans["debate_translation"] == '':
# 终极杀招:Judge 兜底
judge = DebatePlayer(model_name=self.model_name, name='Judge', ...)
judge.add_event(self.save_file['judge_prompt_last1']
.replace('##aff_ans##', aff_ans).replace('##neg_ans##', neg_ans))
ans = eval(judge.ask())
class Agent:
def __init__(self, model_name, name, temperature, sleep_time=0):
self.memory_lst = [] # 私有记忆,只含自己视角
def add_event(self, event): # 当前轮上下文(user)
self.memory_lst.append({"role": "user", "content": f"{event}"})
def add_memory(self, memory): # 持久记忆(assistant)
self.memory_lst.append({"role": "assistant", "content": f"{memory}"})
@backoff.on_exception(backoff.expo, (RateLimitError, APIError), max_tries=20)
def query(self, messages, max_tokens, api_key, temperature):
response = openai.ChatCompletion.create(...) # 旧版 SDK
return response['choices'][0]['message']['content']
eval() 解析 LLM 输出,极脆弱微软出品的通用多 Agent 框架,近 6 万 Star,官方提供 debate 设计模式。⚠️ 已进入维护模式。
RoutedAgent,通过自定义消息协议(AnswerMessage / CritiqueMessage)通信,Runtime 负责消息路由from autogen_core import (AgentId, MessageContext, RoutedAgent,
SingleThreadedAgentRuntime, message_handler, type_subscription)
from autogen_ext.models.openai import OpenAIChatCompletionClient
# 1. 定义消息协议
@dataclass
class AnswerMessage:
content: str
@dataclass
class CritiqueMessage:
content: str
# 2. 定义辩论 Agent
@type_subscription("debate")
class DebateAgent(RoutedAgent):
def __init__(self, model_client, system_message, max_rounds=3):
super().__init__("Debate Agent")
self._model_client = model_client
self._system_message = system_message
self._max_rounds = max_rounds
self._round = 0
@message_handler
async def handle_answer(self, message: AnswerMessage, ctx):
# 收到对方答案 → 生成批评
self._round += 1
return [CritiqueMessage(content=critique_text)]
@message_handler
async def handle_critique(self, message: CritiqueMessage, ctx):
if self._round >= self._max_rounds:
return [] # 结束
return [AnswerMessage(content=revised_answer)] # 修正后回击
# 3. 注册并运行
async def main():
runtime = SingleThreadedAgentRuntime()
model = OpenAIChatCompletionClient(model="gpt-4o")
await DebateAgent.register(runtime, "Affirmative",
lambda: DebateAgent(model, "You argue the affirmative side."))
await DebateAgent.register(runtime, "Negative",
lambda: DebateAgent(model, "You argue the negative side."))
await runtime.start()
await runtime.send_message(AnswerMessage(content="..."), AgentId("Affirmative","debate"))
从 6 个维度横向打分(满分 10)。基于实际调研,非主观偏好。
以下是一场真实运行的两角色辩论,话题为「AI 是否会取代人类的工作」,3 轮交锋 + 主持人总结。演示了正反方如何互相质询、修正观点,最终收敛。
我的立场是:AI 将大规模取代人类工作。证据有三:第一,生成式 AI 已能完成编程、写作、设计、翻译等"白领知识工作"的核心产出,而这些恰是过去十年就业增长最快的领域。第二,成本结构不可逆——一个 AI 实例的边际成本趋近于零,而人类员工的边际成本持续上升,企业有强烈经济动机用 AI 替代。第三,历史规律显示,凡是能被"清晰定义输入输出"的工作,最终都会被自动化。AI 正在让越来越多"看似需要创造力"的工作变得可定义、可自动化。
我不同意"大规模取代"这个判断。正方混淆了"任务自动化"与"岗位消失"。AI 取代的是任务(写一段代码、画一张图),而非岗位(一个工程师要理解需求、做架构权衡、与团队协作、对结果负责)。历史上每次技术革命都消灭了旧任务,却创造了更多新岗位——拖拉机消灭了锄地,但创造了农机维修、农业调度、食品加工等更多岗位。AI 也不例外。更重要的是,AI 本身需要大量人类来训练、对齐、审计、运营——这些"AI 相关工作"正在爆发式增长。所以本质是重塑,不是取代。
反方说"AI 取代任务而非岗位",但这个论点正在被现实击穿。当 AI 能完成一个岗位上 80% 的任务时,企业不再需要 10 个人,只需要 2 个人加 AI。这不是"重塑",这是岗位总量缩减。反方还提到"AI 创造新岗位",但请正视一个不对称性:被淘汰的是 50 岁的流水线工人和中级文案,而新创造的"AI 训练师""提示词工程师"需要全新技能——被淘汰的人和能胜任新岗位的人,不是同一批人。结构性失业是真实且痛苦的。反方如何回应这个"技能错配"问题?
正方的"技能错配"论点我有力地承认——这确实是真问题,但它证明的是需要转型与再培训,而非"取代"。请注意正方悄悄把立场从"取代"滑向了"岗位总量缩减",这是两个不同命题。我反问正方:你如何解释,过去 3 年 AI 能力暴涨,而全球失业率并未随之飙升?美国 2025 年失业率仍在历史低位。更根本的是,人类需求是无限的——AI 满足了旧需求,人类会创造出 AI 无法独立满足的新需求(深度陪伴、个性化教育、复杂谈判、价值判断)。经济规律告诉我们:需求创造就业。只要人类需求不枯竭,就业就不会被"取代",只会迁移。正方的悲观,低估了人类创造新需求的能力。
吸收反方观点后,我修正立场:我不再坚持"AI 会让人类无工可做"的极端版本。但我仍坚持核心主张——AI 会大规模取代特定类别的工作,尤其是那些"输入输出可被清晰定义、且不涉及复杂人际与价值判断"的岗位。短期内(5-10 年),初级文案、初级程序员、客服、数据录入等岗位会经历实质性的岗位数量下降。反方说的"新需求创造新就业"在长期成立,但短中期的转型阵痛是真实的,不应被"长期乐观论"掩盖。我的最终立场:取代会发生,且主要集中在可定义性高的岗位;重塑也会发生,但两者并存,取代的痛感先于重塑的红利到来。
吸收正方观点后,我也修正:我承认"任务自动化 → 岗位缩减"在特定领域确实成立,且短期转型阵痛比乐观者预估的更痛。正方对"技能错配"的指出是负责任的。但我仍坚持核心立场:AI 是工具,本质是重塑而非取代。理由收敛为两点:其一,历史上没有一项通用技术(GPT)最终导致人类就业总量永久下降,蒸汽机、电力、计算机都是先阵痛后扩张;AI 作为 GPT,大概率遵循同一规律。其二,"取代"暗示人类在产出环节被完全剔除,但只要存在需求侧的无限性 + 价值判断的人类独占性,人类就不会被取代,而是被推向价值链更高处。最终立场:短期有阵痛与局部取代,长期是重塑与岗位升级;真正该担心的不是"有没有工作",而是"转型期谁被落下"。
本场辩论双方在 3 轮交锋中都实现了立场修正,这正是多智能体辩论的价值——不是分出胜负,而是通过对抗收敛到更精确的共识。
共识点:双方最终都承认"短期局部取代 + 长期重塑"同时成立。分歧从第一轮的"取代 vs 不取代"二元对立,收敛到第三轮的"转型节奏与阵痛分配"的具体分歧。
遗留分歧:正方强调取代的痛感先于红利、技能错配是硬约束;反方强调需求无限性保证长期就业不枯竭、价值判断是人类独占护城河。
裁决:反方略占优——因为反方成功将辩题从"是否取代"重构为"如何平稳转型",这是一个更有建设性的框架。但正方对短期阵痛的警示是反方无法否定的真实贡献。本场无绝对胜负,达成有效收敛。
根据你的具体场景,对号入座。