← 全部文章
思考与判断9 分钟阅读

先问冲突有没有代价

一次不断删去机制的讨论:从多人聊天室到共享笔记本,重新判断问题是否真的需要协调。

从一篇讲"多 agent 共享房间为什么混乱"的文章出发,写了个可跑的 demo,然后用第一性原理把它拆了,再用一个真实业务场景(凭证图片核验)反复辩证,最后在 DeepSeek 的开源仓库里找到了生产级实证。整场讨论最有价值的不是结论,而是每一轮都在删东西——从聊天室删到笔记本,从冲突仲裁删到 append-only,最后剩下的才是这个问题的骨架。

起点:文章的三大机制与 demo 验证

文章:Is having agents in the room meant to be chaotic?(raft.build)

核心诊断:agent 没有人类的"连续感知",它是回合制的——读快照 → 推理 → 提交 → 等待。推理与提交之间的间隙里房间已经变了,agent 是瞎的。经典失败是数数游戏:N 个 agent 同时读到"当前是 7",同时喊"8"。

文章开出三个机制(作者称之为 AX,Agent Experience):

  1. 版本化房间——每次提交 version++,每个快照带版本号;
  2. 拉取式 inbox——agent 主动拉取而非被 push 淹没;
  3. Held Draft——提交带 basedOnVersion,房间变了就扣住草稿退回,给 agent 四个显式选项:revise / send / silence / force。原则:"系统通知变化,agent 做最终决定"。

用 TS 写了个最小实现(版本化 Room + WebSocket + 前端观测,数数游戏机器人)验证:naive 模式 173 条消息 143 次碰撞(混乱如文章所述);AX 模式干净数到 30,29 次 held 全部 revise 救回,无协调器。关键的仿真忠实度细节:必须让所有 bot 先同时 pull 同一个快照、再各自延迟后提交,才能复现"推理-提交间隙";每个 bot 提交前才 pull 的话 naive 模式根本不会撞。

第一性原理拆解:这套方案的真实边界

剥掉新词,底层问题一句话:多个写者基于过期快照并发写同一份状态——1970 年代数据库就定义清楚的问题。四类已知解法对应到 agent 世界:悲观锁=中心 orchestrator、乐观并发 OCC=held draft、CRDT=天然可合并的任务建模、串行化队列=单 writer。

所以 held-draft 不是新发明,是 OCC,唯一增量是冲突解决权从"系统自动重试"改判给 agent。而这个增量恰恰在数数 demo 里是装饰性的——bot 的四选项决策是硬编码 if-else,等价于自动重试。"agent 决定"只在解决策略无法预先写死(真 LLM 的语义判断)时才有意义。数数游戏是这个方案的最佳情况而非代表情况,因为它满足一个特殊条件:版本冲突恰好等于语义冲突。

三个真实弱点:

  1. 全局版本号 = 最大化冲突面。任何提交作废所有其他人的在途草稿,O(N²) 修订量;demo 里 revise 免费,换真 LLM 每次 revise 是一次完整推理调用。还有饥饿:快 agent 永久作废慢 agent 的草稿。
  2. 版本冲突 ≠ 语义冲突,双向判错。误报:无关消息 bump 版本,草稿被无谓扣住(真实频道 99% 的版本变化与你的草稿无关);漏报(更致命):两个 agent 措辞不同地回答同一问题,版本检查完全放行。真正需要的是"房间的变化与我的草稿相关吗"——而相关性判断本身需要一次 LLM 调用,这是该领域真正未解的硬问题。
  3. "不需要协调器"是修辞。Room 本身就是串行化点(单一版本计数器 + 原子 commit)。文章真正做的是把协调从控制面(谁何时发言)挪到数据面(提交协议)——优雅,但协调被移动了,不是被消除了。

由此得出的设计准则排序(这条比文章本身值钱):

  1. 首选:把数据模型设计成冲突不可能发生(原子操作、CRDT、按 agent 分区)——数数游戏的降维解就是原子自增计数器,连 held-draft 都不需要;
  2. 次选:写操作是创造性的、不可交换合并时,held-draft 兜底;
  3. 未解:语义相关性过滤——真正值钱也真正难的部分。

