用 modsearch 给 DeepSeek Harness 补上联网搜索桥接

前言

DeepSeek Harness(dsh)是 DeepSeek 开源的智能体运行时,官方定位是开发者预览版,口号是「一切皆插件」:模型适配、工具注册、会话日志、Agent 循环,都可以用插件替换,而不必改运行时源码。启动 Web UI 的官方入口是:

npx @deepseek-ai/dsh web

真正动手时,另一个缺口很快出现:不少主力模型本身没有联网,或者官方搜索只覆盖网页、不覆盖指定页面和 X(Twitter)。问「今天 Node.js LTS 是哪一版」、贴一篇博客让它概括、追一条推文讨论,模型只能凭训练数据猜。dsh 虽然自带 web_search 接缝,默认钉在 DeepSeek 带 key 的搜索 API 上;自带的 web_fetch 则默认关闭。

社区目录 deepseek-harness-plugin.com 是独立站点,与 DeepSeek / 幻方没有官方从属关系。它把扩展按分类收录,其中「界面增强」下有一个插件:modsearch。名字看起来像皮肤,实际做的是把搜索接到 dsh 已有的 Web 接缝上,并保留 Web UI 的引用卡片。

本文按该目录详情页、GitHub 仓库 README / INSTALL.md / 宿主接入文档 / CLI 手册 / 输出契约 / 安全说明,以及 DeepSeek Harness 官方仓库核对后整理:它是什么、装完能做什么、命令怎么写、结果长什么样。

这是什么

modsearch 是由 liustackpackage.json 作者署名为 Leon Liu)维护的联网搜索插件,npm 包名 @liustack/modsearch,许可证 MIT,主要语言 TypeScript。写作时仓库 package.json 版本为 5.4.2(2026-08-17),要求 Node.js >= 22.13。社区目录把它分在「界面增强」,收录日期 2026-08-15;GitHub 仓库在 2026-08-17 显示 113 star(目录页快照为 100,星标以仓库页面为准)。

目录页的一句话是:DeepSeek Harness 的联网搜索桥接,让没有原生联网能力的模型也能问网页或 X,拿到结构化答案。仓库 README 中英对照同一件事:搜索、抓取、引用,输出机器可读的 JSON 证据。

在 dsh 里,它不是一份靠提示词触发的 Skill。宿主接入文档写得很明确:这个包本身是 dsh bundle,以原生插件接入。bundle 做三件事:把 modsearch 引擎链注册为 web_search 的 provider,并把接缝指过来(searchProvider: modsearch);另外注册两个 dsh 没有接缝的工具——搜 X 的 x_search,以及带焦点读单页的 read_page。模型继续用原来的 web_search schema,Web UI 的引用卡片也保留。

同一套引擎也以 Agent Skill 形式出现在 Claude Code、Codex、Pi、OpenCode 上,配置都写在 ~/.modsearch/config.json。本文以 dsh 为主。

核心功能

dsh 本就有一条 Web 能力接缝:ctx.web 上的搜索与抓取,再由 dsh-tool-web 暴露成模型可调用的 web_search / web_fetch。modsearch 不另起一个竞争工具,而是注册 id 为 modsearch 的 search provider。cordis.patch.ymlweb 这一层的 searchProvider 从默认的 deepseek-official 改成 modsearch

效果是:只要本机配好了下面任一搜索引擎,web_search 就可以在没有 DeepSeek 搜索 key 的情况下跑起来;引用卡片仍走宿主原来的展示。想切回去,在更后面的 profile patch 里把 searchProvider 钉回其他 provider 即可。

插件启动 CLI 子进程时,用的是包内 dist/main.js,不查 PATH、不走 npx,插件和引擎版本锁在一起。dsh 跑在 Electron 桌面宿主里时,会显式设置 ELECTRON_RUN_AS_NODE=1,避免把 CLI 路径重新交给桌面应用。

2. x_searchread_page

网页接缝覆盖不到的两块,插件做成独立工具,schema 随每次请求发给模型,不靠关键词启发式。

  • x_search:查询 X(Twitter)上的帖子、线程、账号或讨论。Grok Build 已安装并登录时,路由给它;否则用网页引擎顶替,并在输出里标成 degraded,不会无声假装搜过 X。
  • read_page:读一个 http(s) URL,返回摘要、提取正文、外链和不确定项,可用 query 指定阅读焦点。宿主接入文档说明:dsh 自带的 web_fetch 默认关闭,因为它把 SSRF 防护推给别人;modsearch 的抓取默认拦截私网目标,且这个工具不暴露绕开开关。

