Yoda
参考Agent 设计指南扩展

Subagents 子代理

CC 用"声明式 agent 定义文件 + Task 工具"派发子代理(frontmatter 可配工具/模型/隔离/记忆);Codex 用"命令式工具套件"(spawn/send/wait/close 8 个工具)+ config.toml 角色声明,角色本质是一个配置层

Subagents 子代理

结论

两家的子代理走了两种范式:CC 是声明式——.claude/agents/*.md 用 frontmatter 定义 agent 类型(tools/model/permissionMode/mcpServers/hooks/isolation…共 20 余字段),主模型通过单一 Task(Agent) 工具按类型派发,子代理 transcript 以 isSidechain 标记单独存储;Codex 是命令式——给模型一套 multi_agent_v1 工具(spawn_agent/send_message/wait_agent/close_agent 等 8 个),子代理是真正的独立 thread(ThreadSource::Subagent),角色用 [agents.<role>] 在 config.toml 声明、本质是叠加一个配置层config_file 指向角色专属 TOML)。CC 的 agent 定义携带能力包(连 MCP server 都能内联),Codex 的角色携带的是完整配置面(含权限/沙箱)。双方都有 SubagentStart/SubagentStop hook 事件,深度/并发限制 Codex 显式可配(max_depth/max_threads)。

研究问题

  • CC agent 定义的 frontmatter 全集与派发机制?
  • Codex 子代理的工具面、角色声明与线程模型?
  • 上下文隔离怎么做?transcript 存哪?

各 Agent 设计与实现

Claude Code

定义:.claude/agents/*.md(user/project/managed)+ 插件 agents/ + 内建。 [一手源码] src_2026-03-31/tools/AgentTool/loadAgentsDir.ts:308loadMarkdownFilesForSubdir('agents', cwd))。frontmatter 必填 name + description(:404-413),完整字段集见 BaseAgentDefinition(:106-133)与 AgentJsonSchema(:73-99):

tools / disallowedTools / model('inherit'可) / effort / permissionMode /
mcpServers   // 按名引用已配 server,或直接内联整个 server 定义
hooks        // agent 启动时注册的会话级 hooks
maxTurns / skills(预载) / initialPrompt / memory('user'|'project'|'local') /
background / isolation('worktree'|'remote') / omitClaudeMd

值得单独点名的三个字段 [一手源码]:

  • isolation: 'worktree'——agent 在独立 git worktree 里跑(remote 仅内部 ant 用户,:94-97);
  • omitClaudeMd——只读型 agent(Explore/Plan)不注入 CLAUDE.md 层级,注释原文称每周节省 ~5-15 Gtok(:128-132);
  • criticalSystemReminder_EXPERIMENTAL——每轮用户 turn 重注入的短消息(:121)。

内建 agent 6 个。 [一手源码] tools/AgentTool/built-in/ExplorePlangeneral-purposeverificationstatusline-setupclaude-code-guide

派发与隔离。 主模型调 AgentTool(即 Task 工具,Task.ts 任务类型 local_agent),子代理拿独立上下文窗口;transcript 以 sidechain 形式落盘——[一手源码] utils/sessionStorage.ts:995,1042isSidechain 参数随条目写入,:1225entry.isSidechain && entry.agentId 过滤)。skill 也可声明 agent: Explore 借子代理执行(见 skills 章)。

Hook 联动:SubagentStart/SubagentStop 在 27 事件集内;agent frontmatter 自带 hooks 在其会话生效。

Codex CLI

工具面:multi_agent_v1 命名空间 8 个工具。 [一手源码] codex-rs/core/src/tools/handlers/multi_agents_spec.rs:11(namespace 描述 "Tools for spawning and managing sub-agents."):spawn_agent(v1/v2,返回 agent id + nickname)、send_input/send_messagefollowup_taskresume_agentwait_agent(带可配超时)、list_agentsclose_agent。另有 agent_jobs 系列 handler(后台作业)。即:协作原语暴露给模型,编排策略长在 prompt 里,而非像 CC 那样收敛成单工具。

角色 = 配置层。 [一手源码] config/src/config_toml.rs:659-703 AgentsToml

[agents]
max_threads = 8        # 并发线程上限
max_depth = 2          # 嵌套深度(root=0)
job_max_runtime_seconds = 600

[agents.researcher]
description = "Research-focused role."
config_file = "./agents/researcher.toml"   # 角色专属配置层!
nickname_candidates = ["Herodotus", "Ibn Battuta"]

config_file 指向一个完整的 config 层(相对其声明文件解析)——意味着角色可以改模型、权限、沙箱、MCP,能力边界比 CC 的 frontmatter 字段更大(但也更重)。

线程模型。 [一手源码] protocol.rs:2503 ThreadSource::SubagentSessionSource::SubAgent(sub_source) 携带 parent_thread_id(:2572,2655)——子代理是有谱系的独立会话,可 resume_agent 续命、forkhide_agent_type_model_reasoningmax_concurrent_threads_per_session 等派发选项在 spawn 工具 spec 里(multi_agents_spec.rs:23-29)。

入口:TUI /agent/subagents 打开 agent picker(tui/src/chatwidget/slash_dispatch.rs:285)。Hook 事件 SubagentStart/SubagentStop 在 10 事件集内(protocol.rs:1339)。

协作模板collaboration-mode-templates/templates/{default,plan,execute,pair_programming}.md——人机协作模式模板,与 subagent 正交但常被混淆,注意区分。

差异矩阵

维度Claude CodeCodex CLI
范式声明式:agent 定义文件 + 单一 Task 工具命令式:8 个协作工具暴露给模型
定义位置.claude/agents/*.md(frontmatter)+ agents.json + 插件 + 6 内建config.toml [agents.<role>],角色指向配置层文件
能力裁剪tools/disallowedTools 白黑名单、permissionMode角色 config 层可改权限/沙箱/模型(全配置面)
模型/effortfrontmatter model/effortspawn_agent 参数 + 角色 config
隔离上下文隔离 + 可选 isolation: worktree独立 thread(ThreadSource::Subagent,带 parent 谱系)
并发/深度限制maxTurns(轮数);并发未见显式配置 [推断]max_threads / max_depth / job 超时显式可配
双向通信子代理一次性返回结果(Task 结果)send_message/followup_task/resume_agent 持续对话
transcript主会话内 sidechain(isSidechain 标记)独立 thread 存储(thread-store/rollout 体系)
hook 事件SubagentStart/SubagentStop(27 集内)SubagentStart/SubagentStop(10 集内,命名一致)
上下文节流omitClaudeMd 裁掉子代理的 CLAUDE.md角色 config 层自然隔离用户级配置 [推断]

最小复现

# CC:自定义 agent + 派发
mkdir -p .claude/agents && cat > .claude/agents/greeter.md <<'EOF'
---
name: greeter
description: Use for greeting tasks
tools: [Read]
---
You only greet people. Reply in French.
EOF
claude -p "Use the greeter agent to say hi"   # Task 工具应派发 greeter;transcript 出现 isSidechain 条目

# Codex:角色声明
# ~/.codex/config.toml 加 [agents.researcher] description="..."
codex    # /agent 打开 picker 应列出 researcher(未实测;config_toml.rs 字段 + slash_dispatch 为证据)

Harness 接入建议(Yoda 实践)

Yoda harness-spec.ts 目前 subagentDirs: ['.claude/agents'](claude)/ [](codex)——Codex 侧标"不支持"已不准确,应改为解析 config.toml[agents.*] 节:

  1. 检测:CC 扫 .claude/agents/*.md(user+project+managed)+ 插件 agents;Codex 解析各层 config.toml 的 [agents],并跟进 config_file 引用的角色配置层(文件不存在要标错)。
  2. 校验:CC 校验 name/description 必填(源码即此二项硬校验)、tools 列表中工具名存在、mcpServers 引用的 server 已配置(requiredMcpServers 不满足时 agent 不可用);Codex 校验 config_file 相对路径可解析、角色 config 层本身的 TOML 合法性。
  3. 运行观测:CC 解析 transcript 的 isSidechain + agentId 重建子代理树;Codex 用 thread 谱系(parent_thread_id)——Yoda 的多 runtime 并行开工场景里,这是画"agent 拓扑图"的数据源。
  4. 跨 runtime 映射要克制:CC agent 定义 ≠ Codex 角色(前者是能力包,后者是配置层),一键转换只能搬 description + model 等浅层字段,tools 白名单在 Codex 侧没有对应物(其裁剪靠权限/沙箱),UI 上要明示损失。

失效条件

  • Codex 引入文件式 agent 定义(如 .codex/agents/*.md),声明式/命令式对比弱化
  • CC 开放子代理持续通信(Task 工具支持 send/resume 时"一次性返回"结论过期)
  • CC isolation: 'remote' 对外开放(当前 ant-only)
  • Codex multi_agents_v2 取代 v1(multi_agents_v2.rs 已在源码中,工具面可能重构)

参考资料

  • CC 源码:src_2026-03-31/tools/AgentTool/{loadAgentsDir.ts,runAgent.ts,builtInAgents.ts,built-in/}Task.tsutils/sessionStorage.ts(sidechain)
  • Codex 源码:codex/codex-rs/core/src/tools/handlers/{multi_agents_spec.rs,multi_agents.rs,agent_jobs.rs}config/src/config_toml.rs:659-703protocol/src/protocol.rs(ThreadSource/SessionSource)、collaboration-mode-templates/templates/
  • 文档:claude-code-docs/docs/sub-agents.mdagent-teams.mdagent-sdk__subagents.md
  • Yoda:yoda/src/renderer/features/projects/components/harness-view/harness-spec.ts

On this page