DeepSeek Harness 插件

Walvez/dsh-search-failover

Star 数 ★ 4 下载量(近 30 天) 651 分类 工具与能力 收录于 2026-08-18 npm dsh-search-failover

原生 web_search 的搜索池:8 个免费/付费后端自动故障转移与额度感知熔断,设置页管理 API Key、自定义 SearXNG 实例、failover/rotate 策略切换与 SerpApi 实时额度查询。

安装

# npm 包(预构建)

dsh plugin --profile web add dsh-search-failover

# GitHub 源码(首次需按提示配置 allowBuilds 构建授权后重试)

dsh plugin --profile web add github:Walvez/dsh-search-failover

装任何插件都等于在你的机器上跑第三方代码,权限和你本人一样大——能读你的文件、用你的凭据、访问网络,工具审批管不到它。GitHub 来源的插件还会在安装时执行构建脚本——pnpm 默认拦截,所以安装可能停在 ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED 或 ERR_PNPM_IGNORED_BUILDS;dsh 会打印出需要添加的确切键名,把它加进该 profile 的 pnpm-workspace.yaml 的 allowBuilds 下,重跑一次即可装上。放行构建本身就是一次信任判断:请只安装可信来源,并尽量锁定 commit(github:owner/repo#sha)。

README


为什么不用官方默认搜索?

DSH 默认通道 deepseek-official 不是专用搜索 API:每次 web_search 都会发起一轮完整 Messages 模型调用,由 DeepSeek 在服务端执行搜索。这意味着:

官方 deepseek-official 本插件 search-pool
检索方式 一整轮 LLM 调用 + 服务端 web_search 工具 直连 Exa / Tavily / Jina / Firecrawl 等检索端点
模型 token 每次搜索都烧(input + output),结果还会回灌上下文 0(纯检索,不碰任何 LLM)
计费来源 DEEPSEEK_API_KEY 余额 各引擎自己的免费额度
抓取 web_fetch 同样走官方通道 同步接管:Jina Reader / Exa Contents / Tavily Extract / Firecrawl Scrape
宕机 / 额度耗尽 整条链路挂掉 熔断冷却 + 自动下探下一个引擎 / 下一个 Key

装上即把 searchProvider 与 fetchProvider 都指到 search-pool。卸载后自动回落到官方通道。


✨ 核心特性

  • 🛡️ Provider 级透明替换:无侵入接管 DSH ctx.web 的 搜索 + 抓取,保持原生 web_search / web_fetch 工具签名不变。
  • 🔄 双重路由策略:
    • 优先顺序 (Failover):按优先级从高到低依次尝试,前一个后端失败或熔断自动下探下一个。
    • 加权轮询 (Weighted Rotate):按 1~10 权重将搜索流量平摊到所有健康引擎,最大化榨干各大搜索源的免费额度。
  • ⚡ 智能额度感知与熔断器 (Circuit Breaker):
    • 遇到额度耗尽(HTTP 402/429/Quota Exceeded)→ 长冷却 (1h),避免无效请求;
    • 遇到临时网络抖动(Transient Error)→ 5 分钟内连续 3 次失败触发 短冷却 (60s);
    • 冷却到期自动半开探活,成功立即恢复。
  • 🤖 AI 自主换源技能 (web_search_from):
    • 为 Agent 注入专属换源工具。当 AI 认为默认结果不够理想、信息过时或源单一时,可自主选择 exa / serper / tavily / jina / firecrawl 等引擎重新搜索并对比。
  • 🎛️ 现代卡片流 Web GUI 设置面板:
    • 在 DSH 设置页一键填写/修改 API Key、切换策略、拖拽排序、测试连通性,保存即实时生效,无需重启进程。
    • 密钥安全保存在本地 ~/.dsh/settings.yaml,绝不上报。
  • 🔑 单引擎多 Key 轮换:同一后端可换行或逗号填多个 Key;Key A 额度耗尽先切 Key B,全部挂了才熔断下探下一个引擎。
  • 🔌 全生态适配:
    • 搜索:Exa, Serper, Tavily (keyless 匿名档), Jina, SerpApi, Firecrawl, SearXNG (自托管), DuckDuckGo, Brave
    • 抓取:Jina Reader (r.jina.ai) · Exa Contents · Tavily Extract · Firecrawl Scrape

🏗️ 架构概览

┌──────────────────────────────────────────────────────────────┐
│                    AI Agent / User Chat                      │
└──────────────┬────────────────────────────────┬──────────────┘
               │ (默认搜索 / 抓取)                │ (显式换源)
               ▼                                ▼
┌──────────────────────────────┐ ┌─────────────────────────────┐
│  原生 web_search / web_fetch  │ │  web_search_from (增强工具)   │
└──────────────┬───────────────┘ └──────────────┬──────────────┘
               │                                │
               ▼                                ▼
┌──────────────────────────────────────────────────────────────┐
│               SearchPoolProvider (search-pool)               │
│                                                              │
│  [调度决策]                                                   │
│   ├── 指定源 (source): 直连指定引擎, 不走池                      │
│   ├── Failover: 按 priority 升序依次尝试                       │
│   └── Rotate: 按 weight 展开加权轮转                           │
│                                                              │
│  [熔断与健康守护]                                              │
│   ├── CircuitBreaker 监控各后端健康度                          │
│   └── 额度耗尽(1h 冷却) / 瞬时错误(60s 冷却) / 探活恢复           │
└──────────────────────────────┬───────────────────────────────┘
                               │
   ┌──────────┬──────────┬─────┴────┬──────────┬──────────┬──────────┐
   ▼          ▼          ▼          ▼          ▼          ▼          ▼
┌─────┐    ┌──────┐   ┌──────┐   ┌──────┐   ┌─────────┐┌─────┐   ┌─────────┐
│ Exa │    │Serper│   │Tavily│   │ Jina │   │Firecrawl││Serp-│   │ SearXNG │
│     │    │ .dev │   │(Anon)│   │  AI  │   │ .dev    ││ Api │   │ (Local) │
└─────┘    └──────┘   └──────┘   └──────┘   └─────────┘└─────┘   └─────────┘

🎛️ 设置面板实机预览

  • 实时密钥填写:随时填写或更新各引擎 API Key(支持多行多 Key),点击保存立即热生效。行内「↗」直达各引擎申请页。
  • 网页抓取接管:web_fetch 同步走搜索池(Jina Reader / Exa / Tavily / Firecrawl),享受同一套熔断与多 Key。
  • 一键测试连接 (▶ 测试):对指定后端发起 1 条测试搜索,毫秒级反馈连通状态与响应耗时。
  • 动态优先级调整 (↑ / ↓):通过按钮调整引擎在 Failover 链中的优先级。
  • 轮询权重调节:在轮询分摊模式下,为不同引擎设置 1~10 权重值。
  • 添加自定义后端:无需改写代码或配置文件,直接在界面添加 SearXNG 实例或新后端。
  • 额度余量透视:行内直接显示支持额度查询的后端(如 SerpApi)的套餐类型、剩余次数及重置日期。

🚀 快速开始

1. 安装插件

在你的 DSH 项目或 Web Profile 下安装:

# 方式 A: 从 npm 安装 (推荐)
dsh plugin --profile web add dsh-search-failover

# 方式 B: 本地克隆软链调试 (开发者)
git clone https://github.com/Walvez/dsh-search-failover.git
dsh plugin --profile web add link:$(pwd)/dsh-search-failover

2. 启用配置

在 cordis.patch.yml 中声明挂载与默认后端配置:

- id: search-pool
  name: dsh-search-failover
  config:
    strategy: failover          # failover (优先顺序) | rotate (轮询分摊)
    maxResults: 8               # 默认返回条数上限
    timeoutMs: 15000            # 单个请求超时时间 (ms)
    backends:
      - id: exa
        kind: exa
        apiKeyEnv: EXA_API_KEY  # 从 ~/.dsh/.env 读取
        priority: 1
      - id: serper
        kind: serper
        apiKeyEnv: SERPER_API_KEY
        priority: 2
      - id: tavily
        kind: tavily
        apiKeyEnv: TAVILY_API_KEY
        priority: 3
      - id: jina
        kind: jina
        apiKeyEnv: JINA_API_KEY
        priority: 4
      - id: firecrawl
        kind: firecrawl
        apiKeyEnv: FIRECRAWL_API_KEY
        priority: 5
      - id: serpapi
        kind: serpapi
        apiKeyEnv: SERPAPI_API_KEY
        priority: 6
      - id: searxng
        kind: searxng
        baseURL: http://127.0.0.1:8080
        priority: 7
      # opencodex web-search sidecar (可选, 默认不启用):
      # 本机 opencodex 代理的 Codex 登录额度执行真搜索, 结果带摘要质量最高,
      # 但比纯检索端点慢 (~3-15s)。需要本机运行 opencodex (127.0.0.1:10100)。
      # - id: opencodex
      #   kind: opencodex
      #   priority: 0              # 置顶 = 首选, 失败熔断自动下探
      #   # baseURL: http://127.0.0.1:10100
      #   # apiKey: ocx_data_dsh   # 默认免 token / 自定义 token 时填
      #   # carrierModel: opencode-go/glm-5.3-flash
    circuit:
      threshold: 3              # 连续错误阈值
      burstWindowMs: 300000     # 统计时间窗口 (5 分钟)
      cooldownMs: 60000         # 瞬时错误冷却时间 (1 分钟)
      quotaCooldownMs: 3600000  # 额度耗尽冷却时间 (1 小时)

3. 启动 DSH Web

dsh web

打开 Web GUI (默认 http://127.0.0.1:3080),进入 设置 → 搜索池 即可在界面直接管理所有 Key。


📊 后端引擎支持与额度参考

引擎标识 (kind) 搜索 抓取 官方免费额度 (核实) 密钥 申请页
exa ✓ ✓ 注册送 $20,每月赠 $10 必须 dashboard.exa.ai
serper ✓ ✗ 注册赠送 2,500 次 必须 serper.dev
tavily ✓ ✓ 每月 1,000 credits;无 key 走匿名档 可选 app.tavily.com
jina ✓ ✓ 免费注册 Key;s.jina.ai 搜索 / r.jina.ai 抓取 必须 jina.ai
firecrawl ✓ ✓ 每月 1,000 credits 必须 firecrawl.dev
serpapi ✓ ✗ 每月 250 次,支持实时额度查询 必须 serpapi.com
searxng ✓ ✗ 自托管无限 无 docs.searxng.org
brave ✓ ✗ 需绑卡 必须 brave.com/search/api
ddg ✓ ✗ 完全免费 无 —
opencodex ✓ ✗ 走本机 opencodex 的 Codex 登录额度 无 (loopback 免 token) opencodex

opencodex 后端默认不启用:仅在用户 patch 的 backends 里显式声明时进入搜索链。 它不是纯检索端点——搜索经 opencodex 的 web-search sidecar(Codex forward 登录额度)执行, 结果带模型整合的摘要与 sources,质量最高但延迟更高(sidecar 整合约 3–15s)。 适合置顶做首选,失败/额度耗尽由熔断器自动下探到 exa 等纯检索后端。

同一后端可换行或逗号填多个 Key。Key A 额度耗尽先切 Key B,全部挂了才熔断下探下一个引擎。


🤖 AI 自主换源工具 (web_search_from)

当 Agent 认为默认搜索结果不理想时,可以主动调用由本插件注册的 web_search_from 工具:

工具参数

{
  "name": "web_search_from",
  "description": "用指定的搜索后端(引擎)搜索当前信息并返回该源原始结果。可用于多源对比或换引擎重试。",
  "parameters": {
    "query": { "type": "string", "description": "搜索关键词" },
    "source": { "type": "string", "description": "指定后端类型 (例如 exa, serper, tavily, jina, firecrawl, searxng 等)" },
    "maxResults": { "type": "number", "description": "返回结果数量上限 (默认 8)" }
  }
}

Agent 典型工作流

  1. Agent 执行 web_search(query="最新技术动态") 走默认搜索池;
  2. 发现结果大多是旧闻或不相关,Agent 主动调用 web_search_from(query="最新技术动态", source="serper") 从 Google 实时索引获取结果;
  3. 对比各源信息,输出最准确、最及时的回答。

🧪 单元测试

项目包含完善的单元测试套件(覆盖熔断器状态机、加权轮询、优先级排序、多源容灾、自愈探活等):

# 运行单元测试
npm test

# 运行真实网络冒烟测试
EXA_API_KEY=your_key node scripts/smoke.mjs exa serper tavily

📄 开源许可证

本项目基于 MIT License 开源。

欢迎提交 Issue 和 Pull Request 共同改进!

内容来自项目 README(GitHub)↗

链接

同类插件

查看整个分类 →

社区评论

评论公开保存在 GitHub Discussions。加载评论会连接 GitHub 和 Giscus;发表内容需要 GitHub 账号。