【AgentDaily】Hermes 新 Profile Gateway 飞书 WebSocket 超时排查记
systemd 显示 Gateway 正在运行,飞书却始终连不上。最后发现,问题不在凭据,而在新 Profile 的服务没有继承代理环境变量。
问题现象
我为 Hermes 新建了 blog-writer Profile,并为它启动了独立的 systemd 用户服务:
1 | systemctl --user status hermes-gateway-blog-writer.service |
服务状态显示为 active (running),乍看没有异常。但 Gateway 日志中的飞书连接会等待 30 秒后超时:
1 | feishu connect timed out after 30s |
后续自动重连也没有成功:
1 | Reconnect feishu error: feishu connect timed out after 30s, next retry in 60s |
这里最容易被 active 误导。它只能说明 Gateway 主进程没有退出,不能证明飞书适配器已经建立 WebSocket 连接。即使所有消息平台都连接失败,Gateway 仍可继续运行定时任务,因此 systemd 不会把它判为失败。
排查思路
先确认服务是否活着,再确认平台是否真的连上。这两个状态不能混在一起判断。
我按下面的顺序排查:
- 使用
systemctl --user status确认进程没有崩溃或反复重启。 - 使用
journalctl查看启动阶段的完整日志,确认失败点是飞书 WebSocket 连接超时,而不是 Hermes 配置解析失败。 - 检查
blog-writerProfile 的飞书配置是否已被 Gateway 读取,但不在终端或文章中输出任何凭据。 - 对比默认 Gateway 与新 Profile Gateway 的 systemd 环境变量和 drop-in 配置。
- 重启服务后,以飞书连接成功日志作为最终判断依据,而不是只看 systemd 的
active状态。
查看日志可以使用:
1 | journalctl --user -u hermes-gateway-blog-writer.service -n 100 --no-pager |
对比服务加载的 drop-in 和环境变量可以使用:
1 | systemctl --user show hermes-gateway.service \ |
对比结果很直接:默认服务加载了自己的代理 drop-in,新服务最初没有。
根因
Clash 代理变量原本配置在 ~/.bashrc 中,所以从交互式 Shell 启动的命令可以正常访问外网。但 WSL 中由 systemd 用户管理器启动的服务不会读取 ~/.bashrc,它拿不到这些代理变量。
默认 Gateway 之所以能连接飞书,是因为它已有独立的 drop-in:
1 | ~/.config/systemd/user/hermes-gateway.service.d/proxy.conf |
新 Profile 使用的是另一个 systemd unit:
1 | hermes-gateway-blog-writer.service |
它对应的 drop-in 目录也必须使用自己的 unit 名称。默认服务的配置不会因为两个服务都属于 Hermes 就自动继承给新服务。
因此,这次故障的完整链路是:
blog-writerGateway 由 systemd 用户服务启动,没有读取~/.bashrc。- 新 unit 没有独立的代理 drop-in,进程环境中缺少 Clash 代理变量。
- Gateway 主进程能够正常启动,所以 systemd 显示
active。 - 飞书 WebSocket 无法在 30 秒内建立连接,平台适配器进入重试队列。
修复步骤
先为新服务创建与 unit 名称完全对应的 drop-in 目录:
1 | mkdir -p ~/.config/systemd/user/hermes-gateway-blog-writer.service.d |
然后创建:
1 | ~/.config/systemd/user/hermes-gateway-blog-writer.service.d/proxy.conf |
内容如下:
1 | [Service] |
这里同时写入大写和小写变量,是为了兼容不同 HTTP、WebSocket 库读取代理环境变量时的差异。ALL_PROXY 使用 socks5h,让域名解析也经由代理完成;NO_PROXY 则保留本机回环地址的直连,避免本地服务被错误送入代理。
配置写入后,重新加载 systemd 用户配置并重启新服务:
1 | systemctl --user daemon-reload |
这一步不能只执行 daemon-reload。它只让 systemd 重新读取 unit 和 drop-in,正在运行的进程不会自动获得新的环境变量,必须重启服务。
验证方式
先确认新服务确实加载了正确的 drop-in:
1 | systemctl --user show hermes-gateway-blog-writer.service \ |
输出中应包含:
1 | DropInPaths=/home/tianlejin/.config/systemd/user/hermes-gateway-blog-writer.service.d/proxy.conf |
同时应能看到 HTTP_PROXY、HTTPS_PROXY、ALL_PROXY、NO_PROXY 及其小写版本。检查时不要把包含凭据的其他环境变量复制到公开位置。
接着查看本次启动日志:
1 | journalctl --user -u hermes-gateway-blog-writer.service \ |
最终应出现这两条成功标志:
1 | [Feishu] Connected in websocket mode |
本次修复后,飞书 WebSocket 已成功连接,Gateway 也确认有一个平台处于运行状态。相比 active (running),这两条平台层日志才是验证完成的依据。
如果日志里出现包含连接参数的 WebSocket URL,不要直接复制到博客、Issue 或聊天记录中,其中可能带有临时票据或访问凭据。
为什么每个 Profile 都需要独立 drop-in
Hermes Profile 隔离的不只是配置目录,也会对应独立的 Gateway 服务。例如:
1 | hermes-gateway.service |
systemd 的 drop-in 以完整 unit 名称为作用域:
1 | ~/.config/systemd/user/<完整 unit 名称>.service.d/*.conf |
所以:
hermes-gateway.service.d/proxy.conf只修改默认 Gateway。hermes-gateway-blog-writer.service.d/proxy.conf只修改blog-writerGateway。- 创建新的 Profile Gateway 后,不能假设它会继承默认 Gateway 的 drop-in。
~/.bashrc面向交互式 Shell,不是 systemd 用户服务的通用环境配置入口。
独立 drop-in 也符合 Profile 隔离的目标。不同 Profile 可以使用不同代理、不同本地服务地址或完全不使用代理,不会互相污染。
新 Profile Gateway 检查清单
以后新建 Hermes Profile 并启用 Gateway,可以按这份清单逐项检查:
- 确认 Profile 已创建,并确认 Gateway 使用的是目标 Profile 的
HERMES_HOME。 - 确认对应的 systemd unit 名称,不要把默认服务和 Profile 服务混为一谈。
- 使用
systemctl --user status <unit>检查主进程是否稳定运行。 - 使用
journalctl --user -u <unit>检查平台适配器的连接结果。 - 如果 WSL 通过 Clash 访问外网,为该 unit 创建独立的
*.service.d/proxy.conf。 - 同时配置大写和小写的代理变量,并为本地回环地址设置
NO_PROXY与no_proxy。 - 修改 drop-in 后执行
systemctl --user daemon-reload,随后重启对应服务。 - 使用
systemctl --user show <unit> -p DropInPaths -p Environment确认配置已进入进程环境。 - 不要只看
active,还要确认日志出现平台连接成功和 Gateway 平台计数。 - 分享日志前删除 token、ticket、access_key、App ID、App Secret 以及带连接参数的完整 WebSocket URL。
参考资料
- Hermes Agent Profiles 文档: https://hermes-agent.nousresearch.com/docs/user-guide/profiles
- Hermes Agent Messaging 文档: https://hermes-agent.nousresearch.com/docs/user-guide/messaging/
- systemd.unit Drop-in 配置说明: https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html
- systemd.exec 环境变量说明: https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html
创建时间:2026-07-23 · 本文档由 Hermes 用户排查并记录


