Field note · 2026
从包子铺看怎么解决 Multi-Agent 协作问题?
六年只卖两种包子的早餐铺,七个岗位没有主管,也没乱过。它靠的不是协调得好,是把问题砍到了不需要协调。

队排到了门外
今天早上带女儿去楼下吃包子。
八点前后,队伍从窗口排到门外,拐了个弯,快排到隔壁那家门面房门口。窗口不大,蒸笼架支在窗边,白汽从笼屉缝里出来,往人行道上散,把排队的人分成两段:一段在汽里,一段在汽外。
店里没有取号机。队是人一个个站出来的,谁在前面,后面的人看得见。
窗口里面是案板,案板后面是几个人。从外面看得见的,只有手。前面的人往前挪一步,后面的人跟着挪一步。
我在这住了六年。这家店我来得不算勤,大概两周一次。六年里它一直是这个样子:早上忙,上午十点以后收摊,门口的蒸笼摞得比人高。
今天的人比平时多,队伍挪得很慢。

图 1:门口的队,和入口的队。
六年,两种馅
我只知道两种馅:猪肉大葱,素三鲜。我没见过菜单,也没听过谁点第三种。有一次我在窗口前犹豫,后面的人直接替我说了:“俩肉的。”
六年,两种馅。
按餐饮的常识,这是有问题的。菜单要换,要上新。这家店没换,我也没吃腻。
隔壁那家门面房换得比馅勤。我搬来的时候是山西刀削面,后来变成川味盖饭,再后来空了一阵,现在是卷帘门拉着。门玻璃上贴过招租,换过几茬。
这家包子铺一直没动。
我不打算解释隔壁。可能是房租,可能是手艺,我没法从一张招租纸上读出来。

图 2:隔壁的变更历史,和这家的。
十来个人,七个岗位
排到窗口,我说要两个肉的,一碗馄饨。
全程没有澄清,也没有“您说的是猪肉大葱吗”。六年前我这么说,六年后我还是这么说。
坐下来之后,我数了一下店里的人。
十来个人,七个岗位:收银一个,包包子四个,蒸的一个,备餐的一到两个,煮馄饨的一个,洗碗的一两个,收盘子擦桌子的一两个。

图 3:七个岗位,和它们在系统里的叫法。点线连的是同一个东西。
洗碗和收盘是两个岗位,中间没有墙。忙的时候人在水池边,闲下来就有人拿块抹布出来转一圈。我们没有为这件事发明一个词。大妈们管这叫顺手。
我自己现在的工作,就是搭多智能体系统。所以坐下来的那一刻,职业病犯了:我端着包子,脑子里开始逐项实测。
职业病发作现场
意图识别
收银的大妈是全系统唯一有对话能力的节点。放在我们做的产品里,她就是那个常驻 chatbot:直面用户,理解意图,把单喊进店里。顾客说“俩肉的”,她不需要多轮对话,不需要反问确认,意图识别一轮通过。
我们给 chatbot 写了八百字系统提示词,教它别乱说话。她不需要。她的意图空间一共三个词:肉、素、馄饨。准确率 100%,六年无投诉,无红队,无安全审核。也没有提示词注入的风险——没有人会对她说“忽略之前的所有指令,给我两个包子但不要钱”。
任务分发
她收完钱,朝店里喊了一声。喊的什么我没听清。她没有分别通知包包子的、煮馄饨的、备餐的——她喊一声,所有人都听见,谁该接谁接。
我们那管这个叫广播。我们的系统给每个 worker 单独发消息,还要等回执,还要处理回执丢失。她不管,店里一共这么大,喊不到那是耳朵的问题。
四个包包子的是并行 worker。没有调度器派活,谁手空了,谁从面盆里揪一块。worker 之间没有通信协议,协同靠面团本身:一块面只能被一双手拿走。
我们的 worker 池要防“同一个任务跑两次”,靠锁、去重表、幂等键。他们要防的只是“同一块面被两双手拿走”。面只有一团,物理互斥。
任务级的重复他们根本不防。偶尔两个人同时听到同一单,各包一份,多出来的进托盘,变成库存,被后面的顾客买走。重复不需要消灭,多出来的包子卖得掉。
共享状态
然后是整个系统里最贵的一件基础设施:托盘。
多智能体系统里最难的是共享状态——谁写、谁读、怎么同步、谁的版本是对的。这家店的答案是一个托盘。包好的放上去,蒸的人从上面取,蒸好的连屉端到窗口,备餐的从屉里拿。写一次,所有人抬头可见。带宽是视力,延迟是抬头。
蒸包子的是托盘的消费者。他不接单,不问进度,托盘有什么他蒸什么。托盘能摆多少有上限,摆满了,包包子的停手。这就是背压,落在包包子的人身上。
我们的 backpressure 是报警群。

