DeepAI Paper Hermes Agent 教程,Hermes 终端、Docker 与安装 你以为传进 Docker 的变量,其实从没上车:Hermes docker_env 配置为何失效

你以为传进 Docker 的变量,其实从没上车:Hermes docker_env 配置为何失效

有些配置问题最折磨人:你看着 config.yaml 里写得明明白白,程序也没有报错,但运行结果就是不对。

NousResearch/hermes-agent issue #20537 就是这类问题。

用户在 Hermes 的 terminal.docker_env 里配置了环境变量,希望 Docker 终端后端启动容器时带进去。结果容器里什么都没有。

不是 Docker 不支持,不是 YAML 写错,也不是变量被容器吞了。

真正原因很直接:

docker_env 没有被映射成 TERMINAL_DOCKER_ENV。

变量还没到 Docker,半路就掉了。


现象:config.yaml 写了,容器里看不到

用户的配置类似这样:

terminal:
  backend: docker
  docker_env:
    HOME: /root
    MY_VAR: my_value

预期是 Hermes 使用 Docker terminal backend 时,把这些环境变量传进容器。

于是进入 Hermes 后运行:

env | grep -E "HOME|MY_VAR"

结果是:

变量没有按预期出现。

这很容易被误判成 Docker 权限问题、容器启动参数问题,甚至是 env 命令问题。

但 issue 给出的根因指向 Hermes 配置桥接层。


根因:env_mappings 少了一项

issue 指出,docker_env key 缺失于两个地方的 env_mappings 字典:

  • hermes_cli/cli.py
  • gateway/run.py

Hermes 的配置流大概是:

config.yaml -> env_mappings -> TERMINAL_DOCKER_ENV -> terminal_tool -> docker backend

但缺失 docker_env 映射后,链路变成:

config.yaml 里有 docker_env
          ↓
env_mappings 不认识 docker_env
          ↓
TERMINAL_DOCKER_ENV 没有被设置
          ↓
terminal_tool 读取默认空 dict
          ↓
Docker 容器启动时没有这些 env

关键代码表现为 terminal tool 读取:

"docker_env": _parse_env_var(
    "TERMINAL_DOCKER_ENV",
    "{}",
    json.loads,
    "valid JSON"
)

如果上游从来没有设置 TERMINAL_DOCKER_ENV,这里自然只会拿到默认值 {}

这就是为什么配置看起来存在,但运行时完全无效。


为什么 CLI 和 Gateway 都要修?

issue 特别提到两个文件都缺映射:

  • CLI 路径:hermes_cli/cli.py
  • Gateway 路径:gateway/run.py

这点很重要。

因为 Hermes 可能通过不同入口运行:

  • 本地 CLI 直接运行;
  • Slack / Discord / Telegram / WeChat 等 gateway 触发;
  • 后台服务启动;
  • 长任务中由消息平台触发 terminal tool。

如果只修 CLI,不修 Gateway,就会出现:

本地测试好了,消息平台里还是坏的。

如果只修 Gateway,不修 CLI,又会出现:

网关里好了,本地 hermes 命令还是坏的。

所以配置映射类 bug 的修复必须覆盖所有启动入口。


官方评论:这是旧问题的重复,修复 PR 已存在

评论里维护者指出:

Duplicate of #5722 — same root cause (docker_env missing from env_mappings). PR #19574 is the active fix.

也就是说,#20537 不是孤立 bug,而是同一根因的复现:

docker_env missing from env_mappings

这类问题通常不需要复杂推理,只需要把配置链路走一遍,就能定位断点。

但它对用户体验影响很大,因为表面上看不出哪里错。


修复方向:补上 docker_env -> TERMINAL_DOCKER_ENV

issue 给出的修复非常小:在两个 env_mappings 里加入:

"docker_env": "TERMINAL_DOCKER_ENV",

这样配置链路恢复为:

terminal.docker_env
  -> TERMINAL_DOCKER_ENV
  -> terminal_tool docker_env
  -> Docker env args
  -> container runtime environment

真正的 Docker 层其实已经有接收逻辑。

问题只是在进入 Docker 之前,配置没有被桥接过去。


怎么判断你是否踩到了这个坑?

如果你满足这些条件,就很像 #20537

  • Hermes terminal backend 使用 Docker;
  • ~/.hermes/config.yaml 里配置了 terminal.docker_env
  • Docker 容器里看不到对应变量;
  • CLI / Gateway 没有明显报错;
  • TERMINAL_DOCKER_ENV 环境变量没有被设置;
  • terminal tool 最终拿到的是 {}

可以按这个顺序查:

1. 确认配置确实存在

terminal:
  backend: docker
  docker_env:
    MY_VAR: my_value

2. 确认运行时是否有桥接变量

