DeepSeek Harness Hub
← 返回列表

JanisKroja/dsh-web-search-crw

DeepSeek Harnessspec-screened在 GitHub 查看 ↗
未验证

为 DeepSeek Harnessdsh提供的自托管网页搜索:

尚未跑自动兼容性验证,可查看页面内的依赖与入口分析。 · 最近上游提交 2026/9/15 · 已提供中文文档

为 DeepSeek Harness (dsh) 提供自托管网页搜索:一个 ctx.web 提供程序插件,可将 web_search 路由到你自己的 CRW/Firecrawl 兼容服务器——无需第三方 API、无需密钥、每次搜索不消耗 LLM token。自带后端:CRW(通过 Camoufox 使用 Google)或任何 POST /v1/search 实现。

综合分
29.9
GitHub 分
29.9
用户评分
★ Stars
0
周下载量
安装插件(需先安装 dsh CLI 引擎:npm install -g @deepseek-ai/dsh)
dsh plugin --profile web add JanisKroja/dsh-web-search-crw
该插件未发布到 npm,走 GitHub 源安装(pnpm 若拦截 prepare 脚本,按其提示在 pnpm-workspace.yaml 的 allowBuilds 中放行后重跑)
数据截至 2026/9/16(元数据每日更新 · 实装验证按队列轮转,单条结论的验证时间见上方)
依赖的 DSH / Cordis 模块
@deepseek-ai/schemastery@deepseek-ai/cordis@deepseek-ai/dsh-web
用户评分
还没有人投票,来当第一个
订阅周报,不错过优质插件更新
每周一封 · 高评分插件 + 新用户活动

README

dsh-web-search-crw

为 DeepSeek Harness(dsh)提供的自托管网页搜索:
一个用于 harness web 接缝(ctx.web)的 WebSearchProvider 插件,它将面向模型的 web_search 工具指向你自己的
CRW 兼容
(Firecrawl 兼容)服务器,而不是托管的搜索 API。单一软件包——没有配套插件,没有 harness 分支,没有构建步骤。它是一个客户端:需要运行中的后端,参见
要求。

它通过官方 provider 约定——inject: ["web"] +
ctx.settings.installSection + ctx.web.registerSearchProvider——将一个 WebSearchProvider(id 为 crw)注册到 harness web 接缝
(ctx.web)中,其结构与自带的 @deepseek-ai/dsh-web-search-deepseek 插件一致。
没有修改任何自带的 harness 代码;选择完全通过接缝文档化的 searchProvider 配置进行。

它调用什么

POST {baseURL}/v1/search   {"query": "...", "limit": N}

并将 Firecrawl 形状的响应——{success, data: {results, answer?}},
其中 results 是扁平数组或分组的 {web, news, images} 对象——规范化为
接缝的 sources[](snippet || description、publishedDate → publishedAt、
data.answer → content)。传输失败映射为 WEB_PROVIDER_ERROR(带有
端点恢复提示),调用方取消映射为 WEB_ABORTED。

要求

你需要一个运行中的 CRW/Firecrawl 兼容搜索服务器——此插件本身不附带
任何搜索后端;它是一个客户端。 具体来说,它要求一个实现了 POST /v1/search 且符合 Firecrawl v1 搜索契约的
服务器(关于所接受的精确请求/响应形状,参见 它调用什么)。

推荐的后端:

- CRW——此插件所针对构建的参考
后端。一个 Rust 编写的、Firecrawl 兼容的
搜索/抓取/爬取服务器,其 /v1/search 通过
camofox-browser 驱动 Google,后者是
围绕 Camoufox
反检测 Firefox 分支的 REST 封装。快速开始即该仓库的 compose 栈:
docker compose up -d(将服务器发布到 localhost:3000)。
- 任何 Firecrawl 兼容的搜索端点
实现——自托管或托管均可。请查阅
Firecrawl 搜索 API 参考;
注意托管版 Firecrawl 还需要一个真实的 API 密钥(在下方设置 apiKey 或
CRW_SEARCH_API_KEY)。

其他要求:

- dsh web 配置文件,Node ≥ 22.19(与 dsh 本身相同的下限)
- 当服务器在未配置密钥的情况下运行时无需 API 密钥(本地 compose 栈的默认
情况)。一旦服务器配置了 API 密钥,请将
apiKey(或 CRW_SEARCH_API_KEY)设置为其中之一——插件随后会发送
Authorization: Bearer 。

安装

从此仓库安装
npm run install:dsh      # = bash scripts/install-to-dsh.sh

该脚本会将包复制到 $DSH_HOME/profiles/node_modules/dsh-web-search-crw
—— 即 harness 的共享模块解析锚点(参见 @deepseek-ai/dsh-app-boot
profile 文档)。必须使用复制,而非符号链接:Node 会通过符号链接的 realpath 进行解析,
因此被链接的插件会从本仓库向上查找来解析其 @deepseek-ai/ 裸导入,
而不是从 harness 的提升闭包中解析。

然后在你的 profile 补丁($DSH_HOME/profiles/web/cordis.patch.yml)中注册该 provider:

- id: web
name: '@deepseek-ai/dsh-web'
config:
searchProvider: crw
fetchProvider: http

- insert:
- id: web-search-crw
name: dsh-web-search-crw
config:
baseURL: http://localhost:3000
limit: 5
timeoutMs: 60000

web 行补丁会替换整个配置,因此必须重新声明 fetchProvider。
web profile 会热重载此文件(patchReload: live),因此配置变更
无需重启 —— 但对此插件 lib/index.js 的变更则需要重启;参见
重载与重启。

