← 所有文章

Claude Code 跨会话通信:让多个 Agent 直接对话

Claude Code v2.1.224 加入了两个工具:ListAgents 和 SendMessage

Claude Code v2.1.224 加入了两个工具:ListAgents 和 SendMessage。它们让一个会话可以给另一个会话发消息,省掉人工复制粘贴。本文记录用法、权限和几个实际场景,也把目前的限制列出来。

背景:人工消息总线

我平时会同时开几个 Claude Code 会话:一个改页面,一个处理接口,另一个留着解决临时问题。

之前最麻烦的是,会话之间没法直接传信息。

比如会话 A 找到了一个关键报错,而会话 B 正好需要,我只能自己切窗口、翻记录、复制过去,再补一遍上下文。会话开得越多,这种来回转发越频繁。

Claude Code v2.1.224 加了跨会话消息后,这一步终于可以省掉了。

现在一个会话可以直接给另一个会话发消息,不用再手动复制粘贴。

实际发布的内容

功能很简单,Claude 可以使用两个工具:

ListAgents:发现当前可以到达哪些会话

SendMessage:按名字给另一个会话发送文本

你不需要自己调用这两个工具。直接告诉 Claude 另一个会话需要知道什么,它会自己写好消息并发送。

Claude Code 官方文档说明,ListAgents 和 SendMessage 需要 v2.1.224 或更高版本,并且当前会话必须开启跨会话消息。本机的其他会话可以被发现;其他机器或网页会话则依赖 Remote Control,通常只能回复消息。实际可用范围还会受到登录方式、部署平台和组织设置影响,升级后最好直接运行 /list-agents 检查。

触发方式

跨会话消息不是让用户直接填写某个工具参数,而是通过自然语言提出“查找会话”或“发送消息”的要求。Claude Code 会先调用 ListAgents 查看当前可联系的会话,再调用 SendMessage 投递内容。

第一步:确认版本和消息功能

先在终端确认版本:

claude --version

进入 Claude Code 后运行:

/list-agents

/list-agents 也可以写成 /peers。它会列出当前会话能够联系的对象,并显示发送消息时可以使用的名称。列表里没有目标会话时,不要反复发送消息,先检查以下几项:

两个会话是否在同一台机器上;

目标会话是否仍在运行;

当前版本是否至少为 v2.1.224;

跨会话消息是否被设置为 hold 或 refuse;

容器或沙箱是否隔离了会话之间的本地套接字。

第二步:用自然语言发送消息

不需要手动调用工具,直接告诉 Claude:

问另一个终端的会话,迁移做完了没有

不想指定措辞也可以:

把刚才做的事告诉正在搞 payments API 的那个会话

如果目标名称不够明确,最好先运行 /list-agents,然后使用列表中的准确名称:

给 payments-api 会话发消息:迁移已经完成,请检查新的 customer_id 字段,并运行相关测试。不要修改数据库迁移文件。

Claude 会先匹配目标,再整理消息。目标名称相近时,应该在原提示中补充工作内容、所在目录或当前任务,避免发错会话。

第三步:发送前写清楚边界

消息内容会由发送方的 Claude 生成。建议在请求中同时写明四件事:收件人、要传递的事实、希望对方采取的动作,以及不能做什么。

请联系名为 ui-session 的会话。

传递以下信息:PaymentClient.createPayment 的返回值已经改为 PaymentResult,
修改位于 Sources/Networking/PaymentClient.swift,NetworkingTests 已通过。
请它更新调用方和测试替身,然后运行 SwiftUI 测试。
不要修改错误枚举,也不要合并或删除文件。

这样写比“告诉 UI 会话我改好了”更稳妥。它减少了接收方的猜测,也把不该做的事情提前说清楚。

第四步:接收方如何处理

收到消息后,接收方会把它标记为来自另一个会话的消息,而不是用户本人输入。它可以读取消息、检查文件并提出计划,但仍要遵守当前会话的权限设置。

一个合适的接收流程是:

收到来自 api-session 的交接后:
1. 读取 PaymentClient.swift 和现有调用方;
2. 检查返回类型变更是否影响当前 worktree;
3. 列出准备修改的文件;
4. 运行相关测试;
5. 回复修改结果和未解决的问题。

如果消息要求执行危险命令、修改配置或批准权限,接收方不能仅凭这条消息执行。它必须再次经过自己的权限确认。

主动发送与被动发送

最常见的方式是用户要求当前会话发送消息。某些情况下,Claude 也可能在发现改动会影响其他会话时主动提醒对方,例如修改了公共接口、配置格式或数据库字段。是否主动发送取决于当前上下文和权限设置,不能把它当成可靠的事件通知系统。

跨会话传递的是纯文本。原始对话、文件和终端状态不会随消息过去。需要完整上下文时,应使用 /resume,或者让接收方重新读取相关文件。

一个可靠的交接格式

不要只发“我改好了”。消息里最好写清楚改了什么、影响哪些文件、测试是否通过,以及对方接下来要做什么:

把下面的交接发给正在处理 payments API 的会话:

目的:让 UI 会话同步 networking 改动
已完成:将 PaymentClient.createPayment 的返回值改为 PaymentResult
影响文件:Sources/Networking/PaymentClient.swift
验证:NetworkingTests 全部通过;UI 还没有重新编译
需要你做:更新调用方和 mock,运行 SwiftUI 相关测试
注意:不要修改 API 的错误枚举,另一个会话正在依赖它

