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
羽毛球分组比赛记分
小程序二维码

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

Xiaoye