posts/claude-code-session-messaging.md
Claude Code 会传话了,别让它们改同一份代码
Claude Code 刚补上了一个很像人类团队的动作。
一个会话,可以给另一个会话传话。
Claude Devs 的官方演示 里没有绕弯子。你不用再切到另一个终端,把背景、目标和做到哪儿重新讲一遍。Claude 会整理一份摘要发过去,接收方哪怕正在干活,也能在任务中途拿到。
而且传的是摘要,不是完整历史记录,也不是文件。
好家伙,常年开着几个终端、一个 tmux 网格,再靠脑子记住谁在改 API、谁在补测试的人,终于少当一回人工消息队列了。官方帖抓取时已经有约 349.7 万次浏览,社区当天也在追问,前端会话和后端会话是不是终于能自己交接。
我的判断可能有点扫兴。
会传话,是多 agent 开发迈过的一道门槛。可它离真正会协作,还差一整套工程协议。
传一句「接口已经改完」很容易。保证接口真的改完、没有顺手动坏别人的文件、测试跑过、失败能重试、冲突有人收口,才是这件事最费劲的部分。
所以这篇不复述按钮在哪。我更想聊聊,跨会话消息到底解决了什么,没解决什么,以及同时开多个 Claude Code 时,怎样别把效率提升写成一场并发事故。
摘要不是共享大脑
先把最容易误会的地方掰开。
Claude Code 官方说得很克制,发送方交付的是 summary,也就是一份摘要。这个设计挺合理。完整历史记录里有大量工具输出、试错过程、旧结论和路径细节,一股脑塞给另一个会话,不但贵,还会污染它正在做的事。
Claude Code 工作原理文档 明确写着,每个新会话都有独立的上下文窗口。消息、工具调用和结果会保存在本地 JSONL 文件里,但会话默认彼此独立。早期指令还可能在上下文压缩时丢掉,所以长期规则应该放进 CLAUDE.md,不能只指望聊天记录记住。
跨会话摘要做的,是在两块独立上下文之间搭一座窄桥。

窄桥有窄桥的好处。接收方不用背上发送方全部历史,只拿完成当前任务需要的那一点信息。可摘要天然是有损压缩,里面至少有三种东西容易掉。
第一种是约束。发送方可能知道某个字段只能新增、不能改名,摘要只剩一句「接口已更新」。
第二种是证据。发送方说测试通过了,却没有带上测试命令、提交哈希和失败过的边界条件。
第三种是未决项。它把「主路径已经通了,但回滚还没测」压成「主路径已经通了」。前半句没错,后半句也没撒谎,组合起来却很容易让下游误判完成度。
这跟分布式系统里的消息没什么两样。消息送到了,不代表状态一致。摘要读懂了,也不代表双方对「完成」的定义一样。
厉害了,两个 Claude 都能用自然语言聊天,末了还是逃不过 schema。
真正靠谱的交接消息,至少要带任务状态、改动边界、产物位置、验证方式和未解决风险。不是为了把一句话写成周报,而是让接收方能独立核验,不需要相信发送方的语气。
消息能到,锁并不会自己长出来
更麻烦的是文件。
假设一个常见场景,前端会话负责登录页,后端会话负责认证接口。两边都发现 types/auth.ts 里的类型不够用,于是同时修改。它们提前互相说了一声,甚至都很礼貌。
然后呢?
Git 还是会冲突。测试还是可能只在各自分支通过。某个会话还是可能顺手格式化整份文件,让真正的业务差异淹没在几百行 diff 里。
消息传递能降低认知冲突,不能替代写入隔离。
Anthropic 其实已经在 Agent view 文档 里给出了工程答案。后台会话在真正编辑文件前,会移动到独立的 Git worktree。不同会话可以读取同一个仓库,但各自在自己的工作目录和分支里写。一个会话产生的修改,不会直接踩进另一个会话正在看的 checkout。
这套设计比「大家先在群里说一声」靠谱得多。

