第 37 讲:多智能体 Spawn 与角色系统——槽位预留、LRU 驱逐与上下文过滤

Codex 源码解析 · 第 37 讲

Codex 源码解析系列 第 37 讲:多智能体 Spawn 与角色系统——槽位预留、LRU 驱逐与上下文过滤 基于 OpenAI Codex 源码 · 2026-10-31 💡 本讲一句话: Codex 的多智能体不是"无脑 fork 线程"——每次 spawn 都要过四道闸门:容量检查(V2 还会 LRU 驱逐最闲的子代理腾位置)、RAII 槽位预留(失败自动回滚)、角色降权(子代理只能比父会话更弱、不能更强)、上下文过滤(fork 时把父级的审批证据和用量提示全部洗掉)。读完你能说清一个子代理从出生到被驱逐的完整生命周期。 一、spawn_agent_internal:一次派生的完整流水线 多智能体系统的入口在 core/src/agent/control/spawn.rs (全文件 1324 行)。三个公开入口 spawn_agent / spawn_agent_with_metadata / spawn_agent_with_communication 最终都汇入同一个私有函数 spawn_agent_internal 。它做的事比"创建线程"多得多:先定版本、再查容量、预留槽位、继承环境、准备元数据、建线程、投递初始输入——任何一步失败,RAII 保证已占的资源自动归还: 📄 codex-rs/core/src/agent/control/spawn.rs (第 614-730 行) async fn spawn_agent_internal( // 所有派生入口的汇聚点:一次子代理出生要过的全部闸门都在这里 &self, // AgentControl 控制面句柄,容量/预留/通知都挂在它上面 config: Config, // 父会话配置:容量上限、角色、feature flag 都从这里取 initial_input: SpawnInitialInput, // 初始输入二选一:用户 prompt,或 agent 间通信消息(V2) session_source: Option<SessionSource>, // 会话来源:ThreadSpawn 才走子代理分支,None 表示普通新线程 options: SpawnAgentOptions, // 可选参数:fork 模式、父 turn id、环境选择等 ) -> CodexResult<LiveAgent> { // 返回 LiveAgent(thread_id + 元数据 + 状态),失败走 CodexErr let state = self.upgrade()?; // 弱引用升级成强引用,thread manager 已销毁就直接报错退出 let multi_agent_version = state // 先定版本:V1/V2/Disabled 决定后面走哪套容量与通知机制 .effective_multi_agent_version_for_spawn( // 综合配置、父线程、fork 来源解析出实际生效的版本 &InitialHistory::New, // 新派生(非 resume),历史基线为空 session_source.as_ref(), // 传入会话来源,SubAgent 才可能触发 V2 常驻逻辑 options.parent_thread_id, // 父线程 id:用于判断父级是否分页历史模式 /*forked_from_thread_id*/ None, // fork 场景由 spawn_forked_thread 单独处理,这里传空 &config, // 配置里带 multi_agent_version_override / feature flag ) // 方法调用结束 .await; // 异步解析版本(可能读父线程状态) if let Some(session_source) = session_source.as_ref() { // 只有子代理来源才需要执行容量硬检查 self.ensure_execution_capacity(multi_agent_version, session_source)?; // V2 子代理超限直接 AgentLimitReached,fail loud } // 普通线程…

阅读全文:Codex 源码解析 第 37 讲