drscrewdriver/dsh-union-search

drscrewdriver/dsh-union-search

DSH 的联合联网搜索(DDDMUC/dsh-free-search 的整合后继,README 有致谢):28 个引擎分三档——免 key 免费(Bing/DuckDuckGo/AnySearch/SearXNG 多实例联合,Exa/Tavily/Keenable/Firecrawl/Parallel 免 key 模式)、凭 key 付费(知乎/Perplexity/Serply/DeepSeek 官方/You.com/百度/Kimi/阿里云/豆包/智谱/博查/Metaso)、模型内置搜索(OpenAI/Gemini/Claude/Grok,仅显式勾选)——配自动智能路由、逐引擎开关与回退优先级、并行 top-3 融合、multi_search 跨源工具、失败感知回退、屏蔽系统内置搜索开关、时间过滤、平台搜索、web_fetch 与网页设置界面。实验性·免费 advance_fetch:整页 GFM-Markdown 或 CSS 选择器/字段结构化抽取,零 key 零按次计费;抓取身份可配(自定义 UA、Referer、按域 cookie——仅在域名匹配时附带、跨域重定向绝不外流)。宿主 0.1.0-rc.2→0.2.1-rc.2 共 17 个 rc 精确枚举(rc.2 的搜索接管经能力探测后走 volatile 配置钉选,禁版本号分支)。付费引擎需自备 API key(可选,免费引擎开箱即用)。npm:@drscrewdriver/dsh-union-search 与裸名 dsh-union-search 双发。

浏览器与网页

dsh-union-search

DeepSeek Harness 联合搜索插件(原 dsh-free-search)—— 免费搜索与多种专业付费搜索 API 的联合体。 一个给 DeepSeek Harness (dsh) 添加多引擎搜索 provider 的插件,注册进 ctx.web seam。内置 web_search 工具自动选用,支持网页设置页切换引擎、配置 API key、一键测试所有引擎、弹出式命令切换引擎。免费引擎开箱即用、零成本;也支持接入多种专业付费搜索 API(Perplexity / DeepSeek 官方 / Kimi / 智谱 / 博查 / 秘塔 / 豆包 / You.com / OpenAI / Gemini / Claude / Grok 等)提升结果质量。

中文 · English

中文

▲ 免费引擎(以Bing为例)

为什么需要它

dsh 默认的搜索 provider 依赖 DeepSeek 官方 API key(DEEPSEEK_API_KEY)。如果你:

  • 没有(或不想用)DeepSeek 官方 key,
  • 用的是 opencode-go 这类网关(其 OpenAI 兼容端点不支持 web_search 工具),

……那么内置搜索必然失败,agent 会告诉你"无法联网"。

这个插件提供多个免费引擎 + 多种专业付费搜索 API + 自动回退:不配任何 key 开箱即用,彻底摆脱 DeepSeek 官方 key 的依赖;配置付费 key 后可获得更高额度与更专业的搜索质量。

