dsh-searxng-search:给 DSH 接一个免 API key 的本地搜索引擎

前言

DSH 自带的 web_search 默认把 ctx.web 钉在 deepseek-official provider 上,这个 provider 需要 DEEPSEEK_API_KEY。没有这个凭据时 searchReady() 返回 false,web_search 会被扣下,模型每一步只剩 web_fetch。想自建搜索又不想交密钥的人,面对的就是这个门槛。

下面介绍的 Jfreey/dsh-searxng-search 补的正是这个缺口:在本机装一个 SearXNG,把它跑起来,再把 web_search 指过去。

它是什么

一个 DeepSeek Harness 插件,维护者 Jfreey,属于联网工具分类。它没有绕过 DSH 的搜索接口,而是在 ctx.web 上注册一个名为 searxng 的 provider,自带的 web_search 保持原有 schema、格式和结果卡片不变。

用户不需要申请 API key,也不用按查询量付费。SearXNG 自托管,聚合 Bing、Sogou、360search 等引擎,没有广告、没有追踪、没有跳转包装。

核心能力

README 把插件拆成五块,各自职责如下:

  • Provider:注册 searxng provider。既有的 web_search 工具保持 schema、格式与结果卡片不变。
  • Supervision:每次搜索前探 /healthz;服务器挂了就通过 launchd、systemd、Windows 任务或插件自己拥有的子进程把它拉起来。
  • Installer:scripts/bootstrap-searxng.sh(macOS、Linux)和 scripts/bootstrap-searxng.ps1(WSL)以幂等方式安装或修复实例,从不覆盖已有 settings 文件。
  • Settings page:按类别分组的引擎表,一键探测本机可达的引擎、一份推荐名单,以及出站代理设置。
  • Proxy:读写 SearXNG 的 outgoing.proxies.all://,让引擎请求经过本地代理。

安装与启用

顺序是先准备 SearXNG,再装插件。

# 1. 准备一个可指向的 SearXNG(已自行运行时可跳过)
./scripts/bootstrap-searxng.sh            # macOS / Linux
./scripts/bootstrap-searxng.sh --print    # 先看计划再执行

# 2. 把插件装进 DSH profile
#    在 DSH 里走 Plugins → install from a directory,或
dsh plugin install /path/to/dsh-searxng-search

安装脚本要求环境有 git、Python 3.11+,以及 macOS、Linux 或 WSL。SearXNG 还必须开启 JSON 输出,即 search.formats 里包含 json。

指向已有实例时改 config.baseUrl 即可;指向另一台机器时,用 ensure.enabled: false 把监督关掉,避免插件去拉远端机器的进程。

端口是两边必须一致的隐式约定。安装脚本遇到端口被不属于 SearXNG 的进程占用时直接拒绝,并打印是谁占着:

Port 8888 is taken by another process:
  python3.1 (pid 835)
Nothing was installed. Use another port, and set the plugin's baseUrl to match:
  SEARXNG_PORT=8899 ./scripts/bootstrap-searxng.sh
  config.baseUrl: 'http://127.0.0.1:8899'

改成另一个端口时,脚本里传 SEARXNG_PORT,插件侧同步改 config.baseUrl。没有自动端口回退:脚本和插件得就同一个端口达成一致。如果插件指向的端口是死的,它会扫描 8888–8896,找出既回答 /healthz 又能从 /config 返回引擎列表的实例,并提示应该用的地址。

配置

插件配置位于 profile 里,一段完整的写法如下:

- id: searxng-search
  name: 'dsh-searxng-search'
  config:
    baseUrl: 'http://127.0.0.1:8888'
    settingsPath: '~/.local/share/searxng/searxng.yml'   # 可选,这是默认值
    id: searxng              # web 服务钉住的 provider id
    maxResults: 20           # provider 侧下限,工具还会再封顶一次
    timeoutMs: 20000
    safesearch: 0
    probeTimeoutMs: 12000    # 单次引擎探测
    # 可选的 SearXNG 查询参数,为空时省略:
    # language: zh-CN
    # categories: general
    # engines: google,bing
    ensure:
      enabled: true
      healthPath: /healthz
      probeTimeoutMs: 1500
      startupTimeoutMs: 20000
      probeIntervalMs: 400
      retryCooldownMs: 15000
      launchAgent: com.searxng.server   # macOS
      systemdUnit: ''                   # Linux,例如 searxng.service
      windowsTask: ''                   # Windows(仅 WSL)
      windowsService: ''
      command: ''                       # 通用兜底,由插件拥有
      args: []
      cwd: ''
      env: {}

