Skip to main content

添加提供方

Hermes 已经可以通过自定义提供方路径与任何兼容 OpenAI 的端点进行通信。除非你希望为该服务提供第一流的用户体验,否则不要添加内置提供方:

  • 专用的认证或令牌刷新机制
  • 经过筛选的模型目录
  • 设置 / hermes model 菜单条目
  • provider:model 语法中的提供方别名
  • 需要适配器的非 OpenAI API 格式

如果该提供方只是“另一个兼容 OpenAI 的基础 URL 和 API 密钥”,那么命名的自定义提供方可能就足够了。

心智模型

一个内置提供方必须在多个层级上保持一致:

  1. hermes_cli/auth.py 决定如何查找凭据。
  2. hermes_cli/runtime_provider.py 将这些凭据转换为运行时数据:
    • provider
    • api_mode
    • base_url
    • api_key
    • source
  3. run_agent.py 使用 api_mode 来决定请求如何构建和发送。
  4. hermes_cli/models.pyhermes_cli/main.py 使提供方在 CLI 中可见。(hermes_cli/setup.py 自动委托给 main.py —— 无需在此处做任何更改。)
  5. agent/auxiliary_client.pyagent/model_metadata.py 保持辅助任务和令牌预算功能正常运作。

关键抽象是 api_mode

  • 大多数提供方使用 chat_completions
  • Codex 使用 codex_responses
  • Anthropic 使用 anthropic_messages
  • 新的非 OpenAI 协议通常意味着新增一个适配器和一个新的 api_mode 分支。

首先选择实现路径

路径 A —— 兼容 OpenAI 的提供方

当提供方接受标准的 chat-completions 风格请求时使用此路径。

典型工作内容:

  • 添加认证元数据
  • 添加模型目录 / 别名
  • 添加运行时解析
  • 添加 CLI 菜单连接
  • 添加辅助模型默认值
  • 添加测试和用户文档

你通常不需要新的适配器或新的 api_mode

路径 B —— 原生提供方

当提供方的行为不同于 OpenAI 的聊天补全时使用此路径。

当前树中示例:

  • codex_responses
  • anthropic_messages

此路径包含路径 A 的所有内容,并额外包括:

  • agent/ 中添加提供方适配器
  • 为请求构建、分发、使用量提取、中断处理和响应归一化添加 run_agent.py 分支
  • 适配器测试

文件清单

每个内置提供方都必需的文件

  1. hermes_cli/auth.py
  2. hermes_cli/models.py
  3. hermes_cli/runtime_provider.py
  4. hermes_cli/main.py
  5. agent/auxiliary_client.py
  6. agent/model_metadata.py
  7. 测试用例
  8. 用户文档(位于 website/docs/ 下)
tip

hermes_cli/setup.py 不需要 修改。设置向导将提供方/模型选择委托给 select_provider_and_model() 中的 main.py —— 任何添加到那里的提供方都会自动出现在 hermes setup 中。

原生 / 非 OpenAI 提供方的附加项

  1. agent/<provider>_adapter.py
  2. run_agent.py
  3. 如果需要提供方 SDK,则添加 pyproject.toml

第一步:选择一个唯一的提供方 ID

选择一个单一的提供方 ID 并在整个项目中统一使用。

仓库中的示例:

  • openai-codex
  • kimi-coding
  • minimax-cn

该 ID 应出现在以下位置:

  • PROVIDER_REGISTRY 中的 hermes_cli/auth.py
  • _PROVIDER_LABELS 中的 hermes_cli/models.py
  • _PROVIDER_ALIASES 中的 hermes_cli/auth.pyhermes_cli/models.py
  • CLI 中的 --provider 选项(在 hermes_cli/main.py 中)
  • 设置 / 模型选择分支
  • 辅助模型默认值
  • 测试用例

如果这些文件中的 ID 不一致,该提供方将表现为“半连接”状态:认证可能有效,但 /model、设置或运行时解析可能会悄悄失败。

第二步:在 hermes_cli/auth.py 中添加认证元数据

对于基于 API 密钥的提供方,在 PROVIDER_REGISTRY 中添加一个 ProviderConfig 条目,包含:

  • id
  • name
  • auth_type="api_key"
  • inference_base_url
  • api_key_env_vars
  • 可选的 base_url_env_var

同时在 _PROVIDER_ALIASES 中添加别名。

参考现有提供方作为模板:

  • 简单的 API 密钥路径:Z.AI、MiniMax
  • 带有端点探测的 API 密钥路径:Kimi、Z.AI
  • 原生令牌解析:Anthropic
  • OAuth / 认证存储路径:Nous、OpenAI Codex

