OpenClaw 并发安全完整详解

总览

OpenClaw 并发安全由三套核心机制协同构成:

Per-Request 请求隔离模型 + SessionLock 会话级互斥锁 + CronContextHolder 定时任务上下文隔离

属于 UpClaw「并发安全」改造板块,解决多渠道并发消息、多子代理并行、定时任务与用户会话抢占资源、上下文污染、会话状态竞态、重复执行、数据错乱等线上典型并发问题。

原生 AgentScope 痛点:

  1. 无会话锁,同一会话并发多条消息,多轮推理互相抢占上下文,造成消息乱序、上下文覆盖;
  2. 所有请求共享全局静态上下文,并发读写导致记忆、会话状态互相串扰;
  3. 定时任务(HEARTBEAT、后台压缩、记忆归档)与用户前台会话共用一套上下文,变量污染;
  4. 子代理并行创建、工具并发调用缺少会话内限流与互斥保护;
  5. 缺少统一上下文持有者,多插件异步回调容易丢失会话标识、租户、trace 信息。

三层并发防护定位分工:

  1. Per-Request:线程/协程维度,请求上下文隔离,解决跨会话串数据;
  2. SessionLock:单会话维度互斥锁,防止同一个会话并发消息造成状态撕裂;
  3. CronContextHolder:后台定时任务独立上下文容器,隔离定时任务与前台用户会话环境。

生效层级:网关多并发接入层 → Agent 会话层 → 后台调度层,覆盖全链路。

一、Per-Request 请求隔离模型

1. 定义

Per-Request 是基于协程本地存储(Goroutine Local Storage / Async Local Storage)的上下文传播模型。

每一条外部消息(飞书、Websocket、HTTP、SFA2A子代理消息)进入网关,自动生成独立请求上下文 RequestContext,贯穿整条调用链路:插件回调、模型调用、工具执行、记忆读写、Langfuse 埋点。

存储核心元数据:

复制代码
traceId、sessionId、tenantId、agentName、userId
当前生效MD配置快照、权限快照
链路标签、cjkRatio、环境标识

2. 核心机制

  1. 上下文自动透传

    所有可插拔插件(ModelProvider、ToolAdapter、Observer、SecurityPolicy)、生命周期钩子、异步回调,自动继承父 RequestContext;

    异步派生任务(工具后台归档、记忆异步写入)会自动拷贝一份只读快照,防止父上下文提前销毁导致空指针。

  2. 禁止全局静态变量存储会话信息

    强制规范:租户、会话、Trace 相关信息不允许存在全局变量 ,全部从 RequestContext 获取。

    杜绝 A 用户会话数据泄漏到 B 用户会话。

  3. 生命周期边界

    消息入站 → 创建 RequestContext 绑定协程
    执行完整Agent推理循环
    消息响应返回 → 自动清理上下文,释放引用

  4. 与子代理SFA2A联动
    父代理发起 spawn_subagent 时,生成全新独立子 RequestContext;
    仅传递精简任务参数,不直接复用父上下文引用,配合子代理防污染机制。

3. 解决的并发问题

  • 跨会话上下文串扰(最常见BUG:不同用户对话记忆混淆、权限错乱);
  • 异步回调丢失 traceId、无法上报 Langfuse;
  • 插件并发读写全局状态造成数据竞争;

4. 局限性

Per-Request 只能隔离不同请求无法限制同一个会话同时并发多条消息

例:用户快速连续发送2条消息,两条请求各自拥有独立 RequestContext,但共享同一个 Session 内存状态,会并发读写会话上下文、LongTermMemory,引发消息乱序、上下文覆盖。

👉 该缺口由 SessionLock 会话锁补齐

二、SessionLock 会话级互斥锁(核心)

1. 定义

sessionId 为锁粒度的会话互斥锁 ,属于会话层面并发控制原语。

规则:同一个会话,同一时刻只允许执行一轮 Agent ReAct 主循环