监督是怎么跑的

每次 web_search 先探 GET /healthz,预算 1.5 秒。服务器没起来时按下面三级顺序处理,然后轮询到健康为止(预算 20 秒),再执行搜索:

  1. 本平台的监督器,前提是已配置且已安装。由该管理器拥有进程,插件不会去 kill 它。
  2. 否则用 ensure.command,插件通过 ctx.subprocess 启动它,并拥有它,卸载插件时终止。
  3. 两者都没有时搜索失败,错误信息列出试过哪些方式、该改哪个配置或装哪部分。

启动失败会被记住 retryCooldownMs,并发搜索共享一次恢复尝试。provider 不实现 ready(),因此 web_search 始终对每次模型调用开放——服务器宕机时表现为一条可操作的工具错误,而不是工具无声消失。

平台支持

平台 监督器 安装脚本 状态
macOS LaunchAgent,launchctl kickstart -k gui/<uid>/<label> bootstrap-searxng.sh 真机验证过安装、自愈与干净卸载
Linux systemd user unit,systemctl --user restart,失败回退 systemctl restart bootstrap-searxng.sh 安装器、设置、JSON API 与插件往返在 Ubuntu 24.04 容器验证过;unit 本身只用打桩的 systemctl 验证
Windows — bootstrap-searxng.ps1 在 WSL 之外直接拒绝 不支持原生运行:SearXNG 的 searx/valkeydb.py import 了 POSIX 专属的 pwd 模块,进程在 import 阶段就退出。改用 WSL、Docker,或用 config.baseUrl 指向 Linux/macOS 实例

插件那一半是纯 Node,任何平台都能跑;被 POSIX 绑定的只有服务器本身。

引擎页的打分

Settings 页打开后会立刻探测已经勾选的引擎,因此表格永远不会空着,也可以按需重新探测。每项打分 0–100,构成如下:

组成 分值 规则
应答 55 返回合法 JSON,且没有针对它的 unresponsive_engines 条目
延迟 25 / 18 / 10 / 4 / 0 ≤0.8s / ≤2s / ≤5s / ≤15s / 更慢
返回量 20 / 12 / 4 ≥5 条 / 1–4 条 / 无

这是可用性评分,不是准确率——没有任何组件把引擎答案和 ground truth 做比较。没有 labelled corpus、也没做跨引擎一致性采样,页面不做这种声称。

分数上方会标出两类建议:没应答的引擎(CAPTCHA、被封、被停用)和应答慢于 5 秒的引擎,两者都提供一键「select the working set」,只取消勾选这些。零结果不算建议:探测只发一条短查询,货币或翻译类引擎在 5ms 内合理地返回空但本身正常,这类只作为 note 列出。

Apply 会为每个引擎写一条显式开关(- name: "<engine>" + disabled: true|false),并删掉 use_default_settings.engines.keep_only。白名单是单向门——写进去之后 /config 只返回被保留的引擎,其他引擎会从页面上消失且无法再打开。首次 apply 会把文件从它迁走;页面也会列出从 SearXNG 自己的 searx/settings.yml 解析出的引擎,因此即便还没迁移,目录也是完整的。

适用场景与注意

适合这样几类人:

  • 想本地跑搜索、不接受第三方密钥和按量计费的 DSH profile 使用者。
  • 已经会自建 SearXNG、需要让 DSH 指向它的人。
  • 网络环境里部分引擎不通、想按自家网络实测结果挑引擎集合的人。

需要留意的点:

  • 插件以当前 dsh 进程的权限运行,安装前应检查插件源码与许可证(license 为 MIT)。
  • Windows 原生跑不起来服务器,只能走 WSL 或 Docker,或指向远端实例。
  • 引擎表打分只反映可达性、延迟和返回量,不代表搜索质量;要判断质量得自己搭 labelled 语料或做一致性采样,插件没做这件事。

结尾

这个插件的价值不在于换一套搜索接口,而在于把「免 key 的本地搜索」变成 DSH profile 里的一个插件开关:装一次,web_search 就能指向自己机器上的 SearXNG,服务器宕了按配置自愈,引擎集合按本机实测结果调整。所有代码在 GitHub 上开源,目录页是社区站点,与 DeepSeek / 幻方没有官方从属关系。

  • 目录页:https://www.skillhub.cn/plugins/Jfreey/dsh-searxng-search
  • GitHub:https://github.com/Jfreey/dsh-searxng-search
羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