特性

  • 免费 + 付费联合 —— 多个零成本免费引擎(无需 key、无需注册)+ 多种专业付费搜索 API(Perplexity / DeepSeek 官方 / Kimi / 智谱 / 博查 / 秘塔 / 豆包 / You.com / OpenAI / Gemini / Claude / Grok 等);只用免费引擎零成本,配付费 key 提质提额
  • 多引擎可选:DuckDuckGo(html/lite)、Bing、SearXNG(元搜索,支持自定义实例)、AnySearch、Exa、Tavily、Keenable、Firecrawl、Parallel、Perplexity、SerpBase、Serply、DeepSeek 官方、You.com、百度千帆、Kimi、阿里云百炼、火山联网搜索(豆包搜索)、知乎全网/站内(zhihu_global/zhihu_site,经知乎开放平台 MCP)、智谱 Web Search(zhipu,普通平台 Key)、博查(bocha,DeepSeek 官方供应方)、秘塔(metaso,多模态)、OpenAI / Gemini / Claude / Grok(grok,xAI Responses API x_search 搜 X/Twitter)模型内置搜索
  • 网页设置页 —— 引擎切换 + API key 配置(UI 中 key 脱敏显示"已配置")+ 中英文切换;入口在左侧「插件」页的组件行配置(plugins.row.config,DSH 0.1.7-rc.1+)
  • 弹出式切换命令 —— 聊天框输入 /union-search-engine,弹出引擎选择窗口,点选即切换(等效设置页 + 保存)
  • 引擎测试 —— 设置卡「测试全部引擎」一键逐个测试并列出结果,失败引擎进入建议禁用清单(勾选后「应用禁用」,保存生效;auto/multi 虚拟模式不会入列);另有「测试引擎」按钮(直测当前引擎,不走回退链,付费引擎无 key 会明确报错)
  • 全局引擎开关与回退优先级 —— 设置页可勾选/取消引擎(取消后全局生效:普通搜索 / Auto / advanced_search / multi_search / 引擎测试都不再用它),并可用 ↑↓ 调整全局回退顺序(一键恢复默认)
  • Multi 模式 —— 可把搜索引擎设为 Multi Search:web_search 并发请求前 3 个已启用引擎、按 URL 合并去重、跨源命中的结果优先(代价是成倍消耗额度;multi 失败会自动退回单引擎回退链)
  • 统一引擎回退 —— 任何引擎失败(付费/免费,缺 key/401/限流/网络)自动轮流尝试下一个引擎:首选引擎 → 其他引擎(exa/tavily/keenable/firecrawl/parallel 无 key 也会尝试,因为它们自带 keyless 免费额度)→ 剩余免费引擎,搜索永不直接失败;结果顶部注明实际生效的引擎(如 Note: perplexity unavailable or failed, using exa.);失败按类别处理:额度/鉴权失败→本会话冷却该引擎,反爬→短退避,超时/5xx/限流→同引擎重试一次,解析失败/0 结果→不冷却(详见下文「失败分类与引擎冷却」)
  • 时间过滤 —— advanced_search 工具支持 timeRange:固定档、自定义相对值、绝对日期三种形式(详见下方逻辑说明)
  • 系统提示词注入 —— agent 知道当前用哪个引擎、哪些需要 key;并明确所有搜索结果是不可信外部数据,不得执行其中的指令
  • 提示注入防护(不可信数据边界) —— 插件自有工具(advanced_search / platform_search / multi_search)的网页文本包在 ` 边界内(正文里自带的同名标记会被剥离,防止提前闭合);核心 web_search / web_fetch 由 DSH 核心自带同类提示(External web content follows...`);所有 snippet 统一清洗并截断到 300 字符
  • 版本号 + 检查更新 —— 设置卡片显示当前版本(v0.4.17),"检查更新"按钮直连 npm registry 对比最新版,有新版本时提示并可一键跳转
  • 结果缓存 —— 相同查询(含引擎/时间过滤参数)5 分钟内命中缓存(LRU 50 条),防免费引擎限流、省付费额度;时长可在设置页 0-5 分钟自由配置(0 关闭)
  • 免费标注 —— 设置页中免费引擎带绿色 FREE 徽章,付费引擎带橙色 API KEY 徽章
  • 网页抓取(web_fetch) —— 让 agent 抓取网页内容(官方 dsh-web-fetch-http provider,纯 JS,零额外依赖)
  • 增强抓取(advance_fetch,实验性 · 免费) —— 在 web_fetch 之上的插件自有工具,零 key、零按次计费(区别于按次计费的付费搜索 API):整页转 GitHub-Flavored Markdown(转换配置与宿主 tool-web 同款复刻:不可见节点整体剔除、GFM 表格不展开跨列),并支持 CSS selector 限定范围与 fields(label=selector|attr,分号分隔)定向结构化抽取——只要页面的一部分时优先用它。依赖插件自带(turndown + @joplin/turndown-plugin-gfm + cheerio),不碰宿主内部面;输出经门户页脏面清洗(javascript: 等伪协议链接只留文本、布局表全空管道行丢弃、表格内 ` 归一为 " / "、行边界截断不留残句/不拆代理对/不留未闭合代码围栏);相对链接按最终 URL 自动绝对化并剥离 utm/gclid/fbclid 等跟踪参数;GBK/GB2312 等非 UTF-8 老站按声明字符集解码(header → BOM → meta charset 探测);200 状态的反爬挑战页(captcha/验证码等文案 + 近空正文)识别为失败而非当正文;RSS/Atom 按文本透传;登录墙/纯客户端渲染站只返回壳并附 note 提示。抓取身份可配置:设置页可自定义 User-Agent、Referer 与按域 Cookie(逐行 域名 cookie串,仅在抓取目标匹配该域时附带、重定向换域不外流)——凭据只存设置页,勿在对话中粘贴。导航密集型门户页建议优先用 selector/fields 定向抽取;仅 http/https,重定向限 5 跳逐跳复检,**SSRF 地址门默认拒绝回环/内网/云元数据地址**(advanceFetchAllowPrivate` 可显式放行局域网设备),抓取内容包进不可信边界
  • 按需帮助(union_help) —— 转换分派(HTML/JSON/RSS 透传、字符集探测、跟踪参数剥离、输出上限与截断)、fields 语法、引擎与平台清单(读当前设置生成,不另立第二份真相)、抓取身份(自定义 UA/Referer/按域 Cookie)与故障形态,都由 union_help 主题查询;各工具描述只留短说明,不再把长规则平铺在每轮都付费的 schema 面里。
  • 平台搜索(platform_search) —— 搜 GitHub / V2EX / B站 / Reddit / Hacker News / Stack Overflow / 维基百科 / npm / YouTube / Vimeo(公开 API 或免 key 抓取,零依赖)
  • 视频搜索(video_search) —— 跨站找视频:Bing Videos + DuckDuckGo Videos(免 key,失败互相回退),返回视频链接、标题与来源/时长等元信息
  • 干净集成 —— 实现官方 WebSearchProvider seam 接口,与官方插件共存
  • 屏蔽系统自带搜索 —— 设置页「屏蔽系统自带搜索」开关(blockSystemSearch):开启后强制接管 web_search,并把出厂官方搜索引擎 deepseek-official / rc.2 起的 deepseek-search-api 从所有引擎链与接管判据中剔除;保存即生效
  • SearXNG 返回语言可锁定 —— 设置项 searxngLanguage(默认 auto):自动档按 query 文字检测(假名→ja、谚文→ko、西里尔→ru、汉字→zh-CN,判不出落设置页语言兜底);选具体值(zh-CN/zh-TW/en/ja/ko/ru/de/fr/es/all)则锁定不随 query 变化;非法 locale 自动归一防 400
  • SearXNG 多实例综合 —— 自定义列表配置 ≥2 个端点时,自动向前两个端点并发双发请求,等两份请求都返回后按 URL 合并去重,双实例共同命中的条目优先;两个都失败才顺序回退剩余实例