在此阶段需回答的问题:

  • Hermes 应检查哪些环境变量?优先级顺序是什么?
  • 该提供方是否需要基础 URL 覆盖?
  • 是否需要端点探测或令牌刷新?
  • 当凭据缺失时,错误信息应为何?

如果提供方需要比“查找 API 密钥”更复杂的功能,请添加专用的凭据解析器,而不是将逻辑塞入无关的分支中。

第三步:在 hermes_cli/models.py 中添加模型目录和别名

更新提供方目录,确保该提供方可在菜单中使用,并支持 provider:model 语法。

典型修改:

  • _PROVIDER_MODELS
  • _PROVIDER_LABELS
  • _PROVIDER_ALIASES
  • list_available_providers() 内部的提供方显示顺序
  • provider_model_ids()(如果该提供方支持实时 /models 获取)

如果提供方暴露了实时模型列表,优先使用它,并将 _PROVIDER_MODELS 作为静态回退。

该文件也决定了以下输入为何能正常工作:

anthropic:claude-sonnet-4-6
kimi:model-name

如果此处缺少别名,提供方可能正确通过认证,但在 /model 解析时仍会失败。

第四步:在 hermes_cli/runtime_provider.py 中解析运行时数据

resolve_runtime_provider() 是 CLI、网关、定时任务、ACP 和辅助客户端共用的路径。

添加一个分支,返回至少包含以下内容的字典:

{
"provider": "your-provider",
"api_mode": "chat_completions", # or your native mode
"base_url": "https://...",
"api_key": "...",
"source": "env|portal|auth-store|explicit",
"requested_provider": requested_provider,
}

如果该提供方兼容 OpenAI,api_mode 通常应保持为 chat_completions

注意 API 密钥的优先级。Hermes 已包含防止将 OpenRouter 密钥泄露给无关端点的逻辑。新提供方也应同样明确地说明哪个密钥对应哪个基础 URL。

第五步:在 hermes_cli/main.py 中连接 CLI

提供方在交互式 hermes model 流程中出现之前是不可见的。

