<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Codex on DK Blog</title><link>/tags/codex/</link><description>Recent content in Codex on DK Blog</description><generator>Hugo -- gohugo.io</generator><language>zh-CN</language><lastBuildDate>Thu, 25 Jun 2026 20:20:00 +0800</lastBuildDate><atom:link href="/tags/codex/index.xml" rel="self" type="application/rss+xml"/><item><title>Codex 的 Main Agent 和 Subagent 是怎么通信的</title><link>/dkblog/037-codex-main-agent-subagent-communication/</link><pubDate>Thu, 25 Jun 2026 19:20:00 +0800</pubDate><guid>/dkblog/037-codex-main-agent-subagent-communication/</guid><description>&lt;img src="/dkblog/assets/ai/codex-main-agent-subagent-flow.svg" alt="Featured image of post Codex 的 Main Agent 和 Subagent 是怎么通信的" /&gt;&lt;p&gt;很多人第一次看 Codex 的多 agent 机制时，会下意识把 subagent 理解成 “main agent 调了一个内部函数”。这个理解不对。&lt;/p&gt;
&lt;p&gt;在 Codex 里，subagent 更接近于：主线程之外又开了一个独立聊天线程。它有自己的 thread id、上下文、工具调用过程、执行状态和 mailbox。main agent 和 subagent 不共享完整上下文，它们靠 Codex runtime 转发内部消息协作。&lt;/p&gt;
&lt;p&gt;这篇文章不讲 Rust 语法，只讲一条闭环：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt" id="hl-0-1"&gt;&lt;a class="lnlinks" href="#hl-0-1"&gt;1&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-0-2"&gt;&lt;a class="lnlinks" href="#hl-0-2"&gt;2&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-0-3"&gt;&lt;a class="lnlinks" href="#hl-0-3"&gt;3&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-0-4"&gt;&lt;a class="lnlinks" href="#hl-0-4"&gt;4&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-0-5"&gt;&lt;a class="lnlinks" href="#hl-0-5"&gt;5&lt;/a&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;main agent 怎么派任务
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;-&amp;gt; runtime 怎么投递消息
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;-&amp;gt; subagent 怎么独立执行
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;-&amp;gt; 结果怎么回到 main agent
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;-&amp;gt; main agent 怎么继续往下走
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;先看总览图：&lt;/p&gt;
&lt;p&gt;&lt;img alt="Codex main agent 与 subagent 通信总览图" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="/dkblog/assets/ai/codex-main-agent-subagent-flow.svg"&gt;&lt;/p&gt;
&lt;h2 id="先记住一个模型"&gt;&lt;a href="#%e5%85%88%e8%ae%b0%e4%bd%8f%e4%b8%80%e4%b8%aa%e6%a8%a1%e5%9e%8b" class="header-anchor"&gt;&lt;/a&gt;先记住一个模型
&lt;/h2&gt;&lt;p&gt;可以先把 Codex 的 subagent 理解成下面这个结构：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt" id="hl-1-1"&gt;&lt;a class="lnlinks" href="#hl-1-1"&gt;1&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-1-2"&gt;&lt;a class="lnlinks" href="#hl-1-2"&gt;2&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-1-3"&gt;&lt;a class="lnlinks" href="#hl-1-3"&gt;3&lt;/a&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;main agent 所在主聊天线程
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 另外开了一个独立聊天线程
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 这个独立线程就是 subagent
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;所以 subagent 不是 main agent 内部的一个函数。它有自己的：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;thread id&lt;/li&gt;
&lt;li&gt;上下文&lt;/li&gt;
&lt;li&gt;工具调用过程&lt;/li&gt;
&lt;li&gt;执行状态&lt;/li&gt;
&lt;li&gt;mailbox&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这件事决定了 main agent 和 subagent 的关系不是同步函数调用，而是多个独立线程之间通过内部信件协作。&lt;/p&gt;
&lt;h2 id="先看通信闭环"&gt;&lt;a href="#%e5%85%88%e7%9c%8b%e9%80%9a%e4%bf%a1%e9%97%ad%e7%8e%af" class="header-anchor"&gt;&lt;/a&gt;先看通信闭环
&lt;/h2&gt;&lt;p&gt;main agent 能控制 subagent 的方式，不是直接读写它的内存，而是调用一组协作工具：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt" id="hl-2-1"&gt;&lt;a class="lnlinks" href="#hl-2-1"&gt;1&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-2-2"&gt;&lt;a class="lnlinks" href="#hl-2-2"&gt;2&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-2-3"&gt;&lt;a class="lnlinks" href="#hl-2-3"&gt;3&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-2-4"&gt;&lt;a class="lnlinks" href="#hl-2-4"&gt;4&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-2-5"&gt;&lt;a class="lnlinks" href="#hl-2-5"&gt;5&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-2-6"&gt;&lt;a class="lnlinks" href="#hl-2-6"&gt;6&lt;/a&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;spawn_agent 创建子 agent，并给第一条任务
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;send_message 给已有 agent 发消息，但不强制它马上跑
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;followup_task 给已有 agent 发后续任务，并在空闲时触发它继续跑
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;wait_agent 等待有 agent 消息或状态变化
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;interrupt_agent 打断某个 agent 当前执行
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;list_agents 查看当前有哪些 agent
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这些工具本质上都是 function call。模型输出 function call，Codex runtime 收到后执行内部逻辑。&lt;/p&gt;
&lt;p&gt;把完整流程压成一条主链路，大致就是：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt" id="hl-3-1"&gt;&lt;a class="lnlinks" href="#hl-3-1"&gt; 1&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-3-2"&gt;&lt;a class="lnlinks" href="#hl-3-2"&gt; 2&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-3-3"&gt;&lt;a class="lnlinks" href="#hl-3-3"&gt; 3&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-3-4"&gt;&lt;a class="lnlinks" href="#hl-3-4"&gt; 4&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-3-5"&gt;&lt;a class="lnlinks" href="#hl-3-5"&gt; 5&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-3-6"&gt;&lt;a class="lnlinks" href="#hl-3-6"&gt; 6&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-3-7"&gt;&lt;a class="lnlinks" href="#hl-3-7"&gt; 7&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-3-8"&gt;&lt;a class="lnlinks" href="#hl-3-8"&gt; 8&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-3-9"&gt;&lt;a class="lnlinks" href="#hl-3-9"&gt; 9&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-3-10"&gt;&lt;a class="lnlinks" href="#hl-3-10"&gt;10&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-3-11"&gt;&lt;a class="lnlinks" href="#hl-3-11"&gt;11&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-3-12"&gt;&lt;a class="lnlinks" href="#hl-3-12"&gt;12&lt;/a&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;用户提问
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -&amp;gt; main agent 决定拆任务
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -&amp;gt; main agent 调 spawn_agent
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -&amp;gt; runtime 创建 child thread
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -&amp;gt; 第一条任务进入 child thread
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -&amp;gt; child agent 独立执行
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -&amp;gt; main agent 调 wait_agent
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -&amp;gt; child agent 调 send_message(target=root)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -&amp;gt; root mailbox 收到结果
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -&amp;gt; wait_agent 被唤醒
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -&amp;gt; main agent 下一轮读到这条消息
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -&amp;gt; main agent 汇总后回答用户
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这里最重要的三点是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;subagent&lt;/code&gt; 是真的独立 thread，不是内部函数。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;send_message&lt;/code&gt; 和 &lt;code&gt;followup_task&lt;/code&gt; 都是在投递内部消息，只是后者会顺带触发目标 agent 开始下一轮执行。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;wait_agent&lt;/code&gt; 等的是 mailbox 活动，不是同步拿子函数返回值。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;例如 main agent 创建 subagent 时，可能只是发出这样一个调用：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt" id="hl-4-1"&gt;&lt;a class="lnlinks" href="#hl-4-1"&gt;1&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-4-2"&gt;&lt;a class="lnlinks" href="#hl-4-2"&gt;2&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-4-3"&gt;&lt;a class="lnlinks" href="#hl-4-3"&gt;3&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-4-4"&gt;&lt;a class="lnlinks" href="#hl-4-4"&gt;4&lt;/a&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;spawn_agent({
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; task_name: &amp;#34;research&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; message: &amp;#34;你去分析 app-server 里的 subagent 通信逻辑&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;})
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;但 runtime 真正做的是：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt" id="hl-5-1"&gt;&lt;a class="lnlinks" href="#hl-5-1"&gt;1&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-5-2"&gt;&lt;a class="lnlinks" href="#hl-5-2"&gt;2&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-5-3"&gt;&lt;a class="lnlinks" href="#hl-5-3"&gt;3&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-5-4"&gt;&lt;a class="lnlinks" href="#hl-5-4"&gt;4&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-5-5"&gt;&lt;a class="lnlinks" href="#hl-5-5"&gt;5&lt;/a&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;创建 child thread
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;记录 parent_thread_id
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;记录 task_name
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;投递第一条任务
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;启动 child agent 独立执行
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;而 subagent 回结果时，走的也不是“返回值”，而是再发一封内部信：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt" id="hl-6-1"&gt;&lt;a class="lnlinks" href="#hl-6-1"&gt;1&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-6-2"&gt;&lt;a class="lnlinks" href="#hl-6-2"&gt;2&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-6-3"&gt;&lt;a class="lnlinks" href="#hl-6-3"&gt;3&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-6-4"&gt;&lt;a class="lnlinks" href="#hl-6-4"&gt;4&lt;/a&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;send_message({
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; target: &amp;#34;root&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; message: &amp;#34;我查完了。结论是：Codex 通过 InterAgentCommunication 和 mailbox 通信。&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;})
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;所以从运行时视角看，Codex 的多 agent 更像：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt" id="hl-7-1"&gt;&lt;a class="lnlinks" href="#hl-7-1"&gt;1&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-7-2"&gt;&lt;a class="lnlinks" href="#hl-7-2"&gt;2&lt;/a&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;多个独立聊天线程
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 通过 runtime 维护的内部邮箱互相发消息
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="wait_agent-为什么经常被误解"&gt;&lt;a href="#wait_agent-%e4%b8%ba%e4%bb%80%e4%b9%88%e7%bb%8f%e5%b8%b8%e8%a2%ab%e8%af%af%e8%a7%a3" class="header-anchor"&gt;&lt;/a&gt;wait_agent 为什么经常被误解
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;wait_agent&lt;/code&gt; 最容易被误解成“同步等待 subagent 返回值”，其实它更像：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt" id="hl-8-1"&gt;&lt;a class="lnlinks" href="#hl-8-1"&gt;1&lt;/a&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;main agent 暂停一下，等 mailbox 有没有新消息
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;比如：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt" id="hl-9-1"&gt;&lt;a class="lnlinks" href="#hl-9-1"&gt;1&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-9-2"&gt;&lt;a class="lnlinks" href="#hl-9-2"&gt;2&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-9-3"&gt;&lt;a class="lnlinks" href="#hl-9-3"&gt;3&lt;/a&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;wait_agent({
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; timeout_ms: 30000
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;})
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;它的意思是：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt" id="hl-10-1"&gt;&lt;a class="lnlinks" href="#hl-10-1"&gt;1&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-10-2"&gt;&lt;a class="lnlinks" href="#hl-10-2"&gt;2&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-10-3"&gt;&lt;a class="lnlinks" href="#hl-10-3"&gt;3&lt;/a&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;最多等 30 秒
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;如果收到 agent 消息或相关活动，就返回
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;如果 30 秒没有，就返回 timed_out
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;超时返回类似：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt" id="hl-11-1"&gt;&lt;a class="lnlinks" href="#hl-11-1"&gt;1&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-11-2"&gt;&lt;a class="lnlinks" href="#hl-11-2"&gt;2&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-11-3"&gt;&lt;a class="lnlinks" href="#hl-11-3"&gt;3&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-11-4"&gt;&lt;a class="lnlinks" href="#hl-11-4"&gt;4&lt;/a&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;message&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Wait timed out.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;timed_out&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这里一定要分清：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt" id="hl-12-1"&gt;&lt;a class="lnlinks" href="#hl-12-1"&gt;1&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-12-2"&gt;&lt;a class="lnlinks" href="#hl-12-2"&gt;2&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-12-3"&gt;&lt;a class="lnlinks" href="#hl-12-3"&gt;3&lt;/a&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;wait_agent 超时
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;!=
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;subagent 被杀掉
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;子 agent 可能还在继续跑。runtime 不会自动替 main agent 做决策，它不会自动：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;kill 子 agent&lt;/li&gt;
&lt;li&gt;interrupt 子 agent&lt;/li&gt;
&lt;li&gt;判定子 agent 失败&lt;/li&gt;
&lt;li&gt;自动重派任务&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;它只是把 &lt;code&gt;timed_out=true&lt;/code&gt; 交还给 main agent。接下来 main agent 自己决定下一步：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt" id="hl-13-1"&gt;&lt;a class="lnlinks" href="#hl-13-1"&gt; 1&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-13-2"&gt;&lt;a class="lnlinks" href="#hl-13-2"&gt; 2&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-13-3"&gt;&lt;a class="lnlinks" href="#hl-13-3"&gt; 3&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-13-4"&gt;&lt;a class="lnlinks" href="#hl-13-4"&gt; 4&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-13-5"&gt;&lt;a class="lnlinks" href="#hl-13-5"&gt; 5&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-13-6"&gt;&lt;a class="lnlinks" href="#hl-13-6"&gt; 6&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-13-7"&gt;&lt;a class="lnlinks" href="#hl-13-7"&gt; 7&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-13-8"&gt;&lt;a class="lnlinks" href="#hl-13-8"&gt; 8&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-13-9"&gt;&lt;a class="lnlinks" href="#hl-13-9"&gt; 9&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-13-10"&gt;&lt;a class="lnlinks" href="#hl-13-10"&gt;10&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-13-11"&gt;&lt;a class="lnlinks" href="#hl-13-11"&gt;11&lt;/a&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;继续等:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; wait_agent({ timeout_ms: 30000 })
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;打断:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; interrupt_agent({ target: &amp;#34;research&amp;#34; })
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;催促:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; followup_task({ target: &amp;#34;research&amp;#34;, message: &amp;#34;收敛一下，直接给结论&amp;#34; })
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;先回答用户:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 基于已有信息组织答案
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;所以 main agent 在这套机制里，本质上更像调度者。&lt;/p&gt;
&lt;h2 id="这条闭环在源码里怎么落地"&gt;&lt;a href="#%e8%bf%99%e6%9d%a1%e9%97%ad%e7%8e%af%e5%9c%a8%e6%ba%90%e7%a0%81%e9%87%8c%e6%80%8e%e4%b9%88%e8%90%bd%e5%9c%b0" class="header-anchor"&gt;&lt;/a&gt;这条闭环在源码里怎么落地
&lt;/h2&gt;&lt;p&gt;如果只看一张源码总览图，可以先记住这条链：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt" id="hl-14-1"&gt;&lt;a class="lnlinks" href="#hl-14-1"&gt;1&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-14-2"&gt;&lt;a class="lnlinks" href="#hl-14-2"&gt;2&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-14-3"&gt;&lt;a class="lnlinks" href="#hl-14-3"&gt;3&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-14-4"&gt;&lt;a class="lnlinks" href="#hl-14-4"&gt;4&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-14-5"&gt;&lt;a class="lnlinks" href="#hl-14-5"&gt;5&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-14-6"&gt;&lt;a class="lnlinks" href="#hl-14-6"&gt;6&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-14-7"&gt;&lt;a class="lnlinks" href="#hl-14-7"&gt;7&lt;/a&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;模型看到工具定义
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -&amp;gt; 模型发起 function call
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -&amp;gt; tool handler 接住 function call
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -&amp;gt; AgentControl 负责创建 / 发消息 / 等待 / 中断
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -&amp;gt; session handlers 和 InputQueue 负责 mailbox
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -&amp;gt; turn loop 把 mailbox 消息放进模型上下文
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -&amp;gt; app-server / TUI 把事件展示给客户端
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;按这个链路往下看，源码可以分成 6 个位置。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第一层：工具暴露给模型&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;文件：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt" id="hl-15-1"&gt;&lt;a class="lnlinks" href="#hl-15-1"&gt;1&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-15-2"&gt;&lt;a class="lnlinks" href="#hl-15-2"&gt;2&lt;/a&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;codex-rs/core/src/tools/spec_plan.rs
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;codex-rs/core/src/tools/handlers/multi_agents_spec.rs
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这里分别负责两件事：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;spec_plan.rs&lt;/code&gt; 决定当前 turn 要不要把多 agent 工具暴露给模型&lt;/li&gt;
&lt;li&gt;&lt;code&gt;multi_agents_spec.rs&lt;/code&gt; 定义这些 function call 的参数 schema&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;也就是说，main agent 能不能调用 &lt;code&gt;spawn_agent&lt;/code&gt;、&lt;code&gt;send_message&lt;/code&gt;、&lt;code&gt;wait_agent&lt;/code&gt;，第一步先看这里。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第二层：main agent 的控制入口&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;文件：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt" id="hl-16-1"&gt;&lt;a class="lnlinks" href="#hl-16-1"&gt;1&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-16-2"&gt;&lt;a class="lnlinks" href="#hl-16-2"&gt;2&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-16-3"&gt;&lt;a class="lnlinks" href="#hl-16-3"&gt;3&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-16-4"&gt;&lt;a class="lnlinks" href="#hl-16-4"&gt;4&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-16-5"&gt;&lt;a class="lnlinks" href="#hl-16-5"&gt;5&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-16-6"&gt;&lt;a class="lnlinks" href="#hl-16-6"&gt;6&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-16-7"&gt;&lt;a class="lnlinks" href="#hl-16-7"&gt;7&lt;/a&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;codex-rs/core/src/tools/handlers/multi_agents_v2/spawn.rs
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;codex-rs/core/src/tools/handlers/multi_agents_v2/message_tool.rs
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;codex-rs/core/src/tools/handlers/multi_agents_v2/wait.rs
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;codex-rs/core/src/tools/handlers/multi_agents_v2/interrupt_agent.rs
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;codex-rs/core/src/agent/control.rs
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;codex-rs/core/src/agent/control/spawn.rs
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;codex-rs/core/src/agent/registry.rs
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这层可以理解成 “main agent 的控制台”：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;spawn.rs&lt;/code&gt; 负责接住 &lt;code&gt;spawn_agent&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;message_tool.rs&lt;/code&gt; 负责接住 &lt;code&gt;send_message&lt;/code&gt; 和 &lt;code&gt;followup_task&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;wait.rs&lt;/code&gt; 负责 &lt;code&gt;wait_agent&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;interrupt_agent.rs&lt;/code&gt; 负责打断入口&lt;/li&gt;
&lt;li&gt;&lt;code&gt;AgentControl&lt;/code&gt; 是统一控制中心&lt;/li&gt;
&lt;li&gt;&lt;code&gt;spawn_agent_internal(...)&lt;/code&gt; 真正创建 child thread&lt;/li&gt;
&lt;li&gt;&lt;code&gt;AgentRegistry&lt;/code&gt; 记住有哪些 agent、各自的 thread id 和 path&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所以“main agent 怎么找到 subagent、怎么把任务发过去”，主要都在这层。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第三层：内部消息的数据结构&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;文件：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt" id="hl-17-1"&gt;&lt;a class="lnlinks" href="#hl-17-1"&gt;1&lt;/a&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;codex-rs/protocol/src/protocol.rs
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;关键结构：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt" id="hl-18-1"&gt;&lt;a class="lnlinks" href="#hl-18-1"&gt;1&lt;/a&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;InterAgentCommunication
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;它可以直接理解成一封内部信，里面最关键的是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;author&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;recipient&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;content&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;trigger_turn&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;例如：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt" id="hl-19-1"&gt;&lt;a class="lnlinks" href="#hl-19-1"&gt;1&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-19-2"&gt;&lt;a class="lnlinks" href="#hl-19-2"&gt;2&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-19-3"&gt;&lt;a class="lnlinks" href="#hl-19-3"&gt;3&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-19-4"&gt;&lt;a class="lnlinks" href="#hl-19-4"&gt;4&lt;/a&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;from: root
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;to: research
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;content: 继续查一下 thread_history.rs
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;trigger_turn: true
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;第四层：消息如何进入 mailbox&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;文件：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt" id="hl-20-1"&gt;&lt;a class="lnlinks" href="#hl-20-1"&gt;1&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-20-2"&gt;&lt;a class="lnlinks" href="#hl-20-2"&gt;2&lt;/a&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;codex-rs/core/src/session/handlers.rs
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;codex-rs/core/src/session/input_queue.rs
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这里是真正的 mailbox 落点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;handlers.rs&lt;/code&gt; 里的 &lt;code&gt;inter_agent_communication(...)&lt;/code&gt; 收到 &lt;code&gt;Op::InterAgentCommunication&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;input_queue.rs&lt;/code&gt; 里的 &lt;code&gt;enqueue_mailbox_communication(...)&lt;/code&gt; 把消息放进 mailbox&lt;/li&gt;
&lt;li&gt;如果 &lt;code&gt;trigger_turn=true&lt;/code&gt;，runtime 会尝试启动目标 agent 的新一轮 turn&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所以 &lt;code&gt;send_message&lt;/code&gt; 和 &lt;code&gt;followup_task&lt;/code&gt; 的本质区别，就落在 &lt;code&gt;trigger_turn&lt;/code&gt; 上。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第五层：mailbox 怎么进入模型上下文&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;文件：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt" id="hl-21-1"&gt;&lt;a class="lnlinks" href="#hl-21-1"&gt;1&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-21-2"&gt;&lt;a class="lnlinks" href="#hl-21-2"&gt;2&lt;/a&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;codex-rs/core/src/session/turn.rs
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;codex-rs/core/src/session/mod.rs
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这里负责两件事：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;turn.rs&lt;/code&gt; 在每轮请求模型前，从 &lt;code&gt;InputQueue&lt;/code&gt; 取 pending input&lt;/li&gt;
&lt;li&gt;&lt;code&gt;mod.rs&lt;/code&gt; 里的 &lt;code&gt;record_inter_agent_communication(...)&lt;/code&gt; 把消息写进历史和 rollout&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;也就是说，agent 间消息不只是内存里短暂经过，它还会：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;进入下一轮模型上下文&lt;/li&gt;
&lt;li&gt;写入会话历史&lt;/li&gt;
&lt;li&gt;被客户端看到&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;第六层：状态和展示&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;文件：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt" id="hl-22-1"&gt;&lt;a class="lnlinks" href="#hl-22-1"&gt;1&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-22-2"&gt;&lt;a class="lnlinks" href="#hl-22-2"&gt;2&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-22-3"&gt;&lt;a class="lnlinks" href="#hl-22-3"&gt;3&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-22-4"&gt;&lt;a class="lnlinks" href="#hl-22-4"&gt;4&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-22-5"&gt;&lt;a class="lnlinks" href="#hl-22-5"&gt;5&lt;/a&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;codex-rs/core/src/agent/status.rs
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;codex-rs/app-server-protocol/src/protocol/thread_history.rs
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;codex-rs/tui/src/app/loaded_threads.rs
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;codex-rs/tui/src/app/agent_navigation.rs
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;codex-rs/tui/src/app/thread_routing.rs
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这层负责把运行中的事实变成用户能看到的东西：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;status.rs&lt;/code&gt; 把事件映射成 &lt;code&gt;Running&lt;/code&gt;、&lt;code&gt;Completed&lt;/code&gt;、&lt;code&gt;Errored&lt;/code&gt; 等状态&lt;/li&gt;
&lt;li&gt;&lt;code&gt;thread_history.rs&lt;/code&gt; 把协作事件转成客户端能展示的 &lt;code&gt;ThreadItem&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;TUI 相关文件负责找出主线程下有哪些 subagent，以及怎么在界面里切换和缓存它们&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所以你在 app-server 或 TUI 里看到的“创建了哪个 agent”“谁给谁发了消息”“wait 有没有超时”，最终都依赖这层映射和展示。&lt;/p&gt;
&lt;h2 id="最短源码定位表"&gt;&lt;a href="#%e6%9c%80%e7%9f%ad%e6%ba%90%e7%a0%81%e5%ae%9a%e4%bd%8d%e8%a1%a8" class="header-anchor"&gt;&lt;/a&gt;最短源码定位表
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;你想看什么&lt;/th&gt;
					&lt;th&gt;看哪个文件&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;工具怎么暴露给模型&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;codex-rs/core/src/tools/spec_plan.rs&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;function call 参数怎么定义&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;codex-rs/core/src/tools/handlers/multi_agents_spec.rs&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;spawn_agent&lt;/code&gt; 入口&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;codex-rs/core/src/tools/handlers/multi_agents_v2/spawn.rs&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;创建 child thread&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;codex-rs/core/src/agent/control/spawn.rs&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;main 如何控制 agent&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;codex-rs/core/src/agent/control.rs&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;agent 列表和 metadata&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;codex-rs/core/src/agent/registry.rs&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;send_message&lt;/code&gt; / &lt;code&gt;followup_task&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;codex-rs/core/src/tools/handlers/multi_agents_v2/message_tool.rs&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;内部信件结构&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;codex-rs/protocol/src/protocol.rs&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;mailbox 队列&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;codex-rs/core/src/session/input_queue.rs&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;mailbox 进入模型上下文&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;codex-rs/core/src/session/turn.rs&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;通信记录进历史&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;codex-rs/core/src/session/mod.rs&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;wait_agent&lt;/code&gt; 超时逻辑&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;codex-rs/core/src/tools/handlers/multi_agents_v2/wait.rs&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;agent 状态&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;codex-rs/core/src/agent/status.rs&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;app-server 展示&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;codex-rs/app-server-protocol/src/protocol/thread_history.rs&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;TUI subagent 导航&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;codex-rs/tui/src/app/agent_navigation.rs&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="最后收一句"&gt;&lt;a href="#%e6%9c%80%e5%90%8e%e6%94%b6%e4%b8%80%e5%8f%a5" class="header-anchor"&gt;&lt;/a&gt;最后收一句
&lt;/h2&gt;&lt;p&gt;如果只记一句话，我建议记这句：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt" id="hl-23-1"&gt;&lt;a class="lnlinks" href="#hl-23-1"&gt;1&lt;/a&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Codex 的 main agent 和 subagent 不是同步函数调用，而是多个独立 thread 通过 runtime 维护的 mailbox 互相发消息
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;从原理上看，这是一个“多线程聊天 + 内部邮箱”的协作模型；从源码上看，这条链路则落在 tool handler、AgentControl、session mailbox、turn loop、app-server 和 TUI 几层里，刚好首尾闭环。&lt;/p&gt;</description></item><item><title>Multica 初体验：把 Codex、Claude Code 这类 coding agent 当成队友来管理</title><link>/dkblog/022-multica-coding-agent-workspace/</link><pubDate>Thu, 28 May 2026 22:16:00 +0800</pubDate><guid>/dkblog/022-multica-coding-agent-workspace/</guid><description>&lt;img src="https://images.unsplash.com/photo-1515879218367-8466d910aaa4?auto=format&amp;fit=crop&amp;w=900&amp;q=60" alt="Featured image of post Multica 初体验：把 Codex、Claude Code 这类 coding agent 当成队友来管理" /&gt;&lt;p&gt;最近看了一下 Multica，感觉它解决的不是“让 AI 写代码”这个问题，而是另一个更实际的问题：当你同时用 Codex、Claude Code、Copilot CLI、OpenCode 这类 coding agent 时，怎么管理它们干活。&lt;/p&gt;
&lt;p&gt;以前我的用法比较粗糙：开几个终端窗口，每个窗口一个 agent，谁在跑什么、结果有没有回来、上下文有没有断，全靠自己记。任务少的时候还行，一旦同时丢两三个问题，比如一个查 bug、一个写测试、一个做文档，很快就乱了。&lt;/p&gt;
&lt;p&gt;Multica 的思路是把 agent 放进一个协作空间里。它有 workspace、issue、comment、agent 这些概念。你可以把一个 issue 分配给某个 agent，也可以在评论里 &lt;code&gt;@&lt;/code&gt; 它。这个体验更像是在给同事派活，而不是在终端里继续补 prompt。&lt;/p&gt;
&lt;p&gt;我当时顺手记了一个很小的判断：如果一个工具只是在网页里多开几个聊天窗口，那它对 coding agent 的帮助有限；如果它能回答“谁在跑、跑到哪、改了什么、失败后能不能复盘”，它才像是在管理执行单元。Multica 比较接近后者。&lt;/p&gt;
&lt;h2 id="我比较在意的点"&gt;&lt;a href="#%e6%88%91%e6%af%94%e8%be%83%e5%9c%a8%e6%84%8f%e7%9a%84%e7%82%b9" class="header-anchor"&gt;&lt;/a&gt;我比较在意的点
&lt;/h2&gt;&lt;p&gt;我比较在意的一点是：Multica 并不是简单把所有东西都丢到云端跑。官方文档里说，真正执行任务的是本地 daemon。Multica server 负责 workspace、issue、成员、任务队列这些数据；daemon 跑在你自己的机器上，去调用本地安装的 Claude Code、Codex、Copilot CLI 等工具。&lt;/p&gt;
&lt;p&gt;这个设计对我来说挺关键。coding agent 最敏感的地方不是“问答内容”，而是它会读代码、跑命令、改文件。如果一个平台只是提供任务面板，但实际执行仍然在本地，那接受成本会低很多。&lt;/p&gt;
&lt;p&gt;当然这不代表完全没有风险。agent 能做什么、工具权限怎么给、仓库怎么隔离，还是要自己控制。&lt;/p&gt;
&lt;p&gt;从 provider matrix 看，Multica 对不同 coding tool 的支持不是完全一样的。Claude Code、Codex、OpenCode 在 MCP 支持、skill 注入路径、session resumption 上都有差异。这个地方我觉得文档写得比较实在，没有假装所有工具都能做到同一个水平。&lt;/p&gt;
&lt;p&gt;我会特别看这些差异，而不是只看“支持多少 agent”：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;能力&lt;/th&gt;
					&lt;th&gt;我为什么关心&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;session resumption&lt;/td&gt;
					&lt;td&gt;agent 中途断了以后能不能接着跑，不然长任务很容易废掉&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;MCP support&lt;/td&gt;
					&lt;td&gt;能不能接公司内部工具，而不是只靠本地 shell&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;skill injection&lt;/td&gt;
					&lt;td&gt;能不能把团队约定、代码规范、常用命令放进 agent 上下文&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;task history&lt;/td&gt;
					&lt;td&gt;失败任务能不能复盘，而不是只剩一句“没做好”&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="如果我要试"&gt;&lt;a href="#%e5%a6%82%e6%9e%9c%e6%88%91%e8%a6%81%e8%af%95" class="header-anchor"&gt;&lt;/a&gt;如果我要试
&lt;/h2&gt;&lt;p&gt;如果要在项目里试，我大概会先按这个方式用：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt" id="hl-0-1"&gt;&lt;a class="lnlinks" href="#hl-0-1"&gt;1&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-0-2"&gt;&lt;a class="lnlinks" href="#hl-0-2"&gt;2&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-0-3"&gt;&lt;a class="lnlinks" href="#hl-0-3"&gt;3&lt;/a&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;multica daemon start
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;multica setup self-host
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;然后给不同 agent 分清职责，而不是所有任务都丢给一个“全能助手”：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt" id="hl-1-1"&gt;&lt;a class="lnlinks" href="#hl-1-1"&gt;1&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-1-2"&gt;&lt;a class="lnlinks" href="#hl-1-2"&gt;2&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-1-3"&gt;&lt;a class="lnlinks" href="#hl-1-3"&gt;3&lt;/a&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;codex-fixer 小范围代码修复和测试
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;claude-reviewer review、解释设计风险
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;opencode-docs 文档草稿和命令整理
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;我现在对这类工具的看法是：不要指望它让 agent 变聪明。它真正有价值的地方是让 agent 的工作可排队、可观察、可追溯。&lt;/p&gt;
&lt;p&gt;终端里跑 agent 最大的问题是过程容易丢。Multica 把一次运行抽象成 task，有 queued、dispatched、running、completed、failed 这类状态，也有重试和历史记录。这样你至少知道它是没开始、跑挂了，还是已经完成只是结果不理想。&lt;/p&gt;
&lt;h2 id="我不会一上来就接正式仓库"&gt;&lt;a href="#%e6%88%91%e4%b8%8d%e4%bc%9a%e4%b8%80%e4%b8%8a%e6%9d%a5%e5%b0%b1%e6%8e%a5%e6%ad%a3%e5%bc%8f%e4%bb%93%e5%ba%93" class="header-anchor"&gt;&lt;/a&gt;我不会一上来就接正式仓库
&lt;/h2&gt;&lt;p&gt;更合理的方式是先拿一个 side project 或内部工具试：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;只给只读或低风险仓库。&lt;/li&gt;
&lt;li&gt;agent 默认不要有生产凭证。&lt;/li&gt;
&lt;li&gt;每个任务只允许小范围修改。&lt;/li&gt;
&lt;li&gt;输出必须经过人工 review。&lt;/li&gt;
&lt;li&gt;不要把“能跑起来”误认为“能放心用”。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Multica 这类项目让我感觉到一个趋势：coding agent 正在从“单次对话工具”变成“可管理的执行单元”。以前我们关心的是 prompt 怎么写，现在更关心任务怎么派、权限怎么控、结果怎么验收。&lt;/p&gt;
&lt;p&gt;这篇先记到这里。它不是那种看完文档就能断言成熟的工具，但方向我觉得值得关注。尤其是团队里已经有人混用 Codex、Claude Code、Copilot CLI 的时候，与其每个人各玩各的，不如有一个地方把任务和 agent 统一管起来。&lt;/p&gt;
&lt;p&gt;我暂时不会把它写成“推荐大家马上上”。更准确的评价是：如果你的团队还没有稳定使用 coding agent，它不是第一优先级；如果已经有人同时开好几个 agent 做修复、review、文档和测试，它解决的就是混乱本身。&lt;/p&gt;
&lt;h2 id="参考资料"&gt;&lt;a href="#%e5%8f%82%e8%80%83%e8%b5%84%e6%96%99" class="header-anchor"&gt;&lt;/a&gt;参考资料
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://multica.ai/docs" target="_blank" rel="noopener"
 &gt;Multica Docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://multica.ai/docs/how-multica-works" target="_blank" rel="noopener"
 &gt;How Multica works&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://multica.ai/docs/tasks" target="_blank" rel="noopener"
 &gt;Multica Tasks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://multica.ai/docs/providers" target="_blank" rel="noopener"
 &gt;Multica AI coding tools matrix&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/multica-ai/multica" target="_blank" rel="noopener"
 &gt;multica-ai/multica&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Codex CLI 交互斜杠命令全集（含作用与使用场景）</title><link>/dkblog/020-codex-cli-slash-commands/</link><pubDate>Thu, 05 Mar 2026 23:40:00 +0800</pubDate><guid>/dkblog/020-codex-cli-slash-commands/</guid><description>&lt;img src="https://images.unsplash.com/photo-1677442136019-21780ecad995?auto=format&amp;fit=crop&amp;w=900&amp;q=60" alt="Featured image of post Codex CLI 交互斜杠命令全集（含作用与使用场景）" /&gt;
 &lt;blockquote&gt;
 &lt;p&gt;来源：OpenAI 官方文档（Codex CLI Slash Commands）&lt;br&gt;
更新时间：2026-03-05&lt;br&gt;
说明：以下是 &lt;code&gt;codex&lt;/code&gt; 交互界面（TUI）内输入的 &lt;code&gt;/xxx&lt;/code&gt; 命令，不是 PowerShell 系统命令。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;最近在高频用 Codex CLI，发现很多同学刚上手时，会把 &lt;code&gt;/xxx&lt;/code&gt; 斜杠命令和系统命令混在一起，导致操作路径有点乱。&lt;br&gt;
所以我把官方文档里这部分命令做了一次“能直接抄着用”的整理：每个命令不只写功能，还配了一个真实使用场景，方便你在实战里快速判断“现在该敲哪个”。&lt;/p&gt;
&lt;h2 id="使用方式"&gt;&lt;a href="#%e4%bd%bf%e7%94%a8%e6%96%b9%e5%bc%8f" class="header-anchor"&gt;&lt;/a&gt;使用方式
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;启动 &lt;code&gt;codex&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;在输入框输入 &lt;code&gt;/&lt;/code&gt; 打开命令列表&lt;/li&gt;
&lt;li&gt;选择命令或手动输入完整命令&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="命令清单作用--场景"&gt;&lt;a href="#%e5%91%bd%e4%bb%a4%e6%b8%85%e5%8d%95%e4%bd%9c%e7%94%a8--%e5%9c%ba%e6%99%af" class="header-anchor"&gt;&lt;/a&gt;命令清单（作用 + 场景）
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;命令&lt;/th&gt;
					&lt;th&gt;具体作用&lt;/th&gt;
					&lt;th&gt;典型使用场景&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;/permissions&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;设置当前会话的审批/权限策略&lt;/td&gt;
					&lt;td&gt;你要从“手动审批”切到“自动执行优先”时&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;/sandbox-add-read-dir&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;给沙箱追加可读目录（Windows 原生 CLI）&lt;/td&gt;
					&lt;td&gt;需要读取工作区外的配置目录或共享代码目录&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;/agent&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;切换当前活跃 agent 线程&lt;/td&gt;
					&lt;td&gt;同时跑了多个任务，想切回另一个线程继续&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;/apps&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;浏览并插入可用 connectors/apps&lt;/td&gt;
					&lt;td&gt;需要接入外部系统数据（如任务系统、文档系统）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;/clear&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;清屏并开启新会话&lt;/td&gt;
					&lt;td&gt;当前对话太长，想从干净上下文重新提问&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;/compact&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;压缩并总结长对话，减少上下文占用&lt;/td&gt;
					&lt;td&gt;会话很长导致响应变慢或上下文接近上限&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;/copy&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;复制最近一次已完成输出&lt;/td&gt;
					&lt;td&gt;要把刚生成的命令/代码粘贴到别处使用&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;/diff&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;查看当前 Git diff（含未跟踪文件）&lt;/td&gt;
					&lt;td&gt;让模型改完代码后，先人工快速过一遍改动&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;/exit&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;退出 CLI（等价 &lt;code&gt;/quit&lt;/code&gt;）&lt;/td&gt;
					&lt;td&gt;结束当前工作会话&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;/experimental&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;开关实验功能&lt;/td&gt;
					&lt;td&gt;想试新能力或排查某实验特性的影响&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;/feedback&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;提交日志/反馈&lt;/td&gt;
					&lt;td&gt;发现异常行为，需要把现场信息反馈给官方&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;/init&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;在当前目录生成 &lt;code&gt;AGENTS.md&lt;/code&gt; 模板&lt;/td&gt;
					&lt;td&gt;新仓库首次使用 Codex，先定义协作规则&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;/logout&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;退出登录并清理本地凭据&lt;/td&gt;
					&lt;td&gt;切账号、交接机器或做安全清理&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;/mcp&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;查看已配置 MCP 工具&lt;/td&gt;
					&lt;td&gt;检查某工具是否已接入、当前可不可用&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;/mention&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;把文件/目录加入当前对话上下文&lt;/td&gt;
					&lt;td&gt;只想让模型关注某几个目录而不是全仓库&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;/model&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;切换模型（可含推理强度）&lt;/td&gt;
					&lt;td&gt;先用快模型探索，再切强模型做最终修复&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;/plan&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;切到 Plan 模式并提出规划请求&lt;/td&gt;
					&lt;td&gt;任务复杂，先要分步骤方案再执行&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;/personality&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;切换回答风格（friendly/pragmatic/none）&lt;/td&gt;
					&lt;td&gt;团队希望输出更简洁或更工程化&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;/ps&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;查看实验性的后台终端及输出&lt;/td&gt;
					&lt;td&gt;排查后台执行任务卡住或失败原因&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;/fork&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;从当前会话分叉新线程&lt;/td&gt;
					&lt;td&gt;保留原思路，同时探索另一种实现路径&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;/resume&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;恢复历史会话&lt;/td&gt;
					&lt;td&gt;第二天继续昨天做到一半的任务&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;/new&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;在同一 CLI 中新开对话&lt;/td&gt;
					&lt;td&gt;当前问题做完，开始另一个独立任务&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;/quit&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;退出 CLI&lt;/td&gt;
					&lt;td&gt;同 &lt;code&gt;/exit&lt;/code&gt;，用于结束会话&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;/review&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;让 Codex 审查当前改动&lt;/td&gt;
					&lt;td&gt;提交 PR 前先自动扫一轮风险点&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;/status&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;查看会话配置与 token 使用&lt;/td&gt;
					&lt;td&gt;想确认当前模型、沙箱、审批和消耗情况&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;/debug-config&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;输出配置层与策略诊断信息&lt;/td&gt;
					&lt;td&gt;配置不生效时定位是被哪一层覆盖&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;/statusline&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;配置 TUI 状态栏显示项&lt;/td&gt;
					&lt;td&gt;想在界面上实时看到模型/审批等状态&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="兼容与别名"&gt;&lt;a href="#%e5%85%bc%e5%ae%b9%e4%b8%8e%e5%88%ab%e5%90%8d" class="header-anchor"&gt;&lt;/a&gt;兼容与别名
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/approvals&lt;/code&gt;：仍可用，但通常不在 slash 列表里显示；建议改用 &lt;code&gt;/permissions&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/exit&lt;/code&gt; 与 &lt;code&gt;/quit&lt;/code&gt;：功能等价，都是退出 CLI。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="两个高频命令"&gt;&lt;a href="#%e4%b8%a4%e4%b8%aa%e9%ab%98%e9%a2%91%e5%91%bd%e4%bb%a4" class="header-anchor"&gt;&lt;/a&gt;两个高频命令
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/init&lt;/code&gt;：初始化仓库级协作规则（生成 &lt;code&gt;AGENTS.md&lt;/code&gt;）。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/model&lt;/code&gt;：任务中途切模型，平衡速度和质量。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="版本差异说明"&gt;&lt;a href="#%e7%89%88%e6%9c%ac%e5%b7%ae%e5%bc%82%e8%af%b4%e6%98%8e" class="header-anchor"&gt;&lt;/a&gt;版本差异说明
&lt;/h2&gt;&lt;p&gt;不同 &lt;code&gt;codex-cli&lt;/code&gt; 版本会新增/隐藏命令。以你本机实际可见列表为准：在交互界面输入 &lt;code&gt;/&lt;/code&gt; 即可查看当前版本完整命令。&lt;/p&gt;
&lt;h2 id="写在最后"&gt;&lt;a href="#%e5%86%99%e5%9c%a8%e6%9c%80%e5%90%8e" class="header-anchor"&gt;&lt;/a&gt;写在最后
&lt;/h2&gt;&lt;p&gt;如果你是第一次系统使用 Codex CLI，我建议先记住这几个高频命令：&lt;code&gt;/model&lt;/code&gt;、&lt;code&gt;/permissions&lt;/code&gt;、&lt;code&gt;/diff&lt;/code&gt;、&lt;code&gt;/review&lt;/code&gt;、&lt;code&gt;/status&lt;/code&gt;。&lt;br&gt;
这几个覆盖了日常最常见的流程：选模型 -&amp;gt; 管权限 -&amp;gt; 看改动 -&amp;gt; 做审查 -&amp;gt; 查会话状态。&lt;/p&gt;
&lt;p&gt;另外一个实用习惯是：遇到“感觉命令不见了”或者“和别人截图不一致”时，先在当前会话里输入 &lt;code&gt;/&lt;/code&gt; 看本机版本实际列表，再决定下一步。&lt;br&gt;
这样能避免把时间花在“文档有，但你当前版本没开”这类问题上。&lt;/p&gt;
&lt;h2 id="官方链接"&gt;&lt;a href="#%e5%ae%98%e6%96%b9%e9%93%be%e6%8e%a5" class="header-anchor"&gt;&lt;/a&gt;官方链接
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://developers.openai.com/codex/cli/slash-commands" target="_blank" rel="noopener"
 &gt;https://developers.openai.com/codex/cli/slash-commands&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/openai/codex/blob/main/docs/slash_commands.md" target="_blank" rel="noopener"
 &gt;https://github.com/openai/codex/blob/main/docs/slash_commands.md&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item></channel></rss>