添加提供商
Hermes 已经可以通过自定义提供商路径与任何 OpenAI 兼容端点通信。除非你想要该服务的一流用户体验,否则不要添加内置提供商:
- 提供商特定的认证或令牌刷新
- 精选的模型目录
- 设置 /
hermes model菜单项 provider:model语法的提供商别名- 需要适配器的非 OpenAI API 形状
如果提供商只是"另一个 OpenAI 兼容 base URL 和 API 密钥",命名自定义提供商可能就足够了。
心智模型
内置提供商必须在多个层面保持一致:
hermes_cli/auth.py决定如何找到凭据hermes_cli/runtime_provider.py将其转换为运行时数据:providerapi_modebase_urlapi_keysource
run_agent.py使用api_mode决定如何构建和发送请求hermes_cli/models.py和hermes_cli/main.py使提供商在 CLI 中显示(hermes_cli/setup.py自动委托给main.py— 那里不需要更改)agent/auxiliary_client.py和agent/model_metadata.py保持辅助任务和令牌预算工作
重要的抽象是 api_mode。
- 大多数提供商使用
chat_completions - Codex 使用
codex_responses - Anthropic 使用
anthropic_messages - 新的非 OpenAI 协议通常意味着添加新适配器和新
api_mode分支
首先选择实现路径
路径 A — OpenAI 兼容提供商
当提供商接受标准 chat-completions 样式的请求时使用。
典型工作:
- 添加认证元数据
- 添加模型目录 / 别名
- 添加运行时解析
- 添加 CLI 菜单接线
- 添加 aux 模型默认值
- 添加测试和用户文档
通常你不需要新适配器或新 api_mode。
路径 B — 原生提供商
当提供商的行为不像 OpenAI chat completions 时使用。
树中现有的例子:
codex_responsesanthropic_messages
此路径包含路径 A 的所有内容,加上:
agent/中的提供商适配器run_agent.py中用于请求构建、分发、使用提取、中断处理和响应标准化的分支- 适配器测试
文件清单
每个内置提供商必需的
hermes_cli/auth.pyhermes_cli/models.pyhermes_cli/runtime_provider.pyhermes_cli/main.pyagent/auxiliary_client.pyagent/model_metadata.py- 测试
website/docs/下的用户面向文档
hermes_cli/setup.py 不需要更改。设置向导将提供商/模型选择委托给 main.py 中的 select_provider_and_model() — 在那里添加的任何提供商会自动在 hermes setup 中可用。
原生 / 非 OpenAI 提供商的附加项
agent/<provider>_adapter.pyrun_agent.pypyproject.toml(如果需要提供商 SDK)
步骤 1:选择一个规范提供商 ID
选择一个提供商 ID 并在各处使用。
树中的例子:
openai-codexkimi-codingminimax-cn
同一个 ID 应该出现在:
hermes_cli/auth.py中的PROVIDER_REGISTRYhermes_cli/models.py中的_PROVIDER_LABELShermes_cli/auth.py和hermes_cli/models.py中的_PROVIDER_ALIASEShermes_cli/main.py中的 CLI--provider选项- 设置 / 模型选择分支
- 辅助模型默认值
- 测试
如果 ID 在这些文件之间不同,提供商会感觉像是半接线的:认证可能工作,而 /model、设置或运行时解析会静默失败。
步骤 2:在 hermes_cli/auth.py 中添加认证元数据
对于 API 密钥提供商,添加一个带有以下内容的 ProviderConfig 条目到 PROVIDER_REGISTRY:
idnameauth_type="api_key"inference_base_urlapi_key_env_vars- 可选的
base_url_env_var
也添加别名到 _PROVIDER_ALIASES。
使用现有提供商作为模板:
- 简单 API 密钥路径:Z.AI、MiniMax
- 带端点检测的 API 密钥路径:Kimi、Z.AI
- 原生令牌解析:Anthropic
- OAuth / auth-store 路径:Nous、OpenAI Codex
这里要回答的问题:
- Hermes 应该检查哪些环境变量,优先级顺序是什么?
- 提供商是否需要 base URL 覆盖?
- 它需要端点探测还是令牌刷新?
- 当凭据缺失时,认证错误应该说什么?
如果提供商需要比"查找 API 密钥"更复杂的东西,添加专用凭据解析器,而不是将逻辑塞进不相关的分支。
步骤 3:在 hermes_cli/models.py 中添加模型目录和别名
更新提供商目录,使提供商在菜单和 provider:model 语法中工作。
典型编辑:
_PROVIDER_MODELS_PROVIDER_LABELS_PROVIDER_ALIASESlist_available_providers()中的提供商显示顺序- 如果提供商支持实时
/models获取,则为provider_model_ids()
如果提供商暴露实时模型列表,优先使用它并将 _PROVIDER_MODELS 作为静态后备。
这个文件也使以下输入工作:
anthropic:claude-sonnet-4-6
kimi:model-name
如果别名在这里缺失,提供商可能正确认证但在 /model 解析中仍然失败。
步骤 4:在 hermes_cli/runtime_provider.py 中解析运行时数据
resolve_runtime_provider() 是 CLI、gateway、cron、ACP 和辅助客户端使用的共享路径。
添加一个至少返回以下内容的分支:
{
"provider": "your-provider",
"api_mode": "chat_completions", # 或你的原生模式
"base_url": "https://...",
"api_key": "...",
"source": "env|portal|auth-store|explicit",
"requested_provider": requested_provider,
}
如果提供商是 OpenAI 兼容的,api_mode 通常应该保持 chat_completions。
注意 API 密钥优先级。Hermes 已经包含逻辑避免将 OpenRouter 密钥泄露到无关端点。新提供商应该在哪个密钥发送到哪个 base URL 方面同样明确。
步骤 5:在 hermes_cli/main.py 中接线 CLI
提供商只有在出现在交互式 hermes model 流程中才能被发现。
在 hermes_cli/main.py 中更新这些:
provider_labels字典select_provider_and_model()中的providers列表- 提供商分发(
if selected_provider == ...) --provider参数选项- 如果提供商支持这些流程,则为 login/logout 选项
_model_flow_<provider>()函数,或者如果适合则重用_model_flow_api_key_provider()
hermes_cli/setup.py 不需要更改 — 它从 main.py 调用 select_provider_and_model(),因此你的新提供商自动同时出现在 hermes model 和 hermes setup 中。
步骤 6:保持辅助调用工作
这里有两个重要文件:
agent/auxiliary_client.py
如果是直接 API 密钥提供商,向 _API_KEY_PROVIDER_AUX_MODELS 添加便宜/快速的默认 aux 模型。
辅助任务包括:
- 视觉摘要
- Web 提取摘要
- 上下文压缩摘要
- 会话搜索摘要
- 记忆刷新
如果提供商没有合理的 aux 默认值,辅助任务可能会糟糕地回退或意外使用昂贵的主模型。
agent/model_metadata.py
添加提供商模型的上下文长度,以便令牌预算、压缩阈值和限制保持合理。
步骤 7:如果提供商是原生的,添加适配器和 run_agent.py 支持
如果提供商不是普通 chat completions,在 agent/<provider>_adapter.py 中隔离提供商特定的逻辑。
保持 run_agent.py 专注于编排。它应该调用适配器辅助函数,而不是在整个文件中内联构建提供商负载。
原生提供商通常需要在这些地方工作:
新适配器文件
典型职责:
- 构建 SDK / HTTP 客户端
- 解析令牌
- 将 OpenAI 风格的对话消息转换为提供商的请求格式
- 如需要则转换工具 schema
- 将提供商响应标准化为
run_agent.py期望的格式 - 提取使用量和 finish-reason 数据
run_agent.py
搜索 api_mode 并审计每个切换点。至少验证:
__init__选择新的api_mode- 客户端构建适用于提供商
_build_api_kwargs()知道如何格式化请求_api_call_with_interrupt()分发到正确的客户端调用- 中断 / 客户端重建路径工作
- 响应验证接受提供商的形状
- finish-reason 提取正确
- 令牌使用提取正确
- 回退模型激活可以干净地切换到新提供商
- 摘要生成和记忆刷新路径仍然工作
还要在 run_agent.py 中搜索 self.client.。任何假设标准 OpenAI 客户端存在的代码路径在原生提供商使用不同客户端对象或 self.client = None 时都可能破坏。
提示词缓存和提供商特定的请求字段
提示词缓存和提供商特定的旋钮很容易回归。
树中已有的例子:
- Anthropic 有原生提示词缓存路径
- OpenRouter 获取提供商路由字段
- 不是每个提供商都应该接收每个请求侧选项
当你添加原生提供商时,仔细检查 Hermes 是否只发送提供商实际理解的字段。
步骤 8:测试
至少触及守卫提供商接线的测试。
常见位置:
tests/test_runtime_provider_resolution.pytests/test_cli_provider_resolution.pytests/test_cli_model_command.pytests/test_setup_model_selection.pytests/test_provider_parity.pytests/test_run_agent.pytests/test_<provider>_adapter.py(对于原生提供商)
对于仅文档的例子,确切的文件集可能不同。关键是覆盖:
- 认证解析
- CLI 菜单 / 提供商选择
- 运行时提供商解析
- agent 执行路径
- provider:model 解析
- 任何适配器特定的消息转换
运行测试(禁用 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.mdwebsite/docs/user-guide/configuration.mdwebsite/docs/reference/environment-variables.md
开发者可以完美地接线提供商,却仍然让用户无法发现所需的环境变量或设置流程。
OpenAI 兼容提供商清单
当提供商是标准 chat completions 时使用。
-
ProviderConfig添加到hermes_cli/auth.py - 别名添加到
hermes_cli/auth.py和hermes_cli/models.py - 模型目录添加到
hermes_cli/models.py - 运行时分支添加到
hermes_cli/runtime_provider.py - CLI 接线添加到
hermes_cli/main.py(setup.py 自动继承) - aux 模型添加到
agent/auxiliary_client.py - 上下文长度添加到
agent/model_metadata.py - 运行时 / CLI 测试更新
- 用户文档更新
原生提供商清单
当提供商需要新协议路径时使用。
- OpenAI 兼容清单中的所有内容
- 适配器添加到
agent/<provider>_adapter.py - 新
api_mode在run_agent.py中支持 - 中断 / 重建路径工作
- 使用量和 finish-reason 提取工作
- 回退路径工作
- 适配器测试添加
- 实时冒烟测试通过
常见陷阱
1. 将提供商添加到认证但未添加到模型解析
这使得凭据正确解析,而 /model 和 provider:model 输入失败。
2. 忘记 config["model"] 可以是字符串或字典
很多提供商选择代码必须规范化两种形式。
3. 假设内置提供商是必需的
如果服务只是 OpenAI 兼容的,自定义提供商可能已经用更少的维护解决了用户问题。
4. 忘记辅助路径
主聊天路径可以工作,而摘要、记忆刷新或视觉辅助失败,因为 aux 路由从未更新。
5. run_agent.py 中隐藏的原生提供商分支
搜索 api_mode 和 self.client.。不要假设显而易见的请求路径是唯一的。
6. 向其他提供商发送仅 OpenRouter 的旋钮
像提供商路由这样的字段只属于支持它们的提供商。
7. 更新 hermes model 但不更新 hermes setup
两个流程都需要知道该提供商。
实现时的好搜索目标
如果你在寻找提供商触及的所有位置,搜索这些符号:
PROVIDER_REGISTRY_PROVIDER_ALIASES_PROVIDER_MODELSresolve_runtime_provider_model_flow_select_provider_and_modelapi_mode_API_KEY_PROVIDER_AUX_MODELSself.client.