Hermes Agent 多 Provider 实践:自建网关、真实模型名与高质量故障切换

用 OpenAI 兼容网关管理多上游模型:真实模型名、验证链路、高质量 fallback 与长上下文兼容性。

工程笔记 · 2026-07-24 · 约 6 分钟阅读 · 标签:Hermes Agent、LLM、OpenAI Compatible、自托管

当 AI Agent 不只是聊天,而是会运行命令、修改代码、管理服务器时,模型服务的稳定性会直接影响任务能否完成。单一 API 上游很容易因为限流、余额、模型下线或网络问题中断长任务。

我目前采用的方案是:Hermes Agent 连接一个自建 OpenAI 兼容网关,网关后面再配置多个高质量上游;同时保留少量经过验证的 Hermes 直连 Provider 作为备用。

本文不公开真实 API Key、服务器地址和账户信息,只讨论配置原则和验证方法。

为什么不直接在 Hermes 里堆很多 Key

直接配置多个 Provider 当然可行,但自建网关有几个优势:

  • 统一 API 地址和鉴权;
  • 账户级优先级与并发管理;
  • 上游失败后自动切换;
  • 统一记录请求状态与错误;
  • 客户端无需感知具体账号变化;
  • Hermes、Codex 和其他工具可以共用同一入口。

整体结构如下:

Hermes Agent
  → OpenAI-compatible gateway
      → upstream A
      → upstream B
      → upstream C

网关解决的是“上游账户与容错”,Hermes 负责“任务与模型选择”。两层职责不要混在一起。

第一原则:模型名必须透明

很多中转喜欢提供好记的别名,甚至把一个模型名静默映射到完全不同的模型。这对普通聊天也许无所谓,对 Agent 却很危险:

  • 上下文长度不同;
  • 工具调用能力不同;
  • 推理风格和代码质量不同;
  • 价格、速度和限额不可预测;
  • 出现回归时无法定位真实上游。

因此我的规则是:公开什么模型,就用什么真实名字;映射保持 1:1。

例如上游真实提供:

gpt-5.6-sol
gpt-5.6-luna
gpt-5.6-terra

网关也只暴露这些名字:

{
  "gpt-5.6-sol": "gpt-5.6-sol",
  "gpt-5.6-luna": "gpt-5.6-luna",
  "gpt-5.6-terra": "gpt-5.6-terra"
}

不要把 gpt-bestsmart-model 之类的别名放进生产路由,更不要在名字背后跨模型家族切换。

第二原则:/models 返回 200 不等于能用

这是最常见的误判。很多平台允许任何 Key 查看模型列表,但真正调用时可能出现:

  • 401:Key 无效;
  • 403:账号没有模型权限;
  • 429:额度或并发不足;
  • 500/503:上游兼容性或服务故障;
  • 返回 200,但实际模型字段被替换。

因此新增 Provider 时至少做两层测试。

1. 检查模型列表

curl https://gateway.example.com/v1/models \
  -H "Authorization: Bearer $API_KEY"

记录真实模型 ID,不凭经验猜名字。

2. 发真实完成请求

curl https://gateway.example.com/v1/chat/completions \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-5.6-sol",
    "messages": [{"role":"user","content":"Reply exactly: OK"}],
    "max_tokens": 16,
    "stream": false
  }'

检查 HTTP 状态、输出内容和返回的模型字段。

如果要给 Codex 使用,还必须另外测试:

POST /v1/responses

Codex 默认使用 Responses API。只支持 /chat/completions 的中转,不能直接视为完整 Codex Provider。

Hermes 自定义 Provider 的组织方式

概念配置可以写成:

custom_providers:
  - name: backup-a
    base_url: https://gateway.example.com/v1
    api_key_env: BACKUP_A_API_KEY
    models:
      - gpt-5.6-sol
      - gpt-5.6-luna

密钥只放在 .env

BACKUP_A_API_KEY=<API_KEY>

配置完成后,不要只看模型选择器。应启动一个全新的 Hermes 进程:

hermes chat \
  --provider custom:backup-a \
  --model gpt-5.6-sol \
  --toolsets safe \
  -q 'Reply exactly: PROVIDER_OK'

这一步同时验证 Provider 名称解析、.env 加载、模型选择和请求格式。

故障切换只保留高质量模型

Fallback 的目标是恢复任务,不是“有回复就行”。低质量模型可能在工程任务中:

  • 漏掉约束;
  • 错误使用工具;
  • 编造运行结果;
  • 在长任务中不断偏离目标。

因此 fallback 列表应短而明确,并为每个目标固定 Provider 与模型:

fallback_providers:
  - provider: custom:backup-a
    model: gpt-5.6-sol
  - provider: custom:backup-b
    model: gpt-5.5

每一项都必须事先真实调用成功。一个配置存在但模型不存在的 fallback,只会延长故障时间。

一个真实踩坑:短请求成功,长上下文失败

某个 OpenAI 兼容中转在测试时表现正常:

  • /models 返回 200;
  • 几个模型的短对话都返回 OK
  • Hermes 直连测试也成功。

但当 Agent 会话积累了大量日志、工具结果和系统指令后,请求体增长到数百 KB,上游开始返回:

500 sensitive_words_detected

这不是 Key、模型映射或网络故障,而是上游的内容过滤对长上下文不友好。网关检测到失败后切换到另一个账号,因此最终任务仍能完成。

这个案例说明:

  1. 最小请求只能证明基础可用;
  2. Agent Provider 还要测试长上下文;
  3. 短对话可用的中转,不一定适合作为 Agent 主力;
  4. 自动 failover 很重要,但日志必须能看出最终使用了哪个账号。

主模型与辅助模型可以分流

Hermes 不只有主聊天模型,还可能有:

  • 视觉分析;
  • 网页提取;
  • 上下文压缩;
  • 后台摘要;
  • 子 Agent。

把所有任务都压到最昂贵或最敏感的主 Provider 上并不合理。更稳妥的策略是:

主工程任务 → 高质量主模型
上下文压缩 → 稳定、长上下文模型
视觉任务 → 专门视觉模型
网页提取 → 速度优先模型

但分流同样需要验证,不应为了省钱使用明显不可靠的模型。

日常巡检清单

我会定期检查:

  • /models 是否仍包含配置模型;
  • 最小 Chat Completions 请求;
  • Responses API 请求;
  • 流式响应是否会中断;
  • 大请求是否触发 WAF 或敏感词过滤;
  • 网关实际命中的上游账号;
  • fallback 是否真的被调用成功;
  • 模型名是否仍保持透明。

小结

一个可靠的 Agent 路由体系,不是 Provider 越多越好,而是每一层职责清晰:

Hermes:选择适合任务的真实模型
网关:管理账户、并发和故障切换
上游:提供经过验证的模型能力

最终原则可以浓缩成四句话:

  1. 使用真实模型名,不做隐藏跨模型映射;
  2. 不相信模型列表,必须做真实请求;
  3. Fallback 只选经过验证的高质量模型;
  4. 短请求成功后,还要验证 Agent 的长上下文场景。

做好这些,模型服务偶尔波动时,Agent 才不会在关键任务中突然失去工作能力。

全部文章 · 返回 OneMJJ 首页

OneMJJ · 少踩坑,多留传家宝 · Public tools first.