前言¶
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 说明)。