DSH plugin 工具 execute 契约:DeepSeek Harness 参数校验、只读定义与规范返回值

插件开发发布于 2026-10-07作者: DeepSeek Plugin 插件市场
DSH pluginDeepSeek Harness工具开发defineToolexecute
DSH plugin 的 defineTool 工具为什么容易踩坑?本文按官方工具编写参考,讲清 execute 的八条契约:参数已校验、只读定义、exec.token 与 args 不可变、只返回规范 JSON 值、抛异常即 isError、遵守 exec.signal。

DSH plugin 的工具不是「能跑就行」:官方工具编写参考为 execute 定下八条契约,从参数校验、只读定义到返回值与错误语义逐条约束,违反任何一条都会在真实链路里出问题(来源)。 对 DSH插件 作者来说,本文只讲这套契约条文本身——defineTool 的最小写法与四要素入门已写在站内 工具插件开发,工具在流水线里的运行原理见 工具流水线解析,这里不重复。

DSH plugin 工具的参数校验:defineTool 替你校验什么,你还得做什么

参数已经替你校验过了:defineTool 在 execute 运行前会根据统一的 ParameterSchemaSpec 校验模型生成的 arguments,因此 execute 内的 args 会匹配 InferArgs(来源)。 但校验边界必须记清:

  1. 校验覆盖什么 — 类型、必填键、字面量约束、恰好匹配一个分支的联合,以及嵌套值。
  2. additionalProperties 必须显式声明 — 显式对象节点要写 additionalProperties: true | false;隐式参数根对象保持开放。语义偷懒会让非法字段悄悄流入。
  3. schema 表达不了的仍要手检 — 非空字符串、正数、跨字段规则这类约束,schema DSL 表达不了,得在 execute 里自己判断。
  4. 原始 JSON Schema 工具自行负责 — 直接注册的原始 JSON Schema ToolDefinition(MCP 来源的工具就是这样到达的)不走 defineTool 的校验,输入校验由它自己承担。

一句话记住:defineTool 挡住「类型和结构」错误,语义错误归你。

DSH plugin 工具的只读定义与执行身份:注册后不要改

注册会借用你的只读定义,执行身份在执行期间受保护(来源)。 两条纪律:

  1. 注册后不要动定义 — 类型化的同进程贡献不是序列化边界,注册后不要修改其 schema 或替换回调;schemas() 只物化显式的模型可见投影。要热替换工具,必须 dispose 其所属副作用再注册替代品;回调闭包内的可变状态仍是普通的插件状态,可以正常使用。
  2. 执行身份全程冻结 — 注册表在一次递归遍历中把 arguments 物化为分离的无损 JSON,在策略开始前冻结,并分配一个不透明的 exec.token。callId、name、arguments、agent、token、必填且由调用方持有的 signal,以及可选的外层传输 parent token,在整个分发过程中保持不可变;parent 仅用于身份标识,不暴露活跃的外层执行。请把 args 视为只读输入。

唯一的例外是 exec.signal:只有 around-dispatch 包装器会收到可变视图,它可以替换并恢复必填的 exec.signal 以施加截止时间,但不能移除该信号。想包分发加超时,只能走这条路。

DSH plugin 工具该返回什么:规范 JSON 值与 isError 语义

声明并返回一个规范 JSON 值,是工具与调用方之间的硬接口(来源)。

  1. 只返回推导出的值 — output.schema 使用 ValueSchemaSpec,根可以是对象、数组、标量或 null。execute 只返回推导出的值;注册表将其快照为无损 JSON,完成校验和冻结后,再传给 output.render(args, value)。
  2. 不要返回内容块 — 工具主体不要返回内容块,也不要迫使调用方从自然语言中解析 id 和字段。这样做会同时破坏渲染与程序化调用(Code Mode 的 ToolOutputMap 正是从同一组 schema 派生的)。
  3. 异常或无效值即 isError — 注册表会捕获异常,并在观察者运行前收敛 schema、渲染器、元数据投影器和无损 JSON 的失败。基础设施故障请抛异常;成功的领域结果即使表示不理想的状态,也应写入规范值,由其 Native 渲染器解释该状态,例如进程以非零状态退出。

DSH plugin 工具的信号、回放元数据与异步通知

剩下三条规则都关乎运行期协作(来源)。

  1. 遵守 exec.signal — 信号触发时取消进行中的工作。长耗时 I/O 要把 signal 透传下去(如 readFile(path, { signal })),不要忽略它。
  2. 用 presentationMeta 投影持久化的卡片数据(可选) — output.presentationMeta(args, value) 从同一个规范值派生可回放的 JSON;核心将其持久化在 tool/result 上并传给 presentResult,因此需要结果期事实的卡片——例如 write/edit 的已应用 hunk——无需持久化规范值也能在回放中重现。嵌套 Code 分发没有卡片,会跳过该投影器。
  3. 用 exec.agent 发送异步通知 — agent.inject({ content, source: { kind: 'plugin', plugin: '<name>' } }) 追加持久化上下文,下一次模型请求会看到它;这不是唤醒,空闲的 agent 保持空闲。请防范已 dispose 的 agent(用 try/catch 包住)。

