DeepAI Paper Hermes Agent 教程,Hermes 模型与 Provider API,Hermes 记忆、技能与辅助任务 Hermes Agent 辅助任务报 401?provider:auto、base_url 与空 api_key 排错指南

Hermes Agent 辅助任务报 401?provider:auto、base_url 与空 api_key 排错指南

如果你在 Hermes Agent 里主模型调用正常,但启动新会话时看到类似提示:

Auxiliary title generation failed: HTTP 401: Missing Authentication header

或者日志里出现:

Auxiliary title_generation: using custom (...)

明明你已经设置了 OPENROUTER_API_KEY,主对话也能走 OpenRouter / OpenAI-compatible endpoint,为什么偏偏标题生成、摘要、辅助任务会 401?

这类问题很可能不是 API Key 真的没配置,而是 auxiliary.<task> 配置里同时写了 provider: autoprovider: openrouter,又写了 base_url,但 api_key 为空,导致 Hermes Agent 把这个辅助任务误判成 custom provider,并跳过了环境变量里的 provider credential lookup。

这篇文章基于 NousResearch/hermes-agent issue #16829,整理一个面向搜索和实战排错的配置问题:

auxiliary.{task} with provider:auto + base_url set falls into custom path with empty api_key, returns 401

适合搜索关键词:Hermes Agent Auxiliary title generation failed 401Missing Authentication header Hermes Agentprovider auto base_url api_key emptyHermes auxiliary custom api_key NoneOpenRouter 401 Missing Authentication header Hermes


先给结论:主模型能用,不代表 auxiliary 也继承了同一套凭证

这个问题的关键不是“OpenRouter 不可用”,也不是“模型名写错”,而是 Hermes Agent 的辅助任务解析逻辑曾经可能走到这条路径:

if cfg_base_url:
    return "custom", resolved_model, cfg_base_url, cfg_api_key, resolved_api_mode

只要 base_url 存在,它就直接返回 provider="custom"

如果此时你的 YAML 里是:

auxiliary:
  title_generation:
    provider: auto
    model: minimax/minimax-m2.7
    base_url: https://openrouter.ai/api/v1
    api_key: ''

那就会变成:

provider = custom
api_key = None / empty

下游 OpenAI-compatible client 发请求时没有 Authorization header,于是上游返回:

401 Missing Authentication header

用户最容易误判的地方在于:环境变量里明明有 OPENROUTER_API_KEY,主模型也能用。但 auxiliary 任务已经被锁进 custom 分支,未必再走 OpenRouter 的环境变量解析链路。


典型报错现象

你可能会看到下面几类提示:

Auxiliary title generation failed: HTTP 401: Missing Authentication header
API call failed after 3 retries: 401 Missing Authentication header
Auxiliary title_generation: using custom (...)
provider=custom api_key=None

如果日志里显示 auxiliary 使用的是 custom,但你本来期望它使用 openrouterauto,就非常符合这个问题。


为什么只影响 auxiliary,不影响主对话?

Hermes Agent 里主模型和辅助任务可能不是完全同一条配置解析路径。

主模型通常会根据:

  • provider
  • model
  • provider 专用 API Key 环境变量
  • 全局配置
  • OpenAI-compatible endpoint

来选择 client。

auxiliary.title_generationauxiliary.summarization 等任务可以有自己的 per-task override。issue #16829 指出的就是:在 _resolve_task_provider_model() 里,只要任务级配置有 base_url,就优先进入了 custom 分支。

这导致一个很微妙的差异:

场景可能结果
主模型 provider=openrouter,环境变量有 key正常
auxiliary provider=auto/openrouter,没有 base_url可能正常走 provider lookup
auxiliary provider=auto/openrouter,有 base_url,但 api_key 为空可能误走 custom,401

所以看到 401 时,不要只检查全局 API Key,还要检查 auxiliary block 里是否写了空 api_keybase_url


最常见的错误配置

下面这种配置看起来很自然,但正是风险点:

auxiliary:
  title_generation:
    provider: openrouter
    model: minimax/minimax-m2.7
    base_url: https://openrouter.ai/api/v1
    api_key: ''
    timeout: 30
    extra_body: {}