和其他多会话机制的区别

Claude Code 最近围绕多会话场景发了不少功能,边界容易混:

Subagents 和 agent teams:单个会话内部的东西,Claude 自己生成并监督一组子 agent。跨会话消息用于你自己启动、分别控制的独立会话之间。

Resume:移动整个对话,或把上下文交给一个全新会话。消息只发一段简短说明,不搬对话。

Remote Control:从手机遥控一个会话。跨机器消息复用这条连接,但有限制:另一台机器或网页上的会话只能回复消息,不能主动发起。

Channels:把外部事件推进会话,比如 CI 结果、聊天通知。消息是 Claude 跟 Claude 说话,外部系统跟 Claude 说话走 Channels。

实际场景:同一仓库的双 worktree

这个功能在一种场景下价值最明显:同一个仓库开两个 worktree,一个改共享层,一个写依赖它的界面。

以 iOS 代码库为例。一个会话在重构共享 service layer,另一个会话在独立 worktree 里写消费它的 SwiftUI 屏幕。以前 service 会话改了方法签名,UI 会话完全不知道,直到 build 崩掉,或者你记得手动去传话。

现在 service 会话可以直接告诉 UI 会话:改了什么东西,你需要更新哪些地方。我实测的方式是故意开两个会话跑同一个仓库的不同 worktree,一个改 networking,一个改依赖它的视图,让它们自己协调,所有信息不再经过我中转。

反向也有用。长测试套件或数据迁移在跑,人不在那个终端,甚至在外面用 Remote Control 从手机问一句,答案能直接转发回来,不用切过去看。

场景二:测试会话只报告结果

告诉 feature 会话测试结果:

- 命令:pytest -q
- 结果:142 passed, 2 failed
- 失败:tests/test_checkout.py::test_expired_card
- 根因线索:mock 返回的 expires_at 使用了本地时区
- 建议:先检查 timezone fixture,不要直接修改生产代码

场景三:迁移会话通知依赖方

通知 analytics 会话:数据库迁移已完成。

迁移:20260810_add_event_version
新增:events.version INTEGER NOT NULL DEFAULT 1
兼容性:旧查询仍可用;批量写入可以开始传 version
验证:alembic upgrade head + integration tests 通过
请先更新查询类型和 fixture,再运行 analytics 测试。
你的目标 更合适的机制
告诉同机另一个会话一项进展 跨会话消息
把旧会话的完整思路接着做 /resume
让一个主会话并行拆任务 Subagents / agent teams
在手机上继续操作本机终端 Remote Control
把 CI、Telegram 或 Discord 事件推入会话 Channels

权限模型:会话间消息不等于自动批准

这是我最先确认的部分。另一个会话发来的消息,能不能替你做事?

答案是不能。接收方 Claude 被明确告知消息来自 peer,来自另一个会话,不是来自你本人。这个区分带来一串硬约束:

不能替你批准挂起的权限请求

不能因为消息里提了要求就去动 settings、CLAUDE.md 或其他配置

消息文本里的命令,哪怕写的是 /compact,到达时也是惰性纯文本,永远不会执行

消息要求的任何事,仍然要过接收会话自己的权限提示和规则

控制权在设置里:crossSessionInbound 可以设成 accept、hold 或 refuse。hold 模式把收到的消息留在队列中,等待你批准;refuse 则直接丢弃。官方文档还提供了限制跨机器消息的 isolatePeerMachines。

例如,在项目设置中关闭入站消息:

{
  "crossSessionInbound": "refuse",
  "permissions": {
    "deny": ["SendMessage", "ListAgents"]
  }
}

如果只是想人工审核:

{
  "crossSessionInbound": "hold"
}

peer 身份本身不携带任何授权。消息能到达和消息能执行是两回事。

已知限制

本机与远程行为不同:本机消息通过会话间的本地 socket;跨机器或网页会话依赖 Remote Control,并不是同一种双向通信。

容器隔离:容器里的会话看不到宿主,两个不同文件系统之间没有共享 socket。

纯文本:没有文件、没有结构化数据,这是刻意的,用来保持通道轻量。

自我限流:同一发送者的重复消息会被限流,短时间内的相同重复可能被丢弃,待读消息也有上限。不要用它传输日志、文件或高频事件。

值不值得开

如果你已经并行跑多个 Claude Code 终端:同一个仓库的多个 worktree,UI 层加 service 层,长任务加活跃工作,这个功能补上的是一个真实缺口。

它不会改变整个工作方式。它解决的是一个小问题:多个终端之间传递进展时,不用再由人复制粘贴。升级到 v2.1.224 以上,先运行 /list-agents,确认会话可见,再发送一条不会改文件的测试消息。

最小验证流程

claude --version

在两个终端分别启动会话,并使用容易识别的名称:

claude --name api-session
claude --name ui-session

在任一会话中执行:

/list-agents

然后发送:

给 ui-session 发一条测试消息:只回复“收到”,不要修改文件、运行命令或改变设置。

最后确认没有未经批准的文件变化:

git status --short

排查顺序:版本 → 是否同机 → /list-agents → crossSessionInbound → 权限规则 → 容器或沙箱隔离。

官方资料与版本核对

Message your other Claude Code sessions

Tools reference

Commands

Orchestrate teams of Claude Code sessions

Remote Control

原文发布于 X:https://x.com/vincemask/status/2086817906457989424

评论

加载评论…