Failover Search
@tnnevol/dsh-failover-search 为 DSH 的会话内网页搜索提供多个搜索来源,并按 TinyFish → Tavily → 官方搜索 的顺序自动故障转移。配置三方 key 后,搜索优先由三方服务完成,官方搜索只在前面的来源都不可用时兜底。
同一平台可以配置多个账号:请求在这些账号之间轮转分摊,某个账号额度不足或请求失败时先换同平台其它账号,再落到下一平台。
安装
在 fnOS 上使用 DSH 时,插件随应用安装或升级自动安装。其他 DSH 环境可执行:
dsh plugin --profile web add @tnnevol/dsh-failover-search@7.0.2安装后重启 DSH Web profile。插件版本信息见插件总览。
安装前先关掉官方「网络搜索」通道:官方「设置 → 插件 → 内置插件设置 → 网络搜索」页保存时,会把
web行的searchProvider/fetchProvider写成官方 id。DSH 的网页接缝是固定选择语义——配了哪个 id 就只用那个提供方,其它提供方即使注册成功也不会被走到。因此那页每保存一次,本插件就会被顶掉一次:插件照常加载、账号与用量都正常,但web_search/web_fetch走的是官方端点(官方余额耗尽时直接返回 HTTP 402)。
- 安装本插件前,先确认该页没有开启官方搜索/抓取通道;
- 已经开过的不用重装:把消息框左下角的「智能搜索」开关关闭再打开一次,插件会自动把
web选择写回自己。
搜索来源与转移顺序
配置 key 后发起搜索时,插件按以下顺序尝试来源,第一个成功的来源返回结果:
flowchart LR
A[会话发起搜索] --> B{TinyFish 已配置?}
B -->|是| C[尝试 TinyFish 账号]
B -->|否| D{Tavily 已配置?}
C -->|失败| D
C -->|成功| Z[返回结果]
D -->|是| E[尝试 Tavily 账号]
D -->|否| F[官方搜索兜底]
E -->|失败| F
E -->|成功| Z
F --> Z- 未配置 key 的来源被直接跳过,不产生等待。
- 一次搜索最多把已配置来源各尝试一遍,不做跨来源重试。
- 用户主动取消的搜索直接中止,不触发转移。
- 全部来源都失败时,模型收到带错误码的失败信息,而不是空结果。
配置项说明
全部配置在插件管理页 → Failover Search 详情页的配置区完成,保存后下一次搜索立即生效,无需重启。设置弹框中没有本插件的配置入口。
下表与插件详情页的表单逐项对应。

搜索来源与账号
| 配置项 | 说明 | 取值范围 | 默认值 |
|---|---|---|---|
| TinyFish 账号 | TinyFish 平台的一个或多个 API key,每项可附备注名(如 tinyfish-1)用于展示与日志区分 | 每项为非空字符串;至少 1 项才启用该平台 | 空(平台禁用) |
| Tavily 账号 | Tavily 平台的一个或多个 API key,每项可附备注名 | 同上 | 空(平台禁用) |
| 来源顺序 | 三个来源的尝试顺序;官方搜索固定参与,作为兜底可调整位置但不可移除 | TinyFish、Tavily、官方搜索的任意排列 | TinyFish → Tavily → 官方搜索 |
均摊与转移
| 配置项 | 说明 | 取值范围 | 默认值 |
|---|---|---|---|
| 每来源超时 | 单个账号一次搜索请求的超时时间(毫秒) | 正整数;须小于工具层总预算(60 秒) | 15000 |
| 同平台重试 | 某账号请求失败后,是否继续尝试同平台其它账号 | 开 / 关 | 开 |
用量展示与探测
| 配置项 | 说明 | 取值范围 | 默认值 |
|---|---|---|---|
| 用量刷新间隔 | 平台用量快照的后台刷新周期(分钟) | 正整数(1–60) | 5 |
| 请求前探测 | 是否启用基于用量快照的请求前账号排除 | 开 / 关 | 开 |
多账号分摊
同一平台配置多个 key 时,请求按轮转方式分摊到各账号,不会集中在单一账号上消耗:
- 某个账号在请求前被探测排除,或请求失败,同一查询内先换同平台其它账号,再落到下一平台;平台顺序不因账号变化而乱序。
- 只配置一个账号时退化为直连,行为与无均摊一致。
- TinyFish 的限流按 API key 计,多 key 会线性扩大每分钟请求容量;Tavily 的套餐配额按账户计,同一账户下的多个 key 不扩大配额,多 key 的价值是失效冗余与单 key 限流分散。
用量展示与请求前探测
插件详情页的「平台用量」区块按平台分列各账号:

