前言¶
DSH 的 web_fetch 在直连环境里工作正常,但一旦开着 Clash、Surge、v2rayN 这类软件,抓取就很容易失败。排查下来通常是两类问题:TUN 模式把域名解析成 198.18.x.x 这样的假地址,直连安全检查直接拒绝;或者只开了「系统代理」、没开 TUN,DSH 不读系统代理,需要代理的网站打不开。把 HTTP_PROXY 写死进 ~/.dsh/.env 确实能连上,可代理一关,模型对话也跟着断。
下面介绍 dsh-proxy-switch,它就是为这种场景写的插件。
这是什么¶
- 维护者:lightrivers
- 包名:
@lightrivers/dsh-proxy-switch,版本0.4.4,许可证 MIT - GitHub:https://github.com/lightrivers/dsh-proxy-switch
- 目录页:https://www.skillhub.cn/plugins/lightrivers/dsh-proxy-switch,分类「联网工具」,目录页标注星标 0
一句话定位:自动找到本机 HTTP 代理,代理开着时让 web_fetch 走代理,代理关掉后自动改直连,给 web_fetch 单独开一条可切换的线路。默认作用范围是「仅 web_fetch」,不修改全局网络设置、进程环境变量和子进程环境,模型对话和其它工具不受影响。
它解决什么问题¶
README 列出的适用情况:
web_fetch报non-public IP address,或域名被解析到198.18.x.x- 代理开了 TUN / 增强模式 / fake-IP,
web_fetch失败 - 只开了系统代理、没开 TUN,DSH 读不到系统代理,打不开需要代理的网站
- 写死
HTTP_PROXY后代理一关,连模型对话都断了 - 每次开关代理都要手动改配置
原因是 TUN 模式会把域名解析到 198.18.0.0/15 段的假地址,web_fetch 直连时的安全检查不允许访问内网地址;而一旦代理地址写死,代理关闭后什么都连不上。插件在这两条路径之外给 web_fetch 一条可切换的线路。
需要说明的是,README 明确指出:DeepSeek Harness 0.2.2 起,web_fetch 不再拒绝 fake-IP 和内网地址,只用 TUN 的话新版不装插件也能抓网页。插件仍然适合只开系统代理的用户、需要根据代理开关自动切换的用户;另外直连时插件仍只允许公网地址,可以挡住对本机和内网服务的访问。
环境要求¶
| 项目 | 要求 |
|---|---|
| DeepSeek Harness | 桌面版 0.2.1、0.2.2(0.2.2-rc.1 已测) |
| 系统 | macOS(已完整验证);Windows、Linux(代码已支持,尚未在真机完整验证) |
| 代理 | 本机 HTTP 代理或「混合端口」(Clash / mihomo / Clash Verge、Surge、v2rayN 等),不支持 SOCKS、PAC |
核心功能¶
1、自动检测代理。优先读取系统代理设置(macOS 网络设置、Windows Internet 选项、Linux GNOME/KDE 代理设置),找不到再读 DSH 启动时的 HTTPS_PROXY 等环境变量,最后扫描常见端口 7890、7897、6152、1087、10809 等。每个候选地址都会做实际握手验证,确认真的是 HTTP 代理才使用。
2、三种线路:auto(跟随检测结果)、forward(固定走代理)、direct(固定直连)。默认 auto。每次 web_fetch 之前插件会先在本机测一下代理端口,约 1 毫秒,代理刚关也不会走错线路;代理找不到时一律直连,直连的安全检查照常进行。
3、作用范围可切换。默认 web_fetch_only,只有主动选择 global 时其它模块才跟着走这条线路。
4、代理需要账号密码时可手动填写 http://user:pass@地址:端口。密码只保存在本机,权限为 600,界面、日志和提示里一律显示为 ***。
5、web_fetch 的结果里会附上当前状态提示,模型能看到并告诉你。
安装与启用¶
在 DeepSeek Harness 里对模型说下面这句话,然后完全退出并重新打开 DSH:
用 plugin_manager 安装插件 @lightrivers/dsh-proxy-switch
重启后侧栏底部右边会多出一个小按钮,显示当前线路和状态圆点(例如「走代理 ●」)。
如果以前在
~/.dsh/.env里写过HTTP_PROXY/HTTPS_PROXY,先删掉它们再重启。否则插件关掉后,DSH 还会回到写死的代理。
README 另给出了从源码安装的步骤:下载源码到 ~/dsh-proxy-switch,然后对模型说「用 plugin_manager 安装插件 ~/dsh-proxy-switch」(它会执行 plugin_manager action=install_bundle target=<绝对路径>),再完全退出并重新打开 DSH。升级时在源码目录 git pull,再执行一次安装步骤。本文只转述 README 原文,实际安装请使用上面的官方安装方式。
从 0.4.1 及更早版本升级时(0.4.2 起包名改为 @lightrivers/dsh-proxy-switch),先让模型用 plugin_manager 卸载旧的 dsh-proxy-switch,再按上面的方法安装新版,设置和状态会保留。
典型用法¶
大多数人装好后什么都不用做。默认是「自动」:插件读取系统代理设置,找到代理端口,代理运行时 web_fetch 走代理,代理关掉后自动改直连。
点侧栏底部的按钮打开面板,主要区域:
- 最上面一大块:当前走的是哪条线路。线条在流动表示通畅,出问题时符号标在出问题的地方(✕ 表示那里断了,🔒 表示代理要登录,❗ 表示不稳定)。右上角的小标签是作用范围:「仅 web_fetch」或「所有工具」。
- 自动 / 走代理 / 直连:选线路。
- 代理那一行:找到的代理地址、怎么找到的(系统代理、环境变量或端口扫描),以及延迟;右边按钮可以重新检测。
- 更多设置:手动填写代理地址、作用范围、按钮放在哪里。
按钮上的圆点:🟢 正常,🟠 需要处理,🔴 出现问题,⚪ 正在检测。
左侧栏底部可能挤着好几个插件按钮,可以在「更多设置 → 按钮位置」里改成对话顶栏(适合侧栏常收起的人,Windows 上侧栏收起时默认那一行会被隐藏)或不显示。选「不显示」后设置仍在「插件 → 代理开关」页面里。
线路和代理状态对不上时,面板会给一句话说明和一个修复按钮,按按钮上的说明操作即可:固定直连但代理开着时点「改为自动」;代理在运行但找不到端口时点「手动填写地址」,只填端口号(例如 7890)就行。
配置与状态¶
面板里能改的设置保存在 ~/.dsh/storages/dsh-proxy-switch/state.json(目录权限 0700、文件权限 0600),一般不需要手动编辑。
| 字段 | 默认 | 说明 |
|---|---|---|
mode |
auto |
auto / forward(固定走代理)/ direct(固定直连) |
upstreamSource |
auto |
auto 时代理地址由检测结果更新;manual 时只使用手动填写的地址 |
upstream |
http://127.0.0.1:1082 |
代理地址,只接受 http://host:port,可带 user:pass@ |
scope |
web_fetch_only |
web_fetch_only(仅 web_fetch)/ global(所有工具) |
listenPort |
7899 |
仅「所有工具」模式使用的本地端口 |
probeIntervalMs |
15000 |
后台检测代理的间隔(3000–600000 毫秒),界面里不提供修改 |
按钮位置是浏览器端偏好,保存在 localStorage 的 dsh-proxy-switch.placement 里。
插件另提供本机状态接口:
GET /dsh-proxy-switch/state
POST /dsh-proxy-switch/mode { "mode": "auto" | "forward" | "direct" }
POST /dsh-proxy-switch/settings { "scope"?, "upstream"?, "upstreamSource"?, "listenPort"?, "probeIntervalMs"? }
POST /dsh-proxy-switch/probe 立即检测一次当前代理
POST /dsh-proxy-switch/detect 立即重新查找代理
接口只接受本机请求,Host 必须是 DSH 自己的地址,并校验 Origin、Sec-Fetch-Site;POST 还要求 Content-Type: application/json 和请求头 x-dsh-proxy-switch-request: 1。
工作原理¶
插件只替换 web_fetch 的「发请求」这一步:请求先进入插件自己的 web_fetch 提供者,再经本机私有通道(随机端口,只监听 127.0.0.1),之后分流到 HTTP 代理或直连目标网站。重定向、超时、大小限制、编码处理仍沿用 DSH 原来的实现。
- 直连时整组 DNS 结果都必须是公网地址,fake-IP、内网、回环、NAT64 内嵌私网地址等一律拒绝。
- 走代理时,
localhost、.local、.lan这类本地名字和在本机解析出内网地址的目标会被拒绝,但最终由代理解析,所以只是缓解。 - 私有通道每次启动生成随机令牌,本机其它程序无法借用它(以及保存的代理账号密码);每个请求使用新连接,切换线路后不会沿用旧的代理隧道。
适用场景与注意¶
适合:TUN / fake-IP 环境下 DSH web_fetch 失败、只开系统代理没开 TUN、希望代理开关时自动切换线路、希望 web_fetch 结果带状态提示的用户。
需要注意:
- 只支持 HTTP 代理(或混合端口),不支持 SOCKS、PAC。需要账号密码时用
http://user:pass@host:port形式手动填写。 - 目前只在 macOS 上完整验证过,Windows、Linux 代码已支持但尚未真机验证。
- 插件以当前 DSH 进程的权限运行,安装前建议先读一遍源码和 LICENSE(MIT),确认来源可信。
- 走代理时的内网访问拦截只能缓解,不能保证百分之百。开着 TUN 时本机只能解析到假地址,插件判断不了真实目标;如果 DNS 被污染把正常网站解析成内网地址,走代理时该网站会被误拒,提示为「转发模式拒绝请求」,打开 TUN 或换可信 DNS 可恢复。
- README 提醒:插件依赖必须写在
peerDependencies里,不能写进dependencies,否则会装出第二份@deepseek-ai/dsh-http-proxy,「所有工具」模式会静默失效。 - README 另给出测试命令:
npm test(单元测试)、DSH_RUNTIME_MODULES=/path/to/dsh/node_modules node scripts/e2e-host.mjs(真实 Cordis/WebRuntime 集成测试)、node scripts/e2e-real.mjs(可选,经过本机真实 HTTP 代理)、node scripts/e2e-web-fetch-warning.mjs(web_fetch结果附带的警告文本)。
结尾¶
dsh-proxy-switch 的价值不在于新增能力,而是把 web_fetch 在代理环境下的线路选择从「手写 HTTP_PROXY 赌一把」变成「自动检测、可一键切换、默认不波及其它工具」。是否安装取决于你平时是否开着 TUN 或只开系统代理。插件目录页:https://www.skillhub.cn/plugins/lightrivers/dsh-proxy-switch ,源码:https://github.com/lightrivers/dsh-proxy-switch 。