Agent 工程对照
← 返回框架对照

多 Agent · 第 7 章

子代理隔离

派生一个子代理时,它和父代理共享什么、隔离什么?

覆盖度差别最大:openJiuwen 有完整子代理运行时,DeepSeek 能挂别家 Harness,Pi 内核不提供。

场景建议

编辑判断

按你的需求,倾向哪种做法

借鉴的是那一家的设计,不等于选用那个框架。

场景

子代理的输出不能淹没父代理的上下文

openJiuwen 的活动流带节流与截断;Pi 的示例用独立进程,上下文窗口天然隔离。

场景

要防止子代理无限派生、无限并发

openJiuwen 配了实例上限、并发上限与 LRU 驱逐;Codex 有 spawn 深度上限。

场景

要调度异构 Agent

它是四家里唯一把竞品 Harness 当作可挂载子代理 provider 的实现,靠共享结果契约统一返回。

四家怎么做

差异与源码

openJiuwen

独立子代理运行时,带并发上限与 LRU 驱逐

harness/subagent_runtime/ 是一个完整的运行时模块:注册表、会话管理、实例、状态与状态事件、活动流、转录流、持久化、输出文件各成一个文件。配置层直接把子代理当作需要限量的资源管理——最多 10 个实例、同时运行不超过 5 个、单轮超时、开启 LRU 驱逐。活动流还带节流和文本截断,因为子代理输出会淹没父代理的上下文。

适合
大量子代理并发、要当资源来管的平台。
代价
完整运行时(注册表、会话、转录、持久化),模块多,理解成本高。

此后的变化

  • 2026-W34 →

    新增 subagent_spawn/wait/list/send_input/close/resume 六个工具,子代理从一次性委派变为可持续交互。下次走读需复核 subagent_runtime 的对应实现。

Codex

独立线程 + 从父配置派生的角色覆盖

子代理是一个独立的 ThreadId,由 AgentControl 操作管理,并有 spawn 深度上限防止无限派生。隔离的粒度是「角色」:AgentRoleOverrides 在父配置的基础上覆盖 developer instructions、模型、推理强度、人格、特性开关与 skills 配置。注意源码措辞是 parent-derived configuration——子代理默认继承父的一切,只覆盖显式声明的部分。

适合
子代理大体继承父配置、只改角色(模型、指令、skills)的场景。
代价
默认继承父的一切,想隔离什么得显式覆盖,漏写就会泄漏。