如果这个插件帮到了你,欢迎给仓库点个 ⭐(GitHub)——星标是开发者继续维护的最大动力,感谢支持!

引擎列表

id · 引擎 · 费用 · 说明 auto · Auto 智能路由 · 动态 · 根据查询语言/时间条件自动选路(含中文优先 Bing/Baidu/Aliyun/AnySearch,英文优先 Bing/Exa/Tavily;时间过滤优先支持引擎),末尾全量回退 ddg · DuckDuckGo HTML · 免费 · 偶发限流(反爬),解封自动恢复 ddg-lite · DuckDuckGo Lite · 免费 · 轻量版,同上 bing · Bing · 免费 · 默认引擎,最稳定,中文优化(zh-CN) anysearch · AnySearch AI · 免费 · AI 搜索,无 key(匿名额度) searxng · SearXNG 元搜索 · 免费 · 实例三态严格互斥:公网池 / 本地 Docker(回环)/ 自定义列表,任一态不向其他态回落;自定义列表 ≥2 端点时自动向前两个并发双发、等两份都返回后综合(双命中条目优先);返回语言按 query 文字自动判定(假名→ja、谚文→ko、西里尔→ru、汉字→zh-CN),判不出才落设置页语言兜底;聚合网页结果 + 维基卡片(infoboxes)+ 直接答案(answers);设置卡支持实例探测与「设为首选」一键切换端点 exa · Exa · 免费 · 无 key 也可用(MCP 匿名),配 key 提升额度 tavily · Tavily · 免费 · 无 key 也可用(keyless 匿名),配 key 提升额度 keenable · Keenable · 免费 · 无 key 也可用(MCP 匿名),配 key 提升额度 firecrawl · Firecrawl · 免费 · 无 key 也可用(官方免 key 匿名额度),配 key 提升限额 parallel · Parallel · 免费 · 无 key 也可用(官方 MCP 匿名额度),配 key 提升额度并支持精确时间过滤 perplexity · Perplexity · 付费 · 需 PERPLEXITY_API_KEY serpbase · SerpBase · 付费 · 需 SERPBASE_API_KEY(serpbase.dev,注册送 100 次免费额度) serply · Serply · 付费 · 需 SERPLY_API_KEY(serply.io,新账户 30 天内 2,500 次免费额度);Google 网页结果,按设置页语言本地化 deepseek-official · DeepSeek 官方 · 付费 · 需 DEEPSEEK_API_KEY;官方定价 Search $0.75 / 千次成功请求(≈ 单次 5 厘)(2026-10 口径;经 DSH 宿主的服务端工具调用 2026-11-01 前免费),见下方「DeepSeek 官方定价」 you · You.com · 付费 · 需 YOUCOM_API_KEY(you.com/platform/api-keys,注册即送免费额度) baidu · 百度千帆 AI 搜索 · 额度 · 需 BAIDU_API_KEY(千帆 AI 搜索,每日赠 50 次,超额按量后付费);中文全网,支持时间过滤 kimi · Kimi(Moonshot)联网搜索 · 付费 · 需 MOONSHOT_API_KEY(basic 约 ¥0.01/次),返回带正文 chunks 的中文结果 aliyun · 阿里云百炼 EnhancedSearch · 付费 · 需 DASHSCOPE_API_KEY(MCP search_pro,约 ¥0.03/次,新用户 200 次免费包);中文全网带来源 hostname doubao · 火山引擎联网搜索(豆包搜索) · 免费额度 · 需 DOUBAO_SEARCH_API_KEY(联网搜索控制台开通,每月 500 次免费,超出按量付费);中文时效内容强,支持时间/站点过滤,返回千字级摘要 zhihu_global · 知乎全网搜索(开放平台 MCP) · 付费 · 需 ZHIHU_API_KEY;支持时间过滤(publish_time);无 key 时自动跳过 zhihu_site · 知乎站内搜索(开放平台 MCP) · 付费 · 需 ZHIHU_API_KEY;不支持时间过滤 zhipu · 智谱 Web Search · 付费 · 需 ZHIPU_API_KEY(普通平台 Key,非 Coding Plan);REST /api/paas/v4/web_search;search_pro 约 0.03 元/次(search_std 0.01 / search_pro_sogou、search_pro_quark 0.05,可经 zhipuEngine 切档);支持时间过滤(search_recency_filter) bocha · 博查 AI 搜索 · 付费 · 需 BOCHA_API_KEY(open.bochaai.com,注册送额度);DeepSeek 官方联网供应方,中文强;约 0.036 元/次;支持时间过滤(freshness) metaso · 秘塔 AI 搜索 · 免费额度 · 需 METASO_API_KEY(mk- 开头,注册送 5000 点);约 0.03 元/query;支持网页/学术/文库/播客多模态(metasoScope) openai · OpenAI 模型内置搜索 · 付费 · 需 OPENAI_API_KEY;走 Responses API 的 web_search 工具,返回带引用的回答。按次计费,仅在显式选中时使用(不参与自动回退/auto);默认 gpt-6-luna,模型与端点可配(openaiModel / openaiBaseUrl) gemini · Gemini Grounding with Google Search · 付费 · 需 GEMINI_API_KEY(兼容 GOOGLE_API_KEY);走官方推荐的 Interactions API(POST /v1beta/interactions,tools:[{type:"google_search"}]),从 steps[].content[].annotations 取引用。按次计费,仅在显式选中时使用;默认 gemini-3.8-flash,模型与端点可配(geminiModel / geminiBaseUrl) claude · Claude 服务端 web_search · 付费 · 需 ANTHROPIC_API_KEY;结果来自 web_search_tool_result。按次计费,仅在显式选中时使用;默认 claude-sonnet-5-5,模型与端点可配(claudeModel / claudeBaseUrl) grok · Grok · X (Twitter) 搜索 · 付费 · 需 XAI_API_KEY(console.x.ai);走 xAI Responses API 的 x_search 工具,返回带引用的 X 帖子。按 token+按次计费,仅在显式选中时使用;默认 grok-4.2,模型与端点可配(grokModel / grokBaseUrl)

  • 默认引擎为 `bing`(免费且最稳定),安装后开箱即用。
  • 自动回退:任何引擎失败(免费限流/反爬,付费缺 key/无效/网络错误)都会自动轮流尝试下一个引擎——先试其他已配 key 的付费引擎,再试免费引擎(Bing/AnySearch 等),并在结果中附带回退提示——搜索不会因引擎问题直接失败。
  • 设置页有官网链接:免费引擎显示"访问官网 →",付费引擎显示"获取 API Key →"(新标签页打开):
  • Exa:
  • Tavily:
  • Keenable:
  • Parallel:
  • Perplexity:
  • SerpBase:
  • Serply:(API 文档:)
  • DeepSeek:
  • 豆包搜索(火山联网搜索):
  • You.com:
  • 智谱:
  • 博查:
  • 秘塔:
  • xAI(Grok):