Git 官方的 worktree 文档 解释了底层机制,一个仓库可以同时挂出多个工作目录,每个目录检出不同分支。对多 agent 来说,它等于给每个工人一张独立工作台。大家用的是同一份仓库对象库,但不会在同一块桌面上抢螺丝刀。
不过这里有个坑。
官方文档也提醒,如果项目不是 Git 仓库,或者你把 worktree.bgIsolation 设成 none,后台会话可能直接在同一工作目录里写。此时跨会话消息越顺畅,反而越容易让人高估安全性。它们聊得像个团队,落盘时却还是两个进程抢同一份文件。
这玩意有点像给两辆车装上对讲机,却没画车道线。司机能交流当然是好事,弯道里会不会撞,仍然取决于道路隔离和通行规则。
所以我不建议把任务写成「你做前端,你做后端」就开跑。边界还得落到目录、文件和接口上。
可以明确规定,前端会话只改 apps/web/,后端会话只改 services/api/。共享类型由第三个集成会话处理,或者指定唯一 owner。谁需要跨边界修改,先发变更提案,不直接落盘。
听着像项目管理?没办法。并发一上来,管理就是运行时的一部分。
给多会话一份能验收的交接协议
很多朋友可能会问,那发消息时到底该写什么。
别写「我做完了」。这四个字的信息量接近于零。
我更推荐把交接压成一个很小的契约。它不需要复杂平台,放进项目规则或任务提示就够用。
状态
done 或 blocked
改动边界
只列实际修改的目录与关键文件
产物
分支名、提交哈希、PR 或补丁路径
验证
实际执行的命令与结果
接口变化
新增、删除、兼容性与迁移要求
未决风险
没测什么、猜测什么、需要谁确认
下一位动作
接收方拿到后要做的唯一下一步
这份模板看着朴素,作用却很直接。
状态把「进展」和「完成」分开。改动边界让接收方先判断有没有越权。产物给出可追溯锚点。验证不是一句测试通过,而是 pnpm test auth、pytest -q tests/test_login.py 这类可重跑命令。未决风险则专门对抗摘要的报喜不报忧。
那行「下一位动作」尤其重要。
多会话协作最常见的浪费,不是 agent 不干活,而是三个 agent 都以为另一个会收尾。把下一步写成单数,接收方只需要执行一个明确动作,例如「基于提交 abc123 更新前端类型并跑登录端到端测试」。消息到达后,任务就能继续,而不是再开一轮自然语言猜谜。
如果任务会持续很久,还要给消息加版本。
例如接口契约写成 auth-contract-v3。接收方准备合并前,先检查自己拿到的是不是最新版本。旧摘要晚到、重发或重复送达时,不会把新状态覆盖回去。
这就是幂等。一个消息来一次或来两次,结果都一样。圈外朋友第一次看到这个词,可以把它理解成「重复按电梯按钮,不会召唤出两台电梯」。
有点子牛逼的 agent 演示,往往展示消息飞过去的那一刻。真正能在线上活下来的系统,还得处理消息迟到、重复、丢失和接收方已经换了分支这些无聊事。
无聊,但值钱。
并行度会把错误一起放大
跨会话消息会让增加并发变得很诱人。
一个会话写代码,另一个补测试,再来一个查文档,第四个盯 CI。屏幕上四行状态同时滚,感觉吞吐量已经起飞。
先别兴奋太早。
Agent view 官方介绍 的确鼓励把独立任务发给多个后台会话,再回来看一排待审的 Pull Request。可官方文档也给了一个非常直白的限制,十个并行会话,大约会以十倍速度消耗订阅额度。
成本只是明面上的问题。更隐蔽的是验收带宽。
人一天能认真审的 diff 有上限。CI 能发现语法、类型和一部分行为错误,却不知道产品意图有没有被悄悄改掉。会话从两个涨到八个,代码生成吞吐量可能上去了,人的验证能力不会跟着乘四。
此时系统的瓶颈会从生成移动到验收。
坦率讲,这才是 AI 编程下半场最容易被忽略的地方。大家都在给 agent 加并发,真正稀缺的却是能定义完成标准、识别越界修改、读懂测试盲区的人。
我自己的建议是,从两个会话开始。
一个做主任务,一个做独立验证。主会话交付提交和测试证据,验证会话只读需求、diff 与可执行结果,不继承主会话那套自我解释。两边结论不一致,再交给人处理。
这个结构没有八个 agent 满屏跑那么热闹,却更接近生产环境。它把「写」和「验」分开,也避免同一个模型先做决定,再给自己的决定打满分。
对于能完全拆开的任务,再逐步增加并发。文档检索、独立模块、互不重叠的测试用例,通常适合并行。共享 schema、数据库迁移、权限逻辑和同一份核心配置,宁可串行,或者明确唯一 owner。
别拿并行度当战绩。
能稳定合并的吞吐量,才是吞吐量。
从传话员到协作系统
Claude Code 这次更新,我仍然觉得很重要。
过去多个会话之间的上下文,全靠人复制粘贴。现在摘要可以在任务进行中送达,开发者终于不用一直站在终端之间当传话员。Channels 已经展示了运行中会话接收外部事件的方向,跨会话消息再往前走一步,控制面正在慢慢成形。
但也正因为消息变简单了,边界更要写清楚。
摘要不是共享大脑,送达不是状态一致,对话不是文件锁,完成也不是一句 done。把工作区隔离、任务 owner、交接 schema、验证命令和人工验收补齐,多会话才从几个会聊天的终端,变成一个能交付的软件系统。
说真的,这个结论一点都不浪漫。
可工程里最可靠的进步,往往就是把原本靠某个人脑子记住的事,变成所有参与者都能检查的协议。
传话员可以下班了。
验收的人,还得坐一会儿。