3. 多引擎,自动故障转移

仓库 README 列出六条通道,配好其中一个就能用。key 存在 ~/.modsearch/config.json(权限 0600,展示时打码),也可以走环境变量 TAVILY_API_KEYEXA_API_KEYFIRECRAWL_API_KEY

引擎 能做什么 仓库写明的免费条件 怎么开
Antigravity CLI(agy 网页搜索 + 单页抓取 免费,浏览器登录 安装 agy 并登录
Tavily 网页搜索 每月 1,000 credits,文档写注册不绑卡 modsearch config set tavily.apiKey <key>
Exa 网页搜索 每月约 1,400 次($10 循环额度),文档写注册不绑卡 modsearch config set exa.apiKey <key>
Firecrawl 网页搜索 + 单页抓取 每月 1,000 credits;文档写搜索甚至可以无 key modsearch config set firecrawl.apiKey <key>
Grok Build X(Twitter)搜索 随 SuperGrok 或 X Premium 安装 grok 并登录
local 单页抓取 内置 无需配置

配了多个引擎就按优先级自动切换:一个通道失败或额度耗尽时,下一个接手。额度冷却故障转移默认开,modsearch config set cooldown off 可关。兼容 Tavily / Exa / Firecrawl 的第三方或自建端点,可以用 modsearch config set tavily.baseURL <url> 这类命令改地址。

local 抓取器默认拒绝私网和云 metadata 地址,并对每次 DNS 解析做 IP 钉扎,避免重绑定。VPN 把公网主机映射进保留地址段时,可用 --allow-private-networkmodsearch config set allowPrivateNetwork true 打开,文档明确说这是给本地抓取器放行,不是把内网主机名交给云端服务。

4. 结构化 JSON,而不是一段无法核验的散文

CLI 每次向 stdout 打一个信封。搜索模式的外形来自官方输出契约(文档里的示例):

{
  "mode": "search",
  "query": "current Node.js LTS",
  "url": null,
  "results": [
    {
      "source": "web",
      "requestedSource": "web",
      "engine": "antigravity-cli",
      "status": "ok",
      "summary": "The current Node.js LTS is v24.19.0 (Krypton), released 2026-08-03.",
      "items": [
        {
          "title": "Node.js v24.19.0 release",
          "url": "https://nodejs.org/en/blog/release/v24.19.0",
          "snippet": "Krypton is the active LTS line.",
          "published_at": "2026-08-03"
        }
      ],
      "uncertainty": [],
      "warnings": [],
      "attempts": []
    }
  ]
}

几个字段要分开读:

  • summary + items:摘要和带来源 URL 的条目,items 顺序表示相关度,没有数值分(文档说模型很容易把分数编圆,v2 已删掉)
  • uncertainty:引擎对事实没把握的地方(冲突来源、可能过时的数字、页面太薄)
  • warnings:答案是怎么来的(回退、X 被网页顶替、重定向)
  • statusok / degraded / unavailable。X 不可达时,网页顶替必须标 degraded,不能当成 X 覆盖

抓取模式(-u)把 items 换成 content(正文)和最多 20 条 linksagy 给出的是 markdown 正文;local 引擎不跑 JavaScript,也不做综述。

安装与启用

社区目录给出的命令

插件详情页上的安装命令原文是:

dsh plugin add github:liustack/modsearch

需要可复现安装时,目录页要求固定 commit 哈希:

dsh plugin add github:liustack/modsearch#<commit>

目录页同时提示:插件以当前 dsh 进程的权限运行,安装时可能执行代码;安装前应检查源代码仓库和许可证。

仓库针对 dsh 的版本钉死写法

docs/harness-setup.md 给 dsh 用户的命令是另一条。写作时钉在 5.4.2:

npx -y @deepseek-ai/dsh plugin --profile web add @liustack/modsearch@5.4.2

仓库刻意不用 @latest:pnpm 11 默认开启 minimumReleaseAge(24 小时),dist-tag 只在过了冷静期的版本里解析,@latest 可能静默装到一天前的旧版。点名版本号是明确指定。更新也用 add 而不是 updateupdate 只在已记录的 semver 请求内移动,还会再次经过发布时长过滤。

当前版本可用下面命令查询,再把命令里的版本号换成输出值:

npm view @liustack/modsearch version

装完重启 dsh,确认实际装到了什么:

npx -y @deepseek-ai/dsh plugin --profile web list

若出现 declares no dsh.bundle,仓库的判断是发布冷静期装到了旧包,按宿主接入文档的「保持更新」一节处理,不要改去拷贝 Skill 目录。

web 只是文档里的示例 profile。实际 profile 名以本机为准,把 --profile 换成自己的即可。

先准备一个搜索引擎

插件能挂上工具,但真正搜网页的是引擎。默认通道 Antigravity CLI 需要本人在浏览器完成登录,这是仓库说的「唯一需要你亲手做的一步」:

curl -fsSL https://antigravity.google/cli/install.sh | bash
agy

在浏览器完成登录后退出。不想装 agy,就按上一节表格注册 Tavily、Exa 或 Firecrawl 的免费 key,再 modsearch config set ...。只需要读页面时,内置 local 抓取器已经可用,不必配搜索引擎。要搜 X,还得另装并登录 Grok Build。

无图形界面、SSH 无桌面的环境,文档建议不要走 agy 的浏览器登录,改用 API key。

体检

npx @liustack/modsearch doctor

它不花额度、不发网络请求。健康机器上(agy 已登录)报告大致长这样(摘自 INSTALL.md,已精简):

Node
  version: 22.13.0
  status:  OK

search (search the web)
  resolved: antigravity-cli
  - antigravity-cli   READY    binary "agy" found and runnable

fetch (fetch a page)
  resolved: local
  - local             READY    built in, needs nothing installed

social (search X)
  resolved: (none available)

Node status: TOO OLD 就停下来升级。search resolved: (none available) 说明还没配搜索引擎。social(none available) 只表示 Grok Build 没装,不影响网页搜索。加 --json 可拿到机器可读报告。

端到端试一次(会消耗一次搜索额度):

modsearch -q "current Node.js LTS version"

预期 stdout 是 JSON:results 数组里第一条带 engine 和带 urlitems。超时可把 --timeout 提到 300000;文档说 agy 一次通常 10–30 秒。

典型用法

装进 dsh 之后,正常对话即可:问需要查证的问题,或贴一个 URL。下面几条都来自仓库文档和目录页,不是另行编造的案例。

1. 直接驱动 CLI

本机已有 Node 时,也可以不经过对话,自己跑:

modsearch -q "current Node.js LTS version"
modsearch -u "https://nodejs.org/en/about"
modsearch -q "reactions on X" --source x
modsearch -q "TypeScript 5.9 release notes" -o search.json --max-results 6

-u 可以再加 -q,把提取焦点传给引擎。--source 可以是 webxweb,x-e 钉死某个引擎时,失败就报错,不再换通道。

2. 在 dsh 里问需要联网的问题

选 DeepSeek-V4-Flash 这类自身不能联网、或联网偏弱的条目,直接问时事或版本号。模型调用宿主原来的 web_search,后端已经是 modsearch 引擎链。目录页把这个变化概括成:没有原生联网能力的模型也能问网页,拿到结构化答案。

3. 贴一个链接,读这一页

把文档、changelog、博客 URL 丢进对话,需要时带一句关注点(例如「速率限制是多少」)。模型走 read_page,返回摘要、正文提取和外链,而不是整页塞进上下文。

宿主接入文档在讲 Codex 时给过一笔对照(这是仓库自己的实测,不是第三方评测):内置搜索把整页推进上下文,一次搜索密集的回答大约 30,000 token;结构化证据大约几百 token。dsh 上的 read_page 走的是同一套输出契约。

4. 仓库 README 里的实测记录

这些是 README 标明的原样记录,在 Codex 桌面 App 里驱动自身不能联网的 DeepSeek-V4-Flash,用来说明粒度,不是评测榜:

  • 给出一篇博客链接,问文章写了什么:约 25 秒后返回全文结构化摘要,过程中没有打开浏览器
  • 不指定目标,只问「今天有什么有趣的 AI 新闻」:约 36 秒后返回六条带来源的结果,结尾说明哪些细节来自检索聚合、值得再核对——这条提醒来自 uncertainty 字段

5. 同一套引擎用在其他宿主

Skill 安装流程(拷贝 skills/modsearch,或 npx -y skills add liustack/modsearch)只适用于 Claude Code / Codex / Pi / OpenCode,不要在 dsh 上走那条路。在 Codex 里如果已经打开官方 web_search = "live",文档要求先在 ~/.codex/config.toml 里关掉它,否则模型会先伸手够内置搜索,Skill 轮不上。

适用场景与注意事项

比较适合:

  • 在 dsh 里用没有原生联网、或官方搜索覆盖不到指定页面 / X 的模型做编码和调研
  • 希望答案带来源 URL 和不确定项,而不是一段无法核验的综述
  • 已经能登录 agy,或手上有 Tavily / Exa / Firecrawl 的免费额度,不想再单独申请 DeepSeek 搜索 key
  • 需要偶尔搜 X,并且本机已经有 SuperGrok 或 X Premium 对应的 Grok Build

使用前注意下面几条,均来自目录页或仓库文档:

  1. 权限与许可证。 插件以当前 dsh 进程权限运行,安装时可能执行代码。安装前检查 源码 和 MIT 许可证。社区目录不是官方应用商店。
  2. dsh 仍是开发者预览。 官方 README 写明会有破坏性变更。modsearch 自称接触面很小(一次 provider 注册、两次原始工具注册),接口挪了会在宿主日志里报错,而不是静默失效。
  3. 搜索结果和抓取正文按不可信输入处理。 页面里可以写给模型看的指令。安全文档要求:只分析你愿意打开的 URL;提示词会要求引擎把页面当数据而不是指令,但这只是缓解,不是保证。URL 不受你控制时,在沙箱工作目录里跑。
  4. SSRF 与私网。 local 抓取器拒绝私网、保留地址和云 metadata,并钉扎 DNS 解析后的 IP。不要用 --allow-private-network 去打真正的内网地址。read_page 工具不暴露这个开关。
  5. 本机运行时。 需要 Node 22.13+。macOS / Linux 在 CI 的 Node 22 和 24 上跑全量测试;Windows 跑同一套 typecheck / 测试 / 构建,但 agygrok 只在 PATH 上有原生可执行文件时可用,npm 风格的 .cmd 垫片不可用。
  6. 不要用 @latest 更新。 查出当前版本号再点名 add。Skill 安装流程不要用在 dsh 上。
  7. 仓库不接受 Pull Request。 作者说明是单人审阅全部代码。反馈走 Issues;MIT 下可以自行 fork。
  8. 上游额度自负。 Antigravity CLI、Tavily、Exa、Firecrawl、Grok Build 各有条款和配额,遵守这些约束由使用者负责。README 里的「完全免费」指默认 agy 通道和三家备用引擎的月度免费额度,并不覆盖 Grok Build 所需的订阅。
  9. agy 的权限开关。 安全文档写明:ModSearch 调用 agy 时带了 --dangerously-skip-permissions,因为部分环境里 prompt 模式会失败;提示词把 agent 限制在搜索和抓取,但仍应视为本机额外权限。

小结

modsearch 要解决的问题很具体:dsh 背后的模型常常不能联网,或官方搜索覆盖不到指定页面和 X。它以原生插件接入,把 web_search 接到可故障转移的引擎链上,并补上 x_searchread_page;返回的是带来源、不确定项和路由痕迹的 JSON,而不是一段无法核验的描述。默认可以走免费的 Antigravity CLI,配置集中在 ~/.modsearch/config.json,和其他宿主共用。

目录页与仓库:

  • 社区目录:https://deepseek-harness-plugin.com/zh-CN/plugins/modsearch/
  • GitHub:https://github.com/liustack/modsearch
  • 安装说明:https://github.com/liustack/modsearch/blob/main/INSTALL.md
  • 宿主接入:https://github.com/liustack/modsearch/blob/main/docs/harness-setup.md
  • CLI 手册:https://github.com/liustack/modsearch/blob/main/skills/modsearch/references/cli.md
  • 输出契约:https://github.com/liustack/modsearch/blob/main/skills/modsearch/references/output-schema.md
  • 安全说明:https://github.com/liustack/modsearch/blob/main/docs/security.md
  • DeepSeek Harness:https://github.com/deepseek-ai/deepseek-harness
羽毛球分组比赛记分
小程序二维码

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

小夜