此后的变化

  • 2026-W34 →

    「Preserve developer instruction annotations in subagent forks」(#40297) 直接触及本格引用的 AgentRoleOverrides.developer_instructions 继承语义。

DeepSeek Harness

子代理是可插拔 provider —— 包括别家的 Harness

把「子代理怎么跑」也做成了插件族:fork(用父会话已完成的轮次播种的进程内子代理)、spawn(干净的进程内子代理)、acp、dsh-sdk,以及最值得注意的两个——subagent-claude-code 和 subagent-codex。前者调用官方 Claude Agent SDK,后者用 app-server --stdio 起一个临时 Codex 线程,两者都在委派会话的工作区里执行,并通过共享的结果契约返回。四家里唯一把竞品 Harness 当作可挂载能力的实现。

适合
想把别家 Harness(Claude Code、Codex)当子代理调度的编排层。
代价
插件族多(fork、spawn、acp、sdk 与两家外部 Harness),每条路径的语义都要分别理解。
Pi

内核不提供,示例扩展用独立进程实现

全仓检索 subagent 只命中 CHANGELOG、测试与 examples/extensions/subagent/ —— 内核没有子代理概念。示例扩展给出的方案反而是四家里隔离最彻底的:每个子代理是一个独立的 pi 进程,上下文窗口天然隔离,Ctrl+C 会传播下去杀掉子进程。这与它的沙箱选择完全同构:内核保持最小,隔离交给操作系统的进程边界。

适合
要最彻底的隔离、并且接受进程级开销。
代价
内核不提供,只有示例扩展;协作能力要自己搭。
横向读这一行

覆盖度差异最大的一行。openJiuwen 有完整的子代理运行时(注册表、会话管理、转录、持久化),Codex 有角色与控制层,DeepSeek 走得最远——它能把 Claude Code 和 Codex 当作子代理进程挂进来,而 Pi 干脆不在内核里提供子代理,只给一个示例扩展。

设计空间分析

四家把「子代理是什么」映射到了四种不同的隔离对象——受限资源、覆盖角色、可插拔执行后端、操作系统进程边界。

openJiuwen 把子代理当作需要限量调度的资源:harness/subagent_runtime/ 是一个完整运行时模块,注册表、会话管理、实例、状态与状态事件、活动流、转录流、持久化、输出文件各成一个文件;SubagentRuntimeConfig 直接设了硬限额——max_subagents 10、max_concurrent_running 5、turn_timeout_s、enable_lru_eviction;活动流还带节流(activity_throttle_ms)和文本截断(activity_text_max_len),因为子代理输出会淹没父代理的上下文。

codex 把隔离粒度落在「角色」上:子代理是一个独立 ThreadId,由 AgentControl 管理,并有 spawn 深度上限防止无限派生;AgentRoleOverrides 在父配置基础上覆盖 developer_instructions、model、model_reasoning_effort、model_reasoning_summary、model_verbosity、personality、service_tier、features、skills——源码措辞是 parent-derived configuration,子代理默认继承父的一切,只覆盖显式声明的部分。

deepseek harness 把「子代理怎么跑」本身做成了可插拔的 provider 族:packages/subagent/ 下有 subagent-fork-in-process(用父会话已完成轮次播种的进程内子代理,README 写明它与 spawn 共享全部运行机制,会话种子是唯一行为差异)、subagent-spawn-in-process(干净的进程内子代理)、subagent-acp、subagent-dsh-sdk,以及 subagent-claude-code(调用官方 Claude Agent SDK)和 subagent-codex(用 app-server --stdio 起一个临时 Codex 线程)——两者都在委派会话的工作区里执行,通过共享结果契约返回。格子指出这是四家里唯一把竞品 Harness 当作可挂载能力的实现。

pi 的内核没有子代理概念,全仓检索只命中 CHANGELOG、测试与示例扩展;examples/extensions/subagent/README 描述的方案是把每个子代理起成独立的 pi 进程,上下文窗口靠进程边界天然隔离,Ctrl+C 会传播下去杀掉子进程——格子把这称为四家里隔离最彻底的方案,与它在沙箱维度上「内核最小、隔离靠操作系统」的选择同构。

另有两条来自周报的记录值得放在一起看:2026-W34 记录 openJiuwen 新增了 subagent_spawn / wait / list / send_input / close / resume 六个工具,子代理从「派出去等结果」变成「派出去还能持续交互」;同一周报也记录 codex 有一条修复「在子代理 fork 时保留 developer instruction 标注」,直接触及上面 AgentRoleOverrides.developer_instructions 的继承语义。以上关于 openJiuwen 和 codex 的机制描述锁定在各自审计 commit 上,不是对上游当前状态的断言。

编辑判断

四种隔离对象——资源、角色、可插拔后端、进程边界——对应四种不同的「子代理该是什么」的默认假设:openJiuwen 把子代理当作要限量调度和防止拖垮父上下文的资源,codex 当作带覆盖规则的角色分身,deepseek harness 当作可以换成任意执行后端(甚至别家 harness)的插槽,pi 让操作系统的进程模型承担全部隔离工作、框架本身不建模。

还没有定论:openJiuwen 新增的子代理持续交互工具(spawn/wait/list/send_input/close/resume)和 codex 对 developer instruction 继承语义的修复,具体如何改变上面描述的资源限额模型与角色覆盖模型,尚未对照新 commit 重新走读源码,暂不下结论;四种隔离对象在跨会话状态泄漏、子代理崩溃恢复等场景下的实际差距,也没有一手测试数据。

这个问题为什么存在

第 7 章

多 Agent 协作

受限子代理、消息总线与验证者:编排多个循环