DeepSeek Harness 产品级 Subagent 后台任务:用通用 Job 运行时承载 Codex / Claude Code 一次性委派
2026/9/21 1:37:57 网站建设 项目流程

DeepSeek Harness 产品级 Subagent 后台任务:用通用 Job 运行时承载 Codex / Claude Code 一次性委派

【免费下载链接】deepseek-harnessDeepSeek Harness: Everything is a Plugin.项目地址: https://gitcode.com/gh_mirrors/de/deepseek-harness

本指南以 DeepSeek Harness 仓库内的 Agent Note(2026-08-12-product-subagent-one-shot-background-tasks.md)为核心骨架,讲解产品级 Subagent(Codex 与 Claude Code)如何在"一个原生进程、一条最终答案"的一次性(one-shot)模型下,通过run_in_background参数接入通用后台 Job 运行时。读完本文,你将掌握该调度决策的完整生命周期、各组件(Provider、dsh-tool-subagentdsh-jobs-localdsh-tool-jobs)的责任划分、如何通过 Profile 与 Agent Preset 在组合层开启后台能力,以及对应验证方式与边界约束。

背景与问题:独立委派为何只能被前台阻塞

DeepSeek Harness 中,Codex 与 Claude Code 这两个产品提供方(provider)的运行模型是"一次性"的:一次委托只运行一个自包含任务,并返回一条最终答案。与此同时,dsh-tool-subagent这一面向模型的委派工具,早已能把任意 one-shot Provider 适配到通用的后台 Job 运行时上。

问题出在产品工具行的出厂配置上:随产品发布的工具行默认带上了disabled字段,把后台这条路由关掉了。于是,即使一次委派与 Agent 的下一步动作完全无关、完全可以并行,Agent 也只能在前台干等产品答案返回——独立任务被强制串行化、占住了调用现场。

决策总览:一行参数复用三层既有能力

本决策的目标是:暴露后台执行能力,但不引入任何新的产品会话、产品专属 Job 状态、第二个取消所有者或第二套结果协议。一次 Provider 运行仍然只负责一个原生进程/查询和一条最终答案;Job id、收集、取消、所有者清理与完成通知,全部继续由既有 Job 注册表负责。

实现上,这一决策把三层已经存在的能力拼装起来:

  1. 产品 Provider 层dsh-subagent-codexdsh-subagent-claude-code):拥有原生协议、答案选择、本地取消与进程树静默(quiescence);
  2. 通用 one-shot 后台适配器:负责后台注册与结算——启动同一个SubagentRun(见 Subagent 能力缝),用 Job 所有的取消信号覆盖 Provider 启动与执行全程,等待run.resultrun.dispose(),把终态结果与可选的安全诊断映射进 Job;
  3. 通用 Job 运行时dsh-jobs-local作为 Job Provider,dsh-tool-jobs作为面向模型的消费端):job_outputjob_listjob_kill与既有的完成通知负责把 Job 状态暴露给父 Agent。

关键点在于:本调度决策不新增任何 Provider 配置、服务接口、事件、线上字段、持久化格式或产品标识。前台与后台的差异,仅仅在于"由哪个既有消费者去等待同一次 one-shot 运行"。

前台与后台:run_in_background的精确语义

产品工具行的后台能力由 Agent Preset 配置中的backgroundMode: one-shot声明。出厂时,standardcodecordis三个 Agent Preset 都把对应产品工具行配置为dormant(休眠)状态;组合方把该行的disabled字段移除后,既有的可选参数run_in_background才会出现在暴露给 Agent 的工具 schema 中。

该参数取值决定调度方式:

run_in_background行为
省略 或false前台等待:工具调用阻塞,直到 Provider 启动、run.result返回;completed返回最终文本,其他终态原因映射为错误结果(可携带安全诊断),返回前必定dispose运行
true后台运行:先做同步的 Job preflight 与注册,然后立即返回一个父 Agent 所有的 Job id;不等待 Provider 启动,也不等待完成

后台调用在注册前还会做两道防线:校验父 Agent 身份,并拒绝已经收到中止信号的执行请求(详见 通用后台 Subagent 决策)。

