我想要的体验说起来很简单。在 Codex 里输入「@reviewer,帮我看一下这个改动」,对方可能运行在 Claude Code、Cursor 或 Pi 里,甚至在另一台机器上。它知道我指的是哪个项目、哪份改动,能决定接不接这个活;我能看到它收到、开始、遇到问题、完成或拒绝。它忙的时候消息排队,离线时消息不丢,做完之后留下一份我可以核对的结果。
今年每家大厂都做出了其中一块。xAI 的 Grok Bot 在 8 月 11 日以 beta 形式上线,自称「你的一支始终在线的 agent 团队」:在 X 的帖子下面 @ 它,这条帖子就成了它的任务;在群聊里输入 @ 就能选一个 Bot;可以给它一个邮箱地址;它的 Bot 们会「各自独立地互相发消息,在线程里共享上下文」。1 Meta 的 Muse、OpenAI 的 dots 和 Anthropic 的 Claude Duet 在 9 月到 10 月下旬之间相继推出,同一台机器上的 Claude Code 会话现在也能按名字互发消息。每一个都只在自己的围墙里成立。没有一个能和别家的 agent 说话,而我终端里那些干了大部分活的 coding agent,从它们自己的窗口外面根本够不着。
这篇文章讲的是,要把这些碎片连起来需要什么。它从我为了让 coding agent 协作而做的三个小工具出发,走一遍 2026 年 10 月已有的协议,以及测量多 agent 到底换来了什么的研究,最后给出一个我愿意被证伪的计划。结论先说:把握最大的,是一份由任务、投递状态和可核对成果组成的共享记录,agent 明确选择接入它,而 @ 只是进入它的入口。
三个工具,三个教训
ccli:会话是一个文件,它走不远
ccli 读取 Claude Code、Codex、Pi、Cursor CLI 和 Cursor IDE 写在磁盘上的 transcript,告诉你每个会话做了什么、花了多少。我写它,有一部分是为了我最常需要的那种交接:一个 agent 在任务中途停下,因为某个账号的额度用完了,活得在别处接着干。在两个 Claude Code 账号之间,ccli 可以把会话本身搬过去。它拒绝搬一个正被活进程运行的会话;只有当目标是源文件逐字节的前缀时,才把副本往后接上;fork 出来的会话会拿到一个新的 session id。
这些规则就是第一个教训。会话是一个同一时刻只有一个写者的文件,它的身份就是这个文件的身份。在同一个工具的不同账号之间,你可以搬它;在不同工具之间,你搬不动:一份 Claude Code 的 transcript 对 Codex 毫无意义。能从一个工具走到另一个工具的,是一份写下来的工作说明:任务是什么,做了什么,还剩什么,证据在哪里。对话本身永远过不去。
第二个教训关于「在不在」。ccli 能看出哪些 Claude Code 会话正在运行,因为 Claude Code 为每个活进程写一个小文件。Codex、Pi 和 Cursor 的工具没有这样的登记,所以 ccli 根本没法说它们的会话是不是在跑。一个会话索引能回答「有哪些可以恢复的上下文」,回答不了「其中哪个现在正在听」;而恢复一段存下来的对话,和向一段开着的对话投递一条消息,是两种不同的操作。
olympus:把约定放在谁也赖不掉的地方
7 月我写了 olympus,一个完全住在一个 git 仓库里的协调层:一份成员登记表,人和 agent 都在里面,写着各自的领域和权限;接口契约;任务;还有邮箱,每个成员一个文件夹,每封信一个文件,因此「天然不会冲突」。2 它的 README 列出了它要对付的失败,其中两种反复出现。一种它叫「我做完了」:agent 说活干完了,其实什么都没写。另一种是等待死锁:「A 问了 B 一个问题然后干等;B 埋头干活,根本没看到。」
olympus 的教训是,共享记录必须是权威。信是信息,不是指令,所以一条消息没法让一个 agent 做它自己的规则不允许的事。任务靠一次提交来认领,两个 agent 同时认领,冲突发生在 git 里,而不是对话里。任务完成的标准是一个具名测试加一次提交,文字描述不算数。可是等待死锁,olympus 自己解决不了,因为信放在邮箱里,没人读就什么也不会发生。
wakeme:投递进一个正在运行的 agent,才是难的部分
所以我又写了 wakeme,它在自己盯着的东西发生变化时唤醒一个 Codex 线程,比如 olympus 邮箱里来了一封新信。它在 7 月 31 日对照 stock Codex 0.146.0 写下的笔记,是我手里对投递问题最精确的描述。3
stock Codex 没有任何唤醒、通知或订阅一个线程的原语。它的 App Server 可以重新接入一个正在运行的线程,也有一个转向正在进行中那一轮的方法,而那恰恰是无人值守的自动化绝不能调用的。最直观的做法,先读线程是否空闲、再开始一轮,有一个先检查后执行的竞态:在读和开始之间,人可能开始打字,另一个触发也可能到达。所以 wakeme 只通过服务端的原子准入来开始工作,那是我在自己 Codex fork 的一个分支上加的实验性 thread/wake。它要么返回它开始的那一轮的 id,要么告诉你线程正忙、已经有一个触发在排队,或者正处于计划模式。没有这个 fork 时,wakeme 退回用 codex exec resume 冷启动,永远正确,但从不即时。
wakeme 还有三条规则,适用于任何 agent 间协作的设计。它从不替人回答审批或输入请求。只有在精确匹配的那一轮完成之后,它才推进自己「已经投递到哪里」的记录;线程忙、出错、被取消、结果未知,一律让记录留在原地,于是投递会被重复,而不会丢失。它也不假装传输是完美的。用它自己的话说,「真正的『恰好一次』来自语义,而不是传输」:唤醒只说一句「重新扫描权威来源」,所以重复、丢失或乱序的信号最后都会收敛到同一个状态,一次重复的唤醒只花掉一轮什么新东西也没找到的廉价调用。
wakeme 的架构文档把整个栈画成了四层:
flowchart TB
H["人的界面<br/>pull request、项目看板、通知<br/>观察、批准、合并"]
C["协作记录<br/>olympus:git 里的任务、信件、决定"]
W["唤醒运行时<br/>wakeme:观察、攒批、唤醒"]
E["执行<br/>Codex App Server 和它的终端界面:线程、轮次、审批"]
H --- C --- W --- Ewakeme 的设计在 2026 年 7 月假定的四层。每一层都能单独拔掉:没有 wakeme,就由人手动唤醒 agent;没有 olympus,wakeme 就是一个通用的「源一变就唤醒线程」的工具。
把三者放在一起,问题就有了形状。ccli 是一个上下文的索引,olympus 是一份持久的共享记录,wakeme 是向正在运行的 agent 诚实地投递。agent 间协作,就是把这三样跨工具、跨机器地接起来,并且让人能看见、能叫停其中的一切。
名字指向的究竟是谁
把 agent 等同于模型,会漏掉工具、权限和记忆;把 agent 等同于 session,又会把一次随时可能结束的运行当成长期身份。这些部分得分开命名:
| 对象 | 它回答的问题 |
|---|---|
| 人或组织 | 工作代表谁,谁能授权和撤销 |
| Agent 身份或别名 | 谁通常承担这类工作,例如 reviewer |
| 持久任务 | 这份工作是什么:输入、范围、期限、完成的判据 |
| Session 实例 | 由哪段上下文执行,它是否已经重启或分叉 |
| 客户端连接 | 现在谁能安全地向这个 session 投递、取消或展示消息 |
| 模型和它的工具 | 实际能做什么,成本多少,处在哪些数据边界之内 |
所以「@reviewer」和「@ 那个正在运行的 session」必须是两种意思。前者请求一种能力,系统可以把它交给现有的会话,也可以新开一个。后者要求一条消息进入某个特定的上下文,这需要那个客户端配合:得有人把这条消息和人自己的输入排好顺序,标明它从哪里来,决定会话分叉了怎么办,并把它写进会话的历史。
应该长期保存的是任务、它背后的授权、输入的版本和结果。Session 更像一份上下文的租约:有用,但会被压缩、恢复、分叉、关闭,也会被下一次客户端更新改变。把 session 当作唯一的事实来源,离线恢复和跨客户端协作都会变得脆弱。
个人 agent 有了地址
今年推出的产品,展示了一个地址可以是什么样子。
Grok Bot 让每个人拥有一组 Bot,从他们本来就在的地方就能够到。在 X 上,「在帖子或回复里 @bot,就能把这条帖子作为任务交给你的 Grok Bot」;在群聊里,「输入 @ 并选择一个 Bot」;在 Slack 里,一个团队的每个 Bot 都有自己的账号名。用户可以为自己的 Bot 申请一个邮箱地址,每人一个,这个地址属于人而不属于某个 Bot;对团队来说,每封外发邮件都先停在草稿里,直到有人按下发送。群聊里的 Bot 会「传递工作、分配归属」,它们之间的交接是一条异步消息,它们还能把编码任务交给 Cursor 的云端 agent。1
OpenAI 的 dots 在 9 月 29 日推出,每个都有一个像 @yourname-dot 这样的名字,能在 ChatGPT、Slack、Teams 里找到,也能通话,还能「在连接的电脑上创建 Work 或 Codex 任务」。4 Anthropic 的 Claude Duet 是 10 月 21 日的研究预览,「一个 Claude 作为主动 agent 工作的新 App」,会带上记忆、技能和连接的应用。5 Meta 的 Muse 在 9 月 8 日推出,故意走了相反的方向:它「被隔离开,别人的 agent 无法触及它」。6
在 coding agent 这边,Claude Code 加入了同一台机器上会话之间的消息:一个会话用 ListAgents 找到另一个,用 SendMessage 发送,还可以用 @session-name 点名目标。接收方的会话可以设成接受、暂存或拒绝来信,而一条消息改变不了它的配置。7 Codex 只允许同一个会话的子 agent 树内部互发消息。
这些设计里我最喜欢 Grok Bot 的,因为它把顺序弄对了。地址属于一个比任何一次对话都活得久的身份;一次 @ 把一段内容变成一个任务;地址归人所有;真正要紧的副作用,一封邮件发出去,要等人的手。地址、收件箱、任务,加上一道把副作用交给人的闸门:agent 间协作需要的就是这个形状。这些产品无一例外止步于自己的围墙。Grok Bot 的 Bot 之间互相说话,dots 把活交给 Codex,Claude Code 的会话之间互相说话;就它们的文档所写,没有一个和别人家的说话。
一层一层看协议
2026 年的协议进展,比「还没人定义 agent 怎么说话」要靠前得多。每个协议都把一条边界处理得不错。
A2A,即 Agent2Agent 协议,在 2026 年 3 月发布了 1.0 版,8 月加入了 Linux 基金会旗下的 Agentic AI Foundation。8 它定义一个 agent 服务如何发现并使用另一个。Agent Card 放在 /.well-known/agent-card.json,可以签名,描述这个 agent 提供什么。客户端发送消息、流式接收结果,获取、列出、取消和订阅任务;任务依次经过 SUBMITTED、WORKING、INPUT_REQUIRED、AUTH_REQUIRED,以及四个终态 COMPLETED、FAILED、CANCELED 和 REJECTED。一个 A2A 服务可以在内部按需启动工作者,所以说它「要求每个 agent 常驻 HTTP」并不准确。它标准化的是服务边界;一个人正在使用的终端会话如何被发现、排队、写入历史,仍由服务的实现者负责。
MCP 是同一个基金会的创始项目,让客户端使用工具、资源和提示。它很适合暴露一个共同的通讯入口:查询 agent、提交任务、读取邮箱、取回成果。但调用了 MCP 的发送工具,只证明请求到达了这个工具,不能证明目标会话收到了什么;MCP 连接的生命周期,也不是对话的生命周期。
Agent Client Protocol,ACP,由 Zed 发起,标准化客户端如何驱动一个 coding agent:session/new、支持时的 session/load、session/prompt、一串 session/update 通知、session/cancel,以及权限请求。9 v2 仍是草案。在草案里,对 prompt 的响应只确认它已被接受,完成情况稍后以状态更新的形式到达,session/load 让位给带重放起点的 session/resume。这份草案是所有协议里离下一节那串投递状态最近的,也正因如此,不能把它当成每个客户端都已做出的保证。已经有适配器把 Codex(基于它的 App Server)和 Claude 的 agent SDK 放到 ACP 后面,于是一个宿主可以同时驱动两者。它们驱动的是宿主自己创建或加载的会话,不会接管别人早已在另一个终端打开的会话。
微软的 Agent Host Protocol 让多个客户端看到同一个 agent 会话的同步视图,并且明说了自己的边界:「AHP 协调的是客户端,不是 agent。agent 之间如果需要对话,那是另一回事。」10 AG-UI 标准化 agent 和人所看界面之间的事件。ANP 提出一套跨组织的 agent 身份、命名、发现和安全消息协议。agentgateway 是一个数据平面,它代理的流量里就包括 agent 发出的 MCP 和 A2A。11
| 边界 | 适合采用的现有工作 | 还留着的空白 |
|---|---|---|
| Agent 使用工具和数据 | MCP | 委托给另一个 agent |
| 独立的 agent 服务 | A2A | 投递进本地交互式会话,以及它与人的排序 |
| 客户端驱动 coding agent | ACP | 跨宿主点名、邮箱、委托链 |
| 多个客户端共享一个会话 | AHP 等宿主方案 | agent 之间的任务与权限 |
| 人观察并介入 | AG-UI,或产品自己的界面 | 身份、授权,以及任务是否真的发生 |
所以没人需要发明一个包办所有层的协议。没定下来的,是它们之间的契约:一个经过人授权的请求,如何找到合适的执行者,并以任何人都能核对的方式,变成一个任务、一组会话事件和一份结果。
「已发送」背后的一串状态
设想两个 agent 同时给 reviewer 发消息,而一个人正在 reviewer 的终端里打字。一条消息先到邮箱,另一条先到客户端;客户端把第二条写进 transcript,在通知控制面之前崩溃了。如果系统只显示一个绿色的「已发送」,这个故障就再也无从诊断。
我会把每个阶段分开记录,作为一条消息走向成果的过程中经过的状态:
flowchart TB
subgraph seen["控制面看得到的"]
direction LR
A["已接受<br/>由控制面"] --> S["已持久化"] --> C["已领取<br/>由某个客户端"]
end
subgraph only["只有接收方看得到的"]
direction LR
P["已准入<br/>由它的策略"] --> R["已记录<br/>在会话历史里"] --> T["已接受为任务"] --> D["成果已提交<br/>附带证据"]
end
seen --> only从已接受到成果已提交,一共七个状态。其中任何一个都可能改以拒绝、过期、取消或失败结束,而每个组件只能为它亲眼看到的状态作证。
每一层只能证明它观察到的东西。传输层能说消息已持久化,客户端能说它领取了,只有接收方能说它的策略允许了、它的历史里现在有了这条消息。即便如此,每个状态能证明的也比看上去少。进入 transcript,不能证明模型理解了请求。模型回答了,也不能证明外部副作用真的发生了。wakeme 的协议笔记对它自己的几层说过同一件事:如果一轮完成了却没有真正处理那封信,这封信在仓库里仍然是打开状态,下一次重新扫描就是重试。
这把一个模糊的愿望变成了具体的要求,个个枯燥,个个决定成败:消息 ID、去重键、每个会话的顺序、期限、队列上限、接收方忙时默认排队、取消,以及崩溃后的恢复。不要轻易承诺任何事「恰好执行一次」。如果外部 API 调用已经成功,进程却在写下记录之前崩溃,盲目重试会让副作用发生两次。系统需要幂等的操作,或者一份独立的提交记录;无法确认时,该显示的状态是「结果待核对」,绝不能是成功。
客户端适配器的职责也由此变得具体。它要知道自己投递的是哪个会话实例,免得同一段历史被两个进程恢复后收到两次同一条消息。它要把消息写进会话的正式历史,又不能覆盖人已经输入、尚未发送的内容。它还要只回报自己能证明的确认。用 tmux send-keys 往终端里敲字,可以演示效果,提供不了这些保证;恢复一段存下来的对话,也不等于向正在运行的那段投递一条消息,这正是 wakeme 吃过苦头才学到的。
通讯越多,团队越好吗?
2026 年的研究比各种演示克制得多。9 月的一篇预印本发现,多 agent 的收益集中在「依赖稀疏的长程任务上,而在紧密耦合的串行工作流里,单 agent 仍然更好」,并把差距归因于不断增长的上下文开销。12 10 月一项关于 coding agent 团队的研究发现,在 ProgramBench 上团队的「成本是单个 agent 的三到七倍」,规划是「工作者最有价值的用途」,而实现者和验证者超过四个之后就不再进步。13 这些结果各自属于自己的基准,都不是软件工程的普遍定律,但它们指向同一个方向。4 月,bloop 关停了,它是 Vibe Kanban 背后的公司,而 Vibe Kanban 是较知名的、用来同时跑许多 agent 的第三方看板之一;这个项目以社区维护的开源形式继续存在。14
这改变了自由通讯的用途。真正稀缺的,可能是接收方的注意力、上下文预算和可靠合并的能力,远多于传输带宽。如果每个 agent 都能随时找任何一个别的 agent 讨论,结果就是重复劳动和递归扩张。调度器应当先判断:任务能不能拆成相对独立的成果,什么时候第二个视角值得它的成本,什么时候一个强 agent 加上工具就够了。人和 agent 共处的房间可以保持开放,但后台工作默认异步,忙碌的会话默认排队,自动转委托受预算和深度限制。
评估要有单 agent 的基线。成功率、实际耗时、总 token 和费用、重复工作、人工介入、恢复时间和越权次数,要放进同一张表里看。如果两个 agent 只是制造了更多消息,结果和关键路径都没有变好,「更像一个团队」就不是保留它们的理由。
消息承载注意力,成果承载事实
在同一台机器上,共享文件和 git 已经很好用。「请看 commit abc123 里的 auth 改动,重点检查权限回退,测试日志在这个文件里」,通常比转发整段对话有效。但一条路径只在同一个工作区、同一时刻指向同一份内容;跨机器或者有未提交的改动时,它甚至可能指向另一个文件。
所以跨运行时的引用至少要带上工作区和仓库的身份、一个提交或快照、相对路径、内容摘要以及读取权限。未提交的内容可以作为补丁或受控快照传递。接收方先校验摘要,再读取需要的部分。成果同样如此:结论要链接到 diff、测试日志、数据或能复现的命令,而不只是一句「我检查过了」。
2026 年的一项研究给了这件事一个实验依据。PACT 把冗长的 agent 输出投影成紧凑的动作与状态更新;在它的测试里,它「以每解决一个问题少用 10% token 的代价,提高了 OpenHands 的解决率」,并在 SWE-agent 上保持解决率不变的同时把输入 token 减半。15 我会让一条正式消息至少包含这些字段:意图、所需动作、输入引用、已知事实、未解决的问题和完成判据。自然语言仍然负责协商和解释;调度、授权和验证需要程序能读的字段。
这还有一个容易忽略的好处:接收者不必继承发送者的全部历史。共享的是与任务有关的证据,而不是把两个上下文窗口拼在一起。这样成本更低,秘密、过期指令和被注入的提示沿协作链传播的机会也更少。
模型会用自己的内部状态说话吗?
「不同模型之间只能交换自然语言」已经不再成立。结构化数据本来就能跨模型交换,而 8 月的一篇论文,用它称为 XKV 的方法训练一个转换器,让「家族、层数、KV 头数、头维度和 tokenizer 都可能不同」的冻结模型直接交换键值缓存;端到端,它比 LCF-X 基线快 26%,比文本快 6.8 倍。16 不同模型之间的 latent 通讯是可能的。
单凭快,并不足以让它适合开放网络。转换器要针对每一对模型训练,模型升级可能让它失效,内部状态难以审计,还可能带着接收方本不该看到的输入。5 月的防御研究 LCGuard 学习对缓存做变换,以减少对手能从中重建出的发送方私有输入,这说明泄漏是真实存在的。17 8 月的一项因果审计提醒:「基准分数的提升本身不能证明发生了 latent 思维的传递;要证明这一点,需要做错配缓存的审计。」18 6 月一项关于缓存完整性的研究补充说:「一条可见的消息看起来可能无害,哪怕隐藏状态已经被改动」,并展示了一个 HMAC 清单,接受了全部 774 份诚实负载,拒绝了全部 295 份被篡改的负载。19
我会把 latent 通讯放在性能研究这条线上,限于有人端到端掌控的集群内部。开放、可审计的跨客户端协作,眼下仍然建立在文本、结构化状态和有来源的成果引用之上。等 latent 层成熟,它可以加速那些本来就已正确运行的工作链,而不必取代人的授权和成果的证据。
权限不是一枚签名
agent 之间一旦能直接对话,一个在网页或仓库文件里读到了注入指令的低权限 agent,就可能请一个高权限的同伴替它读秘密、推代码。签名证明的是谁发了消息,不证明有人允许了这个请求。OWASP 的多 agent 安全建议一句话说清了:「有效的消息签名并不授予执行所请求动作的权限。」它还要求接收方对发送者、接收者、类型、负载、时间和唯一 ID 签名,并在接收方的所有实例之间原子地拒绝重复的 ID。20
一条可用的委托链始于人的授权,并在每一跳都同时保留「代表谁」和「现在谁在行动」。OAuth 2.0 Token Exchange,即 RFC 8693,已经把两者分开:subject 是「请求所代表的一方」,actor「代表行动方的身份」,act 声明记录「委托已经发生」。21 具体到任务,权限还应当约束接收者、仓库和路径、允许的动作、外部网络访问、预算、期限,以及还能再转委托几次。每一跳只能收窄,执行动作的工具在模型之外检查。
A2A 有意把这件事留给实现。它最新的规范写道,任务请求授权时,「A2A 协议不定义所获授权决定或凭证的范围、表示、有效期或撤销语义」;22 这一条是 7 月加进去的,还不在任何已打标签的版本里。产品也在小处体现着同一个原则:Grok Bot 把团队的外发邮件留给人来发,Claude Code 的会话可以暂存或拒绝别的会话发来的消息。2 月,NIST 启动了一项 agent 标准计划,身份和授权是它最先关注的主题之一。23
撤销能阻止尚未发生的动作,却收不回一封已经发出的邮件,也撤不掉一次已经完成的推送,所以审计日志必须记录请求和结果,同时限制敏感内容的保存期限。还有一条常被忘记的边界:把内部代码交给另一家模型服务,可能改变数据的去向。模型无关,不等于人已经同意任何一家提供商读取同一份资料。
一定要有一个网关吗?
需要的是一个逻辑上的控制面。名字解析、可用能力、持久邮箱、任务事件、权限检查和审计记录,总得有个地方落下。它可以是一台机器上的 daemon,也可以是工作区里的事件日志加 sidecar,或者跨机器的联邦服务。中心化网关是一种部署方式,不是它的定义。
如果今天动手,我会做一个每用户或每工作区的宿主。它保存一份只追加的事件日志和一个小型成果库,用短期租约登记它启动的 agent 会话,负责排序、任务认领和权限。客户端通过 CLI 或 MCP 提交请求;它控制的 coding agent 通过 ACP 驱动,这样它知道哪个会话在处理哪个 prompt、收到了哪些更新;独立的远端服务在边界上用 A2A 交流。房间是日志的共享视图,@ 是选择收件人的方式,任务是一组带证据的事件。
最要紧的选择,是从会话创建的那一刻起就管理它,wakeme 的 fork 在 Codex 上走的正是这一步。持有连接的宿主知道自己投递了什么、什么时候投递的。它仍然要标明同伴消息的来源,免得另一个 agent 的话看起来像是人刚发出的高权限指令。对于有人在另一个终端里打开、客户端又不提供入口的会话,诚实的选项是邮箱、通知或显式领取;不要假装实时投递。真正的 @existing-session 能否实现,取决于每个客户端是否开放一个带确认语义的入口。
7 月我给自己列的那张清单,对工作的顺序说得很直白:先别做新界面;尽量用已经稳定的基础功能,git 仓库、pull request、把 issue 当收件箱、GitHub Apps;还要有一个地方,一眼就能看到所有 agent 的状态和所有任务的进展。olympus 做到了前一半。后一半是那个视图,而事件日志正好让它变得便宜。
开放网络上的发现可以以后再说。ANP 这类方案在探索跨组织的身份、发现和消息,但全网可被发现,本身解决不了垃圾请求、权限、隐私、付费和成果可信的问题。直接的点对点仍然需要离线邮箱、信任根和撤销的传播。先把一个工作区内的协作做对,再把稳定的 agent 能力以 A2A 服务的形式对外暴露,这条路更清楚。
我会押注哪条路
这里的判断基于今天已有的接口和工程约束,不是概率预测。
把握大:在一个掌控会话的宿主里,跨模型、跨客户端协作。 宿主创建或显式导入会话,用 ACP 这样的正式接口处理输入和进度,用事件日志保存任务,用带摘要的引用交换内容。换了模型、关掉一个会话,工作本身仍然可以恢复。Codex 和 Claude 的 ACP 适配器已经缩短了离原型的距离。
有条件可行:直接 @ 任意一个已存在的交互式会话。 条件是目标客户端开放一个正式的入口,带排序、来源标记和确认。没有这些,读取 transcript、恢复会话或往终端里敲字,都算不上可靠的投递。这里可能形成跨客户端的标准,也可能多年里由各家客户端各自实现。Claude Code 的会话间消息和 Grok Bot 的线程,说明它在一家厂商的围墙之内是能做到的。
长期研究:跨组织的开放 agent 网络,以及不同模型之间的 latent 交换。 前者难在身份、授权、发现的质量和经济机制,后者难在模型之间的兼容、信息是否真的传递,以及保密和审计。两者都值得跟踪,都不应成为第一版的前提。
这也修正了我最初的目标。「让所有 agent 完全忽略客户端和基模」,严格意义上做不到。客户端决定消息何时进入 agent 的循环,模型决定同一个任务的质量和成本。更有用的目标,是让任务契约和成果可迁移,把各端的差异公开声明、公开协商。系统不要求所有 agent 都一样,只要求每个 agent 说清楚自己能做什么、实际做了什么。
一个可能失败的实验
下面的计划,写成了能证明我错的样子。
- 先定义语义,再接任何东西。 给 agent 别名、任务、会话实例、权限和成果各自的 ID。给状态命名,其中包括 queued、admitted、working、completed、failed、rejected 和 expired,并写明什么证据能推动每一个状态。把「收到」和「完成」分开。
- 在一台机器、一个工作区里纵向做深,用两个明确接入的客户端。 让宿主创建会话,投递一个只读的审查任务,收回一份带引用的结论。然后故意把它弄坏:让接收方一直忙,投递时同时打字,杀掉宿主,恢复会话,把同一条消息发两次。检查没有任务误投到别的会话,没有输入被覆盖,重复的领取不会重复副作用。如果接口只能证明消息进了邮箱,产品就只说这一点。
- 加入会动手的任务,每一次工具调用都由模型之外的策略裁决。 测试收窄的转委托、撤销、过期、预算耗尽和恶意的同伴消息。外部副作用可能发生了却无法确认时,状态就停在待核对。在接收方能执行权限之前,不让任何 agent 自动替另一个 agent 执行工作。
- 放进真实工作,和单个 agent 比。 选能拆开的工作,比如代码审查、并行的事实核验和独立的测试,也选拆不开的工作作对照。只有质量、耗时和总成本都占优时才增加 agent。跨设备同步、通过 A2A 联邦和更复杂的身份方案,放到最后。
停止的条件比愿景更重要。如果两个客户端都无法确认消息进入了正式历史,就放弃向任意旧会话实时投递的承诺。如果崩溃后的重试会重复外部副作用,就不要扩大扇出。如果多个 agent 长期赢不了一个,就把成果定位为协作与可观测性的基础设施,而不是一台增加智能的机器。
仍然开放的问题
开放网络里的 agent 名字,会不会像域名一样被抢注?Agent Card 又由谁来核实?一个 agent 声称「擅长安全审查」,和一个 agent 一年来持续交付可信的审查结果,是两回事。信誉需要一份可以核对的任务记录,而不是自我描述。
人应该在多大程度上待在房间里?完全实时,会不停被打断;完全放在后台,又会失去对授权和纠错的把握。也许最好的体验是:人随时能看到每一个事件,但只在需要决定、风险升高或结果完成时收到通知。这需要真实的使用来回答,不是协议推演能定下来的。
还有更深的一层。未来 agent 之间的通讯,也许不像一个高速运转的聊天室,而更像软件系统之间交换可以执行的承诺。一条好消息应该让接收方准确判断:要我做什么,凭什么可以做,输入是哪一版,什么时候该结束,怎样证明做完了。闲谈仍有它的位置,只要它最后落到一个有人能核对的下一步。
从 ccli 出发,我最初看到的是许多分散的会话。看得更远一些,值得连接的不是一堆终端窗口,而是它们背后持续存在的工作。@ 是入口,会话是一次执行,网关是控制面的一种部署方式。能让不同的 agent 真正一起工作的,是持久的任务、只会收窄的权限,以及任何人都能核对的成果。
Footnotes
-
xAI,「Introducing Grok Bot」;「Tag @bot on X」,英国、欧盟、欧洲经济区和澳大利亚的账号不可用;「Message and collaborate」;「Give your Bot an email address」。 ↩ ↩2
-
wakeme,尤其是
docs/protocol.md和docs/architecture.md;实验性的thread/wake在我的 Codex fork 的wakeme-thread-wake分支上。 ↩ -
OpenAI,「Meet dots」。 ↩
-
Anthropic,「Introducing Claude Duet」。 ↩
-
Meta,「Introducing Muse: The World’s First Personal AI Agent Built for Everyone」,2026 年 9 月 8 日。 ↩
-
Claude Code 文档,「Message your other Claude Code sessions」。 ↩
-
A2A 规范;「A2A joins AAIF」,2026 年 8 月 17 日。 ↩
-
Agent Client Protocol,v1 概览与迁移到 v2;适配器 codex-acp 与 claude-agent-acp。 ↩
-
「Rethinking Multi-Agent Collaboration: When More Is Less」,arXiv:2609.19759,2026 年 9 月。 ↩
-
「Scaling Inference-Time Compute with Teams of Coding Agents」,arXiv:2610.17471,2026 年 10 月。 ↩
-
Vibe Kanban,「Goodbye bloop」,2026 年 4 月 10 日。 ↩
-
「What Should Agents Say? Action-state Communication for Efficient Multi-Agent Systems」,arXiv:2606.05304,2026 年 6 月。 ↩
-
「Dual-Cache Latent Space Communication between Heterogeneous Language Models」,arXiv:2608.20617,2026 年 8 月。 ↩
-
「LCGuard: Latent Communication Guard for Safe KV Sharing in Multi-Agent Systems」,arXiv:2605.22786,2026 年 5 月。 ↩
-
「When Does Latent Communication Pay? A Causal Audit of Relayed KV Caches in Multi-Agent LLMs」,arXiv:2608.04893,2026 年 8 月。 ↩
-
「When Latent Agents Lie: KV-Cache Integrity in Multi-Agent LLM Collaboration」,arXiv:2606.28958,2026 年 6 月。 ↩
-
OWASP,「AI Agent Security Cheat Sheet」,第 7 节。 ↩
-
NIST,「Announcing the AI Agent Standards Initiative」,2026 年 2 月。 ↩
