AI代理决策优化:结构化辩论引擎Amogus的设计与实现
1. 项目概述:一个为AI代理引入“结构化辩论”的决策引擎
如果你用过Cursor、Claude Code这类AI编程助手,或者自己捣鼓过AI Agent,肯定遇到过这个场景:你给AI一个复杂任务,比如“帮我用Next.js 15和Tailwind从头搭建一个带用户认证的博客系统”,AI会立刻给你吐出一个洋洋洒洒的计划。这个计划听起来头头是道,步骤清晰,但你心里总会犯嘀咕——“它真的考虑周全了吗?有没有更好的库?这个部署步骤会不会在云环境里卡住?万一用户量突然上来,数据库设计能扛住吗?”
问题就出在这里。单个AI代理的决策过程是“独裁式”的。它基于自己的知识库和当前提示词,生成一个看似合理的单一方案,但这个方案缺乏挑战、没有辩论、更没有不同视角的碰撞。在真实的软件工程团队里,一个技术方案要经过产品经理(要快)、架构师(要稳)、资深工程师(知道坑在哪)和新手(会问出最基础但关键的问题)的多轮“拷问”才能最终拍板。这种“张力”恰恰是产生稳健方案的关键。
Amogus — The Council这个项目,就是为了把这种“团队辩论”机制注入到AI代理的决策流程里。它不是一个独立的应用,而是一个基于Model Context Protocol的“决策增强层”。你可以把它理解为一个虚拟的、高度结构化的技术评审会,任何支持MCP的AI工具(如Cursor、Claude Code、Windsurf)都可以随时调用它,让四个性格迥异的“AI议员”对你的任务计划进行隔离辩论、相互挑战,最终产出一个经过多维度审视的、带详细理由和备选方案的执行计划。
这个项目在Cursor Hack London 2026上获得了Agent Runtime Tools赛道的第二名,核心目标直指比赛悬赏#08:“让AI代理在行动前为其决策提供理由”。它不只是让AI“解释”一下,而是强制它经历一个完整的、防止“群体思维”的辩论流程,并把所有正反论据透明地呈现给你。
2. 核心设计思路:用架构强制多样性,对抗LLM的趋同本能
设计多智能体系统的最大陷阱,就是你以为搞了四个AI一起讨论,结果它们“英雄所见略同”,迅速达成一致。这本质上是因为大多数LLM在看到了其他AI的推理过程后,其概率分布会自然而然地倾向于生成“我同意,因为…”这类延续性文本。这根本不是真正的辩论,而是“回声室效应”的加速版。
Amogus的核心设计哲学,就是通过架构层面的隔离与约束,而非简单的提示词工程,来强制产生多样化的观点。它认识到,仅仅给AI赋予不同“角色”(比如“乐观者”、“悲观者”)是不够的,必须用制度让它们“不得不”从不同角度思考。
2.1 辩论流程的“两轮制”与结构隔离
项目的核心流程是一个精心设计的两轮制辩论,其精髓在于“隔离”:
第一轮:隔离审议
- 输入:所有四位议员(RAZOR, GHOST, SCOUT, BISHOP)同时收到完全相同的原始需求、通过“侦察兵”阶段收集的上下文信息,以及一个由单个AI生成的“原始计划”。
- 关键约束:在这一轮,四位议员被完全隔离。它们看不到彼此,无法进行任何形式的交流。每个议员都必须根据其独有的“强制评估框架”回答问题。
- 输出:每个议员独立提交一份包含“批判意见”、“修订后的计划”和“投票(赞成/反对原始计划)”的结构化输出(JSON格式)。
第二轮:挑战与反驳
- 触发条件:只有当第一轮的投票结果出现分歧(非全票通过或否决)时,才会进入第二轮。
- 过程:所有议员第一轮的立场和理由被同时公开。每个议员必须选择另一个立场不同的议员进行针对性挑战,并提出反驳。之后,它们进行最终投票,可以选择“坚持己见”或“改变立场”。
- 防从众机制:这里引入了一个“叛变惩罚”机制。如果一个议员在第二轮改变了自己的投票(即“叛变”),它的信誉分会受到惩罚。这从制度上抑制了无原则的跟风行为。
这个设计模拟了高效的会议:先让每个人独立思考形成观点,再集中讨论碰撞。隔离确保了观点的独立性,而结构化的挑战环节确保了讨论的针对性和深度。
2.2 议员的“人设”与强制评估框架
让四个AI产生不同观点的关键,不是起不同的名字,而是给它们截然不同的、必须回答的问题清单。这就是“强制评估框架”。即使底层是同一个Claude模型实例,回答不同的问题必然导致不同的推理链条和结论。
| 议员 (代号/颜色) | 核心人设 | 强制评估框架(必须回答的问题示例) |
|---|---|---|
| RAZOR (红色) | 执行者/交付狂 | 1. 实现可运行产品的最快路径是什么? 2. 计划中哪里隐藏了复杂性? 3. 哪些部分可以明确推迟到V2? 4. 每一步的现实工作量估算是否准确? |
| GHOST (紫色) | 悲观主义者/风险官 | 1. 当负载增长10倍时,什么会最先崩溃? 2. 每一步的兜底回滚计划是什么? 3. 哪些依赖项可能突然断供或出现重大变更? 4. 哪些错误情况被忽略了? |
| SCOUT (绿色) | 研究员/生态通 | 1. 现有开源方案哪些能直接解决部分问题? 2. 相关技术栈的基准测试数据说明了什么? 3. 社区的趋势和采用率如何? 4. 是否忽略了某些重要的先前案例? |
| BISHOP (黄色) | 架构师/系统思维者 | 1. 执行后的系统依赖图会变成什么样? 2. 这个方案是否会制造不必要的耦合? 3. 步骤的顺序在技术逻辑上是否正确? 4. 应该定义哪些清晰的抽象层? |
这种设计天然形成了“2v2”的张力:RAZOR和SCOUT通常倾向于“用现成方案,快速上线”,而GHOST和BISHOP则倾向于“设计稳健,打好基础”。这种张力正是产出平衡方案所需要的。
2.3 “死神”机制:引入进化压力
这是项目中最具游戏化色彩,也最体现系统思维的一环。系统不会让议员们永远固步自封。
- 评分:每次决策后,会根据议员的投票是否与最终采纳的方案一致、是否“叛变”等行为,更新其个人得分。
- 淘汰与进化:每经过5次决策,系统会进行一次评估。得分最低的议员(如果低于阈值)会被“处决”——从议会中移除。
- 繁衍:同时,系统会“繁衍”一个新议员。这个新议员会随机继承一个基础人设,但会从当前得分最高的议员那里继承一个“强制评估问题”。它的“族谱”会被记录,例如
GHOST-v3 (paranoid + RAZOR traits)。
这个机制模拟了“适者生存”。糟糕的思维模式会被淘汰,成功的思考角度(体现为某个好的评估问题)会像基因一样在议会中传播。通过人类用户使用council_override工具对历史决策进行纠正,系统还能间接学习到用户的真实偏好,让议会整体向更有用的方向进化。
3. 技术架构与实现拆解
Amogus不是一个庞然大物,它的架构清晰且高效,在5小时的黑客松中完成,体现了良好的工程取舍。
3.1 协议层:基于Model Context Protocol的轻量集成
选择MCP是项目的关键决策,这决定了它的定位和可用性。
- 为什么是MCP?MCP是一个新兴的、旨在标准化AI应用与工具之间通信的协议。它使用简单的stdio或HTTP作为传输层,通过JSON-RPC进行通信。这意味着任何实现了MCP客户端的AI工具(如Cursor、Claude Code)都可以无缝调用Amogus,而无需复杂的插件系统或API集成。Amogus将自己暴露为一组MCP工具,完美契合了黑客松“Agent Runtime Tools”的赛道要求。
- 核心工具:
council_plan: 核心工具,触发完整的辩论流程。council_members: 查看当前议会成员状态和“族谱”。council_history: 审计日志,查看历史决策细节。council_override: 人类反馈回路,用于纠正历史决策,影响议员评分。council_sandbox: 打开实时可视化沙盘。
3.2 服务端:Node.js与并发的LLM编排
服务端使用TypeScript开发,核心是高效、可靠地并行协调多个LLM调用。
- 并发控制:第一轮审议中,四个议员的LLM调用是通过
Promise.allSettled并发执行的,这最大程度减少了等待时间。这是实现“隔离”的技术基础——它们物理上就是同时、独立发起的请求。 - 结构化输出:调用Claude API时,严格使用JSON Schema来约束输出格式。这确保了无论模型生成多么冗长的文本,最终都能被解析成程序可处理的标准化数据(投票、批判点列表、修订计划),避免了“用自然语言处理自然语言”的复杂性。
- 上下文侦察:在辩论开始前,有一个独立的“侦察”阶段。这里直接利用了Claude API内置的联网搜索工具,对任务涉及的关键词进行并行搜索,获取最新的库信息、GitHub动态、文档等。项目明智地没有引入向量数据库或嵌入模型,因为对于这种一次性的、任务相关的信息检索,实时搜索的准确性和时效性更高,架构也更简单。
- 状态与通信:服务端内置了一个轻量的HTTP/WebSocket服务器。它负责两件事:一是托管可视化沙盘的静态文件;二是通过WebSocket向沙盘推送实时事件(如“议员A开始思考”、“进入第二轮”、“BISHOP挑战了GHOST”)。这种设计将可视化与核心逻辑解耦,沙盘只是一个“客户端”。
3.3 可视化沙盘:Next.js与Canvas的实时演绎
可视化部分用“Among Us”游戏风格呈现,极大地增加了项目的趣味性和演示效果。
- 技术选型:采用Next.js 15进行开发,但构建为静态导出。这意味着沙盘的所有前端资源(HTML, JS, CSS)都是静态文件,由上述的Node.js服务器直接托管。无需单独启动一个前端服务,降低了部署复杂度。
- 渲染核心:游戏化的场景(飞船地图、船员走动、会议桌动画)使用HTML5 Canvas绘制,而不是DOM。Canvas在处理大量动态图形和动画时性能更好,也更适合这种“小游戏”风格的渲染。
- 实时同步:通过WebSocket与服务端连接。服务端在辩论的每个关键节点(共定义了约18种事件类型)都会推送事件,前端根据事件类型更新Canvas动画和右侧的文本面板(显示批判内容、投票进度等)。这种事件驱动的方式保证了视图与后端状态的强一致性。
- 自动寻址:服务器启动时会自动探测可用端口,避免了手动配置端口可能导致的冲突,提升了用户体验。
4. 实操:如何集成并使用Amogus
让我们抛开理论,看看如何真正把它用起来。假设你是一个使用Cursor进行开发的工程师。
4.1 安装与配置
最快捷的方式是一行命令安装:
curl -fsSL https://raw.githubusercontent.com/ViktorSmirnov71/amogus/main/setup.sh | bash这个脚本会帮你完成克隆仓库、安装依赖、配置环境变量等所有步骤。
如果你想手动操作,步骤也很清晰:
- 克隆项目:
git clone https://github.com/ViktorSmirnov71/amogus.git - 安装依赖:进入
mcp-server目录运行npm install。 - 配置API密钥:在项目根目录创建
.env文件,填入你的ANTHROPIC_API_KEY。 - 配置MCP客户端:以Cursor为例,将项目提供的
.cursor/mcp.json.example复制为.cursor/mcp.json,并修改其中的路径指向你本地的Amogus服务器入口文件。
注意:确保你的Claude API有足够的权限和额度,因为一次完整的
council_plan调用可能会消耗多次(4+)的Claude API请求。
4.2 在Cursor中发起一次议会辩论
安装配置完成后,重启Cursor。现在,你的AI助手就具备了调用议会的能力。
提出一个复杂需求:在Cursor的Chat界面,你可以直接输入:
“使用
council_plan工具来帮我规划一下:我要开发一个个人财务追踪Web应用,后端用Python FastAPI,前端用React,需要包含交易导入、分类和简单报表功能。请确保方案考虑周全。”观察过程:Cursor的Agent会识别到这个工具调用,并启动Amogus服务。此时,你的浏览器可能会自动弹出,展示Among Us沙盘界面。你会看到四个小船员开始忙碌:
- 侦察阶段:他们跑向不同的“研究站”(Web搜索、文档、GitHub等),收集信息。
- 第一轮隔离:船员们走进隔离舱,头顶冒出思考气泡,右侧面板开始滚动显示每位议员的批判意见。例如,RAZOR可能会说:“直接用Plaid API导入交易太复杂,初期可以手动CSV上传。” GHOST则会警告:“CSV解析必须处理各种日期格式和字符编码错误。”
- 第二轮辩论(如果需要):船员们围到会议桌,彼此之间出现挑战连线,进行反驳。
- 投票与合成:投票条动态填充,最终一个综合了所有意见、并带有颜色标注(指出每条建议来自哪位议员)的详细计划文档在屏幕中央“敲定”。
获取结果:最终,Cursor会收到一个结构化的、可直接执行的“产品需求文档”。这个文档不仅包含步骤,还会附注:
- “RAZOR建议:将‘实现投资账户同步’移至V2阶段。”
- “GHOST警告:在交易分类算法中必须添加人工复核覆盖机制。”
- “SCOUT发现:可以考虑使用
react-chartjs-2库快速实现图表,社区活跃。” - “BISHOP设计:应在后端明确划分
数据导入层、业务逻辑层和API路由层。”
现在,你得到的不是一个平铺直叙的计划,而是一个经过多角度辩论、风险被标识、备选方案被评估的增强版决策。你可以基于这个更有深度的计划,继续让Cursor或你自己来执行。
4.3 高级用法与系统维护
- 查看议会状态:如果你好奇当前议会的构成,可以在Cursor里问:“调用
council_members看看。” 你会看到每个议员的胜率、被“处决”次数和遗传谱系。 - 纠正历史决策:如果你发现之前某次议会给出的最终建议在实际操作中是个坏主意,你可以使用
council_override工具来“翻案”。系统会调整相关议员的分数,影响未来的进化方向,让议会更贴合你的判断标准。 - 审计与复盘:通过
council_history,你可以回顾过去的每一次辩论,看看当时每位议员的具体理由和投票情况,这对于理解AI的决策逻辑非常有帮助。
5. 开发心得与避坑指南
在复现或借鉴这个项目时,有几个关键点需要特别注意,这些是从项目设计和我们实践经验中总结出的干货。
5.1 确保真正的“隔离”
- 坑:最容易犯的错误是“伪隔离”。比如,在代码中不小心让后一个LLM调用的提示词里包含了前一个调用的输出,或者使用了全局变量导致信息泄露。
- 解法:像Amogus一样,使用
Promise.allSettled或Promise.all发起完全并行的请求。确保每个请求的提示词模板是独立的,所有输入数据在调用前就已准备就绪。将每个议员的上下文、问题框架、原始计划作为独立的变量传入,避免任何串行依赖。
5.2 结构化输出是生命线
- 坑:依赖LLM生成自由格式的文本来进行后续解析,是一场噩梦。格式的轻微不一致就会导致解析失败,整个流程崩溃。
- 解法:不惜一切代价使用结构化输出。无论是通过Claude的JSON模式、OpenAI的函数调用(工具调用),还是Llama的grammar,必须强制模型返回一个格式预定义的JSON对象。Amogus中每个议员的输出都严格定义了
{critique: string[], revisedPlan: string[], vote: ‘approve’ | ‘reject’}这样的结构。这大大提升了系统的可靠性。
5.3 评估框架的设计比角色名称更重要
- 心得:不要满足于给AI起个“魔鬼代言人”或“乐观派”的名字。这几乎没用。你必须设计出具体、可操作、互斥的问题列表。RAZOR的“哪里可以推迟?”和GHOST的“什么会崩溃?”就是绝佳的例子。好的问题才能引导出不同维度的思考。
5.4 控制成本与延迟
- 注意:一次完整的
council_plan调用涉及至少:1次侦察搜索 + 1次原始计划生成 + 4次第一轮调用 + (可能)4次第二轮调用 + 1次合成。这可能会消耗大量token并增加响应时间。 - 优化建议:
- 设置超时和回退:对每个LLM调用设置严格的超时限制,并使用
Promise.allSettled确保单个成员失败不会导致整个流程失败。 - 缓存侦察结果:对于常见或相似的任务,可以缓存侦察阶段的结果,避免重复搜索。
- 提供“快速模式”选项:在不需要极高可靠性的场景,可以提供跳过第二轮辩论或减少议员数量的选项。
- 设置超时和回退:对每个LLM调用设置严格的超时限制,并使用
5.5 可视化是“可观测性”的体现
- 心得:Amogus的Among Us沙盘不仅是噱头。对于这种多步骤、异步的复杂系统,可视化是至关重要的调试和信任构建工具。它能让你直观地看到流程进行到哪一步、每个AI“在想什么”。如果你构建类似的系统,即使不做游戏化,也强烈建议提供一个能实时显示状态和中间结果的简单界面。这比查看日志文件直观得多。
6. 常见问题与排查实录
在实际运行或借鉴开发时,你可能会遇到以下问题:
Q1: 调用council_plan后,Cursor没反应,也没弹出浏览器。
- 排查步骤:
- 检查
.cursor/mcp.json配置文件中的路径是否正确指向了mcp-server目录下的编译输出(通常是dist/index.js)或源码(src/index.ts,如果配置了直接运行ts-node)。 - 在终端手动进入项目目录,运行
npm start或node dist/index.js,查看服务器是否正常启动,有无报错(如API密钥缺失、端口占用)。 - 查看Cursor的“MCP Server”日志(通常可以在设置或开发者工具中找到),看是否有连接错误。
- 检查
Q2: 议会辩论结果看起来还是很趋同,四个议员说的都差不多。
- 原因与解决:
- 评估框架不够有力:检查你为议员设计的“强制评估问题”是否足够具体和差异化。尝试让问题更尖锐、更聚焦于不同阶段(如RAZOR只关心“本周”,GHOST只关心“明年”)。
- 提示词泄露:再次确认隔离性。确保在构造每个议员的提示词时,没有意外混入其他角色的信息。
- 模型温度:尝试适当提高LLM调用的“temperature”参数(例如从0.2调到0.7),增加输出的随机性。但要注意,太高会导致输出不稳定。
Q3: WebSocket连接失败,沙盘不更新。
- 排查:
- 打开浏览器开发者工具,查看Console和Network标签页,确认WebSocket连接是否成功建立(状态码101)。
- 确保服务端HTTP服务器成功启动,并且沙盘前端连接的是正确的WS地址(通常是
ws://localhost:[端口]/ws)。 - 检查服务端是否有CORS问题,虽然项目设计为本地托管,通常不会有此问题。
Q4: 运行一段时间后,API调用频繁失败或超时。
- 可能原因:
- API限额:检查你的Anthropic API套餐的每分钟/每天请求限制。一次议会辩论消耗多次调用,频繁使用可能触发限流。
- 网络问题:确保网络稳定。可以考虑为LLM调用添加重试逻辑(例如,指数退避重试2-3次)。
- 服务端资源:如果并发请求太多,Node.js进程可能占用较高内存。确保你的运行环境资源充足。
这个项目最吸引我的地方在于,它用一种优雅且可复用的方式,解决了一个AI应用中的普遍痛点——单一代理决策的盲目自信。它没有试图打造一个全能AGI,而是选择做一个专注的“决策增强器”。通过MCP协议,它可以像乐高积木一样嵌入到现有的AI工作流中,这种设计思路非常值得借鉴。在实际尝试将其思想应用到自己的项目中时,最大的收获是:对抗AI的趋同性,需要的是制度设计,而不仅仅是角色扮演。
