TL;DR
В цепочке из нескольких агентов самая опасная поломка — не «сообщение не дошло», а «дошло, но без части данных». Формально всё в порядке: формат корректный, ошибок нет, следующий агент спокойно работает дальше. Исследование показывает, что каждый пятый сбой остаётся молчаливым, а при потере части содержимого — три из четырёх. Выигрывает схема, где нужные доказательства можно получить другим путём, а не только через одну передачу «из рук в руки».
Боль знакома всем, кто строит цепочки «исполнитель → проверяющий → решающий». Проверяющий получает отчёт без пары ключевых полей и пишет «подтверждено». Он принял «запрошено 1 штуку» за «зафиксировано 1 штуку». Отчёт собран по шаблону, поэтому пропажи никто не замечает. Ошибка не всплывает, а тихо переезжает в итоговый результат.
Главный практический вывод: смена модели почти не лечит такие сбои, а смена структуры потока лечит заметно. Переход на схему с запасным путём информации спасал в разы больше упавших запусков, чем замена модели. Защита «останови или перезапусти исполнение» и защита «проверь доказательства» спасают разные случаи, то есть дополняют друг друга. Но восстановление доказательств работает, только если хоть где-то осталась нетронутая копия данных.
Схема: как поломка добирается до результата
ИСТОЧНИК → сеть, обрыв, таймаут, устаревший контекст, разбор в среде выполнения
СИМПТОМ → сообщение не пришло / опоздало / пришло частично /
пришло искажённым / дубль / старое
ПОСЛЕДСТВИЕ → системное (видно): провал делегирования, таймаут
смысловое (тихо): потеря ограничений, «уплыл» план,
устаревшее знание, неверное решение
ИСХОД → задача выполнена / провалена (оценивает независимый судья)
Где ломали сообщения в цепочке:
I2: запрос действия (инструкция, вызов инструмента)
I3: наблюдение (результат инструмента вернулся в цепочку)
I4: передача доказательств проверяющему или решающему агенту ← самое уязвимое место
Пример применения
В статье нет готовых промптов. Пример ниже — перенос выводов на промпт. Он опирается на случай из рис. 1, где проверяющий принял неполные доказательства.
Задача: Вы настраиваете цепочку агентов для возвратов на маркетплейсе в духе Ozon или Wildberries. Приёмщик читает обращение и фото, проверяющий решает «возврат обоснован», третий агент инициирует выплату в рублях. Нельзя, чтобы проверяющий одобрил выплату по неполным данным только потому, что отчёт «выглядит нормально».
Промпт (системная инструкция проверяющего):
Ты — Проверяющий в цепочке обработки возвратов. Ты НЕ доверяешь статусу
«успех» от предыдущего агента. Ты проверяешь доказательства.
<ОбязательныеПоля>
- номер_заказа
- сумма_заказа_руб
- причина_возврата (со слов клиента)
- наблюдение: что приёмщик увидел сам (фото, трек-статус, дата доставки)
- ссылка_на_исходное_обращение
ОбязательныеПоля>
<Правила>
1. Сверь входящее сообщение со списком обязательных полей.
Если хотя бы одного нет — ответ «НЕДОСТАТОЧНО ДАННЫХ: нет полей [...]».
Не додумывай и не восстанавливай по смыслу.
2. Разделяй «заявлено» и «наблюдено». Слова клиента — это «заявлено».
Фото и статус доставки — «наблюдено». Нельзя считать заявленное наблюдённым.
3. Если поля неполные, запроси данные напрямую из исходного обращения
(ссылка_на_исходное_обращение). Не требуй, чтобы приёмщик пересказал заново.
4. Одобряй возврат только если все поля есть и «наблюдено» подтверждает причину.
Правила>
<ФорматОтвета>
Проверка полей: [есть / нет — какие]
Заявлено: ...
Наблюдено: ...
Решение: ОДОБРИТЬ / ОТКЛОНИТЬ / НЕДОСТАТОЧНО ДАННЫХ
ФорматОтвета>
Результат: Проверяющий сначала покажет проверку полей. Если одного поля нет, он остановится с пометкой «недостаточно данных» вместо молчаливого «одобрено». При возможности сам заберёт недостающее из исходного обращения. В ответе будут отдельные строки «заявлено» и «наблюдено», так что видно, на чём держится решение.
Почему это работает
Слабость. LLM-агент принимает сообщение как есть. Если формат цел, он не замечает, чего в нём не хватает. Он не видит отсутствие, он читает то, что дали. Поэтому потеря поля выглядит как полноценный отчёт. Модель к тому же склонна «достраивать» пробелы правдоподобным смыслом. Так «запрошено» превращается в «наблюдено».
Сильная сторона. Модель хорошо сверяет текст со списком и чётко следует явным правилам. Если ей дать перечень обязательных полей и запретить принимать статус на веру, она сама назовёт, чего не хватает.
Как использовать. Метод не лечит потерю сообщений, он делает пропажу заметной и даёт второй источник правды. Это и есть вывод статьи: восстановление доказательств работает, когда есть нетронутый путь к данным, и не работает, когда сбой задел все пути сразу.
Рычаги: - Список обязательных полей → короче для простых задач, строже для денег и юридических действий. - Запасной источник (исходное обращение, общий файл) → чем он независимее от основной цепочки, тем лучше. Копия, прошедшая через тот же канал, не спасает. - Правило остановки («недостаточно данных» вместо додумывания) → для критичных решений делай обязательным, для черновиков можно смягчить.
Шаблон промпта
Это моя сборка из выводов статьи, не авторский шаблон. Блок для любого агента, который принимает работу от другого:
Ты — {роль_агента}. Ты получаешь результат работы от {предыдущий_агент}.
<ВходящееСообщение>
Обязательные поля: {список_обязательных_полей}
Запасной источник данных: {где_взять_оригинал}
ВходящееСообщение>
<Правила>
1. Сначала сверь входящее со списком обязательных полей.
Не хватает поля → напиши «НЕДОСТАТОЧНО ДАННЫХ: нет [поля]».
2. Статусы вроде «успех», «готово», «проверено» — не доказательство.
Опирайся только на данные внутри сообщения.
3. Различай «заявлено» и «наблюдено». Нельзя принимать первое за второе.
4. Если поля неполные — возьми недостающее из {где_взять_оригинал}.
Если и там нет — остановись и запроси у человека.
5. Решение принимай только когда все обязательные поля подтверждены.
Правила>
<ФорматОтвета>
Проверка полей: [...]
Заявлено: [...]
Наблюдено: [...]
Решение: {варианты_решения}
ФорматОтвета>
Что подставлять:
- {роль_агента} — проверяющий, решающий, редактор итогового отчёта.
- {список_обязательных_полей} — минимум данных, без которых решение нельзя принимать.
- {где_взять_оригинал} — первичный источник: исходное обращение, файл в репозитории, таблица.
- {варианты_решения} — например: одобрить / отклонить / недостаточно данных.
🚀 Быстрый старт — вставь в чат:
Вот шаблон защитного блока для агента, принимающего работу от другого агента.
Адаптируй под мою цепочку: [опиши агентов и что они передают друг другу].
Задавай вопросы, чтобы заполнить поля.
[вставить шаблон выше]
LLM спросит, какие данные критичны для решения, где лежит независимый первоисточник и какие решения допустимы. Без этого блок не сработает: нужен список обязательных полей и второй путь к данным. Модель возьмёт структуру из шаблона и соберёт блок под вашу цепочку.
Ограничения
⚠️ Сбои искусственные: Потери и искажения сообщений вносили специальным перехватчиком. Как часто такое случается в вашей реальной системе — вопрос отдельный. Если агенты работают в одном чате без сетевых протоколов, риск ниже.
⚠️ Запасного пути нет — защита не спасает: Если сбой задевает все каналы с данными, восстановление доказательств не работает. Копия, прошедшая тем же путём, не помогает.
⚠️ Шаблон — не из статьи: Авторы изучали сбои и механизмы защиты, но не тестировали промпты в духе «проверь обязательные поля». Промпт выше — перенос принципа, его нужно проверить на своей цепочке.
⚠️ Структура важнее модели, но цифры экстремальны: Огромный разрыв между схемами (больше половины успеха против нескольких процентов) получен при искусственных сбоях именно в точке передачи доказательств. В обычной работе разница будет мягче.
⚠️ Часть статьи не видна: В доступном тексте оборвано описание самих механизмов защиты. Детали их устройства и цены (задержка, число запросов) здесь не разобраны.
⚠️ Нужен код для полной защиты: Полноценные перехватчики, повторные попытки и контроль доставки — это инженерия. Через инструкции агенту можно лишь частично закрыть смысловую часть.
Как исследовали
Идея была простой: сломать сообщения между агентами и посмотреть, что будет. Команда построила перехватчик, который встаёт между отправителем и получателем и портит передачу. Он может потерять сообщение, задержать, продублировать, обрезать или исказить. Ломали в трёх точках: запрос действия, результат инструмента и передача доказательств проверяющему.
Всего вышло больше 29 000 запусков: 100 задач, 5 областей, 3 схемы потока (последовательная цепочка, иерархия с координатором, плоская схема) и 3 конфигурации моделей. Из них 15 882 сбоя реально дошли до цели. В 80,2% случаев задача провалилась, и почти у 90% были заметные последствия для системы. Среди 8 335 провалов с полной записью 20,7% были молчаливыми. Для частичной потери содержимого доля достигала 76,2%.
Неожиданнее всего оказалась роль структуры. В плоской схеме при сбоях сохранялось 53,0% успеха, в последовательной и иерархической — около 3%. Преимущество давала не сама плоскость, а альтернативный путь информации. Если проверяющий мог взять доказательства не только из одной передачи, потеря сообщения его не губила. Сравнение «сменить структуру» против «сменить модель» на 1 408 одинаковых случаях дало 19–27% спасённых провалов против 0,2–4,5%. Вывод для практики: когда цепочка ломается на передачах, чинить нужно поток, а не покупать модель дороже.
Отдельно проверили защиту на 1 098 запусках. Защита исполнения и защита доказательств спасали разные случаи, то есть дополняли друг друга. Оценку исхода делал независимый судья, а не сама система, поэтому «статус: успех» от агентов в зачёт не шёл.
Адаптации и экстраполяции
Это мои идеи по мотивам статьи, не проверенные авторами.
🔧 Техника: добавить второй путь → потеря сообщения перестаёт быть смертельной
Пусть агент не только передаёт результат в сообщении, но и пишет его в общее место (файл, таблицу, заметку проекта). Проверяющий читает оба источника и сверяет.
Результат работы запиши в файл {путь}/результат.md И передай коротким
сообщением. Проверяющий обязан открыть файл и сверить с сообщением.
При расхождении — остановись и сообщи.
🔧 Техника: запретить «статус вместо доказательства» → проверяющий смотрит данные
Слова «готово», «успех», «проверено» не принимай как подтверждение.
Требуй сами данные: что именно было сделано и что именно получено.
Экстраполяция для агентов вроде Claude Code: в инструкции для субагентов (CLAUDE.md или описание субагента) добавь правило: «Результат возвращай в ответе и сохраняй в файл. Если итог без ссылки на файл — считай его неполным». Работает ли это на вашем проекте, нужно проверить.
Ресурсы
- When Messages Go Wrong: Understanding Communication Faults in LLM-Based Multi-Agent Systems
- Авторы: Jinhao Zhou (Waseda University), Xiaoyu Zhang (HKUST), Jiongchi Yu (Nanyang Technological University), Fahao Chen (Shandong University), Jun Wu (Shanghai Jiao Tong University)
- Код и данные: https://github.com/SonGoKu21/mas_communication/
- Сайт: https://songoku21.github.io/mas_communication/
- Упомянутые системы и протоколы: MCP (Model Context Protocol), A2A (Agent-to-Agent), AutoGen, MetaGPT, AgentChaos, MASFIRE, ReliabilityBench
