前言¶
DeepSeek Harness(DSH)在 ctx.web seam 上每次只解析一个 search provider,provider 也只有一个 model 字段,没有失败重试链。一旦上游出错(HTTP 错误、没有 web_search_tool_result 结果块或返回空结果),整次搜索就失败。new-api 的自动换渠道只在“同一个模型名有多个渠道”时生效,要么在网关造别名,要么在 harness 侧做故障转移。本插件选后者:保持网关上的官方模型名,通过顺序尝试多个后端,在任一后端失败时自动切换到下一个,直到所有后端都失败才报错。
这是什么¶
dsh-web-search-failover 是 DeepSeek Harness 的联网工具类插件,由维护者 xingzoudefengye 提供。它注册了一个 deepseek-failover provider,按顺序尝试一组搜索后端。当主后端失败或返回空结果时,插件会自动切换到下一个后端,直到所有后端都尝试完。插件通过 patch 自身禁用默认的 web-search-deepsearch 行,无需手动编辑 profile。插件本身纯 JS、无构建步骤,依赖 DSH ≥ 0.2.1 与 Node ≥ 22。
核心功能¶
- 注册
deepseek-failoverprovider,替换默认搜索 provider。 - 支持有序后端列表,第 0 个优先,后续为备胎。
- 失败判定:抛错、成功但没有 sources,但不处理
WEB_ABORTED(用户取消)。 - 通过
backends配置项逐个构造 provider,每项独立指定model、baseURL和apiKeyEnv。 - 通过
cordis.patch.ymlpatch 自身,禁用默认web-search-deepseek行。 - 插件无构建步骤,纯 JS,不会触发 pnpm 的
allowBuilds拦截。
安装与启用¶
前置条件:
- DSH ≥ 0.2.1
- Node ≥ 22,且
pnpm在 PATH 上 - 能访问
https://codeload.github.com - 一个 OpenAI/Anthropic 兼容的搜索网关及其 API key
在 web profile 下安装:
dsh plugin --profile web add github:xingzoudefengye/dsh-web-search-failover
Windows 上完全一样:
dsh plugin --profile web add github:xingzoudefengye/dsh-web-search-failover
安装后必须重启 DSH(关掉 dsh web 的终端再重新起)。插件在 host 启动时 import,不重启不会生效。
Desktop 版 profile 名是 desktop,需要先完全退出应用再加:
dsh plugin --profile desktop add github:xingzoudefengye/dsh-web-search-failover
凭据配置¶
插件的 apiKeyEnv 指向一个凭据引用名,不是明文。把网关令牌写入 harness 的凭据文件:
- macOS / Linux:
~/.dsh/.credentials.yaml - Windows:
%USERPROFILE%\.dsh\.credentials.yaml
示例:
refs:
NEWAPI_API_KEY: sk-...
该文件由 harness 的 credentials 插件注入,不需要写系统环境变量。如果更习惯环境变量,可以把 apiKeyEnv 改成对应的变量名。
配置示例¶
在 profile 的 cordis.patch.yml 里覆盖 id: web-search-failover 的 config。插件默认顺序为 deepseek-v4-flash → claude-haiku-5-5,不覆盖则按此走:
- id: web-search-failover
config:
providerId: deepseek-failover # ctx.web 选中的 provider 名,一般不用改
backends:
- { model: deepseek-v4-flash, baseURL: https://your-gateway/v1, apiKeyEnv: NEWAPI_API_KEY }
- { model: claude-haiku-5-5, baseURL: https://your-gateway/v1, apiKeyEnv: NEWAPI_API_KEY }
配置项说明:
| 键 | 默认 | 作用 |
|---|---|---|
providerId |
deepseek-failover |
注册给 ctx.web 的 provider 名;bundle patch 里 web.searchProvider 必须与它一致 |
backends |
— | 有序列表,第 0 个优先,其后都是备胎;每项 model / baseURL / apiKeyEnv 各自独立 |
apiKeyEnv / baseURL / apiKey / apiVersion / maxTokens / maxUses |
见 lib/index.js 的 Config |
旧式单后端字段;用 backends 时不需要,插件按 backend 逐个构造 provider |
失败判定:抛错、或成功但没有 sources。WEB_ABORTED(用户取消)直接向上抛,不换后端。全部失败才返回最后一个错误;如果所有后端都成功但确实没结果,返回那个空结果。
验证安装¶
执行以下命令,应看到 searchProvider: deepseek-failover:
dsh --profile web --dump-config | grep -A3 "searchProvider"
PowerShell:
dsh --profile web --dump-config | Select-String -Pattern "searchProvider" -Context 0,3
再做一次真实搜索,网关日志里会出现主后端的模型名;只有主后端失败时才会多一条备用后端。
注意:插件自带的 cordis.patch.yml 里 baseURL 写的是示例网关(http://43.133.21.227:3000/v1),请改成你自己的网关地址。
适用场景与注意¶
- 适合需要多个搜索后端、希望自动切换的场景,如主后端不稳定或需要混合使用不同模型进行搜索。
- 插件以当前 dsh 进程的权限运行,安装前建议检查源码与许可证。
- 插件不处理
WEB_ABORTED,用户取消不会触发备用后端。 - 旧式单后端字段(
apiKeyEnv、baseURL等)在配置backends时不需要。
卸载¶
dsh plugin --profile web remove dsh-web-search-failover
然后重启 DSH。bundle 的 patch 随之失效,harness 原有的 web-search-deepsearch 行会恢复;如果你之前手工在 profile patch 里删过它,需要自己加回来。
同步到另一台机器¶
逻辑全在插件里,换机器不需要搬配置,但要满足四件事:
- 装插件:运行
dsh plugin add github:xingzoudefengye/dsh-web-search-failover。版本自动跟master最新提交,两台机器不必同 commit,但 harness 版本要一致(都 ≥ 0.2.1)。 - 凭据:
.credentials.yaml的refs:里要有NEWAPI_API_KEY。 - 清掉旧的 provider 行:profile patch 里若还有
- id: web-search-deepsearch,删掉。 - 网关可达:
baseURL换成本机可访问的地址。
排错¶
| 现象 | 原因 | 处理 |
|---|---|---|
dsh plugin add 成功,但搜索行为没变 |
插件在 host 进程启动时 import,进程里的模块不会热替换 | 重启 DSH(关掉 dsh web 再起) |
改了插件源码(哪怕是 lib/index.js)也不生效 |
Node 的 ESM 缓存:已 import 的模块不会重新执行 | 同上,重启 host;GitHub 安装还需先 dsh plugin add 重装以拉新代码 |
dsh plugin add 卡住或报网络错误 |
拉的是 codeload.github.com 的 tarball,公司网络/代理常拦 |
走代理,或把仓库整目录拷过去,依赖改成 file: 路径后 pnpm install(插件无外部 npm 依赖,离线可装) |
报 WEB_PROVIDER_UNAVAILABLE |
所有 backends 都 available() === false,通常是 apiKeyEnv 指向的引用没有值 |
检查 .credentials.yaml 的 refs: 里有该键,且键名与 apiKeyEnv 完全一致 |
| 搜索一直是备用后端的模型 | 主后端失败但未报错(返回空结果也会触发回落) | 看网关日志确认主后端返回码;密钥额度、模型名拼写是最常见原因 |
配置树里出现同一个 row id 冲突(web-search-deepsearch 被两处同时声明) |
profile patch 里手工加过 id: web-search-deepsearch 的行,与 bundle patch 打架 |
删掉 profile 里那一行,插件自带的 patch 已负责禁用它 |
开发¶
本仓库是纯 JS、无构建步骤。仓库里没有 node_modules,直接 npm test 会因为找不到 @deepseek-ai/* 的 peer 依赖而失败 —— 先把本机已安装的 harness 包链进来:
node scripts/dev-link.mjs # 探测 dsh 的安装位置,链入 schemastery / dsh-web / dsh-web-search-deepseek 等
npm test # node --test
dev-link 依次探测:dsh 可执行文件所在的 npm 目录、$DSH_HOME/profiles/<profile>、$DSH_HOME/profiles、$DSH_HOME,也可以用第一个参数或 DSH_PACKAGE_DIR 直接指定 @deepseek-ai/dsh-* 所在目录。Windows 上用 junction,不需要管理员权限。
改完代码在本地验证,再装到 profile:dsh plugin --profile web add <本仓库绝对路径> 走 link: 依赖,配合 dev-link 即可改完重启 host 就看到效果。
生态背景¶
DeepSeek Harness 的理念是「一切皆插件」,社区目录 SkillHub 与 DeepSeek / 幻方无官方从属关系,仅作为插件索引与展示。本插件遵循 MIT 许可证,由维护者 xingzoudefengye 维护。
相关插件¶
同作者、同一套安装方式(dsh plugin add github:xingzoudefengye/<repo>):
- dsh-browser — 给 agent 一个可驱动的真实浏览器,侧栏并排显示
- dsh-compaction-local-handoff — 无模型的本地交接式压缩
- dsh-project-memory — 有界、可提交进 git 的项目记忆
- dsh-resume-budget — 会话恢复时的输入预算控制
- dsh-session-recall — 无模型、有界的会话史书
结语¶
本插件通过有序后端列表与自动切换机制,解决了 DeepSeek Harness 单一搜索 provider 失败导致整次搜索失败的问题,适合需要高可用搜索能力的场景。更多细节与源码请参考:GitHub | SkillHub 目录页