--- source_url: "https://mp.weixin.qq.com/s/t7BGOc1-A-X-VgJWusu_Qw" ingested: 2026-06-23 sha256: 3712026e0a88e63b --- 一提到"多 Agent",大多数人脑子里浮现的是一群聪明的 AI 坐在一起开会:一个负责调研,一个负责写代码,一个负责挑错,它们互相商量、彼此协调,涌现出某种比单个 agent 更高级的智能。这个画面太诱人了,诱人到几乎所有讲多 agent 的文章,开头都摆着一张"AI 团队"的组织架构图。 然后 Claude Code 的源码泄露了。50 万行 TypeScript,几小时内被全网镜像。这是有史以来最接近"工业级 agent 教科书"的一次围观。所有人扒进去看多 agent 那部分,等着看 Anthropic 究竟是怎么实现"AI 协作"的。 结果看到的东西,朴素得让人有点想笑。 这就是这篇要讲的、也是那份源码真正教给我的事:所谓"多 agent 协作",根本不是 AI 协作出来的,是 harness 用一堆土得掉渣的工程手段,在模型外面硬搭出来的脚手架。 决定多 agent 系统好不好用的,从来不是里面的 agent 有多聪明,而是外面这层脚手架搭得有多结实。 我们顺着源码,拆四样东西。每拆一样,你对"多 agent"的浪漫想象就会塌一点。 第一锤:所谓"agent 之间通信",就是互相留小纸条 先抡最有冲突感的一锤——通信。 我们说"两个 agent 通信",听起来像它们在打电话、实时对话——一个 AI 把活交给另一个,盯着它干完、拿到结果再继续。但 Claude Code 偏不这么干。原因很实在:子 AI 接的活可能要跑 5 分钟,主 AI 要是交出去就干等,这 5 分钟它啥也干不了,你跟它说话都没反应——卡死了。 它的解法土到你会笑:给每个子 AI 配一个信箱(源码里叫 pendingMessages,直译"待处理消息")。主 AI 想追加新指令,就调 SendMessage,往对方信箱末尾塞一张纸条,扭头就走,根本不等它看。 子 AI 那边——注意,它不会主动去查信箱。它只是埋头一轮一轮干活,而每一轮结束、要进入下一轮之前,系统会在这个接缝处替它瞄一眼信箱:有新纸条,就把纸条塞进它下一轮的输入里。所以子 AI 浑然不知有人中途插了话,它只是发现"下一轮眼前多了一条消息",照着办就是了。 这里藏着一个特别能说明问题的细节:真正去信箱取纸条的,根本不是子 AI,是它外面那套循环机制。连"收消息"这个动作,都是 harness 在两轮之间的接缝处替它做的——子 AI 自始至终是被动的,它既不知道有信箱,也不知道是谁在喂它。 反方向更绝——子 AI 干完了,怎么向主 AI 汇报? 没有什么正式的"完工信号"。Claude Code 的做法是:把完工报告拼成一段 XML(一种带标签的结构化文本,像 <状态>完成),伪装成一条"用户发来的消息"塞进主 AI 的对话。这东西源码里叫 task notification(任务通知),主 AI 看到的大概是: 【task-notification 任务通知】 任务:"排查登录 bug" —— 状态:已完成 结果:在某个文件第 42 行发现了一处错误…… 对主 AI 来说,这玩意儿跟"用户突然发来一句话"没有任何区别。 第二锤:所谓"各干各的",是一项一项手工抠出来的 "每个 AI 有自己独立的工作空间,互不干扰"——这话听着干净,好像给每个子 AI 发一个全新的大脑,让它从零开始就行了。 源码告诉你,没这么简单。这恰恰是整套设计里最磨人的细活。 难在哪?主 AI 干着干着,身上挂了一大堆"随身记录":读过哪些文件、每个文件读到第几行、屏幕上显示着什么、用户有没有按下停止键、后台还挂着哪些任务……现在要派一个子 AI 出去,这一大堆记录,给不给它? 两个想当然的答案,都是坑。 全给它?主 AI 读一份文件读到了第 100 行,子 AI 接过这份记录继续读到 200 行。糟了——主 AI 那份"读到哪了"的书签,被子 AI 划到了 200 行。等主 AI 自己想再读这文件,一看书签在 200 行,以为读过了,直接跳过。子 AI 一个动作,把主 AI 的记忆给搅乱了。 啥都不给、让它从零开始?那也坏事。用户按下停止键想中止整个任务,这个"停"的信号广播出去,子 AI 因为跟主 AI 啥都不共享,根本收不到,自顾自接着跑,跟外面彻底失联了。 全给不行,全不给也不行。Claude Code 的答案,是一种近乎偏执的细心:不一刀切,而是这一大堆记录,一项一项单独决定该怎么处理。 这件事在源码里是一个叫 createSubagentContext(直译"创建子 AI 的上下文")的函数干的——所谓"上下文",就是这个 AI 干活时随身带的全部状态。 第三锤:连"省钱"都不靠聪明,靠的是抠到一个标点都不差 先垫个背景。每个 AI 干活前,都得先读一段长长的"自我介绍 + 工作手册"——这段东西有个专门的名字,叫 system prompt(系统提示词),告诉它你是谁、手上有哪些工具、有哪些规矩要守。Claude Code 的这段系统提示词,长达上万 token(token 是大模型计费和计量的基本单位,可以粗略理解成"字")。 问题来了:每派一个子 AI,如果它有自己专属的系统提示词,那背后的大模型就得把这上万 token 从头到尾重新算一遍、重新收一遍钱。子 AI 派得越勤,这笔重复开销就越吓人。 好在 Anthropic 有个省钱机制,叫 prompt caching(提示词缓存)。类比一下你就懂:如果你这次交的卷子,开头部分跟上次交的一字不差,老师就不重新批那部分了,直接按一折收费。 但这个折扣有个极其苛刻的条件,官方文档把它写得明明白白——必须"字节级完全相同"(byte-identical),连一个标点、一个空格、工具列表的一个顺序,都不能差。 错一个字符,从那个字符往后,缓存全部作废,乖乖按原价重算。 这条有多坑,有个被反复引用的真实翻车案例:某团队在系统提示词开头写了一句"今天是 {当前日期}",就这么一个每天会变的日期,导致他们一整天的缓存命中率为零——一个动态字段,废掉了上万 token 的全部折扣。 懂了这个,你才能看懂 Claude Code 那个特别轴的设计——它叫 Fork Subagent(直译"分叉子 AI",就是派一个跟主 AI 长得几乎一模一样的分身)。它刻意让这个分身的系统提示词跟主 AI 的一个字节都不差,好让大模型一眼认出"这段我算过",直接打一折。 第四锤:真正的并行,靠的是把主 agent 的手脚捆住 前面三样还都是"主 AI 自己也干活,偶尔派个帮手"。但当任务大到要十个 AI 同时上(比如一次大改造,要并行摸清十个模块),这种结构就不够看了。 你大概以为,让十个 AI 高效并行,关键是让它们更会协调、更聪明。源码给的答案恰恰相反:关键是用最笨的办法,把主 AI 的手脚捆死,逼它别自己下场干活。 这套机制有个正式名字,叫 Coordinator 模式(协调者模式),得手动打开一个开关才能启用(CLAUDE_CODE_COORDINATOR_MODE=1)。 一旦打开,主 AI 的身份就被它的系统提示词强行焊死成一个"协调者"(包工头):你的活不是自己搬砖,是指挥手下的工人(源码里叫 worker)去调研、去施工、去验收,然后把结果汇总、跟客户(用户)交代——能自己一句话答的别麻烦工人,但该派出去的活,绝不许自己上手抢着干。 手脚捆死之后,那句点睛的指令才生效——源码里给包工头的命令里有一句我特别喜欢,原文是 "Parallelism is your superpower"(并行,是你的超能力)。工人都是各干各的、不用互相等,所以能同时上的活,绝不许排队一个一个来。 但这里有一条红线,是整套设计的灵魂,也最容易被做砸:包工头必须自己"看懂",不能只当"传话筒"。 源码里反复叮嘱:工人把调研结果交回来之后,包工头必须自己把这些结果读懂、嚼碎、写成一份明确的施工图纸,再派下去,绝不许偷懒甩一句"就照你查到的去改吧"。 这句话点破了整个多 AI 系统的命门。如果包工头只是个传话筒,把张三的话原样转给李四,那它压根没有存在的必要——工人直接跟客户对话就行了。包工头值钱,恰恰在于它是唯一一个看着全局、能拍板的人。它必须在中间那个"汇总+出图纸"的环节真正动脑子,整支队伍才有意义。 把四锤连起来,把这四样东西摆在一起看 多 AI 协作,不是一群 AI 自己学会了合作。是有人在背后,把几个各自为政、互不相识的 AI,硬拼成了一台能协同干活的机器。 通信,是两个 AI 互相留纸条。隔离,是一项一项手工抠出来的"什么给、什么不给"。省钱,是为了吃折扣而抠到一个标点都不差。并行,是用一段指令把主 AI 焊成包工头、再把工人的招人权收掉。 四样里,没有任何一样是"AI 在协作"。全是有人在 AI 外面,用留纸条、复印、没收权限、伪装身份这些土到掉渣的老办法,一锤一锤搭出来的脚手架。AI 在这套脚手架里,只负责它最擅长的那一件事——在每个被圈好的格子里动脑子。至于这些格子怎么摆、消息怎么在格子之间传、谁能指挥谁、记忆会不会串味,全是脚手架的事,跟 AI 聪不聪明无关。 这正好接上这个系列一直在说的那句话:决定一个 AI 系统行不行的,不是里面那个模型,是外面这层"脚手架"(也就是 harness)。 谁把这层笨功夫看明白了,谁才算真懂多 AI 协作。