Provider 抽象层:让 Hermes 同时驾驭 30+ 个 LLM 提供商

声明式 Profile、插件化注册、三种传输协议、多认证路径、Fallback 链

通过 Hermes 探秘 Agent 工程 | 第 10 篇 · 查看全部

上一篇:技能系统:Agent 如何把经验变成可复用的程序化记忆


[系列文章导航]

#文章定位
1Agent Loop:Agent 的核心执行循环入口
2System Prompt:身份、上下文与策略的三层架构认知层
3工具系统:从注册到调度工具层
4工具调度系统:从注册到执行的完整生命周期调度层
5安全防护体系:当 Agent 拥有终端时如何防止「做出格」的事安全层
6沙箱与代码执行:让 Agent 安全跑代码的 RPC 架构执行层
7上下文压缩:让 Agent 在有限窗口里「记得住」记忆层
8记忆系统:跨会话持久化的工程实现记忆层
9技能系统:Agent 如何把经验变成可复用的程序化记忆记忆层
10Provider 抽象层:让 Hermes 同时驾驭 30+ 个 LLM 提供商模型层
11Gateway 网关:连接 20+ 平台的统一消息路由接入层
12多 Agent 协作:委托、调度与看板协作层

问题:一个 Agent,30+ 个大脑

Hermes 可以接入的 LLM 提供商超过 30 个:商业 API(OpenAI、Anthropic、Google Gemini)、聚合器(OpenRouter、HuggingFace)、本地推理(Ollama、vLLM)、自定义端点。

每个提供商的差异很大:传输协议不同、认证方式不同、请求格式怪癖、模型列表获取方式不同。

Hermes 的 Provider 抽象层用一个声明式 + 插件化的架构统一了这些差异。

ProviderProfile:声明式描述一切

@dataclass
class ProviderProfile:
    name: str
    api_mode: str = "chat_completions"  # 传输协议
    env_vars: tuple = ()                # 环境变量名(按优先级)
    base_url: str = ""                  # 推理端点
    auth_type: str = "api_key"          # api_key | oauth_device_code | oauth_external | copilot | aws_sdk
    supports_vision: bool = False
    fallback_models: tuple = ()         # 静态模型列表(live fetch 失败时用)
    fixed_temperature: Any = None       # None=调用方默认, OMIT_TEMPERATURE=不发送
    default_max_tokens: int | None = None
    default_aux_model: str = ""         # 辅助任务用的便宜模型

    # 钩子
    def prepare_messages(self, messages): ...
    def build_extra_body(self, *, session_id, **context): ...
    def build_api_kwargs_extras(self, *, reasoning_config, **context): ...
    def get_max_tokens(self, model): ...
    def fetch_models(self, *, api_key, base_url, timeout): ...

Profile 是声明式的——它描述 Provider 的行为,但不拥有客户端构造、凭证轮换或流式处理。

插件化注册发现

两层位置:

  1. 内置插件plugins/model-providers/<name>/ 目录,随 Hermes 一起发布
  2. 用户插件$HERMES_HOME/plugins/model-providers/<name>/,用户自定义或第三方覆盖

发现顺序:内置插件 → 用户插件 → 旧版单文件。用户可以覆盖任何内置 Profile

三种传输协议

api_mode协议典型 Provider
chat_completionsOpenAI Chat Completions APIOpenRouter、DeepSeek、Kimi、Ollama
anthropic_messagesAnthropic Messages APIAnthropic 原生、MiniMax、Kimi Code
codex_responsesOpenAI Codex Responses APIOpenAI Codex、xAI、OpenAI API(GPT-5.x)

自动检测:runtime_provider.py_detect_api_mode_for_url() 可以根据 base_url 自动推断协议。

四种认证路径

auth_type机制典型 Provider
api_key从环境变量读取 API KeyOpenRouter、DeepSeek、Gemini
oauth_device_codeOAuth 2.0 Device Code 流程Nous Portal
oauth_external外部浏览器 OAuth 流程OpenAI Codex、xAI
copilotGitHub Copilot ACPGitHub Copilot
aws_sdkAWS SDK 认证AWS Bedrock

API Key 凭证隔离:每个 Provider 的 API Key 只发往自己的 base URL。Hermes 会根据 base URL 的 hostname 自动推导对应的环境变量名,同时防御了域名仿冒攻击

Fallback Provider 链

触发点:API 响应无效、不可重试的客户端错误、瞬态错误且重试耗尽。

激活流程:检查是否已激活 → 构建新客户端 → 确定 api_mode原地替换 (self.modelself.providerself.base_urlself.client) → 重置重试计数,继续循环。

限制:子 Agent 不继承 fallback 配置;辅助任务不走 fallback。

辅助模型路由

辅助任务(视觉、上下文压缩、技能操作、MCP 辅助、记忆刷新)可以使用与主对话不同的 Provider/Model

配置方式:

auxiliary:
  provider: openrouter
  model: google/gemini-2.0-flash-001

HermesOverlay:Hermes 特有的元数据

HermesOverlay 补充了 models.dev 目录不覆盖的 Hermes 特有信息:传输协议标记(transport)、是否为聚合器(is_aggregator)、认证类型标记、额外环境变量、base_url 覆盖。


下一篇:Gateway 网关:连接 20+ 平台的统一消息路由 — 用 session key 隔离多用户、双层守卫防止并发