dsh-model-proxy
English | 中文
把 DeepSeek Harness 的模型 API 请求送进代理,让第三方海外模型服务在国内网络下可用;
清单之外的请求一律直连——网页搜索、抓取页面、MCP 服务和工具调用,除非你把它们的域名
加进清单,否则不会经过代理。
- 不修改 harness 的任何文件;卸载后行为与安装前完全一致
- 支持系统代理、自定义代理(
http/https/socks4/socks4a/socks5/socks5h)或环境变量代理 - 全局或按域名分流;域名规则支持精确主机名、通配符和后缀
- 三条安全约束,配置无法放宽(见下文)
安装
dsh plugin --profile <你的 profile> add github:recyvan/dsh-model-proxy
安装后重启 DSH——宿主部分是在 harness 进程内加载的。
需要 DSH 0.2.1-rc.2 或更新版本。设置页由宿主按插件的 Config schema 生成
(0.2.x 移除了宿主侧的 settings 服务和客户端的 settingsScope 服务),
更老的 harness 会在安装阶段被拒绝。
配置
打开 设置 → 模型代理(设置左侧独立一页)。
| 字段 | 含义 |
|---|---|
| 模式 | rule(推荐)/ system / custom / off |
| 代理协议 | http / https / socks5 / socks5h / socks4 |
| 代理地址 | socks5h://127.0.0.1:7890,或直接写 127.0.0.1:7890(协议按“代理协议”字段补齐) |
| 仅代理这些域名 | 留空 = 内置预设;填写 = 只代理这些(逗号分隔,如 *.openai.com、.aiplatform.googleapis.com) |
| 排除域名 | 始终直连,优先级最高 |
改动在下一个请求生效,不需要重启。
三种常见配法
A. Clash / V2Ray 在 127.0.0.1:7890,只代理海外 API
模式 = rule,协议 = http,地址 = 127.0.0.1:7890,域名列表留空。
预设会把 OpenAI / Anthropic / Gemini / xAI / Groq / OpenRouter 等送进代理,
DeepSeek、DashScope、智谱、Kimi 等国内服务保持直连。
B. 跟随 Windows 系统代理
模式 = system。插件每 30 秒重读一次
HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings,跟随系统里的改动。
C. 全部走代理,只留少数例外
模式 = custom,填好地址,把例外域名写进“排除域名”。
国内访问海外 API 的注意事项
- DNS 污染:优先用
socks5h(由代理解析 DNS),或让你的代理客户端接管 DNS。 - 明文
http默认被拒绝——API Key 不应该以明文穿过代理。确实需要时,在设置页里勾选对应选项。 - 代理必须监听回环地址;请在代理客户端里打开本地/局域网监听。
验证
- 设置页显示实时状态:
path A · exit route · N rules · proxied x / direct y。 http://127.0.0.1:/dsh-model-proxy/status返回同一份快照的 JSON
(仅限回环 / 同源访问)。- 在源码仓库里跑
npm test(等价于node test/run-all.mjs)。测试套件随仓库发布、
不在 npm 包里,也不需要安装依赖——它会从你的 DSH profile(或DSH_HOME)里取宿主自己的
undici与@deepseek-ai/schemastery。
安全约束
无论怎么配置都成立,也是规则引擎最先检查的内容:
- 强制直连——回环地址、私有网段(
10/8、172.16/12、192.168/16、
169.254/16、fc00::/7等)、localhost以及.local/.lan/.internal这类名字
永远不会走代理。用户规则可以新增条目,但不能删掉这些。 - 明文闸门——非
https的模型请求在打开任何 socket 之前就被拒绝,除非显式开启该选项
(此时设置页会持续显示警告)。 - 数据最小化——插件以流的方式透传请求和响应体;从不解析它们、从不写入磁盘,
也从不读取Authorization或任何厂商的 API Key。默认日志只记录出口标识和错误类别,
不含主机名、不含路径、不含请求体。
出口失败时回落到直连,绝不换到另一个出口:悄悄把流量挪到别的出口,等于在用户
不知情的情况下改变出网身份。
出口失败时回落到直连,绝不换到另一个出口:悄悄把流量挪到别的出口,等于在用户
不知情的情况下改变出网身份。回落会记日志并显示在设置页上,降级状态是看得见的。
开发
lib/index.js Cordis 宿主入口——唯一接触 harness API 的文件
lib/client.js 设置页(`__ModuleLoader__` 浏览器入口)
lib/core/* 纯逻辑,不依赖 harness,可独立测试
test/run-all.mjs 测试套件:先跑纯逻辑各组,再跑入口文件冒烟
undici 与 @deepseek-ai/schemastery 都是 peer——宿主已经带了,再装一份会让进程里出现
两个 dispatcher / Schema 实例。devDependencies 里的同名条目只是为了让 npm test
能在 DSH 之外跑;测试本身优先用宿主那份。
限制
- 只覆盖走
fetch的请求——实际就是全部模型请求,外加你把域名加进清单的其它fetch
流量。transport: websocket流式传输和各厂商原生 SDK 通道(例如 Amazon Bedrock)不走
fetch,这里代理不到——这类请用 harness 自带的环境变量代理。抓取网页同理:harness 的
抓取工具自建undiciagent,域名规则看不到它。 - 分流按域名进行。若某个域名同时承载模型 API 和其他流量,它的全部流量都会进代理;
把这类域名写进“排除域名”。 - 代理凭据只能写在代理地址里(
http://user:pass@host:port),会以明文保存在设置中。
建议让代理直接接受回环连接、不做认证。 - 支持任意跳数的代理链:每一跳的 CONNECT 经由上一跳转发,顺序与配置一致。
每一跳都是真的——测试用三个 CONNECT 桩逐跳断言实际拨向的端口。
验证连通性
设置页有「测试代理」按钮:用当前出口真实发一次请求,回报耗时、HTTP 状态与失败分类,
不回报主机名与响应体。它回答的是诊断页回答不了的那个问题:到底是代理的问题,还是别的原因?
卸载
dsh plugin --profile <你的 profile> remove dsh-model-proxy
dsh --profile <你的 profile>
卸载后 DSH 恢复完全直连——没有配置残留,也不再有监听端口。
许可证
MIT