在 Windows 上跑 Hermes Gateway,最让人抓狂的一类问题不是“服务真的挂了”,而是:
Telegram 明明还能连,Gateway 进程明明存在,Scheduled Task 也在运行,
但 hermes gateway status 却说它 stopped。
NousResearch/hermes-agent issue #25513 记录的就是这个场景。
它看起来像 Telegram 配置问题、Gateway 没启动、Windows 服务没装好,甚至像模型 API 不通。但真正的问题更底层:Hermes 在 Windows 上判断 Gateway runtime 状态的逻辑不够准确,把一个实际运行中的 Scheduled Task Gateway 误报成 stopped 或 manual process。
这类 bug 的麻烦在于,它会误导用户做错误操作:反复重启、重复安装、改 token、换模型,却没有解决状态探测本身的误判。
一句话现场:运行中的 Gateway 被诊断成 stopped
issue 里的现象可以压缩成四句话:
Gateway 实际在运行。
Telegram connectivity 是活的。
Windows Scheduled Task 已安装并处于运行状态。
但 hermes gateway status / hermes status --all 报 stopped 或 manual process。
用户可能看到类似结果:
Gateway Service: stopped
Manager: manual process
No gateway process detected
但另一边,系统里又能找到真实的 Gateway 进程:
python -m hermes_cli.main gateway run --replace
这就是典型的“观测层坏了”:服务没死,诊断仪表盘读错了。
为什么 Windows 更容易踩这个坑?
Linux/macOS 上,Hermes Gateway 的运行方式通常更容易被归类:
- systemd;
- launchd;
- 当前 shell 里的 manual process;
- Docker/container。
但 Windows 原生安装经常走 Scheduled Task 路径。
也就是说,Gateway 不是一个传统意义上的 Unix service,也不一定能通过 Linux/macOS 那套 manager 探测逻辑识别。
如果 hermes gateway status 没有 Windows-specific runtime-manager branch,就可能退回到泛化逻辑:
找不到明确 manager → 当成 manual process / stopped
这正是 issue 提到的第一个根因。
根因一:get_gateway_runtime_snapshot 缺少 Windows 分支
issue 的 root cause 写得很明确。
hermes_cli/gateway.py:get_gateway_runtime_snapshot() 当时没有真正的 Windows runtime manager 分支。
结果是:
Windows Scheduled Task gateway
→ 没有被识别为 windows scheduled task
→ fallback 到 generic/manual process 判断
→ status 展示 stopped 或 manual process
这不是用户没启动 Gateway。
是 Hermes 没把 Windows Scheduled Task 当成一等公民来识别。
一个正确的状态快照至少应该能区分:
manager = windows scheduled task
status = running
pid = <runtime pid>
而不是在已安装 task 的情况下还显示:
Manager: manual process
Status: stopped
根因二:PID 扫描既太宽,又排除了真正的 Gateway
第二个坑更微妙。
issue 提到 find_gateway_pids() / _scan_gateway_pids() 的命令匹配过宽,匹配到了类似:
hermes gateway ...
这会把一些 helper / status / tool invocation 也纳入候选。
为避免把当前查询命令自己当成 Gateway,程序又会排除 caller ancestry。
问题在 Windows 这个场景里,某些 helper/tool 调用可能是实际 Gateway 的 descendant,广泛排除 ancestor chain 时,反而可能把真正的 live gateway process 排掉。
于是出现一个很反直觉的组合:
匹配条件太宽 → 需要排除更多调用链
排除范围太宽 → 真正 Gateway 也被隐藏
最终 → no gateway process detected
这不是进程不存在,而是扫描规则把它弄丢了。
正确方向:匹配真正的 gateway run,而不是所有 hermes gateway
修复方向不是“扫描更多进程”,而是“扫描得更准”。
issue 里给出的方向包括:
- Windows 上新增真正的 runtime snapshot 分支;
- 查询 Windows Scheduled Task 状态;
- 报告 manager 为
windows scheduled task; - PID 检测只匹配真实 runtime command;
- 避免把普通 helper 命令和运行中的 Gateway 混为一谈。
关键是区分这两类命令:
真实 Gateway runtime:
python -m hermes_cli.main gateway run --replace
和:
状态查询 / 管理命令:
hermes gateway status
hermes gateway restart
hermes status --all
它们都可能包含 hermes 和 gateway,但语义完全不同。
为什么这不是 DeepAI 或模型 API 问题?
这类问题很容易被误归因。
用户看到 Gateway status 是 stopped,可能会联想到:
- Telegram bot token 错了;
- API Key 没配;
- DeepAI / OpenAI-compatible endpoint 不通;
- 模型没响应;
- 网络代理出问题。
但 issue #25513 的问题发生在:
Hermes CLI status detection → Windows process / Scheduled Task runtime snapshot
它甚至还没进入模型调用链路。
如果 Telegram 连接实际活着,Gateway runtime PID 也存在,只是 hermes status --all 报错,那你首先应该怀疑状态探测逻辑,而不是模型 API。
DeepAI API 中转站适合解决的是模型调用层的问题,例如统一 OpenAI-compatible Base URL:
https://api.deepai.wang/v1
但它不会改变 Windows 上 get_gateway_runtime_snapshot() 如何识别 Scheduled Task。
排查顺序:别先重装,先确认“真死”还是“误报”
遇到 Windows 上 Gateway status 异常,建议先按下面顺序判断。
1. 看消息通道是否真的断了
如果 Telegram bot 仍然能接收消息,说明 Gateway 不一定死了。
状态命令显示 stopped,不等于事实 stopped。
2. 看是否存在真实 runtime command
重点找的不是所有 hermes gateway 命令,而是真正运行入口:
python -m hermes_cli.main gateway run --replace
如果这个进程存在,状态命令却说 stopped,就很像 runtime detection bug。
3. 看 Windows Scheduled Task 是否在运行
如果 Scheduled Task 已安装并运行,但 Hermes 报:
Manager: manual process
这就是 manager 识别错误。
4. 对照版本是否包含 PR #25503 修复
issue 评论说明 #25513 是 #25502 的 duplicate,修复在 PR #25503。
如果你使用的是旧版本,优先升级到包含该修复的版本,再判断是否仍然复现。
为什么“状态误报”也值得修?
有人可能会说:Gateway 能跑不就行了,status 显示错一点有什么关系?
问题在于,Agent 系统高度依赖状态命令做决策。
一旦状态层误报 stopped,后续可能诱发:
- 用户重复启动多个 Gateway;
- 自动化脚本误判服务失败;
- Agent 执行不必要的 restart;
- 排障方向从 Windows runtime 偏到 token/API/model;
- 监控系统发出错误告警。
状态命令不是装饰品。它是控制平面的一部分。
在 Gateway 这种消息入口上,错误状态会直接影响运维判断。
给 Windows 用户的实用判断
如果你在 Windows 11 上遇到:
hermes gateway status 显示 stopped
hermes status --all 显示 manual process
但 Telegram bot 还在线
不要马上删配置、换 API Key、重装 Hermes。
更合理的判断是:
先确认是否是 Windows Scheduled Task runtime detection 误报。
尤其是当你能看到:
python -m hermes_cli.main gateway run --replace
并且 Scheduled Task 状态正常时。
FAQ
为什么 Gateway 还在跑,Hermes 却显示 stopped?
因为旧版 Windows runtime detection 没有正确识别 Scheduled Task manager,并且 PID 扫描/调用链排除逻辑可能把真实 Gateway 进程漏掉。
Manager: manual process 一定说明我是手动启动的吗?
不一定。在这个 issue 里,它可能只是 Windows Scheduled Task 没被正确识别后的 fallback 结果。
这和 Telegram token 有关系吗?
通常没有。如果 Telegram connectivity 本身是活的,问题更像状态探测误报,而不是 token 配置错误。
这个问题修复了吗?
issue 评论说明 #25513 是 #25502 的 duplicate,修复在 PR #25503。
DeepAI API 中转站能修这个问题吗?
不能。这是 Hermes 在 Windows 上识别 Gateway runtime 状态的问题,不是模型 API 请求问题。DeepAI 适合模型调用层,不负责 Windows Scheduled Task 状态探测。
总结
#25513 的核心教训是:
Gateway 状态命令显示 stopped,不一定代表 Gateway 真的死了。
在 Windows Scheduled Task 场景里,Hermes 需要同时正确识别:
- manager 是
windows scheduled task; - runtime PID 是真实的
gateway run进程; - helper/status 命令不能和 runtime 命令混淆;
- Windows 不能完全套用 POSIX/systemd/launchd 的状态判断假设。
对用户来说,最重要的排查习惯是:先分清“服务真的不可用”还是“观测层误报”。
如果 Telegram 还通、进程还在、Scheduled Task 还跑,别急着重装。先查 Hermes 版本是否已经包含 Windows Gateway runtime detection 的修复。