Files
2026-07-24 08:00:31 +08:00

14 KiB
Raw Permalink Blame History

调研发现

上游 Multi-agent V2

  • 本机 codex-cli 版本为 0.144.1。
  • codex features list 显示:multi_agent 已稳定且启用;multi_agent_v2 为 under development 且默认关闭;旧 collaboration_modes 已移除但配置值仍显示启用。
  • 因此 V2 目前应按实验性、显式开关能力看待,不能假设所有 app-server 客户端都自动获得新行为。
  • 本机二进制进一步暴露了 V2 的配置面:并发线程上限、等待超时上下限/默认值、用量提示、根/子代理提示文案、工具命名空间、隐藏 spawn_agent 元数据、仅非 code mode 启用,以及 custom / explicitRequestOnly / proactive 三种 multiAgentMode。
  • 二进制中的 app-server 类型仍沿用 CollabAgentToolCall 和 SubAgentActivity,并新增/保留 agentNickname、agentRole、agentPath、depth、parentThreadId 等代理身份与层级元数据。
  • 已从 OpenAI 官方 openai/codex 仓库的 rust-v0.144.1 标签对应提交 44918ea1 下载源码归档。V2 不是单一 UI 开关:涉及 feature config、上下文提示、agent control、独立的 multi_agents_v2 handlers、CSV 批量派工、app-server MultiAgentMode 协议字段及线程状态/通知。
  • V2 工具语义发生实质变化:spawn_agent 强制 task_name 并返回规范任务路径;默认继承全部历史,也可用 fork_turns=none|all|N;fork_context 在 V2 明确报错。
  • V1 的 send_input、resume_agent、close_agent 被 V2 的 send_message(不触发新 turn)、followup_task(触发/续跑 turn)、interrupt_agent(中断但保留代理)、list_agents 取代。
  • V2 wait_agent 不再接收目标列表,也不返回代理最终正文;它等待整个代理树的 mailbox 活动,用户 steer 也会提前唤醒。最终内容应经 mailbox/事件链消费。
  • V2 引入规范层级路径(如 /root/task1/task3)和嵌套代理树,可按路径前缀列举;这会把 cc-web 从“按 agent id 展示卡片”推进到“代理树 + mailbox 事件”模型。
  • MultiAgentMode 有 custom、explicitRequestOnly、proactive 三种策略,并作为 developer 上下文片段注入;默认 Ultra 推理会选 proactive,其余选 explicit-request-only(除非配置自定义提示)。
  • 另有 spawn_agents_on_csv 批量任务:按 CSV 每行派生 worker、并发执行、worker 用 report_agent_job_result 回报、最后导出结果 CSV。它是独立的批处理能力,不是基础聊天 UI 必须支持的协议。
  • app-server v2 schema 已出现 multiAgentMode,但 0.144.1 的 thread/start 处理器暂时把入参绑定为 _multi_agent_mode,并在 start/resume/fork 响应中固定回 explicitRequestOnly;还需确认 turn/start 是否才是当前有效入口。
  • 已确认 thread/start.multiAgentMode 与 turn/start.multiAgentMode 都在 0.144.1 源码中标为 deprecated/ignored,注释明确要求用 Ultra reasoning effort;因此 cc-web 不应实现新的 multiAgentMode 控件或依赖其返回值。
  • 相比 rust-v0.143.0,V2 工具 schema 基本未变,0.144.1 最重要的协议变化是事件标准化:wait_agent 从专用 collab_waiting_begin/end 改为 item/started + item/completed 的 collabAgentToolCall(tool=wait);spawn/message/interrupt 从专用 sub_agent_activity event 改为 completed subAgentActivity turn item。
  • 这意味着 cc-web 若只监听旧顶层 collab/sub-agent 通知会漏状态;若已有统一 item/started/item/completed 分发并识别这两种 item,则基本兼容。
  • 官方提交记录对应三项连续迁移:canonical sub-agent activity(#31299)、canonical collab tool call(#31300)、canonical collab wait(#31301);另有 Ultra + 高并发提示(#31621)。
  • OpenAI 最新稳定版实际已是 0.145.0(2026-07-21 发布),而非本机的 0.144.1。官方发布说明明确称“Stabilized the opt-in multi-agent V2 experience”,覆盖可配置子代理模型/推理等级/并发、角色恢复和代理导航,并在 #34383 将 V2 标记为 stable。
  • 0.145.0 同时包含:统一多代理设置到 agents(#33550)、遵循子代理模型默认值(#33631)、恢复 V2 agent roles(#33657)、父线程持有的子代理线程只读(#33841)、agent picker 存活性/路径选择(#33921/#33922),并移除了 CSV-backed agent jobs(#34413)。因此 0.144.1 的 spawn_agents_on_csv 不能作为最新稳定版能力建议。
  • 已获取 0.145.0 官方源码提交 25af12f7。V2 的核心工具仍是 spawn_agent / send_message / followup_task / interrupt_agent / list_agents / wait_agent,fork_turns 与 mailbox wait 语义保持不变;canonical subAgentActivity / collabAgentToolCall 事件路线也仍存在。
  • 0.145.0 新增 [agents] 统一配置,包含 enabled、最大线程数、最大嵌套深度、默认子代理模型、默认子代理推理强度、interrupt message 等;旧 features.multi_agent_v2 仍保留兼容配置和部分 UI/工具参数。
  • 精确配置语义:multi_agent_v2 在 0.145.0 为 stable 但 default_enabled=false;agents.enabled 默认 true 且旧 feature 开关优先。agents.max_depth 的 schema 明确写“V2 忽略”,所以 V2 的路径树不能按 V1 深度上限推断。
  • V2 的 spawn model / reasoning_effort 在 0.145.0 默认不暴露,只有 features.multi_agent_v2.expose_spawn_agent_model_overrides=true 才进入工具 schema;agent_type 也只有实际配置角色时才暴露。cc-web 不应在固定 developer instructions 中假设这些字段总可用。
  • 0.145.0 允许 full-history fork 叠加 model/reasoning override,只禁止 full-history 同时覆盖 agent_type;这再次证明 cc-web 当前硬编码的 fork_context/override 规则已经过时,最佳修复是让模型遵循运行时工具 schema,而不是在 cc-web 重述易漂移规则。
  • 0.145.0 新增 child terminal turn → direct parent 的标准 completion envelope,结果以不触发新 turn 的 inter-agent communication 写入父代理 mailbox。因此即使 cc-web 没抓到 child 的独立 app-server 通知,Codex 核心仍可让 wait_agent 唤醒并把结果交给父代理;服务端 child route 缺口应定级为“实时卡片/状态观测缺口”,不是核心代理结果丢失。
  • app-server v2 仍以 canonical TurnItem 生命周期为主,旧 SubAgentActivity 顶层 event 只保留给兼容/raw consumers。cc-web 当前使用 item/completed(subAgentActivity) 的方向正确。
  • 已将当前用户实际使用的 Codex 从 0.144.1 升级为 0.145.0,路径仍为 ~/.local/bin/codex;npm 包和 CLI 版本一致。升级后 multi_agent_v2 状态为 stable/false,未自动开启实验/opt-in 能力。
  • 升级后仍有两个 2026-07-02/07-18 启动的 app-server 子进程,其 /proc/<pid>/exe 指向已删除的旧安装目录;它们不会热切换到 0.145.0。当前 ccweb 只检测到本轮一个 running 对话,但本轮不重启服务,避免中断正在进行的会话。

cc-web 当前实现

  • codebase-memory 初始索引只含 10 个源码文件,漏掉 server.js 与 lib/codex-app-runtime.js;执行 full reindex 后节点数仍未变化。.cbmignore 并未排除这些源码,推测是索引器对超大 JS 文件的提取限制。本轮对未索引文件按仓库规则降级到 rg/定点源码读取。
  • 前端 public/app.js 已识别 subAgentActivity,并把它归并到 collab_agent_tool_call 子代理卡片;回归脚本覆盖 agentPath、agentThreadId、role、taskDescription、各 activity kind 与普通工具防误判。
  • 后端 lib/codex-app-runtime.js 已明确处理 item/started、item/completed、collabAgentToolCall、subAgentActivity,并保留 started→completed 的输入合并与持久化。
  • server.js 已有 canonical item lifecycle 路由和 collab 状态归并;说明 0.144.1 最关键的事件迁移在 cc-web 中已有针对性实现与回归。
  • lib/codex-app-runtime.js 的 lifecycle 处理可兼容 V2:item/started 建立工具项,item/completed 合并并结束;subAgentActivity 会把 agentPath/agentThreadId/prompt/role 规范化成子代理卡片状态,V2 wait 的 collabAgentToolCall 也走统一路径。
  • 明确缺口: CODEX_APP_COLLABORATION_INSTRUCTIONS 仍注入 V1 规则:要求使用/推断 fork_context,并要求 wait_agent 持续等待“最终状态”。V2 会拒绝 fork_context,且 wait 只报告 mailbox 活动、不返回最终正文。这些开发者指令会直接诱导 V2 工具调用失败或空转等待,应优先改为版本中立/V2 兼容指令。
  • codexAppCollabToolName 与 collab fallback 仍主要识别 V1 动作(spawn/wait/send_input/resume/close),未显式识别 V2 的 send_message、followup_task、interrupt_agent、list_agents。其中 send_message 被折叠为 send_input,其余需评估对历史恢复和状态归并的影响。
  • 明确缺口:Ultra 被 cc-web 丢弃。 上游 V2 用 ReasoningEffort::Ultra 触发 proactive,但 server.js 的允许集合、Codex App 模型字符串解析、lib/agent-runtime.js 的 CLI 参数解析,以及前端推理强度选项都只到 xhigh。即使 ~/.codex/config.toml 配置 model_reasoning_effort = "ultra",cc-web 也不会把它编码进 session model/turn collaboration settings。
  • mock/regression 目前反而断言了旧的“重复 wait_agent 直到 final”指导,说明修复 V2 指令时必须同步调整 mock 摘要与回归断言,避免测试把旧语义锁死。
  • 明确缺口:V2 spawn 的 child thread 未进入服务端路由表。 handleCodexAppNotification 只对 collabAgentToolCall 调 syncCcwebMcpChildAgentsFromCollabItem;0.144.1 V2 spawn 发的是 completed subAgentActivity。runtime/前端虽能画卡片,但 ccwebMcpChildThreads 没有登记该 child,随后 child 自己的 agentMessage/turn 通知会成为 unrouted,实时最终消息与状态无法可靠回填。
  • 现有 mock 的多代理场景仍模拟 V1 collabAgentToolCall(tool=spawn_agent) 后再发 child turn;没有模拟“parent 收到 V2 subAgentActivity → 注册 child → 路由 child turn”的真实链路。因此当前回归通过不能证明 V2 live routing 完整。
  • 嵌套代理树也未覆盖。 即便 child 已被登记,processCcwebMcpChildNotification 只处理其 agentMessage 与 turn 生命周期,不处理 child 发出的 subAgentActivity;V2 grandchild 的创建/消息会被忽略。基础一层代理修复应为 P0,完整嵌套树可作为 P1。
  • recoverCcwebMcpChildThreadsFromPersistedToolCalls 能从已持久化的 subAgentActivity 恢复 child map,但只在 cc-web 启动时的残留 turn 恢复路径调用;它不能弥补当前活跃 turn 中 V2 child 的即时注册缺口。
  • V2 SubAgentActivityItem 本身不含原始 task prompt,cc-web 目前只能用 agentPath basename 生成标题;若要保留任务描述,需要额外关联同 call id 的 spawn 请求或接受“仅路径标题”的降级。这属于体验优化,不是协议阻断。
  • 本机 ~/.codex/config.toml 当前模型为 gpt-5.6-sol、推理强度 xhigh,且未配置 multi_agent_v2;结合 codex features list 可确认当前 V2 实际未启用。因此这些缺口目前不会破坏现有 V1 会话,但会阻断/削弱未来显式启用 V2。

差距与建议

P0:启用 V2 前必须跟进

  1. Ultra 全链路:CODEX_REASONING_LEVELS、Codex/Codex App 模型字符串解析、CLI model_reasoning_effort 参数、前端 Thinking picker 和回归用例全部加入 ultra。
  2. 删除 V1 字段级 developer instructions:不再注入 fork_context 和“wait 直到 final”的规则;仅保留 cc-web 自有 title 规则,并要求遵循当前运行时工具 schema/描述。

P1:建议同步完成

  1. parent 收到 subAgentActivity(kind=started) 时登记 child thread,随后能路由 child 的 agentMessage/turn 通知并回填实时卡片;同一路径递归处理 child 发出的 grandchild activity。
  2. mock 改成真实 V2 序列:completed-only subAgentActivity、空 receiver 的 wait item、child completion/mailbox、嵌套路径;保留 V1 用例做双栈回归。
  3. UI 的“关闭”在 V2 中实际只是 interrupt,不能伪装成销毁;应调整文案/状态或明确隐藏与可恢复语义。代理展示应保留 canonical task path,避免只取 basename 后同名冲突。

无需跟进

  • 不新增 multiAgentMode 控件:0.145.0 仍标记 deprecated/ignored,proactive 由 Ultra 驱动。
  • 不做 CSV fanout UI:spawn_agents_on_csv 已从 0.145.0 移除。
  • 不默认强开 multi_agent_v2:它虽 stable 但仍 opt-in/default false;应继续尊重用户 Codex 配置。
  • [agents] 配置由 Codex app-server 直接读取,cc-web 暂无需复制一套配置管理 UI。

已兼容

  • canonical item/started / item/completed 分发。
  • collabAgentToolCall 与 subAgentActivity 的 runtime/前端归并和基础卡片渲染。
  • app-server collaborationMode.settings 的 model/reasoning/developer_instructions 形状及线程级 MCP 注入。

实施结果

  • Ultra 已贯通本地 Codex 配置、会话模型字符串、Codex CLI model_reasoning_effort、Codex App collaborationMode.settings.reasoning_effort 与前端 Thinking picker。
  • 固定注入的 V1 fork_context / 重复 wait_agent 指导已删除,改为只要求遵循当前 runtime tool schema 与工具描述。
  • 服务端会从父级或任意已登记 child 的 subAgentActivity 递归登记子线程,保留直接 parentThreadId、spawnToolId、canonical agentPath 与任务描述。
  • 子代理操作与状态改为“中断 / 已中断”,保留后续 turn 恢复可能;前端卡片 tooltip/footer 展示 canonical path,避免同名 basename 混淆。
  • mock 同时保留 V1 collabAgentToolCall(spawn_agent) 序列,并新增 V2 completed-only activity、child→grandchild、空 receiver wait 与终态回填序列。
  • 静态检查、定向 subagent 回归和完整 npm run regression 均通过;multi_agent_v2 仍保持 opt-in/default false,未由 cc-web 强制开启。