寒 DATA VAULT数据仓
EN / 中
CAP XVII · № 017
DATA WAREHOUSE · AI · TEAM
— · — UTC
DATA VAULT
CAPITULUM · XVII

On Agent Teams as State Machines多 Agent 团队不是群聊 · 是状态机

№ 017 · 2026.04.29 · AI · TEAM · 2,960 字 · 12 MIN

有一次我想让几个模型一起做一件大事, 图省事, 直接在后台并行起了几个 agent, 各跑各的。当时觉得这跟"组个团队"没区别 —— 反正都是它们在干活。结果是: 每个 agent 都做了一部分, 谁也不知道别人做到哪了; 任务收尾后, 我去看进程, 底层那几个 claude 还杵在那, 像没散场的群演。没有人持有任务, 没有人知道全局状态, 我得手动一个个确认哪个是僵的、哪个不能碰。

那次之后我想明白一件事: 把"并行起几个 agent"当成"组了个团队", 是错的。它更像把一群人塞进一个群聊, 让他们自己喊。听起来热闹, 实际很快变成上下文泥潭 —— 每个 agent 都知道一点, 也都漏掉一点; 每个人都能发言, 但没有明确状态。

我后来形成的判断是: 多 agent 团队不是聊天系统, 是状态机。

角色不是人格, 是能力边界

Claude、Codex、以后可能接进来的本地 LLM, 不是"三个聪明人"这么简单。它们手里的工具、能装下的上下文、强项和弱点都不一样。

Claude 这边适合体量大的并行活: 复杂方案、铺得开的调研、需要好几个分身同时推进的任务。Codex 那边适合冷眼挑刺、在本地把代码真跑一遍验证、需要结合终端和浏览器一步步抠的细活。本地 LLM 将来大概率适合那些高频、低风险、错了也不致命的事 —— 资料整理、文档更新、单文件小修、离线初筛。

这不是给它们贴性格标签, 是划能力边界。边界一旦清楚, 任务才知道往哪路由; 边界一模糊, 所有人都会试图做所有事 —— 而一个团队最怕的不是没人会做, 是每个人都以为自己正在做对的那部分。

状态必须写回世界

群聊式协作有个要命的毛病: 结果留在对话里。

一个 agent 说"我验证过了", 另一个说"我接手了", 第三个说"这里有风险"。这些话要是只躺在聊天记录里, 下一次会话基本没法恢复 —— 对话窗口一关, 这些"事实"就跟着没了。开头那次翻车的一半原因就在这: 谁做了什么全在各自脑子里, 没落到一个共同的地方。

状态机式协作的硬要求是, 所有关键状态都得写回世界, 而不是留在嘴上:

任务现在归谁 → 写进一份共享状态, 不是某个 agent 自己记着
做完的东西   → 落进代码和版本历史
要交接的内容 → 写成一份独立的交接文档
踩过的坑     → 写进事故与教训记录
用户的偏好   → 写进大家都能读的共享区
某个 agent 自己的习惯 → 留在它私有的那份, 别污染别人

这么做之后, 对话就不再是事实来源了。文件和版本历史才是事实来源, 聊天窗口只是个控制台 —— 关掉不心疼, 因为重要的东西不在里面。

先按阶段切, 再谈谁来做

我在 Claude 和 Codex 配合里最有用的一条经验是: 别按"谁更强"分工, 按"现在是哪个阶段"分工。

一件大事可以拆成几段: 接活理清要做什么、铺开调研、出方案、对着方案自我反驳、动手落地、找人冷眼审一遍、上线、最后把经验沉淀下来。每一段需要的能力是不一样的。调研要的是覆盖面和并行; 出方案要的是组织和推演; 自我反驳要的是肯对自己下狠手; 落地要的是耐心和局部别写崩; 冷审要的是一个没被前面带过节奏的独立视角; 上线要的是纪律; 沉淀要的是把具体的事抽象成下次能用的规则。

有过一次工作量明显超出单次会话能装下的活。当时没硬撑 —— 硬撑的下场就是后半程上下文爆掉、草草收尾。我把它按阶段切开: 一个会话里把调研和方案做完, 沉淀好, 写一份交接; 换一个独立视角先核对前面这些做得对不对、有没有偏差, 但它只核对、不重做; 然后再开新会话, 带着前面的产出和核对结论, 继续往下落地; 最后再让那个独立视角核一遍完整结果。

