DSH plugin 自定义联网能力:WebSearchRequest、WebFetchRequest 与错误分类

插件开发发布于 2026-10-17作者: DeepSeek Plugin 插件市场
DeepSeek HarnessDSH pluginWebSearchRequestWebFetchRequestWebErrorprovider
DSH plugin 的联网 seam 怎么自己写提供方:一个 ctx.web 横跨 search 与 fetch、maxResults 由消费方定并由 seam 强制执行、非 2xx 也是结果、提供方选择不依赖注册顺序。

DSH plugin 的联网 seam 把「搜索」与「抓取」放在同一个 ctx.web 上,但不是为了复用请求结构——两者连 schema 都不共享。 共享的是三件中间件式的东西:提供方选择策略的唯一所有者、一套中止与错误词汇、一个面向产品的配置界面。代价是服务上并行的 searchX/fetchX 方法对,官方明确说这是有意设计。

写提供方时只要记住两条硬规则:maxResults 由消费方定、由 seam 在返回时强制执行;非 2xx 是结果而不是错误。

DSH plugin 联网 seam 的分层:定义、提供方与唯一消费方

一句话结论:提供方注册的是能力而不是工具;工具名、schema、提示词与展示都集中在唯一的消费方。

  1. 服务定义:dsh-web 拥有 ctx.web 与提供方注册表。
  2. 提供方:搜索侧有 exa、perplexity、deepseek 等,抓取侧有 http 实现。
  3. 消费方:dsh-tool-web 独占 web_search 与 web_fetch 的 schema 与渲染。
  4. 换提供方不改调用方式:模型提交查询与请求 URL 的方式不变。
  5. 可选能力:不属于 agent loop 主干,词汇定义在 web 页而不是 core 页。

DSH plugin 的 WebSearchRequest:一条 query、一个上限

一句话结论:seam 请求只带一条 query;上限由消费方设、由 seam 在返回时截断。

ts
interface WebSearchRequest { query: string; maxResults?: number }
interface WebSearchResult { content?: string; sources: WebSearchSource[]; truncated: boolean }
  1. 扇出:消费方接受 queries 数组,拆成多个独立 seam 请求;单元素就是一次搜索。
  2. 上限来源:maxResults 是消费方配置(默认 8),透传给 seam。
  3. 强制执行:提供方返回超量时,seam 截断 sources 并置 truncated。
  4. content 可选:有的提供方返回生成式答案,有的只给来源;不要强求。
  5. 来源形状:url 必填,title、snippet、publishedAt 可选——强制适配器编造会让 seam 说谎。
  6. 展示兜底:消费方用 title ?? hostname(url) 渲染标题。

DSH plugin 的 WebFetchRequest:URL 一个字段,状态码是资源状态

一句话结论:请求故意只带 URL;非 2xx 仍返回结果,WebError 只留给无法安全获取的情况。

ts
interface WebFetchRequest { url: string }
interface WebFetchResult { url: string; statusCode: number; body: WebFetchBody; truncated: boolean }
  1. 为什么只有一个字段:超时与取消是执行参数,格式、提示词与抽取属于更高层,不属于安全抓取。
  2. 状态码语义:404 或 500 也会产出结果,正文按内容类型解码并有上限。
  3. 最终 URL:结果里的 url 是允许重定向之后的最终地址。
  4. 正文是闭合联合:html 或 text,消费方用 switch 穷尽处理,新增类型会编译失败直到处理完。
  5. 截断标记:truncated 说明提供方对正文设了上限。
  6. 安全边界:重定向与协议限制由抓取网络策略负责,别在提供方里自行放宽。

DSH plugin 的提供方可用性与选择:不看注册顺序

一句话结论:available() 只做本地检查;选择靠显式 id 或唯一可用,歧义直接报错。

  1. available() 的纪律:凭证是否存在、配置能否解析——禁止网络调用。
  2. 选择时机:执行时读取它来选择提供方,不是后台健康检查。
  3. 显式 id:searchProvider / fetchProvider 配置或对应环境变量。
  4. 唯一可用:恰好一个可用时自动选择。
  5. 歧义:多个可用却未配置 id → WEB_PROVIDER_AMBIGUOUS,不会挑最先注册的那个。
  6. 顺序无关:注册顺序、配置顺序、热重载顺序都不参与选择。

DSH plugin 的联网错误分类:什么时候才叫失败

