dsh-plugin-search-hub
DeepSeek Harness 的多引擎网页搜索插件(插件页显示名:中文界面为“多引擎网页搜索”,英文界面为“Multi-engine Web Search”,文案在 locale/ 里):
- 免费模式:在 Exa、Parallel、Firecrawl、Keenable 四家匿名免费端点之间轮询(与 Hermes Agent 使用的端点相同),不需要任何 API key。
- 冷却:某家引擎被限流(429、限流提示文本)或出故障(401/402/403/5xx、网络错误、超时)后,会被跳过 60 秒,同一次请求自动换下一家。服务端返回的
Retry-After 更长时,以它为准。
- 付费引擎:Tavily、Brave、Serper(Google)、Exa、Perplexity Sonar、Jina、博查、SearXNG(自建)。
- 三种模式:
single(单个引擎)、fallback(按顺序降级)、round-robin(轮流使用)。free 可以作为一个整体放进任意模式。
- 结果控制:设置结果个数、内容截断长度(超过多少字就截断,省 token)、屏蔽的网站(黑名单)。
- 图形设置页:在插件页里切换模式、引擎和顺序,填写 API Key。Key 存在 dsh 的凭据库里,不写进配置文件,保存后下一次搜索立即生效。
web_fetch 沿用 dsh 内置的实现。
怎么接入 dsh
| 部分 | 入口 | 作用 |
|---|
| 服务 | dsh-plugin-search-hub | 宿主层的 ctx.pluginSearchHub,负责引擎注册、调度和冷却,所有会话共享一份冷却状态。它同时注册为 ctx.web 的搜索提供方 plugin-search-hub。 |
| 设置页 | dsh-plugin-search-hub/client | 显示在插件页的“多引擎网页搜索”详情页上。 |
| 工具 | dsh-plugin-search-hub/tool | 参数更丰富的 web_search(时间范围、域名、地区、语言、新闻),挂在宿主层。 |
bundle 补丁把 web 行的 searchProvider 设为 plugin-search-hub:
- 桌面版 / Web:每个智能体预设自带的
web_search 都通过 ctx.web 搜索,所以全部自动走 Search Hub,不需要额外的预设。这里模型使用内置工具的参数格式(只有查询词),时间范围、域名等过滤参数用不了;引擎、模式、免费轮询和冷却都照常生效。
- TUI / headless:宿主层的内置搜索关掉,换成本插件的
web_search,带完整的过滤参数。
如果在桌面版的“网页搜索”官方设置页里切换了 DeepSeek 搜索 API,web 的搜索提供方会被改回 DeepSeek。想切回 Search Hub,删掉 profile cordis.patch.yml 里 web 行的覆盖即可。
安装
在 DeepSeek Harness 桌面版里:插件 → 添加插件,输入 dsh-plugin-search-hub,安装后打开开关,重启 App。
命令行:
dsh plugin --profile <name> add dsh-plugin-search-hub
从源码安装:
pnpm install && pnpm build
dsh plugin --profile <name> add /path/to/dsh-plugin-search-hub
pnpm build 会编译宿主端代码(lib/*.js),并用 esbuild 生成浏览器端 lib/client.js(dsh 客户端模块加载器所需的 factory 格式)。
设置
打开 插件,在“已安装插件”里点 多引擎网页搜索,设置就直接显示在详情页上:
- 搜索模式:单引擎 / 顺序降级 / 轮询。
- 使用的引擎:单引擎模式下单选;另外两种模式下勾选,并用箭头调整顺序。每个引擎旁边会标出“免费”“已配置 Key”或“未配置 Key”。
- API Key:只显示已选引擎的输入框,紧跟在引擎列表下方。留空表示保留当前的 Key,“清除”会删除已保存的 Key。也可以用同名环境变量提供,例如
TAVILY_API_KEY。选了 SearXNG 时会显示它的地址输入框。
- 结果个数:每次搜索最多返回几条(1–20)。桌面版内置的
web_search 自身最多取 8 条,设得比 8 大时以 8 为准。
- 内容截断长度:每条结果的摘要,以及引擎附带的总结(Tavily、Perplexity 等会返回),超过这个字数就截断。默认是 0,即不截断。
- 屏蔽的网站:这些域名(含子域名)的结果一律去掉。支持排除参数的引擎会直接在请求里排除,其余的由插件在本地过滤,并多要几条结果来补足数量。
- 冷却时间、单次尝试超时。
“已修改”只在值和默认值不同时显示。
也可以直接改 profile 的 cordis.patch.yml(补丁会整体替换这一行的 config,所以要把需要的字段写全):
- id: plugin-search-hub
config:
mode: fallback # single | fallback | round-robin
engine: free # single 模式使用的引擎
engines: [tavily, brave, free]
cooldownSeconds: 60
attemptTimeoutMs: 15000
maxResults: 8
truncateChars: 0 # 默认 0,不截断;填 500 表示超过 500 字截断
blockedDomains: [csdn.net]
searxngUrl: https://searx.example.org
可选的引擎 id:free、exa-free、parallel-free、firecrawl-free、keenable-free、tavily、brave、serper、exa、perplexity、jina、bocha、searxng。
| 引擎 | 凭据名(环境变量) |
|---|
| Tavily | TAVILY_API_KEY |
| Brave | BRAVE_SEARCH_API_KEY |
| Serper | SERPER_API_KEY |
| Exa | EXA_API_KEY |
| Perplexity | PERPLEXITY_API_KEY |
| Jina | JINA_API_KEY |
| 博查 | BOCHA_API_KEY |
| SearXNG | SEARXNG_URL(也可以在设置页填地址) |
在 fallback / round-robin 模式里,没配 key 的引擎会被跳过(不进入冷却),并在结果里说明缺少哪个变量。
开发
pnpm typecheck
pnpm test # 63 个单元测试,不访问网络
node scripts/smoke.ts # 真实调用免费引擎,打印轮换和冷却情况
test/fixtures/ 里是从四个免费端点抓下来的真实响应。
已验证与未验证
- 已验证:
- 四个免费端点的请求和响应格式(真实调用)。
- Exa 免费档限流文本的识别。
- 在 dsh 0.2.1-rc.2 的独立 web profile 里:bundle 安装和配置合成(
web 行已切到 plugin-search-hub),设置页的显示,模式、引擎、结果个数、截断长度、黑名单的保存,Key 的保存和清除(Key 只写进凭据库),按所选引擎显示 Key 输入框。
- 未验证:
- 8 个付费引擎是按各家公开文档写的,没有真实调用过。
- 在桌面版里实际跑一轮带搜索的对话。
卸载
在插件页的详情页里点“卸载”,或者:
dsh plugin --profile <name> remove dsh-plugin-search-hub
发布
npm publish
prepublishOnly 会先跑类型检查、单元测试和构建。