dsh-provider-proxy:按模型和提供商路由代理

前言

DeepSeek Harness(DSH)在启动一个进程时只能应用一条代理策略(通过 HTTP_PROXY / HTTPS_PROXY / NO_PROXY / ALL_PROXY 环境变量)。当同一个进程需要针对不同模型、不同提供商使用不同代理,或者需要将部分流量直连时,原有机制无法满足需求。dsh-provider-proxy 在此之上增加两层路由轴,支持按提供商和模型分别配置代理出口。

插件定位

  • 插件名称:apolenkov/dsh-provider-proxy
  • 维护者:apolenkov
  • 分类:模型推理
  • 核心能力:在 DSH 进程代理策略之上,叠加按提供商和模型粒度的路由,并通过 UI 可视化配置

核心功能

1. 两层路由轴

插件在 DSH 的 undici fetch 层之上插入 RoutingDispatcher,根据请求上下文匹配两条路由轴:

  • Host 轴(providers):匹配请求 URL 的主机(支持精确匹配、子域名、可选 host:port)。该规则影响所有 fetch() 调用,包括 LLM 推理、网页搜索、MCP 等。
  • Model 轴(models):匹配发起请求的 provider/model 对。支持精确 ID 和带 * 的前缀匹配,并可显式绑定到某个 provider。

2. 优先级规则

路由匹配按以下顺序进行:

  1. provider-pinned 精确模型
  2. 精确模型(不限定 provider)
  3. provider-pinned 前缀模型(带 *)
  4. 前缀模型(不限定 provider)
  5. provider host 规则
  6. 默认路由(inherit 或 direct)

3. 代理值说明

值 含义
inherit 继承进程的代理策略(环境变量 + NO_PROXY)
direct 直连目标,忽略进程的代理策略
http(s)://… 通过指定代理(使用 ProxyAgent)

UI 会拒绝包含凭证的代理 URL,建议使用无凭证的代理端点。

安装与启用

安装前需确保 DSH profile 已启用插件管理器(桌面应用和 dsh web 均可)。

从 npm 安装(推荐):

dsh plugin --profile <profile> add @apolenkov/dsh-provider-proxy

从 git 安装(使用 release 标签):

dsh plugin --profile <profile> add git+https://github.com/apolenkov/dsh-provider-proxy.git#v0.1.0

从本地目录安装:

dsh plugin --profile <profile> add /absolute/path/to/dsh-provider-proxy

安装后重启 DSH。插件会在插件列表中插入 provider-proxy 行,路由配置位于该行的“配置”页面。

典型用法

在 UI 中配置

打开侧边栏 Plugins → 打开 dsh-provider-proxy bundle → Configure。页面包含:

  • Default route:默认路由(inherit 或 direct)
  • Provider rules:label、hosts(逗号或换行分隔)、代理值
  • Model rules:模型 ID(精确或带 *)、可选 provider 绑定、代理值

编辑后点击 Save,支持版本冲突检测:如果配置在保存时被他人修改,保存会被拒绝而不是静默覆盖。清除表单不会写入任何内容,离开页面则放弃已暂存的编辑。

在 YAML 中配置

在 profile 的 cordis.patch.yml 中添加或修改行:

- id: provider-proxy
  name: "dsh-provider-proxy"
  config:
    default: inherit
    providers:
      corp:
        hosts: ["llm.internal.example"]
        proxy: direct
      opencode-go:
        hosts: ["opencode.ai"]
        proxy: "http://127.0.0.1:1301"
    models:
      "muse-spark-1.3-contributor":
        provider: opencode-go
        proxy: "http://127.0.0.1:1301"
      "longcat-*": inherit

YAML 中的无效条目会导致整个配置拒绝(fail-closed),插件会记录原因并保留之前的路由。

验证路由生效

插件将最近一次应用结果写入 $DSH_HOME/provider-proxy/state.json:

{
  "appliedAt": "2026-10-22T07:59:22Z",
  "pid": 42120,
  "status": "active",
  "routes": "muse-spark-1.3-contributor→http://127.0.0.1:1301, llm.internal.example→direct, default→inherit"
}

可以将规则指向一个不存在的代理(如 http://127.0.0.1:9),观察请求失败并返回 ECONNREFUSED,随后恢复真实代理即可验证。

限制与注意事项

  • WebSocket 传输不一定保证经过 undici dispatcher,严格路由建议使用 http/https 传输。
  • web_fetch 可能会通过 launcher 的策略绕过这些路由,插件主要覆盖模型流量。
  • Model 规则仅作用于 llm/stream 内部;网页搜索和 MCP 使用 host 轴。
  • Model 规则不会对非模型流量触发;host 规则不会覆盖 localhost / loopback。
  • 代理 URL 中包含凭证时,transport 层可能接受,但 UI 会拒绝,建议使用无凭证端点。

适用场景

  • 需要为不同模型走不同代理的 DSH 场景。
  • 需要将部分内部 host 直连、外部 host 通过代理的场景。
  • 在多模型、多 provider 的复杂配置中,希望避免为每个模型单独设置环境变量的场景。

安装前建议检查源码与许可证(MIT)。

总结

dsh-provider-proxy 在 DSH 进程级代理策略之上提供了更细粒度的路由控制,支持按 provider 和 model 两轴配置,并通过 UI 与 YAML 两种方式管理。适合需要精细控制模型代理出口的场景,便于在保持 DSH 配置简洁的同时,满足多样化的网络策略需求。

插件目录页 | GitHub

羽毛球分组比赛记分
小程序二维码

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

Xiaoye