很多用户的直觉是:

  • provider: openrouter 告诉 Hermes 用 OpenRouter;
  • base_url 只是补充 endpoint;
  • api_key: '' 表示从环境变量 OPENROUTER_API_KEY 读取。

但在问题版本里,base_url 的优先级更高,导致它不再按 OpenRouter provider 处理,而是按 custom 处理。


立即可用 workaround:删掉 auxiliary 里的 base_url 和空 api_key

如果你希望 auxiliary 任务和主 provider 一样走自动识别,可以先把任务级的 base_url 和空 api_key 删除。

例如改成:

auxiliary:
  title_generation:
    provider: auto
    model: minimax/minimax-m2.7
    timeout: 30
    extra_body: {}

然后确认环境变量存在:

export OPENROUTER_API_KEY="sk-or-..."

重启 Hermes gateway / agent 后,再看日志是否从:

Auxiliary title_generation: using custom (...)

变成:

Auxiliary title_generation: using auto (...)

如果 401 消失,就基本坐实是 auxiliary provider resolution 的问题。


什么时候应该保留 base_url?

不是说 base_url 永远不能写。

如果你真的要让某个 auxiliary task 使用一个自定义 OpenAI-compatible endpoint,而且不想走 provider 自动识别,那么应该同时明确提供 api_key

auxiliary:
  title_generation:
    provider: custom
    model: your-model-name
    base_url: https://your-endpoint.example.com/v1
    api_key: ${YOUR_CUSTOM_API_KEY}

核心区别是:

  • base_url + api_key:明确 custom endpoint;
  • provider:auto/openrouter + base_url + 空 api_key:容易造成歧义;
  • provider:auto/openrouter + 无 base_url + 环境变量:更适合走 provider credential lookup。

修复方向:只有 base_url 和 api_key 都存在时才走 custom

issue 和相关 PR #16950 指向的修复思路很直接:

if cfg_base_url and cfg_api_key:
    return "custom", resolved_model, cfg_base_url, cfg_api_key, resolved_api_mode

也就是说,只有当用户同时显式配置了 base_urlapi_key,才把它当作 custom provider。

如果有 base_url 但没有 api_key,则应继续走:

  • 显式 provider,例如 openrouter
  • provider: auto 的自动识别;
  • 再从环境变量中读取 OPENROUTER_API_KEY 等 provider 专用 key。

需要注意的是,GitHub 上 #16829 已 closed/completed,评论中也写到 “Fixed in #16950”;但 PR API 显示 #16950merged_atnull。因此排错时建议你以当前安装版本的实际代码和日志为准:

  • 升级到较新的 Hermes Agent;
  • 检查 _resolve_task_provider_model() 是否仍是 if cfg_base_url:
  • 如果仍旧如此,先用配置 workaround;
  • 如果已变成 if cfg_base_url and cfg_api_key:,再排查其他 401 原因。

和 DeepAI API 中转站怎么配合?

这个问题和 DeepAI API 中转站的关系要说清楚:它不是 DeepAI 或 OpenAI-compatible 网关本身导致的,而是客户端 auxiliary 配置解析的问题。

如果你的工具支持 OpenAI Compatible API,DeepAI API 中转站可以帮助你统一:

  • Base URL;
  • API Key;
  • 模型列表;
  • 团队配置;
  • Cherry Studio、Cline、Dify、Open WebUI 等工具里的多模型接入。

但如果 Hermes Agent 的某个辅助任务把 provider:auto + base_url + 空 api_key 解析成 custom + api_key=None,中转站也无法替客户端补上已经被跳过的 Authorization header。

更稳的配置思路是:

auxiliary:
  title_generation:
    provider: auto
    model: your-model
    timeout: 30
    extra_body: {}

然后在支持 OpenAI-compatible 的工具或主配置中统一设置 DeepAI 的 Base URL 和 Key。对于 Hermes auxiliary 这种 per-task override,尽量避免“写了 base_url 但 api_key 为空”的半自定义状态。


排错清单

遇到 Auxiliary title generation failed: HTTP 401 时,可以按这个顺序查:

