很多人用 Hermes Agent,折腾到最后不是败给模型,而是败给配置文件。明明已经改了 provider、填了 key、做了 OAuth,结果一跑还是旧模型、旧路由、旧报错。问题往往不在"你没改",而在于 你改的文件不对、改的层级不对,或者改的是当前实例根本没在读的那一份状态目录。
Hermes 官方文档把默认状态目录定义在 ~/.hermes/,其中最核心的三份文件就是 config.yaml、.env 和 auth.json。
先说结论。你可以把 Hermes 的配置体系理解成三层:config.yaml 管"非敏感设置",.env 管"密钥和环境变量",auth.json 管"OAuth 凭据和认证状态"。再往上还有一层更狠的东西,就是 命令行参数,它的优先级比前面三者都高。也就是说,你在文件里改对了,也可能被启动命令当场覆盖掉。
一、config.yaml 到底管什么
config.yaml 是 Hermes 的主配置文件,官方把它定义为"所有非 secret 设置的主文件"。模型、provider、终端后端、压缩策略、内存限制、toolsets、provider routing、skills 配置,基本都归它管。hermes config edit 打开的就是这份文件,hermes config set 在写入非敏感键时,默认也会落到这里。
这份文件最容易让人误会的点,是它不只是"静态偏好",而是 Hermes 的主运行配置源。官方明确写了优先级顺序:CLI 参数第一,config.yaml 第二,.env 第三,最后才是内建默认值。也就是说,只要某个非敏感设置同时存在于 config.yaml 和 .env,Hermes 会优先采用 config.yaml。所以你在 .env 里偷偷塞一个 model.provider=... 的思路,本来就不稳,容易被 config.yaml 直接压过去。
config.yaml 还有一个很实用但也很容易误伤你的能力,就是支持 ${VAR_NAME} 形式的环境变量替换。比如你可以在 auxiliary.vision.api_key 里引用 ${GOOGLE_API_KEY}。但注意,Hermes 只支持 ${VAR} 这种写法,不支持裸 $VAR;更重要的是,如果变量没定义,那个占位符会原样保留,不会自动报错帮你兜底。于是你表面上"写上了",实际上运行时还是空壳。
二、.env 到底管什么
.env 的职责很单纯,也最不该乱用:它主要放 API key、token、密码、bot token 之类的敏感信息。官方文档写得非常直白,Secrets 放 .env,其他东西放 config.yaml。hermes config set OPENROUTER_API_KEY ... 这一类命令,也会自动把值写进 .env,而不是 config.yaml。
Hermes 的很多 provider 都是这样接入的。OpenRouter 用 OPENROUTER_API_KEY,AI Gateway 用 AI_GATEWAY_API_KEY,GLM 用 GLM_API_KEY,Kimi 用 KIMI_API_KEY,这些都属于 .env 管辖范围。工具侧也是一样,像 API Server、Home Assistant、Tool Gateway 的若干环境变量,官方都要求通过 .env 提供。
但 .env 最容易把人坑到怀疑人生的地方,是 它不是万金油总开关。例如你为某个工具已经写好了直连 API key,如果 config.yaml 里给那个工具设了 use_gateway: true,Hermes 运行时会优先走 Nous Tool Gateway,直接跳过 .env 里的直连 key。官方文档把这条优先级写得非常明确:use_gateway: true 时,即使 .env 里已有 direct key,运行时仍会走 gateway。
还有一个高频误判是:你以为自己切到了 Codex、Nous 或本地 custom endpoint,结果某些辅助任务还是在偷偷走 OpenRouter。这个不是幻觉。Hermes 官方 provider 文档明确说明,即便主模型已经换成 Nous Portal、Codex 或 custom endpoint,某些工具任务,比如 vision、网页摘要、MoA,默认仍可能使用单独的 auxiliary model,而这一链路默认可由 OPENROUTER_API_KEY 激活。你改了主模型,却没改辅助模型,当然会出现"怎么还有旧 provider 的痕迹"这种诡异现象。
三、auth.json 到底管什么
auth.json 不是给普通 API key 准备的,它主要负责 OAuth 型 provider 的凭据和认证状态。官方配置文档把它定义为 "OAuth provider credentials",比如 Nous Portal、Codex 这类登录式接入,凭据就存在这里。AI Providers 文档还特别说明,OpenAI Codex 通过 device code OAuth 登录后,Hermes 会把得到的凭据存到 ~/.hermes/auth.json,并且在存在 ~/.codex/auth.json 时还能尝试导入已有 Codex CLI 凭据。
Tool Gateway 也和 auth.json 强相关。官方文档明确写到,当工具启用 use_gateway: true 时,gateway 认证使用的是你通过 hermes model 获取的 Nous Portal 凭据,这些凭据就保存在 ~/.hermes/auth.json。所以你看到 web、image、tts 明明没用 .env 里的 key,却还能跑,别奇怪,它们可能根本就是拿 auth.json 里的 OAuth 身份在工作。
如果你想再看深一点,近期公开 issue 已经暴露出 auth.json 的内部结构至少包含 version、providers、active_provider、updated_at、credential_pool 这些顶层键。也正因为某段逻辑一度读错了这个结构,才会出现"OAuth 凭据明明已经写进 auth.json,但 provider picker 里就是不显示"的问题。这个锅不是你不会配,是软件近期确实出过坑。
四、为什么你明明改了,却还是不生效
第一种:CLI 参数覆盖
最常见,也最蠢,但命中率最高:CLI 参数把文件配置覆盖了。只要你是用 hermes chat --model ...、--provider ...、-p ... 之类的方式启动,命令行就是最高优先级。你回头改 config.yaml,当然像没改一样。
第二种:hermes model vs /model 混淆
把 hermes model 和会话内的 /model 搞混了。官方文档说得很清楚,hermes model 是完整的 provider 配置向导,可以新增 provider、跑 OAuth、填 API key、配置 endpoint;而 /model 只能在已有配置之间切换,不能新增 provider,也不能触发 OAuth。你在聊天里敲 /model 期待它替你补齐认证流程,本来就是在难为软件。
第三种:profile 目录搞混
你改的是默认 profile,跑的却不是默认 profile。Hermes 的 profile 机制会给每个 profile 单独分配自己的状态目录,里面各自有独立的 config.yaml、.env、memory、sessions 和 gateway 状态;从架构文档看,每个 profile 本质上都有自己独立的 HERMES_HOME。所以你在 ~/.hermes/.env 里改了 key,但实际跑的是 hermes -p coder,那它根本读的是另一个 profile 目录。
第四种:gateway 绑定错目录
gateway 或服务进程还绑定着另一个状态目录。官方 Messaging 文档明确写到,不同 HERMES_HOME 目录对应不同的 gateway service 名称,hermes gateway 命令会自动面向当前 HERMES_HOME 的服务。换句话说,你在终端里改了一个目录,后台跑着的可能还是另一个目录对应的 gateway。你改得很认真,服务读得很冷漠。
第五种:旧 key 和自动检测
旧 key 或自动检测逻辑把你的 custom endpoint 又拽回去了。近期公开 issue 已经记录了一个很典型的问题:用户明明把 provider 配成了 custom endpoint,本地模型也设置好了,但 Hermes 仍然可能因为旧的 API key 和 provider auto-detection,把请求重新路由到 OpenRouter,甚至把辅助任务也一起带偏。这个问题不是你一个人撞上,公开 issue 已经把它写明白了。
第六种:auth.json 显示 bug
你以为 auth.json 里的 OAuth 没生效,实际上只是 /model 没把它显示出来。近期 issue 显示,Nous Portal、OpenAI Codex、Copilot 等 OAuth provider 曾出现过"凭据已经正确存入 auth.json,但 gateway 的 /model picker 里完全不显示"的 bug,而且还是静默失败。这种情况下,别因为 picker 空了就立刻删认证,先用 hermes auth list 和 hermes status 去核实实际状态。
五、最稳的修改方式,不要再手工乱抠三份文件
如果你想尽量避免"改了却不生效",官方推荐的路径其实很明确。
非敏感设置用:
hermes config set <KEY> <VALUE>
hermes config check
hermes config
敏感信息和认证流程优先用:
hermes model
hermes auth
hermes auth list
这些命令不是装样子,它们最大的价值就是自动把值写到正确文件,并尽量避开你手工改错层级。官方文档已经明确说明,hermes config set 会自动把 API key 写进 .env,其他设置写进 config.yaml;hermes model 则负责 provider/model 选择、OAuth、API key 和 endpoint 配置。
如果你已经用了 profile,再补一条铁律:所有排查命令都在同一个 profile 下执行。例如:
hermes -p coder config
hermes -p coder auth list
hermes -p coder status
别一边改默认 profile,一边让 coder gateway 在另一个状态目录里继续跑。那不是排障,那是在给自己制造平行宇宙。
结语
Hermes 的三份核心配置文件,其实分工并不复杂。config.yaml 管设置,.env 管密钥,auth.json 管 OAuth。真正让人觉得复杂的,从来不是文件数量,而是优先级、profile、gateway、辅助模型和自动路由这些东西叠在一起后,表面像是"配置没生效",本质却是"另一个更高优先级的来源在生效"。
所以以后再遇到"我明明改了,为什么还是老样子",先别急着删文件重装。你先问自己四句:
- 我改的是不是当前 profile?
- 是不是被 CLI 覆盖了?
- 是不是 gateway 抢路由了?
- 是不是 OAuth 根本存进了 auth.json 而不是 .env?
这四句问明白,很多 Hermes 的配置问题都会瞬间从玄学变成体力活。
问题求助
没能解决你的问题?直接问我
如果你遇到任何技术问题无法解决,可以在这里提交求助。我会尽快查看并回复你。
支持作者
如果这篇文章帮到了你,可以支持我
扫码打赏,支持我持续更新原创排障文章。