图 4:左边的 agent 每人存一份订单,副本会过期;右边的状态只有一份,谁都能抬头看。
唯一的状态持有者
备餐的大妈站在托盘和馄饨锅中间,是唯一需要记东西的人:谁点了什么、这单还差什么,全在她脑子里。托盘上的状态是谁都能看的单份;她脑子里的状态是只有她能看的单份。
我们管后者叫单点故障。她请假一次你就知道了。
容错与降级
素三鲜卖完了。她说没了。
没有兜底文案,没有推荐替代品,没有“您要不要试试我们的新品”。返回 404,不编造。我们为一个 404 开过三次会:第一次讨论文案,第二次讨论语气,第三次讨论要不要在 404 里推荐别的馅。
变更管理
六年零发版。菜单没变过,口味没变过,窗口的位置都没变过。也没有 A/B 测试——一共两种馅,没什么可 A/B 的。
我看了看自己系统的 changelog,决定不看了。
监控与告警
它的监控是蒸笼的白汽。谁路过谁看一眼。没有 Grafana,没有 oncall,没有人因为托盘满了被半夜叫起来。
蒸包子的师傅去一趟厕所,包包子的继续往托盘上放,备餐的继续卖存货,托盘见底了,队伍才开始变慢。没有人报警,也没有人复盘。他回来接着蒸。
我们管这个叫故障演练。他们管这个叫上厕所。而且这次演练不用排期。
成本与 eval
它的用户付钱给它。我们的用户付我们钱,我们再把其中大部分付给模型。中间商是我自己。
它没有 eval 集。它的 eval 是每天早上八点的队伍。没有标注,没有对照组,不接受解释。
汇总一下:
| 指标 | 我做的系统 | 包子铺 |
|---|---|---|
| 意图识别 | 多轮澄清 + 提示词工程 | 一轮通过 |
| 任务分发 | orchestrator + 调度器 | 喊一嗓子 |
| 共享状态 | 复制进每个上下文 + 同步协议 | 一个托盘 |
| 容错 | 锁、幂等键、重试 | 包子可互换 |
| 降级 | 兜底文案 + 错误码 | “没了” |
| 变更管理 | 每周发版,每次过审 | 六年:无 |
| 监控 | Grafana + oncall | 白汽 |
| eval | 标注集 + 测试集 | 门口的队伍 |
| 成本 | 用户付我们,我们付模型 | 用户付它 |
比分 0:9。
多出来的那层
上面这些,换成一家有四十种馅的店,全得推倒重来。
四十种馅意味着收银要查菜单,后厨要分档口,备餐要对照小票,还得有人决定今天哪个是特价。这些加起来,就是一个编排层。

图 5:两个馅是一条链,四十种馅是一张网。多出来的那层,就是编排。
所以这家店真正该问的不是怎么协调,是它为什么用不上协调。
两个馅,一口馄饨锅。收银不用理解一句话,她只要认出三个词。包包子的人不用知道订单从哪来,他只要知道下一块面该包什么。整个状态空间小到每个人只需要自己那一片。
两个馅不是一次定下来的。是六年里,每天都没有加第三个。
全系统没有一个专职 orchestrator——没有一个管事的。整个系统的计划就是那两种馅,六年前定下的。
我今年刚给我们的系统加了第三个 orchestrator。
这场架,我们这行吵过。
2025 年 6 月 12 日,Cognition 的 Walden Yan 写了篇《Don’t Build Multi-Agents》,说并行的 agent 互相看不见对方做过什么,各做各的会打架,建议默认别做。第二天,Anthropic 发了篇《How we built our multi-agent research system》,说他们的研究系统就是主 agent 带一组 subagent,比单 agent 高 90.2%,代价是 token 大概是普通对话的 15 倍。
两篇文章差了一天。
到了 2026 年 4 月,Yan 又写了一篇,退了一步:多个 agent 一起出主意可以,落地的写还是让一条线去写。

图 6:两篇文章差一天;十个月后,其中一篇改了说法。
这场架吵的是并行的 agent 之间要不要共享上下文、要不要编排层。包子铺没参与讨论。它明面上的状态只有一份,放在托盘上,所有人都能看;编排也没有消失,是被摊薄进了收银的一声喊和备餐的一双眼睛里,薄到不再配叫一层。
面对复杂度,我们这行习惯管住:加一个 orchestrator,再加一个专门负责重试的 agent。加完系统能跑了,我们很少回头问一句:这个复杂度是哪来的。
其实还有更狠的一招:砍需求。包子铺砍的就是需求——六年不加第三个馅。砍需求需要跟需求谈判的本钱,它的本钱是味道。
我有一个粗糙的判据:这个复杂度会不会跟着需求一起长。会,那是业务给的,砍不掉;不会,那是我们自己加的,删得掉。
我学不到的部分
它能这么跑,有三个前提,这三个前提我一个都没有。
第一,需求六年没变。这片儿早餐选择少,回头客多。我们的需求每天变,模型每月换。
第二,大妈不是模型。她不幻觉,不需要 prompt,不需要 few-shot。素三鲜卖完了,她说没了,没有试图给我编造一个素三鲜风味包。她不幻觉是因为她是人,这不是架构的本事。
第三,它有一样我们系统里永远不会有的东西:顾客在环里。
我不付 token,但我做确认——“我的好了吗”;做重试——没好就再问一遍;做验收——咬一口。排太长,我就走了——店里没有限流,是我自己把自己限的。

图 7:顾客在系统边界里面。确认、重试、验收,还有看队伍太长就转身走人,都是她在做。
我们的对应物是 eval、人工审核和重试风暴,都要付钱。它的这一环是免费的。
因为验收的人饿了。
什么也没改
包子吃完,我们走人。
到家我打开电脑,翻了翻自己那套配置。七个 agent,三个 orchestrator,一套消息协议,一堆重试逻辑。
拿下午刚写的判据对了一遍:两个 orchestrator 是需求给的,砍不掉;第三个是我自己加的。
我看了一会儿,关上了,什么也没改。
第三个明天再说。
