如果你在 Telegram 里使用 Hermes Agent,普通消息突然反复收到:
⚡ Interrupting current task... I'll respond to your message shortly.
但你发送:
/stop
却得到:
No active task to stop.
这不是模型慢,也不是 Telegram 网络延迟,而是 Hermes Gateway 曾经出现过的一类 busy lock split-brain 问题:平台 adapter 还以为会话忙着,但 gateway runner 已经没有对应的 active agent。
本文基于 NousResearch/hermes-agent issue #11016,整理 Telegram 会话被 stale adapter busy lock 卡住的症状、根因、临时恢复方法和官方修复方向。
典型症状:/stop 说没任务,但普通消息一直被拦
这个问题最迷惑的地方,是两个状态互相矛盾:
- 你发普通消息,系统说正在中断当前任务;
- 你发
/stop,系统又说没有活跃任务可停止。
用户可见表现包括:
⚡ Interrupting current task... I'll respond to your message shortly.
反复出现。
同时:
/stop返回No active task to stop.;/new或/reset可能清空历史,但不一定解除卡死;- 只有
/restart能立即恢复; - 后台日志可能只看到 Telegram text-batch flush,而没有正常 inbound processing。
这就是典型的 Gateway 状态 split-brain。
根因:adapter 和 runner 对“会话是否忙”的判断分裂
issue 中给出的根因很清楚,涉及两个状态表:
gateway/platforms/base.py → adapter._active_sessions
gateway/run.py → runner._running_agents
问题状态是:
adapter._active_sessions 仍认为 session active
runner._running_agents 已经没有对应 active agent
于是发生连锁反应:
1. 普通文本进入 Telegram adapter; 2. adapter 看到 session active,于是触发 busy guard; 3. 消息被当作“打断当前任务”处理,无法进入正常 dispatch; 4. 用户发送 /stop; 5. /stop 去 runner 查 active agent; 6. runner 说没有; 7. 用户被困在“普通消息被拦、停止命令又无效”的状态。
这就是为什么它看起来像系统人格分裂:一边说忙,一边说没任务。
为什么 /restart 能救?
/restart 能恢复,是因为它会更彻底地重置 Gateway 进程或运行状态,把 adapter 里的 stale lock 也清掉。
而 /stop、/new、/reset 在问题版本里可能只处理了 runner 或历史状态,没有把 adapter 的 _active_sessions 一起释放。
这也是临时恢复的最直接方法:
/restart
但这只是恢复,不是修复。因为同一个生命周期 race 后续仍可能再次出现。
这不是“模型太慢”或“Telegram 消息丢了”
遇到 Telegram bot 卡住时,很多人会先怀疑:
- 模型响应太慢;
- OpenRouter / DeepAI / OpenAI API 超时;
- Telegram webhook 不稳定;
- Docker 网络有问题;
- Redis / queue 异常。
但 #11016 的核心不是模型响应,而是 Gateway 内部会话状态没有对齐。
一个简单判断是:
- 如果模型真的在运行,
/stop应该能找到 active task; - 如果
/stop找不到,但普通消息仍被 busy guard 拦截,那就很像 stale adapter lock。
修复方向:让 adapter task ownership 和 runner 状态一起清理
issue 里的本地修复思路包括:
1. 在 gateway/platforms/base.py 记录每个 session 的 adapter background task ownership; 2. 增加 cancel_session_task(session_key); 3. busy-session handler 清理 stale lock 后,重新检查 _active_sessions,允许回到正常 dispatch; 4. runner 的 force-unlock 路径要同时清理 adapter session state; 5. 覆盖这些路径:
- stale busy self-heal;
/stop;/new//reset;- sentinel hard-stop;
6. 防止 startup gap race:adapter 已标记 active,但 runner 还没 claim _AGENT_PENDING_SENTINEL 时,不能误判为 stale。
后续维护者评论明确说明:
Fixed in #14513
修复综合了:
- adapter-side task ownership;
/stop//new//resethandoff;- runner-side slot ownership guard;
- on-entry stale-lock self-heal。
用户可见变化是:
/stop、/new、/reset能确定性取消 in-flight adapter task 并释放 guard;- split-brain guard 会在下一条 inbound message 自愈;
- stale async run 退出时不能覆盖新 run 的 session slot。
临时排查和恢复步骤
如果你线上 Telegram Hermes 卡住,可以按这个顺序处理。
1. 先确认症状是否匹配
看是否同时满足:
普通消息 → Interrupting current task...
/stop → No active task to stop
/restart → 立即恢复
如果满足,优先怀疑 stale busy lock。
2. 查看 Gateway 日志
关注是否有:
- 普通消息没有进入正常 dispatch;
- 只有 repeated busy ack;
- runner active agent 为空;
- adapter active session 未释放。
3. 用 /restart 先恢复服务
线上优先恢复可用性:
/restart
如果你是 Docker/container 部署,也可以重启容器或 Gateway 进程。
4. 升级到包含 #14513 修复的版本
如果你频繁遇到这个问题,不要长期靠 /restart。
升级后重点验证:
/stop是否能释放 busy guard;/new//reset是否能解除卡住状态;- 快速连续发送消息时是否还会卡;
- stale run 结束时是否会覆盖新 session。
为什么测试要覆盖 startup gap?
这个问题修复时还有一个二次 race:
adapter 已经把 session 标为 active
runner 还没设置 _AGENT_PENDING_SENTINEL
第二条消息快速进来
如果修复逻辑太粗暴,会把这个“正在启动中的正常任务”误判成 stale lock,然后取消掉第一条刚启动的任务。
所以好的修复不能只是“runner 没 active agent 就清 adapter”。它必须知道:
- adapter 是否仍有 live per-session task;
- runner 是否处在 pending startup;
- 当前 slot owner 是否属于同一次 run。
这也是 Gateway 并发状态机里最容易出错的地方。
和 DeepAI API 中转站的关系
DeepAI API 中转站适合解决模型 API 接入层问题,例如:
Base URL: https://api.deepai.wang/v1
API Key: 你的 DeepAI Key
Model: 以控制台为准
但 Telegram busy lock 卡死发生在 Gateway 会话调度层:消息还没正常走到模型请求,就被 adapter busy guard 拦住了。
因此,DeepAI API 中转站不能直接修复:
- adapter
_active_sessionsstale; - runner
_running_agents不一致; /stop与 busy guard 状态分裂;- startup gap race。
正确分层是:
- Gateway 负责消息进入和任务生命周期;
- DeepAI / OpenAI-compatible provider 负责模型调用;
- 如果消息没到模型层,先修 Gateway。
FAQ
一直 Interrupting current task,是不是模型还在跑?
不一定。如果 /stop 同时说 No active task to stop,更像 adapter stale busy lock,而不是模型仍在跑。
/new 或 /reset 能解决吗?
问题版本里不一定。它们可能重置历史,但未释放 adapter active session。修复后这些路径应清理 adapter lock。
/restart 为什么可以?
因为它更彻底地重置 Gateway 运行状态,能清掉 stale lock。
这个问题只影响 Telegram 吗?
issue 标注为 Telegram,但根因属于 Gateway adapter/runner 生命周期,其他平台如果有类似 busy guard 和 runner state 分离,也可能有相似风险。
DeepAI API 中转站能缓解吗?
不能直接缓解。消息在 Gateway 层就被拦住了,还没进入模型 API 请求。
总结
Hermes Telegram 反复提示:
Interrupting current task...
但 /stop 又说:
No active task to stop
这通常不是模型慢,而是 Gateway adapter 与 runner 的会话状态分裂:adapter 仍认为 session busy,runner 已经没有 active agent。
短期用 /restart 恢复,长期应升级到包含 #14513 修复的版本,让 /stop、/new、/reset 和 stale-lock self-heal 都能正确释放 busy guard。