前言¶
DeepSeek Harness(DSH)內置的 web_search 工具走 ctx.web 這條 seam。若你希望用 Tavily 做聯網檢索,常見做法是掛官方 tavily-mcp,再通過 dsh-mcp-client 接入。中轉域名、自定義 base URL,或只想讓內置 web_search 統一走一條 provider 時,MCP 路徑往往對不上:端點寫死在 https://api.tavily.com/...,工具也不經過 ctx.web,模型可能要在兩套工具之間選。
下面介紹社區插件 dsh-web-search-tavily-relay(維護者 hjnvv00v),它把搜索 provider 註冊進 ctx.web,Harness 自帶的 web_search 直接調用該實現,無需額外學新工具,中間也沒有 MCP 進程。
這是什麼¶
dsh-web-search-tavily-relay 是面向 DSH ctx.web 的 Tavily 兼容聯網搜索 provider。官方 Tavily API、鏡像 Tavily REST 形態的中轉,以及暴露 OpenAI 兼容接口的網關,都可以通過配置切換端點、憑證與線協議。插件當前版本 0.2.0,許可證 MIT,分類屬於社區目錄中的「聯網工具」。
與官方 Tavily MCP 的差異(README 中的設計動機)¶
README 明確對比了 seam 原生方案與 tavily-mcp:
- MCP 的 endpoint 固定爲
https://api.tavily.com/{search,extract,crawl,map,research,feedback},無法配置 base URL,自定義域名不可用。 - MCP 工具繞過
ctx.web,內置web_search仍使用 seam 已選的 provider,模型可能面對兩套並行工具集。
本插件走 seam 原生路徑:一個 provider、三種線協議、一個可配置 endpoint。
支持的線協議¶
通過 protocol 選擇請求形態(別名如 responses、chat、rest 等也可接受;baseURL 可以是 base,也可以是完整 URL):
protocol |
請求方式 | 適用場景 |
|---|---|---|
tavily(默認) |
POST {base}/search,Tavily 原生 body |
Tavily 官方,或 REST 形態一致的中轉 |
openai-responses |
POST {base}/responses,原生 web_search 工具 |
暴露 Responses API 的 OpenAI 兼容網關 |
openai-chat |
POST {base}/chat/completions,帶 web_search_options |
模型側搜索並引用的 Chat Completions 網關 |
檢索結果中的來源(sources)只從結構化證據讀取:Tavily 的 results[]、Responses 裏的 url_citation 與 web_search_call sources、Chat 裏的 annotations;若網關無 annotations,則回退到回答 markdown 中的鏈接。
配置要點¶
可在 Web 側欄 Plugins 下該插件頁面編輯,或寫入 profile 的 cordis.patch.yml。常用字段如下(默認值與含義以 README 爲準):
| 字段 | 默認 | 含義 |
|---|---|---|
providerId |
tavily |
註冊 id,須與 web 條目裏的 searchProvider 一致 |
protocol |
tavily |
tavily / openai-responses / openai-chat |
baseURL |
隨協議 | 中轉域名或完整 endpoint;空則 Tavily 用 https://api.tavily.com,OpenAI 協議用 https://api.openai.com/v1 |
apiKey |
省略 | 明文 key;更推薦 apiKeyEnv,避免密鑰進設置文件 |
apiKeyEnv |
TAVILY_API_KEY |
經 ctx.credentials 再解析啓動環境 |
authStyle |
auto |
auto / bearer / body / header / none |
searchDepth |
basic |
Tavily search_depth |
maxResults |
5 |
向 provider 請求的上限 |
includeAnswer |
"false" |
是否向 Tavily 要合成答案,作爲結果 content |
defaultParameters |
省略 | 與官方 MCP 的 DEFAULT_PARAMETERS 同類:JSON 對象,最後合併進請求體,可覆蓋也可新增 Tavily 參數字段(query 不可被配置覆蓋) |
timeoutMs |
30000 |
單次請求超時 |
defaultParameters 示例(profile YAML 中可直接寫對象;插件卡片也可能以 JSON 字符串寫入,解析結果相同):
- id: web-search-tavily
name: dsh-web-search-tavily-relay
config:
baseURL: https://relay.example
defaultParameters:
time_range: week
country: China
exact_match: true
認證:authStyle: auto 會發 Authorization: Bearer <key>,且在 tavily 協議下也在 body 裏帶 api_key,以適配不同中轉實現。密鑰解析順序爲:apiKey → ctx.credentials(apiKeyEnv)→ DSH 啓動環境;配置頁寫入的 key 走 credentials 域,不會落進 settings 文檔。無任何 key 時,對 https://api.tavily.com 的請求會走 Tavily 的無 key 模式。
包內自帶 cordis.patch.yml:安裝後會掛載 loader,並把 web 條目的 searchProvider 指向 tavily(與 provider 選擇機制綁定,需與插件一併生效)。ctx.web 在構造 seam 時讀取 searchProvider 一次;多個可用 provider 時不會自動猜測,未選中則無法工作——安裝本插件即完成 pin 的一部分。
安裝與啓用¶
官方安裝命令(web 爲 profile 名,桌面端可換成 desktop 等):
dsh plugin --profile web add github:hjnvv00v/dsh-web-search-tavily-relay
單獨執行 dsh plugin add 亦可;bundle 已含 patch。安裝後在 Web 側欄 Plugins 打開該插件頁,配置憑證;若使用中繼,再改 endpoint,然後重載 UI。
從本地包目錄安裝(非 git clone 場景下的 README 說明):
node install.mjs # 複製到 desktop profile 並接線 seam
node install.mjs --profile web # 或其他 profile
install.mjs 會把包裝進 <profile>/node_modules,寫入 dsh.profile.bundles 並記錄依賴;可重複執行,會備份所改文件;node install.mjs --uninstall 可撤銷。
運行環境要求:Node.js >= 22(見 package.json 的 engines)。
典型用法¶
- 按上文命令把插件加入目標 profile。
- 在插件頁或
cordis.patch.yml中設置apiKeyEnv對應的環境變量或 credentials,必要時設置baseURL與protocol。 - 重載 UI 後,對話裏 Harness 內置的
web_search即通過本 provider 出網檢索;無需再爲搜索單獨掛 MCP 工具。
若中轉只接受 Bearer 或只接受 body 裏的 key,將 authStyle 設爲 bearer、body 或 header 即可;OpenAI 兼容網關可改 protocol 爲 openai-responses 或 openai-chat,並按網關要求調整 model、responsesToolType、chatWebSearchOptions 等字段。
適用場景與注意¶
適合誰: 已在 DSH Web / 桌面 profile 上使用內置聯網 seam,希望 Tavily、Tavily 形態中轉,或 OpenAI 兼容搜索網關統一接到 web_search 的開發者。
注意:
- 插件以當前 DSH 進程的權限出網並持有你配置的 API key;安裝前請自行查看 GitHub 倉庫 源碼與 MIT 許可證,確認符合你的安全與合規要求。
- 社區插件目錄(如 SkillHub 條目)爲獨立生態站點,與 DeepSeek / 幻方無官方從屬關係;「一切皆插件」是 DSH 的產品理念,本文介紹的是社區維護的聯網工具類插件。
includeRawContent爲 true 時 Tavily 可能返回raw_content,但 seam 的 source 形態沒有整頁字段,僅能在缺少 snippet 時作補充;整頁抓取應使用web_fetch等其它能力(README 說明)。