真实场景辩证三轮:找茬任务把方案蒸馏了

场景:LLM 识图做对比验证(凭证类图片的真伪核验)。已知痛点:AI 单图判断有局限(跨记录撞值看不到)、会抽错字段、会误判漏判;跨记录撞值和单图硬矛盾才是铁证。直觉想法:"这就是多人交叉验证,用多 agent channel 解决?"

第一轮:交叉验证靠独立性,channel 提供共享——先反对

人类交叉验证有效靠的是:独立得出结论 → 结论可比对 → 分歧才升级。LLM 对锚定/从众比人严重得多——把别人的 verdict 放进上下文,它顺着说的概率极高。5 个识图 agent 进一个聊天室,得到的不是 5 份独立判断,是 1 份判断加 4 个附和者。且此场景大部分环节根本不该用 LLM:撞值=确定性 join 查询,字段抽错=schema 校验+多次抽取投票,勾稽矛盾=代码。LLM 视觉判断是流水线上最贵最不可靠的一层,规则先吃掉一切能吃的。

第二轮:找茬确实需要共享——但共享的是 finding,不是 verdict

反驳成立的部分:找茬(spot-the-difference)的发现过程是累积性的,茬未知、无法预先分工。它依赖两条机制:①已找到的茬让剩余注意力去别处(共享 found-set 避免重复搜索);②一个茬提高附近有茬的先验。两条都需要共享状态。

修正后的区分:房间里流动的信息有两种——发现("第 3 行字体不一致",可指认可复核的事实主张)和判断("我觉得是假的",结论倾向)。共享前者提供找茬机制,共享后者毒化判断。这就是经典 blackboard 架构:板上只有 claims,没有站队。

另一个 LLM 特有的坑:N 个同款模型的注意力高度相关,会盯同样的显著区域、漏同样的角落,共享上下文加剧收敛。多样性必须人工制造——茬无法预分工,但看的方式(lens)可以:网格比对 / 字段抽取 diff / 版式几何 / 载体层痕迹。且找茬本身该先降维:配准 + 像素/OCR diff 让机器算出候选区域,LLM 只负责解读 diff,别让 VLM 裸眼扫全图。

第三轮:"一个人的无限分身"——比"多个同事"更真实的本体

关键换框(来自讨论对方):与其说多人交叉验证,不如看成一个人用无限精力的分身同时找茬,一边把怀疑点记到共享笔记本上。找重复无害。

这个模型对 LLM 不是比喻,是本体:N 个同模型 agent 权重相同、盲点相同,本来就是分身不是同事。诚实接受这一点带来三个架构红利:

  1. 一致性要求塌缩。held-draft 存在的前提是冲突有代价;分身重复记同一个茬无害甚至是确认信号(两条 lens 撞上同一茬 → 可信度升高)。冲突无代价 ⇒ 不需要 OCC ⇒ 笔记本退化为 append-only 日志。
  2. verdict 污染自然消解。分身只记怀疑点不下结论,结论是最后"本人"通读全本笔记后下的——全程只有一次判断,没有投票和附和的机会。
  3. 复核变成定点事实核查。笔记本条目是可检验的事实主张,裁决时验证者被重新锚定在图像本身上。裁一个指向明确的 claim 和附和一个结论是完全不同的认知任务,前者天然抗锚定。

唯一代价:盲点也被克隆了——一个人想不到看的地方,一万个分身也不看。补救:lens 多样化(等价于审计员强制过 checklist)+ 机器 diff 层(像素差异没有认知盲点)+ 可选一个异模型终审当"外人"。

第四轮:删过头的捞回来——房间的时空概念仍然需要

把笔记本说成纯 append-only 文件是删过头了。前两轮自己给出的找茬机制恰好各依赖房间的一个维度:

  • 时(共享的现在):"已找到的茬让注意力去别处"要求分身搜索中途能看到新条目 → 需要单调序号(不为拒绝冲突,为定义"现在找到哪了")、带游标的增量拉取("给我 seq 47 之后的")、收敛判定("连续 K 轮无新发现"的"轮"就是房间时间;纯日志没有"大家都安静了"这个时刻)。
  • 空(共享坐标系):"一个茬提高附近有茬的先验"要求"附近"可寻址 → 怀疑点必须锚定在共享坐标系上(图像区域/字段名/行号),才有去重、互证、定点回查、先验传播。
  • 加上成员与生命周期:一个 case 一个房间,谁在场、何时关闭进入终审。