2. 两种锁模式(可通过 ConditionalOnProperty 切换)

Mode A:排队模式(默认生产模式 FIFO Queue)

同一会话并发多条消息,进入会话内部等待队列,串行依次执行;

优点:消息不会丢失,保证时序;适合客服IM、聊天场景。

Mode B:拒绝模式(高速API场景)

会话正在繁忙时,新入消息直接返回 session busy

适合实时指令类场景,避免消息堆积延迟持续放大。

3. 完整生命周期执行卡点

消息入站完整流程:

复制代码
Channel接收消息 → 创建Per-Request上下文
→ 尝试抢占 SessionLock(sessionId)
   ├─ 获取锁成功:执行onSessionCreate/推理循环/工具调用
   └─ 获取锁失败:排队 or 返回繁忙
→ 推理、工具、记忆读写全部持有锁期间执行
→ 本轮Agent循环结束 → 释放SessionLock
→ 下一条排队消息开始执行

重要边界:

锁保护范围:主Agent推理循环

子代理拥有独立 sessionId,持有独立 SessionLock;

父会话锁不会阻塞子代理并行执行(支持可控多子代理并发,由maxConcurrentSubAgents限流)。

4. 锁配套能力

  1. 锁超时自动释放(防死锁)

    配置 sessionLockTimeout(默认300s):

    Agent 发生模型卡死、沙箱挂起、无限工具循环时,超时强制解锁,避免会话永久卡死。

    同时写入告警日志,在 Langfuse SessionSpan 标记锁超时。

  2. 锁状态可观测

    Observer 插件采集指标:

  • 当前持有锁会话数量
  • 会话排队队列长度
  • 锁平均持有时长、锁超时次数
  1. 和三层Tool治理联动

    持有锁期间所有工具执行、记忆读写串行化;

    防止同一会话并发读写 LongTermMemory 造成记忆写入冲突、摘要错乱。

  2. 和Context Compaction联动

    压缩属于会话临界区操作;压缩进行中,同会话其他消息排队,避免一边压缩一边拼装上下文引发内存视图撕裂。

5. 解决典型并发故障

  1. 用户快速连发多条消息 → 上下文并发读写导致对话历史错乱、消息乱序;
  2. 同时触发上下文压缩+新一轮推理 → ContextEngine 视图竞争;
  3. 多轮并发工具调用,LongTermMemory 同时读写产生脏数据;

6. 边界约束(设计取舍)

SessionLock 是会话串行化保护,不会阻止:

  • 不同session之间完全并行(网关水平扩容无瓶颈);
  • 会话内合法并行子代理(受全局子代理并发上限管控);

三、CronContextHolder 定时任务上下文隔离

1. 背景痛点

HEARTBEAT.md、定时记忆归档、后台批量压缩、会话自动回收等定时任务,如果直接复用前台会话上下文会出现两类严重问题:

  1. 定时任务修改会话状态时,前台用户消息同时进入,产生竞态;
  2. 定时任务没有合法 RequestContext,插件、观测、记忆模块取不到租户/trace信息,埋点失效;
  3. 定时任务异常变量泄漏污染正常用户请求上下文。

2. CronContextHolder 定义

专门为后台定时/后台异步任务 设计的独立上下文持有者。

不复用 Per-Request,拥有独立上下文生命周期。

分为两类实例:

  1. 全局定时上下文:不属于任何用户会话(全局记忆清理、系统巡检)
  2. 会话绑定定时上下文:归属某个session(会话心跳、定时自动压缩)

元数据组成

复制代码
contextType: cron
sessionId(可选)、tenantId、traceId(自动生成cron-trace标识)
readOnly:标记定时任务是否允许修改会话状态
schedulerTaskId、taskType: heartbeat/compaction/memory_clean

