Claude Code 会话间如何实现相互发送消息
了解 Claude Code 如何通过 ListAgents 和 SendMessage 工具实现跨会话通信。本文解析了 v2.1.224 及以上版本的配置要求、VPS 环境下的适用场景,以及为何消息会被系统暂时挂起。
Claude Code 会话之间相互发送消息的含义
如果两个 Claude Code 会话在同一台机器上,并且使用同一个操作系统用户运行,它们就可以相互发送消息。消息是一段由一个 Claude 会话写给另一个会话的纯文本。消息不包含对话历史或文件。Claude 使用 ListAgents 工具查找另一个会话,再使用 SendMessage 发送文本,因此您无需手动调用这两个工具。您只需说明另一个会话需要了解什么,Claude 会自行编写消息。
此功能称为跨会话消息传递。截至 October 2026,在 macOS 和 Linux(包括 WSL 2 中的 Linux)上需要 Claude Code v2.1.224 或更高版本,在原生 Windows 上需要 v2.1.234 或更高版本。同一台机器上的会话之间可以使用所有 provider 传递消息,包括 Amazon Bedrock、AWS 上的 Claude Platform、Google Cloud's Agent Platform 和 Microsoft Foundry;在这些 provider 上需要 v2.1.248 或更高版本。访问其他机器或云中的会话时,适用范围更窄:该功能通过 Remote Control 实现,需要登录 claude.ai,因此不支持 API key,也不支持上述四个 provider。会话满足这些要求后,消息传递功能已自动启用,无需额外配置。以下行为说明来自 Anthropic 的跨会话消息传递文档。
VPS 是这项功能最有用的场景,因为会话会在 VPS 上持续运行,值得相互联系。在笔记本电脑上,您合上盖子就会关闭会话。在运行 tmux 的服务器上,您周一启动的会话到周四可能仍在运行,并继续保留某个代码仓库的上下文。当您有两个这样的会话后,它们如何通信就不再只是理论问题。如果您还没有完成设置,请先阅读 在 VPS 的 tmux 中运行 Claude Code,其中介绍了本指南所依赖的会话配置。
何时值得使用第二个会话
先考虑成本。每个会话都是独立的 Claude 实例,并拥有自己的上下文窗口。因此,在相同时间内,两个会话的成本大约是一个会话的两倍。发送的消息与您输入的提示一样,都会计入用量。协调并不是免费的;如果工作本质上是一系列连续步骤,将其拆分到多个会话中会使过程更慢、成本更高。
值得使用第二个会话的情况通常具有相同特征:两项工作可以同时运行,彼此无需等待,并且其中一项在执行过程中获得了另一项所需的信息。
- 一个会话发现了破坏性变更,而另一个会话正基于受影响的代码继续开发。Claude 会总结该变更并发送出去,您无需在另一个终端中重新输入。
- 两个会话在同一仓库的独立 git worktree 中工作,其中一个需要了解已经合并的内容。
- 长时间运行的迁移或测试任务将结果发送回您正在查看的会话。
- 一个构建会话和一个审查会话:审查会话读取构建会话生成的内容,并返回发现的问题。
如果工作是连续执行的,或者两个会话都会编辑相同的文件,请使用一个会话。如果您希望 Claude 在单个任务中创建并监管一个协作组,这属于 agent teams,是一项独立且仍处于实验阶段的功能。如果您只是想在另一个终端中继续同一段对话,请恢复该会话。跨会话消息传递适用于彼此独立、由您自行启动和控制的会话。
在规划使用该功能前,先确认功能确实存在
先查看版本:
claude --version将版本号与 2.1.224 比较。然后在会话中输入 /list-agents;该命令也可通过 /peers 调用。它会列出此会话可以访问的所有代理,以及每个代理响应的名称。如果系统完全无法识别该命令,则此会话不支持跨会话消息传递,任何 crossSessionInbound 值都无法改变这一点。输入 /status,查找 Peer address 行;该行包含此会话自己的收件箱地址,地址以 uds: 开头。
旧版本会给 VPS 用户带来一个容易忽略的问题。在 v2.1.248 之前,同机消息传递依赖功能标志获取,而多个隐私变量会关闭该获取功能,使消息传递保持默认关闭状态。DO_NOT_TRACK、DISABLE_TELEMETRY、CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC 和 DISABLE_GROWTHBOOK 都会关闭该功能。用户通常会将这些变量粘贴到 ~/.bashrc 中来加固新服务器,随后却发现 /list-agents 不存在。从 v2.1.248 开始,即使关闭获取功能,同一台机器上的会话仍可互相传递消息,因此更新版本是更简洁的解决方案。这些变量仍会影响访问本机之外会话的能力:关闭获取功能后,只有在 Remote Control 可用时,Claude 才能访问这些会话;而 CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC 和 DISABLE_GROWTHBOOK 会使 Remote Control 不可用。相同的值也可能来自设置文件中的 env 映射或托管设置,因此请先检查 shell 环境。
env | grep -E 'DO_NOT_TRACK|DISABLE_TELEMETRY|DISABLE_GROWTHBOOK|NONESSENTIAL'在旧版本中,取消设置输出结果中出现的变量。对于 DISABLE_TELEMETRY 和 CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC,任何非空值都会启用该行为,包括字符串 0,因此 DISABLE_TELEMETRY=0 的实际效果并不像表面看起来那样。要关闭该功能,请取消设置变量,或将其设置为空字符串。
为会话命名,否则 Claude 无法定位会话
Claude 按名称将消息发送到会话。在启动会话时设置名称:
claude --name builder-api您也可以在运行中的会话内使用 /rename 设置名称。如果不设置名称,Claude Code 会根据工作目录的文件夹名称生成名称,例如 myapp-3f。一个会话时这样没有问题,但同时运行四个会话时会造成混淆,而且两个会话可能获得相同的名称。除非会话已连接到 Remote Control,否则 /list-agents 输出会显示每个本地会话的工作目录,因此可以区分同名会话;Claude 自己的列表还会在名称冲突时,将短标识符添加到地址中。自行命名比查看标识符更省事。您设置的名称还会让 @ 补全功能发挥作用:从 v2.1.232 开始,在提示符中输入 @builder 并选择会话,Claude 就能准确知道您指的是哪个会话。
可复现的双会话 tmux 布局
这是在同一个仓库中运行的构建会话和审查会话。审查会话使用独立的 git worktree,因此两个会话不会写入同一个文件。git worktree add 配合 HEAD 可创建一个分离的检出,这适合只读取代码而不提交更改的会话。由于两个会话承担不同的任务,最好为审查会话单独设置输出风格。该设置会修改此会话的系统提示词,因此在每一轮中都有效,不会像只输入一次的指令那样逐渐失效。
cd ~/src/api
git worktree add ../api-review HEAD
tmux new-session -d -s agents -n builder -c ~/src/api
tmux new-window -t agents -n reviewer -c ~/src/api-review
tmux send-keys -t agents:builder 'claude --name builder-api' C-m
tmux send-keys -t agents:reviewer 'claude --name reviewer-api' C-m
tmux attach -t agentsCtrl+b 然后 w 会按名称列出窗口,便于选择目标窗口。在构建窗口中运行 /list-agents。你应看到 reviewer-api,其工作目录为 ~/src/api-review。如果看不到,说明审查会话尚未完成启动,或者下一节中的两个问题之一适用。然后用自然语言交接任务:
Tell reviewer-api which files I changed for the rate limiter and what to look at first.Claude 会编写并发送摘要。你不需要编写消息正文,而且 Claude 发送的内容每次可能不同。在审查窗口中,消息会显示为一行灰显预览,其中包含发送者名称和文本的第一行,例如 › Message from @builder-api: …。如果该会话处于空闲状态,Claude 会立即在其中开始新一轮处理。如果会话正在执行当前轮次,消息会等到两次工具调用之间再处理,因此不会中断正在运行的命令。Ctrl+O 会打开包含完整文本的记录查看器;无论你是否展开消息,Claude 都会读取完整内容。当构建会话保持较小的更改时,这两个会话的配合效果更好,因为较小的差异会产生更短的交接内容,也便于另一个会话在一轮处理中完成审查。这正是懒惰高级开发者技能要培养的习惯。
同一 VPS 上谁能看到谁
同机投递不会经过 Anthropic 服务器。每个会话都会绑定自己的收件箱套接字,即一个路径位于该计算机文件系统中的 Unix 域套接字。只有绑定了该套接字的会话,才会出现在其他会话的列表中。在服务器上,这会带来两个后果。
该套接字受您的操作系统用户限制。您以 root 启动的会话与以 deploy 启动的会话无法互相看到,即使它们位于同一个 tmux 服务器中,因为一个用户的会话无法访问另一个用户的套接字。请让两个会话使用同一个用户运行。
容器拥有独立的文件系统。Docker 内的会话与宿主机上的会话无法互相访问。同一容器内的两个会话可以正常互发消息。如果您像在一次性 VM 中运行编码代理一样,将代理保存在容器中以实现隔离,请注意:容器内的消息传递可以正常工作,但无法跨越容器边界。
只有在本会话连接到 Remote Control 时,其他计算机上的会话和云端会话才会出现在列表中。其他计算机上的会话会标记为 Remote Control。从 v2.1.225 开始,Claude 可以与其中一个会话发起对话,而不只是回复它。此类消息会经过 Anthropic 服务器。如果 Claude 向本机之外发送消息时,本会话未连接到 Remote Control,消息仍会发送,但不包含回复地址,因此另一端无法回复。
为什么你的消息始终没有送达
通常原因与网络无关。接收会话决定如何处理消息,而它选择了不投递。每条到达的消息最终只有3种结果:已投递、已暂存(在你批准前暂不投递),或已拒绝(直接丢弃,不予投递)。
当没有适用的 crossSessionInbound 值时,Claude Code 会根据两个会话的权限模式逐条决定。它会将绕过权限提示的会话归为一类,将其他会话归为另一类。auto、acceptEdits 和 dontAsk 都属于需要提示的模式。在具有可用绕过权限的交互式终端会话中,计划模式属于绕过提示的一类。如果你不确定某个会话属于哪一类,建议先阅读各权限模式的实际作用,因为大多数会话现在以 auto 模式启动,而该模式属于需要提示的一侧。规则是对称的:
- 需要提示权限的接收会话会投递每条消息。只有在发送会话表明自己会绕过提示时,它才会暂存消息。
- 绕过提示的接收会话会暂存所有消息,等待你批准。只有在发送方也绕过提示时,它才会投递消息。
因此,大多数人首先构建的工作流恰好无法运行。你使用 --permission-mode bypassPermissions 启动构建器,因为希望它无人值守地运行;评审器则保留默认设置。结果,构建器发送的每条消息都会停留在无人查看的批准对话框中。该对话框会在 dialogExpiry 截止时间后关闭。该时间默认值为 5m,消息随后会被丢弃。在判断 socket 有问题之前,先查看接收会话的屏幕,确认是否有待处理的批准对话框。
要让会话在无人值守的情况下接收消息,请将 crossSessionInbound 设置为 accept。设置位置决定了该配置的适用范围。Claude Code 会先读取受管设置,然后读取 --settings 标志,最后读取用户设置,并采用找到的第一个值。项目设置或本地设置中的值仅在其更严格时生效,优先级顺序为 accept < hold < refuse。.claude/settings.json 中的 accept 比任何值都宽松,因此只要受信任的来源已设置值,它就会被忽略。将其写入 ~/.claude/settings.json,或仅为一个会话传入该值。从 v2.1.232 开始,/config 行 来自其他会话的消息 会自动为你写入相同的用户设置。
claude --name runner --settings '{"crossSessionInbound":"accept"}'无头 claude -p worker 会像交互式会话一样绑定 inbox socket 并显示在列表中,但无法显示批准对话框。Claude Code 会在相同的 dialogExpiry 截止时间内暂存该消息,默认值为5分钟。如果在此时间内模式或设置发生变化,使消息可以投递,则会投递消息;否则会丢弃消息,并向能够联系到的发送方报告消息已过期。上面的 --settings 行用于让此类 worker 接收消息。以 bare 模式启动的会话完全不会绑定 socket,因此既不能接收消息,也不会显示在列表中。
交接卡死的位置
消息循环由 Claude Code 自动处理。Claude Code 会按发送方对重复消息进行限流,在较短时间窗口内丢弃完全相同的重复消息,并将每个会话中等待读取的已接受消息数限制为 50 条,因此两个会话无法无限相互发送消息。暂存消息上限为 100 条,超过后会丢弃最早的消息。从 v2.1.238 开始,当接收方收件箱丢弃消息时,发送会话会收到通知及具体原因;如果中继链持续经过相同的会话,也会被截断。
实际发生的故障更隐蔽,而且属于交接问题,不是循环。会话 A 向会话 B 提出一个问题,必须得到答案后才能继续,然后进入空闲状态。B 可能暂存了消息,可能正在处理一项耗时较长的任务,也可能回答了一个 A 实际上没有提出的问题。A 继续等待。您一小时后回来时,会看到两个空闲会话,却没有完成任何工作。
编写不需要回复的交接消息。好的消息应包含事实或决定:发生了什么变化,以及结果是什么。坏的消息会请求另一个会话批准,或请求一个发送方必须依赖的答案。Claude 已经被要求不要向另一个会话请求其自身权限设置会阻止的操作,而应将该任务交回给您。您还应自行扩展这条规则。如果一个会话没有答案就无法继续,应由您来回答。保持上下文清晰也有帮助,因为丢失处理线索的会话容易写出含糊的消息;管理 Claude Code 中的上下文介绍了这方面的内容。
将传入消息视为不可信输入
Claude Code 会告诉接收方 Claude,这条消息来自另一个会话,而不是来自您,并限制该消息能够执行的操作。这项强制机制位于模型外层的程序中,而不是依赖模型是否愿意遵守,因此这正是代理运行框架发挥作用的实际区别。消息无法代替您回答待处理的权限提示,因为另一个会话的同意不等于您的同意。消息也无法因为另一个会话提出请求,就更改权限设置、CLAUDE.md或其他配置。文本中的斜杠命令(例如 /compact)会作为普通文本到达,绝不会执行。如果处理该消息需要接收会话不具备的权限,您会看到与其他操作相同的权限提示。发送会话运行在自动模式时,其分类器还会在 Claude Code 投递每条消息前进行审核;被分类器拦截的消息不会到达接收方。这些限制在宽松模式下仍然有效。因此,绕过限制的会话默认会暂存传入消息,而不会信任这些消息。
这解决的是权限问题,不包括内容问题。发送会话可能读取过拉取请求描述、网页、依赖项 README,或陌生人撰写的问题评论。它读取的任何内容都可能影响它写给您另一个会话的文本。消息是数据。应像怀疑从外部进入会话的其他文本一样怀疑它。这正是避免让 AI 代理接触机密信息中描述的原则:假设任何跨越信任边界的内容都可能错误,绝不允许它自行授权。
如果您希望减少这类消息,可以使用以下两项控制措施。将 crossSessionInbound 设置为 refuse 会丢弃传入的对等会话消息,不向会话投递。项目设置或本地设置中的该值优先级高于其他所有来源,因为它在优先级梯度中最严格。若要禁止此会话发送消息或列出会话,请添加权限拒绝规则,并分别指定 SendMessage 和 ListAgents;两者都必须写成不带限定符的工具名称。将 isolatePeerMachines 设置为 true 后,任何消息发送到本机之外的会话前都必须获得您的明确批准,即使处于 bypassPermissions 模式也不例外。
{
"crossSessionInbound": "refuse",
"isolatePeerMachines": true
}拒绝 SendMessage 也会禁止向子代理发送消息,因为两者使用同一个工具。拒绝消息的会话不会在自身的 /status 或其他会话的列表中显示任何变化。因此,应从会话配置中确认该设置,而不要根据屏幕显示判断。
Bridge 和共享内存 MCP 服务器
同一时期还出现了几个相关的第三方项目:在运行中的代理之间转发文本的本地代理间 Bridge,以及让多个代理共享读写存储的 MCP(模型上下文协议)服务器。应将它们视为不同形态的方案,而不是竞争产品。运行任何安装命令前,都应先根据项目自己的 README 进行核对。消息传递属于推送,因为发送方会将文本放入接收方当前的交互轮次。共享存储属于拉取,因为它不会中断任何会话,会话下次查看时才能看到这条记录。对于变化较慢的状态,拉取方式更平稳;但只有会话实际查看时,它才会生效。
如果选择这类方案,值得关注的问题应围绕进程,而不是功能列表。服务器以哪个用户身份运行?它可以读取主机上的哪些内容?在 VPS 上运行 MCP 服务器介绍了相关配置。在多个代码仓库之间共享代理技能介绍了更简单的场景:如果希望在多个会话之间共享的是指令而不是实时状态,这种方式可以减少许多原本需要发送的消息。要了解更广泛的背景,请从在 VPS 上运行代码代理开始。
FAQ
为什么我的会话无法识别 /list-agents?
该会话未启用跨会话通信功能。请首先检查 claude --version:该功能在 macOS 和 Linux 上需要 2.1.224 或更高版本,在原生 Windows 上需要 2.1.234 或更高版本,在 Amazon Bedrock、AWS 上的 Claude Platform、Google Cloud 的 Agent Platform 以及 Microsoft Foundry 上则需要 2.1.248 或更高版本。对于低于 2.1.248 的版本,还需检查 shell 中是否包含 DO_NOT_TRACK、DISABLE_TELEMETRY、CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC 或 DISABLE_GROWTHBOOK,因为这些开关会禁用旧版本实现通信功能所需的特性标志获取。更新到 2.1.248 或更高版本后,同一台机器上的会话将不再依赖该特性标志获取机制。
为什么发送给另一个会话的消息没有送达?
如果 /list-agents 运行正常,说明通信功能已开启,消息未送达是由更具体的原因导致的。常见原因是权限模式设置。如果接收会话绕过了权限提示,它会挂起所有入站消息等待确认,除非发送方也绕过了权限提示;且该确认对话框会在 dialogExpiry 期限(默认 5 分钟)后失效。请检查接收会话中是否有待处理的确认对话框。若要解决此问题,请在 ~/.claude/settings.json 中将 crossSessionInbound 设置为 accept,或通过 --settings 传递该参数,因为项目设置或本地设置中的 accept 会因其权限宽松而被忽略。
Docker 中的 Claude Code 会话可以与宿主机上的会话通信吗?
不可以。每个会话的收件箱都是该机器文件系统上的一个套接字,而容器拥有独立的文件系统,因此容器内的会话与宿主机上的会话无法相互访问。位于同一容器内的两个会话可以正常通信。同样的规则也解释了为什么以 root 身份运行的会话与以普通用户身份运行的会话无法通信:套接字仅限于所属的操作系统用户访问。
来自其他 Claude Code 会话的消息可以安全执行吗?
请将消息内容视为不可信输入,因为发送会话可能读取了由他人编写的网页、README 或问题评论。Claude Code 本身已限制了消息的自动执行能力:它无法批准待处理的权限提示,无法按请求更改权限设置或 CLAUDE.md,且文本中的斜杠命令仅作为纯文本接收,不会被执行。这些保护措施仅涵盖权限,不代表判断逻辑,因此在指示接收会话执行操作前,请务必阅读收到的内容。
跨会话通信会将我的代码发送给 Anthropic 吗?
在同一台机器上的两个会话之间,不会。消息通过该机器上的会话专用套接字传输,不会经过 Anthropic 服务器,且仅发送 Claude 编写的文本,绝不会发送对话历史记录或文件。发送到您另一台机器上的会话或云端会话的消息确实会经过 Anthropic 服务器。从 2.1.225 版本开始,Claude 不仅可以回复消息,还可以发起此类交换。请将 isolatePeerMachines 设置为 true,以要求在任何数据离开机器前必须经过您的批准。