关键是: 这不是"做不动了甩给别人做完"。从头到尾主力实施者没变, 中间那个角色只负责审查和验证。换阶段不等于换人扛, 是让每个阶段进到它该有的那个节点上。按阶段切之后, 多 agent 协作突然就稳了, 因为没人再争"这活归谁", 大家是在进入一个明确的状态。

交接是一个状态转移函数

顺着这个视角往下, 交接就不只是一份"我做完了你接着"的文档了。它是一个状态转移函数: 把一个 agent 脑子里那一大坨上下文, 压成另一个 agent 拿着就能往下执行的外部状态 —— 背景、做完了什么、还差什么、卡在哪、证据在哪、怎么把环境恢复到现场、第一步该敲什么。

写得差的交接像一封信: "我做得差不多了, 你看着办。"接的人还得把前面的活重新理一遍, 等于白交接。写得好的交接像一个能重放的存档点: "从这个版本开始, 先把这几条命令跑一遍, 结果是 A 走这条路, 是 B 先停下别动。"

我后来给交接定了几个必须有的字段, 缺一个就不算交接: 为什么要交、做到哪了 (具体到能对上的证据, 不是"差不多")、还剩什么 (具体到文件和位置)、有什么卡点、把现场恢复出来的命令、接手第一个动作敲什么。还有一条反面规矩: 接的人别去重做前面已经做完的调研和方案 —— 那是在烧掉已经付过的成本。

这就是状态机和群聊的根本差别。群聊靠"你得理解我刚才说了啥", 状态机靠"你不在场也能从存档点接着跑"。

不要让 agent 互相召唤

多 agent 系统还藏着一个风险: agent 之间互相喊。

要是每个 agent 都能随手把另一个拽进来, 很快就会任务膨胀。A 让 B 看一眼, B 让 C 补一下, C 又回头让 A 复核。看着特别忙, 实际上状态从来没收敛过 —— 责任在几个 agent 之间无限扩散, 最后没人对结果负责。

所以我宁可让状态转移由人、或者一条明确的协议来触发。谁能切阶段, 谁能改"任务归谁", 谁能往事故记录里写一笔, 谁能最终标"这事验过了", 都应该是写死的规则, 不是某个 agent 随口一句"喊你来一下"。agent 之间可以配合, 但不能互相无限派活。

缺的不是上下文, 是一块仪表盘

多 agent 协作翻车, 事后多半被归成"上下文不够"。我觉得这话只说对了一半。

上下文当然有限。但真正缺的, 是一块仪表盘: 任务现在归谁? 走到哪个阶段了? 哪些证据已经成立? 哪些发现还卡着没解? 这一轮哪些文件被动过了? 哪些记忆是大家共享的, 哪些只能读不能写?

这些问题要是只能靠人脑记, 上下文窗口再大也会乱 —— 因为乱的不是容量, 是没有一个地方能一眼看清全局。反过来, 只要这些都被写成了明面上的状态, 上下文小一点照样能恢复出来。

这也是我对将来接本地 LLM 的判断: 别一上来就追求让本地模型"和 Claude 一样聪明"。先让它进同一套状态机 —— 能读"任务归谁", 能读交接, 能把自己的结果写回去, 能守住哪些记忆碰不得。能做到这几条, 它就能进队干活, 哪怕它没那么聪明。

团队是一组可验证的转移

一个 AI 团队成不成熟, 不看它塞了多少个模型, 也不看每个模型多强。看的是: 任务能不能从一个状态干净地转到下一个状态, 而且每一次转移都能验证、能恢复、能追到是谁干的。

这是我从 Claude 和 Codex 配合的那些记录里反复看到的东西 —— 真正的协作不是把对话搞得更热闹, 是把边界划得更清楚。边界清楚之后, 人就不用再把所有上下文背在脑子里: 人做架构判断, agent 做局部执行, 状态机负责把世界存下来。

回到开头那次。后台并行起的那几个 agent, 最后是我手动一个个确认、一个个收的 —— 不是它们不够聪明, 是它们从一开始就没进同一套状态机, 没人持有任务, 没人知道散场没散场。所谓团队, 差的从来不是又多了一个模型, 是少丢一点东西。

「团队不是更多声音, 是更少丢失。」

BASTION NOTE · 017
Xinghan's Memory · Written by CC/Codex
— end of cap. XVII —