hermes-agent/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/developer-guide/provider-runtime.md
Teknium febc4cfec0
remove Vercel AI Gateway and Vercel Sandbox (#33067)
* remove Vercel AI Gateway provider and Vercel Sandbox terminal backend

Both Vercel-hosted integrations are removed end-to-end. Users on the AI
Gateway should switch to OpenRouter or one of the other aggregators
(Nous Portal, Kilo Code). Users on the Vercel Sandbox backend should
switch to Docker, Modal, Daytona, or SSH.

What's removed:
- `plugins/model-providers/ai-gateway/` provider plugin
- `hermes_cli/vercel_auth.py` Vercel-Sandbox auth helper
- `tools/environments/vercel_sandbox.py` terminal backend
- `ai-gateway` provider wiring across auth, doctor, setup, models,
  config, status, providers, main, web_server, model_normalize, dump
- `vercel_sandbox` backend wiring across terminal_tool, file_tools,
  code_execution_tool, file_operations, approval, skills_tool,
  environments/local, credential_files, lazy_deps, prompt_builder,
  cli, gateway/run
- `AI_GATEWAY_BASE_URL` constant, `_AI_GATEWAY_HEADERS` auxiliary-client
  header set, run_agent base-URL header/reasoning special-cases
- `[vercel]` pyproject extra and `vercel`/`vercel-workers` from uv.lock
- env vars: `AI_GATEWAY_API_KEY`, `AI_GATEWAY_BASE_URL`, `VERCEL_TOKEN`,
  `VERCEL_PROJECT_ID`, `VERCEL_TEAM_ID`, `VERCEL_OIDC_TOKEN`,
  `TERMINAL_VERCEL_RUNTIME`
- Tests: deletes test_ai_gateway_models.py and
  test_vercel_sandbox_environment.py; scrubs references across 23
  surviving test files (no entire tests deleted unless they were
  dedicated to AI Gateway / Sandbox)
- Docs: provider tables, env-var reference, setup guides, security
  notes, tool config, terminal-backend tables — English plus zh-Hans
  i18n parity
- `hermes-agent` skill: provider table entry and remote-backend list

What stays (intentional):
- `popular-web-designs/templates/vercel.md` — CSS design reference,
  unrelated to Vercel-the-AI-product
- `x-vercel-id` in `stream_diag.py` headers — generic Vercel CDN
  response header, useful diag signal on any Vercel-hosted endpoint
- `vercel-labs/agent-browser` URL in browser config — lightpanda
  browser project, different OSS effort
- `userStories.json` historical contributor entry mentioning Vercel
  Sandbox — archive, not active docs

Validation:
- 1153 tests in the 22 targeted files pass (`scripts/run_tests.sh`)
- Full repo `py_compile` clean
- Live import of every touched module + invariant check (no
  `ai-gateway` in `PROVIDER_REGISTRY`, no `_AI_GATEWAY_HEADERS`, no
  `vercel_sandbox` in `_REMOTE_TERMINAL_BACKENDS`)

* test: convert profile-count check from change-detector to invariant

The hardcoded "== 34" assertion broke when ai-gateway was removed.
Per AGENTS.md change-detector-test guidance, assert the relationship
(registry count >= number of plugin dirs) instead of a literal count.
Counts shift when providers are added/removed; that's expected.
2026-05-27 00:43:32 -07:00

8.3 KiB
Raw Blame History

sidebar_position title description
4 Provider 运行时解析 Hermes 如何在运行时解析 provider、凭据、API 模式及辅助模型

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请结合本页阅读 添加 ProviderModel 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 / Geminigeminigoogle-gemini-cli
  • Alibaba / DashScopealibabaalibaba-coding-plan
  • DeepSeek
  • Z.AI
  • Kimi / Moonshotkimi-codingkimi-coding-cn
  • MiniMaxminimaxminimax-cnminimax-oauth
  • Kilo Code
  • Hugging Face
  • OpenCode Zen / OpenCode Go
  • AWS Bedrock
  • Azure Foundry
  • NVIDIA NIM
  • xAIGrok
  • Arcee
  • GMI Cloud
  • StepFun
  • Qwen OAuth
  • Xiaomi
  • Ollama Cloud
  • LM Studio
  • Tencent TokenHub
  • Customprovider: custom)— 适用于任何 OpenAI 兼容端点的一等 provider
  • 命名自定义 providerconfig.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 解析选择 anthropicHermes 使用:

  • 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 为 mainHermes 通过与普通对话相同的共享运行时路径进行解析。实际效果为:

  • 环境变量驱动的自定义端点仍然有效
  • 通过 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_modeopenai-codex 使用 codex_responsesanthropic 使用 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. 配置流程

    • CLIcli.py 读取 CLI_CONFIG["fallback_model"] → 传递给 AIAgent(fallback_model=...)
    • Gatewaygateway/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 内部机制

测试覆盖

参见 tests/test_fallback_model.py,其中包含覆盖所有支持 provider、单次触发语义及边界情况的完整测试。

相关文档