聚合六个搜索后端,按序回退取最新结果
30.8/100
综合分
1
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/10/11 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
自动兼容检查有告警:未发布到 npm registry,仅可从源码安装。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add orfeomorello/dsh-websearch-stack该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:需留意
是什么
dsh 原生插件 · search
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 22 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
⚠︎ 实装验证未通过(dependency_conflict · 2026/10/31) ——可能是验证环境差异,装前建议到 GitHub 仓库确认最近更新与 issue。
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查⚠ 装前注意未发布到 npm registry,仅可从源码安装
展开查看检查明细 ↓
以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。
✗npm 包dsh-websearch-stack(未发布到 npm,仅可源码安装)
✓Node 引擎要求 >=22.19.0 · 基线 Node 22.19 满足
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明
验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/12 08:17:45
安全扫描自动 · 静态分析源码v2.7.0🟢 扫描:未发现敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描未发现敏感能力:最多只发网络请求、读取自身元数据或只读文件,未发现执行命令、文件写入或敏感信息读取。
发起外部网络请求
查看扫描证据(共 2 处,展示前 2 条)
- 发起网络请求lib/http.js:16
response = await fetch(url, { ...init, signal }); - 发起网络请求src/http.ts:25
response = await fetch(url, { ...init, signal })
扫描于 2026/11/1(1 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
依赖的 DSH / Cordis 模块
@deepseek-ai/schemastery@deepseek-ai/cordis@deepseek-ai/dsh-client-ui-primitives@deepseek-ai/dsh-client-locale@deepseek-ai/dsh-llm@deepseek-ai/dsh-web给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
功能亮点
- 聚合六个搜索后端
- 按序回退取结果
- 插件页管理密钥
README
由 DeepSeek 最新模型翻译生成dsh-websearch-stack
为 DeepSeek Harness(dsh)提供多服务商网页搜索。插件在 ctx.web 接缝上注册一个搜索服务商;这个服务商在你启用的后端上跑一条有序回退链。
状态:v0.1.0,MVP。已实现并做过单元测试的后端有六个。实测可用的有:Tavily 免密钥和 Parallel MCP。其余几个需要 API 密钥或本地实例,尚未验证——见已知限制。
功能
- 六个搜索后端:Tavily(可免密钥)、Parallel MCP(无需凭据)、SearXNG(自托管)、Brave、TinyFish、Exa。
- 有序回退链:可恢复的错误(网络、超时、限流、响应异常)会切到下一个后端;终止性错误直接中止;全部失败时,错误里会列出每一次尝试。
- 改密钥不用重启:四个需要密钥的后端在网页客户端的 Plugins 页面配置,写入 Host 的凭据存储,按请求解析——绝不写进设置文件,环境变量作为兜底。
- 启动时确定链路:链路顺序、SearXNG URL、结果上限、超时和缓存 TTL 都是易变字段,从你配置档的补丁层设置(见配置)。
安装
lib/ 已提交,所以从 GitHub 安装不需要构建步骤。
展开完整文档(README 剩余 1 节)
dsh-websearch-stack
为 DeepSeek Harness(dsh)提供多服务商网页搜索。插件在 ctx.web 接缝上注册一个搜索服务商;这个服务商在你启用的后端上跑一条有序回退链。
状态:v0.1.0,MVP。已实现并做过单元测试的后端有六个。实测可用的有:Tavily 免密钥和 Parallel MCP。其余几个需要 API 密钥或本地实例,尚未验证——见已知限制。
功能
- 六个搜索后端:Tavily(可免密钥)、Parallel MCP(无需凭据)、SearXNG(自托管)、Brave、TinyFish、Exa。
- 有序回退链:可恢复的错误(网络、超时、限流、响应异常)会切到下一个后端;终止性错误直接中止;全部失败时,错误里会列出每一次尝试。
- 改密钥不用重启:四个需要密钥的后端在网页客户端的 Plugins 页面配置,写入 Host 的凭据存储,按请求解析——绝不写进设置文件,环境变量作为兜底。
- 启动时确定链路:链路顺序、SearXNG URL、结果上限、超时和缓存 TTL 都是易变字段,从你配置档的补丁层设置(见配置)。
安装
lib/ 已提交,所以从 GitHub 安装不需要构建步骤。
dsh plugin --profile web add github:orfeomorello/dsh-websearch-stack
想先在一次性配置档上试:
dsh --profile web --dump-config > before.txt
dsh plugin --profile web add github:orfeomorello/dsh-websearch-stack
dsh --profile web --dump-config > after.txt
快速开始
默认链路 ['tavily', 'parallel-mcp'] 不需要密钥、不需要配置就能用:Tavily 免密钥运行,Parallel 不需要凭据。装好插件,重启配置档,然后问任何需要最新信息的问题——web_search 会通过这条链路作答。
接下来:
- 想要更多或不同的来源? 在配置档补丁里重排链路或加后端(见配置)——SearXNG、Brave、TinyFish 和 Exa 各自都需要单独设置;
- 想用自己的实例? 看 SearXNG:不依赖外部 API,不需要密钥,跑在你自己的基础设施上;
- 想要更高质量的 Tavily 结果,或者用 Brave/Exa? 在网页客户端的插件页面粘贴密钥;下一个请求就生效。
配置
分两个入口,因为网页客户端的 Plugins 页面只能写凭据:
| 内容 | 位置 | 何时生效 |
| API 密钥(TAVILY_API_KEY、BRAVE_SEARCH_API_KEY、TINYFISH_API_KEY、EXA_API_KEY) | Plugins 页面 → 本 bundle 的页面,通过设置卡片 | 下一个请求,无需重启 |
| enabled_providers、searxng_url、default_max_results、default_timeout_ms、cache_ttl_seconds | 你配置档里的 cordis.patch.yml(或 --patch 覆盖层) | 下次配置档启动时 |
第二份清单是 Host 的限制,不是插件的问题:在 @deepseek-ai/dsh-client-ui-plugin-manager 0.2.0-rc.2 里,页面渲染 plugins.bundle.config 时没有配置表单,所以 bundle 自己的字段永远拿不到控件。这些字段声明为 volatile(每个都是 Host 可以原地改写的引用),因此照着 plugins.row.config 写的表单——或者任何写这个命名空间的命令行工具——都能让它们即时生效;眼下还是得走配置档补丁。
启动时的值
这些值放在配置档自己的补丁层里,即 $DSH_HOME/profiles/<profile>/cordis.patch.yml,以本插件的 row id 为键。这个结构可以用 dsh --profile <profile> --dump-config 验证:
~/.dsh/profiles/web/cordis.patch.yml
- id: websearch-stack
name: dsh-websearch-stack
config:
enabled_providers: [tavily, parallel-mcp]
default_max_results: 5
想临时试一下又不动文件,可以用覆盖层,它在所有其他层之后应用:
dsh --profile web --patch ./searxng.yml
searxng.yml
- id: websearch-stack
name: dsh-websearch-stack
config:
enabled_providers: [searxng, tavily]
searxng_url: http://localhost:8080
字段缺省就保留默认值。未知的值会被 schema 拒绝,所以打错字会让启动失败,而不是悄悄禁掉某个后端。
Compose 风格的部署也可以把 URL 放进环境变量:entry-list YAML 方言在条目激活时求值 !!js 标量,作用域里有 Node 全局变量。
~/.dsh/profiles/web/cordis.patch.yml
- id: websearch-stack
name: dsh-websearch-stack
config:
enabled_providers: [searxng, tavily]
searxng_url: !!js process.env.SEARXNG_URL ?? ''
--dump-config 打印的是未求值的表达式节点——dump 出来的是存储的补丁,不是解析后的值。
| 选项 | 默认值 | 含义 |
| enabled_providers | ['tavily', 'parallel-mcp'] | 回退链,按顺序。取值:tavily、parallel-mcp、searxng、brave、tinyfish、exa。空列表会禁用插件(见回退如何工作)。 |
| searxng_url | — | 自建 SearXNG 实例的基础 URL,例如 http://localhost:8080。searxng 必填。 |
| default_max_results | 5 | 请求未指定时,每次查询的最大来源数(1–20)。 |
| default_timeout_ms | 10000 | 每个后端的请求超时,单位毫秒(1 000–60 000)。 |
| cache_ttl_seconds | 60 | 相同查询的缓存 TTL。0 禁用缓存。 |
SearXNG
自建方案:用你自己的实例,不依赖外部 API,也不需要密钥。它需要两样东西——一个启用了 JSON 格式的实例,以及指向它的 searxng_url。
1. 跑一个实例(Docker Compose,项目推荐的布局):
mkdir -p ./searxng/core-config/bash
cd ./searxng/
curl -fsSLO https://raw.githubusercontent.com/searxng/searxng/master/container/docker-compose.yml
curl -fsSLO https://raw.githubusercontent.com/searxng/searxng/master/container/.env.example
cp -i .env.example .env
docker compose up -d
2. 在 core-config/settings.yml 里启用 JSON 格式 —— json 不在默认的 search.formats 里(默认只有 html): yaml search: formats:
- html
- json
3. 让插件指向它(配置档补丁,然后重启配置档): yaml
- id: websearch-stack
name: dsh-websearch-stack
config:
enabled_providers: [searxng, tavily, parallel-mcp]
searxng_url: http://localhost:8080
后端会调用 GET <searxng_url>/search?q=…&format=json&language=en,并读取 results[].{url,title,content}。没有 searxng_url 时,后端会把自己标记为不可用,链路继续往下走。SearXNG 自身的安装细节见它的 container 和 search: settings 页面。
后端
| Id | Key | 说明 |
| tavily | TAVILY_API_KEY(可选) | 不带 key 时发送 x-tavily-access-mode: keyless(已实测)。带 key 时用 Bearer。 |
| parallel-mcp | 无 | 在 web_search 上走 JSON-RPC tools/call(参数为 objective 和 search_queries),无需凭据。已实测。 |
| searxng | 无 | 自建实例,需要 searxng_url。未实测(需要实例)。 |
| brave | BRAVE_SEARCH_API_KEY | X-Subscription-Token。未用真实 key 实测。 |
| tinyfish | TINYFISH_API_KEY | X-API-Key。未用真实 key 实测。 |
| exa | EXA_API_KEY | x-api-key,POST /search。未用真实 key 实测。 |
Key 从 Host 凭据存储读取,上面的环境变量作为兜底:从设置卡片写入的 key 按请求解析,所以不需要导出环境变量。配置 YAML 里永远不放密钥。
设置卡片(web 客户端)
插件为 dsh web 客户端(dsh.client.platform: "web")附带一张配置卡片。它出现在 Plugins 页面 dsh-websearch-stack 包下,通过 Host 的 credentials 服务管理四个基于 key 的 API key:
- 状态徽章只显示 key 是否已配置(describe),从不显示值;
- 你写入的内容落在 Host 凭据存储里(例如 $DSH_HOME/.credentials.yaml),不落在任何设置文档里;
- 服务商会在 Host 的 credentials/reference-updated 事件上重新解析引用,所以从页面写入的 key 下一次请求就生效,不用重启;
- 留空的字段不会清除已存储的 key;
- 每个字段以对应服务商命名 —— Tavily API key、Brave Search API key、TinyFish API key、Exa API key —— 下面的 Search providers 区块把每个后端都链接到其所属站点(见下文)。
UI 状态:页面和卡片已在实时 Web 客户端中验证过(bundle 页面、它的标题、关键控件和 providers 区块都能渲染)。宿主没有渲染的,是这个 bundle 自身配置字段的表单——见配置和已知限制。
插件页面显示什么
Plugins 页面中这个 bundle 的详情会说明 bundle 自身的身份——来自 locale/en.json 的显示标题、版本号、包名(就是你在别处安装的那个,显示在一行 里)——然后是插件的配置:四个关键控件,以各自的服务商命名,还有一个 Search providers 区块,列出链式词汇表接受的所有后端:
| 服务商 | 需要什么 | 在哪里配置 |
| Tavily | API key 可选(无 key 也能用) | https://app.tavily.com/home |
| Parallel | 不需要 key | https://docs.parallel.ai/ |
| SearXNG | 自托管实例 | https://docs.searxng.org/ |
| Brave Search | API key | https://brave.com/search/api/ |
| TinyFish | API key | https://docs.tinyfish.ai/search-api/reference |
| Exa | API key | https://exa.ai/ |
每一行都链接到对应服务商的站点,在那里创建 key,或者查阅服务文档。这个区块是 bundle 对页面 plugins.detail.section 插槽的贡献;文案放在 src/client/card.ts。
与原生 DeepSeek 服务商共存
web 配置档已经自带 web-search-deepseek(provider id 为 deepseek-official),而 @deepseek-ai/dsh-base 把接缝固定到它: yaml
- id: web
name: '@deepseek-ai/dsh-web'
config:
searchProvider: deepseek-official
fetchProvider: http
这个固定对任何第三方搜索服务商来说就是全部问题所在:DeepSeek 服务商的 available() 即使没有 DEEPSEEK_API_KEY 也返回 true(它在每次搜索时解析凭据,而不是在选择时),所以只要固定生效,每次 web_search 都会以 WEB_PROVIDER_CREDENTIAL_MISSING 失败,永远到不了这个 bundle 注册的服务商。
因此这个 bundle 的 cordis.patch.yml 覆盖了那一行(越靠后的 bundle 层越优先;配置档自己的补丁、home 补丁和 --patch 覆盖层更靠后,想固定什么都可以): yaml
- id: web
name: '@deepseek-ai/dsh-web'
config:
searchProvider: websearch-stack
fetchProvider: http
补丁会替换匹配行的整个 config——绝不是深度合并——所以 fetchProvider: http 要原样重写,和基础行留下的完全一致。配置档里没有 @deepseek-ai/dsh-base 时,web 行不存在,覆盖会被跳过并给出加载器警告,接缝会自动选择这个服务商,因为它是唯一可用的。
要把 web_search 交还给原生服务商,就在配置档的 cordis.patch.yml(或 --patch)里重新固定它,两个键都要重写: yaml
- id: web
config:
searchProvider: deepseek-official
fetchProvider: http
回退机制如何工作 seam 在未配置任何搜索服务商时,会接受一个可用的搜索服务商。因此插件只注册一个服务商 websearch-stack,它按顺序遍历各后端:
- 不可用的后端(没有 key、没有 SearXNG URL)在发起任何请求之前就跳过;
- 可恢复的错误(网络、超时、限流、响应无效、认证或额度)会转到下一个后端;
- 终止性错误(例如取消)会停止整条链并重新抛出;
- 如果全部失败,错误里会列出每一次尝试。
链的顺序在每次请求时读取,所以在配置档补丁里修改 enabled_providers,从下次启动起生效,链上每个后端也会按请求重新解析。当链为空——或者链上每个后端都不可用——available() 为 false,seam 返回 WEB_PROVIDER_CONFIGURED_UNAVAILABLE,因为 bundle 补丁把 searchProvider 固定到了这个服务商。在配置档补丁里重新加回一个后端,web_search 就能恢复工作。
开发 bash
npm install
npm run typecheck # tsc --noEmit
npm test # unit/integration tests (node:test)
npm run build # rebuild lib/ from src/ (also emits the client bundle)
npm run bundle:client # rebuild only lib/client.js (ModuleLoader bundle)
lib/ 已提交到仓库。改完 src/ 之后,运行 npm run build,并把 lib/ 一起提交——两者不一致时 CI 会失败。
已知限制
- 实时服务只验证了一部分。 Tavily 无 key 模式和 Parallel MCP 已实测通过。Brave、TinyFish、Exa 和 SearXNG 还没验证:它们需要 API key 或本地实例。
- 链无法从 Web 客户端编辑。 Plugins 页面会渲染 bundle 的配置卡片(这里的 API key),但不会渲染 bundle 自身配置字段的表单:在 @deepseek-ai/dsh-client-ui-plugin-manager 0.2.0-rc.2 中,plugins.bundle.config 渲染时没有传 form prop,而 plugins.row.config 会收到它。给插件的行加一个 plugins.row.config 条目就能补上这个缺口;在那之前,请编辑 $DSH_HOME/profiles/<profile>/cordis.patch.yml 并重启配置档(见 Configuration)。
- seam 被固定,这是有意为之。 bundle 补丁把 web.searchProvider 固定到 websearch-stack,因为基础配置档把它固定到了 DeepSeek 服务商,而后者没有 key 时 available() 也为真。后果是:链为空时 web_search 会以 WEB_PROVIDER_CONFIGURED_UNAVAILABLE 失败,而不会回退到原生服务商(见 Coexisting with the native DeepSeek provider)。
- 不做抓取。 页面抓取由 DSH 的 dsh-web-fetch-http 服务商处理,不是这个插件。
- 不是沙箱。 代码和每个 dsh 插件一样,以宿主进程的权限在宿主进程内运行。
License
MIT — 见 LICENSE。预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
orfeomorello/dsh-websearch-stack
聚合六个搜索后端,按序回退取最新结果
相关插件 · 搜索 / 抓取
LLM 知识平台Tencent/WeKnora
概览 ·快速开始 ·新特性 ·功能 ·客户端 ·文档 ·开发
★ 36,161已汉化DSH
72.1
智能体记忆系统MemTensor/MemOS
MemOS 2.0 Stardust星尘
★ 12,195已汉化DSH
71.2
跨代理记忆库zilliztech/memsearch
跨平台语义记忆,专为 AI 编程智能体打造。
★ 2,799已汉化DSH
70.9
技能语料库EverMind-AI/SkillCorpus
SkillCorpus 能给你什么
★ 694已汉化DSH
69.7
代码图谱记忆syncable-dev/memtrace-public
你的智能体值得拥有结构化记忆。
★ 509已汉化MCP
67.9
AnySearch 搜索插件anysearch-team/anysearch-dsh
AnySearch 网页搜索服务商,为 DeepSeek Harness(DSH)提供高级搜索工具
★ 457已汉化DSH
66.6