Skip to content

dsh-web-search-searxng

Verified

@lathly/dsh-web-search-searxng · v0.1.0 · MIT

Self-hosted SearXNG search provider plugin for the DSH web capability seam (ctx.web)

Install

dsh plugin add @lathly/dsh-web-search-searxng

Confirm the layer applied with dsh --profile default --dump-config — see the install guide.

Source

Creators

Readme

@lathly/dsh-web-search-searxng

面向 DeepSeek Harness 的自托管 SearXNG 搜索提供方插件。Harness 通过你自己的 SearXNG 元搜索实例检索网络:不需要 API key,也没有第三方能看到查询。

English | 中文

这个包为什么存在

DSH 自带三个搜索提供方:deepseek、exa、perplexity。三者都需要 key,三者都会把查询发给第三方。这一族里没有自托管选项。

本插件在同一个公开接缝 ctx.web.registerSearchProvider 上注册第四个提供方,让部署把查询和引擎组合留在自己的硬件上。它是独立发布的包,装进任何 DSH 部署即可,不需要 fork 仓库。

安装

npm install @lathly/dsh-web-search-searxng

DSH 各包声明为 peerDependencies,因此插件使用宿主自带的 @deepseek-ai/cordis、@deepseek-ai/dsh-web、@deepseek-ai/dsh-launch-environment 与 @deepseek-ai/schemastery。同一进程里出现第二份 Cordis,插件拿到的 web 服务就会与宿主的不同;这一布局正是为了避免该故障。

经过测试的版本是 0.2.1-alpha.2 一线:@deepseek-ai/dsh-web 0.2.1-alpha.2、@deepseek-ai/dsh-launch-environment 0.2.1-alpha.2、@deepseek-ai/cordis 4.0.5-alpha.1、@deepseek-ai/schemastery 3.18.5-alpha.1。

你的实例

SearXNG 必须提供 JSON API。在 settings.yml 中:

search:
  formats:
    - html
    - json

没有 json 的实例会返回 HTML 正文,每次搜索都以 WEB_PROVIDER_ERROR 失败。

挂载

本包附带 bundle patch,因此能解析到该包的 DSH bundle 会自动挂载它:

- name: '@deepseek-ai/dsh-web'
- name: '@lathly/dsh-web-search-searxng'

或写进 profile overlay:

- insert:
  - id: web-search-searxng
    name: '@lathly/dsh-web-search-searxng'
    config:
      baseURL: http://localhost:8888

提供方以 searxng 身份注册。当它是唯一可用的搜索后端时,ctx.web.search() 会自动解析到它。若同时存在其他可用提供方,请用 searchProvider: searxng 指定;deepseek-official 在没有 API key 时仍报告为可用,因此两者并存的部署必须指定其一,否则每次搜索都以 WEB_PROVIDER_AMBIGUOUS 失败。

配置

实例地址按此顺序解析:config.baseURL,然后启动环境中的 $SEARXNG_URL,最后是包内默认值 http://localhost:8888。

字段 默认值 含义
baseURL $SEARXNG_URL,然后 http://localhost:8888 SearXNG 实例地址;请求时追加 /search。无法解析的值会使提供方不可用
engines (未设置) 逗号分隔的引擎白名单,作为 SearXNG 的 engines 发送。它只在实例自身已配置的引擎内收窄
categories (未设置) 逗号分隔的分类,作为 SearXNG 的 categories 发送

一次搜索返回什么

每条 SearXNG 结果映射为一个 WebSearchSource:url、非空的 title、去除首尾空白的 content 作为 snippet,以及引擎提供时的 publishedDate 作为 publishedAt。没有 URL 的条目被丢弃。引擎扇出产生的重复 URL 保留第一条。

非空的 answers[] 会并入结果的 content。这是该族中唯一能携带生成式答案的后端,因为 SearXNG 的答案块已经存在于线路上。实例没有可生成答案的引擎时,就没有 content。