1. 确认主模型是否正常; 2. 打开 ~/.hermes/config.yaml; 3. 找到 auxiliary.title_generation 或其他 auxiliary.<task>; 4. 检查是否同时有 provider: auto/openrouterbase_urlapi_key: ''; 5. 查看日志里 auxiliary 是否显示 using custom; 6. 临时删除 auxiliary block 里的 base_url 和空 api_key; 7. 重启 gateway / agent; 8. 确认环境变量如 OPENROUTER_API_KEY 对 gateway 进程可见; 9. 再次观察是否仍然 401; 10. 如果仍然失败,再检查模型名、额度、endpoint path、provider 是否支持该模型。


401、404 和 provider 配置问题怎么区分?

很多 OpenAI-compatible 配置问题都会表现成 HTTP 错误,但含义不同:

错误常见含义优先检查
401 Missing Authentication header请求没带 Authorizationapi_key 是否为空、是否走错 custom path
401 Invalid API key带了 key,但 key 不对key 是否过期、前缀是否正确、环境变量是否污染
404 Not Foundendpoint path 或模型路径错误base_url 是否多/少了 /v1,api_mode 是否匹配
400 Bad Requestpayload 或模型协议不兼容messages、tools、reasoning/thinking 字段

#16829 这一类问题属于第一种:请求根本没有正确带上认证头。


FAQ

为什么我设置了 OPENROUTER_API_KEY,还是 401?

因为 auxiliary task 可能被 base_url 锁进了 custom provider 分支,导致它没有继续走 OpenRouter 的环境变量读取逻辑。

api_key: '' 不就是表示从环境变量读取吗?

很多人会这么理解,但具体取决于客户端实现。这个 issue 里,空 api_key 搭配 base_url 会导致 custom client 没有 Authorization header。

删除 auxiliary 里的 base_url 会不会影响主模型?

通常不会。你删除的是 auxiliary.<task> 的 per-task override,让它回到 provider auto-detection 或全局 provider 路径。

如果我必须使用自定义中转站怎么办?

那就不要半配置。明确写 provider: custombase_url 和非空 api_key,并确认该 endpoint 是 OpenAI-compatible。

DeepAI API 中转站能解决这个 401 吗?

DeepAI 可以提供统一的 OpenAI-compatible Base URL 和 Key,但不能修复客户端把 auxiliary task 解析成 custom + api_key=None 的问题。你仍然需要修正 Hermes 配置或升级到修复版本。


总结

Hermes Agent auxiliary 任务报 401 Missing Authentication header,尤其是 title_generation 失败时,不要只盯着全局 API Key。

如果你的配置里同时出现:

provider: auto
base_url: https://...
api_key: ''

就要怀疑 auxiliary 被误判成 custom provider,并且没有带 Authorization header。

最稳的临时修复是:删除 auxiliary task 里的 base_url 和空 api_key,让它回到 provider 自动识别;如果你确实要自定义 endpoint,就同时显式提供非空 api_key

一句话总结:provider:auto 负责自动识别,custom 负责显式 endpoint;不要把 base_url 写成 custom,但把 api_key 留空。

Related Post

/reload-mcp 一按就卡死:Hermes CLI 为什么会在确认框里等不到回车?/reload-mcp 一按就卡死:Hermes CLI 为什么会在确认框里等不到回车?

Hermes CLI 执行 /reload-mcp 后确认框显示出来,却无法输入 1/2/3,SSH 会话像被冻住。本文客观复盘 #23853:prompt_toolkit raw mode、daemon thread 中的 input() fallback、 / 行结束符错位、TUI slash worker pipe 死锁,以及 prompt_toolkit-native modal 的修复方向。

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

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

让 Hermes 别回复却收到 Codex incomplete?空响应被重试 3 次的原因让 Hermes 别回复却收到 Codex incomplete?空响应被重试 3 次的原因

Hermes openai-codex 路径中,用户要求机器人不回复时,completed empty final answer 曾被归一化成 incomplete 并重试 3 次。本文解释空响应不等于未完成、finish_reason 误判、continuation loop 和群聊机器人“沉默成功”的重要性。