Hermes Telegram 渠道代理导致 API 超时排查
Hermes Telegram 渠道代理导致 API 超时排查
Telegram 机器人收到消息后一直显示"正在输入"却不回复,而同一时间终端 CLI 用同一个模型却完全正常。最终定位到是 launchd 启动的网关进程不继承系统代理环境变量,而 .env 里的代理配置又被注释掉了,导致网关直连海外 API 超时。
现象
用户通过 Telegram 发消息给 Hermes bot:
- Bot 显示"正在输入..."(typing indicator),但永远不返回回复
- 等待数分钟后收到
No response from provider for 180s错误 - 同一时间在终端 CLI 里使用同一个模型完全正常,5-10 秒响应
错误日志:
⚠️ No response from provider for 180s (model: mimo-v2.5-pro, context: ~20,614 tokens). Reconnecting...
⚠️ API call failed (attempt 1/3): APITimeoutError
🔌 Provider: custom Model: mimo-v2.5-pro
🌐 Endpoint: https://YOUR-API-ENDPOINT/v1
📝 Error: Request timed out.排查过程
初始判断(错误方向)
最初怀疑是 API 不稳定或流式传输超时设置太短:日志显示 Stream stale for 180s (threshold 180s) — no chunks received,建议增加 HERMES_STREAM_STALE_TIMEOUT=300。但用户指出 CLI 用同一个模型完全正常。
教训
当同一个 API 在不同客户端表现不一致时,问题大概率不在 API 端,而在客户端差异。
检查代理配置
系统环境有代理:
$ env | grep -i proxy
HTTP_PROXY=http://127.0.0.1:10808
HTTPS_PROXY=http://127.0.0.1:10808
ALL_PROXY=socks5h://127.0.0.1:10808代理是 Xray,端口 10808。通过代理测试 API 正常:
$ curl --proxy http://127.0.0.1:10808 https://YOUR-API-ENDPOINT/v1/models
# 200, 0.8s — 正常代理本身没问题。
发现 Telegram session 卡死循环
查看 agent.log,发现 Telegram session 陷入死循环:收到消息后调用 API,流式传输 180 秒无数据被杀,网关重启恢复 session,又卡 180 秒……删除卡死的 session 并重启网关,问题依旧,新 session 一样卡死。
对比 CLI 和 Telegram 的 API 调用
关键观察:CLI session 的 API 调用 5-10 秒完成,Telegram session 的 API 调用 180 秒超时。两者走同一个 endpoint、同一个模型,但表现完全不同。
检查网关阻塞
发现 gateway.log 在某个时刻之后完全停止输出:cron ticker 不再打印、新消息不再被记录,但 CLI session 的 agent.log 仍在正常写入。说明网关进程的 asyncio 事件循环被卡死的 HTTP 请求完全阻塞。
发现 launchd 环境差异(根因)
检查 launchd plist:
<key>EnvironmentVariables</key>
<dict>
<key>PATH</key>
<string>~/.hermes/hermes-agent/venv/bin:...</string>
<key>VIRTUAL_ENV</key>
<string>~/.hermes/hermes-agent/venv</string>
<key>HERMES_HOME</key>
<string>~/.hermes</string>
</dict>没有 HTTP_PROXY、HTTPS_PROXY、ALL_PROXY!
同时检查 .env:
# HTTP_PROXY=http://127.0.0.1:10808 ← 注释掉了!
# HTTPS_PROXY=http://127.0.0.1:10808 ← 注释掉了!
# ALL_PROXY=socks5h://127.0.0.1:10808 ← 注释掉了!真相大白:
| 进程 | 启动方式 | 代理 | API 表现 |
|---|---|---|---|
| CLI | 终端启动,继承系统环境 | ✅ 有代理 | 5-10 秒响应 |
| 网关 | launchd 启动,不继承系统环境 | ❌ 无代理 | 直连海外,180 秒超时 |
API 服务器在海外,从国内直连被墙或极慢,必须走代理。
修复
编辑 ~/.hermes/.env,取消代理注释:
HTTP_PROXY=http://127.0.0.1:10808
HTTPS_PROXY=http://127.0.0.1:10808
ALL_PROXY=socks5h://127.0.0.1:10808确保 NO_PROXY 不包含需要代理的域名:
NO_PROXY=localhost,127.0.0.1,::1然后重启网关:
hermes gateway restart经验总结
核心教训
- launchd 不继承系统环境变量:macOS 的 launchd 启动的进程只有 plist 里
EnvironmentVariables定义的变量。终端里export的、甚至系统偏好设置里配的代理都不会传递给 launchd 进程。 .env是网关的唯一环境来源:网关通过.env文件加载环境变量。如果.env里某个变量被注释掉,网关进程就没有这个变量。- 同一 API 不同客户端表现不一致 → 查客户端差异:不是 API 的问题,是两个客户端的网络路径不同。
- 网关卡死时 gateway.log 会停止更新:如果 gateway.log 突然没有新日志(但 agent.log 还在写),说明网关主循环被阻塞。
快速诊断清单
遇到 Telegram 渠道无响应但 CLI 正常时:
# 1. 检查网关是否卡死(gateway.log 是否有新日志)
tail -f ~/.hermes/logs/gateway.log
# 2. 检查代理配置
cat ~/.hermes/.env | grep -i proxy
# 3. 检查系统环境代理
env | grep -i proxy
# 4. 对比:直连 vs 走代理测试 API
curl -w "%{time_total}s" https://YOUR-API-ENDPOINT/v1/models
curl --proxy http://127.0.0.1:10808 -w "%{time_total}s" https://YOUR-API-ENDPOINT/v1/models
# 5. 检查 launchd 环境变量
cat ~/Library/LaunchAgents/ai.hermes.gateway.plist | grep -A 20 EnvironmentVariables代理配置最佳实践
对于需要代理的用户,.env 里应该显式配置代理,不要依赖系统环境:
# ~/.hermes/.env
HTTP_PROXY=http://127.0.0.1:10808
HTTPS_PROXY=http://127.0.0.1:10808
ALL_PROXY=socks5h://127.0.0.1:10808
NO_PROXY=localhost,127.0.0.1,::1 # 国内直连的服务加在这里不要把代理配置注释掉,除非你确定所有 API 都在国内可直连。
