Клиента в этом кейсе нет. Ломалось у нас, цифры — с рабочей доски.
Что именно работает
Grow2.ai ведёт контент-производство как мультиагентную систему на Paperclip: редактор ставит задачи, автор пишет мастер-материал, дистрибьютор адаптирует под платформы, публикатор выкладывает, отдельный агент собирает метрики. Похожую конфигурацию мы разбирали в кейсе про четырёх агентов в менеджменте — здесь та же логика, только применённая к собственному контенту. Каждый этап — отдельный агент со своим контекстом, своим запуском и своей задачей на доске. Переход между этапами формализован через статус задачи и blocker-зависимость: агент закрывает свою задачу в done, и это будит следующего.
Масштаб на 13 августа 2026 года: доска ведёт сквозную нумерацию от AUSA-14 до AUSA-2417, первая задача создана 12 марта. В контент-части 165 материалов, из них 82 опубликованы. Пяти месяцев хватило, чтобы увидеть, что именно ломается на самом деле.
Главное наблюдение: агенты не падали
Ожидание было такое, что проблемы будут внутри агентов. Галлюцинации, испорченный JSON, агент неправильно понял задачу, агент зациклился. Такие вещи случались, они дешёвые и заметные: агент пишет комментарий, ты читаешь и исправляешь — и именно под них строится привычная обвязка защиты.
Дорогие сбои выглядели иначе. Агент отрабатывал успешно, отчитывался успешно, закрывал задачу успешно — и работа исчезала. Не терялась в смысле удаления файла, а становилась невидимой для следующего этапа. Материал лежит на диске, задача закрыта, все метрики зелёные, публикации нет.
Три паттерна ниже — самые дорогие из тех, что мы нашли; самый долгий держался 24 дня. Общее в них не технология, а то, что ни один не диагностируется проверкой «работает ли агент».
Паттерн 1: одобренный материал, который никогда не вышел
Апрув у нас проходит через Telegram: приходит карточка с материалом, пользователь нажимает «Approve», сервис-шлюз ловит решение и создаёт задачу на публикацию.
Дальше был баг допущения. Шлюз создавал дочернюю задачу «опубликовать», но саму задачу-апрув в done не переводил — у него банально не хватало прав на чужую задачу. А следующий этап, который каждое утро ищет, что сегодня публиковать, гейтил публикацию именно по статусу апрува: done или нет. Апрув оставался в in_review, через семь рабочих дней политика устаревших задач сдвигала его в backlog, и материал становился невидимым навсегда.
Состояние на момент, когда мы это нашли (скан 9 июля 2026, 2010 задач на доске):
Показатель | Значение |
|---|---|
Задач на публикацию, созданных шлюзом с 12 марта по 9 июля | 82 |
Из них апрув не в | 34 |
— застряли в | 18 |
— висели в | 15 |
— в | 1 |
То есть 34 материала были одобрены живым человеком и одновременно невидимы для системы. Самая неприятная подгруппа — те 18 в backlog: политика устаревания исправно помечала их как «висит без решения больше недели», хотя решение было принято в первый день. Система отчитывалась противоположно тому, что произошло.
Починили так: закрытие апрува стало отдельным шагом редактора в ежедневном прогоне. Скан всех задач на публикацию с маркером апрува, и если родительский апрув не закрыт — закрыть. Квитанцией апрува считается само наличие дочерней задачи на публикацию.
Если квитанция о решении пишется одним компонентом, а читается другим, проверять надо не то, что компонент отработал, а то, что квитанция действительно появилась там, где её будут искать.
Паттерн 2: молчащий агент — это сломанный движок, а не доступы
У публикатора был настоящий, задокументированный блокер: часть токенов соцсетей мертва. Задача на разблокировку доступов висела с июня.
Поэтому когда задачи на публикацию перестали двигаться, диагноз казался очевидным. Задачи AUSA-2084 и AUSA-2085 созданы 13 июля, стоят в todo, публикаций нет, у публикатора нет токенов — причина найдена, ждём доступов.
Правильный ответ нашёлся 6 августа, через 24 дня. В тех задачах было ноль комментариев.
Агент, который упирается в отсутствующие доступы, оставляет комментарий: перечисляет платформы, которые отвалились, и останавливается. Агент, который не оставил ни одного комментария, не запускался вообще. Ломался не доступ, а движок сессии — агент падал на инициализации, до того как увидеть задачу. Лечение оказалось не в токенах, а в конфигурации модели; после перевода агентов на новую модель публикатор в тот же день опубликовал материал. То, что поведение агента зависит не только от промпта, но и от обвязки вокруг него, мы разбирали отдельно — почему один и тот же AI-агент даёт разные результаты.
Прежде чем списать застой на известный блокер, открой задачу и посмотри, есть ли там комментарий агента. Нет комментария — чини запуск, а не интеграцию. Разницу между «агент попробовал и не смог» и «агент не проснулся» на доске не видно никак, а стоила она двадцати четырёх дней.
Нюанс, которого мы тоже не знали: публикатор просыпается на создание задачи, а старые задачи в todo не перевызывает сам. После починки движка их надо будить явно.
Паттерн 3: фильтр, который отсеивает своих
Ежедневная проверка «что публикуем сегодня» отбирает материалы условием дата публикации == сегодня. Строгое равенство здесь не случайно: ослабление до <= сегодня приводит к тому, что материал с прошедшей датой и уже закрытой задачей на публикацию получает новую задачу каждое утро, а создание задач не идемпотентно. Дубли ежедневно — хуже, чем пропуск.
Следствие, которое из этого правила не вытекает очевидно: материал без поля даты не совпадает с сегодняшним числом никогда. Он невидим бессрочно — и при этом может быть полностью готовым, с заполненными адаптациями под платформы и реальным апрувом.
10 августа таких материалов было 32. Разбор по состоянию апрува показал, что «32 потерянных» — неточная формулировка, и разные подгруппы лечатся по-разному:
Подгруппа | Количество | Что это значит |
|---|---|---|
Апрув в | 19 | Одобрено пользователем, не выйдет никогда — лечится датами |
Апрув | 2 | Требует ручного решения |
Апрув в | 2 | Требует ручного решения |
Нет ссылки на апрув | 9 | Другой дефект, лечится процедурой поиска «сирот» |
На 13 августа без даты остаётся 26 материалов: 17 со ссылкой на апрув и 9 без неё.
Это не ошибка кода. Условие написано ровно так, как задумано, и ослабить его нельзя. Ошибка в допущении, что дата всегда есть, — а поле необязательное, и материал может дойти до готовности без него.
Рядом жил ещё один дефект той же природы, и стоил отдельного дня. Те же сканы сначала были написаны как обход папки текущего месяца. Папка — это месяц создания материала, а дата в файле — месяц публикации, и расходятся они регулярно. Скан по августовской папке честно рапортовал «публиковать нечего», пока два готовых материала с датой на сегодня лежали в июльской.
Что общего в трёх паттернах
- В первом — шлюз сделал ровно то, на что имел права, а квитанция о решении не появилась там, где её читали.
- Во втором — агент не существовал как процесс, но его статус на доске был валидным состоянием «до работы», не отличить от «ждёт своей очереди».
- В третьем — фильтр корректно отсеял всё, что не совпадает с условием, включая то, что должно было пройти.
Общий знаменатель: агент, который отчитался об успехе, и работа, которая дошла до следующего этапа, — это два разных события. Мониторинг, который проверяет первое, ничего не знает о втором.
Эта формулировка не наше открытие. Работа Why Do Multi-Agent LLM Systems Fail? (Cemri и др., NeurIPS 2025) разобрала более 1600 аннотированных трасс выполнения из семи популярных мультиагентных фреймворков и построила таксономию MAST — 14 режимов отказа в трёх категориях. Одна из трёх категорий — inter-agent misalignment, то есть сбой передачи критической информации между агентами, а не внутри них. Частота отказов в разобранных фреймворках составила от 41% до 86,7%. Наши три паттерна ложатся ровно в эту категорию, и то, что они воспроизвелись на собственном стеке без знакомства с этой таксономией, — скорее подтверждение, чем совпадение.
Что мониторить на стыках
Практический минимум, к которому мы пришли. Это не универсальный фреймворк, а то, что закрывает наши три паттерна.
Проверять артефакт, а не статус. После написания должен появиться файл, после публикации — URL или ID записи на платформе. Задача в done не доказывает, что работа состоялась: наш публикатор честно закрывает задачу в done и тогда, когда пропускает материал по дате.
Тишина агента — отдельное состояние. Задача назначена, прошли сутки, комментариев ноль — это не «в работе», это «не запустился». На доске оба выглядят одинаково, так что различать приходится явно.
Строгие фильтры должны рапортовать отсев: не только что прошло дальше, но и сколько не прошло и почему. Фильтр дата == сегодня, который молча выбрасывает 26 готовых материалов, отчитывается как «сегодня публиковать нечего».
И отдельно — то, что не про код вообще. Самая дорогая из трёх ошибок технической не была: двадцать четыре дня мы строили план вокруг правдоподобного объяснения, вместо того чтобы потратить один запрос на его проверку. Известный блокер в системе — удобный ответ, к которому симптомы липнут сами. Это касается и собственных вчерашних выводов, что мы тоже проверили на себе: посылку «закрывать апрувы батчем нельзя, будут дубли» мы возили в голове неделю, пока скан не показал, что дублей не будет ни одного.
Честная граница этого материала
Здесь нет клиентских результатов и нет утверждений о том, что это универсально. Это пять месяцев работы одной системы — 18 агентов на одной платформе оркестрации, из них пять в контент-цепочке. Три паттерна — то, что мы нашли у себя, а не исчерпывающий перечень режимов отказа; MAST насчитывает четырнадцать.
Grow2.ai строит кастомных AI-агентов под процесс клиента, и публиковать список собственных поломок — слегка неудобный способ об этом говорить. Но совет «мониторьте переходы, а не агентов» без трёх конкретных историй, где мы этого не делали, стоил бы ровно ничего.
Как мы строим агентов и где проводим границу между тем, что стоит автоматизировать, а что нет — на grow2.ai.