OpenClaw Observability 并发安全(Per-Request Hook)完整详解

📅 2026/7/16 4:17:01
OpenClaw Observability 并发安全(Per-Request Hook)完整详解
一、定位与原生并发痛点Observability可观测体系依托Observer可插拔插槽 全局生命周期Hook事件总线 四层Langfuse追踪实现全链路埋点Per-Request Hook是观测链路并发安全的底层核心规范隶属于 UpClaw「可观测性、并发安全」两大改造板块与前文Per-Request上下文、SessionLock、CronContextHolder三位一体解决观测场景典型并发故障无规范约束下典型线上问题Trace串扰最频发异步Hook、后台回调、子代理回调丢失上下文A会话Span挂载到B会话TraceLangfuse链路父子关系错乱、标签混淆、租户数据交叉。上下文污染协程/异步逃逸全局事件总线广播Hook异步协程复用陈旧RequestContexttraceId、sessionId错乱前台流量与Cron定时任务观测标签互相覆盖。Span重复创建/提前关闭多协程并发触发同一个生命周期Hook多次创建同类型Span上下文提前销毁导致endSpan()调用时报错、链路截断。异步埋点丢失元数据工具后台归档、记忆异步写入、流式推理分片回调取不到tenantId、userId无法做租户成本分摊、审计追溯。Cron定时观测与用户流量无法区分定时任务Hook缺少独立上下文标记前台埋点与后台定时Span混在一起容量、成本统计失真。核心设计总纲所有观测Hook执行强制绑定Per-Request上下文载体禁止Hook直接读写全局静态链路变量区分三类上下文载体Per-Request前台用户消息、CronContextHolder后台定时、SubAgent独立RequestContext子代理异步派生任务强制上下文快照拷贝。观测层三层并发隔离模型载体层Per-Request / CronContextHolder 上下文隔离数据源隔离调度层事件总线Hook上下文自动透传、异步快照拷贝传播安全存储层Span/Trace线程独立构造、父子链路强绑定、防并发写冲突观测数据安全二、基础概念梳理1. Per-Request上下文RequestContext回顾每条外部消息飞书、Websocket、HTTP、SFA2A父→子代理消息进入网关创建独立RequestContext存储traceId、sessionId、tenantId、agentName、userId、链路标签、cjkRatio、env、当前MD快照2. 两类Hook体系观测全部基于这两类Hook同步生命周期Hook主线程/主协程执行before_model_resolve、before_tool_run、before_prompt_build异步回调Hook派生协程执行流式chunk回调、工具异步归档、记忆后台写入、子代理结果回调并发风险主要集中在异步Hook同步Hook天然复用当前协程上下文风险较低。3. Per-Request Hook 强制规范定义任何观测逻辑创建Span、记录指标、日志、Langfuse埋点不允许脱离合法上下文载体执行Hook触发时自动绑定当前协程活跃上下文异步派生任务自动拷贝只读快照禁止传递原始上下文引用。三、四层核心并发安全机制Per-Request Hook完整体系第一层事件总线上下文自动绑定Hook触发时自动注入载体OpenClaw全局事件总线EventBus做了一层封装消息入站→创建RequestContext→绑定当前协程存储→触发整条链路所有生命周期Hook。规则同步Hook直接读取当前协程活跃RequestContext无需手动传参派生异步任务子协程总线自动捕获当前上下文生成只读快照副本传递给异步HookCron定时任务触发Hook载体是CronContextHolder标记context_typecron不使用Per-Request子代理spawn_subagent新建独立RequestContext不继承父原始上下文引用仅拷贝精简标签防止父会话庞大上下文污染子代理观测链路。禁止反模式线上高危写法❌ 在Hook内部把RequestContext存入全局Map、全局静态变量❌ 异步回调直接持有原始上下文引用父请求完成销毁上下文异步回调访问已释放对象引发错乱、空指针✅ 标准模式异步自动快照拷贝快照只读不允许修改会话状态。第二层上下文三类载体区分观测标签天然隔离所有Hook执行前自动识别载体类型写入Span统一标签context_typeuser_requestPer-Request 前台用户消息IM、API、Webcron_taskCronContextHolder 后台定时心跳、批量归档subagent子代理独立RequestContext价值四层Langfuse可以直接按标签筛选前台流量/后台定时/子代理流量成本、告警、观测报表天然隔离不会混算。第三层Hook异步快照拷贝机制解决最大并发风险1. 快照拷贝触发时机出现以下场景框架自动生成上下文只读快照LLM流式输出on_stream_chunk 分片异步回调Tool执行完成后异步记忆归档Hook工具后台结果持久化SubAgent结果异步回流父代理HookScheduler定时任务派生后台任务2. 快照约束只读快照快照只能读取元数据traceId、tenantId禁止通过快照修改会话状态、修改标签快照生命周期独立于原始RequestContext原始请求响应完成销毁快照依然有效供异步埋点使用快照不携带可变会话指针session状态、上下文视图仅携带链路标识、静态标签杜绝异步协程篡改活跃会话。时序示例流式推理典型场景用户消息入站 → 创建RequestContext活跃 触发before_model_resolve Hook同步使用活跃上下文 发起LLM流式调用 每一块chunk触发on_stream_chunk异步Hook → 框架自动拷贝上下文只读快照传入异步回调 主线程推理完成原始RequestContext标记可回收 异步分片Hook继续执行埋点仅依赖快照不受主上下文销毁影响第四层观测数据Span/Trace并发写入保护结合四层Langfuse追踪Per-Request Hook配套三条链路构造规则Trace根节点与RequestContext一一绑定一条用户请求对应唯一Trace所有Span父子挂载到该Trace不允许跨Trace挂载Span从根源杜绝Trace串扰。Hook Span幂等标识防重复创建每个生命周期Hook生成Span携带hook_name traceId turnSeq复合唯一标识并发多次触发同一Hook时先检测是否已存在同标识Span避免重复创建。Span生命周期与Hook生命周期绑定Hook启动 → startSpan() Hook执行完成/异常 → endSpan()同步Hook同步启停异步Hook快照内持有span引用异步回调结束再关闭配套超时兜底超过maxSpanTtl自动endSpan防止链路永久悬挂。四、完整Hook执行时序前台用户请求标准链路Channel接收消息 │ 1. 创建 Per-Request RequestContext绑定当前协程 │ 2. 事件总线触发前置HookonInputReceived ├─ 同步Hook直接读取活跃上下文创建顶层Trace │ 3. 进入Agent主循环SessionLock串行保护同一会话 │ 依次触发 │ before_prompt_build → ContextEngineSpan │ before_model_resolve │ llm_start → Generation开始 │ │ ├─ 流式分片异步on_stream_chunk Hook │ │ → 自动拷贝上下文只读快照传入异步回调 │ 4. llm输出完成解析工具调用指令 │ before_tool_run → ToolRunSpan │ 工具执行前后Hook │ 5. 本轮Agent循环结束 after_agent_turn │ 同步关闭本轮Trace顶层Span │ 6. HTTP/IM响应返回用户 │ → 原始活跃RequestContext标记待回收 │ 7. 派生异步任务记忆持久化、后台埋点 │ 继续使用预先拷贝的只读快照完成剩余观测上报 │ 8. 所有异步快照任务执行完毕 → 资源彻底释放五、Cron定时任务观测Hook特殊规则与前台严格隔离定时任务Hook载体为CronContextHolder绝对不复用Per-Request强制规则Cron上下文独立生成专属cron-traceId不挂载任何用户会话Trace标签固定context_typecron_task定时任务尝试抢占SessionLock非阻塞逻辑所有抢占、跳过事件生成独立CronScheduleSpan禁止Cron Hook创建Span挂载到用户会话Trace杜绝后台定时操作混入用户对话链路。六、子代理SubAgent观测Hook隔离规则spawn_subagent 创建子会话时新建独立RequestContext与独立Trace父代理仅传递精简任务参数快照不传递父完整原始上下文父Trace内部生成SubAgentDispatchSpan作为父侧引用锚点子代理整套四层链路独立存在通过span属性建立关联不是直接父子Span嵌套设计目标防止子代理海量工具Span污染父Trace视图同时可以双向关联溯源兼顾隔离与可追溯。七、和现有全部核心模块联动1. 联动 并发安全三套件Per-Request Hook 建立在Per-Request上下文基础之上SessionLock同一会话串行执行主Agent循环Hook避免同一轮Turn并发创建冲突SpanCronContextHolder区分定时任务上下文载体隔离前后台观测链路。2. 联动 SubAgent三层安全约束子代理独立上下文观测链路隔离防污染机制在观测层落地子代理内部埋点不会串入父会话。3. 联动四层Langfuse追踪所有Span、Generation全部由Per-Request Hook驱动创建自动携带租户、Agent、上下文类型标签实现分层观测采样、成本统计。4. 联动 12 ConditionalOnProperty 条件开关可以按环境/租户/Agent精细化控制观测Hook启用ConditionalOnTenant金融租户开启全量Hook完整记录Generation输入输出普通租户启用采样模式ConditionalOnGlobalEnvdev开启全部调试Hookprod关闭部分高消耗调试埋点ConditionalOnSubAgent控制是否采集子代理完整内部Span。5. 联动 Context Compaction上下文压缩在ContextEngineSpan内完整记录压缩发生时的反抖动、CJK优化标记全部写入Span标签快照机制保证后台异步压缩埋点不会污染活跃用户上下文。八、常见错误模式 vs 标准正确模式错误1异步Hook直接持有原始RequestContext引用现象主请求提前完成释放上下文异步回调读取上下文出现随机错乱、trace串号。✅ 框架自动快照拷贝业务代码禁止手动保存原始上下文长期引用。错误2Cron定时Hook强行复用用户会话RequestContext现象定时任务Span挂载到用户Trace报表、成本统计失真。✅ 定时任务统一使用CronContextHolder载体独立traceId。错误3在Hook全局变量缓存sessionId/traceId多并发下全局变量被覆盖后到来请求覆盖前一条请求标识。✅ 所有标识从当前Hook绑定的上下文载体实时读取禁止缓存到全局。错误4子代理直接复用父RequestContext大量父会话标签、冗余上下文传入子代理观测链路庞大混乱存在数据泄漏风险。✅ 子代理新建独立RequestContext仅传递必要任务参数快照。九、优势总结从根源杜绝Trace串扰上下文载体隔离 异步只读快照双保险解决企业多租户高并发观测最棘手链路错乱问题前后台流量天然隔离用户请求 / 子代理 / Cron定时三类流量观测标签自动区分容量规划、成本分摊、告警可以独立配置异步场景完整覆盖流式LLM、异步记忆写入、后台归档等高并发异步场景埋点稳定不会丢失元数据与整套安全、并发体系统一标准观测层并发模型和会话锁、定时安全约束、子代理隔离保持一致设计思想运维与开发一套规范可观测审计闭环每条Span天然携带租户、会话、上下文类型满足政企审计、资源计量需求。十、横向对比原生AgentScope / Codex / Claude Code原生 AgentScope无标准化Per-Request Hook上下文透传异步回调没有快照机制观测埋点大多硬编码全局变量并发场景极易Trace串扰不支持多租户生产观测。OpenAI Codex云端任务隔离但不存在持久会话模型没有分层上下文载体没有区分前台/后台定时流量Hook体系封闭无法自定义分层观测策略。Claude Code本地单会话单进程模型无网关并发层不存在多请求并发观测问题缺少分布式多租户观测并发安全设计。OpenClaw Per-Request Hook观测并发模型面向多渠道、多租户、前后台混合流量、多子代理并行的AI中台设计将上下文传播规范内置进Hook事件总线实现观测链路稳定可控是企业级LLMOps可观测底座必备能力。十一、生产落地最佳实践业务插件禁止自行缓存RequestContext所有埋点元数据在Hook触发时刻从载体实时读取开发自定义Observer插件时异步回调依赖框架自动生成的只读快照不要捕获原始上下文排查Trace错乱故障优先查看Span标签context_type快速区分是用户流量、定时任务还是子代理高并发生产环境对高消耗Generation全量文本采集启用租户/Agent粒度采样开关平衡合规与算力开销Langfuse配置告警监控trace_cross跨会话挂载Span异常一旦出现代表Hook上下文传递存在Bug。