DeepAI Paper Hermes Agent 教程,Hermes 模型与 Provider API 钥匙明明在 .env,Hermes 却说找不到:credential_pool 只摸口袋不看保险箱

钥匙明明在 .env,Hermes 却说找不到:credential_pool 只摸口袋不看保险箱

认证问题最容易让人怀疑自己:API Key 写错了吗?provider 名填错了吗?环境变量没生效吗?

NousResearch/hermes-agent issue #15932 讲的是一个更隐蔽的问题:用户把 API key 放进了 ~/.hermes/.env,但 Hermes 的 credential pool 初始化路径只看 os.environ,没有读取 Hermes 自己的 .env 文件。

结果就是:

key 明明在 ~/.hermes/.env 里,Hermes 却报 No API key found。

这类问题对 OpenAI-compatible provider、第三方模型中转站、多 provider 配置都很致命,因为认证链路断了,后面的模型调用根本不会开始。


现象:.env 里有 key,启动时却说没有

复现路径很清楚。

先确保 shell 环境里没有 API key:

unset OPENAI_API_KEY

然后把 key 写进 Hermes 的配置文件:

# ~/.hermes/.env
OPENAI_API_KEY=sk-...

再启动一个需要 API key 的 provider。

预期是 Hermes 能从 ~/.hermes/.env 里读到 key。

实际却是:

No API key found

这说明 Hermes 的某条认证读取路径只查了进程环境变量,没有查 Hermes 自己的 .env 配置源。


根因一:credential_pool._seed_from_env() 只看 os.environ

issue 指出第一个问题在:

credential_pool._seed_from_env()

它只检查:

os.environ

但没有通过 Hermes config 层读取:

hermes_cli.config.get_env_value()

这会造成一个很反直觉的状态:

Hermes 官方/约定位置 ~/.hermes/.env 里有 key
但 credential pool 初始化时看不见

也就是说,key 不是没写,而是认证系统看错了地方。


根因二:_resolve_api_key_provider_secret() 没有回退到 credential pool

issue 还指出第二个问题:

hermes_cli/auth.py:_resolve_api_key_provider_secret()

当环境变量里找不到 key 时,它没有 fallback 到:

credential_pool.load_pool()

这会让认证链路缺少第二道兜底。

一个更健壮的查找顺序应该类似:

显式配置 / provider secret
    ↓
os.environ
    ↓
~/.hermes/.env via get_env_value()
    ↓
credential_pool.load_pool()

而不是只摸 os.environ 这个“口袋”。

如果 key 被用户放在 Hermes 的“保险箱”里,认证系统也应该去那里找。


为什么这个问题会影响 OpenAI-compatible 场景?

很多 provider 都用 API key auth。

例如:

  • OpenAI 官方;
  • OpenAI-compatible 中转站;
  • 自建 NewAPI / OneAPI;
  • DeepAI API 中转站;
  • 其他兼容 Chat Completions / Responses API 的服务。

这些场景经常会通过 .env 管理:

OPENAI_API_KEY=...
OPENAI_BASE_URL=...
OPENAI_MODEL=...

如果 Hermes 某条认证路径只看 shell env,不看 ~/.hermes/.env,用户就会看到:

我明明填了 key,为什么还说没有?

这类问题很容易被误判成:

  • API key 无效;
  • provider 不支持;
  • base URL 写错;
  • 模型名不可用;
  • DeepAI 或其他中转站有问题。

但在 #15932 里,真正原因是 Hermes 内部 credential resolution 的读取源不完整。


官方评论:这是 #15914 的重复,修复在 #16101

维护者评论指出:

Likely duplicate of #15914 — same root cause:
_resolve_api_key_provider_secret() only reads os.environ, not credential_pool.
Fix PR at #15920.

后续又确认:

Fixed in #16101 (salvage of #15920)

并明确说两个点都修了:

1. _seed_from_env() 使用 get_env_value(),可以检查 ~/.hermes/.env; 2. _resolve_api_key_provider_secret() 在 env var 为空时 fallback 到 credential_pool.load_pool()

这说明问题不是用户配置习惯错,而是认证查找链路确实缺了两段。


用户排查时应该怎么确认?

如果你遇到类似问题,可以按下面顺序排查。

1. 确认 shell 环境和 Hermes .env 的区别

先看 shell:

echo "$OPENAI_API_KEY"

再看 Hermes 文件:

grep OPENAI_API_KEY ~/.hermes/.env

如果 shell 为空、.env 有值,而 Hermes 报 no key,就要怀疑读取路径。

2. 确认 provider 是否真的需要这个变量名

不同 provider 可能使用不同 key 名:

OPENAI_API_KEY
ANTHROPIC_API_KEY
GOOGLE_API_KEY
DEEPAI_API_KEY

如果 provider 期望 OPENAI_API_KEY,你却写成别的名字,也会报错。

#15932 的重点是:变量名正确时,~/.hermes/.env 仍可能没被读。

3. 检查 Hermes 版本是否包含 #16101

