添加提供者
Hermes 已经可以通过自定义提供者路径与任何兼容 OpenAI 的端点通信。除非你希望该服务获得一流的用户体验,否则不要添加内置提供者:
- 提供商特定的认证或令牌刷新机制
- 经过筛选的模型目录
- 设置 /
hermes model菜单项 provider:model语法的提供者别名- 需要适配器的非 OpenAI API 形式
如果该提供者仅仅是“另一个兼容 OpenAI 的基础 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 菜单连接
- 添加辅助模型默认值
- 添加测试和用户文档
通常不需要新的适配器或新的 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.py- 如果需要提供者 SDK,则需修改
pyproject.toml
第一步:选择一个唯一的提供者 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、设置或运行时解析可能会静默失败。
第二步:在 hermes_cli/auth.py 中添加认证元数据
对于基于 API 密钥的提供者,在 PROVIDER_REGISTRY 中添加一个 ProviderConfig 条目,包含:
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 / 认证存储路径:Nous、OpenAI Codex
在此阶段需要回答的问题:
- Hermes 应检查哪些环境变量?优先级顺序是什么?
- 提供者是否需要基础 URL 覆盖?
- 是否需要端点探测或令牌刷新?
- 当凭据缺失时,认证错误信息应如何提示?
如果提供者需要的功能超出“查找 API 密钥”范围,请添加专用的凭据解析器,而不是将逻辑塞入无关的分支中。
第三步:在 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 解析时仍会失败。
第四步:在 hermes_cli/runtime_provider.py 中解析运行时数据
resolve_runtime_provider() 是 CLI、网关、cron、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。
第 5 步:在 hermes_cli/main.py 中连接 CLI
在提供者出现在交互式 hermes model 流程之前,它是不可发现的。
请在 hermes_cli/main.py 中更新以下内容:
provider_labels字典select_provider_and_model()函数中的providers列表- 提供者分派逻辑(
if selected_provider == ...) --provider参数的可选值- 如果该提供者支持登录/登出流程,更新相应的选项
- 添加一个
_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 添加一个轻量级/快速的默认辅助模型。
辅助任务包括:
- 视觉摘要
- 网页提取摘要
- 上下文压缩摘要
- 会话搜索摘要
- 内存清理
如果该提供者没有合适的默认辅助模型,辅助任务可能会表现不佳,或意外使用昂贵的主模型。
agent/model_metadata.py
为该提供者的模型添加上下文长度,以确保令牌预算、压缩阈值和限制保持合理。
第 7 步:如果提供者是原生的,添加适配器和 run_agent.py 支持
如果提供者不是标准的聊天补全接口,请将提供者特定的逻辑隔离到 agent/<provider>_adapter.py 中。
保持 run_agent.py 专注于编排。它应调用适配器辅助函数,而不是在文件中各处直接构建提供者请求负载。
原生提供者通常需要在以下位置进行修改:
新的适配器文件
典型职责包括:
- 构建 SDK / HTTP 客户端
- 解析令牌数
- 将 OpenAI 风格的对话消息转换为提供者的请求格式
- 如有必要,转换工具模式
- 将提供者响应规范化为
run_agent.py所期望的格式 - 提取使用情况和结束原因数据
run_agent.py
搜索 api_mode 并审计每个分支点。至少需验证:
__init__选择了新的api_mode- 客户端构建对提供者有效
_build_api_kwargs()知道如何格式化请求_api_call_with_interrupt()能正确分派到对应的客户端调用- 中断 / 客户端重建路径正常工作
- 响应验证能接受提供者的响应结构
- 结束原因提取正确
- 令牌使用量提取正确
- 回退模型激活能平滑切换到新提供者
- 摘要生成和内存清理路径仍能正常工作
同时在 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.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.mdwebsite/docs/user-guide/configuration.mdwebsite/docs/reference/environment-variables.md
开发者可能完美配置了提供者,但仍可能导致用户无法发现所需的环境变量或设置流程。
OpenAI 兼容提供者检查清单
如果提供者符合标准聊天补全接口,请使用此清单。
- 在
hermes_cli/auth.py中添加ProviderConfig - 在
hermes_cli/auth.py和hermes_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. 将提供者添加到认证但未添加到模型解析
这会导致凭据解析正确,但 /model 和 provider:model 输入会失败。
2. 忘记 config["model"] 可以是字符串或字典
许多提供者选择代码必须同时处理这两种形式。
3. 认为必须使用内置提供者
如果服务仅是 OpenAI 兼容的,自定义提供者可能已用更少的维护成本解决用户问题。
4. 忘记辅助路径
主聊天路径可能正常工作,但摘要、记忆清除或视觉辅助功能失败,因为辅助路由从未更新。
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.