有些配置问题最折磨人:你看着 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.pygateway/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_mappings 和 TERMINAL_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 框架来说,配置系统最怕的就是这种“前端有字段、后端有读取,中间没有桥”的断链。
用户看到的是变量没进容器,工程上真正要修的是配置映射表。