3. 运行规则

  1. 定时任务启动时,由 Scheduler 插槽主动创建 CronContextHolder;
  2. 如果是绑定会话的心跳任务:尝试非阻塞抢占SessionLock
    • 会话当前空闲:拿到锁执行后台清理、记忆归档;
    • 会话正在处理用户消息:直接跳过本轮心跳,避免抢占用户请求资源;
  3. 定时任务执行全程上下文隔离,不会污染任何 Per-Request 用户上下文;
  4. 定时任务所有日志、Span 统一标记 context_type=cron,Langfuse 可区分前台流量与后台任务流量。

4. 典型场景示例

  1. HEARTBEAT 定时触发后台 Context Compaction
    CronContextHolder 创建后台上下文,尝试抢占会话锁;用户正在聊天则本轮压缩延后,不抢占用户推理算力。
  2. 过期记忆定时归档
    全局定时上下文,无会话绑定,批量操作向量库,独立观测指标。
  3. 超时会话自动销毁
    Scheduler 通过 CronContext 遍历会话表,安全执行会话资源回收。

四、三者协同完整并发模型(标准时序)

场景:用户在IM连续发送两条消息

复制代码
消息1、消息2同时抵达网关
│
├─ 两条消息各自生成独立 Per-Request 上下文
│
├─ 两条请求同时尝试抢占同一个 sessionId 的 SessionLock
│
├─ 消息1抢占成功,进入ReAct循环
└─ 消息2进入会话内部等待队列(排队模式)
│
消息1执行:LLM推理 → Tool调用 → Memory读写 → 上下文更新
消息1执行完毕 → 释放SessionLock
        ↓
队列中消息2获取锁,开始执行

场景:会话心跳定时任务 + 用户消息并发

复制代码
用户消息:Per-Request,抢占SessionLock(成功,正在推理)
定时心跳任务:CronContextHolder 发起,非阻塞抢锁
→ 锁被占用,心跳任务直接跳过本轮执行,等待下一个周期
避免定时后台任务抢占用户前台算力。

场景:父代理并行拉起多个子代理

复制代码
父会话持有父SessionLock
spawn_subagent 创建多个子session
每个子session拥有独立SessionLock、独立Per-Request上下文
子代理之间可以并行执行,受maxConcurrentSubAgents全局限流管控
完美支持多子代理并发分工。

五、与现有全体系联动关系

1. 联动 12+ ConditionalOnProperty

  • claw.session.lock.mode:排队/拒绝模式切换
  • claw.session.lock.timeout:死锁保护时长
  • claw.scheduler.enable:开关Cron定时上下文
  • claw.subagent.maxConcurrentSubAgents:控制子代理并行上限

2. 联动 SubAgent 安全约束

父会话锁不阻塞子代理并行;

子代理各自独立锁,实现可控并发;

同时配合防递归、防污染隔离。

3. 联动 Context Compaction

上下文压缩属于临界区操作,必须持有SessionLock;

定时后台压缩使用 CronContext + 非阻塞锁,优先保障用户对话。

4. 联动四层 Langfuse 追踪

  • Per-Request → Trace/Span 携带用户请求标识
  • CronContext → Span 标记定时任务类型
  • SessionLock 抢占、排队、超时事件生成独立 RulePolicySpan,可观测会话拥堵情况

5. 联动三层Tool治理

同会话工具串行执行,防止并发读写沙箱、并发调用API产生重复操作;

子代理独立会话可并行执行工具。

六、并发安全三层机制优缺点

优势

  1. 分层粒度清晰
    跨请求隔离(Per-Request)→ 同会话串行保护(SessionLock)→ 后台任务隔离(CronContextHolder),覆盖所有并发场景;
  2. 兼顾串行安全与并行能力
    同会话串行防错乱,不同会话完全水平扩展;支持可控子代理并行;
  3. 防止死锁+资源抢占均衡
    定时任务非阻塞抢锁,不抢夺用户请求资源;锁超时自动释放;
  4. 全链路可观测
    锁竞争、排队、定时任务流量全部埋点,方便定位会话堆积、并发竞态问题;
  5. 适配多渠道(飞书、Web、API、SFA2A)统一并发模型。

