Nicholas Clooney

和 agent 的聊天太乱?你只需要再加一个。真的。

所属系列

最近几天,我一直用 tmux-agents 同时运行许多 agent。在 Stone Age 重制项目上,可能有五到十个同时工作,另外还有几个处理轻量的支线项目。整体感觉很棒,但做了一处小调整后,这套配置才不再显得混乱。

配置

Codex 是这个项目的主要实现者。这个月 Pro 计划拿到了不错的优惠,所以繁重工作都交给它:接下任务、拆分,再通过 tmux-agents 启动自己的子 agent,每个都使用工作树池中的一个槽位。

在我与 Codex 之间,还有一个 Claude agent。我与 Claude 对话,Claude 把工作交给主 Codex,Codex 再分派给子 agent,回复沿着同一条链返回。全部加起来,可能有十个 agent 同时运行。

tmux-agents 列表显示三个正在工作的 Codex 子 agent 和两个已关闭的子 agent,并实时预览其中一个
从 tmux-agents 看到的主 Codex 子 agent:三个工作中,两个已经关闭。

问题:一个 agent 做两份工作

链条本身运转正常。问题出在中间的 Claude,因为它同时承担两份差别很大的工作。

一份是与我交流:回答问题、请我做决定、接收新任务。另一份是运行项目:接收 Codex 报告、审阅并合并工作、重启在线服务器、编辑文件。两种工作都落进同一段对话。

于是历史记录成了什么都有的信息流。Codex 回复提交哈希和截图列表,接着是 cherry-pick、更新日志检查、服务器重启、后台构建结束。中间某处夹着一个问我的问题,再往后某处才是我的回答。

Claude agent 的历史记录:Codex 的长回复之后,接着是 cherry-pick、更新日志检查、停止并重启服务器
之前:与我对话的 agent,也在合并 Codex 的工作和重启服务器。

更糟的是,我经常得等轮到自己。如果 Claude 正在处理 Codex 回复或执行命令,我的问题就排在这些工作后面。本该与我交流的 agent,成了屋里最忙的那个。

解决办法:再加一个窗格

我又加了一个 Claude agent。全部改动就是这个。

我在同一个 tmux 窗口里打开新窗格,把它连接到已有的 Claude,并告诉它职责:现在你是主 agent,只和我交流。你不写代码,也不运行项目。任何需要做的事,都交给另一个 Claude;后者现在是我们与主 Codex 之间的 coordinator。

三个 tmux 窗格:左边的主 Claude 与我聊天,右上角是 coordinator Claude,右下角的主 Codex 正在向子 agent 发送请求
之后:左边的主 Claude 只与我聊天。右上角 coordinator 与右下角主 Codex 沟通,再由后者联系子 agent。

现有 agent 完全不用改变。原来的 Claude 保留历史、与 Codex 的连接,以及进行中的工作,只是不再是我直接对话的对象。

我还刻意没有把新的主 agent 连接到 Codex。如果它能直接与 Codex 沟通,Codex 报告就又会流进我的对话,一切回到原点。主 agent 恰好只有一个同伴:coordinator。

把角色写下来

当场告诉新 agent 职责,暂时有效。为了让它长期成立,让任何读到项目的 agent 都知道谁做什么,我把角色和消息规则写进了项目的 AGENTS.md。下面是这一节,保留了 agent 名称:

## Agent roles and messages

Three agents work together in tmux panes: main agent → coordinator → worker.

- **main agent (Claude, `claude-projects-stone-age-2`)**: interfaces with the user
  and the other agents: clarifies intent, turns it into self-contained tasks and
  relays user decisions. Does not investigate or implement.
- **coordinator (Claude, `claude-projects-stone-age-1`)**: coordinates Codex and
  owns the main checkout: merges Codex commits, runs importers, backs up saves,
  relaunches the server, runs tests and records decisions in docs. Sends anything
  that needs a user decision to the main agent, not to the user.
- **worker (Codex, `codex-projects-stone-age-1` and its sub agents)**: main
  implementer. Sub agents split work by file ownership to avoid conflicts.

Messages:

- Everything goes through `tmux-ask`. Long reports go in a file; the message is a
  short summary plus the path.
