与 AI 单独讨论方案时,顺畅并不一定意味着结论可靠。模型习惯沿着用户的思路继续补全,安全、成本和实现复杂度等反对意见很容易被弱化。为让不同立场真正进入同一场讨论,作者搭建了一个带主持人、共享上下文、协作协议和预算护栏的多智能体圆桌系统。
一个人用 AI,最舒服的地方也是最大的问题:它太配合了。
你提出一个方案,它顺着你说。你写了一段代码,它帮你补全,而不是先问你"这个设计是不是有问题"。你问"这方案行不行",它列出几点优点和"一些需要注意的地方",然后你点了确认。
问题不在于 AI 不够聪明,而在于结构:单次对话是"你 vs 一个模型",而这个模型的目标是配合你完成任务,不是挑战你。
我需要的是另一种东西:
于是我写了个东西:RoundTable——一个跑在 DeepSeek Harness 上的圆桌会议插件。
【配图 1】建议截:拓扑图全貌(左主持 · 右环形专家 · 中央汇聚网关)

我先试过最朴素的做法:同一个问题分别问 4 个模型,然后把答案拼起来。
结果就是四份互不相干的报告。它们不在同一个上下文里,不会互相反驳,也无法收敛——你只是得到了 4 倍的阅读量。
真正需要的不是"多",而是会议的结构:
| 要素 | 为什么必须有 |
|---|---|
| 角色边界 | 你是安全专家,就只谈安全;否则四个模型会输出四份雷同的综述 |
| 共同上下文 | 能看到别人的发言,才可能反驳;否则只是并行,不是辩论 |
| 协作协议 | 统一的发言格式(状态 / 产出 / 下一步),以及"何时把决策交回人类" |
| 主持人 | 决定谁发言、转达观点、语义仲裁、收敛结论 |
| 预算护栏 | 没有预算的多智能体是无底洞——上下文会爆炸式膨胀 |
这五件事,缺一个,多智能体就退化成"多问几遍"。
打开之后你会看到:左侧一个主持人锚点,右侧一圈专家节点,中间是汇聚网关,连线带方向箭头。
【配图 1】的位置
一句话开会,不用点任何按钮:
开个圆桌会议,评审 v0.5 的架构方案,从性能、安全、成本三个角度各安排一位专家,最后给我一份汇总报告。
主持人会先弹一张设置卡片(专家名单 / 协作模式 / 轮数与 Token 预算 / 知识库 / skill),你确认后才真正创建会议——不会偷偷开会。
① 专家是"持久的子代理",不是一次性调用
每位专家是一个可续聊的子代理,带着《全局协作总纲》(目标 / 角色边界 / 协作协议 / 安全红线)入会。
这意味着:它能记住自己之前说过什么;主持人可以追问;会议可以跨会话存活,重启之后拓扑还在。
② 三种协作模式,成本结构完全不同
| 模式 | 谁在说话 | 成本特征 |
|---|---|---|
| 主持人统筹 | 一切经由主持人转达 | 中——主持人转达有开销,但上下文可控 |
| 多模型平等 | 专家直达互辩 | 高——每轮所有人都要知道所有事,上下文近似平方级膨胀 |
| 针锋相对 | 专家只攻击"已定稿"的方案 | 低——单轮攻击 + 收集表态 |
「多模型平等」我强制要求先设置轮数/Token 上限,超限自动闭麦。因为一旦专家开始互相辩论,成本曲线不是线性的。
③ 观点可拆分、可逐条表态
红队专家的发言通常是一大段。我做了一层"观点拆分":一条发言自动拆成 1~3 条独立观点(LLM 拆分优先;失败则降级为本地按「观点 N」结构切分,零 token)。
于是你可以对单条观点点「支持」或「驳回」——驳回必须填理由,理由会回传给主持人,修订方案时逐条回应。
【配图 2】建议截:针锋相对评审窗口(左方案 / 右观点列表 + 支持·驳回按钮)