生命周期与所有者清理

原文档给出的生命周期如下:

product tool call -> omitted / false: tool call waits -> final answer or error -> run disposal -> true: Job preflight + owner cleanup -> starter begins provider startup under Job-owned signal -> Job record/id published and returned (startup remains pending) -> provider result + run disposal -> Job settlement + notice -> job_output reads / job_kill cancels -> parent disposal: Job owner cleanup cancels -> run disposal -> process exit

几条值得注意的语义:

  • 后台任务进程本地、父级所有:它不会在父 Agent 销毁后存活,不暴露中间产品活动,也不会让产品会话变得可续接(resumable);
  • 取消信号跨启动期与执行期cancel(reason?)中止任务拥有的控制器,同一个信号既覆盖"Provider 尚未启动完成"的挂起期,也覆盖已发布运行剩余的收尾工作;
  • 终态映射completed返回最终文本;被取消的归为killed;其他停止原因归为failed并携带 Provider 诊断(若存在);启动、结果、dispose 任一环节失败都变成失败结果,而不是拒绝任务的 promise;
  • readOutput缺席:运行期间job_output只返回状态;结算后幂等地返回最终输出。中间的子 Agent 活动留在子会话中,不流入父会话日志。

责任分配表

事实或资源所有者产品工具责任可观察结果
产品 Provider 安装与注册显式 Profile安装可选 Provider 包,在 host 平面挂载必需的具名实例Provider 名字可用,但不必把包塞进每个生产dsh安装
产品选择与暴露Agent Preset把一个固定工具名绑定到一个固定 Provider启用一行只暴露该产品工具
前台/后台选择dsh-tool-subagentone-shot策略下解析run_in_background省略即前台;显式true返回 Job id
Job id、状态、输出、取消、通知ctx.jobsdsh-tool-jobs注册并呈现既有的 one-shot 运行通用 Job 工具为精确的父 Agent 收集或停止该运行
原生结果、可选诊断、进程静默产品 Provider 与dsh-subprocess产出一条最终结果并释放一个进程树Job 结算与前台返回消费同一条结果,且都等待 dispose

多实例扩展:命名实例与唯一工具名

在 命名实例决策 的支持下,Codex 或 Claude Code 可以各挂载多个Provider 实例。每个额外的 host Provider 行拥有各自的providerName;每个被暴露的 Preset 工具行通过provider绑定那个确切的名字,同时保留唯一的toolName。前台/后台的调度选择不会限制实例数量——也就是说,组合方可以为不同工作区、不同权限画像配置多套产品 Provider,每一套都可以独立地选择前台或后台运行。

组合(Composition):生产基座、Profile 选装与预置工具行

生产基座零负担

生产版dsh的基座把两个可选产品 Provider 排除在依赖闭包之外。选择加入的 Profile 负责:安装所需包(dsh-subagent-codexdsh-subagent-claude-code),并在 host 平面挂载必需的 Provider 实例。每个完整 Preset 都保持两个产品工具行处于disabled状态,同时把通用 Job 控制工具(job_outputjob_listjob_kill)纳入自己的 Agent 作用域,而共享的 Job 注册表归 base host 所有。

启用流程:用户复制一份 Preset,在 Profile 的 Provider 已就绪之后,从对应产品行移除disabled即可。组合过程中不会启动任何产品进程。

独立自定义组合的最低要求

一个要启用 one-shot 后台执行的独立自定义组合,必须同时提供:

  • 产品 Provider(dsh-subagent-codex/dsh-subagent-claude-code);
  • 完整的通用 Job 能力:dsh-jobs-local作为 Job Provider,dsh-tool-jobs作为模型可调用的消费端。

基于dsh-base的 Profile 已经自带 Job 能力,只需在启用 Preset 工具行前追加可选产品 Provider。反过来,没有 Job 运行时的产品工具仍然可以前台执行,但显式的后台请求会在既有的 Job preflight 处失败,而不是发布一个无法收集的 id——这保证了"拿不到 id 就一定不会有孤儿运行"。

ACP 产品组合