echo "$TERMINAL_DOCKER_ENV"

如果为空,说明还没进 terminal tool。

3. 在容器里确认变量

env | grep MY_VAR

如果 runtime env 为空,而配置又存在,就要怀疑 env_mappings

4. 区分 CLI 和 Gateway

本地 CLI 测一次,消息平台 gateway 再测一次。

如果两个入口表现不同,说明很可能其中一条启动路径没有同步修复。


这个问题为什么适合做配置系统复盘?

因为它展示了 Agent 框架里常见的“三段式配置断链”:

用户配置层 -> 进程环境层 -> 工具执行层

任何一段少了映射,最终现象都会像“工具没读配置”。

但根因不一定在工具本身。

#20537 里:

  • 用户配置层有 docker_env
  • 工具执行层会读 TERMINAL_DOCKER_ENV
  • Docker 层也能构造 env args
  • 唯独中间映射层断了

这类问题对 Agent 工具链尤其常见,因为一个工具可能同时被 CLI、Gateway、subagent、cronjob、消息平台入口调用。


和 DeepAI API 中转站的关系

这个问题和 DeepAI API 中转站没有直接关系。

DeepAI API 中转站适合解决模型 API 入口问题,例如在支持 OpenAI-compatible API 的工具里统一管理模型调用。

但 Docker terminal backend 的 docker_env 是否能传入容器,是 Hermes 内部配置映射和工具运行时问题。

不要把模型 API、Docker 环境变量、终端后端混在一起排查。

更准确的边界是:

DeepAI 负责模型接口入口;Hermes 负责 terminal/docker 配置链路。

如果你在 Cherry Studio、Cline、Dify、Open WebUI 这类支持 OpenAI-compatible API 的工具中接入 DeepAI,可以关注模型 URL、API key、模型名是否正确。

但如果你在 Hermes Docker backend 里传不进环境变量,就应该查 Hermes 的 env_mappingsTERMINAL_DOCKER_ENV


FAQ

为什么 config.yaml 里写了 docker_env,容器里还是没有?

因为 docker_env 没有被映射到 TERMINAL_DOCKER_ENV,terminal tool 最终读取默认 {}

这是 Docker 的问题吗?

不是。Docker 层有接收 env args 的逻辑,问题发生在配置到环境变量的桥接阶段。

为什么 CLI 和 Gateway 都要改?

Hermes 有不同启动入口。如果只修一个入口,另一个入口仍可能不传 docker_env

临时 workaround 是什么?

可以手动设置 TERMINAL_DOCKER_ENV 为合法 JSON,但更稳的方式是升级到包含修复的版本或补上 env_mappings

DeepAI 能解决这个问题吗?

不能。这是 Hermes Docker terminal backend 的配置映射问题,不是模型 API 问题。


总结

#20537 的结论很简单:

配置写进 YAML,不代表已经进入运行时。

Hermes 的 docker_env 问题不是 Docker 不接收变量,而是 env_mappings 没有把 docker_env 转成 TERMINAL_DOCKER_ENV

对 Agent 框架来说,配置系统最怕的就是这种“前端有字段、后端有读取,中间没有桥”的断链。

用户看到的是变量没进容器,工程上真正要修的是配置映射表。

Related Post

Ollama 本地模型记不住上一轮?Hermes Agent num_ctx 与 2048 上下文截断排错指南Ollama 本地模型记不住上一轮?Hermes Agent num_ctx 与 2048 上下文截断排错指南

Hermes Agent 接入 Ollama 后同一会话记不住上一轮?这可能不是 memory tool 坏了,而是 Ollama num_ctx 回落到 2048 导致历史被服务端静默截断。本文解释 context_length、ollama_num_ctx、/api/show 探测失败和 PR #19613 的修复方向。

日志里写着 systemd,机器却是 macOS:Hermes shutdown forensics 被 launchd 带偏的细节日志里写着 systemd,机器却是 macOS:Hermes shutdown forensics 被 launchd 带偏的细节

macOS 上 Hermes Gateway 由 launchd 管理,但 shutdown forensics 却记录 under_systemd=yes?本文复盘 #25510:ppid==1 不能跨平台等同于 systemd,排障日志也要尊重 launchd、systemd、Scheduled Task 的平台语义。

Agent 排障时一条 pkill 把自己杀了:Hermes Gateway 自终止为什么需要危险命令拦截Agent 排障时一条 pkill 把自己杀了:Hermes Gateway 自终止为什么需要危险命令拦截

Hermes Gateway Agent 误判自己没运行后执行 pkill -f "cli.py --gateway",结果把承载自己的 Gateway 进程杀掉。本文复盘 #3397:为什么 kill/pkill/killall 命中 hermes/gateway/cli.py 必须进入审批流。