dsh-proxy-routes
Per-provider (account) proxy routing for DSH. SOCKS5/HTTP proxy pool with account-level routing based on API keys. Supports forced direct connections and hot-swapping built-in web tools proxies. Managed via a graphical settings page in DSH.
Install
dsh plugin --profile web add dsh-proxy-routes
Sandbox test results
| Stage | Result |
|---|---|
| 1 install | ✓ |
| 2 list | ✓ |
| 3 mount | ✓ |
| 4 boot | — |
Four stages run in an isolated sandbox: install (network on) → list → mount → boot (last three with no network).
README
dsh-proxy-routes —— 让每个 AI 账号走自己的代理
给 DSH(DeepSeek Harness)装的插件:同一个模型服务商的多个账号,可以各自决定走哪个代理还是直连。配置在 DSH 设置页图形化管理,保存即热生效,不需要手写任何文件。
它解决什么问题
- Anthropic / NVIDIA NIM 等海外 API 对中国大陆 IP 返回 403(DSH 界面误显示为 "API key is invalid")
- 智谱 / DeepSeek 等国内 API 又不该绕道代理
- 最关键的场景:同一服务商的多个账号——免费额度号要走代理、付费主力号要直连,但它们打向同一个 API 域名,任何按域名的分流都无法区分
本插件按每个请求携带的 API 密钥识别它属于哪个账号,从而精确到账号级分流。
三步上手
第 1 步:安装
DSH Desktop 用户(不用带 --profile,桌面版自动管理 desktop profile):
dsh plugin add dsh-proxy-routes
命令行(dsh web)用户:
dsh plugin --profile web add dsh-proxy-routes
前提:已装 DSH、有 pnpm、代理客户端(Clash / v2rayN / xray 等)在运行。插件只负责分流,不会替你启动代理客户端。
第 2 步:重启,打开卡片
完全退出 DSH(桌面版从托盘退出)再启动,然后打开 设置 → 代理路由。
卡片的三个入口(任选其一,内容相同):
- 设置 → 代理路由(独立设置页,各版本都有,推荐)
- DSH Desktop 2.0.14+:侧栏「插件」页 → dsh-proxy-routes → 详情
- DSH Desktop 2.0.13:设置 → 插件 → 代理路由
第 3 步:配置并保存
1. 代理池:给每个代理起名并填地址,例如 main = socks5://127.0.0.1:50939。填完直接点「测试」确认可达——测试的是输入框里当前的草稿值,不用先保存
2. 按提供商(账号)分流:列表自动来自 DSH「模型」页配置的 LLM 账号(claude1、nvidia-01…),每行下拉选择 直连 / 池中某个代理;选「规则」(默认)表示不单独设置、按默认走向走。识别依据是请求携带的 API 密钥 + 目标主机名(v0.6.0 组合识别,Google 原生协议的 x-goog-api-key 头同样参与)
3. 默认走向:未单独设置的账号(以及一切非 LLM 流量)走哪条路——建议 direct,让新流量默认不绕代理。其下方「直连的行为」默认绝对直连:被选为直连的请求由本插件强制直连,无视 DSH 全局代理与其他代理设置;想交回 DSH 原生策略可切换为「遵循全局代理」
4. 内置联网工具代理(可选,v0.5.0):想让 web_fetch 抓境外网页、MCP 子进程等未认领流量也走代理时勾选,填一个 http:// 代理的 host:port(如 127.0.0.1:10000,http:// 前缀已固定;v0.5.1 起支持认证,写 user:pass@host:port,密码特殊字符须 URL 编码如 @ → %40)——保存即生效、无需重启,关闭或卸载插件时自动还原 DSH 原有全局设置
5. 点「保存」,立即生效
验证生效
随便给一个走代理的模型发条消息,然后在日志里找这一行(格式:账号=>代理名:地址):
[proxy-routes] POST api.anthropic.com/v1/messages -> claude1=>main:socks5://127.0.0.1:50939
日志在哪看:
- DSH Desktop(Windows):
%APPDATA%\DSH Desktop\logs\host\dsh-<日期>.log(Win+R 输入%APPDATA%\DSH Desktop\logs\host回车,打开今天日期的文件,搜[proxy-routes]) dsh web:运行它的那个控制台窗口
直连的请求不打印;日志只含去向,绝不包含 API 密钥。关掉「其他选项 → 打印每次走代理的请求日志」可以静音。
卡片功能细节
代理池
- 三种协议混用,可带认证(
socks5://user:pass@host:port): socks5://127.0.0.1:1080—— 域名解析交给代理端(等效 socks5h,防 DNS 污染)http://127.0.0.1:7890—— HTTP CONNECT 隧道https://127.0.0.1:7891—— 代理端 TLS- 混合端口(同一端口同时收 http 和 socks,如 xray 常见配置)两种写法都行,按你写的协议分发
- 「测试」探测的是「其他选项」里的
probeUrl。默认https://www.gstatic.com/generate_204在大陆直连是被墙的——建议改成墙内外都可达的地址(如https://www.baidu.com),这样「直连」和「走代理」两边的测试结果才都真实 - 名称可以随时改(不会丢焦点),删除前先确认没有走向还在引用它——引用了不存在名字的规则会回退直连并在日志警告
按提供商(账号)分流
- 提供商列表 = DSH「模型」页里的 LLM 账号,自动出现/更新,无需手动添加
- 下拉选项 = 直连 + 代理池里的每个名字(池为空时只有直连)
- 「规则」= 不单独设置 → 走默认走向
- 每行的「测试」按该提供商当前生效的路由探测;没有单独设置的账号测的就是默认走向
它是怎么认出账号的(原理一瞥)
DSH 发出的每个 LLM 请求都带着该账号的 API 密钥头(x-api-key / authorization: Bearer)。插件在 fetch 层提取密钥、匹配「密钥 → 提供商」映射(启动时经 DSH settings + credentials 服务在内存中建立),即可判断这次请求属于哪个账号。密钥只在内存中匹配,绝不写日志、绝不外发。
路由优先级:提供商显式走向 > 默认走向。
直连的行为(v0.5.0)
默认走向与各提供商的「直连」都由这一对单选决定,默认「绝对直连」:
- 绝对直连:直连请求由本插件用自建 dispatcher 发出,在传输层就绕开官方 dsh-http-proxy 安装的全局代理——不管系统设没设
HTTP(S)_PROXY、也不受其他代理插件干扰,「直连」就是字面意义的直连。调用国内模型飞快,不被任何全局代理拖累 - 遵循全局代理:回到 v0.4 的语义——本插件对直连请求不干预,交回 DSH 原生出站策略(若设置了
HTTP(S)_PROXY环境变量则随之走代理) - 两种模式下,配了代理的提供商都走自己的代理,不受影响
「测试」按钮按同样语义探测:绝对直连时,直连测试走的就是插件自建 dispatcher,测出来的即真实路径。
内置联网工具代理(v0.5.0)
DSH 内置的 web_fetch 抓取、之后启动的 MCP 子进程、以及一切未被本插件认领的流量,默认不经过本插件——它们归官方全局出站策略管。勾选本模块即可在卡片里直接驱动该策略:
- 只支持 http:// 代理(官方 dsh-http-proxy 拒收 SOCKS URL),因此地址固定为
http://前缀 +host:port(如127.0.0.1:10000),输入框只填host:port;v0.5.1 起支持带认证——填user:pass@host:port即可,密码中的特殊字符须 URL 编码(@→%40、:→%3A) - 保存即生效,无需重启 DSH,也完全不需要设置系统环境变量——插件热装官方全局策略;关闭或卸载时自动原样还原,系统原有的
HTTP(S)_PROXY配置不受破坏。海外环境可直接填商用代理的远程地址(含用户名密码),不必先用 xray 等工具把端口映射到本机 - 典型场景:模型 API 走国内端点、被本插件认领为绝对直连——飞快;同时
web_fetch抓境外网页走这里配的代理——不被墙。两者互不干扰,这就是「直连的行为」作为底层保证的意义 - 回环地址(localhost / 127.0.0.1)永远自动豁免,本地流量不会被送进代理
兼容性
DSH 版本 · 设置机制 · 卡片入口
Desktop 2.0.14(dsh 0.1.7) · 从插件 Config schema 派生条目表单 · 设置 → 代理路由 + 插件页详情
Desktop 2.0.13(dsh 0.1.5-rc.2) · settings 命名空间 · 设置 → 插件 → 代理路由
更老(< 0.1.0-rc.7) · 无设置机制 · 仅文件模式(见下文)
传输层要求 DSH ≥ 0.1.3(自带 undici ≥ 7.10,含 Socks5ProxyAgent);「内置联网工具代理」的热装依赖宿主自带的 @deepseek-ai/dsh-http-proxy(同版本起均内置,无需额外安装)。
常见问题(排障)
重装/升级时报 ERR_PNPM_EPERM(operation not permitted)
Windows 文件锁:DSH 正在运行时无法替换插件目录。先完全退出 DSH Desktop(托盘 → 退出)再执行 dsh plugin add。如果之前是从本地目录链接安装、后来改从 npm 装,node_modules 里可能残留指向旧目录的 Junction,清理后再装(rmdir 只删链接本身,不碰真实文件):
cmd /c rmdir "C:\Users\<你>\.dsh\profiles\desktop\node_modules\dsh-proxy-routes" cmd /c rmdir "C:\Users\<你>\.dsh\profiles\desktop\node_modules\dsh-proxy-routes_tmp_*" dsh plugin add dsh-proxy-routes
dsh plugin update 拉不到新版本
早期安装记录的是 ^0.1.0 之类的窄范围,永远看不到 0.4.x。解决:dsh plugin remove dsh-proxy-routes 再 dsh plugin add dsh-proxy-routes(remove + add,不要只 update)。
「直连」测试显示不通,但代理其实是好的
默认探测地址 gstatic 在大陆直连被墙。把「其他选项 → 测试连接使用的探测地址」改成 https://www.baidu.com 即可。
界面仍报 "API key is invalid"
看日志里有没有 [proxy-routes] 请求记录:没有 = 路由没命中或插件没加载(确认插件已装、DSH 重启过);有记录但报错 = 代理出口本身的问题。
日志里出现 session-title-service ... maxOutputTokens 警告
那是 DSH 自带的「会话自动起标题」功能的模型输出超限,与本插件无关(请求已被正常路由)。
卡片显示「读取配置失败」
host 桥接没挂上或不是本机访问。确认 DSH ≥ 0.1.0-rc.7 且重启过;从局域网其他设备访问 dsh web 时,桥接的回环校验会拒绝——需要在本插件条目配置里加 trustedOrigins: ["http://<访问地址:端口>"] 放行。
连接 SOCKS5 代理超时 / UND_ERR_SOCKS_AUTH_FAILED
代理客户端没开、端口不对、认证信息错误。
模型联网搜索时,搜索流量走哪条路?和模型的代理设置有关吗?
分三层:① DSH 内置 web_search 是服务端搜索——由搜索端点(默认 DeepSeek)的服务器替你搜,用它们的网络,本机只发一个搜索 API 请求;该请求经本插件路由,但按搜索密钥的归属(通常是默认走向),与当前聊天用哪个模型无关。每次搜索是一次真实的模型调用(默认 deepseek-v4-flash 挂服务端搜索工具),要扣费:当前会话跑 DeepSeek 账号模型时用 DSH 登录账号额度,跑其他模型(含第三方)时用配置的 DEEPSEEK_API_KEY(凭据服务 / 环境变量 / 搜索配置字面量),两者都拿不到则直接报错、不做搜索。给这把 key 配的代理只影响「本机 ↔ 搜索端点」这段传输,搜索本身仍在服务端完成,代理设不设不改变搜索性质。② 内置 web_fetch 抓取不经过本插件(见已知限制)。③ 若模型服务商自身带搜索能力(服务端工具),搜索同样在服务商的服务器上执行。
不同账号用了同一个 API 密钥,分得清吗?
先说清一个事实:API 密钥本身就是厂商侧的账号身份——两个独立账号
…(truncated)
Rendered from the README published on npm. Formatted only, not edited.
Versions
Published on npm::9,最后更新 2026-11-02