Hermes Agent v2026.5.16 升級:PYTHONPATH 修正與 lazy_deps 機制
背景
在 Zeabur 上部署 Hermes Agent 的過程中,發現語音轉文字功能(faster-whisper)無法正常載入。調查後發現原因是:faster-whisper 並非在 Docker image 建置時安裝,而是透過 lazy_deps 機制在第一次使用時動態安裝,但安裝路徑與 Hermes Agent 的 Python 環境不同。
問題分析
Hermes Agent 的依賴管理有兩層:
- 建置時依賴(Dockerfile):透過
uv sync --frozen --no-install-project --extra all安裝,產出/opt/hermes/.venv - 執行時依賴(lazy_deps):部分模組(如 faster-whisper、discord.py、slack 等)設計為在第一次使用時自動安裝
為什麼 faster-whisper 找不到?
faster-whisper 在 lazy_deps 的定義如下(tools/lazy_deps.py):
1
2
3
"stt.faster_whisper": (
"faster-whisper==1.2.1",
),
當使用者第一次使用語音轉文字功能時,lazy_deps 會嘗試透過以下順序安裝:
- Tier 1:
uv pip install(使用/usr/local/bin/uv,不需要 venv 裡有 pip) - Tier 2:
python -m pip+ensurepip.bootstrap(備援方案)
問題在於:faster-whisper 安裝到 /opt/data/venvs/faster-whisper(一個手動建立的 venv),但 Hermes Agent 執行時的 Python 環境是 /opt/hermes/.venv,兩者不通。
解決方案:PYTHONPATH
在 entrypoint-ssh.sh 中,在呼叫上官 entrypoint 之前加入一行:
1
export PYTHONPATH="/opt/data/venvs/faster-whisper/lib/python3.13/site-packages:$PYTHONPATH"
這樣的好處:
- 不需要重 build Docker image:只要修改 entrypoint script 並重啟即可
- /opt/data 是持久化 volume:即使 container 重啟,設定依然保留
- 上游 entrypoint.sh 不需要改:我們的 entrypoint-ssh.sh 保持 SSH 功能,同時載入上官的 entrypoint
修改內容
在 docker/entrypoint-ssh.sh 的第 56-58行之間加入:
1
2
3
4
# Make faster-whisper venv site-packages available to Hermes Python
# This avoids rebuilding the Docker image when faster-whisper is installed
# via the lazy_deps installer at /opt/data/venvs/faster-whisper.
export PYTHONPATH="/opt/data/venvs/faster-whisper/lib/python3.13/site-packages:$PYTHONPATH"
commit: 14b2c8d78 feat: add faster-whisper venv to PYTHONPATH in entrypoint-ssh
關於 lazy_deps 的更多細節
lazy_deps 是 Hermes Agent 用來解決依賴衝突的機制。傳統做法是把所有依賴(透過 pyproject.toml extras)全部裝進同一個環境,但這樣只要其中一個模組的依賴有問題(如版本衝突、被 PyPI 下架),整個安裝就會失敗。
lazy_deps 的設計:
- 按需安裝:模組在第一次 import 時才檢查並安裝
- 隔離環境:每個模組安裝到
sys.executable對應的 venv - 安全機制:僅允許清單內的套件(防止惡意注入)
- 離線容錯:安裝失敗時不默默忽略,而是抛出明確的錯誤
結論
這次修正不影響 Docker image 的建置流程,純粹是執行環境的設定調整。Zeabur 重啟後會吃到新的 entrypoint-ssh.sh,SSH 功能正常,faster-whisper 也能正確找到。