要切回内置 provider,请设置 searchProvider: deepseek-official。

配置

设置命名空间 web-search-crw(也可在
设置 → 插件 → 插件配置 → Web 搜索 (CRW) 下实时编辑):

| 键 | 默认值 | 含义 |
|---|---|---|
| baseURL | http://localhost:3000 | CRW 基础地址;会追加 /v1/search。环境变量回退:CRW_SEARCH_BASE_URL |
| apiKey | — | 可选的 bearer key。环境变量回退:CRW_SEARCH_API_KEY |
| limit | 5 | 当工具未传入 maxResults 时的结果数量回退值 |
| timeoutMs | 60000 | 每次搜索的截止时间。一次 Camofox Google SERP 请求冷启动约需 45 秒,因此旧的 30000 默认值会中止真实搜索 |
| resolveRedirects | true | 将 Google 的点击重定向包装(/url?q=、/goto?url=、/aclk、/imgurl)展开为真实目标地址 |
| resolveTimeoutMs | 4000 | 每个包装的截止时间;无法解析的行会保留其原始 URL,而不是被丢弃 |

timeoutMs 嵌套在宿主工具层自身的预算
tool-web.searchTimeoutMs(默认 30000)之内,后者会先约束同一个
web_search 调用。请同时提高两者 —— 在 30 秒宿主截止时间之后的 60 秒 provider 截止时间
仍会在 30 秒时中止。

resolveRedirects 存在的原因:Google 的 SERP 锚点指向
google.com/goto?url=,而非目标地址,且该 token
base64 解码后是不透明的 protobuf 字节 —— 目标 URL 只存在于
重定向的 Location 中。harness 的 fetch 客户端按设计拒绝跨源重定向
(一种 SSRF 防护),因此未展开的链接意味着可引用来源与每个结果额外一次解析往返之间的差别。
仅当 CRW 本身开始返回干净 URL 时才将其关闭。

开发

验证点击重定向展开(stubbed fetch,无网络 —— 断言该
/url?q= 和 /goto?url= 路径、Location 与 meta-refresh 恢复
路由、第二跳拒绝、重复项折叠,以及超时回退):

node scripts/verify-unwrap.mjs          # 离线断言
node scripts/verify-unwrap.mjs --live   # 针对真实 CRW 服务器;若泄漏任何包装 URL 则以 1 退出

两种安装模式:

npm run install:dsh            # 复制 — 部署安全(默认)
npm run install:dsh -- --link  # 符号链接 — 本地开发,实时编辑

复制模式将包物理放置在
$DSH_HOME/profiles/node_modules/dsh-web-search-crw 下,这是 harness 的共享
模块解析锚点,因此其裸 @deepseek-ai/ 导入会通过 Node 的父级遍历解析到
harness 提升后的闭包。

--link 模式将该锚点条目替换为指向本仓库的符号链接。
由于 Node 通过符号链接的 realpath 进行解析,一个天真的符号链接会从本仓库解析
插件的裸宿主导入——因此该脚本还会将
@deepseek-ai/dsh-web 和 @deepseek-ai/schemastery 链接到这里的 node_modules/ 中,
指向正在运行的 harness 所加载的相同 realpath(Node 按 realpath 去重,保留类/服务
身份——切勿 npm install 你自己的宿主包副本;一个遮蔽的第二副本会破坏 Cordis
服务身份)。随时可用普通复制模式切回。如果本仓库移动或 dsh 被重新安装,
请重新运行该脚本以修复链接。

实际加载的那份副本(如果编辑似乎消失了,请读这里)

如果 profile 的 package.json 将此插件列为依赖项——通常是
"dsh-web-search-crw": "file:/path/to/this/repo",这正是仓库最初进入
profile 的方式——包管理器还会将其实体化到
$DSH_HOME/profiles//node_modules/dsh-web-search-crw/,作为一个由硬链接文件组成的真实
目录,而非指向仓库的符号链接。

Node 会先于锚点解析该 profile 本地副本,因此它会遮蔽
$DSH_HOME/profiles/node_modules/dsh-web-search-crw。此时编辑本仓库——或
仅安装到锚点——都不会改变 harness 所能看到的任何内容,而重启会重新加载同一份陈旧的
副本。scripts/install-to-dsh.sh 会将 lib/ 同步到它找到的每个 profile 本地副本中,并在
被解析的是锚点时告知你;在 profile 目录内执行 pnpm install --force 是包管理器
原生的等效做法(它还会拾取 package.json,并且需要 registry
可访问以获取 profile 的其他依赖项)。

你可以确认加载的是哪个文件:

grep -c classifyRedirectWrapper ~/.dsh/profiles/web/node_modules/dsh-web-search-crw/lib/index.js

重载 vs 重启

web profile 上的 patchReload: live 会在
运行中的进程内重新应用 cordis.patch.yml 配置。cordis 中没有任何东西会破坏插件的模块缓存,因此
lib/index.js 在启动时只被导入一次:

| 变更内容 | 生效时机 |
|---|---|
| cordis.patch.yml 行,或此插件的配置(baseURL、limit、timeoutMs、resolveRedirects、resolveTimeoutMs) | 实时生效,无需重启 |
| lib/index.js(任何代码更改) | 重启 dsh web 后生效 |

许可证

MIT

上游仓库有新提交时邮件通知你(每天最多一封,无更新不打扰),随时一键退订。

💬 加入 DPharness 群聊

插件用法、部署报错、新插件第一时间同步——群里问,比一个人翻文档快。

点击加入 QQ 群
DPharness 群聊二维码,手机 QQ 扫码进群
扫码进群