hermes-concurrency-defects-todo.md 3.9 KB

Hermes 并发缺陷待办

调研日期:2026-08-18 背景:对话页多会话并发场景调研结论。当前主流程(对话页多会话并发)链路安全, 以下缺陷暂不触发或影响面有限,记录备查。

并发安全现状(无缺陷部分)

层 隔离机制 位置
Java 执行层 ChatRunService 固定线程池 max(8, cpu×2),每 run 独立线程;SseEventBus 按 runId 隔离 backend/src/main/java/com/agent/management/service/ChatRunService.java:110
Bridge 线程层 每个 /run 请求创建独立 daemon 线程,事件经 run 级 queue(局部变量)隔离 backend/hermes-bridge/hermes_bridge.py:541
Agent 实例层 LRU 池按 session_id::hermes_home::model_id 键控;每会话有独立 hermesSession hermes_bridge.py:202、ChatSessionService.java:51
工作目录(主要路径) _SESSION_CWD 为 contextvars,线程内 set/reset 配对,hermes-agent 工具优先读取 hermes_bridge.py:489-525
Clarify 按 clarify_id 注册/唤醒,run 级孤儿清理配对 hermes_bridge.py:411-447

缺陷清单

缺陷 1:os.chdir 进程级竞态(优先级:中)

位置:backend/hermes-bridge/hermes_bridge.py:474-479

现象:working_dir 除设置 contextvar 外,还会切换进程 cwd(os.chdir(wd)) 并覆盖进程级环境变量 TERMINAL_CWD。多个 run 并发时:

  • 进程 cwd 由最后执行 chdir 的 run 主导,先启动的 run 拿到错误目录;
  • 一个 run 结束时在 finally 中恢复 original_cwd,会破坏仍在运行的 run 的进程 cwd。

影响面:仅限直接调用 os.getcwd() 的工具;走 _SESSION_CWD(contextvar, 线程隔离)的工具不受影响。

触发场景:工作流 DAG 同层多个 Hermes 节点并发执行(多个 /run 请求同时 携带不同 working_dir)。对话页多会话场景因 Agent 隔离 + 工具走 contextvar 基本无感。

修复建议:将 os.chdir / TERMINAL_CWD 下沉为按 task_id 的隔离机制 (与 register_task_env_overrides 同思路),运行线程内不再触碰进程全局状态。

缺陷 2:同 cache_key 并发复用同一 Agent 实例(优先级:高)

位置:backend/hermes-bridge/hermes_bridge.py:494-500、:202-207

现象:同一 session_id::hermes_home::model_id 的两个并发 run 会从 LRU 池 拿到同一个 Agent 实例:

  • _run 内直接给实例属性赋回调(agent.tool_start_callback = ... 等), 后启动的 run 覆盖先启动 run 的全部回调 → 事件流向错乱;
  • Agent 的对话上下文(run_conversation 历史)交叉污染。

当前防线:仅前端"同会话运行中禁发"(useChat.js 的 sending computed)。 双浏览器窗口打开同一会话、或直接调 API 可绕过。

修复建议(低成本方案):Java 层 ChatRunService.startRun 增加校验—— 同会话存在 RUNNING 状态消息时拒绝新 run(返回业务错误)。Bridge 层可选 加固:/run 检测 cache_key 已有活跃 run 时强制 force_new 并发运行。

缺陷 3:HERMES_HOME 环境变量进程全局覆盖(优先级:低)

位置:backend/hermes-bridge/hermes_bridge.py:210-212

现象:带 hermes_home 的请求直接 os.environ["HERMES_HOME"] = ..., 并发请求互相覆盖,技能目录加载可能错乱。

当前防线:对话页与工作流节点均传 hermes_home=null(Java 侧 HermesAgentExecutor.java:98),回落固定 HERMES_HOME,暂不触发。

修复建议:仅在 Agent 构造期间临时设置并立即恢复(临界区内),或改为 显式传参注入而非环境变量。

修复优先级建议

缺陷 2(Java 层会话级 run 互斥校验,成本低、封堵面大)> 缺陷 1(工作目录 隔离机制重构)> 缺陷 3(当前不触发,可延后)。