前言¶
DeepSeek Harness(DSH)把联网能力拆成 web_search 与 web_fetch 两类原生工具,由 ctx.web 服务挂载具体 provider。默认装配里往往依赖云端搜索后端;若你希望搜索与抓取都跑在自己可控的基础设施上,需要单独接 provider,并处理 Cordis 装配、鉴权与超时等行为与原生工具对齐的问题。
dsh-surfing-plugin 走另一条路:向 DSH 注册两个自托管 provider——搜索走 SearXNG,抓取走 Crawl4AI。原生工具名、参数、渲染、超时、取消与结果上限均保持不变,换的是后端实现。
这是什么¶
dsh-surfing-plugin 由维护者 cyijun 发布,归类为联网工具。它在 DSH 的 ctx.web 层注册 surfing-searxng(对应 web_search)与 surfing-crawl4ai(对应 web_fetch),分别对接 SearXNG 的 /search 与 Crawl4AI 的 /crawl。插件随附的 cordis.patch.yml 会挂载插件、选中上述两个 provider,并增加一个仅 fetch 的原生工具 consumer,以便在 headless 与 Web UI 两种 DSH 装配下都能正确分工:web_search 由装配或 Agent Preset 决定挂载方,而 fetch 侧由该 consumer 统一消费。
架构与数据流¶
flowchart LR
A[Native DSH web_search] --> B[surfing-searxng provider]
B --> C[SearXNG /search]
D[Native DSH web_fetch] --> E[surfing-crawl4ai provider]
E --> F[Crawl4AI /crawl]
SearXNG provider 以 format=json 向 POST /search 发送表单请求,保留绝对 HTTP(S) 结果 URL、按 URL 去重,并把 title、content、publishedDate 映射为 DSH sources;非空的 SearXNG answers 会作为结果内容返回。
Crawl4AI provider 向 POST /crawl 发送最小体 { "urls": [url] };模型输入不能附带浏览器或爬虫配置。仅接受 HTTP(S) 目标;目标页非 2xx 状态码仍可作为成功的 DSH fetch 结果返回,而 Crawl4AI API 层面的失败会转成结构化的 WebError。
环境与依赖¶
运行前需满足:
- Node.js
^22.19.0或>=24.0.0 - DeepSeek Harness
>=0.1.0-rc.6 <0.2.0 - 可访问的 SearXNG 与 Crawl4AI 服务
- SearXNG 配置中
search.formats已启用 JSON
安装与启用¶
端点可填服务根地址,也可填完整的 /search 与 /crawl URL。先导出环境变量:
export SEARXNG_URL=http://127.0.0.1:8080
export CRAWL4AI_URL=http://127.0.0.1:11235
# 当前 Crawl4AI 发行版默认启用 Bearer 鉴权
export CRAWL4AI_API_TOKEN=replace-with-your-token
本地 checkout 安装到 web profile:
dsh plugin --profile web add .
dsh --profile web --dump-config
dsh --profile web
npm 发布后可用包名安装:
dsh plugin --profile web add dsh-surfing-plugin
移除:
dsh plugin --profile web remove dsh-surfing-plugin
从 GitHub 按提交固定版本时,README 给出的命令为:
dsh plugin --profile web add github:cyijun/surfing-plugin#COMMIT_SHA
若使用 pnpm 10 及以上,Git 依赖首次安装可能因 build-script 审批被拦截;将提示中的包名写入 profile 的 pnpm-workspace.yaml 后重试:
allowBuilds:
dsh-surfing-plugin: true
npm 包与 pnpm pack 产物已包含 lib/,通常不需要上述审批。
配置¶
显式配置优先于环境变量。可在 $DSH_HOME/profiles/web/cordis.patch.yml 中覆盖本插件对应行:
- id: surfing-plugin
config:
searxng:
url: https://search.example.com
apiKeyEnv: MY_SEARXNG_KEY
authHeader: X-API-Key
authScheme: ''
language: en
categories: general,news
safeSearch: 1
timeRange: month
crawl4ai:
url: https://crawl.example.com
apiKeyEnv: CRAWL4AI_API_TOKEN
authHeader: Authorization
authScheme: Bearer
markdownMode: raw
maxContentChars: 100000
常用字段与环境变量对应关系如下(节选):
| 字段 | 环境变量或默认 | 含义 |
|---|---|---|
searxng.url |
SEARXNG_URL |
服务根或 /search 端点 |
searxng.apiKeyEnv |
SEARXNG_API_KEY |
可选密钥所在环境变量 |
searxng.language |
服务端默认 | SearXNG language 参数 |
searxng.categories |
服务端默认 | 逗号分隔的 categories |
searxng.safeSearch |
服务端默认 | 0、1 或 2 |
searxng.timeRange |
无 | day、month 或 year |
crawl4ai.url |
CRAWL4AI_URL |
服务根或 /crawl 端点 |
crawl4ai.apiKeyEnv |
CRAWL4AI_API_TOKEN |
可选密钥所在环境变量 |
crawl4ai.markdownMode |
raw |
优先 raw、fit 或 citations markdown |
crawl4ai.maxContentChars |
100000 |
返回给 DSH 前的内容上限 |
字面量 apiKey 优先于 apiKeyEnv 指向的环境变量;无可用密钥时不发送鉴权头。fit 与 citations 模式在首选字段为空时会回退到 raw markdown;仅当不存在 markdown 表示时才返回 HTML。
典型用法¶
完成安装并启动 dsh --profile web 后,Agent 侧仍调用原生 web_search 与 web_fetch;无需改工具名或参数。搜索请求经 surfing-searxng 落到自托管 SearXNG;抓取请求经 surfing-crawl4ai 落到 Crawl4AI。你在对话里提出的查询与自然语言 URL 意图,会按 DSH 原有语义流转,只是后端不再依赖默认云端搜索 provider。
开发或自检插件本身时,仓库内约定:
corepack pnpm install
corepack pnpm run check
corepack pnpm pack
适用场景与注意¶
适合需要在 DSH 中统一使用自托管搜索与抓取、且已部署或可部署 SearXNG 与 Crawl4AI 的开发者。插件以当前 dsh 进程权限运行;安装前应阅读源码与 MIT 许可证,并自行评估后端服务的网络暴露面。
安全方面,README 建议:优先用 apiKeyEnv,勿将凭据提交到版本库;非回环地址使用 HTTPS;Crawl4AI 负责浏览器隔离、目标网络访问与 SSRF 策略,对外暴露前应限制其网络与鉴权;后端重定向会被拒绝,避免凭据被转发到其他端点。
DSH 生态奉行「一切皆插件」;SkillHub 等社区目录为独立站点,与 DeepSeek / 幻方无官方从属关系。本插件在 GitHub 上约 13 stars,属社区联网工具类条目。
链接¶
- SkillHub 目录页:https://www.skillhub.cn/plugins/cyijun/dsh-surfing-plugin
- GitHub 仓库:https://github.com/cyijun/dsh-surfing-plugin