Passer au contenu principal
S

dsh-llm-proxy

superfish058/dsh-llm-proxy

Routage proxy par modèle pour les requêtes LLM : les modèles sélectionnés passent par un proxy (Clash, etc.) tandis que les autres restent en direct, avec réessai automatique sur erreurs de transport, 429 et 5xx, configuré en direct depuis la page des paramètres.

Installer

dsh plugin --profile web add github:superfish058/dsh-llm-proxy

README

@superfish058/dsh-llm-proxy

npm

DSH 模型代理插件:给 LLM 请求按「目标域名」分流——选中的模型走代理,其余直连。官方出站代理包(dsh ≥ 0.1.3)在时装官方引擎复用其传输层,旧 harness 用自带 dispatcher;重试统一交给官方 dsh-llm-retry。

版本要求:v1.5.0 面向 dsh ≥ 0.1.7(设置文档由插件自己的 Config 承载,客户端用 configForms + Plugins 页的 plugins.item 槽)。dsh 0.1.6 及更早请继续用 v1.4.0——路由与重试行为相同,只是设置页在老 harness 上可用。

它是干嘛的

  • 按模型走代理:在 DSH 设置页(设置 → 插件 → 模型代理)勾选需要走代理的模型(如 deepseek-v4-flash),该模型的请求自动经 proxyHost:proxyPort(默认 127.0.0.1:7897,即 Clash)转发;未勾选的模型(DeepSeek、小米、通义等国内 API)保持直连。路由按模型的 API 地址(baseURL host) 生效:选中一个模型后,同一地址下的所有模型都会走代理(例如 B.AI 的 deepseek-v4-flash 与 deepseek-v4-flash-vision-exp 共享 api.b.ai)。
  • 失败自动重试(官方引擎):重试由官方 dsh-llm-retry 执行——对断连(ECONNRESET 等)、429 限流、5xx 按 provider 自己的 retryPolicy 重放请求(默认 5 次、500ms→10s 指数退避 + 抖动,并遵循 Retry-After)。卡片上的 retries/retryIntervalMs(默认 3 次 / 1s 固定间隔)镜像进被勾选 provider 的该策略,取消勾选还原官方默认;插件自身不再在传输层重试(v1.4.0 起)。
  • 模型列表与官方一致:只配了 apiKeyEnv、没写 models 的 provider(如 xiaomi),其模型从 pi-ai 内置目录(@earendil-works/pi-ai)回退补齐;llm-deepseek 命名空间即使保持默认空文档(llm-deepseek: {})也回退官方内置目录(https://api.deepseek.com + DEEPSEEK_API_KEY),deepseek-official/* 模型开箱可用。勾选列表与 DSH 官方模型选择器完全同步。
  • retryPolicy 镜像:卡片上的 retries/retryIntervalMs 会镜像进被勾选 provider 的官方 retryPolicy(既是设置页 (retry/maximum) 提示的来源,也是真正的重试参数),取消勾选自动还原官方默认值——一套配置驱动官方重试。
  • 多模态模型镜像:DSH 官方模型声明里,部分支持图像识别的模型(如 deepseek-v4-flash-vision-exp)没有可供用户勾选「图像输入」的配置入口,选中后发图会被 DSH 以 UNSUPPORTED_CONTENT 拒绝。在设置卡「多模态模型」区勾选这些模型后,插件把 image 写进所属 provider 的模型声明(pi-ai 的 models[].input / 目录型 modelOverrides[].input,官方 DeepSeek 的 models[].inputModalities),使 DSH 允许对该模型发图;取消勾选自动还原官方默认。注意:该功能只对真正支持图像输入的模型(如 vision 模型)有意义,纯文本模型(如 deepseek-v4-flash)勾选后 DSH 虽放行,实际请求仍会因模型不支持图像而报错。
  • 测试连接:走代理的模型列表每行新增「测试连接」按钮,探测请求走当前生效的全局 dispatcher(即真实 LLM 请求的路径),返回 HTTP 状态 / 耗时 / 引擎给出的真实路由(经代理或直连);失败时直接显示提供方返回的错误 body(脱敏、截断),如 B.AI 的 max_tokens 限制一眼可见。注意:测试走已保存的配置——改了勾选后请先点「保存」再测试。
  • 保存即生效,无需重启:设置写入本插件的配置项(dsh 0.1.7 的 Loader entry llm-proxy,即 cordis.patch.yml 里这一行)后运行时整体替换 dispatcher,不碰供应商自己的配置。冷启动时若 provider 命名空间(llm-pi-ai/llm-deepseek)尚未注册,插件会带退避重试直到可解析代理域名,不再需要手动"恢复默认再保存"。
  • 图片输入不再由本插件代管:dsh 0.1.7 起模型图片输入(input / inputModalities)由官方模型设置页与官方 provider 配置直接管理,v1.4.0 的「多模态模型镜像」因此在 v1.5.0 移除——需要给某模型开图片输入时,请在官方模型设置处配置。

用什么技术

  • 两种引擎:优先复用官方 @deepseek-ai/dsh-http-proxy(用它的公开接缝安装一份按模型算出来的进程策略,不自建 dispatcher);没有该包时退化为自带的 RoutingDispatcher(按 hostname 路由)挂到 Node 全局 undici dispatcher。LLM 请求(OpenAI SDK → undici fetch)自动经过它,位于 LLM 适配器之下、供应商之上。
  • Cordis 插件:宿主侧用导出的 Config(schema 全字段 volatile())直接充当 llm-proxy 设置文档(lib/settings.js 只保留模型列表/测试桥接);浏览器侧设置页(src/client/)注册进 Plugins 页的 plugins.item 槽,设置读写走官方 configForms 服务(本地回环 bridge 兜底)。
  • 客户端构建:tsdown(Rolldown)打包 lib/client.js,经 window.__ModuleLoader__ 注入前端。

与官方 @deepseek-ai/dsh-http-proxy 的关系

DSH 官方从 0.1.3 起自带出站代理包(@deepseek-ai/dsh-http-proxy,npm 上是库不是插件):它实现进程级代理策略(HTTP(S)_PROXY / NO_PROXY、子进程环境发布、web-fetch 例外),但没有「按模型 / 按 provider 分流」的概念——策略只有一份。粒度这件事只有插件能做,所以本插件按环境选引擎:

引擎触发条件谁拥有传输层直连语义
official能加载到官方 @deepseek-ai/dsh-http-proxy(dsh ≥ 0.1.3)官方。插件只调用其公开接缝 installProxyFromEnvironment(envLookup, report) 喂一份算好的策略,卸载时把 launcher 原本的策略原样还回去官方默认「代理一切、按 no_proxy 绕过」:勾选的模型主机走代理,其余已配置 provider 主机写进 no_proxy 保持直连;非 provider 主机(web fetch / HTTP MCP)跟随代理
bundled加载不到(dsh ≤ 0.1.2,含内置桌面壳 0.1.2-rc.1)插件自己:RoutingDispatcher 挂到 undici 全局 dispatcher只代理勾选的模型主机,其余一切直连(含 web fetch / MCP)

日志首行会打印实际引擎(engine=official … / engine=bundled …)。官方引擎下你原有的 no_proxy 环境变量会被读取并与插件算出的绕过列表合并,不会被覆盖;代理地址是 socks5 / PAC 等官方不路由的 scheme 时,插件拒绝安装并保留 launcher 策略(官方解析器此时会回退成 DIRECT,等于抹掉你已配好的代理)。

重试不在这条分流的讨论范围内:插件的传输层 RetryAgent 已在 v1.4.0 移除(它和官方 dsh-llm-retry 会同时重试同一次请求),重试统一由官方按每个 provider 的 retryPolicy 执行。

适合什么场景

  • 国内网络访问境外模型 API(如 api.b.ai)超时/不可达——代理已就绪,只想让特定模型走。
  • 免费额度被 429/5xx 打断,需要按 provider 自动重试扛过限流窗口(走官方 retryPolicy,勾选即生效)。
  • 想按模型粒度控制代理,而不是全局开代理连累国内直连 API。

安装

# 推荐:npm 包(最新版,预构建 lib,秒装)
dsh plugin --profile web add @superfish058/dsh-llm-proxy

# 本地源码联调(改源码后需 npm run build 重建)
dsh plugin --profile web add C:/path/to/dsh-llm-proxy

若提示 build 授权,把 @superfish058/dsh-llm-proxy 加进 profile 的 pnpm-workspace.yaml → onlyBuiltDependencies。装完重启 dsh web(托盘退出 → 启动)。

配置

字段默认说明
proxyHost127.0.0.1代理主机/IP(Clash 等),可不在本机。只填主机,不要带 http://(误填会自动归一化,内联端口也会生效)
proxyPort7897代理端口
proxiedModels[]走代理的模型,<providerId>/<modelId>,其余直连
retries / retryIntervalMs3 / 1000重试次数与固定间隔(ms)。只镜像进被勾选 provider 的官方 retryPolicy(重试由 dsh-llm-retry 执行);插件自身不在传输层重试
trustedOrigins[]反代部署专用(进阶项,设置卡不显示,写进 profile 的 cordis.patch.yml 该插件行):设置页 bridge API 默认只允许回环主机访问,反代会把 Host 改写成公共域名导致 403;把公共访问源(完整 origin,如 https://dsh.example.com)加进此数组即可放行。默认空 = 仅本机。CSRF 同源校验始终生效——Host 命中白名单但 Origin 不一致仍会 403

反代部署示例(cordis.patch.yml 中该插件行的 config):trustedOrigins: ['https://dsh.example.com']。多域名就多写几项。

验证

最快方式:设置页(设置 → 插件 → 模型代理)的「走代理的模型」列表里,每行有「测试连接」按钮,点击即向该模型发一次最小探测请求(走插件自己的全局 dispatcher,即真实代理路径):

  • ✓ 连接成功:显示 状态 · 耗时 · 经代理/直连(如 ✓ 连接成功 · 200 · 38ms · 经代理)
  • ✗ 连接失败:直接显示脱敏后的提供方错误原因(认证失败、限流、max_tokens 限制等),一眼定位问题

注意:测试走的是已保存的配置——改了代理勾选/代理地址后,先点「保存」再测试;测试只验证一次非流式探测,流式/长对话仍建议用真实会话确认。

日志方式:重启后日志出现:

# dsh ≥ 0.1.3:官方出站代理包在 → 官方引擎
dsh-llm-proxy: engine=official — official outbound-proxy package detected (...); the transport layer stays official, this plugin only computes the per-model policy
dsh-llm-proxy: official policy installed (engine=official, proxy=127.0.0.1:7897, proxiedHosts=[api.b.ai], directHosts=[api.deepseek.com])

# dsh ≤ 0.1.2:没有官方包 → 自带 dispatcher
dsh-llm-proxy: engine=bundled — official outbound-proxy package not found, using the built-in dispatcher
dsh-llm-proxy: global dispatcher → RoutingDispatcher (engine=bundled, proxy=127.0.0.1:7897, proxiedHosts=[api.b.ai])

模型选择器里选中代理模型,流式响应正常、该模型域名出现在 proxiedHosts 里即成功。(官方引擎遵循官方「默认代理、按 no_proxy 绕过」语义,因此非 provider 主机也会走代理;自带引擎则只代理勾选的模型主机。)

遇到问题?让大模型帮你排查

插件出问题时,可在 DSH 中让其他模型帮忙排查——把下面这段提示词发给模型即可,模型会自行排查,无需用户提供报错信息或执行任何操作:

检查当前 DSH 插件 @superfish058/dsh-llm-proxy 是否正常可用,按以下步骤自行排查:

1. 查看插件配置确定当前代理端口号,自行通过该端口访问外网(如 github.com 等)判断端口是否连通,并确认本机可访问的端口和域名;
2. 检查「走代理的模型」是否已勾选;
3. 检查已勾选模型能否连通(可通过设置页「测试连接」验证);
4. 检查 dsh web 日志中 dsh-llm-proxy 相关输出。

根据排查结果判断插件是否可用;如不可用,给出全面修复方案。

Plugins associés