为什么免费引擎不需要 key?

  • AnySearch:其 v1/search REST 接口提供匿名的公共搜索额度,无需注册或 API key。额度有限流(适合日常搜索),但作为免费引擎之一,与其他免费引擎互相回退,体验稳定。
  • Exa:公开 MCP 端点(mcp.exa.ai/mcp)支持匿名调用,不配 key 也能用;配置 EXA_API_KEY 后可获得更高额度。
  • Tavily:通过 x-tavily-access-mode: keyless 头走 keyless 匿名额度,不配 key 即可用;配置 TAVILY_API_KEY 后走账号档,额度更高、结果质量更稳定。
  • Keenable:无 key 时走其公开 MCP 端点(api.keenable.ai/mcp)匿名调用;配置 KEENABLE_API_KEY 后走 REST API(api.keenable.ai/v1/search),额度更高、按组织限流。
  • Firecrawl:其 /v2/search 端点无需 key 即可使用(官方文档明确说明,有匿名限流);配置 FIRECRAWL_API_KEY 后可提高限额。支持 tbs 时间过滤(qdr:h/d/w/m/y 与自定义日期区间)。

DeepSeek 官方定价(2026-10,以官方定价页为准)

搜索/抓取是独立按请求计费的 API(与模型 token 费分开):

