dsh-fk-search-tier:两级搜索与抓取 failover 的 DSH 工作流插件

前言

在 DeepSeek Harness(DSH)里,智能体要查资料通常走 ctx.web 的搜索与抓取能力。默认的 deepseek-official 搜索通道会把每次查询当成一整轮模型调用,README 里给出的实测约为 9.6K input token,按 token 计费时成本偏高。社区里也有多后端 failover 插件,但体量更大、配置更重。

dsh-fk-search-tier 由维护者 FuriousKinght 发布,分类为工作流,当前在 GitHub 上星标为 0。它不改 DSH 本体,只通过纯 ctx.web provider 注册,把搜索做成「Tavily → DeepSeek Search API」两层,抓取做成「DeepSeek Fetch API → 直连」两层;第一层因额度、限流、错误或空结果失败时自动切下一层,并带额度感知的熔断。若你只需要这条两级链路而不是十几个搜索后端,README 把它定位为更轻的替代方案。

这是什么

一句话:dsh-fk-search-tier 是 DSH 的 bundle 插件(package.json 版本 0.2.0,MIT 许可证),注册 search-tier 与 fetch-tier 两个 provider,在 Tavily 与 DeepSeek 官方 Search/Fetch API 之间做有序 failover,直连抓取作为零成本兜底。

维护者与仓库:FuriousKinght / GitHub。社区目录页:SkillHub 插件条目(独立站点,与 DeepSeek / 幻方无官方从属关系)。

核心功能

两级搜索

默认顺序 order: [tavily, deepseek]:

  1. Tavily:可无 key 使用 keyless 匿名档;有 TAVILY_API_KEY 时走账户额度(README 写明免费档 1000 credits/月)。
  2. DeepSeek Search API:按次计费(README 写明 5 元 / 1000 次成功请求,不按 token 烧搜索轮次)。

当上一层出现 429、额度耗尽、5xx、超时、空结果(failOnEmpty: true 时)等情况,会切到下一层;Tavily 正常返回时不会无故切到 DeepSeek,这是设计行为。

两级抓取

默认顺序 fetchOrder: [deepseek-fetch, direct]:

  1. DeepSeek Fetch API:返回 Markdown 正文(README 给出 2026-10-17 实测:example.com 约 0.53s,GitHub 仓库页约 0.27s)。
  2. 直连抓取:fetch HTML 后转纯文本,无 API 成本;不解析 JS 渲染页面。

熔断与切换

搜索与抓取各有一套相同语义的熔断器(配置项 breaker):

触发条件 行为 冷却
429 / 402 / 文本含 insufficient、quota 该层开断并切下一层 1 小时(quotaCooldownMs)
401 / 403 跳过该层,改配置可立刻恢复 无
5xx / 超时 / 网络错误 窗口内累计达到 threshold(默认 3)才开断 60 秒(cooldownMs)
搜索返回 0 条 本次切下一层,不计入熔断 无
deepseek 层缺 key 跳过 无

冷却到期后半开探活,成功则闭合。

与模型侧的契约

搜索只返回 sources(url、title、snippet 等),由 DSH 的 formatSearchOutput 组装;DeepSeek 层优先用 summary 长摘要。抓取遵循 WebFetchResult:成功时 statusCode 为 200,DeepSeek API 不报告目标页真实 HTTP 状态(README 列为已知限制)。

诊断工具

插件注册只读工具 search_tier_status,可查看各层 hasKey、open、lastWinner 与熔断状态,用于确认 DEEPSEEK_API_KEY / TAVILY_API_KEY 是否被进程读到。

安装与启用

安装命令以 README 为准,不要手工把插件目录里的 cordis.patch.yml 抄进 profile,否则会绕过 bundle 加载时序并可能出现 tool-web: waiting for web:

dsh plugin --profile desktop add <本包路径或包名>

装完后重启 DSH。插件要求 Node >=20,peer 依赖 @deepseek-ai/cordis >=4.0.1 <5。

配置要点

密钥不要写在插件目录

随插件发布的 cordis.patch.yml 不宜写 apiKey。推荐用环境变量:

后端 环境变量
DeepSeek Search / Fetch DEEPSEEK_API_KEY
Tavily(可选) TAVILY_API_KEY

改环境变量后必须重启 DSH。也可在 $DSH_HOME/profiles/<profile>/cordis.patch.yml 用同名 id: search-tier 整段覆盖配置(私有文件可写密钥);profile 层覆盖会替换插件自带段,需把要保留的键一并写上。

零密钥最小用法

不配密钥时:搜索走 Tavily keyless,抓取走直连。代价是没有 DeepSeek 兜底,匿名档限流时第二层不可用。

- id: search-tier
  name: dsh-fk-search-tier
  config:
    order: [tavily, deepseek]
    tavily: {}
    deepseek: {}

完整项包括 fetchOrder、timeoutMs、fetchTimeoutMs、failOnEmpty、breaker,以及 tavily.depth、deepseek.needContent、deepseek.fetchMaxBytes 等,见仓库 README 的「完整配置项」一节。

与官方 provider 的关系

DSH 0.2.1-rc.2 起可内置 DeepSeek Search/Fetch,但 README 写明官方不会自动回退到其他提供者。本插件显式指定 searchProvider / fetchProvider 时可避免歧义;若同时打开官方开关,需注意是否出现 WEB_PROVIDER_AMBIGUOUS。

典型用法与自测

  1. 按上文安装并配置密钥或环境变量,重启 DSH。
  2. 让智能体调用 search_tier_status,确认 layers 里 hasKey 与 open 符合预期。
  3. 正常使用 DSH 的联网搜索与 WebFetch;失败时观察是否按顺序 failover。

仓库提供自测脚本:

node test/selftest.mjs

README 写明 53 项断言,含熔断、契约、真实 Tavily keyless 与 DeepSeek Fetch 调用等。

适用场景与注意

适合谁:希望默认先用 Tavily(含免 key 档)压低成本,仅在失败或空结果时用 DeepSeek Search;抓取优先干净 Markdown,失败再直连兜底的工作流用户。

使用前请知悉:

  • 插件以当前 DSH 进程权限运行,安装前应自行审阅 源码 与 MIT 许可证。
  • Tavily keyless 为匿名档,有速率限制且可能被官方调整;DeepSeek Search/Fetch 均按次计费。
  • 无图形设置页,改 YAML 后需重启;与官方内置 provider 并存时要弄清最终生效的 provider。
  • README 对比 dsh-search-failover:本插件约 26 KB、仅 2 个搜索后端,但包含抓取 failover 与 DeepSeek 新 Search/Fetch API。

结尾

dsh-fk-search-tier 把「搜索 Tavily → DeepSeek」和「抓取 DeepSeek Fetch → 直连」收成一条可配置、带熔断的 ctx.web 链路,适合在 DSH「一切皆插件」的生态里做轻量联网工作流。目录与仓库:

  • https://www.skillhub.cn/plugins/FuriousKinght/dsh-fk-search-tier
  • https://github.com/FuriousKinght/dsh-fk-search-tier
羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