· Jeff · 教程  · 6 分钟阅读

Hermes Agent从0.17.0升级到0.19.1,飞书机器人无响应解决办法

升级 Hermes Agent 后飞书机器人不响应?根因是 lark-oapi 从默认依赖变为可选依赖,旧版 1.5.3 不支持 extra_ua_tags 参数。本文提供从排查到持久化修复的完整方案。

升级 Hermes Agent 后飞书机器人不响应?根因是 lark-oapi 从默认依赖变为可选依赖,旧版 1.5.3 不支持 extra_ua_tags 参数。本文提供从排查到持久化修复的完整方案。

Hermes Agent从0.17.0升级到0.19.1,飞书机器人无响应解决办法

问题现象

将 Hermes Agent 从 v0.17.0 升级到 v0.19.1 后,飞书机器人看似正常运行,但发送消息后毫无响应。查看日志发现 Gateway 启动时飞书适配器加载失败,报错类似 feishu_sdk_incompatible 或静默跳过。


根因分析

v0.17.0 之后,lark-oapi(飞书 SDK)被从 Hermes 的默认依赖改成了可选依赖(归类到 feishu extra)。更关键的是,Docker 镜像里设置了 HERMES_DISABLE_LAZY_INSTALLS=1禁止了运行时自动安装缺失的依赖

所以升级时的链路是这样的:

  1. 新镜像不再自带 lark-oapi
  2. 容器启动时 pip install -e ".[all]" 如果失败,兜底只装基础依赖
  3. 飞书适配器被静默禁用——老的 Gateway 进程在内存里还能跑,一旦重启就崩

即便 lazy-packages 里保留了旧版 lark-oapi,那也是 1.5.3,不支持 Hermes v0.19.x 飞书适配器需要的 extra_ua_tags 参数。必须升级到 lark-oapi==1.6.8

💡 兼容版本参考:Python 3.11.15 + lark-oapi==1.6.8 + websockets==15.0.1 精确兼容。


排查:确认问题

SSH 进入容器,先看现状:

docker exec -it hermes /bin/bash

# 查找 lark_oapi 安装位置
find / -name "lark_oapi" -type d 2>/dev/null

# 查看 Gateway 进程用的 Python
ps aux | grep gateway | grep -v grep

典型输出:

/opt/data/lazy-packages/lark_oapi
/opt/data/profiles/baibai/lazy-packages/lark_oapi
/opt/data/profiles/wenwen/lazy-packages/lark_oapi
...

关键发现:

  • Gateway 进程使用 /opt/hermes/.venv/bin/python3
  • lark_oapi 装在 /opt/data/lazy-packages/ 和各 profile 的 lazy-packages
  • /opt/hermes/.venv没有 lark-oapi

修复步骤

第一步:安装 lark-oapi 1.6.8

Hermes 镜像自带 uv,直接用:

# 装到 Gateway venv(当前容器生效)
uv pip install --python /opt/hermes/.venv/bin/python3 "lark-oapi==1.6.8"

# 装到持久化卷的 lazy-packages(重建容器也不丢)
uv pip install --target /opt/data/lazy-packages "lark-oapi==1.6.8"

# 各 profile 同步更新
for d in /opt/data/profiles/*/lazy-packages; do
  uv pip install --target "$d" "lark-oapi==1.6.8" 2>/dev/null
done

如果 uv 命令不存在,用 pip 兜底:

/opt/hermes/.venv/bin/python -m ensurepip --upgrade 2>/dev/null || \
  curl https://bootstrap.pypa.io/get-pip.py -o /tmp/get-pip.py && \
  /opt/hermes/.venv/bin/python /tmp/get-pip.py

/opt/hermes/.venv/bin/python -m pip install -U "lark-oapi==1.6.8"

第二步:验证版本

# 确认版本号
/opt/hermes/.venv/bin/python -c "import lark_oapi; print(lark_oapi.__version__)"
# 必须输出 1.6.8

# 确认 extra_ua_tags 参数被支持
/opt/hermes/.venv/bin/python -c \
  "import inspect, lark_oapi.ws; \
   print('extra_ua_tags' in inspect.signature(lark_oapi.ws.Client.__init__).parameters)"
# 必须输出 True

第三步:修权限(容易漏的一步)

Gateway 进程以 hermes 用户(uid 10000)运行,pip/uv 安装的包默认权限 700,会导致 PermissionError——错误被上层吞掉,只报 “requirements not met”:

chmod -R o+rX /opt/hermes/.venv/lib/python*/site-packages/
chmod -R o+rX /opt/data/lazy-packages/

⚠️ 这条如果不做,前面全白装。

第四步:重启 Gateway

# 退出容器
exit

# 重启容器(最简单的方式)
docker restart hermes

# 观察日志确认飞书连接成功
docker logs hermes --tail 50 -f

看到 [Feishu] Connectedconnected to wss://msg-frontier.feishu.cn/ws/v2 就修复成功了。