API · 计费单位 · 价格 Search(联网搜索) · 每 1,000 次成功请求 · $0.75(≈ 单次 ¥0.005・5 厘 @汇率7.1) Fetch(网页抓取) · 每 1,000 次成功请求 · $0.75(≈ 单次 ¥0.005・5 厘 @汇率7.1)

注:通过 DeepSeek Harness(本宿主)/ Claude Code / Codex 调用时,服务端工具已经会命中 Search/Fetch API;这部分目前免费,自 2026-11-01 00:00(北京时间)起按次计费。本插件的 deepseek-official 引擎走同一价目表;这也是「屏蔽系统自带搜索」开关存在的背景之一——如果你不想为出厂搜索付费,用免费引擎即可。

模型 token 定价(每百万 tokens,平峰/高峰,1 美元计价):

模型 · 输入(缓存命中) · 输入(缓存未命中) · 输出 deepseek-flash · $0.003 / $0.006 · $0.15 / $0.30 · $0.60 / $1.20 deepseek-v4-pro · $0.022 / $0.044 · $0.66 / $1.32 · $1.98 / $3.96

高峰时段为周一至周五 UTC 01:00–04:00、06:00–10:00(中国法定节假日除外),其余时段均为平峰,平峰价是高峰价一半。数据来源:。

安装

# npm(推荐,0.10.15+ 统一裸名)
dsh plugin --profile web add dsh-union-search

# 或从源码/本地 tgz 安装
git clone https://github.com/drscrewdriver/dsh-union-search.git
dsh plugin --profile web add /path/to/dsh-union-search

注意:包名统一为裸名 dsh-union-search(scoped @drscrewdriver/dsh-union-search 自 0.10.15 起停止维护)。 DSH 以「bundle 行名 == 包内 name」判定客户端半(dsh-client-modules:locatePkgJson -> nearestPackage), 历史 scoped 安装升级到新版请用裸名重装(dsh plugin remove 后按裸名 add);插件已持久化设置(API key/引擎开关)以条目 id 为键,改名重装会重置,需重新配置(0.10.15 维护决策,2026-10-24 确认)。

然后重启:

dsh web

接管行为与验证

插件加载后自动接管搜索(运行时接管,不改配置层):

  • web.searchProvider 未设置,或仍是 DSH 出厂默认的官方搜索时,自动切换为本插件的 provider(id 固定为 ddg);出厂默认在 0.2.1-rc.2 起有两个 id——deepseek-official(Messages 服务端 web_search)与 deepseek-search-api(新内置的 Search/Fetch 独立 API),两者都会被识别并接管;
  • 如果(你或别的插件)已显式选择其他 provider,本插件不抢占,只在启动日志输出 WARN 与切换用的 YAML;
  • 设置页开启「屏蔽系统自带搜索」(blockSystemSearch: true)后,无论 web.searchProvider 指向谁,都强制接管为本插件 provider,且 deepseek-official 引擎被从所有引擎链中剔除;保存即生效,无需重启。

不再往配置里写 `searchProvider: ddg`:静态覆盖曾导致"悬空引用"——patch 是整段覆盖 config,一旦插件那一行被停用或跳过(比如在插件管理器里关掉),配置仍指向 ddg 而没有任何东西注册它,于是每次搜索都失败:

Error: configured web provider "ddg" is not registered

现在没有这层覆盖:插件被停用时 web.searchProvider 保持官方默认(deepseek-official),搜索至少还能走官方通道;插件启用时由上面的运行时接管切到 ddg。

