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-best、smart-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、模型映射或网络故障,而是上游的内容过滤对长上下文不友好。网关检测到失败后切换到另一个账号,因此最终任务仍能完成。
这个案例说明:
- 最小请求只能证明基础可用;
- Agent Provider 还要测试长上下文;
- 短对话可用的中转,不一定适合作为 Agent 主力;
- 自动 failover 很重要,但日志必须能看出最终使用了哪个账号。
主模型与辅助模型可以分流
Hermes 不只有主聊天模型,还可能有:
- 视觉分析;
- 网页提取;
- 上下文压缩;
- 后台摘要;
- 子 Agent。
把所有任务都压到最昂贵或最敏感的主 Provider 上并不合理。更稳妥的策略是:
主工程任务 → 高质量主模型
上下文压缩 → 稳定、长上下文模型
视觉任务 → 专门视觉模型
网页提取 → 速度优先模型
但分流同样需要验证,不应为了省钱使用明显不可靠的模型。
日常巡检清单
我会定期检查:
/models是否仍包含配置模型;- 最小 Chat Completions 请求;
- Responses API 请求;
- 流式响应是否会中断;
- 大请求是否触发 WAF 或敏感词过滤;
- 网关实际命中的上游账号;
- fallback 是否真的被调用成功;
- 模型名是否仍保持透明。
小结
一个可靠的 Agent 路由体系,不是 Provider 越多越好,而是每一层职责清晰:
Hermes:选择适合任务的真实模型
网关:管理账户、并发和故障切换
上游:提供经过验证的模型能力
最终原则可以浓缩成四句话:
- 使用真实模型名,不做隐藏跨模型映射;
- 不相信模型列表,必须做真实请求;
- Fallback 只选经过验证的高质量模型;
- 短请求成功后,还要验证 Agent 的长上下文场景。
做好这些,模型服务偶尔波动时,Agent 才不会在关键任务中突然失去工作能力。