SearXNG 没有结果数量参数,因此请求的 maxResults 在服务侧约束最终来源,而不是约束请求本身。实例自身的扇出仍会完整执行。

失败

提供方失败(HTTP 错误、网络失败、无法解析或结构不符的正文)以 WebError 呈现,代码为 WEB_PROVIDER_ERROR。被中止的请求呈现为 WEB_ABORTED。重定向在联系 Location 目标之前即被拒绝,因此行为异常或被劫持的实例无法把查询转发到其他来源。

当实例地址无法解析,或某个过滤器被设置为空值时,提供方不可用,每次搜索调用都以结构化错误失败。

模型体验

经由 dsh-tool-web 间接呈现。该消费者保留本提供方受 maxResults 约束的 URL、标题、摘要、发布日期与实例答案块,或保留其原样的 SearXNG search aborted、SearXNG search request failed: <error>、SearXNG returned an unprocessable response body: <error> 失败文本,并套用消费者自身的错误包装。

不直接失效 KV 缓存;请求前缀的任何变化由该消费者负责。

设计说明

本提供方是 SearXNG JSON API 之上的薄适配层,带有三条刻意规则。

  • 结构上无凭据。 SearXNG 的 API 不需要 key,因此没有可泄露的东西。提供方仍然选择加入该族的重定向拒绝策略。
  • 只使用可移植来源。 来源的 snippet 只来自 SearXNG 的 content 字段。空白或带填充的值会被裁剪或省略,绝不编造。
  • 诚实的答案。 answers[] 是实例自己的自由文本块。它被并入 content 而不是丢弃。

search() 请求 {baseURL}/search?q=<query>&format=json,可带 engines 与 categories 参数,并使用 redirect: 'error'。解析出的 results[] 逐条映射,无 URL 的条目丢弃,重复项去除,服务在返回途中施加最终的 maxResults 约束。中止(名为 AbortError 的 DOMException)转为 WEB_ABORTED;其他情况转为 WEB_PROVIDER_ERROR。

已知限制

  • 实例必须启用 JSON API。 只有 HTML 的实例会使每次搜索以 WEB_PROVIDER_ERROR 失败,而不是 harness 能够报告的配置错误。
  • 实例侧控制未暴露。 引擎组合、默认分类与答案块取决于实例的 settings.yml 与引擎集合。engines 与 categories 只在其中收窄。
  • maxResults 在扇出之后生效。 实例先取回完整结果集,服务再截断,因此较大的实例答案要付出其完整延迟。
  • 中止判定依赖错误形态。 只有名为 AbortError 的 DOMException 映射为 WEB_ABORTED。携带自定义原因的中止,例如 dsh-timeout 的 TimeoutReason,会呈现为 WEB_PROVIDER_ERROR。
  • API 尚未稳定。 DSH 的 API 处于 pre-stable 阶段。改变 WebSearchProvider 的 DSH 版本可能破坏本插件;测试套件会最先暴露这一点。

开发

pnpm install
pnpm run typecheck   # 针对已发布的 DSH 包做类型检查
pnpm run test        # 26 个单元与真实组合测试,无需实例
pnpm run test:e2e    # 真实实例冒烟测试;实例无响应时自动跳过
pnpm run build       # 产出 lib/*.js 与 lib/types/*.d.ts
文件 职责
src/index.ts 插件入口:配置 schema、环境变量回退、提供方注册
src/provider.ts SearxngSearchProvider:请求分发、中止分类、结果映射
src/types.ts SearXNG 线路类型:SearxngResponse、SearxngResult

待办:SearXNG 的 time_range、safesearch、language 控制仍未暴露。暴露它们需要先有提供方中立的服务字段,让这一族加入一个统一控制,而不是某个厂商专用的参数。

与上游的关系

该提供方也存在于 DSH 仓库内,包名 @deepseek-ai/dsh-web-search-searxng,路径 packages/web/web-search-searxng。那份副本是 fork 仓库所携带的版本。本包是同一个提供方的独立发布,目的是让不改动上游的部署也能把搜索留在自己的硬件上。