ChatGPTClaudeGrok / X / CursorGemini

DSH plugin 怎么接 PTC 运行时?ctx.ptcRuntime、超时取消与沙箱边界

插件开发发布于 2026-10-21作者: DeepSeek Plugin 插件市场
DSH pluginDeepSeek HarnessPTCptcRuntime沙箱
PTC 运行时让模型写的程序在 Host 绑定上执行:resolve 校验目录、截止与权限,run 返回 value、logs 与 error 字段。失败不抛异常,而是按 exception、timeout、abort 等类型报告。

PTC 运行时的核心不是“执行一段代码”,而是“把一段程序放进一个有 Host 绑定、有预算、有沙箱事实的执行世界”。 ctx.ptcRuntime 提供两个动作:resolve(request) 把调用方输入补齐成完整的 PtcRunSpec,run(spec) 执行并返回 PtcRunResult。程序失败是结果字段,不是异常;沙箱事实是独立报告,不是“成功即证明”。

DeepSeek Harness:三个核心对象

先分清 request、spec 与 result,写实现时就不会把校验和执行混在一起。 三者关系:(来源)

对象谁产生关键字段
PtcRunRequest调用方program、bindings、timeoutMs、sandboxPolicy、signal
PtcRunSpec提供方 resolve补齐后的 cwd、timeoutMs 与支持的选择
PtcRunResult提供方 runvalue、logs、error、sandbox

resolve 的职责是“验证支持的选择并应用部署默认值”。省略 timeout 用提供方默认值,数值请求封顶经过时间预算,null 请求不设截止。提供方在执行前拒绝不支持的选择,而不是等程序跑起来再失败。

run 只接收完整输入:cwd 一定存在,timeoutMs 一定是正数或 null。这样实现者不必在每次执行里重复补默认值。

DeepSeek Harness:绑定怎么设计

绑定是程序能看到的 Host 函数,不是任意对象通道;参数与返回值都必须是无损 JSON。 设计要点:(来源)

  1. 一个命名空间一个全局对象 — 每个 PtcBindingNamespace 以 global 名暴露,函数按名字挂在下面。预期:程序里能像调普通异步函数一样调用。
  2. 名字必须是可移植标识符 — 只允许 [A-Za-z_][A-Za-z0-9_]*,且不能是保留字。预期:同一份命名空间列表能跑在 JS 与 Python 后端。
  3. 函数名按自有属性处理 — __proto__、constructor 这类名字也要当普通键,构造时用 null-prototype。预期:不会发生原型碰撞。
  4. 错误可以类型化 — 可选 errorClass 让程序看到真实的错误构造器与成员名。预期:拒绝能以结构化方式被程序捕获。
  5. 值必须无损 — 参数与解析值都要能无损穿过 JSON 边界。预期:不可克隆的值被明确拒绝,而不是悄悄变成字符串。

如果一个绑定需要传复杂对象,先把它拆成 JSON 可表达的字段;不要依赖后端的序列化“碰巧能过”。

DeepSeek Harness:失败分类与结果处理

PTC 的失败是正交结果:超时不是异常,中止不是超时,基底崩溃也不是两者中的任何一个。 八类:(来源)

  • exception — 程序抛出或解析/转换失败。
  • timeout — 实现拥有的预算耗尽。
  • abort — 请求的 signal 触发。
  • worker-exit — 执行基底死亡,例如 OOM。
  • invalid-output — 完成值不是无损 JSON。
  • output-limit — 序列化后的日志、值或诊断超过上限。
  • protocol — 程序发出非法或超预算的控制流量。
  • sandbox-unavailable — 所需约束无法建立。

处理时不要把 error 当成异常再抛一遍;它本来就是给调用方展示或回喂模型自纠的字段。日志是纯字符串,每个来源通道保留自己的顺序,但跨通道如何交错由后端决定。

DeepSeek Harness:三种接入方式

接 PTC 不只有“自己写一个运行时”一条路;按隔离与持久化需求选。 三种:(来源)

  1. 使用发布的 Node 提供方 — 适合大多数本地执行,已有沙箱与持久 REPL 行为。预期:不用自己处理进程隔离。
  2. 实现无状态提供方 — 每次请求全新环境,忽略 stateOwner。预期:实现简单,适合一次性计算。
  3. 实现保留状态的提供方 — 用 stateOwner 隔离内存,消费者结束时 release(owner)。预期:能在同一所有者下复用环境,但保留对象不会进入持久 Session。

无论哪种,每个实现都要在资源释放期间终止并等待活跃执行;清理失败应拒绝 release 或 shutdown。

DeepSeek Harness:实现前的检查表

写一个能用的 PTC 提供方,先把下面四件事定下来,再写代码。 检查表:(来源)

  1. 语言与 programFormat — 是异步函数体还是 REPL,决定顶层 await 与 return 的语义。预期:程序不会因为格式不符在解析阶段失败。
  2. 绑定命名空间 — 哪些 Host 函数暴露、全局名是什么、是否带类型化错误。预期:名字符合可移植标识符规则。
  3. 预算与隔离 — 默认 timeout、数值上限、null 的含义、是否有沙箱。预期:resolve 能给出完整的 PtcRunSpec。
  4. 资源释放 — 每个运行的状态如何隔离,release(owner) 如何终止在途执行。预期:清理失败会显式拒绝。