持久化方案:防止下次升级复发

先厘清持久化边界

Docker 部署中,只有 /opt/data 映射到了宿主机的 ~/.hermes/。容器的其他路径(包括 /opt/hermes/.venv)不在挂载卷内:

操作venv 里的 lark-oapilazy-packages 里的 lark-oapi
docker restart✅ 不丢✅ 不丢
docker compose up -d 重建❌ 会丢不丢

所以必须把 lark-oapi 1.6.8 装到 /opt/data/lazy-packages(持久化卷内),这是容器重建后唯一能保留的位置。

终极方案:fix_lark.sh 启动脚本

docker-compose.yml,挂载修复脚本作为容器启动的前置步骤:

services:
  hermes:
    image: nousresearch/hermes-agent:latest
    volumes:
      - ~/.hermes:/opt/data
      - ./fix_lark.sh:/fix_lark.sh:ro
    entrypoint: ["/bin/bash", "-c", "/fix_lark.sh && exec /run/s6/basedir/scripts/rc.init"]

fix_lark.sh 内容:

#!/bin/bash
set -e
# 确保 lark-oapi 1.6.8 存在于持久化卷
uv pip install --target /opt/data/lazy-packages "lark-oapi==1.6.8" 2>/dev/null || true
# 同步到 venv(当前容器立即生效)
uv pip install --python /opt/hermes/.venv/bin/python3 "lark-oapi==1.6.8" 2>/dev/null || true
# 修权限
chmod -R o+rX /opt/data/lazy-packages/ 2>/dev/null || true
chmod -R o+rX /opt/hermes/.venv/lib/python*/site-packages/ 2>/dev/null || true
exec "$@"

这样无论是 docker restart 还是 docker compose up -d 重建容器,lark-oapi 1.6.8 都会被自动确保存在。


多 Profile 场景

如果你的容器里跑了多个 Profile 的 Gateway(如 baibaiwenwenruiruitutu),每个 Profile 有自己的 lazy-packages 目录,修复时建议一并更新:

for d in /opt/data/profiles/*/lazy-packages; do
  uv pip install --target "$d" "lark-oapi==1.6.8" 2>/dev/null
done

重启容器后,所有 Profile 的飞书连接应同时恢复。


总结

这个问题的本质是 Hermes 依赖管理策略变化 + Docker 镜像的惰性安装禁用 组合拳导致的。

核心修复就三步:

# 1. 装包(两条路径双保险)
uv pip install --python /opt/hermes/.venv/bin/python3 "lark-oapi==1.6.8"
uv pip install --target /opt/data/lazy-packages "lark-oapi==1.6.8"

# 2. 修权限
chmod -R o+rX /opt/hermes/.venv/lib/python*/site-packages/
chmod -R o+rX /opt/data/lazy-packages/

# 3. 重启
docker restart hermes

持久化靠 fix_lark.sh 启动脚本,一劳永逸。

📌 据说 0.19.1 之后的补丁镜像已经锁了 lark-oapi 到 1.6.8+,届时可直接 docker compose pull && docker compose up -d 解决。但在此之前,上述手动修复是最可靠的方案。

☕ 如果这篇文章对你有帮助

欢迎请 Jeff 喝杯咖啡,支持我持续分享更多软件技巧~

打赏功能即将上线,先点个赞也是支持 ❤️

返回博客

相关文章

查看全部 »
1.3GB 内存的服务器上,浏览器自动化必然 OOM:我最后用纯 HTTP 重写了一遍签到

1.3GB 内存的服务器上,浏览器自动化必然 OOM:我最后用纯 HTTP 重写了一遍签到

一个每天跑的签到脚本,用 Playwright 时 6 分钟才启动完浏览器、随后必崩。我一度以为是脚本写得不对,换了三种写法都没用。真正的结论是:在 1.3GB 内存、swap 全满的机器上,浏览器自动化注定失败——不是代码问题,是物理问题。更值得记的是第二层翻车:当时得出的「必须借浏览器上下文」这个结论本身就是错的,而它被固化进了代码,白折腾了一周。

FileBrowser 免登录图片直链:容器部署 + Notion 嵌入完整指南

FileBrowser 免登录图片直链:容器部署 + Notion 嵌入完整指南

想让 Notion 页面直接嵌入服务器上的图片,又不想把 FileBrowser 的管理登录暴露给所有人?核心思路不是 FileBrowser 自带功能,而是 nginx 层用 alias 把图片目录直接映射出来绕过认证。这篇是完整实战指南,含部署、直链、验证和排障。

Android 上跑 Hermes Agent:Termux 完整安装攻略

Android 上跑 Hermes Agent:Termux 完整安装攻略

想把 Hermes Agent 装进安卓手机?Termux 是唯一正解。本文实测覆盖从装 Termux、装系统依赖、三种安装方式(含 psutil 兼容坑)到飞书网关、防杀后台、SSH 远程管理的完整流程,手机直接变身随身 AI 助手。