Обмен сообщениями между сессиями Claude Code
Узнайте, как настроить взаимодействие между двумя сессиями Claude Code на одном сервере. Разбираем работу инструментов ListAgents и SendMessage в версии 2.1.224 и выше.
Что означает обмен сообщениями между сессиями Claude Code
Две сессии Claude Code могут обмениваться сообщениями, если они запущены на одной машине под одним и тем же пользователем операционной системы. Сообщение представляет собой фрагмент обычного текста, который один экземпляр Claude пишет для другого. Оно не содержит истории переписки или файлов. Claude находит другую сессию с помощью инструмента ListAgents и доставляет текст через SendMessage, поэтому вам не нужно вызывать эти инструменты вручную. Вы сообщаете, что именно нужно передать другой сессии, и Claude самостоятельно формирует сообщение.
Эта функция называется межсессионным обменом сообщениями (cross-session messaging). По состоянию на август 2026 года для её работы требуется Claude Code v2.1.224 или более поздняя версия; она работает в macOS и Linux, включая Linux внутри WSL 2. Нативная поддержка Windows отсутствует, также функция недоступна в Amazon Bedrock, Claude Platform on AWS, Google Cloud's Agent Platform или Microsoft Foundry. Если сессия соответствует этим требованиям, обмен сообщениями включен по умолчанию и не требует дополнительной настройки. Описанное ниже поведение основано на документации Anthropic по межсессионному обмену сообщениями.
Это актуально для VPS, так как именно там сессии живут достаточно долго, чтобы имело смысл обращаться к ним. На ноутбуке вы просто закрываете крышку. На сервере под управлением tmux сессия, запущенная в понедельник, продолжает работать в четверг, сохраняя контекст репозитория. Как только у вас появляется две такие сессии, вопрос их взаимодействия перестает быть теоретическим. Если вы еще не настроили это, начните с запуска Claude Code на VPS под управлением tmux, где описана базовая организация сессий, на которую опирается данное руководство.
Когда вторая сессия оправдывает затраты токенов
Начните с оценки стоимости. Каждая сессия — это отдельный экземпляр Claude с собственным контекстным окном, поэтому две сессии обходятся примерно в два раза дороже, чем одна за тот же период. Отправленное сообщение учитывается в лимитах использования точно так же, как и введенный вами запрос. Координация не бесплатна, и работа, представляющая собой единую последовательность шагов, замедляется и становится дороже при разделении на несколько сессий.
Случаи, когда вторая сессия окупает себя, имеют общую черту. Две части работы выполняются одновременно, не ожидая друг друга, и одна из них получает данные, необходимые другой в процессе выполнения.
- Одна сессия обнаруживает критическое изменение (breaking change), в то время как другая работает с кодом, который это изменение затронуло. Claude суммирует изменения и передает их, избавляя вас от необходимости перепечатывать их в другом терминале.
- Две сессии работают с одним репозиторием в разных git worktrees, и одной из них нужно знать, какие изменения были приняты.
- Длительная миграция или выполнение тестов отправляют результат обратно в сессию, за которой вы наблюдаете.
- Сессия разработчика и сессия рецензента, где рецензент читает созданный разработчиком код и отправляет обратно свои замечания.
Если работа последовательна или обе сессии должны редактировать одни и те же файлы, используйте одну сессию. Если вам нужна скоординированная группа, которую Claude создает и контролирует в рамках одной задачи, используйте команды агентов (agent teams) — это отдельная и пока экспериментальная функция. Если вам просто нужно продолжить тот же диалог в другом терминале, возобновите сессию. Обмен сообщениями между сессиями предназначен для независимых сессий, которые вы запускаете и направляете самостоятельно.
Проверьте наличие функции перед планированием работы с ней
Сначала проверьте версию:
claude --versionСравните полученное число с 2.1.224. Затем в рамках сессии введите /list-agents, которая также откликается на /peers. Команда выводит список всех агентов, доступных для данной сессии, с именами, под которыми они зарегистрированы. Если команда не распознаётся, значит, в этой сессии отсутствует поддержка межсессионного обмена сообщениями, и никакой файл настроек это не исправит. Введите /status и найдите строку Peer address: в ней указан адрес входящих сообщений текущей сессии с префиксом uds:.
Одна ловушка особенно актуальна для пользователей VPS. Межсессионный обмен сообщениями зависит от оценки флагов функций, а ряд переменных конфиденциальности отключают эту оценку, оставляя функцию в состоянии «выключено» по умолчанию. DO_NOT_TRACK, DISABLE_TELEMETRY, CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC и DISABLE_GROWTHBOOK приводят именно к этому результату. Пользователи часто ужесточают настройки свежего сервера, вставляя эти переменные в ~/.bashrc, а затем удивляются, почему /list-agents не существует. Те же значения могут поступать из карты env в файле настроек или из управляемых параметров, поэтому сначала проверьте переменные окружения оболочки.
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. Это удобно для одной сессии, но запутывает, если их четыре, к тому же две сессии могут получить одинаковые имена. Вывод /list-agents показывает рабочую директорию каждой локальной сессии, что позволяет различать сессии с одинаковыми именами, а собственный список Claude добавляет короткий идентификатор к адресу при возникновении конфликтов имён. Присваивать имена самостоятельно проще, чем разбираться в идентификаторах.
Макет tmux из двух сессий, который можно воспроизвести
Это сессия разработчика и сессия рецензента для одного репозитория. Рецензент работает в отдельном git worktree, поэтому они никогда не записывают изменения в один и тот же файл. git worktree add вместе с HEAD создают отсоединенный checkout, что и требуется для сессии, которая предназначена для чтения, а не для коммитов. Поскольку эти две сессии выполняют разные задачи, стоит настроить для рецензента собственный стиль вывода, который изменит системный промпт сессии и будет сохраняться на протяжении всей работы, а не исчезнет, как разовая инструкция.
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, может варьироваться. В окне рецензента сообщение появляется в диалоге с именем отправителя. Если сессия простаивает, Claude сразу начинает новый цикл работы в ней. Если сессия занята, сообщение ожидает завершения вызовов инструментов, поэтому выполнение команды не прерывается. Как только Claude прочитает сообщение, оно сворачивается в одну строку Message from, которую можно развернуть с помощью Ctrl+O. Эта пара работает эффективнее, если разработчик вносит небольшие изменения: узкий diff позволяет сделать передачу задачи более лаконичной, а рецензирование — завершить за один цикл. Именно для формирования такой привычки существует навык ленивого старшего разработчика.
Кто кого видит на одном VPS
Доставка сообщений в рамках одного сервера никогда не проходит через серверы Anthropic. Каждая сессия записывает файлы регистрации на диск и привязывается к собственному сокету входящих сообщений, а Claude Code считывает эти файлы для поиска других ваших сессий. Из этого следуют два вывода, оба из которых актуальны при работе на сервере.
Доступ к сокету ограничен вашим пользователем операционной системы. Сессия, запущенная вами от имени root, и сессия, запущенная от имени deploy, не могут «видеть» друг друга, даже если они запущены рядом в одном и том же tmux, так как сессии одного пользователя не имеют доступа к сокету другого. Запускайте обе сессии от имени одного и того же пользователя.
У контейнера собственная файловая система. Сессия внутри Docker и сессия на хосте не могут взаимодействовать друг с другом, так как они не считывают одни и те же файлы регистрации. Две сессии внутри одного контейнера могут обмениваться сообщениями в обычном режиме. Если вы используете контейнеры для изоляции агентов, как описано в запуске агентов для программирования во временной виртуальной машине, учитывайте, что обмен сообщениями будет работать внутри контейнера, но не через границу контейнера.
Ваши сессии на других машинах и в веб-интерфейсе отображаются в списке только тогда, когда установлено соединение Remote Control, и они имеют соответствующую пометку. Claude в данном случае может ответить только на сообщение, поступившее из одной из таких сессий. Он не может инициировать такой обмен самостоятельно.
Почему ваше сообщение не было доставлено
Обычно причина не связана с сетью. Принимающая сессия сама решает, что делать с сообщением, и в данном случае решение было не доставлять его. Каждое входящее сообщение имеет один из трех исходов: доставлено, удержано (отложено без доставки до вашего подтверждения) или отклонено (удалено без доставки).
Если не задано значение crossSessionInbound, Claude Code принимает решение для каждого сообщения, сравнивая режимы разрешений двух сессий. Он разделяет сессии на два класса: те, что обходят запросы разрешений, и все остальные. auto, acceptEdits и dontAsk считаются режимами с запросами. Режим Plan считается обходом, если в сессии доступны соответствующие права. Если вы не уверены, к какому классу относится сессия, сначала стоит прочитать что именно делает каждый режим разрешений, так как большинство сессий сейчас запускаются в режиме auto, который относится к стороне с запросами. Правило при этом симметрично:
- Принимающая сессия, запрашивающая разрешения, доставляет каждое сообщение. Она удерживает сообщение только в том случае, если отправляющая сессия идентифицирует себя как обходящую запросы.
- Принимающая сессия, обходящая запросы, удерживает каждое сообщение до вашего одобрения. Она доставляет сообщение только тогда, когда отправитель также работает в режиме обхода.
Поэтому первый рабочий процесс, который создают многие, оказывается нерабочим. Вы запускаете сборщик с --permission-mode bypassPermissions, чтобы он работал без присмотра, оставляете настройки рецензента по умолчанию, и каждое сообщение от сборщика попадает в диалоговое окно подтверждения, которое никто не видит. Это окно закрывается по истечении срока dialogExpiry, который по умолчанию равен 5m, и сообщение удаляется. На той же машине отправляющая сессия получает уведомление, когда сообщение удерживается, а затем последующее уведомление, когда получатель доставляет, отклоняет или аннулирует его по истечении времени. Поэтому сначала изучите экран отправителя, прежде чем винить сокет.
Чтобы сессия принимала сообщения без участия пользователя, установите crossSessionInbound в значение accept. Место установки определяет, будет ли настройка применена. Claude Code сначала считывает управляемые настройки, затем флаг --settings, затем пользовательские настройки и применяет первое найденное значение. Значение в настройках проекта или локальных настройках применяется только в том случае, если оно строже, согласно иерархии accept < hold < refuse. Значение accept в .claude/settings.json является менее строгим, чем любые другие, поэтому оно игнорируется, если значение уже задано доверенным источником. Укажите его в ~/.claude/settings.json или передайте для одной сессии:
claude --name runner --settings '{"crossSessionInbound":"accept"}'Безголовый (headless) воркер claude -p привязывается к сокету входящих сообщений так же, как интерактивная сессия, и отображается в списке, но он не может показать диалоговое окно подтверждения. Удержанное сообщение остается в таком состоянии до тех пор, пока последующее изменение режима или настроек не разрешит его доставку. Строка --settings выше — это способ разрешить такому воркеру принимать сообщения. Сессия, запущенная в режиме bare, вообще не привязывается к сокету, поэтому она не может ни получать сообщения, ни отображаться в списке.
Где возникают взаимные блокировки при передаче задач
Циклы сообщений обрабатываются автоматически. Claude Code ограничивает частоту повторных сообщений от одного отправителя, отбрасывает идентичные повторы, поступившие в короткий промежуток времени, и ограничивает количество принятых сообщений, ожидающих прочтения, до 50 на сессию, поэтому две сессии не могут бесконечно обмениваться запросами. Количество удерживаемых сообщений ограничено 100, после чего самые старые отбрасываются.
Сбой, который действительно происходит, протекает тише и представляет собой не цикл, а проблему передачи задачи. Сессия A задает сессии B вопрос, ответ на который ей необходим для продолжения работы, после чего переходит в режим ожидания. B удерживает сообщение, либо B занята выполнением длительной задачи, либо B отвечает на вопрос, который A на самом деле не задавала. A ждет. Вы возвращаетесь через час и обнаруживаете две простаивающие сессии и отсутствие результата.
Формируйте передачу задач так, чтобы она не требовала ответа. Хорошее сообщение содержит факт или решение: что изменилось и каков результат. Плохое сообщение запрашивает у другой сессии разрешение или ответ, на котором блокируется отправитель. Claude уже получил инструкцию никогда не запрашивать у другой сессии действие, которое было бы заблокировано его собственными настройками разрешений, и вместо этого перенаправлять такую работу вам. Распространите это правило на свою практику. Если сессия не может продвинуться без ответа, именно вы должны дать этот ответ. Дисциплина контекста здесь также помогает, поскольку сессия, потерявшая нить рассуждений, пишет расплывчатые сообщения; управление контекстом в Claude Code охватывает эту сторону вопроса.
Обработка входящих сообщений как недоверенных данных
Claude Code сообщает принимающему экземпляру Claude, что сообщение поступило из другого сеанса, а не от вас, и ограничивает возможности такого сообщения. Это принудительное ограничение реализовано в программе-обертке вокруг модели, а не зависит от готовности модели подчиниться; именно в этом заключается практическое различие, которое обеспечивает агентная обвязка. Сообщение не может ответить на ожидающий запрос разрешения от вашего имени, так как согласие из другого сеанса не является вашим согласием. Оно не может изменить настройки разрешений, CLAUDE.md или другие параметры конфигурации по запросу из другого сеанса. Команда с косой чертой внутри текста, например /compact, поступает как обычный текст и никогда не выполняется. Если для выполнения действий по сообщению требуется разрешение, которого нет у принимающего сеанса, вы увидите тот же запрос, что и при любой другой работе. В автоматическом режиме классификатор также проверяет каждое сообщение перед доставкой, и заблокированное им сообщение никогда не доходит до получателя. Эти ограничения действуют даже в разрешительных режимах, поэтому сеанс, обходящий ограничения, по умолчанию удерживает входящие сообщения, а не доверяет им.
Это касается разрешений. Это не касается содержимого. Отправляющий сеанс мог прочитать описание pull request, веб-страницу, README-файл зависимости или комментарий к задаче, написанный посторонним лицом, и всё прочитанное может повлиять на текст, который он пишет в ваш другой сеанс. Сообщение — это данные. Оно заслуживает такого же подозрения, как и любой другой текст, попавший в сеанс извне. Это дисциплина, описанная в разделе защита секретов от ваших ИИ-агентов: исходите из того, что всё, что пересекло границу доверия, может быть неверным, и никогда не позволяйте этому авторизовать себя.
Существует два элемента управления, если вы хотите ограничить это поведение. Установка crossSessionInbound в значение refuse отбрасывает входящие сообщения от узлов без их доставки, и этот параметр, заданный в проектных или локальных настройках, имеет приоритет над любыми другими источниками, так как является самым строгим в иерархии. Чтобы запретить этому сеансу отправку или отображение списка, добавьте правила запрета разрешений, указав SendMessage и ListAgents, записанные как имена инструментов без дополнительных спецификаторов. Установка isolatePeerMachines в значение true требует вашего явного одобрения перед тем, как любое сообщение достигнет сеанса за пределами этой машины, и это одобрение требуется даже в режиме bypassPermissions.
{
"crossSessionInbound": "refuse",
"isolatePeerMachines": true
}Запрет SendMessage также отключает обмен сообщениями с субагентами, так как один и тот же инструмент используется для обеих целей. Отклоняющий сеанс не показывает видимых изменений в собственном /status или в списках других сеансов, поэтому проверяйте настройки через конфигурацию сеанса, а не по экрану.
Мосты и MCP-серверы с общей памятью
В тот же период появилось несколько сторонних проектов, решающих смежные задачи: локальные мосты «агент-агент», передающие текст между запущенными агентами, и MCP-серверы (model context protocol), предоставляющие нескольким агентам единое хранилище для чтения и записи. Рассматривайте их как альтернативный подход, а не как конкурентов, и всегда проверяйте любую команду установки по файлу README конкретного проекта перед запуском. Обмен сообщениями здесь работает по принципу push, так как отправитель помещает текст в очередь получателя. Общее хранилище работает по принципу pull: никто не прерывает работу, а сессия видит заметку при следующем обращении. Модель pull лучше подходит для статусов, которые меняются медленно, и работает только тогда, когда сессия действительно запрашивает данные.
Если вы выбрали этот путь, стоит задавать вопросы о процессах, а не о списке функций. От имени какого пользователя работает сервер и к каким файлам на машине он имеет доступ? В статье Запуск MCP-серверов на VPS описана эта настройка. В статье Обмен навыками агентов между репозиториями рассматривается более простой случай, когда между сессиями нужно передавать инструкции, а не текущее состояние; это позволяет избавиться от множества лишних сообщений. Для общего понимания ситуации начните с запуск агента для программирования на VPS.
FAQ
Почему команда /list-agents не распознается в моей сессии?
В сессии отсутствует обмен сообщениями между сессиями. Сначала сверьте claude --version с версией 2.1.224, так как эта функция требует указанную версию или более позднюю. Затем проверьте платформу: она работает в macOS и Linux, но не в нативной Windows, а также недоступна в Amazon Bedrock, Claude Platform on AWS, Google Cloud's Agent Platform и Microsoft Foundry. Если с этим всё в порядке, проверьте оболочку на наличие DO_NOT_TRACK, DISABLE_TELEMETRY, CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC или DISABLE_GROWTHBOOK, так как каждый из этих параметров блокирует оценку флага функции, от которой зависит работа, и оставляет её выключенной.
Почему мое сообщение для другой сессии не дошло?
Если /list-agents работает, значит, обмен сообщениями включен, и доставку блокирует что-то более узкое. Частая причина — права доступа. Сессия, которая обходит запросы разрешений, удерживает каждое входящее сообщение до вашего подтверждения, если отправитель также не использует обход. Диалоговое окно подтверждения закрывается по истечении срока dialogExpiry (по умолчанию — пять минут). Проверьте сессию-отправитель на наличие уведомления об удержании. Чтобы исправить это, установите crossSessionInbound в значение accept в файле ~/.claude/settings.json или передайте его через --settings, так как accept в настройках проекта или локальных настройках игнорируется как менее строгое значение.
Может ли сессия Claude Code в Docker отправить сообщение сессии на хосте?
Нет. Сессии находят друг друга через регистрационные файлы на диске и сокет входящих сообщений для каждой сессии. У контейнера своя файловая система, поэтому они не видят одни и те же файлы. Две сессии внутри одного контейнера могут обмениваться сообщениями в обычном режиме. Это же правило объясняет, почему сессия, запущенная от имени root, и сессия, запущенная от имени вашего обычного пользователя, не могут связаться друг с другом: сокет ограничен пользователем операционной системы, который им владеет.
Безопасно ли выполнять действия по сообщению из другой сессии Claude Code?
Относитесь к тексту как к недоверенным входным данным, так как сессия-отправитель могла прочитать веб-страницу, README или комментарий к задаче, написанный кем-то другим. Claude Code уже ограничивает автоматическое выполнение сообщений: он не может подтвердить ожидающий запрос разрешения, не может изменить настройки разрешений или CLAUDE.md по запросу, а slash-команда в тексте приходит как обычный текст и не выполняется. Эти меры защиты касаются разрешений, а не оценки содержимого, поэтому прочитайте полученное сообщение, прежде чем давать принимающей сессии команду на выполнение.
Отправляет ли обмен сообщениями между сессиями мой код в Anthropic?
Между двумя сессиями на одном компьютере — нет. Сообщение передается через локальный сокет сессии и не проходит через серверы Anthropic. Передается только текст, написанный Claude, а не история переписки или файлы. Сообщения для сессии на другом вашем устройстве или в веб-интерфейсе проходят через серверы Anthropic по каналу Remote Control. В этом направлении Claude может только ответить на полученное сообщение, но не инициировать его. Установите isolatePeerMachines в значение true, чтобы требовать вашего подтверждения перед отправкой любых данных с компьютера.