首页 › ai-agents › 并发写共享态:丢更新三栈实测

概述

把单智能体的 RAG 管线原样复制成多智能体,第一个崩的不是模型智商,而是共享态。2026 年 4 月的工程复盘给出一条反直觉的因果链:五个以上智能体并发写同一代码库时,"读旧版本—改—写回"会静默吞掉彼此的工作,报错为零。Cursor 把乐观锁压到 20 并发后发现,真正的问题不是冲突本身,而是重试成本在统计上扭曲了智能体行为——它们开始主动挑小活儿。本期拆解乐观锁、角色分层消息总线、事件溯源三种协调架构,并对照 S-Bus 提出的可观测读隔离(ORI)一致性模型:它在专用分片负载下达到零污染(88 万次提交、其中 43 万次强竞争),却在单分片协作写作里反向有害——因为"保留"会把并发矛盾也一起传播下去。结论是:丢更新不是 bug,是默认一致性模型选错的税。

核心故障与三种架构对比

维度 乐观锁(OCC) 角色分层 + 消息总线 事件溯源(ESAA)
一致性模型 版本标签 + CAS 重试 文件所有权互斥(Planner 保证) append-only 日志串行化
写冲突处理 冲突即重试 结构上禁止同文件并发 到达序串行,无丢更新
并发上限(实测) ~20 智能体即行为退化 5+ 智能体基线方案 受日志吞吐限制
行为副作用 重试压力→智能体变怂 Planner 错配所有权即裸奔 编排开销 + 物化视图成本
可审计/可回放 弱 中(事件流) 强(全量历史 + 分支)
适用场景 元数据、注册表、状态板 共享代码库的多角色流水线 强审计、长程恢复、可分支
代表实现 Cursor 早期实验 AG2 事件引擎 / LangGraph Pregel ESAA、LangGraph get_state_history

深度分析

1. 丢更新的病根:四分钟的读—改—写窗口

并发多智能体最被低估的生产事故,描述起来极简、预防起来极难:智能体 A 在版本 7 读文件,智能体 B 也在版本 7 读同一文件;A 改了两个函数写回,文件升到版本 8;B 还在用版本 7 的理解,改了第三个函数写回——A 的工作凭空消失,全程没有任何报错。AgentMarketCap 2026 年 4 月的复盘把这称为"共享内存问题",并指出 57% 的企业已在生产环境跑智能体,其中越来越多在共享仓库上同时跑五个以上智能体。

与线程不同,智能体的"事务"是不可预测的、长达数秒到数分钟的多步推理。传统数据库的串行化事务、行级锁在这种非确定性长事务上开销过重——你不可能让一个智能体思考四分钟时一直握着写锁。所以丢更新不是偶发边缘情况,而是"任何跑三个以上智能体、工作有重叠"的系统里的日常事故。它还有一个欺骗性:破坏的产物看起来和模型幻觉一模一样,让团队把一致性 bug 当成模型能力 bug 去调,南辕北辙。

2. 乐观锁的反噬:重试压力让智能体变怂

乐观锁是最轻量的方案:每次读共享资源时附带一个版本标签,写回时检查版本是否变过,变了就失败重试。逻辑干净,前提是"写冲突是少数"。Cursor 在并行编码智能体的扩展实验里验证了它,结论很有教育意义:低竞争时乐观锁工作正常;但逼近 20 个并发智能体同写一个代码库时,一个意想不到的问题浮出水面——智能体变得风险厌恶。

# 乐观锁的提交循环:冲突即整体重算
def commit_with_occ(key, read_version, patch):
    cur = store.get(key)            # 重读当前态
    if cur.version != read_version: # 被人改过 → 丢更新风险
        raise ConflictRetry("re-read and recompute")
    store.put(key, cur.apply(patch))  # CAS: 写回

知道"雄心勃勃的多文件编辑更可能撞版本冲突、被迫重算"后,智能体在策略上开始往更小、更不易冲突的任务靠。重试成本的统计压力正在扭曲智能体行为。更深的失败是:乐观锁假设冲突是例外,可当很多智能体在文件图有重叠的代码库上干活时,冲突不是例外,是工作负载的结构性属性。所以乐观锁适合元数据(任务队列、注册表、状态板),不适合当作并发文件编辑的主力协调机制。