短板

  1. 单会话串行天然限制超高频指令场景;可拆分为多会话架构或者切换拒绝模式;
  2. 大量会话同时排队会增加端到端延迟,需要监控队列长度设置告警;
  3. 协程模型下需要严格规范开发,禁止插件随意跨协程传递原始上下文引用。

七、对比原生AgentScope / Codex / Claude Code

  1. 原生 AgentScope

    无 SessionLock;无标准化 Per-Request 上下文模型;无独立定时上下文;

    并发多条消息极易产生上下文竞争、记忆错乱,仅适合演示原型,不支持线上IM高并发场景。

  2. OpenAI Codex

    云端任务相互隔离,但不存在"会话"持久概念,没有会话锁机制;面向单次代码任务,不支持长期持续聊天会话并发管控。

  3. Claude Code

    本地单进程单会话模型,没有多并发网关设计,不存在完整并发安全体系。

  4. OpenClaw

    面向多渠道接入、多租户、长期持续会话、前后台混合流量设计的完整三层并发安全模型,是企业AI中台网关必备基础设施。

八、生产落地典型风险案例

案例1:用户连续发送多条指令,AI来回混淆历史对话

根因:无SessionLock,多条请求并发读写同一会话上下文;

修复:启用排队模式SessionLock,串行执行。

案例2:定时后台压缩和用户聊天同时执行,上下文崩溃

根因:后台任务无独立上下文,无锁争抢;

修复:压缩逻辑使用CronContextHolder,非阻塞抢占会话锁,繁忙则跳过。

案例3:异步工具回调,日志无法关联traceId

根因:异步协程丢失请求上下文;

修复:Per-Request异步自动快照拷贝上下文。

案例4:多子代理同时写入父代理回流结果,父上下文错乱

根因:多子代理并发回流;

解决方案:父会话串行汇总子代理结果,子代理内部允许并行执行。

九、落地价值(UpClaw 从可用 → 可上线)

  1. 解决多渠道高并发接入场景会话数据竞争、消息乱序、记忆错乱等稳定性故障;
  2. 隔离前台用户流量与后台定时任务,保障用户体验优先;
  3. 统一上下文传播规范,约束插件开发,避免内存泄漏、跨租户数据泄漏;
  4. 并发行为全链路可观测,支持容量规划、拥堵告警;
  5. 在安全性(串行防竞态)与性能(跨会话水平扩展、可控子代理并行)之间取得工程平衡。
相关推荐
武子康1 小时前
🔥 codex-plugin-cc 原理全拆:四层桥接 + JSON-RPC 2.0 + JSONL + 后台任务状态机
人工智能·llm·claude
手写码匠1 小时前
从零实现大模型推理引擎:Continuous Batching 与动态调度系统深度解析
人工智能·深度学习·算法·aigc
李白你好1 小时前
一款面向攻防演练、红蓝对抗和安全研究场景的高交互智能欺骗蜜罐平台
安全·交互
科技发布1 小时前
获奖平台传播易 全域广告投放一站式解决方案
人工智能
breeze jiang1 小时前
告别等待焦虑:Vue 3 + DeepSeek 实现 AI 打字机流式对话,用户体验提升立竿见影
vue.js·人工智能·ux
Databuff1 小时前
个人用的桌面级开源智能体有哪些?OpenOcta 八爪鱼上手与对比
人工智能·ai·语言模型·开源·开源软件
网易云信1 小时前
从“合规”到“信任”:网易智企专属云打造强监管下的通信新范式
人工智能·后端
Zzj_tju1 小时前
LLM for Code Research:程序合成、自动调试与软件工程评测
人工智能·语言模型·软件工程
拾起_3691 小时前
12-Provider 配置与模型路由:多 provider 接入机制
人工智能·开源