四件事没定清楚就写 run,通常会在“错误处理”和“状态泄漏”上返工。

DeepSeek Harness:一个最小调用骨架

调用方只需要关心 resolve 与 run 两步,程序失败看 result.error。 骨架:(来源)

ts
const spec = ctx.ptcRuntime.resolve({
  program,
  bindings: [{ global: 'tools', functions: { readFile } }],
  cwd,
  timeoutMs: 30_000,
})
const result = await ctx.ptcRuntime.run(spec)
if (result.error) return { ok: false, kind: result.error.kind }
return { ok: true, value: result.value, logs: result.logs }

注意 resolve 可能因为不支持的选择而抛错,这属于调用方契约错误;run 里的程序失败则是 result.error,两者不要混。

安全与边界

沙箱事实是“报告”,不是“保证”;程序成功本身不能证明每项限制都强制执行。 四点:

  1. 看 sandbox.mode 与 denied — 模式、观察到的拒绝、强制完整性是独立事实。预期:不把“没报错”当成“没有越权”。
  2. isolation 不是安全声明 — 它只描述执行基底。预期:不要拿它当合规证明。
  3. 不接收代理配置 — Workflow worker 与 Node PTC 进程不继承代理变量。预期:模型脚本读不到可能带密码的代理 URL;需要出网时自行配置并受沙箱约束。
  4. 区分运行失败与契约误用 — 程序失败进 error,只有 Service Definition 误用才让调用拒绝。预期:调用方不会把用户代码错误当成框架崩溃。

DeepSeek Harness 常见问题

Q:PTC 和普通工具调用有什么区别? 普通工具调用是一次函数调用;PTC 让模型写一段程序,在 Host 绑定上组合多次调用,并共享一次执行的目录、预算与沙箱事实。

Q:能不能让 PTC 程序持久保存状态? 可以用 stateOwner 在进程内保留,但它不是持久 Session 格式;进程退出后状态不保证存在。

Q:超时后绑定里的在途调用会怎样? 运行时会停止程序,但在途绑定调用由调用方负责收尾;不要把 timeout 当成“所有副作用都已停止”。

一句话收束: PTC 运行时要把“校验、执行、结果、沙箱”四件事分开看;混在一起,最容易把程序失败误判成框架异常。

ChatGPTClaudeGrok / X / CursorGemini

常见问题

DeepSeek Harness 的 PTC 运行时是什么?

DeepSeek Harness 里,PTC 运行时是 dsh-ptc-runtime 提供的可选能力 seam,通过 ctx.ptcRuntime 让一段程序在 Host 绑定上执行,并报告输出、失败与适用的沙箱事实。它不属于智能体循环主干。

PtcRunRequest 和 PtcRunSpec 有什么区别?

DeepSeek Harness 里,PtcRunRequest 是调用方输入,包含程序、绑定、取消与可选执行选择;resolve 会校验支持的选择并补齐目录、截止与权限,产出 cwd 与 timeoutMs 都明确的 PtcRunSpec,run 只接收完整输入。

PTC 程序的失败会抛异常吗,在 DeepSeek Harness 中如何处理?

DeepSeek Harness 里,不会。程序失败通过 PtcRunResult.error 返回,error 是结果上的字段;只有 Service Definition 契约误用才拒绝。失败类型包括 exception、timeout、abort、worker-exit、invalid-output、output-limit、protocol 与 sandbox-unavailable。

PTC 运行时里的绑定能传任意对象吗,在 DeepSeek Harness 中如何处理?

DeepSeek Harness 里,不能。绑定参数与返回值必须是无损 JSON;运行时会把不可克隆或会丢信息的值拒绝掉,而不是静默转换。不同后端还有各自的传输上限,seam 不设统一字节上限。

PTC 运行时为什么收不到代理配置,在 DeepSeek Harness 中如何处理?

DeepSeek Harness 里,官方明确说 Workflow worker 与 Node ptc-runtime 进程不接收代理配置,避免模型脚本读到可能带密码的代理 URL。直接请求要自行配置代理,并继续受执行沙箱约束。

相关术语

PTC
PTC 是 DeepSeek Harness 中让模型编写程序并调用 Host 绑定的执行能力,由可选的 ctx.ptcRuntime seam 提供,不属于智能体循环主干。— DeepSeek Harness 官方参考 - PTC 运行时
PtcRunRequest
PtcRunRequest 是一次 PTC 执行的调用方输入,包含 program、bindings、cwd、timeoutMs、sandboxPolicy、stateOwner 与 signal;resolve 负责校验并补齐默认值。— DeepSeek Harness 官方参考 - PTC 运行时
PtcRunResult
PtcRunResult 是一次 PTC 执行的结果,包含可选的 sandbox 事实、完成值 value、日志 logs 与失败字段 error;程序失败不会让 run() 拒绝。— DeepSeek Harness 官方参考 - PTC 运行时
stateOwner
stateOwner 是 PTC 请求里用于标识可选保留内存的进程内对象身份;不同对象相互隔离,省略时请求全新环境,消费者在所有者结束时调用 release(owner)。— DeepSeek Harness 官方参考 - PTC 运行时

来源