- Tavily:Key 用量、套餐名称与套餐已用/上限。
- TinyFish:钱包余额、自动充值状态与搜索单价。
数据带获取时间,来自平台免费查询端点,后台按配置周期自动刷新,不产生平台计费调用。某个账号查询失败时,该账号显示可理解的失败提示,不影响其它账号,也不影响搜索。
探测在每次搜索前参考缓存的用量快照:快照显示额度不足或已触限的账号被提前跳过,请求直接落到同平台其它账号或下一平台。快照过期或尚未生成时按「无用量信息」处理,退化为失败后再转移——探测是优化,不会阻塞搜索。
结果呈现
三方来源的结果在会话搜索卡片中的呈现与官方来源一致:标题、链接与摘要都会展示;来源返回发布日期时展示日期,未返回时不显示占位内容。结果数量沿用现行搜索上限规则,超出上限时截断。
用量展示与手动刷新
插件详情页的「平台用量」区块按平台分列各账号的用量(TinyFish 钱包余额与自动充值状态、Tavily key 用量与套餐已用/上限),数据带获取时间。
- 后台自动刷新:按配置的「用量刷新间隔」(默认 5 分钟)定时重查平台免费查询端点。
- 手动刷新:区块标题右端的「刷新」按钮,点击后立即重查两个平台端点并更新数值与获取时间,不必等满一个刷新周期。刷新期间按钮禁用并显示「刷新中」,避免重复触发多余的平台请求。
- 刷新只查询平台用量端点,不产生平台计费调用;单个账号查询失败时该账号显示失败提示,不影响其它账号与搜索功能。
消息框的「智能搜索」开关
消息框左下角(与「深度思考」同一行区域)有一个「智能搜索」开关:
- 开启(默认):该会话接入本插件——网页搜索按三方优先、官方兜底;网页抓取按本地优先、三方兜底。
- 关闭:该会话完全不接入本插件,搜索与抓取回落到官方来源,已配置的三方账号在该会话内不被调用(配额零消耗)。
- 开关是按会话独立的:在一个会话里关掉,不影响其它会话;切换后下一次搜索立即生效,无需重启或重开会话。
- 重新开启时顺带修复接缝选择:开启动作会检查
web命名空间的searchProvider/fetchProvider,如果它们被写成了官方 id(例如保存过官方「网络搜索」设置页),插件会立即改回dsh-failover-search。所以被官方页顶掉之后,把开关关一次再开一次就能恢复,既不用手改cordis.patch.yml,也不用重装插件。- 只在开启方向写:关闭是会话级偏好,不会改动其它会话的全局选择,也不会把配置改成官方。
- 已经是本插件接管时不产生任何写入。
- 状态只存在内存里、不写入插件配置;DSH 重启后回到默认开启。插件被禁用或卸载时该控件不出现。
网页抓取兜底
除搜索外,本插件也接管网页抓取(web_fetch 工具),采用本地优先 + 平台兜底:
| 跳 | 说明 |
|---|---|
| 1. 本地 HTTP 抓取 | 官方 provider,行为与未安装插件时完全一致(大小/超时/重定向上限同官方默认) |
| 2. TinyFish Fetch | 本地失败且 TinyFish 已配置账号时启用。服务端真浏览器渲染,对 JS 重度页面可用;免费(限 150 URL/分钟) |
| 3. Tavily Extract | 前两跳都失败且 Tavily 已配置账号时启用。计 1 credit / 5 个成功 URL,消耗套餐配额 |
- 为什么需要它:本地抓取在用户侧网络受限时会被安全策略拒绝(例如代理的 fake-ip DNS 让域名解析到保留段),而平台抓取发生在平台服务端,不受本机 DNS/代理/反爬影响。
- 对模型透明:
web_fetch的调用方式与返回结构不变;兜底取回的内容按同样的方式呈现。 - 用户中止立即中断整条链路,不再尝试后续跳。
- 抓取与搜索互相独立:抓取失败不影响搜索,反之亦然;账号复用同一份配置,无需重复填写。
- 本地抓取成功时不产生任何平台调用(不消耗配额)。
- 两平台的抓取差异(同站点实测对照):TinyFish Fetch 返回干净正文(对 GitHub 仓库页实测 2597 字符、0 处导航样板);Tavily Extract 返回整页转换(同页 53091 字符、含 11 处导航样板与 375 个链接)。这是「TinyFish 优先、Tavily 次之」的排序依据——先拿干净正文,需要时再退回更完整的整页内容。
- 站点类型:静态文档站、JS 重度代码托管站(GitHub)、纯文本 raw 资源均已验证可用;目标页面本身不可访问(如 404)时两平台都会报错,链路按失败语义如实透出。
凭据与隐私
- 两个平台的 key 以 secret 角色存储,配置表单不回显明文,也不会出现在会话记录或错误信息中。
- 账号列表展示的是 key 的不可还原掩码(如
sk-tin…KFFtn),用于辨认每一行配的是哪个 key;同平台多个账号时掩码彼此不同。 - 「复制 key」是用户显式触发的单个账号操作:点击时才按「平台 + 代号」取回该账号的明文写入剪贴板,明文不进入页面状态、不落缓存与日志。
- 失败原因只包含平台、状态码与响应片段,不含 key。
- 用量查询只使用平台的免费端点。
停用与回滚
禁用或卸载插件后,网页搜索自动恢复为官方来源,不需要手工修改任何配置:插件的组合配置随插件一起失效,搜索来源回落到发行版基线的官方搜索。插件没有独立持久化数据,用量快照与限流记账都在内存中重建。
常见问题
搜索没有走三方来源
确认已在插件详情页保存了 TinyFish 或 Tavily 的 key。key 为空表示该平台禁用;两个平台都为空时搜索直接使用官方来源。
插件已安装,但网页工具仍走官方端点(提示余额不足 402)
说明 web 行的搜索/抓取选择被写成了官方 id,接缝固定选择官方提供方,本插件的复合提供方不会被调用。最常见的原因是在官方「设置 → 插件 → 内置插件设置 → 网络搜索」页保存过一次——那页的两个选项都是官方 id,且保存即覆盖。
恢复方式(任选其一):
- 把消息框左下角的「智能搜索」开关关闭再打开——插件会把两个键写回自己;
- 手动把
~/.dsh/profiles/<profile>/cordis.patch.yml里- id: web的searchProvider与fetchProvider改成dsh-failover-search,然后重启 DSH。
注意 web 行的 config 是整行替换而不是合并:两个键要一起写,只写一个会让另一个能力回落。以后在那页再点一次保存,覆盖会重新出现,重复上面的恢复步骤即可。
搜索结果变少或缺少日期
TinyFish 的部分查询不返回发布日期,此时卡片不显示日期,这是设计内的降级行为。如果来源返回的是搜索平台自己的相对跳转地址,插件会还原成目标地址;无法还原的条目会被跳过,避免卡片里出现打不开的链接。
用量区块显示失败提示
用量查询使用平台免费端点,可能因为网络或平台侧故障失败。失败只影响该账号的展示,搜索仍会正常发起;等待下一次后台刷新即可。
提示缺少官方凭据
当三方来源全部失败、且官方搜索也没有可用凭据时会出现该提示。按提示配置 DeepSeek 官方凭据(设置 → 模型中的搜索凭据)后即可恢复兜底能力。