在 Hermes Agent 上使用 Bedrock 托管的 GPT-5.5:custom_providers 配置与五个陷阱

 

本文是一篇实战笔记:如何把通过 Amazon Bedrock 提供的 OpenAI GPT-5.5 / GPT-5.4 接入 Hermes Agent,以及那五个让它"看起来坏了其实没坏"的配置陷阱。

作者:agent-manager · 整理发布于 Tech Note

TL;DR

GPT-5.5 和 GPT-5.4 于 2026-06-01 在 Amazon Bedrock GA,通过 Bedrock 的 OpenAI 兼容 Responses APIbedrock-mantle 端点)提供。Hermes Agent 目前还没有一等公民级的 "Bedrock OpenAI" provider(feature request #8694 已提),也没有对应文档页——但今天就能零代码改动跑起来,靠一个命名的 custom_providers 条目。你只需要把五个字段全部配对;漏掉任何一个,它都会以一个误导性的 401 或空响应失败。

可用配置:

# config.yaml
model:
  default: "openai.gpt-5.5"
  provider: "custom:bedrock-gpt5"   # custom:<name>,不是裸 "custom"
  base_url: ""
custom_providers:
  - name: bedrock-gpt5
    base_url: https://bedrock-mantle.us-east-2.api.aws/openai/v1   # /openai/v1,不是 /v1
    key_env: AWS_BEARER_TOKEN_BEDROCK
    api_mode: codex_responses
    models:
      openai.gpt-5.5:
        context_length: 272000
# .env
AWS_BEARER_TOKEN_BEDROCK=<your Bedrock API key>

就这些。本文剩下的部分讲为什么每一行是这样——因为每一行都是我踩过的坑。

背景:Bedrock 上的 GPT-5 和 Bedrock 上的 Claude 是两种完全不同的东西

如果你已经在 Hermes 上通过 Bedrock 跑 Claude(或 Nova/Llama),你用的是 provider: bedrock,它通过 bedrock-runtime 用 SigV4(或 IAM role)说 Converse API。你的直觉会是用同样的方式加 GPT-5。这个直觉是错的,AWS 的 model card 明确说了为什么:


Bedrock 上的 Claude / NovaBedrock 上的 GPT-5.5 / GPT-5.4
APIConverse仅 Responses API(Chat Completions 被拒绝)
端点bedrock-runtimebedrock-mantle
Model IDinference-profile id(us. / global. 前缀) openai.gpt-5.5(无 profile 前缀)
认证SigV4 / IAM roleBearer token(AWS_BEARER_TOKEN_BEDROCK
上下文窗口up to 1M(Claude)272K

所以用 Hermes 的话说,GPT-5 根本不是一个 bedrock 模型——它是一个恰好托管在 AWS 上的 OpenAI 兼容 custom 端点。正确的 Hermes 原语是 custom_providers

动 Hermes 之前先做个 sanity check——用一个裸调用确认端点和 key 能用:

curl -s https://bedrock-mantle.us-east-2.api.aws/openai/v1/responses \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $AWS_BEARER_TOKEN_BEDROCK" \
  -d '{"model":"openai.gpt-5.5","input":"ping"}'
# → 200,output[].content[].text = "pong"

如果返回 200,说明 model/region/key 都没问题,剩下任何失败都纯粹是 Hermes 配置问题。

五个陷阱

下面每一个,单独都能搞坏集成——而且报错信息都把你往错误的方向引。

1. provider 必须是 custom:<name>,不是裸 custom

provider: "custom"               # 错——静默退回到默认聚合端点
provider: "custom:bedrock-gpt5"  # 对——绑定命名的 custom_providers 条目

用裸 custom,Hermes 不知道你指哪个 custom 端点,于是解析到它默认的 OpenAI 兼容聚合 base URL——然后你的 Bedrock key 在那里被拒:

HTTP 401: Missing Authentication header

这个 401 看起来像认证问题。它不是——请求根本没到 Bedrock。custom:<name> 形式才是告诉 Hermes 用那个条目的 base_urlkey_envapi_mode

2. api_mode: codex_responses——因为 mantle 对 GPT-5 拒绝 Chat Completions

custom OpenAI 兼容 provider 的默认 wire 协议是 chat_completions。GPT-5 在 Bedrock 上不支持这条路径:

HTTP 400: The model 'openai.gpt-5.5' does not support the '/v1/chat/completions' API

Bedrock 上的 GPT-5.x 是 仅 Responses API。在 Hermes 里,Responses transport 是 api_mode: codex_responses。在 provider 条目上显式设置它。

旁注:Hermes 在 hermes model 里提供了一个交互式 "Bedrock API Key mode",指向 mantle——但它硬编码了 /v1 路径和 chat_completions。那个 wizard 是为 mantle 上可聊天的开源权重模型(gpt-oss、Kimi、GLM、DeepSeek)设计的,不是为 GPT-5。别用它配 GPT-5;手工配 custom_providers 条目。

3. base_url 路径是 /openai/v1,不是 /v1

https://bedrock-mantle.<region>.api.aws/openai/v1   # GPT-5 Responses 正确
https://bedrock-mantle.<region>.api.aws/v1          # 错——wizard 写的就是这个

mantle 上的 OpenAI 模型住在 openai/v1 路径前缀下(按 AWS model card:"available on the openai/v1/responses path")。配错就会 404 或打到错误的 surface。

4. key_env: AWS_BEARER_TOKEN_BEDROCK——显式把条目指向 key

这是最微妙的一个。codex_responses transport 最初是为 OpenAI 自己的 Responses 端点写的,那里凭证来自 OAuth/auth-file 流程。如果你不给 custom-provider 条目一个显式的 key_env,transport 会试图从那些 codex auth 位置取 bearer,而不是从你的环境变量——于是你得到:

HTTP 401: Invalid bearer token

……即使同一个 key 在上面的裸 curl 里能用。在条目上设置 key_env: AWS_BEARER_TOKEN_BEDROCK(或任何持有你 Bedrock key 的环境变量)让 transport 读到正确的凭证。不需要单独的 OPENAI_API_KEY

5. 如果 config 里已经有 custom_providers: 块,要合并——不要加第二个

custom_providers 是一个顶层 YAML key,持有一个 list。如果你的 config 曾被 hermes model 的 "Custom Endpoint" wizard 碰过,它可能已经包含条目(常是 wizard 写的过时条目)。在文件后面再加一个 custom_providers: key 不会追加——YAML 只保留重复 key 的最后一次出现,所以你的新条目会按顺序静默地赢或输,于是你得到:

Unknown provider 'custom:bedrock-gpt5'

……因为你的条目被另一个块覆盖了(或覆盖了别人)。先 grep -c '^custom_providers:';如果已经有了,把你的条目加到现有 list 里(顺便清掉任何过时的 wizard 条目)。我就是把一个在干净 profile 上逐字生效的 config 应用到一个有 wizard 残留的第二个 profile 上时被这个坑到——同样的 YAML,不同的结果,纯粹因为预先存在的块。

Region 在 URL 里——这是一个特性

GPT-5.5 目前仅 us-east-2;GPT-5.4 在 us-east-2 和 us-west-2。因为 region 编码在 base_url 里(bedrock-mantle.<region>.api.aws),它和你全局的 AWS_REGION 完全解耦。这意味着单个 Hermes 部署可以为一个 profile 从 us-east-2 跑 GPT-5.5,而其他一切(Converse 上的 Claude、embeddings 等)留在另一个 region——无需 AWS_REGION 来回切,无需跨 region inference profile。Per-model 的 region 路由从 custom-provider 模型里免费得到。

另外:显式设 context_length: 272000。GPT-5.5 的窗口是 272K,不是你习惯于 Claude 的 1M;如果留空不设,自动探测会向下退到一个保守默认值(丢失 headroom),或更糟——停在 Claude 尺寸的 1M,在压缩触发前就超出真实上限。

一个比配置更值钱的调试教训

我花了太多时间逆向 transport 和 request body 才找到真正的问题,因为 Hermes 的 one-shot 模式(hermes -z "..."把 stdout/stderr 吞进了 devnull,只报一个扁平的 no final response was produced。你从 CLI 看不到真实错误。

快速路径:直接在 Python 里用 INFO logging 调 agent runner,读解析出的 base_url= / provider= 和 HTTP 状态行:

import logging; logging.basicConfig(level=logging.INFO)
from hermes_cli.oneshot import _run_agent
print(repr(_run_agent("say hi", model=None, provider=None,
                      toolsets=None, use_config_toolsets=True)))

跑一次就会打出这样的行:

OpenAI client created ... provider=custom base_url=https://...openrouter... model=openai.gpt-5.5
... HTTP 401: Missing Authentication header

——错误的 base_url 一眼就跳出来。上面五个陷阱每一个都能用这种方式在几秒内诊断出来。一般原则:当 wrapper 隐藏了错误,就下沉一层到真实调用发生的地方,把 logging 调高——不要从外部逆向这个调用。

结语

这些都不需要 patch Hermes。能力早就在 custom_providers 里了;缺口纯粹是"没文档 + 五个不直观的字段 + 一个隐藏错误的 CLI"。等上游 ship 了一等公民级的 Bedrock-OpenAI provider(#8694),这些大部分会塌缩成 provider: bedrock,你就能删掉 custom 条目。在那之前,本文开头的配置是一个干净、零代码的方式,今天就把 GPT-5.5 放到 Hermes 后面工作。

Previous Post
No Comment
Add Comment
comment url