3. 角色分层 + 消息总线:编排即互斥

从 Cursor、Deloitte、微软的早期部署里沉淀出来的更耐久架构,是角色分离 + 消息传递三层结构:Planner 智能体持续探索代码库、分解任务、向消息总线发布工作项,但永不写源文件;Worker 智能体订阅工作项、在隔离中执行、完成后推送变更,且彼此从不直接协调;Judge 智能体评估完成情况、判定是否满足验收标准、向 Planner 发出继续或重新入队的信号。关键不变量是——任何时刻没有两个 Worker 碰同一文件,由 Planner 通过跟踪"文件所有权"来保证,拒绝把重叠文件集分给并发 Worker。

这恰好对应业界两条主线:AG2(AutoGen 的继任者)在 2025 年底围绕该模型重构内核,交付事件驱动执行引擎,异步优先、可插拔编排;LangGraph 1.0 的 Pregel/BSP 执行模型把每次状态更新当作一个事件,并在每步之后做图级检查点。它的主要约束是 Planner 必须对文件所有权判断正确——如果两个工作项被错误允许重叠,消息总线对由此产生的写冲突毫无防护,等于裸奔。

4. 事件溯源(ESAA):append-only 的天然串行

事件溯源是结构上最鲁棒、也最复杂的方案。智能体不再读写可变共享态,而是把每次状态变更作为不可变事件追加进日志;任何资源的当前态都由"从起点(或最近的快照)回放事件日志"推导而来。ESAA(Event Sourcing for Autonomous Agents,2026 年 2 月 arXiv)把这套范式形式化给基于 LLM 的软件工程:智能体不直接写文件,而是向 append-only 事件库发射结构化意图(描述想做的变更的校验 JSON);一个确定性编排器校验意图、持久化事件、应用写文件的效果、维护代码库当前态的物化视图。

# ESAA:智能体只发意图,编排器串行落地
orchestrator.submit(Intention(
    agent="worker-3", file="schema.sql",
    op="rename_column", old="user_id", new="uid"))
# 编排器按到达序逐条处理 → 两个并发意图天然序列化,零丢更新

append-only 语义天然把并发智能体的活动序列化——两个智能体可同时提交意图,编排器按到达序逐条处理,没有丢更新的可能。日志的时序还带来完整可审计性,可精确回放代码库如何演化、谁在何时做了什么;智能体中途失败时,从最后一个有效检查点回放即可恢复。LangGraph 的 get_state_history(thread_id) 和 update_state(config, values, checkpoint_id) 暴露了类似能力。代价是运维开销——除了智能体本身,你还得管理事件库、投影层和物化视图。

5. S-Bus + 可观测读隔离(ORI):读集重建中间件

S-Bus(arXiv:2605.17076)走了一条更聪明的路:它是一个 HTTP 中间件,核心机制是服务端的 DeliveryLog——一份按智能体记录的 HTTP GET 操作日志。它的精妙之处在于:智能体无法被修改去声明自己的读集(它们的 SDK 是黑盒),于是 S-Bus 直接从被观测到的 HTTP GET 流量里,在提交时刻重建每个智能体的读集。这把普通 HTTP 流量变成了可验证的读集,从而在不改动任何智能体内部协调代码的前提下,对共享多智能体态施加乐观并发控制(OCC)。它提供的一致性属性叫可观测读隔离(Observable-Read Isolation, ORI)——一种在"HTTP 可观测读投影"上的偏因果一致性:提交前,S-Bus 检查智能体当初读来形成变更的数据是否仍然有效,若被别的智能体更新过,提交被拒,促使它重读重算。