- The user reads coordinator→main agent messages directly, so the main agent does
  not restate them; it surfaces a decision as a one-line summary plus options.
- Mark FYIs "no reply needed". A decision request states the default and what is
  blocked meanwhile.
- An instruction the user gives directly to any agent wins; that agent tells the
  others what changed.

有几条规则比预想中更重要。“凡是需要用户决定的事,都交给主 agent,而不是用户”,防止 coordinator 悄悄又变成我的直接对话对象。“说明默认选择和期间被阻塞的工作”,让我知道如果一小时不理这条决策请求,会发生什么。而“用户直接给任何 agent 的指令优先”,则保留了绕过链条的通道:必要时,我仍能在任意窗格输入,收到指令的 agent 负责告知其他成员。

前后对比

之前: coordinator 一直很忙。Codex 消息不断进来,它不断问我做决定,也不断执行命令。想提问或布置任务,得等空隙。

之后: 我只和主 agent 交流。它回答能回答的,其余交给 coordinator,再由 coordinator 视情况交给 Codex。coordinator 的回复出现在主 agent 窗格里,我可以在消息到达时直接阅读,主 agent 不再重复。只有需要我时,它才介入,用一句摘要列出选项。

之前:我与一个 Claude agent 对话,它也负责运行项目,并与 Codex 及其子 agent 传递消息 之前 我 Claude 一个 agent,一份历史,包办一切 · 我的问题与决定 · Codex 报告 · 合并与测试 · 重启服务器、编辑文件 Codex 子 agent 子 agent 子 agent
之后:我只与主 Claude 对话,由它交给 coordinator Claude,再与 Codex 及其子 agent 沟通。主 agent 与 Codex 刻意不连接。 之后 我 主 Claude 只与我交流,不写代码 coordinator Claude · Codex 报告 · 合并与测试 · 重启服务器、编辑文件 Codex 子 agent 子 agent 子 agent 未连接
之前,与我对话的 agent 也负责运行项目。之后,我只与主 agent 交流,其余交给 coordinator。主 agent 与 Codex 刻意不连接。

为什么有效

事后回看,我觉得有几件事在起作用。

对话与工作分开了。 以前,我的对话与项目操作共享一份历史,现在分成两份。主 agent 的历史只包含我和我问过的事,于是重新像一段对话。那些噪声,包括报告、合并、日志和重启,仍然存在,只是累积在 coordinator 那里,除非出了问题,否则没人需要读。

与我交流的 agent 总是有空。 主 agent 几乎不亲自做工作,所以很少陷入漫长的一轮执行。我的消息不用排在服务器重启或代码审查后面,而是立刻被读到。等待从我身上转移到了 agent 身上,这才是它该在的地方。

上下文保持较小。 截图中,主 agent 用了 90k token,占窗口的 9%;coordinator 用了 300k,占 30%。一部分原因是主 agent 更年轻,但它也只随我们的对话增长,不会随项目里的每份报告增长。更小、更干净的上下文,agent 才真正能跟得住。

决策以容易回答的形式送到我面前。 coordinator 发给主 agent 的是简短摘要,知会消息标明无需回复,我可以快速浏览。需要决定时,主 agent 会整理成一行,明确列出选项、默认选择和期间被阻塞的工作。选 A 还是 B,只要一秒;从一长串 Codex 报告里挖出同一个问题,可不是这样。

只有一条路径。 我、主 agent、coordinator、Codex、子 agent。因为主 agent 与 Codex 没连接,就没有让对话分叉到两处的捷径。每条信息都有明确的去路和回路。

这不是没有代价。每个请求多了一跳,增加一点时间和 token;每次交接又都是摘要,细节可能像传话游戏一样逐步丢失。对于这么多 agent 的项目,目前这个取舍很值得。不过我这样运行的时间还不长,还不能判断连续几周后会怎样。

我的收获

令人意外的是,所需改动如此之少。没有新工具,没有修改 tmux-agents,也没有重启正在工作的 agent。只是一个新窗格、一条连接,以及几句话描述的角色。

这和工作树池给我的启示相同,只是换了一个角度:agent 多了,有意思的问题不在某一个 agent 身上,而在它们彼此之间,以及它们与我之间的连接形态。与我交流的 agent 不再同时承担实际工作后,整套环境都安静了下来。