写完自检四项:显式对象节点是否声明了 additionalProperties;注册后是否还有人改 schema 或换回调;execute 是否只返回规范值而不是拼好的文本;长耗时操作是否把 exec.signal 透传下去。想对照生产级实现,可在 DSH Plugin Hub 找工具类插件;工具结果卡片怎么渲染见 工具卡片渲染契约,门禁、超时与观测该挂哪个扩展点见 功能→机制映射。

常见问题

DSH plugin 的 defineTool 会替我校验参数吗?我还需要做什么?

DSH plugin 的 defineTool 会在 execute 运行前按统一的 ParameterSchemaSpec 校验模型生成的 arguments——类型、必填键、字面量约束、恰好匹配一个分支的联合以及嵌套值,因此 execute 内的 args 会匹配 InferArgs。但显式对象节点必须声明 additionalProperties: true | false,schema DSL 表达不了的约束(非空字符串、正数、跨字段规则)仍需手动检查,直接注册的原始 JSON Schema 工具则自行负责输入校验。

DSH plugin 工具注册后可以改 schema 或换 execute 回调吗?

不可以——DSH plugin 工具注册后会借用你的只读定义,注册后不能改 schema 或换 execute 回调。类型化的同进程贡献不是序列化边界,schemas() 只物化显式的模型可见投影。要热替换工具,必须 dispose 其所属副作用再注册替代品;回调闭包内的可变状态仍是普通的插件状态。

DSH plugin 的 execute 到底应该返回什么值?能不能直接返回内容块?

DSH plugin 的 execute 只返回推导出的规范 JSON 值:output.schema 使用 ValueSchemaSpec,根可以是对象、数组、标量或 null,注册表会把返回值快照为无损 JSON,完成校验和冻结后再传给 output.render(args, value)。工具主体不要返回内容块,也不要迫使调用方从自然语言里解析 id 和字段。

DSH plugin 工具出错时应该抛异常还是返回错误值?

DSH plugin 工具抛异常或返回无效值都意味着 isError:注册表会捕获异常,并在观察者运行前收敛 schema、渲染器、元数据投影器和无损 JSON 的失败。基础设施故障请抛异常;成功的领域结果即使表示不理想的状态(例如进程以非零状态退出),也应写入规范值,由其 Native 渲染器解释该状态。

DSH plugin 工具里的 exec.token 和 exec.signal 分别有什么用?

DSH plugin 里 exec.token 是不透明且全程不可变的执行身份,callId、name、arguments、agent、token、signal 与可选 parent 在整个分发过程中都不可变,args 必须视为只读输入;exec.signal 是唯一可替换的操作字段,只有 around-dispatch 包装器可以替换并恢复它以施加截止时间,但不能移除该信号,execute 必须遵守信号、在触发时取消进行中的工作。

相关术语

ParameterSchemaSpec(参数 schema 规范)
ParameterSchemaSpec 是 DeepSeek Harness 统一的参数 schema 描述:defineTool 在 execute 运行前据此校验模型生成的 arguments,覆盖类型、必填键、字面量约束、恰好匹配一个分支的联合与嵌套值,校验后的 args 匹配 InferArgs。— https://deepseek-harness.github.io/deepseek-harness/reference/cookbook/adding-a-tool
exec.token(执行身份令牌)
exec.token 是注册表在分发前分配的不透明执行身份令牌,与 callId、name、arguments、agent、signal 及可选 parent 一起在整条分发过程中保持不可变,仅用于身份标识而不暴露活跃的外层执行。— https://deepseek-harness.github.io/deepseek-harness/reference/cookbook/adding-a-tool
ValueSchemaSpec(返回值 schema 规范)
ValueSchemaSpec 是 output.schema 使用的返回值 schema 规范,根可以是对象、数组、标量或 null;execute 只返回推导出的规范 JSON 值,由注册表快照、校验并冻结后再交给 output.render。— https://deepseek-harness.github.io/deepseek-harness/reference/cookbook/adding-a-tool
presentationMeta(回放元数据投影)
presentationMeta 是可选的 output.presentationMeta(args, value) 投影器,从同一个规范值派生可回放的 JSON;核心把它持久化在 tool/result 上并传给 presentResult,让需要结果期事实的卡片在回放中重现而不必持久化规范值。— https://deepseek-harness.github.io/deepseek-harness/reference/cookbook/adding-a-tool

来源