ACP 产品组合使用相同的固定产品行与通用 Job 控制。其无密钥(keyless)schema 快照会为每个启用的产品工具暴露descriptionprompt与可选的run_in_background,而无需真正调用 Codex、Claude Code 或任何外部模型。

验证:四类测试锚定行为

原文档的验证策略覆盖四个层面:

  1. Web 组合测试:从仓库 examples 依赖锚点显式挂载两个可选 Provider,然后启动四种用户预置变体——"两者都不用、仅 Codex、仅 Claude Code、两者都用"——逐一检查每个启用的产品工具是否同时暴露run_in_backgroundjob_outputjob_listjob_kill
  2. 两个包自带的 Loader 组合:在空PATH下运行,检查同样的 schema 与控制工具,证明显式加载 Provider不会启动任何产品进程
  3. ACP 无密钥快照:钉住组装后的显式产品 schema;
  4. 既有dsh-tool-subagent与 Job 测试套件:钉住前台默认值、Job 注册、最终输出收集、共享诊断呈现、取消、完成通知、所有者销毁与 Provider 销毁等行为。

此外,两个真实产品 Provider 套件独立证明:原生权限失败会先进入同一条共享结果,之后才轮到前台或后台任一调度路径消费它——这保证了两条路径对失败呈现完全一致。

备选方案回顾:为什么是"前台默认 + 后台显式"

备选方案被否原因
产品工具仅限前台schema 最小,但即使通用 one-shot Job 适配器已具备所需生命周期,Agent 仍无法调度独立的产品工作
产品委派默认后台one-shot Job 需要事后收集,不同于拥有持久会话 id 与结算投递的可续接子会话;前台保持兼容默认,后台保持显式选择
用 Codex / Claude Code 原生会话状态充当后台所有者会在通用 Job 注册表之外制造 Provider 专属的 id、状态、取消与恢复语义;Provider 保持一次性结果生产者、原生 id 保持私有
增加产品专属 output / wait / kill 工具重复通用 Job 协议,为每个 Provider 教一套不同的收集流程;既有job_*工具已覆盖所需操作
同时引入可续接的产品会话恢复、追问、进度与持久化产品会话需要新的产品契约与生命周期所有权;本决策只暴露已实现的 one-shot 后台路由

影响与边界

收益:当 Codex 或 Claude Code 处理一项独立的一次性任务时,Agent 可以继续做其他有用工作,随后通过与其他后台生产者完全相同的 Job 控制工具收集最终答案或取消它。前台与 one-shot 后台消费者在失败结果携带安全诊断时呈现完全相同的 Provider 诊断。

不变的契约:每一次产品委派仍然启动全新的原生进程或查询、只产出最终助手文本作为唯一助手负载,并以 Provider 销毁和整树退出收尾;失败结果可额外携带安全诊断。后台调用只是额外暴露通用 Job id、状态、完成通知与收集/取消结果。

硬边界:后台 Job 是进程本地的、父 Agent 所有的——不随父销毁存活、不暴露中间产品活动、不可续接。生产安装除非 Profile 显式安装,否则不为任一产品集成付费;任何暴露run_in_background的组合都必须同时保留通用 Job Provider 与控制工具。

源码索引

  • 面向模型的委派工具:packages/subagent/tool-subagent/package.json(peer 依赖含dsh-jobsdsh-subagentdsh-tools等,验证其位于委派与 Job 的交汇处)
  • Codex one-shot Provider:packages/subagent/subagent-codex/package.json(依赖@openai/codex,自带cordis.patch.yml组合补丁)
  • Claude Code one-shot Provider:packages/subagent/subagent-claude-code/package.json(依赖@anthropic-ai/claude-agent-sdk与 MCP SDK)
  • Job 运行时与消费工具:packages/jobs/jobs-local/package.jsonpackages/jobs/tool-jobs/package.json
  • 相关决策记录:通用后台 Subagent 适配器、Subagent 能力缝、产品 Provider 后端、非交互权限、命名实例

【免费下载链接】deepseek-harnessDeepSeek Harness: Everything is a Plugin.项目地址: https://gitcode.com/gh_mirrors/de/deepseek-harness

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询