一句话结论:拿不到安全可表示的资源才失败;能拿到状态码与正文,就返回结果。

  1. 选择失败:WEB_PROVIDER_AMBIGUOUS 一类,错误码与消息会指出缺失 id 或歧义候选。
  2. 抓取失败:网络不可达、重定向不被允许、正文无法安全表示。
  3. 搜索失败:提供方调用失败或响应无法解析。
  4. 不算失败:非 2xx、正文被截断、来源被截断——这些都是结果里的字段。
  5. 分支写法:先看 kind 与错误码,再决定重试、换提供方还是向用户说明。
  6. 验证:故意请求一个 404 页面,应拿到带 statusCode: 404 的结果而不是异常。

DSH plugin 排查注意事项

一句话结论:联网问题先分「选不到提供方」「请求被安全策略拦」「结果被截断」三类。

  1. 没有提供方 → 检查凭证与配置,available() 为 false 时不会被选中。
  2. 报歧义 → 显式配置提供方 id,别依赖自动选择。
  3. 正文缺一半 → 看 truncated,属上限行为不是失败。
  4. 来源少几条 → 到达 maxResults 上限,seam 主动截断。
  5. 抓到 500 却没重试 → 非 2xx 是结果,重试策略在你这一层。
  6. 修复状态如实:本文的两项操作共享中间件、请求/结果形状、可用性与选择规则均取自官方「Web 访问」页面;抓取网络策略与接口签名以该页及 Cordis API 为准。

来源:Web 访问、dsh-web 源码、dsh-tool-web。

常见问题

DSH plugin 的联网能力为什么要放在同一个 ctx.web 里,而不是两个服务?

DSH plugin 的搜索与抓取共用一层中间件:一个提供方选择策略的所有者、一套中止与错误词汇、一个面向产品的配置界面。代价是服务上并行的 searchX/fetchX 方法对,这是有意设计而不是遗漏。

DSH plugin 里,搜索返回的 sources 超过上限时,是提供方截断还是 seam 截断?

DSH plugin 的 maxResults 由消费方决定并通过 seam 传递,返回时由 seam 强制执行。提供方返回超量时,seam 截断 sources 并把 truncated 置为 true,提供方也可以在自己的 API 层提前限制以省成本。

DSH plugin 里,抓取到 404 或 500,算 WebError 吗?

不算,DSH plugin 把 HTTP 状态码视为被抓取资源状态的一部分:非 2xx 仍产出一个带状态码与有界正文的结果。WebError 只用于无法安全获取或表示资源的情况。

DSH plugin 里,同时注册了两个可用的搜索提供方,调用会怎么选?

DSH plugin 的选择从不依赖注册顺序:有显式提供方 id 就用 id,恰好只有一个可用时才自动选择;多个可用却未配置 id 会抛 WEB_PROVIDER_AMBIGUOUS,而不是挑最先注册的那个。

DSH plugin 里,提供方的 available() 里可以做联网健康检查吗?

不可以,DSH plugin 的 available() 必须是廉价的本地检查,例如凭证是否存在、配置能否解析,禁止发起网络调用。它是执行时选择提供方的输入,不是健康检查系统。

相关术语

WebSearchRequest(搜索请求)
WebSearchRequest 是 DSH plugin 联网 seam 的单次搜索请求,只携带一个 query 与可选的 maxResults 上限。消费方会把多查询扇出成多个独立请求。— https://deepseek-harness.github.io/deepseek-harness/reference/subsystems/web
WebFetchResult(抓取结果)
WebFetchResult 是一次抓取的结果,含重定向后的最终 URL、HTTP 状态码、按内容类型分类的正文与截断标记。非 2xx 响应同样是结果而不是错误。— https://deepseek-harness.github.io/deepseek-harness/reference/subsystems/web
WebError
WebError 是 DSH plugin 联网 seam 的结构化错误,只用于无法安全获取或表示资源的情况,并带可据以分支的错误码,例如提供方选择歧义。— https://deepseek-harness.github.io/deepseek-harness/reference/subsystems/web
WEB_PROVIDER_AMBIGUOUS
WEB_PROVIDER_AMBIGUOUS 是提供方选择失败的错误码:存在多个可用提供方却没有配置显式 id。它保证选择不会退化为「用最先注册的那个」。— https://deepseek-harness.github.io/deepseek-harness/reference/subsystems/web

来源