DeepSeek-Harness 子代理:委派给 Claude Code、Codex、ACP 及进程内代理
DeepSeek-Harness 子代理机制详解——五个官方 provider、一次性与可续接两种委派模式,以及 dsh 如何把任务交给 Claude Code 或 Codex 当子代理执行。
DeepSeek-Harness(dsh)通过 ctx.subagents——一个可以同时挂载多个实现的具名 provider 注册表——把任务委派给子代理,其中两个 provider 会把任务直接交给两个完全不同的智能体产品:Claude Code 和 Codex。这是大多数对比类文章会漏掉的细节:dsh 和 Claude Code 在这一点上并不是纯粹的竞争关系,dsh 可以把 Claude Code 编排为自己的一个执行后端。
dsh 子代理和 bash executor 有什么不同
dsh 里大多数能力接缝在同一时刻只有一个生效的实现——比如一个 ShellExecutor 服务通常只由一个 provider 支撑。子代理不同:ctx.subagents 被明确设计成一个注册表,意味着可以同时注册多个 provider,由调用方按任务决定委派给哪一个。子代理不会继承父代理的 agent-scope(即隔离一个代理能看到哪些工具/提示词/变量的机制)——作用域隔离和委派血缘是两套独立系统。"血缘"(谁委派了谁)是通过 parentSession 和 delegationDepth 字段单独维护的,不依赖 scope 结构表达。
五个官方 provider
| Provider 包 | 作用 |
|---|---|
dsh-subagent-spawn-in-process / dsh-subagent-fork-in-process | 在同一个 dsh 进程内运行子代理,起一个子 session,不需要独立进程 |
dsh-subagent-acp | 拉起一个独立进程,通过 Agent Client Protocol(ACP)驱动 |
dsh-subagent-codex | 委派给 Codex,走 Codex 官方 app-server 协议 |
dsh-subagent-claude-code | 委派给 Claude Code,走 Claude Code 官方 Agent SDK |
dsh-subagent-dsh-sdk | 把另一个 dsh 运行时当子进程驱动,走 SDK 的 stdio JSON-RPC 协议 |
其中三个完全留在 dsh 自己的世界里(进程内、ACP、dsh-sdk);另外两个则直接把执行权交给另一个智能体产品。哪个 provider 可用取决于你的 profile 里装了哪个子代理插件——除了基础 bundle 自身的委派需求之外,没有哪个 provider 是默认必然存在的。
一次性(one-shot)与可续接(continuable)
子代理调用有两种模式:
- 一次性——子代理跑完一个被委派的任务后返回结果并结束。这个模式支持四个可选能力,每一个都需要 provider 明确声明支持:
outputSchema——结构化输出而非自由文本depthLimit——限制子代理自身还能再往下委派多少层toolFilter——限制子代理能看到/使用哪些工具persona——为被委派任务覆盖系统提示词层面的身份设定
- 可续接——子代理的 session 保持存活,可以接收后续的追加委派,不需要从头重建上下文。
如果一个 provider 没有声明支持这四个一次性能力中的某一个,收到相应请求时会直接拒绝——dsh 不会静默降级或忽略一个不支持的能力请求,如果你在构建假设 outputSchema 普遍可用的自动化流程,这一点值得注意。
为什么"dsh 能把 Claude Code 当子代理跑"这件事很重要
这个事实让常见的"dsh vs Claude Code"叙事变得没那么简单。因为 dsh-subagent-claude-code 是一个真实存在、官方维护的 provider,dsh 会话可以把一个子任务委派给一个真正的 Claude Code Agent SDK 实例,再把结果拿回自己的会话——这两个工具不是像两个竞争的 IDE 那样互斥的关系。Codex 通过 dsh-subagent-codex 也是同样的情况。如果你评估 dsh 的原因恰恰是想在把顶层编排统一到 dsh 的同时,某些任务还想继续用 Claude Code 或 Codex,这条委派路径正是让这件事可行的机制——更完整的对比参见DeepSeek-Harness vs Claude Code与DeepSeek-Harness vs OpenAI Codex CLI。
在自己的插件代码里发起委派
因为 ctx.subagents 和其他能力接缝一样是一个可注入的服务,在自己的插件里调用它并不需要引入一整套工作流框架——一个工具的 execute 函数完全可以把工作交给某个具名 provider 去做,而不是内联完成,这和我们自定义工具教程里讲的任何一个 inject: ['subagents'] 插件是同一种基本形态。(调用某个具体 provider 的精确调用签名本文没有给出,因为本文使用的溯源文档没有把它钉死——如果要照着写代码,请先去 dsh 仓库的 docs/subsystems/subagent.md 核对当前的精确 API。)有文档依据、且无论精确调用形态如何都值得围绕它做设计的是:为任何被委派的任务传一个保守的 depthLimit,让你调用的子代理不能无限制地继续往下委派;只要你不希望子代理继承 provider 默认会暴露的全部工具,就传 toolFilter。
为什么深度与工具限制对安全很重要
委派是一个真正值得认真做安全审查、而不是事后补救的环节。一个没有被 toolFilter 限制的子代理,会默认继承 provider 暴露的所有工具——对于像 dsh-subagent-claude-code 这样的进程外 provider 来说,这意味着一个拥有自己独立工具集的另一个智能体产品,正在同一个工作区上操作。对任何涉及不可信输入的委派路径(例如,在决定要不要进一步委派之前,先总结一段从网上抓取的内容),都应该刻意组合使用 depthLimit 和 toolFilter,这和你在为顶层会话考虑权限预设时的思路是一样的——被委派的子代理实际运行在什么沙箱模式下,参见我们的权限与沙箱指南。这四个一次性能力都不会覆盖 provider 执行任务所处的沙箱模式;它们控制的是子代理能尝试做什么,而不是它尝试之后实际被允许执行什么。
子代理机制与基于插件的编排生态
ctx.subagents 机制是底层原语;工作流与自动化分类里的插件在它之上构建了更高层的编排。两个值得了解的例子:
- dsh-agent-teams 在 dsh 委派原语之上实现了多智能体"团队"协作。
- dsh_workflow 是一套更宽泛的、可保存/可治理的多智能体编排工作流(UltraCode 风格),同样构建在底层子代理与工作流引擎之上。
这两个插件都不是使用子代理机制的必需品——你完全可以在自己的插件代码里直接调用 ctx.subagents 来完成一次委派任务,不需要引入团队/看板这类抽象。只有当你需要跨多轮维护持久化的多智能体协作状态,而不只是一次性的委派时,才有必要用上这类插件。
FAQ
dsh 会话可以委派给 Claude Code 吗?
可以——dsh-subagent-claude-code 是一个官方 provider,通过 Claude Code 的 Agent SDK 完成委派。这是 dsh 的原生能力,不是社区的变通方案。
子代理和 hook 有什么区别?
hook 拦截的是一个生命周期扩展点(参见我们的hooks 与命令指南);子代理则是把一个任务委派给另一个代理实例执行,可以是进程内也可以是进程外。这是两套不相关的机制。
子代理会继承父会话的工具权限吗?
不会通过 scope 自动继承——子代理不继承父代理的 agent-scope。委派血缘(parentSession、delegationDepth)是单独维护的,而 toolFilter 这类能力存在的目的正是为了控制被委派的子代理能访问什么。
如果向一个不支持 outputSchema 的 provider 请求它会怎样?
请求会被直接拒绝而不是被静默忽略——在依赖某个能力之前,先确认这个 provider 声明支持四个一次性能力(outputSchema、depthLimit、toolFilter、persona)中的哪几个。
一定要装 dsh-agent-teams 这类插件才能用子代理吗?
不需要——任何注入了 ctx.subagents 的插件都能直接使用它。团队/看板类插件是在此基础上叠加的持久化多智能体协作能力;一次性的委派任务不需要它们。
Next steps
想了解 dsh 的委派模型与 Claude Code、Codex 自身的子代理/任务工具相比如何,阅读DeepSeek-Harness vs Claude Code与DeepSeek-Harness vs OpenAI Codex CLI。想看构建在这个原语之上的多智能体编排插件,浏览最佳 DeepSeek-Harness 工作流插件和工作流与自动化分类页。想查阅相关术语(agent-scope、turn/step/round),参见术语表。