有一种 Hermes Agent 报错很容易被误判成“API Key 错了”或“OpenRouter / NVIDIA 端点不可用”:
⚠️ API call failed (attempt 1/3): BadRequestError
Error code: 400
Non-retryable client error detected. Aborting immediately.
更迷惑的是,用户会发现:换 OpenRouter 模型不行,换 NVIDIA 模型也不行,Hermes CLI 能启动,但 hermes chat -q "Hello" 一发请求就失败。
这篇文章基于 NousResearch/hermes-agent issue #1083,讲清楚一个细节:Hermes 曾经把 reasoning 参数无条件塞进 OpenRouter 请求的 extra_body,而 MiniMax、NVIDIA 等不支持 reasoning 扩展的上游会把这个未知字段拒绝掉,返回 HTTP 400。
现场:看起来像“所有模型都不能用”
issue 里的用户环境大致是:
hermes model
显示:
Current model: glm5
Active provider: Custom endpoint
Default model set to: minimax/minimax-m2.5 (via OpenRouter)
然后执行:
hermes chat -q "Hello"
结果:
⚠️ API call failed (attempt 1/3): BadRequestError
⏱️ Time elapsed before failure: 0.28s
📝 Error: Error code: 400
📊 Request context: 2 messages, ~2,718 tokens, 31 tools
🧾 Request debug dump written to: /home/u/.hermes/sessions/request_dump_....json
❌ Non-retryable client error detected. Aborting immediately.
💡 This type of error won't be fixed by retrying.
这类错误的第一反应往往是:
- OpenRouter Key 不对?
- NVIDIA API Key 不对?
- Base URL 写错?
- 模型 ID 错了?
- WSL 网络问题?
但 #1083 的关键不在认证,而在请求体。
关键线索:BadRequestError 400 不是 401
先区分错误类型。
如果是 API Key 错误,通常会看到:
401 Unauthorized
403 Forbidden
Missing Authentication header
Invalid API key
但这里是:
BadRequestError
Error code: 400
HTTP 400 代表服务端认为请求格式或参数不对。也就是说,Hermes 发出去的 JSON body 里,可能有上游不接受的字段。
Hermes 的错误输出里给了一个非常重要的路径:
Request debug dump written to: ~/.hermes/sessions/request_dump_....json
遇到 400,不要只盯着 Key;要打开 request dump,看真实发出的 body。
根因:reasoning extra_body 被发给不支持的模型
issue 评论给出的根因很明确:
_build_api_kwargs unconditionally sends reasoning in extra_body to all OpenRouter requests.
OpenRouter forwards this to the upstream provider, and models that don't implement the reasoning extension reject it with 400.
翻译成人话:
1. Hermes 构造 API 请求时,在 extra_body 里加了 reasoning; 2. 这个参数通过 OpenRouter 转发给后面的真实模型供应商; 3. 但不是所有模型都支持 OpenRouter 的 reasoning 扩展; 4. MiniMax、部分 NVIDIA 模型等看到未知/不支持字段,就直接返回 400。
所以问题不是“OpenRouter 不能用”,而是 Hermes 对 provider/model 能力的判断太粗,把 reasoning 参数发给了不该发的模型。
为什么换模型也可能不行?
如果 Hermes 的逻辑是“只要走 OpenRouter 就都带 reasoning”,那么你换多个不支持 reasoning 的模型,都会失败。
例如:
minimax/minimax-m2.5- 某些 NVIDIA Nemotron 模型
- 其他没有实现 reasoning 扩展的 OpenRouter 上游
它们不是同时坏了,而是收到同一个不兼容参数。
这也是为什么用户会感觉“Impossible to configure any model OpenRouter or Nvidia”。
修复方向:只对支持 reasoning 的模型发送 reasoning
评论里提到的修复 PR #1089 思路是:
> only send reasoning extra_body when the model slug matches a known reasoning-capable prefix
也就是只在模型 slug 属于已知支持 reasoning 的前缀时,才发送 reasoning。
例如维护一个类似白名单的判断:
_REASONING_MODEL_PREFIXES = (
"deepseek/",
"anthropic/",
"openai/",
"x-ai/",
"google/gemini-2",
"qwen/qwen3",
)
后续讨论里还提到是否加入 nvidia/,但维护者也指出:如果是 custom Nvidia endpoint,就不一定走 OpenRouter 那条 reasoning extra_body 路径,可能还需要继续看 request dump 里的 tools、extra_body 或其他字段。
这点很重要:不要把所有 NVIDIA 400 都简单归因到 reasoning;要看实际请求体。
排查步骤:别猜,看 request dump
遇到这类 400,建议按下面顺序排查。
1. 确认错误码
如果是:
Error code: 400
BadRequestError
优先怀疑请求体字段、工具 schema、模型参数不兼容。
如果是:
401
403
再回到 API Key / 权限排查。
2. 打开 request dump
Hermes 会输出类似:
~/.hermes/sessions/request_dump_20260312_204413_....json
重点看:
urlheadersbody.modelbody.extra_bodybody.toolsbody.reasoning
3. 查找 reasoning 字段
如果 body 里出现:
"extra_body": {
"reasoning": {...}
}
而你使用的模型并不支持 reasoning 扩展,这就是强嫌疑。
4. 换一个明确支持 reasoning 的模型验证
如果支持 reasoning 的模型能跑,不支持的模型 400,基本能锁定为能力判断问题。
5. 升级 Hermes 或临时禁用 reasoning
如果你使用的是受影响版本,应升级到包含相关修复的 Hermes。
临时绕过可以是:
- 换支持 reasoning 的模型;
- 关闭 reasoning / thinking 配置;
- 用不注入 reasoning extra_body 的 provider 路径;
- 使用 custom endpoint 时检查是否还有其他不兼容字段。
OpenRouter 场景:转发不等于兼容
OpenRouter 的价值是统一入口,但它并不会把所有模型都变成同一种能力。
一个模型是否支持:
- reasoning 参数;
- tool calling;
- JSON mode;
- vision input;
- parallel tool calls;
- structured output;
仍然取决于后面的真实供应商和模型。
所以对于 Agent 工具来说,最好不要只按 provider 判断能力,而要按 provider + model profile 判断能力。
Hermes 这类 bug 的教训是:
> “走 OpenRouter”不是一个足够细的能力标签;“这个具体模型支持哪些字段”才是关键。
NVIDIA 场景:custom endpoint 要另查 body
issue 讨论中,用户又提到 NVIDIA Nemotron custom endpoint:
custom_providers:
- name: nvidiaNemotron
base_url: https://integrate.api.nvidia.com/v1
api_key: <key>
model: nvidia/nemotron-3-super-120b-a12b
维护者提醒:如果是 custom Nvidia endpoint,而不是 OpenRouter 路径,那么 #1089 的 OpenRouter reasoning 修复不一定影响它。此时 400 可能来自:
- tool schema 不兼容;
tools[0]格式不符合上游要求;- 另一个
extra_body字段不被支持; - 模型 ID / endpoint path 与文档不匹配。
所以 NVIDIA 400 的正确做法仍然是:看 request dump 的 body,不要只凭 provider 名称判断。
和 DeepAI API 中转站的关系
DeepAI API 中转站适合作为 OpenAI-compatible API 统一入口,减少多工具、多模型切换时的 Base URL / API Key 管理成本。
例如在支持自定义 OpenAI-compatible endpoint 的工具里,通常关注三项:
Base URL: https://api.deepai.wang/v1
API Key: 你的 DeepAI Key
Model: 以 DeepAI 控制台为准
但本文这个问题的关键是客户端发送了上游不支持的字段。DeepAI 中转站不能“魔法消除”所有客户端错误参数;如果工具把某个模型不支持的字段发出去,上游仍可能返回 400。
因此更稳的策略是:
- 用 DeepAI 统一可用的 OpenAI-compatible 接入;
- 同时在 Hermes 里让 provider/model profile 正确描述能力;
- 不要把 reasoning、vision、tool calling 等能力当成所有模型默认支持。
FAQ
400 BadRequestError 是不是 API Key 错?
通常不是。API Key 错更常见是 401 或 403。400 更像请求体参数、工具 schema、模型能力不兼容。
为什么 OpenRouter 上有的模型能用,有的模型不能用?
因为 OpenRouter 是统一入口,不代表所有上游模型都支持同一套扩展参数。reasoning 就是典型例子。
看到 reasoning 字段就一定错吗?
不一定。如果模型支持 reasoning,它可能是正确参数。关键是模型是否支持该扩展。
NVIDIA Nemotron 报 400 也一定是 reasoning 吗?
不一定。尤其是 custom endpoint 路径,要检查 request dump 里的 extra_body、tools 和模型参数。
DeepAI API 中转站能解决这个问题吗?
DeepAI 可以简化 OpenAI-compatible 接入和模型切换,但客户端仍应按模型能力发送参数。它不能保证不兼容字段一定被自动修复。
总结
Hermes Agent 接 OpenRouter / NVIDIA 模型时出现:
BadRequestError
Error code: 400
不要先盲目重试,也不要只改 API Key。先打开 request_dump_*.json,检查是否把 reasoning、工具 schema 或其他 extra_body 字段发给了不支持的模型。
issue #1083 的核心教训是:模型能力判断必须精确到具体模型;不能因为走 OpenRouter,就默认所有模型都支持 reasoning。