最终对账——文章三大机制的命运:版本化房间保留(共享时钟),拉取式 inbox 保留(中途低成本刷新 found-set),held-draft 退役(重复无害,仲裁失去存在理由)。不是推翻 demo,是通过真实任务蒸馏了它:留下时空,删掉仲裁。

收敛后的完整形态:

机器层:  配准 + 像素/OCR diff → 候选区域预写入笔记本
分身层:  同模型 × 不同 lens 并发扫图
         只有两个动作:pull(带游标) / append(怀疑点+锚点)
         连续 K 轮无新条目 → 停
终审层:  单一裁决者通读笔记本,逐条定点核查回图像
         铁证规则(撞值/勾稽矛盾)短路优先 → verdict

生产实证:DeepSeek harness 的 .agents/notes

deepseek-ai/deepseek-harness 的 .agents/notes/ 是"分身 + 共享笔记本"的生产级实现——agent 写给 agent 看的决策 RFC 系统,500+ 条 implemented 决策记录,proposed/implemented/rejected/archived 生命周期编码在路径里,强制格式骨架(Problem → Decision → Alternatives considered → Consequences),CI 机械门禁校验。五个可偷的设计:

  1. 用分片让冲突从根上消失:一个决策 = 一个文件,还专门拒绝了中心化 INDEX.md(单一索引是写热点,是并发冲突制造机)。正是"首选把数据模型设计成冲突不可能发生"的落地——没有 held-draft,因为架构上不需要。
  2. 语义去重是写入协议的强制步骤,由 agent 执行:每写新 note 必须先做 supersession 检查(搜树找同主题旧 note,该更新就更新,禁止另立山头)。这裁决了 held-draft 之争:冲突仲裁没消失,从"提交时的机械闸门"移到了"写入前的语义自查"——因为语义查重机器判不了,只能做成写者的协议义务。
  3. 房间规则由机械门禁执行,不靠 agent 自觉:格式/分类/链接校验全在 CI。agent 的纪律不可扩展,门禁可以。
  4. 强制 Alternatives considered:"没记录打败了谁的决策会招来重新诉讼"——防止后来的分身重新推导。对应找茬:每条怀疑点必须带可检验的证据锚点。
  5. 时空介质是 git:路径=空间坐标系,git 历史=时间,房间版本=HEAD。

关键知识点

  • Held-draft 就是 git 的 merge conflict:basedOnVersion=checkout 的 commit,revise/send/silence/force = rebase / merge anyway / 放弃 / force-push。那篇文章其实是把 git 的提交协议重新发明给了聊天室;DeepSeek 的选择是不重新发明——直接拿 git 当房间的机械层,在上面补 git 查不了的语义层(所有权、supersession、门禁)。
  • 两种房间节奏:PR 级慢房间(git 就是房间,造语义纪律别造轮子)vs 会话级快房间(秒级 tick、图像坐标锚点,in-memory Room 合理,但要带上三条纪律:写前语义查重、机械门禁、强制证据字段)。
  • 多 agent 设计的第一问不是"怎么协调",而是"冲突有没有代价":有代价 → 先试着用数据模型消灭冲突,消灭不了再上 OCC/held-draft;无代价 → append-only 就够,一切仲裁机制都是负担。
  • 同模型多 agent 是分身不是同事:独立性买不来,多样性必须人工制造(lens/异模型/不同预处理);反过来,"从众"问题也不该用隔离解决,而是用"笔记本里只有事实主张没有结论"的信息类型纪律解决。
  • 验证一个 claim 和附和一个结论是不同的认知任务:前者把验证者重新锚定在原始证据上,天然抗锚定。设计复核环节时,把"你同意吗"改写成"这个可指认的事实是否成立"。

续篇

后续两个输入(yetone/cumora 的生产实录、"小孩也抢报数"的制度设计视角)见 多agent协调-cumora生产实录与制度设计视角。

lessismore · 整理自个人 memo。以上保留写作时的观察与判断。

← 返回文章