前言¶
DeepSeek Harness(dsh)是 DeepSeek AI 開源的智能體框架,官方倉庫把它的架構概括成一句話:一切皆插件。網頁訪問也不例外。官方文檔把這項能力放在 ctx.web 這條可選縫上:一邊是 web_search,一邊是 web_fetch。模型仍然只提交查詢詞或 URL,真正去哪兒搜、去哪兒抓,由註冊進去的 Provider 決定。
隨 Harness 一起提供的搜索後端,是 DeepSeek、Exa、Perplexity 這類需要雲端 API 密鑰的實現;抓取則另有 HTTP Provider。本地已經跑着 SearXNG、又用 Crawl4AI 做頁面抽取的人,往往不想再爲智能體單獨買一路搜索接口。surfing-plugin 做的就是這件事:把原生工具接到自託管服務上,工具名稱、參數、超時、取消和結果截斷都還是 DSH 原來的那一套。
需要先說明來源。本文依據的是社區插件目錄頁與維護者倉庫,不是 DeepSeek / 幻方的官方應用商店。目錄站點獨立運營,和官方倉庫沒有從屬關係。寫作時倉庫規範名爲 cyijun/dsh-surfing-plugin(GitHub 顯示 12 星),舊地址 cyijun/surfing-plugin 會重定向過去;目錄頁安裝命令仍寫作 github:cyijun/surfing-plugin,下文以目錄頁原文爲準。
這是什麼¶
surfing-plugin 是由 cyijun 維護的 DeepSeek Harness 插件,npm 包名爲 dsh-surfing-plugin,當前 package.json 版本爲 0.1.0,許可證爲 MIT,主要語言是 TypeScript。社區目錄把它歸在「界面增強」分類下,簡介是「SearXNG 搜索與 Crawl4AI 抓取提供方」。從源碼看,它並不新增側邊欄或皮膚,而是向 ctx.web 註冊兩個 Provider:
- 搜索:
surfing-searxng,請求 SearXNG 的/search - 抓取:
surfing-crawl4ai,請求 Crawl4AI 的/crawl
插件依賴 @deepseek-ai/dsh-web,並聲明 inject = ['web']。也就是說,它掛在 DSH 已有的網頁訪問服務上,不另起一套工具名。官方 Web Access 文檔也寫明:換搜索後端不會改變模型提問查詢的方式,換抓取後端不會改變模型提交 URL 的方式。
它要解決的問題很具體:在已經能訪問 SearXNG 與 Crawl4AI 的前提下,讓 web_search / web_fetch 走這兩套自託管服務,而不是默認的雲端搜索 Provider。
核心功能¶
倉庫 README 和源碼對行爲寫得很明確,可以分成四塊。
1、SearXNG 搜索。 Provider 向 /search 發送表單編碼的 POST,並固定 format=json。只保留絕對 HTTP(S) 結果 URL,按 URL 去重,把 title、content、publishedDate 映射成 DSH 的 source 字段;如果 SearXNG 返回了非空的 answers,會拼進搜索結果的 content。maxResults 會在 Provider 和 DSH web 服務兩側都執行。
2、Crawl4AI 抓取。 Provider 只發送最小請求體 { "urls": [url] },不允許模型把瀏覽器或 crawler 配置注入進去。目標必須是 HTTP(S)。目標站點的非 2xx 狀態會作爲一次成功的抓取結果返回;Crawl4AI API 本身失敗、抓取失敗或無法表示的響應,會變成結構化的 WebError。markdown 優先模式默認是 raw,也可以選 fit 或 citations;後兩種在對應字段爲空時回退到 raw。沒有 markdown 但有 cleaned_html 或 html 時,返回 HTML。返回給 DSH 前有字符上限,默認 100000。
3、隨包發佈的 cordis.patch.yml。 它會做三件事:掛載本插件;把搜索、抓取 Provider 分別固定爲 surfing-searxng 和 surfing-crawl4ai;再插入一個只註冊原生 web_fetch 的 @deepseek-ai/dsh-tool-web 行。README 解釋了爲什麼要拆這一行:headless 繼續用宿主層的 web_search,Web UI 繼續用各 Agent Preset 裏的 web_search,避免重複註冊。已有的 DeepSeek 搜索 Provider 可以繼續掛着,但不會被選中。
4、配置覆蓋環境變量。 服務地址既可以寫服務根路徑,也可以寫成完整的 /search、/crawl。沒有密鑰時不發認證頭,適合本機無認證部署;有密鑰時優先用 apiKeyEnv,字面量 apiKey 會覆蓋環境變量。
安裝與啓用¶
目錄頁給出的安裝命令是:
dsh plugin add github:cyijun/surfing-plugin
插件以當前 dsh 進程的權限運行,安裝時可能執行代碼。安裝前應檢查源代碼倉庫和許可證。目錄頁也寫了:如需可復現安裝,請固定 commit 哈希。
維護者 README 建議裝進 web profile,並把 commit 寫死。對應寫法如下(把 COMMIT_SHA 換成實際哈希):
dsh plugin --profile web add github:cyijun/surfing-plugin#COMMIT_SHA
從 Git 安裝會走包裏的 prepare 腳本做構建。pnpm 10 及以上默認攔截 Git 依賴的構建腳本。第一次安裝被攔住時,把提示裏的確切包鍵寫進該 profile 的 pnpm-workspace.yaml,再重試:
allowBuilds:
dsh-surfing-plugin: true
環境要求以倉庫 README 和 package.json 爲準:
- Node.js
^22.19.0或>=24.0.0 - DeepSeek Harness
>=0.1.0-rc.6 <0.2.0 - 本機或內網能訪問的 SearXNG、Crawl4AI
- SearXNG 必須在
search.formats中啓用json;否則請求format=json會被拒絕。SearXNG 文檔同樣指出,很多公開實例默認關掉了 JSON 輸出
README 另外寫了本地 checkout 安裝:
dsh plugin --profile web add .
dsh --profile web --dump-config
dsh --profile web
卸載命令是 dsh plugin --profile web remove dsh-surfing-plugin。
關於 npm:README 寫的是「發佈到 npm 後」再用 dsh plugin --profile web add dsh-surfing-plugin,並提到首次發佈前要確認包名仍可註冊。本文寫作時未能從 npm 註冊表確認該包已經上架,因此當前安裝路徑以 GitHub 命令爲準,不要把 npm 包名當成已經可用的安裝入口。
配置與用法¶
先準備兩個後端地址。值可以是服務根,也可以是完整端點:
export SEARXNG_URL=http://127.0.0.1:8080
export CRAWL4AI_URL=http://127.0.0.1:11235
# Crawl4AI 當前版本默認啓用 Bearer token;無認證部署可以省略。
export CRAWL4AI_API_TOKEN=replace-with-your-token
需要覆蓋默認值時,在 $DSH_HOME/profiles/web/cordis.patch.yml 裏改本插件那一行。顯式配置優先於環境變量。倉庫給出的示例如下(中文 README 把語言寫成了 zh-CN):
- id: surfing-plugin
config:
searxng:
url: https://search.example.com
apiKeyEnv: MY_SEARXNG_KEY
authHeader: X-API-Key
authScheme: ''
language: zh-CN
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;服務根或/searchsearxng.apiKeyEnv:默認讀SEARXNG_API_KEYsearxng.language/categories/safeSearch/timeRange:傳給 SearXNG 的查詢參數;safeSearch只能是0、1、2,timeRange只能是day、month、yearcrawl4ai.url:環境變量CRAWL4AI_URL;服務根或/crawlcrawl4ai.apiKeyEnv:默認讀CRAWL4AI_API_TOKENcrawl4ai.markdownMode:raw、fit或citations,默認rawcrawl4ai.maxContentChars:默認100000
裝好並配好後端之後,智能體仍然調用原生的 web_search 和 web_fetch,不需要換工具名,也不需要在對話裏寫插件專用指令。可以用 dsh --profile web --dump-config 覈對 patch 是否已經把 searchProvider / fetchProvider 指到 surfing-searxng 和 surfing-crawl4ai。
適用場景與注意事項¶
比較適合這幾類用法:已經自建 SearXNG 和 Crawl4AI,希望 DSH 的網頁工具走同一套後端;希望搜索與抓取留在自己控制的網絡裏,而不是默認的雲端搜索 Provider;同時使用 headless 與 Web UI,需要 README 裏那種拆開的 web_fetch Consumer,以免重複註冊 web_search。
使用前有幾條邊界需要看清楚。
第一,這不是「裝上就能搜」的插件。兩個後端服務要先能訪問;SearXNG 還要打開 JSON 格式。公開 SearXNG 實例經常關掉 JSON,不適合直接拿來當 API。
第二,它不是通用爬蟲控制器。Crawl4AI 請求體被故意寫死成單個 URL,模型不能指定瀏覽器參數、抽取策略或併發。抓取策略、瀏覽器隔離、目標網段和 SSRF 策略都在 Crawl4AI 一側,公開部署前要按 Crawl4AI 自己的安全說明限制網絡和認證。
第三,認證與傳輸。倉庫建議優先用 apiKeyEnv,不要把密鑰寫進 Git;對非本機服務用 HTTPS;Provider 請求禁止重定向,避免認證頭被轉到另一個後端。沒有密鑰時不發認證頭。
第四,版本窗口比較窄。當前聲明的 DSH 範圍是 >=0.1.0-rc.6 <0.2.0。官方倉庫仍處於開發者預覽,README 寫明會有破壞兼容性的變更,升級 Harness 後應再覈對本插件是否仍匹配。
第五,也是目錄頁的安全提示:插件以當前 dsh 進程的權限運行,安裝時可能執行代碼。Git 安裝還會走 prepare 構建。安裝前應閱讀源碼和 MIT 許可證,並儘量固定 commit,避免後續推送靜默改變實際執行的代碼。
小結¶
surfing-plugin 把 DSH 原生的 web_search、web_fetch 接到自託管的 SearXNG 與 Crawl4AI 上,工具協議仍由 Harness 自己的 web 縫負責。目錄把它放在「界面增強」裏,實際能力是 Provider 替換。安裝命令以目錄頁爲準,配置以後端地址和密鑰環境變量爲主。
目錄頁:https://deepseek-harness-plugin.com/zh-CN/plugins/surfing-plugin/
GitHub(目錄收錄地址,會轉到現規範名):https://github.com/cyijun/surfing-plugin
GitHub 現規範倉庫:https://github.com/cyijun/dsh-surfing-plugin