下面三个都是我自己写错的地方。比起"我做成了什么",我觉得这些更值得写出来。
流程是这样的:你在 UI 上删掉一个专家 → 写一条记录到 user-actions.jsonl → 主持人下一轮读取并执行 → 然后清空这个文件。
问题出在"清空":最早的实现是直接截断文件,不是原子操作。
如果清空的瞬间恰好 UI 正在追加,或者进程在写一半时崩溃,文件里就会留下半行 JSON。
而读取侧对坏行的处理是——跳过。
于是那条用户操作永久消失,而且没有任何人知道。
修法:
{ cleared, malformed }。最后一条最重要:宁可告诉用户"有 1 条操作丢了",也不要报告一个漂亮的"已清空 3 条"。
评审记录可以导出成 Markdown 交付物。它的头部有这么一行:
- **插件**:@huanlin/dsh-plugin-roundtable v0.2.21
这行是硬编码的。
而 package.json 已经走到 0.2.32 了。
也就是说:用户导出、留存、贴进 issue 的交付物里,版本号是错的——而且没有任何测试会发现。
修法: 新增 src/version.ts 作为源码侧唯一来源,并加了一条测试,两者不一致时直接失败:
test('version.ts 与 package.json 的版本号必须一致')
这个坑的教训不是"记得改版本号",而是:代码里的字面量会在某一天开始撒谎,而没有任何机制阻止它。
界面上有个预算条,写着 1,249 / 200,000 token。
我一直以为那是消耗估算。直到这次翻代码才发现:
meeting.budget.usedTokens += estimateTokens(full.content)
它只累加发言内容(中文约 0.6 token/字),不包含 system prompt、专家 persona、对话历史、工具调用开销。
而这些在真实计费里往往才是大头。
所以:
这次我没做根本修复(要接宿主的真实用量回调,得先确认 API),但做了诚实化:预算行明确标注 (spoken-text estimate only — NOT the real LLM spend),并在给模型的使用协议里加了一条 HONESTY RULE——要求主持人向用户报告时必须说明这个口径。
一个失真的指标比没有指标更危险,因为它看起来很精确。
这个插件自带一个模式叫「针锋相对」:方案定稿后,拉红队专家只挑毛病,禁止提出替代方案。
于是我拿它评审了自己下一轮的开发计划。
红队(zai-coding-cn/glm-5.2)给了 3 条,每条都带文件行号取证:
1. 我的优先级排错了。 我把「设置卡片真机验证」排在第一位,但它其实是运维验证行为,不产出任何代码变更;而卡片逻辑已经有 10 个纯函数测试覆盖。把不产出代码的项,排在并发 bug 修复之前,会拖延真正影响正确性的工作。
2. 我的一项设计越界了。 我想把「每个专家的 Token 上限」和「persona 补充指令」挂到"角色预设"上。但预设的定位是表单填充来源,而这两个都是启动时的运行时参数。塞进去之后,预设就从"填表面板"变成了"执行参数配置中心",职责边界被打破。
3. 我有项是伪需求。
我写"做归档正好把预留的 archived 状态接上闭环"。红队指出:archived 和已有的 ended 没有任何行为差异定义(只读?不可恢复?)。"接上预留状态"的前提是先定义语义,否则是为用而用。
这三条我全部接受。
这就是红队的价值:它不认识我,所以不会为我的方案找理由。
(顺带一提:这次评审因为额度耗尽,只跑完一位专家就搁置了。工具再好,也得有额度。)
① 零依赖测试。
Node 24 原生支持剥离 TypeScript 类型,所以测试可以直接 import 源码里的 .ts:
node --test test/
不需要 vitest / jest / ts-node,零新增依赖。目前 7 个文件、56 个用例,覆盖卡片渲染、输入净化、预算熔断边界、观点拆分兜底、摘要缓存失效、整场导出渲染、版本一致性。
② 每次改动跑三重验证。 双端类型检查 + 构建 + 测试全绿,才算改完。
③ 诚实优先。 预算是估算,就标"估算";缓存是摘要,就说"这是摘要不是全文";红队没发现问题,就输出「暂无」,不许为凑数列问题。
git clone https://github.com/9931666/dsh-plugin-roundtable
cd dsh-plugin-roundtable
pnpm install && pnpm build
dsh plugin --profile web add .
装完重启 DSH、刷新页面,然后在对话里直接说:
开个圆桌会议,从性能、安全、成本三个角度评审这个方案,最后给我一份汇总报告。
做这个插件的过程中,我最深的一个体会是:
多智能体的价值不在"多",而在"结构"。
四个模型各答一遍,你得到四份报告。 四个模型在一个有主持、有角色、有协议、有预算的结构里辩论,你才可能得到一个你自己没想到的反对意见。
而那个反对意见,往往才是真正值钱的东西。
项目地址:https://github.com/9931666/dsh-plugin-roundtable
如何在Ubuntu 20.04上安装Microsoft Edge浏览器
Ubuntu20.10优麒麟触摸手势有哪些? 优麒麟系统新增手势汇总
优麒麟20.04.1发布 更新内容汇总(附下载)
Mermaid Visual Editor 如何同步可视化操作与 Mermaid 源码?
摆脱 AI 一味附和:我组织了 5 个模型进行圆桌评审
AI 流程图生成器如何把英文描述转换为可编辑的 Mermaid 代码?