0.2.1-rc.2 机制变化:宿主删掉了可写的运行时选择字段,改为每次调用读 web 条配置的 volatile 值(未配置且多个可用 provider 时报 WEB_PROVIDER_AMBIGUOUS)。本插件能力探测分流:≤rc.1 仍走内存接管(非持久);rc.2+ 经 settings 服务把 web.searchProvider: ddg 钉进条配置(持久)——若后续停用本插件,记得删掉该字段(或拨回官方开关),否则宿主会响亮报 CONFIGURED_MISSING;blockSystemSearch 开启时同步把 fetchProvider 钉回 http(web_fetch 保留,钳离按次计费的 deepseek-fetch-api)。
如果你曾按旧文档手动在 profiles//cordis.patch.yml 里加过下面这段,而插件没有启用,就会看到上面那条错误——删掉这段即可(或重新启用插件):
# 可选,通常不需要:只有你想强制指定时才加。
# DSH 0.1.2+ 的 patch 是"整段覆盖 config",必须保留 fetchProvider。
- id: web
  config:
    searchProvider: ddg
    fetchProvider: http
  • searchProvider: ddg —— 本插件的 provider id(固定值),不是"使用 DuckDuckGo 引擎";用哪个引擎由设置页的 provider 字段决定(bing/baidu/auto/…)。
  • fetchProvider: http —— 官方网页抓取(web-fetch-http),手动声明时必须保留。
  • 想改用官方搜索:在插件管理器里停用本插件条目即可,不需要改配置。

依赖说明

插件对 @deepseek-ai/dsh-settings 和 @deepseek-ai/dsh-tools 使用 peerDependencies,这是刻意的:DSH 运行时必须使用安装树中的唯一实例。请通过 dsh plugin --profile add ... 安装插件,不要把 DSH 核心包复制进 profile 的本地 node_modules;重复副本会导致工具调度器失效。

使用

网页设置(推荐)

安装后打开配置页(DSH 0.1.7-rc.1+):

  • 左侧 插件 页 → 已安装 分组 → union-search → 点击组件行 web-search-free(行内"配置"入口)

配置页提供:

  • Search engine:下拉框切换引擎,保存即生效
  • API keys:为 Exa / Tavily / Keenable / Firecrawl / Parallel / Perplexity / DeepSeek / SerpBase / Serply / You.com 填写 key(密码框,保存后只显示"已配置";Exa / Tavily / Keenable / Firecrawl / Parallel 不填也可免 key 使用)
  • 推荐:付费引擎 key 建议写入 harness 凭据中心 ~/.dsh/.credentials.yaml(如 DEEPSEEK_API_KEY: sk-...,与官方 LLM provider 一致,一处管理所有 key)。插件读取优先级:凭据中心 > 设置页 > 环境变量,设置页填的 key 仅作为遗留兼容。
  • Test engine:直测当前引擎可用性(不走回退链,付费引擎无 key 会明确报错)
  • Use Bing default:把当前搜索引擎切回稳定的免费 Bing;Discard 只撤销尚未保存的编辑
  • Platform search:勾选启用 GitHub / V2EX / Bilibili / YouTube / Vimeo 平台搜索(platform_search 工具按此过滤)
  • EN / 中文:切换界面语言(默认中文)

▲ 免费引擎(显示绿色 FREE 徽章与官网链接) ▲ 付费/API Key 引擎(显示橙色 API KEY 徽章与获取链接)

聊天框切换引擎(/union-search-engine)

不用进设置页也能切换引擎:在聊天框输入 /union-search-engine,弹出引擎选择窗口(和 /model 选模型一样的交互),点选即切换,当前引擎会标记出来。等效于设置页切换 + 保存,且界面语言跟随设置页(中文/英文)。

命令只改首选引擎配置,搜索仍走 web_search + 统一回退链:即使首选引擎挂了也会自动换其他引擎,永不直接失败。系统提示词同步刷新。

引擎开关、回退优先级与 Multi 模式

设置页有三个新块(都会保存进条目 config):

  • 全局启用的搜索引擎:取消勾选后,该引擎会从普通 web_search 回退链、Auto 智能路由、advanced_search、multi_search 和引擎测试中全局排除;至少要保留一个引擎。
  • 全局回退优先级:用 ↑↓ 调整先后顺序。首选引擎仍先尝试;Auto 保留"语言/时间"路由规则,但自定义后同一分组内及后续回退按此顺序。被禁用的引擎保留在列表里(标记「已禁用」)但不执行;「恢复默认顺序」一键还原。
  • 搜索引擎下拉里的 `Multi Search`:选中后 web_search 会并发查询路由/优先级前 3 个已启用引擎,URL 去重合并、跨源命中的结果排前面。注意并发会成倍消耗额度;Multi 失败时会自动退回普通单引擎回退链并在结果里注明。

