dsh-provider-pool:本地 OpenAI 兼容代理與多 Provider 優先級回退

前言

在 DeepSeek Harness(DSH)裏接入自定義模型時,常見做法是直接填某個雲廠商的 Base URL 和 API Key。一旦該線路限流、欠費、宕機或響應過慢,對話會整段失敗,需要手動換配置或改代碼。社區插件 dsh-provider-pool(維護者 vamyane,分類:模型推理)在宿主機上起一層 僅監聽 127.0.0.1 的 OpenAI 兼容代理,按 priority 依次嘗試多個上游 Provider,並在約定錯誤與超時時自動切換到下一個。DSH 側只需把自定義模型指向固定本地地址 http://127.0.0.1:3121/v1(實際端口以面板爲準)。當前版本爲 0.1.0(MVP),本地使用、未發佈 npm、無網絡遙測。

下面介紹插件定位、能力、安裝步驟與典型用法;事實以 GitHub 倉庫 README 爲準。插件目錄頁見 skillhub.cn。DSH 生態主張「一切皆插件」;skillhub 等爲社區目錄,與 DeepSeek / 幻方無官方從屬關係。

這是什麼

dsh-provider-pool 是 DSH 插件:在本地提供 OpenAI 兼容 HTTP 服務(默認端口 3121,佔用時自動嘗試 3122–3130),把聊天請求按配置好的 Provider 列表與優先級轉發,失敗時自動回退。上游 API Key 只在宿主機使用;瀏覽器側 UI 僅能看到密鑰末四位掩碼形式。

核心功能

本地代理接口

基於 node:http,綁定 127.0.0.1,兼容常見 OpenAI 風格路徑:

  • POST /v1/chat/completions(流式與非流式)
  • GET /v1/models(聚合各 Provider 模型列表,單路失敗可忽略)
  • GET /health

自動回退規則

Provider 按 priority 排序,數值越小越先嚐試。

  • 非流式:在 401 / 402 / 403 / 429 / 5xx、連接錯誤或 20 s 超時(可配置 timeoutMs,默認 20000)時切換下一 Provider。
  • 流式:僅在收到上游 第一個字節之前(響應頭階段)可回退;SSE 已開始輸出後不再中途換源,避免混流損壞內容。
  • 其他 4xx(如 400、404)原樣返回,不掩蓋請求本身的問題。

調用統計與面板

每次嘗試記錄 time, providerId, model, ms, status, fallback, stream,內存保留最近 200 條,並持久化到 ~/.dsh/provider-pool-stats.json(不含密鑰)。

側欄提供 Provider Pool 入口及全屏面板(React 直出,無 iframe):管理 Provider、連通性測試、近期調用統計、代理地址複製等。

密鑰與安全相關行爲

  • 代理用池內密鑰替換入站 Authorization;列表與統計接口僅返回 •••• + 末四位。
  • 配置中的明文 Key 寫在 ~/.dsh/provider-pool.json;POSIX 下文件模式 600。
  • 代理不對外網監聽;不對本地調用方做鑑權——任何本機進程均可訪問,信任邊界與 DSH 進程相當。安裝前宜自行審閱源碼與 MIT 許可證(package.json 要求 Node >=20,peer 依賴 @deepseek-ai/cordis >=4.0.0 <5)。

安裝與啓用

包未發佈到 npm,需在克隆或解壓後的源碼目錄本地構建並裝入 DSH profile:

cd dsh-provider-pool
node build.mjs        # generates lib/client.js from app/panel.js
npm pack              # dsh-provider-pool-0.1.0.tgz

任選其一:

dsh plugin --profile desktop add ./dsh-provider-pool-0.1.0.tgz

或按 DSH 內部方式手動:將包複製到 <profile>/local-plugins/dsh-provider-pool,在 profile 的 dependencies 增加 "dsh-provider-pool": "link:./local-plugins/dsh-provider-pool",把 dsh-provider-pool 寫入 dsh.profile.bundles,在 profile 目錄執行 pnpm install,並完全重啓 DSH。

重啓後,左側邊欄底部應出現 Provider Pool 入口。

典型用法

1. 配置 Provider 池

在面板中添加至少一個 Provider,或手工創建 ~/.dsh/provider-pool.json:

{
  "proxyPort": 3121,
  "providers": [
    {
      "id": "deepseek",
      "name": "DeepSeek official",
      "baseUrl": "https://api.deepseek.com",
      "apiKey": "sk-...",
      "model": "deepseek-chat",
      "priority": 1
    },
    {
      "id": "backup",
      "name": "Backup provider",
      "baseUrl": "https://api.openai.com/v1",
      "apiKey": "sk-...",
      "model": "gpt-4o-mini",
      "priority": 2
    }
  ]
}

配置文件在每次請求時重新讀取,面板內修改 Provider 即時生效;修改 proxyPort 需重啓 DSH(監聽在插件加載時創建)。

2. 在 DSH 中指向本地代理

在模型設置裏添加 自定義 OpenAI 兼容 Provider:

  • Base URL:http://127.0.0.1:3121/v1(可從面板複製;若端口被佔用,以面板顯示爲準)
  • API Key:任意佔位(代理使用池內真實密鑰)
  • Model:任意;若某 Provider 配置了 model 字段,代理會改寫請求中的 model,否則原樣轉發

3. 驗證回退

正常聊天即可。若首選 Provider 返回 500 / 429 / 401 或超時,面板統計中會看到 fallback 記錄,回答來自下一優先級 Provider。

配置字段摘要

字段 默認值 說明
proxyPort 3121 本地端口;忙則嘗試 3122–3130,面板顯示實際端口
timeoutMs 20000 等待上游響應頭的超時
providers[] [] Provider 列表,按 priority 排序嘗試
providers[].baseUrl — 自動補 /v1/chat/completions,或以 /v1 結尾時直接使用
providers[].apiKey "" 僅宿主機使用
providers[].model "" 非空時改寫請求 model
providers[].priority 插入順序 越小越優先

宿主還提供同域 Panel API,前綴 /api/dsh-provider-pool(如 GET /list、POST /test、GET /stats、POST /save 等),由 DSH connection 服務鑑權。

適用場景與注意

適合:需要在 DSH 裏 stable 使用「主備多條 LLM 線路」、希望 Key 不進入瀏覽器、且接受本機單進程代理信任模型的開發者。

已知限制(README 明示):

  • 流式中途 Provider 斷連不會靜默換源續寫。
  • 回退僅覆蓋限流/鑑權/服務端錯誤類狀態與網絡超時,業務型 4xx 不回退。
  • 暫無 vision / embedding / rerank,僅 chat completions 與 models 列表。
  • 3121–3130 若均被佔用,代理無法啓動,面板會報錯,但插件其他部分仍可用。
  • 插件以當前 DSH 進程權限運行;~/.dsh/provider-pool.json 含明文 Key,需自行保護主機與備份策略。

結尾

dsh-provider-pool 把「多 Provider + 優先級 + 自動回退」收斂成本地單一 OpenAI 兼容端點,減少在 DSH 裏反覆改 Base URL 的成本,並通過面板與 provider-pool-stats.json 保留可觀測的嘗試記錄。當前爲 0.1.0 MVP,使用前建議在 GitHub 閱讀完整 README 與 Security model 小節。

  • 目錄頁:https://www.skillhub.cn/plugins/vamyane/dsh-provider-pool
  • 源碼與文檔:https://github.com/vamyane/dsh-provider-pool
羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