它的形式化证据是三层机械化验证:TLAPS 证明了 ReadSetSoundness 与 ORICommitSafety(模一个类型公理);穷举 TLC 在 N=3 下探索了 20,763,484 个状态、零违规;Dafny 卸载了 9 个归纳引理。经验上,它对 PostgreSQL 17 SERIALIZABLE 和 Redis 7 WATCH/MULTI 取得安全对等——在 884,110 次提交尝试(其中 427,308 次在强竞争下)零 I 类污染。论文的 PH-3 LLM 判官还经人工标注者以严格 kappa=0.93 独立校准。

6. ORI 的反噬:保留即传播矛盾

S-Bus 论文最值钱的发现不是"ORI 能防住污染",而是它的第三个贡献(C3)里的反直觉警告:ORI 在专用分片负载下是语义中性的,但在单分片协作写作里有害——因为"保留(preservation)会把并发的矛盾也一起传播下去"。

# ORI 的提交门:读集是否仍然新鲜?
def ori_commit(agent, write_set, delivery_log):
    for key in delivery_log.read_set(agent):
        if store.version(key) > delivery_log.read_at(agent, key):
            return REJECT("stale read, recompute")  # 防住丢更新
    return ACCEPT(write_set)

直白说:两个智能体读到同一分片的 v1,分别往相反方向改(比如 A 要把库从 PostgreSQL 换成 SQLite,B 还在旧 PostgreSQL schema 上生成迁移脚本)。ORI 会拒绝 B 的提交、逼它重读——这确实防住了"迁移脚本错库"的污染。但若它们本就在同一份共享文本上协作(你写一段、我写一段),ORI 的严格保留反而会反复拒绝合法的并行贡献,把本来该合并的分歧当作冲突丢回去重算,保住了一致性、却杀掉了协作。教训是:一致性模型没有银弹,ORI 适合"专用分片、强隔离"的拓扑,把它套到"共享写作、高频合流"的场景,就是在给协作收税。这也是为什么 delivered 的 DeliveryLog 只在 dedicated-shard 拓扑里承诺安全。

7. 谁的态算数:多数票失效与领导选举

当"谁的态算数"从文件层上升到决策层,问题就变成共识。一个被广泛引用的 2026 实测结论是:在有争议的问题上,LLM 智能体的多数票失效接近 24%。换言之,三个智能体投票不是可靠的"真理裁判",它和分布式系统里的拜占庭容错面对同样的悖论——你不知道谁是错的。经典 Raft/Paxos 解决的是"诚实节点达成一致",可 LLM 智能体会自信地错,把自信度当权重反而放大偏差。

于是出现了两条出路。一是置信度加权共识:CONCAT(arXiv:2605.29612)等免训练框架用"共识 × 置信度"做临时组队,让高置信答案拉低噪声。二是动态领导选举:adaptive-llm-election 这类实验在 GPT-5/GPT-4/LLaMA-3 混编组里研究投票行为、网络中心性与公平性——谁当编排者本身就是一场选举,而中心性高的智能体容易"挟持"决策。对生产系统的启示:不要把多数票当终判,要么叠加置信度门槛 + 二轮审议,要么显式选一个"领导"并对它的输出做独立验证,否则 24% 的失败率会原样落到你的下游流水线。

8. 检索层的隐形竞态:向量库一致性

文件层的丢更新被人盯着,向量库层的竞态却安静地坐在下面。多个智能体并发往同一个向量索引里写——一个在嵌入新文档、一个在删旧块、一个在建索引——读侧会拿到"写了一半"的中间态:刚删的块还能被检索到,新文档的部分 chunk 已可见、部分还在路上。这种部分可见性比文件丢更新更阴险,因为它不报错、不丢更新,却让检索结果在毫秒级窗口里自相矛盾。

# 检索竞态:删/插并发,读侧拿到半成品索引
def rag_query(q):
    docs = vector_store.search(q, k=5)  # 可能命中"已删未生效"块
    # 写侧:async upsert + delete 并发,索引处于中间态
    return llm.complete(q, context=docs)  # 上下文自相矛盾

解法和文件态同构:要么对向量库施加 ORI 式的读集检查(提交前确认检索命中的块版本未被并发改动),要么走事件溯源——把嵌入、删除、重建都做成 append-only 事件,由确定性投影在"索引已一致"的快照上提供查询。多数框架默认忽略这一层,结果就是多智能体 RAG 系统的幻觉率,很大一块不是模型问题,是向量库没做并发控制。

