第1章:多 Agent 并发与事务的关系 —— 为什么 79% 的多 Agent 任务在主流框架下会损坏
用一个具体的航班预订 race condition 把多 Agent 并发问题钉死,划清 Agent 事务与 DB 事务、Saga、Reflexion 的边界,建立看任何 multi-agent 系统的并发坐标系
打开 AutoGen 文档,5 行代码就能让 3 个 Agent 并发跑。看起来一切美好——直到你让它们同时改一份机票订单,有 79% 概率得到一份乱码(AgentSTM ARR 2026 投稿数据:14 个 ground-truth 任务,10 轮均值,无保护并发下只有 3 个能通过校验)。这不是 LLM 不够聪明,是多 Agent 系统忘了把数据库 1970 年代就解决的并发问题接进来。本章不解决问题,只把问题钉死:race condition 在 Agent 工具调用层是怎么发生的、它和数据库事务的相同与不同、它和 Reflexion 这种”单 Agent 反思”为什么不是一回事。读完你会拿到一个”5 秒判别工具”——给你任何一个 multi-agent 系统,问 4 个问题就能判断它有没有事务保护、属于哪一档。
📑 目录
- 1. 一个反直觉的开场:你以为 AutoGen 帮你管了,其实没有
- 2. 在 Agent 工具调用层,race condition 长这样
- 3. Agent 事务 vs 数据库事务:相同与不同
- 4. Agent 事务 vs Reflexion:单 Agent 反思 ≠ 多 Agent 一致性
- 5. Agent 事务 vs Saga:为什么”补偿”不够用
- 6. 5 秒判别工具:4 个问题
- 7. 本模块的边界外
- 自我检验清单
- 参考资料
1. 一个反直觉的开场:你以为 AutoGen 帮你管了,其实没有
下面这段 AutoGen 代码是文档里的标准多 Agent 模式:
# 简化的 AutoGen 多 Agent 示例
from autogen import AssistantAgent, GroupChat
shared_db = {"booking_42": {"passengers": [], "baggage": 0, "flight": "AA100"}}
agent_a = AssistantAgent("PassengerEditor", tools=[update_passengers])
agent_b = AssistantAgent("BaggageEditor", tools=[update_baggage])
agent_c = AssistantAgent("FlightEditor", tools=[update_flight])
# 三个 agent 并发处理同一份预订
group = GroupChat(agents=[agent_a, agent_b, agent_c], messages=[task])
group.run_concurrent()
直觉上这段代码应该工作——三个 Agent 改 booking 的不同字段,互不影响。但实际跑起来:
Agent A: read booking_42 → passengers=[]
Agent B: read booking_42 → baggage=0
Agent C: read booking_42 → flight=AA100
Agent A: write booking_42.passengers = ["Alice", "Bob"] # ✓ 正确
Agent B: write booking_42 = {passengers: [], baggage: 30} # ✗ 整体写回,丢了 A 的 passengers
Agent C: write booking_42.flight = "AA101" # 取决于 tool 实现
问题的根源:LLM Agent 调工具时不知道”字段级写”还是”整体写”。Tool 接口写法不规范、提示词不够精确,一行 update_booking(booking_42, ...) 就可能把整张记录覆盖。这就是经典的 lost update——数据库教科书第 3 章的内容,在 multi-agent 框架里完整复活。
🌟 结论:AutoGen / CrewAI 这类框架只管并发调度,不管并发一致性。后者是它们没有解决、也不打算解决的问题——但你的项目要解决。
2. 在 Agent 工具调用层,race condition 长这样
把上一节的 lost update 推广,能在 Agent 工具调用层观察到至少 4 类经典并发冲突:
2.1 写写冲突(Lost Update)
Agent A: counter ← read() # 读到 5
Agent B: counter ← read() # 也读到 5
Agent A: write(counter + 1) # 写 6
Agent B: write(counter + 1) # 也写 6(应该是 7)
症状:计数器 +2 但只 +1;批量任务计数对不上;reservation 名额超卖。
2.2 读写冲突(Stale Read)
Agent A: profile ← read_user_profile("user_42")
Agent A: ... 用 profile 生成 5 段对话回复 ...
Agent B: write_user_profile("user_42", new_profile) # 中间发生
Agent A: send_email(content_based_on_profile) # 发出去的邮件用了旧 profile
症状:客服 Agent 给用户发了”基于你过去 30 天偏好”的内容,但偏好刚被 Agent B 更新过;推荐用旧标签。
2.3 因果违反(Write Skew)
约束:账户 A + 账户 B 的余额必须 ≥ 0
A: read(account_a)=100, account_b=100
A: 决定从 a 转 50 到外部
B: read(account_a)=100, account_b=100
B: 决定从 b 转 50 到外部
A: write(account_a=50) ← 各自看局部都合法
B: write(account_b=50) ← 各自看局部都合法
最终:a=50, b=50, 总=100,但中间各自看的都是合法状态——约束没有被任何一个 agent 单独违反,却被并发整体违反
症状:账户余额、库存、配额这类”跨实体不变式”被悄无声息地打破。最难调试的一类。
2.4 计划级冲突(Plan-Level Conflict)
这是 Agent 时代独有的一类——因为 Agent 的”原子单位”不是单条 SQL,而是一个 plan:
Agent A 的 plan:[读 doc.md → 改 §2 → 写回]
Agent B 的 plan:[读 doc.md → 改 §3 → 写回]
并发执行:
A: 读 doc.md
B: 读 doc.md
A: 改 §2,写回 doc.md
B: 改 §3(基于自己读到的旧版),写回 doc.md ← B 的 §2 还是旧的,覆盖了 A
🍎 直觉比喻:传统数据库的事务粒度像”一颗螺丝”,agent plan 的粒度像”装一辆自行车”——并发装两辆车,光保证每颗螺丝原子是不够的。
2.5 四类冲突的混合矩阵
| 冲突类型 | 是否被 ACID 单条事务解决 | Agent 框架默认是否检测 | 论文里的标准对应 |
|---|---|---|---|
| Lost Update | ✅ 单 SQL 级 | ❌ | OCC 经典 |
| Stale Read | ✅ Snapshot Isolation | ❌ | MVCC |
| Write Skew | ⚠️ 需要 Serializable | ❌ | SSI |
| 计划级冲突 | ❌(DB 事务粒度太小) | ❌ | AgentSTM 主战场 |
关键观察:前 3 类是数据库领域已经解决的问题,在 Agent 工具调用层退化重现;第 4 类是 Agent 时代新增的——plan 级别的并发,需要 plan 级别的事务粒度,而这正是 AgentSTM 的核心贡献。
3. Agent 事务 vs 数据库事务:相同与不同
第 2 节让”agent 也需要事务”听起来很自然——但 Agent 事务不是数据库事务的简单移植。它在 4 个维度上有本质差异:
| 维度 | 数据库事务 | Agent 事务 |
|---|---|---|
| 原子单位 | 一条 SQL / 一个 commit | 一个 plan(多步 tool calls) |
| 冲突时怎么办 | 重做相同事务 | 重规划成不同 plan(关键差异) |
| 状态来源 | 自己的存储 | 外部 API / 文件 / KV / DB(heterogeneous) |
| 隔离机制 | MVCC / 锁 | 版本化资源 wrapper + commit-time 验证 |
| 失败成本 | 微秒级回滚 | LLM 调用代价 = 重要的优化目标 |
🧠 关键洞察:数据库事务冲突后做”identical retry”——重做同一笔事务总会成功,因为环境会松。但 Agent 事务在多 Agent 持续争用下,identical retry 永远撞墙——这就是论文里 Theorem 1 (Bounded-Retry Impossibility) 证明的:n > k 个 Agent 抢同一个 r,按 PR 假设至少一个必然永久失败。
🌟 结论:Agent 事务必须有”计划重写”这一新维度。这是普通线程做不到的——LLM 是第一类能 reason about why 失败、并改写自己执行计划的”线程”。
3.1 一个具体的”鸽笼证明”(Theorem 1 直观版)
设:3 个 Agent 都要修改资源 r,最大重试 k=2 次
轮 1:3 个并发 commit r,最多 1 个成功 → 2 个失败
轮 2(重试):2 个再次同时 commit r,最多 1 个成功 → 1 个失败
轮 3(无):1 个 Agent 已经用完 k=2 次重试,永久失败
只要 n(并发 Agent 数)> k(重试预算),按”重做同一份 plan”的策略,至少一个 Agent 必然失败——这是数学事实,不能靠”加大重试次数”绕过(k 必须有限,否则不再叫 bounded retry)。
4. Agent 事务 vs Reflexion:单 Agent 反思 ≠ 多 Agent 一致性
读到这里可能有人想:“不就是 Reflexion 吗?让 LLM 反思失败、改下一次尝试不就行了?” ——不是。这是这个领域最大的一个混淆点。
| 维度 | Reflexion | Agent 事务(AgentSTM 类) |
|---|---|---|
| 目标 | 单 Agent 自我改进 | 多 Agent 一致性 |
| 失败信号 | 任务失败的自然语言反思 | 结构化冲突 metadata(哪个资源、被谁改、当前版本) |
| 反思后做什么 | 改提示词,再次执行同样的任务 | 必须改 plan(不同资源 / 不同顺序 / 不同分解) |
| 失败原因假设 | 单 Agent 推理质量不够 | 多 Agent 资源争用 |
| 能解决并发吗 | ❌ 解决不了 | ✅ |
AgentSTM 论文做了一个很巧妙的”same-plan verbal-retry control”实验来证明这点:让 LLM “verbal 上反思”但 executed plan 不变,结果——回复文本的 Jaccard token 保持率 0.115(看起来很高,接近 Structured+Full 的 0.143),但 conflict 次数没有下降(4.4±0.5 vs intent-preserving 的 4.0±0.0),因为它说的不一样了,做的还是同一件事。
🧠 关键洞察:Verbal 反思 ≠ Plan 改写。Reflexion 提供的是前者——给单 Agent 性能加成——但放在多 Agent 并发场景下解决不了 race,因为 race 不是”agent 推理不够好”造成的,是”两个 agent 同时争用资源”造成的。
⭕ 互补:Reflexion 和 AgentSTM 不是替代关系。Reflexion 改 task 表征质量,AgentSTM 改并发恢复策略——一个项目可以两个都用:单 Agent 任务难度问题用 Reflexion,多 Agent 并发问题用 AgentSTM。
5. Agent 事务 vs Saga:为什么”补偿”不够用
Sagas(García-Molina & Salem, 1987)解决的是”长事务怎么办”:把一个长事务拆成多个短事务,每个短事务配一个补偿动作(compensation),失败时反向执行。SagaLLM (VLDB 2025) 把这套搬到 LLM workflow——这是历史上第一篇明确用”事务”概念组织 Agent workflow 的论文。
但 Saga 在多 Agent 并发下有两个根本性问题:
5.1 串行化代价
为了让”补偿动作链”可执行,Saga 隐式假设事务以串行顺序执行——并发版本的 Saga 在工业界几乎没有成功案例。SagaLLM 的实测显示在 τ-bench airline benchmark 上,serial Saga 的吞吐是 66 tasks/s,而支持真并发的 AgentSTM 是 205 tasks/s(3.1× 差距)。
5.2 补偿级联(Compensation Cascade)
更严重的问题:Saga 的失败处理是全 chain 回滚。在 30% fault injection 下:
| 系统 | 完成率 | 原因 |
|---|---|---|
| SagaLLM | 10%(5/50 任务) | 任何一步失败 → 触发 chain compensation → 之前的工作也回滚 |
| AgentSTM | 58%(29/50 任务) | 每 Agent 的事务独立,单 Agent 失败不波及他人 |
🌟 结论:Saga 适合”长流程、低并发、强补偿语义”场景(订单 → 支付 → 发货 → 物流,可补偿)。多 Agent 并发改共享 state 不属于这类场景——这里需要的是 OCC 式的”乐观执行 + 验证 + 重规划”,不是补偿链。
6. 5 秒判别工具:4 个问题
给你任何一个 multi-agent 系统(开源框架 / 论文 / 自家产品),问 4 个问题:
Q1: 多个 Agent 能否真正并发改同一份 state?
└ NO → 串行系统(MetaGPT / ChatDev / SagaLLM)。无并发问题但放弃吞吐
└ YES → 继续
Q2: 框架是否在 commit/write 时验证"读时版本"是否还有效?
└ NO → 无保护并发(AutoGen / CrewAI)。79% 损坏率
└ YES → 继续
Q3: 冲突时框架做什么?
└ 重做同一计划 → Plan-Rigid Retry。Bounded-Retry Impossibility 适用
└ 让 LLM 反思但任务不变 → Reflexion-style 同 plan retry。无效
└ 让 LLM 重写 plan → 真正的 intent-preserving replan ✓
Q4: 重试预算用尽后兜底是什么?
└ 抛错给用户 → 系统脆弱
└ 降级到悲观锁串行执行 → graceful degradation ✓
4 个问题全选 ✓ 才是真正的多 Agent 事务系统。截至 2026-05,符合这个标准的开源框架几乎没有——AgentSTM 论文是第一个把所有 4 个问题都答对的方案。
7. 本模块的边界外
为了避免后面 7 章误入歧途,先把”本模块不讲”的事讲清楚:
- 单 Agent 任务难度:那是 Reflexion / LATS / Tree-of-Thought 的范畴,模块六(Agent Runtime)和模块七(Agentic RL)覆盖
- Agent 间消息一致性 / 共识:Aegean 这类共识协议解决的是”多 Agent 决策投票一致”,不是”多 Agent 共享 state 一致”——前者本模块只在第 4 章一带而过
- 分布式部署的网络一致性:本模块假设单机或局域网,跨数据中心的 Agent 一致性是另一个话题(参考模块十三)
- Byzantine Agent:恶意 Agent 故意写冲突值的场景。AgentSTM 假设 cooperative Agent
- 代码 merge / git 并发:CodeCRDT 解决的代码协同编辑问题,第 4 章会精读,但不是模块主线(主线是”shared state 上的 transactional consistency”)
✅ 自我检验清单
- Race 类型:能用一句话区分 Lost Update / Stale Read / Write Skew / 计划级冲突,并各举一个 Agent 场景
- AutoGen 缺陷:能解释为什么 AutoGen 默认配置在多 Agent 场景下会损坏 79% 的任务
- DB vs Agent 事务:能列出 Agent 事务相对数据库事务的 4 个本质差异
- Reflexion 区别:能解释”verbal 反思”和”plan 改写”的差别,并讲清前者解决不了多 Agent 并发的原因
- Saga 局限:能解释 SagaLLM 在 fault injection 下崩塌到 10% 完成率的根因(compensation cascade)
- 5 秒判别:拿到一个新 multi-agent 框架,能用 4 问判别它的并发保护等级
- Bounded-Retry:能用鸽笼原理直观解释”为什么 plan-rigid retry 必然在 n>k 时永久失败”
📚 参考资料
概念入门
- 数据库事务 ACID —— Wikipedia:ACID
- Lost Update / Write Skew 的标准定义 —— Berenson et al. 1995, “A Critique of ANSI SQL Isolation Levels”
- OCC(Optimistic Concurrency Control)入门 —— Wikipedia:Optimistic concurrency control
关键论文
- Reflexion: Language Agents with Verbal Reinforcement Learning(Shinn et al., 2023):arXiv 2303.11366 —— 单 Agent 反思的奠基;本章 §4 的对比基线
- Sagas(García-Molina & Salem, 1987):SIGMOD 1987 —— 长事务补偿链的祖师爷
- SagaLLM(Bui et al., VLDB 2025):VLDB 2025 —— LLM workflow 的 Saga 化,本章 §5 主要对比对象
- AgentSTM(Anonymous, ARR/EMNLP 2026) ⭐:本章数据来源;OCC + LLM replan 把 multi-agent 并发讲透的工作之一
- AutoGen(Wu et al., 2023):arXiv 2308.08155 —— 多 Agent 框架代表,本章 §1 用作”无保护”案例
行业讨论
- AutoGen GitHub issues 中的并发问题 —— 搜索 “race condition” / “concurrent state” 关键词
框架文档
- AutoGen 官方文档:microsoft.github.io/autogen
- CrewAI 官方文档:docs.crewai.com