H繁中版
文件開發者指南provider runtime
<!-- Source: https://hermesbible.com/docs/developer-guide/provider-runtime -->

Hermes 擁有共用的供應商執行時解析器,跨以下場景使用:

  • CLI
  • 閘道器
  • 排程任務
  • ACP
  • 輔助模型呼叫

主要實作:

  • hermes_cli/runtime_provider.py — 憑證解析、_resolve_custom_runtime()
  • hermes_cli/auth.py — 供應商註冊表、resolve_provider()
  • hermes_cli/model_switch.py — 共用的 /model 切換管線(CLI + 閘道器)
  • agent/auxiliary_client.py — 輔助模型路由
  • providers/ — ABC + 註冊表入口點(ProviderProfileregister_providerget_provider_profilelist_providers
  • plugins/model-providers/<name>/ — 每個供應商的外掛(內建),宣告 api_modebase_urlenv_varsfallback_models 並在首次存取時向註冊表報到。使用者外掛位於 $HERMES_HOME/plugins/model-providers/<name>/,可覆寫同名的內建外掛。

providers/ 中的 get_provider_profile() 為給定的供應商 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 拾取它——不需要在解析器本身中新增分支。

如果你正在嘗試新增一個新的一等推論供應商,請同時閱讀新增供應商模型供應商外掛指南

解析優先順序

從高層次來看,供應商解析使用:

  1. 明確的 CLI/執行時請求
  2. config.yaml 模型/供應商設定
  3. 環境變數
  4. 供應商特定的預設值或自動解析

此順序很重要,因為 Hermes 將已儲存的模型/供應商選擇視為正常運行的真實來源。這防止了過時的 shell 匯出靜默覆寫使用者在 hermes model 中最後選擇的端點。

供應商

目前的供應商家族包括(完整內建集合參見 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 相容端點的一等供應商
  • 命名自訂供應商(config.yaml 中的 custom_providers 列表)

執行時解析的輸出

執行時解析器回傳的資料例如:

  • provider
  • api_mode
  • base_url
  • api_key
  • source
  • 供應商特定的中繼資料如到期/刷新資訊

為什麼這很重要

此解析器是 Hermes 能在以下場景之間共用認證/執行時邏輯的主要原因:

  • hermes chat
  • 閘道器訊息處理
  • 在新會話中運行的排程任務
  • ACP 編輯器會話
  • 輔助模型任務

OpenRouter 和自訂 OpenAI 相容基礎 URL

Hermes 包含邏輯以避免在存在多個供應商金鑰時(例如 OPENROUTER_API_KEYOPENAI_API_KEY)將錯誤的 API 金鑰洩漏到自訂端點。

每個供應商的 API 金鑰限定在其自己的基礎 URL 範圍:

  • OPENROUTER_API_KEY 只發送到 openrouter.ai 端點
  • OPENAI_API_KEY 用於自訂端點並作為回退

Hermes 也區分:

  • 使用者選擇的真實自訂端點
  • 未設定自訂端點時使用的 OpenRouter 回退路徑

此區別對以下場景特別重要:

  • 本地模型伺服器
  • 非 OpenRouter 的 OpenAI 相容 API
  • 無需重新執行設定即可切換供應商
  • 應在 OPENAI_BASE_URL 未在當前 shell 中匯出時仍可運作的設定儲存自訂端點

原生 Anthropic 路徑

Anthropic 不再只是「透過 OpenRouter」。

當供應商解析選擇 anthropic 時,Hermes 使用:

  • api_mode = anthropic_messages
  • 原生 Anthropic Messages API
  • agent/anthropic_adapter.py 進行翻譯

原生 Anthropic 的憑證解析現在在兩者都存在時,優先選擇可刷新的 Claude Code 憑證而非複製的環境變數權杖。實務上這意味著:

  • Claude Code 憑證檔案在包含可刷新認證時被視為首選來源
  • 手動的 ANTHROPIC_TOKEN / CLAUDE_CODE_OAUTH_TOKEN 值仍作為明確覆寫運作
  • Hermes 在原生 Messages API 呼叫前預飛 Anthropic 憑證刷新
  • Hermes 在重建 Anthropic 用戶端後仍重試一次 401,作為回退路徑

OpenAI Codex 路徑

Codex 使用獨立的 Responses API 路徑:

  • api_mode = codex_responses
  • 專用的憑證解析和認證儲存支援

輔助模型路由

輔助任務例如:

  • 視覺
  • 網頁擷取摘要
  • 上下文壓縮摘要
  • 技能 hub 操作
  • MCP 輔助操作
  • 記憶刷新

可以使用自己的供應商/模型路由,而非主對話模型。

當輔助任務以供應商 main 設定時,Hermes 透過與正常聊天相同的共用執行時路徑解析它。實務上這意味著:

  • 環境驅動的自訂端點仍運作
  • 透過 hermes model / config.yaml 儲存的自訂端點也運作
  • 輔助路由可以區分真實的已儲存自訂端點和 OpenRouter 回退

降級模型

Hermes 支援已設定的降級供應商鏈——一個 (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 相容
    • 重新評估提示快取(在 OpenRouter 上的 Claude 模型啟用)
    • 設定 _fallback_activated = True——防止再次觸發
    • 重設重試計數為 0 並繼續迴圈
  4. 設定流程

    • CLI:cli.py 讀取 CLI_CONFIG["fallback_model"] → 傳遞給 AIAgent(fallback_model=...)
    • 閘道器:gateway/run.py._load_fallback_model() 讀取 config.yaml → 傳遞給 AIAgent
    • 驗證:providermodel 鍵必須非空,否則停用降級

不支援降級的場景

  • 子代理委派tools/delegate_tool.py):子代理繼承父代的供應商但不繼承降級設定
  • 輔助任務:使用自己獨立的供應商自動偵測鏈(見上方輔助模型路由)

排程任務支援降級:run_job()config.yaml 讀取 fallback_providers(或舊版 fallback_model)並傳遞給 AIAgent(fallback_model=...),與閘道器的 _load_fallback_model() 模式一致。參見排程任務內部

測試覆蓋率

降級行為在多個測試套件中有覆蓋:

  • tests/run_agent/test_fallback_credential_isolation.py — 主模型和降級之間的憑證隔離
  • tests/hermes_cli/test_fallback_cmd.py/fallback CLI 命令
  • tests/gateway/test_fallback_eviction.py — 閘道器對失敗供應商的淘汰

相關文件



新增工具