失败分类与引擎冷却(Failure-aware fallback)

回退链不再把所有失败一视同仁,而是先给失败分类(issue #36):

  • `quota`(额度/预算耗尽,HTTP 402 / `NO_MORE_CREDITS` / SerpBase 免费额度用尽):立即切换,并把该引擎在本进程内冷却——后续搜索不再尝试它,避免反复撞墙;
  • `auth`(401/403、key 无效或未配置):同上,冷却到本会话结束(改好 key 重载插件即恢复);
  • `bot-wall`(如 DDG 反爬挑战):冷却一小段(默认 60s)后再自动放回链中;
  • `transient`(超时 / 5xx / 网络 / 429 限流):同一引擎重试一次再回退,避免一次抖动就丢掉好引擎;
  • `invalid-response`(解析失败 / 结构变化 / 返回 0 结果):照常回退,但归类为插件侧问题,不冷却引擎。

回退结果的 Note: 现在会给出具体类别,例如 Note: exa is out of quota, using doubao.、Note: perplexity is misconfigured (API key rejected), using doubao.、Note: bing failed (transient), using doubao.。free_search_test 也会为每个失败引擎附上类别(failureClass)。

冷却只作用于本进程(重载插件或重启即清空),且对配置的首选引擎同样适用:若它正在冷却,本轮会跳过并回退,结果里注明 is cooling down;冷却中的引擎一旦成功即自动解冻。

fallbackOn 控制哪些失败类别允许触发回退:默认勾选全部六类,即当前的「搜索永不直接失败」;取消某类后,遇到该类失败会停下并把该引擎的错误报出,不再换引擎(例如去掉 invalid-response:首选引擎返回空/解析失败时直接报错,而不是静默退回低质引擎)。设为空数组 [] 则任何失败都立即中止。注意缺 key、被禁用、不支持时间过滤不算失败,无论怎样都照常换引擎。设置页有对应勾选框,也可在 config 写 fallbackOn: [quota, auth, bot-wall, transient, invalid-response, unknown]。

配置文件

DSH 0.1.7-rc.1 起,配置跟随 profile 的插件条目保存:设置页与 /union-search-engine 都会写入当前 profile 的 cordis.patch.yml 中 web-search-free(dsh-union-search)条目的 config。

旧版 ~/.dsh/settings.yaml 的 free-search: 段不会被 DSH 核心自动导入(核心的 importLegacyDocument 只为 ui-developer-tools / ui-onboarding / shell 三个段提供了映射),原文件在导入其它段后会被改名为 settings.yaml.imported,该段的值只留在那里。插件会在启动时检测 settings.yaml.imported(或仍存在的 settings.yaml)中的 free-search: 段,把可识别的字段一次性补种进当前 profile 的条目 config(写一次后不再重复,可在启动日志看到 free-search: migrated N field(s)…)。如果你想手动处理,也可以照着 settings.yaml.imported 里的值在插件页行配置中填一遍。

# profiles/<profile>/cordis.patch.yml 中该条目的 config:
provider: bing              # ddg / ddg-lite / bing / searxng / anysearch / exa / tavily / keenable / firecrawl / parallel / perplexity / serpbase / serply / deepseek-official / you / baidu / kimi / aliyun / doubao / openai / gemini / claude / auto / multi
blockSystemSearch: false    # true = 屏蔽系统自带搜索:强制接管并把 deepseek-official/search-api 移出引擎链
advanceFetchEnabled: true   # false = 拒绝 advance_fetch 调用(热生效)
advanceFetchAllowPrivate: false # true = 放行 advance_fetch 访问回环/内网(局域网设备场景;协议/重定向门不变)
advanceFetchUserAgent: ""   # 空 = 内置默认 UA;可自定义用于按 UA 拦截的站
advanceFetchReferer: ""     # 空 = 不发 Referer;可配防盗链图床/接口解锁
advanceFetchCookieMap: ""   # 逐行 `域名 cookie串`(# 注释),如 weibo.com SUB=xxx;仅在目标匹配该域时附带,重定向换域不外流
searxngLanguage: auto       # SearXNG 返回语言:auto=按 query 检测;显式值=锁定(zh-CN/zh-TW/en/ja/ko/ru/de/fr/es/all)
fallbackOn: [quota, auth, bot-wall, transient, invalid-response, unknown]   # 允许触发回退的失败类别;[] = 任何失败都立即中止(默认全部)
lang: zh                    # 设置页界面语言(zh / en)
bingMarket: zh-CN           # Bing 市场
region: cn-zh               # DuckDuckGo 区域(可选)
searxngInstances:           # 自定义 SearXNG 实例(可选)
  - https://your-instance.example
exaApiKey: ...              # 或通过设置页填写
tavilyApiKey: ...           # 或通过设置页填写
keenableApiKey: ...         # 或通过设置页填写
firecrawlApiKey: ...        # 或通过设置页填写
parallelApiKey: ...         # 或通过设置页填写
perplexityApiKey: ...
serpbaseApiKey: ...         # 或通过设置页填写
serplyApiKey: ...           # 或通过设置页填写
deepseekApiKey: ...

一键测试全部引擎

设置卡底部点「测试全部引擎」,host 端逐个测试并列出结果;失败的引擎会进入建议禁用清单(默认全勾选),取消勾选不想禁用的项后点「应用禁用」再保存即可。暂时性故障(CAPTCHA/限流)可以跳过不禁用,日后随时可在引擎勾选区恢复。

时间过滤(advanced_search)

让 agent 搜"最近一周的新闻"、"这个月的发布"、"最近 3 天的消息"、"7 月以来的更新",它会调用 advanced_search 工具,带 timeRange 参数。该工具同样走统一回退链,且可显式指定 engine,返回结构同 web_search。

timeRange 支持三种形式:

形式 · 示例 · 含义 固定档 · day / week / month / year · 分别 = 1 / 7 / 30 / 365 天 自定义相对值 · 12h、3d、2mo、1y · 最近 12 小时 / 3 天 / 2 个月 / 1 年 绝对日期 · 2026-07-01 · 该日期(含)之后发布的结果

各引擎对 timeRange 的处理逻辑:

引擎 · 参数 · 是否精确 · 说明 Exa · startPublishedDate · ✅ 精确 · 自定义天数转成 ISO 日期(N 天前),绝对日期原样传入 Keenable · published_after · ✅ 精确 · 相对值原样传(12h/3d/2mo/1y),绝对日期原样传 Tavily · time_range · ⚠️ 近似 · 只认固定档,自定义天数自动映射到最近似档位 Firecrawl · tbs · ⚠️ 近似 · 固定档映射到 qdr:d/w/m/y;绝对日期用 cdr:1,cd_min:M/D/YYYY(精确) Parallel · source_policy.after_date(有 key 时精确);无 key 走 MCP,无日期参数,改为把窗口写进 objective 作为新鲜度提示(软过滤) · ✅ 精确 / ⚠️ 软过滤 · 自定义天数转成 ISO 日期(N 天前),绝对日期原样传入 SearXNG · time_range · ⚠️ 近似 · 同上 DuckDuckGo / Lite · df · ⚠️ 近似 · 同上 Bing / AnySearch · — · ❌ 忽略 · 无对应参数

"最近似档位"映射规则:≤2 天 → day,≤14 天 → week,≤90 天 → month,否则 year。例如 3d 在 Tavily 上按 day 处理,2mo 按 month 处理。

引擎链优先级:当带 timeRange 搜索时,支持时间过滤的引擎(tavily / exa / keenable / firecrawl / parallel / searxng / ddg / ddg-lite)会排到引擎链前面,确保过滤真正生效——即使首选引擎是 bing(不支持过滤),也会先尝试支持过滤的引擎。

示例对话:*"帮我搜最近 3 天关于 DSH 的新闻"* → agent 调用 advanced_search,timeRange: "3d"。

多源并发合并搜索(multi_search)

当需要对重要问题做多源交叉验证、避免单一引擎偏差或单源死锁时,可以让 agent 调用 multi_search 工具:

  • 并发请求:默认基于当前查询类型并发请求前 3 个优选引擎(或显式传入 engines 列表),各引擎独立解析 API Key 与容错(缺 key 引擎自动跳过,不阻断其他引擎)。
  • 去重与合并:按规范化 URL 去除结尾斜杠并合并结果,多引擎共同命中的条目优先置顶排在最前,并在结果附带 seenIn 命中来源清单(如 [seen in: bing, exa])。
  • 不可信边界与清洗:严格遵守 `` 数据边界,正文 snippet 统一清洗。
  • ⚠️ 注:多源并发会消耗更多 API 配额,建议在需要多角度核验时按需使用。

抓取网页内容(web_fetch)