hermes_cli/main.py 中更新以下内容:

  • provider_labels 字典
  • providers 列表(在 select_provider_and_model() 中)
  • 提供方调度(if selected_provider == ...
  • --provider 参数选项
  • 如果提供方支持登录/登出流程,添加相应选项
  • 添加一个 _model_flow_<provider>() 函数,或复用 _model_flow_api_key_provider()(如果适用)
tip

hermes_cli/setup.py 无需更改——它调用的是 select_provider_and_model() 中的 main.py,因此你的新提供方会自动出现在 hermes modelhermes setup 中。

第六步:保持辅助调用正常工作

这里有两个关键文件:

agent/auxiliary_client.py

如果是直接基于 API 密钥的提供方,应在 _API_KEY_PROVIDER_AUX_MODELS 中添加一个廉价/快速的默认辅助模型。

辅助任务包括:

  • 视觉摘要
  • 网页提取摘要
  • 上下文压缩摘要
  • 会话搜索摘要
  • 内存清理

如果该提供方没有合理的默认辅助模型,侧边任务可能会降级运行,或意外使用昂贵的主模型。

agent/model_metadata.py

为该提供方的模型添加上下文长度,以确保令牌预算、压缩阈值和限制保持合理。

第七步:如果提供方是原生的,添加适配器和 run_agent.py 支持

如果提供方不是标准的聊天补全格式,请将提供方特定逻辑隔离在 agent/<provider>_adapter.py 中。

保持 run_agent.py 专注于编排。它应调用适配器辅助函数,而不是在文件各处内联手写提供方负载。

原生提供方通常需要在以下位置进行修改:

新的适配器文件

典型职责:

  • 构建 SDK / HTTP 客户端
  • 解析令牌
  • 将 OpenAI 风格的对话消息转换为提供方的请求格式
  • 如有必要,转换工具模式
  • 将提供方响应归一化为 run_agent.py 所期望的格式
  • 提取使用量和结束原因数据

run_agent.py

搜索 api_mode 并审计每个 switch 分支。至少需确认:

  • 适配器已正确注册
  • 请求构建逻辑符合提供方要求
  • 响应解析和使用量提取准确无误
  • 中断处理机制正常工作- __init__ 选择新的 api_mode
  • 客户端构建对提供方有效
  • _build_api_kwargs() 知道如何格式化请求
  • _api_call_with_interrupt() 能正确分发到对应的客户端调用
  • 中断 / 客户端重建路径正常工作
  • 响应验证能接受提供方的返回结构
  • 结束原因(finish reason)提取正确
  • token 使用量提取正确
  • 回退模型激活可无缝切换至新提供方
  • 摘要生成和记忆清除路径仍正常工作

同时搜索 run_agent.py 中的 self.client.。任何假设标准 OpenAI 客户端存在的代码路径,在原生提供方使用不同客户端对象或 self.client = None 时都可能出错。

提示词缓存与提供方特定请求字段

提示词缓存和提供方特有参数很容易被引入回归问题。

树内已有示例:

  • Anthropic 有原生提示词缓存路径
  • OpenRouter 接收提供方路由字段
  • 并非所有提供方都应接收所有请求侧选项

添加原生提供方时,请务必确认 Hermes 只发送该提供方实际理解的字段。

第 8 步:测试

至少覆盖保护提供方连接逻辑的测试。

常见位置:

  • tests/test_runtime_provider_resolution.py
  • tests/test_cli_provider_resolution.py
  • tests/test_cli_model_command.py
  • tests/test_setup_model_selection.py
  • tests/test_provider_parity.py
  • tests/test_run_agent.py
  • tests/test_<provider>_adapter.py(针对原生提供方)

对于仅文档示例,具体文件集合可能有所不同。重点是覆盖以下方面:

  • 认证解析
  • CLI 菜单 / 提供方选择
  • 运行时提供方解析
  • 代理执行路径
  • 提供方:模型 解析
  • 任何适配器特有的消息转换

运行测试时禁用 xdist:

source venv/bin/activate
python -m pytest tests/test_runtime_provider_resolution.py tests/test_cli_provider_resolution.py tests/test_cli_model_command.py tests/test_setup_model_selection.py -n0 -q

对于较深入的改动,推送前请运行完整测试套件:

source venv/bin/activate
python -m pytest tests/ -n0 -q

第 9 步:实时验证

测试通过后,进行一次真实的烟雾测试。

source venv/bin/activate
python -m hermes_cli.main chat -q "Say hello" --provider your-provider --model your-model

若修改了菜单,也需测试交互流程:

source venv/bin/activate
python -m hermes_cli.main model
python -m hermes_cli.main setup

对于原生提供方,还需验证至少一次工具调用,而不仅仅是纯文本响应。

第 10 步:更新用户文档

如果该提供方旨在作为一级功能发布,请同步更新用户文档:

  • website/docs/getting-started/quickstart.md
  • website/docs/user-guide/configuration.md
  • website/docs/reference/environment-variables.md

开发者可能完美配置了提供方,但用户仍无法发现所需的环境变量或设置流程。

OpenAI 兼容提供方检查清单

适用于标准聊天补全接口的提供方。

  • ProviderConfig 中添加 hermes_cli/auth.py
  • hermes_cli/auth.pyhermes_cli/models.py 中添加别名
  • hermes_cli/models.py 中添加模型目录
  • hermes_cli/runtime_provider.py 中添加运行时分支
  • hermes_cli/main.py 中添加 CLI 配置(setup.py 会自动继承)
  • agent/auxiliary_client.py 中添加辅助模型
  • agent/model_metadata.py 中添加上下文长度
  • 更新运行时 / CLI 测试
  • 更新用户文档

原生提供方检查清单

适用于需要新协议路径的提供方。

  • 完成 OpenAI 兼容检查清单中所有项目
  • agent/<provider>_adapter.py 中添加适配器
  • run_agent.py 中支持新的 api_mode
  • 中断 / 重建路径正常工作
  • 使用量和结束原因提取正常
  • 回退路径正常工作
  • 添加适配器测试
  • 实时烟雾测试通过

常见陷阱

1. 将提供方加入认证系统,但未加入模型解析

这会导致凭据解析成功,但 /modelprovider:model 输入失败。

2. 忘记 config["model"] 可以是字符串或字典

大量提供方选择代码必须能处理这两种形式。

3. 假设必须使用内置提供方

如果服务只是 OpenAI 兼容,自定义提供方可能已能以更低维护成本解决用户需求。

4. 忽略辅助路径

主聊天路径正常,但摘要、记忆清除或视觉辅助等功能因辅助路由未更新而失败。

5. 原生提供方分支隐藏在 run_agent.py

搜索 api_modeself.client.。不要默认认为显而易见的请求路径是唯一路径。

6. 向不支持的提供方发送 OpenRouter 特有字段

如 provider routing 字段仅适用于支持该功能的提供方。

7. 更新 hermes model 但未更新 hermes setup

两个流程都需要知晓该提供方的存在。

实现过程中推荐的搜索关键词

若需查找提供方影响的所有位置,建议搜索以下符号:

  • PROVIDER_REGISTRY
  • _PROVIDER_ALIASES
  • _PROVIDER_MODELS
  • resolve_runtime_provider
  • _model_flow_
  • select_provider_and_model
  • api_mode
  • _API_KEY_PROVIDER_AUX_MODELS
  • self.client.

相关文档