如果你使用旧版本,优先升级到包含 #16101 的版本。

否则临时 workaround 是把 key export 到 shell 环境:

export OPENAI_API_KEY=sk-...

但这只是绕过 .env 读取问题,不是根治。

4. 检查 credential pool 是否被正确加载

如果你使用的是 credential pool,而不是直接 env var,确认认证解析函数是否会 fallback 到:

credential_pool.load_pool()

旧版本可能不会。


这类 bug 的工程教训

认证系统最怕多个“真相来源”:

shell env
~/.hermes/.env
config.yaml
credential pool
provider secret

如果每条代码路径只看其中一部分,用户就会遇到“这里能用,那里不能用”的割裂。

一个成熟的 Agent 框架应该做到:

  • 认证查找顺序明确;
  • 每个来源的优先级清楚;
  • 报错时告诉用户查了哪些地方;
  • 不要只说 No API key found,而要说“哪个 provider、哪个变量名、查了哪些来源”。

比如更好的错误信息应该类似:

No API key found for provider=openai.
Checked: os.environ[OPENAI_API_KEY], ~/.hermes/.env, credential_pool.

这比单纯一句 no key 有用得多。


和 DeepAI API 中转站的关系

如果你用 DeepAI API 中转站作为 OpenAI-compatible API 入口,通常会配置:

OPENAI_API_KEY=你的 DeepAI key
OPENAI_BASE_URL=https://api.deepai.wang/v1

或者在工具里填写对应的 base URL、API key 和模型名。

但如果 Hermes 的认证路径没有读取 ~/.hermes/.env,即使 key 是正确的,也可能报:

No API key found

所以这里要区分两类问题:

DeepAI key 无效 / base URL 错误

和:

Hermes 没从正确位置读取 key

#15932 属于后者。

DeepAI 可以提供 OpenAI-compatible 模型入口,但不能替 Hermes 修复 credential pool 的读取逻辑。正确做法是升级 Hermes 或修复认证读取链路。


FAQ

为什么 ~/.hermes/.env 里有 API key,Hermes 还说找不到?

旧版本中 credential_pool._seed_from_env() 只检查 os.environ,没有读取 ~/.hermes/.env

这是不是 API key 错了?

不一定。先确认 Hermes 是否真的读取到了 key。如果 shell env 为空、.env 有值,而旧 Hermes 只看 shell env,就会误报 no key。

临时解决办法是什么?

把 key export 到 shell 环境,例如:

export OPENAI_API_KEY=sk-...

但更推荐升级到包含 #16101 修复的版本。

修复点是什么?

_seed_from_env() 改为使用 get_env_value() 检查 ~/.hermes/.env_resolve_api_key_provider_secret() 在 env var 为空时 fallback 到 credential_pool.load_pool()

DeepAI 能解决这个问题吗?

不能。这是 Hermes 认证读取链路问题。DeepAI 只负责 OpenAI-compatible API 服务入口,不负责 Hermes 如何读取本地 API key。


总结

#15932 的核心教训是:

API key 存在,不代表认证系统看得到。

Hermes 旧版本里,credential pool 的初始化只看 os.environ,而没有读取 ~/.hermes/.env;认证解析函数也没有在 env var 为空时回退到 credential pool。

所以用户看到的是 No API key found,工程上真正缺的是完整的 credential resolution chain。

对 Agent 产品来说,认证不是只要“支持 env var”就够了。只要你提供了 .env、credential pool、config.yaml,多来源查找就必须一致,否则用户迟早会被“明明填了 key 却说没有”折磨。

Related Post

一个工具会失败,两个工具反而可能成功:Hermes Memory 调度路径的反直觉 bug一个工具会失败,两个工具反而可能成功:Hermes Memory 调度路径的反直觉 bug

Hermes Honcho memory tools 在单工具调用时返回 Unknown tool,但多工具并发路径有时正常。本文复盘 #15118:schema 已注入不代表执行层会路由成功,sequential dispatch 漏掉 MemoryManager.has_tool() 才是真正根因。

Hermes Agent 报 No module named agent.transports?pip / Nix 源码安装缺包排错指南Hermes Agent 报 No module named agent.transports?pip / Nix 源码安装缺包排错指南

Hermes Agent 源码安装后报 ModuleNotFoundError: No module named agent.transports?这通常不是 Anthropic API Key 或模型名问题,而是 setuptools include 缺少 agent.*,导致 pip / Nix 安装产物漏掉 agent/transports 子包。

GPT-5 模型报 unsupported_api_for_model?Hermes Agent 自动切换 Responses API 的排错指南GPT-5 模型报 unsupported_api_for_model?Hermes Agent 自动切换 Responses API 的排错指南

Hermes Agent 使用 GPT-5.4、Copilot 或 OpenRouter 时,如果请求漂移到 /chat/completions 并报 unsupported_api_for_model,核心往往不是模型不可用,而是 GPT-5.x 必须走 Responses API / codex_responses。本文解释 provider fallback、api_mode、gateway 缓存和 OpenAI-compatible API 的正确排查顺序。