🧠 核心问题
当一个 Agent 系统中有多个执行单元(主模型、子 Agent、Skill、Cron 任务)可能同时操作同一份数据时,如何避免数据冲突?这个问题在数据库领域叫"并发控制",在 Agent 编排中同样存在,只是形式不同。
Claude Code 用了一个巧妙的互斥机制来解决记忆写入冲突:主模型自己写了记忆,后台提取进程就自动跳过。这个看似简单的约束,实则解决了一个核心问题 —— 同一条信息被两个执行单元各写一遍,措辞不同、粒度不同,导致后续检索时信号矛盾。没记忆比有矛盾记忆更好。
⚔️ 三类互斥场景
场景一:读写互斥(Lost Update)
这是最基础也最常见的场景。Skill A 调用 get_xxx 拿到数据,正在组装入参准备提交;与此同时 Skill B 也对同一条记录做了修改并已提交。A 用旧数据调用 update_xxx,直接覆盖了 B 的改动。
这和数据库的 Lost Update 问题完全同构。实际案例:用户在用 Skill A 修改个人信息附件的同时,Skill B(如自助服务)顺手改了另一个字段,两个 Skill 各自 get → 修改 → update,后提交的那个覆盖前一个的全部变更。
场景二:编排锁(多 Skill 串行化)
当多个 Skill 可能操作同一资源时,需要某种形式的串行化。目前的 OpenClaw 编排缺少这个机制 —— Skill 之间是并行的,互不知道对方的存在。
可借鉴 Claude Code 的游标思路:给关键数据加一个"处理中标记"。Skill 操作前标记"我在改",改完清掉。另一个 Skill 看到标记就等或跳过。轻量但有效。
场景三:主模型 vs 子 Agent 互斥
这是最容易被忽略、但破坏力最大的场景。如果主会话正在操作某条数据,Cron 触发的 isolated session 也在操作同一条记录,两者完全互不感知。这和 Claude Code 的主模型 vs 后台子 Agent 冲突是同一个问题,但在 OpenClaw 中更严重 —— 因为 isolated session 可能执行任何操作,不只是写记忆。
🛠️ 可落地的设计模式
模式一:互斥跳过(Claude Code 原生模式)
核心思路:先到先得,后来者跳过。主模型写了记忆,后台提取就跳过。适用于"写操作是幂等的、跳过不影响正确性"的场景。
- 适用:记忆写入、缓存更新、日志记录等幂等操作
- 不适用:业务数据修改(跳过 = 丢变更)
模式二:乐观锁(CAS)
核心思路:get 时记录版本号,update 时检查版本号是否变化。如果变了,说明有别人改过,重新 get 再提交。这和数据库的乐观锁完全一样。
在 Agent 编排中,可以在 Skill 的 get_xxx 返回值里包含一个 version 或 last_modified 字段,update_xxx 时带上这个字段做校验。后端已有支持的话,只需 Skill 编排加上这个检查逻辑。
模式三:编排级锁(轻量互斥标记)
核心思路:在编排层面加一个"资源锁"概念。每个 Skill 声明自己要操作的资源 ID(如 employee_id、record_id),编排引擎在执行前检查是否有其他 Skill 正在操作同一资源。
- 实现方式:Session 级别的内存锁,或文件锁(如 flock),或 Redis 锁(分布式场景)
- 粒度选择:太粗(锁整个 Skill)→ 并发度低;太细(锁每个字段)→ 复杂度高。推荐锁到"资源 ID"级别
模式四:合并机制(最后写入者合并)
借鉴 Claude Code 的合并机制:如果上一次操作还在运行,新的操作请求被暂存,等当前操作完成后,再用最新上下文执行。适用于"操作之间有关联、需要合并处理"的场景。
典型场景:用户连续发了三条修改指令(改名字、改手机、改地址),如果每个指令都触发一个 Skill 执行,三次 get → 三次 update,最后一次覆盖前两次。合并机制可以把三条指令合并为一次 get → 一次 update(三个字段一起改)。
📊 模式选择决策树
操作是幂等的? → 是 → 互斥跳过(最简单) 操作是幂等的? → 否 → 多个 Skill 可能同时操作同一资源? → 是 → 编排级锁 + 乐观锁双重保障 → 否 → 用户可能连续发指令? → 是 → 合并机制(批量处理) → 否 → 乐观锁(CAS)兜底即可
🏗️ 对 OpenClaw 编排的实操建议
- 短期(立即可做):在 Skill 编排的 update 前加"最后时刻 re-get"铁律。已经在员工自助 Skill 中验证有效 —— 附件上传、字典查询等中间操作做完后,update 前必须重新 get 最新数据。这不是互斥,但能大幅降低 Lost Update 概率。
- 中期:引入资源级别的轻量锁。Session 维护一个 {resource_id: skill_name} 的锁表,Skill 操作前检查,冲突时等待或提示用户。
- 长期:如果 Skill 数量和并发场景继续增长,考虑引入编排级的 CAS 机制 —— get 返回 version,update 带 version 校验,失败自动重试。这需要后端 API 的配合。
逍遥云初 | 2026.04.17