系统架构与流程

flowchart TB
    subgraph FAIL["默认会崩:读-改-写竞态"]
        A1["AgentA 读 v7"] --> A2["AgentA 写 v8"]
        B1["AgentB 读 v7"] -.等待.-> B2["AgentB 覆盖写<br/>v8 被吞"]
        A2 -.-> B2
    end

    FAIL ==>|"选一种一致性栈"| FIX

    subgraph FIX["三种协调架构 + ORI 门"]
        direction TB
        OCC["乐观锁 OCC<br/>版本标签 + CAS 重试<br/>副作用:重试压力→智能体变怂"]
        MSG["角色分层 + 消息总线<br/>Planner→Worker→Judge<br/>文件所有权互斥"]
        ES["事件溯源 ESAA<br/>append-only 意图日志<br/>到达序串行,零丢更新"]
        ORI["S-Bus DeliveryLog<br/>读集重建 + ORI 门<br/>提交前校验读集新鲜度"]
        OCC --- ORI
        MSG --- ORI
        ES --- ORI
    end

    FIX --> VERDICT{"单分片协作写作?"}
    VERDICT -->|"是"| WARN["ORI 有害<br/>保留=传播矛盾<br/>改用 ES 分支合并"]
    VERDICT -->|"否/专用分片"| OK["ORI 安全<br/>88万提交零污染"]
sequenceDiagram
    participant A as AgentA
    participant M as S-Bus中间件
    participant S as 共享态
    participant B as AgentB

    A->>S: GET shard (DeliveryLog 记录 read@v1)
    B->>S: GET shard (DeliveryLog 记录 read@v1)
    A->>M: 提交 write_set
    M->>S: 校验 read@v1 仍最新 ✓ ACCEPT → v2
    B->>M: 提交 write_set (基于 v1)
    M->>S: 校验: 当前 v2 ≠ read v1
    M--xB: REJECT 丢更新被拦下
    B->>S: 重读 v2,重算后再提交

推荐方案

一句话决策:先问"谁的态算数",再选一致性栈——丢更新不是模型 bug,是默认一致性模型选错收的税。

参考来源

  1. Concurrent Multi-Agent State Management: Solving the Shared Memory Problem — AgentMarketCap,2026-04,乐观锁/消息总线/事件溯源三栈实测,含 Cursor 20 并发智能体行为退化与 57% 企业生产数据
  2. S-Bus: Automatic Read-Set Reconstruction for Multi-Agent LLM State Coordination (arXiv:2605.17076) — DeliveryLog 读集重建、ORI 一致性,TLAPS/TLC(20,763,484 状态零违规)/Dafny 形式化验证,884,110 次提交零污染,含 C3 单分片协作写作有害警告
  3. Enhancing Multi-Agent LLM Reliability: Structural Race Conditions — ARSA Technology,2026-05,结构化竞态(SRC)与 S-BUS/ORI 防护机制工程解读
  4. Consensus Protocols for Multi-Agent Decisions: When Agents Disagree — 多数票在争议题失效 ~24%,Raft/Paxos 与 LLM 原生辩论/拜占庭对比
  5. adaptive-llm-election (GitHub) — GPT-5/GPT-4/LLaMA-3 混编组的动态领导选举、投票行为与网络中心性实验代码

[!tip] 51学通信知识星球 星主:爱卫生(微信:gprshome201101)——公众号「51学通信」创办者,19 年通信行业运维与讲师经验,著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书(各大电商平台有售)。 星球定位:深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域,主打运维岗位与信令分析。 当前规模:5200 篇主题 / 990 个回答,198 元/年。 加入福利:加入星球后请加爱卫生微信,拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题,另有群内分享。 AI 加持:51学通信知识星球已作为 skill 接入 WorkBuddy,使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例,做总结、找文档和 PPT 等场景全覆盖。

51学通信知识星球海报-扫码加入