Как мы докатились до монстра
У каждого, кто год-два держал один боевой промпт, есть такой момент. Сначала это был короткий текст: «ты помощник по заявкам, вот справочник, вот примеры». Потом добавился разбор дат, потом условия с клиентом, потом костыль под странный шаблон подрядчика. К концу квартала промпт уже занимал полэкрана, а любая правка начинала ломать то, о чём уже никто не помнил.
Мы запихнули туда всё: условия, исключения, «если просит X — делай Y, но не когда Z». Модель работала нормально в 80 % случаев, а в остальных 20 % ошибалась каждый раз по-новому. Ловить регресс становилось всё дороже.
В итоге стало ясно: проблема не в промпте. Мы пытались одним агентом решить задачу, где внутри как минимум три разных ремесла. Тогда и решили переделывать всё в систему агентов.
Почему один агент не тянул
Заявка, которая приходит в бизнес, почти никогда не бывает простой. Клиент пишет «нужен кабель ВВГ 3×2.5 на объект в Подмосковье, до конца недели, счёт на ту же компанию». В одном сообщении сразу четыре операции: поиск номенклатуры, привязка адреса, дата и реквизиты. У каждой — своя логика ошибок.
Единый агент при этом ведёт себя как человек, которого одновременно спросили о трёх вещах: на что-то отвечает уверенно, что-то выдумывает, а что-то просто роняет. Когда мы добавляли ещё инструкций, всё только размывалось. Правишь одно — плывёт другое.
Разделение на роли
Первый порыв — просто разрезать промпт под каждый инструмент — не помог. Это был всё тот же монстр, только разложенный по полочкам.
Настоящий сдвиг случился, когда мы перестали думать про инструменты и начали думать про роли. Появились три отдельных агента:
- маршрутизатор — читает сообщение и раскладывает его на простые задачи, ничего не отвечает клиенту;
- исполнители — узкие агенты под свою область (номенклатура, реквизиты, даты), у каждого свой промпт и свои инструменты;
- проверяющий — собирает результаты, сверяет с исходной заявкой и решает, отправлять ответ или доспрашивать.
По сути это просто разделение труда, к которому пришли бы любые три человека на одной задаче.
Как они общаются
Между агентами поставили жёсткий контракт: не свободный текст, а структурированные сообщения. Российские модели нормально возвращают JSON по схеме, если чётко объяснить, чего хочешь.
Всё состояние хранится в PostgreSQL. Каждый шаг агента — отдельная строка со ссылкой на родительскую задачу. Это дало возможность откатить один шаг и понять, где именно решение поехало не туда.
Что вылезло при внедрении
Первое, чего не ждали: качество выросло не на сложных заявках, а на простых. Раньше единый агент «перестраховывался» из-за инструкций под сложные случаи. Как только простые запросы пошли коротким путём — они стали лететь без лишних вопросов.
Второе: латентность выросла. Три модели вместо одной — это три сетевых вызова. Часть времени отыграли параллельным запуском исполнителей и лёгкой моделью для маршрутизатора.
Третье: система ломается тише. Когда падал один большой промпт — клиент сразу получал ерунду. Когда падает маршрутизатор, одна подзадача просто исчезает, и через день менеджер спрашивает, куда делся счёт. Пришлось сразу добавлять сквозные идентификаторы и метрики.
Как проверять систему
Со снапшот-тестами на один промпт мы уже умели работать. Но когда агентов несколько, снапшот на финальный ответ перестаёт быть полезным — непонятно, где именно сломалось.
Сделали внутренний прогон: берём реальные заявки с эталонным разбором, запускаем всю систему и сравниваем не только финал, но и промежуточные шаги. Так регресс ловится раньше и видно, в каком звене.
Что изменилось в работе
Раньше правка любого сценария была маленьким приключением. Теперь правка идёт в промпт конкретного исполнителя и не трогает остальных. Разбор странных случаев превратился в разбор конкретного звена по идентификатору задачи.
Когда делить стоит, а когда нет
Если в задаче честно одно действие — не надо городить три роли. Один хороший промпт и один инструмент отработают лучше и дешевле.
Правило, которое вывели для себя: если промпт уже занимает больше экрана и в нём появились «но если», «за исключением», «в случае когда» — это сигнал, что внутри прячется несколько разных задач. Их проще разделить между агентами.
А как только агентов становится несколько — сразу закладывай состояние в базу, сквозные идентификаторы и оценочный прогон. Иначе через месяц система станет такой, что её страшно трогать.
