当前位置: 首页 > news >正文

hermes源码学习5-Provider 运行时解析

Hermes 拥有一个共享的 provider 运行时解析器,用于以下场景:

  • CLI
  • gateway
  • cron 任务
  • ACP
  • 辅助模型调用

主要实现:

  • hermes_cli/runtime_provider.py— 凭据解析,_resolve_custom_runtime()
  • hermes_cli/auth.py— provider 注册表,resolve_provider()
  • hermes_cli/model_switch.py— 共享/model切换流水线(CLI + gateway)
  • agent/auxiliary_client.py— 辅助模型路由
  • providers/— ABC + 注册表入口点(ProviderProfileregister_providerget_provider_profilelist_providers
  • plugins/model-providers/<name>/— 每个 provider 的插件(内置),声明api_modebase_urlenv_varsfallback_models并在首次访问时将自身注册到注册表。用户插件位于$HERMES_HOME/plugins/model-providers/<name>/,会覆盖同名的内置插件。

providers/中的get_provider_profile()为给定 provider id 返回一个ProviderProfileruntime_provider.py在解析时调用它,以获取规范的base_urlenv_vars优先级列表、api_modefallback_models,无需在多个文件中重复这些数据。在plugins/model-providers/<your-provider>/(或$HERMES_HOME/plugins/model-providers/<your-provider>/)下添加一个调用register_provider()的新插件,即可让runtime_provider.py自动识别它——无需在解析器本身中添加分支。

如果你想添加一个新的一等推理 provider,请结合本页阅读 添加 Provider 和 Model Provider 插件指南。

解析优先级

从高层来看,provider 解析使用以下顺序:

  1. 显式 CLI/运行时请求
  2. config.yaml中的模型/provider 配置
  3. 环境变量
  4. provider 特定的默认值或自动解析

该顺序很重要,因为 Hermes 将已保存的模型/provider 选择视为正常运行的真实来源。这可以防止过时的 shell 导出变量悄悄覆盖用户在hermes model中最后选择的端点。

Provider

当前 provider 系列包括(完整内置集合见plugins/model-providers/):

  • OpenRouter
  • Nous Portal
  • OpenAI Codex
  • Copilot / Copilot ACP
  • Anthropic(原生)
  • Google / Gemini(geminigoogle-gemini-cli
  • Alibaba / DashScope(alibabaalibaba-coding-plan
  • DeepSeek
  • Z.AI
  • Kimi / Moonshot(kimi-codingkimi-coding-cn
  • MiniMax(minimaxminimax-cnminimax-oauth
  • Kilo Code
  • Hugging Face
  • OpenCode Zen / OpenCode Go
  • AWS Bedrock
  • Azure Foundry
  • NVIDIA NIM
  • xAI(Grok)
  • Arcee
  • GMI Cloud
  • StepFun
  • Qwen OAuth
  • Xiaomi
  • Ollama Cloud
  • LM Studio
  • Tencent TokenHub
  • Custom(provider: custom)— 适用于任何 OpenAI 兼容端点的一等 provider
  • 命名自定义 provider(config.yaml中的custom_providers列表)

运行时解析的输出

运行时解析器返回的数据包括:

  • provider
  • api_mode
  • base_url
  • api_key
  • source
  • provider 特定的元数据,如过期/刷新信息

为什么这很重要

该解析器是 Hermes 能够在以下场景之间共享认证/运行时逻辑的主要原因:

  • hermes chat
  • gateway 消息处理
  • 在全新会话中运行的 cron 任务
  • ACP 编辑器会话
  • 辅助模型任务

OpenRouter 与自定义 OpenAI 兼容 base URL

Hermes 包含相关逻辑,以避免在存在多个 provider 密钥时(例如同时存在OPENROUTER_API_KEYOPENAI_API_KEY)将错误的 API key 泄露给自定义端点。

每个 provider 的 API key 仅作用于其自身的 base URL:

  • OPENROUTER_API_KEY仅发送至openrouter.ai端点
  • OPENAI_API_KEY用于自定义端点及作为回退

Hermes 还区分以下两种情况:

  • 用户主动选择的真实自定义端点
  • 未配置自定义端点时使用的 OpenRouter 回退路径

这种区分对以下场景尤为重要:

  • 本地模型服务器
  • 非 OpenRouter 的 OpenAI 兼容 API
  • 无需重新运行 setup 即可切换 provider
  • 通过 config 保存的自定义端点,即使当前 shell 中未导出OPENAI_BASE_URL也应正常工作

原生 Anthropic 路径

Anthropic 不再仅限于"通过 OpenRouter"访问。

当 provider 解析选择anthropic时,Hermes 使用:

  • api_mode = anthropic_messages
  • 原生 Anthropic Messages API
  • agent/anthropic_adapter.py进行转换

原生 Anthropic 的凭据解析现在在两者同时存在时,优先使用可刷新的 Claude Code 凭据,而非复制的环境变量 token。实际效果为:

  • 包含可刷新认证的 Claude Code 凭据文件被视为首选来源
  • 手动设置的ANTHROPIC_TOKEN/CLAUDE_CODE_OAUTH_TOKEN值仍可作为显式覆盖
  • Hermes 在调用原生 Messages API 前会预检 Anthropic 凭据刷新
  • Hermes 在重建 Anthropic 客户端后,仍会在收到 401 时重试一次,作为回退路径

OpenAI Codex 路径

Codex 使用独立的 Responses API 路径:

  • api_mode = codex_responses
  • 专用的凭据解析和认证存储支持

辅助模型路由

辅助任务包括:

  • 视觉
  • 网页提取摘要
  • 上下文压缩摘要
  • skills hub 操作
  • MCP 辅助操作
  • 记忆刷新

这些任务可以使用各自独立的 provider/模型路由,而非主对话模型。

当辅助任务配置的 provider 为main时,Hermes 通过与普通对话相同的共享运行时路径进行解析。实际效果为:

  • 环境变量驱动的自定义端点仍然有效
  • 通过hermes model/config.yaml保存的自定义端点同样有效
  • 辅助路由能够区分真实保存的自定义端点与 OpenRouter 回退

回退模型

Hermes 支持配置回退 provider 链——一个按顺序尝试的(provider, model)条目列表,当主模型遇到错误时依次尝试。旧版单对fallback_model字典仍被接受以保持向后兼容(并在首次写入时迁移)。

内部工作原理

  1. 存储AIAgent.__init__存储fallback_model字典并将_fallback_activated设为False

  2. 触发点_try_activate_fallback()run_agent.py主重试循环的三处被调用:

    • 在无效 API 响应(None choices、缺少 content)达到最大重试次数后
    • 在不可重试的客户端错误(HTTP 401、403、404)时
    • 在瞬时错误(HTTP 429、500、502、503)达到最大重试次数后
  3. 激活流程_try_activate_fallback):

    • 若已激活或未配置,立即返回False
    • 调用auxiliary_client.py中的resolve_provider_client()构建带有正确认证的新客户端
    • 确定api_mode:openai-codex 使用codex_responses,anthropic 使用anthropic_messages,其余使用chat_completions
    • 原地替换:self.modelself.providerself.base_urlself.api_modeself.clientself._client_kwargs
    • 对于 anthropic 回退:构建原生 Anthropic 客户端而非 OpenAI 兼容客户端
    • 重新评估 prompt 缓存(对 OpenRouter 上的 Claude 模型启用)
    • _fallback_activated设为True——防止再次触发
    • 将重试计数重置为 0 并继续循环
  4. 配置流程

    • CLI:cli.py读取CLI_CONFIG["fallback_model"]→ 传递给AIAgent(fallback_model=...)
    • Gateway:gateway/run.py._load_fallback_model()读取config.yaml→ 传递给AIAgent
    • 验证:providermodel键均须非空,否则回退被禁用

不支持回退的场景

  • 子代理委托tools/delegate_tool.py):子代理继承父代理的 provider,但不继承回退配置
  • 辅助任务:使用各自独立的 provider 自动检测链(见上方辅助模型路由)

Cron 任务支持回退:run_job()config.yaml读取fallback_providers(或旧版fallback_model)并传递给AIAgent(fallback_model=...),与 gateway 的_load_fallback_model()模式一致。参见 Cron 内部机制。

怎么添加一个模型插件

Each subdirectory is a self-contained provider profile plugin. The directory layout mirrors `plugins/platforms/`: ``` plugins/model-providers/ ├── openrouter/ │ ├── __init__.py # registers the ProviderProfile │ └── plugin.yaml # manifest: name, kind, version, description ├── anthropic/ │ ├── __init__.py │ └── plugin.yaml └── ... ``` ## How discovery works `providers/__init__.py._discover_providers()` scans this directory (and `$HERMES_HOME/plugins/model-providers/`) the first time anything calls `get_provider_profile()` or `list_providers()`. Each `__init__.py` is imported and expected to call `providers.register_provider(profile)`. User plugins at `$HERMES_HOME/plugins/model-providers/<name>/` override bundled plugins of the same name — last-writer-wins in `register_provider()`. Drop a file there to replace a built-in. ## Adding a new provider 1. Create `plugins/model-providers/<your_provider>/__init__.py`: ```python from providers import register_provider from providers.base import ProviderProfile my_provider = ProviderProfile( name="your-provider", aliases=("alias1", "alias2"), display_name="Your Provider", description="One-line description shown in the setup picker", signup_url="https://your-provider.example.com/keys", env_vars=("YOUR_PROVIDER_API_KEY", "YOUR_PROVIDER_BASE_URL"), base_url="https://api.your-provider.example.com/v1", default_aux_model="your-cheap-model", ) register_provider(my_provider) ``` 2. Create `plugins/model-providers/<your_provider>/plugin.yaml`: ```yaml name: your-provider-profile kind: model-provider version: 1.0.0 description: Short sentence about the provider author: Your Name ``` Nothing else needs to change. `auth.py`, `config.py`, `models.py`, `doctor.py`, `model_metadata.py`, `runtime_provider.py`, and the chat_completions transport all auto-wire from the registry. ## Non-trivial profiles Override the `ProviderProfile` hooks in a subclass for per-provider quirks — see `plugins/model-providers/openrouter/__init__.py` for `build_extra_body` and `build_api_kwargs_extras` examples, and `plugins/model-providers/gemini/__init__.py` for `thinking_config` translation.
http://www.rkmt.cn/news/1509087.html

相关文章:

  • 2026年专精特新小巨人申报意义汇总,北京上海地区服务商推荐 - mypinpai
  • 解读《Effective Python 3rd Edition》:从练气到老魔(第五章 Item 36 - 39)
  • 【验证码系列】某用平台滑块-加密流程分析rsa、base64
  • 044、Edge Impulse的音频分类实战
  • 从RDD到DataFrame:SparkSQL性能提升的秘密,就藏在这张‘表结构’里
  • 第10篇-进阶排序-归并排序与快速排序的核心思想
  • 扩散MRI结构连接组自动化分析工具:支持ACT纤维追踪、跨被试归一化与BIDS标准全流程
  • Python性能优化必学:timeit模块精准基准测试实战指南
  • 【Springboot毕设全套源码+文档】基于springboot中小学教育辅导系统设计与实现(丰富项目+远程调试+讲解+定制)
  • 2026年山东工业职业学院价格排名 - mypinpai
  • Calico网络架构图 跨主机通信原理
  • 从零构建专业天气数据爬虫:以天气网为例详解表单提交与模拟查询全流程
  • 保定市黄金回收白银回收铂金回收彩金回收靠谱门店TOP排行榜及联系方式地址电话+诚信店铺推荐 - 大熊猫898989
  • APA佛山改装展获得UFI认证后,是不是更国际化了?
  • 3588 只读根文件系统配置 overlayroot(防掉电损坏)
  • 3.1.6 B Tree
  • 保山市黄金回收白银回收铂金回收彩金回收靠谱门店TOP排行榜及联系方式地址电话+诚信店铺推荐 - 大熊猫898989
  • 大同人身伤害维权遇到困难?2026年这5位侵权赔偿律师推荐 - 本地品牌推荐
  • 综合案例 - AI 智能租房助手 [ 5 ]
  • Function Calling:大模型结构化调用与API协同执行机制
  • 从预测到逻辑思考:开启CPU+GPU的AI新时代
  • 大模型语义缓存与去重策略:从精确匹配到语义相似度的缓存优化
  • 深度解析 Bun:重新定义 JavaScript 运行时的性能边界
  • 091、动态蛇形卷积 DSConv:管状结构自适应聚焦的几何约束卷积
  • AMD Ryzen处理器终极调试指南:免费开源工具SMUDebugTool完整使用教程
  • 北京研学机构哪家好?一站式北京研学机构推荐 - 品牌2026
  • UAssetGUI:虚幻引擎资产深度解析与编辑的专业架构设计与实现原理
  • 讲真的2026年大同离婚律师推荐 这5位值得信赖选择 - 本地品牌推荐
  • 避开OV5640时钟配置的坑:PCLK算不准?可能是这3个寄存器设错了(附排查清单)
  • java 注解和反射