Полгода назад в нашем продукте был один автотест. Не одна папка с тестами — один тест. Сейчас их 878, и заметная часть написана не людьми, а командой ИИ-агентов, которую я собрал и которую мы внутри называем харнессом.
Про то, как «LLM пишет автотесты», написано уже много. Обычно это выглядит так: взяли модель, дали промпт, получили черновик, инженер поправил. Работает, экономит часы, но упирается в потолок примерно через неделю — потому что промпт живёт в голове автора, качество плавает от запуска к запуску, и никто не может ответить на вопрос «а этот наш новый супер-промпт вообще лучше, чем без него?».
Эта статья — про то, что мы построили вместо этого, и почему в системе, где код пишут агенты, самой дефицитной компетенцией оказывается не разработка, а тестирование.
Проблема: агент-универсал не масштабируется
Первая версия была стандартной — один агент, большой промпт, «ты опытный QA-инженер, напиши автотест по этому ТЗ». Она сломалась о три вещи.
Контекст. Чтобы написать хороший тест для мобильного приложения на Kotlin Multiplatform, нужно одновременно держать в голове: бизнес-требование, архитектуру приложения, стратегию локаторов, конвенции тестового фреймворка, особенности фермы устройств и десяток грабель, на которые уже наступали. В один промпт это не влезает, а если влезает — модель начинает терять то, что в середине.
Границы. Универсальный агент, которому разрешено всё, рано или поздно делает лишнее: правит чужой тест, лезет в соседний модуль, коммитит без спроса. Один раз это мило, на пятидесятый — вы уже разбираете последствия дольше, чем писали бы руками.
Невоспроизводимость. Самое неприятное. Сегодня агент выдал отличный тест, завтра на такой же задаче — мусор. Почему? Непонятно. Что поменялось? Ничего, кроме формулировки задачи. Управлять этим нельзя, а значит нельзя и внедрять в команду.
Решение: не агент, а команда с контрактами
Мы перестали думать «промпт» и начали думать «команда разработки». Не один универсал, а набор узких ролей, у каждой — своя зона ответственности, свои инструменты и своя память об ошибках.
Харнесс собран из компетенций: ba, sa, mobile, backend, web, testing, sec и общий слой common. Компетенция — самодостаточный модуль, и у каждой одинаковые шесть слоёв:
agents/— промты ролей, один файл = одна роль;commands/— сценарии запуска: кто за кем работает и что кому передаёт;skills/— переиспользуемые процедуры «как сделать X правильно»;patterns/— декларативные правила, каким должен быть результат;gotcha/— журнал отклонений «как делать нельзя»;scripts/— гейты, генераторы и раннеры.
Между слоями действует жёсткое ограничение — не больше трёх переходов: command → agent → skill → pattern. Это не эстетика, это защита от той самой потери контекста: агент физически не может утонуть в дереве ссылок, потому что дерево неглубокое.

Ещё один инвариант, который дороже, чем кажется: папки agents/ и gotcha/ зеркальны. Завёл роль — заведи ей папку граблей. Иначе роль появится, а её правила читать будет неоткуда, и вы получите ровно того самого универсала, от которого уходили.
Где здесь тестирование: два разных ответа
Когда я рассказываю про харнесс коллегам, первый вопрос всегда один: «а тестировщик там зачем, если агенты сами всё пишут?». Ответов два, и второй интереснее первого.
Ответ первый: testing — это отдельная компетенция
В харнессе есть модуль testing, и он самый населённый из всех. Восемь ролей: qa-lead (оркестрирует), test-designer (проектирует кейсы), tester (проверяет вручную то, что не автоматизировано), auto-mobile и auto-web (пишут автотесты), qaops (окружения, стенды, устройства), researcher (разбирается в незнакомом коде перед тем, как его тестировать) и reviewer (ревьюит работу остальных).
Под ними — паттерны, которые фиксируют «каким должен быть результат»: архитектура мобильных автотестов, стратегия локаторов для Appium, дизайн тест-кейса, права тестовых аккаунтов, доказательства прогона. И скрипты, которые делают руками неприятное: поднять Appium, подготовить устройство, собрать APK, прогнать тесты, собрать артефакты, вытащить кейсы из Allure, проверить репозиторий на мусор.
Это ожидаемая часть. Полезная, но предсказуемая.
Ответ второй: тестирование — это дисциплина, применённая к самому харнессу
А вот дальше начинается то, ради чего я и пишу эту статью.
Главная проблема любого набора промптов и «скилов» — они попадают в систему на доверии. Кто-то написал промпт, он показался хорошим, его закоммитили. Через полгода у вас сто промптов, из которых работают тридцать, а какие именно — не знает никто, потому что никто никогда не проверял.
Мы сделали так, что новый инструмент не попадает в харнесс без доказательства. Процедура называется гейтом и устроена как обычный TDD, только тестируем мы не код, а полезность инструмента:
RED. Свежий субагент решает задачу без инструмента, на реальных продакшн-исходниках. Это базовая линия: что модель выводит сама, без нашей помощи.
GREEN. Тот же субагент решает ту же задачу с инструментом и проходит заранее написанную рубрику.
Вердикт по лестнице удержания: retain-correctness (инструмент даёт корректность, которой не было) → retain-efficiency (корректность та же, но дешевле) → retain-floor-differential (работает там, где без него не работало на слабой модели) → иначе cull-candidate и culled.

Последнее слово тут ключевое. Culled значит «удалили». Инструмент, который не доказал пользу, выкидывается — так же, как выкидывается мёртвый код. У паттерна доказательство лежит рядом в EXAM.md, у скила — в BENCH.md. Нет пруфа — нет инструмента.
Отдельный режим — A/B, когда сравниваются не «инструмент против пустоты», а два варианта между собой: две формы оркестрации, два способа разложить работу по агентам. И вот тут мы вписали в линтер правило, которое я считаю самым ценным во всей системе:
Вердикт «B лучше» невалиден, если на том уровне, который его формирует, не установлен паритет по корректности.

По-человечески: дешевле и быстрее не считается победой, если результат хуже. Это ровно тот разговор, который QA ведёт с бизнесом последние двадцать лет, только теперь он зашит в линтер и падает в CI. Мы добавили это правило не из любви к строгости, а потому что один раз чуть не приняли решение по красивым цифрам стоимости, где «выигравшая» ветка просто не компилировалась в половине прогонов.
Есть ещё понятие флора — минимального уровня модели, на котором инструмент доказан. Скил, отработавший на слабой локальной модели, помечается иначе, чем тот, которому нужна фронтир-модель. И это свойство инструмента, а не роли: одна и та же роль может иметь и дешёвые процедуры, и дорогие.
Gotcha: регрессионные тесты для поведения агента
Третий кусок QA-дисциплины — журнал граблей. Каждый раз, когда агент делает что-то не то, это фиксируется отдельной записью в gotcha/, и перед следующей работой агент обязан прочитать свою вертикаль: общие правила → правила своей компетенции → правила своей роли. Трёхъярусно, чтобы роль читала только релевантное, а не весь журнал.
Функционально это регрессионные тесты, только объект проверки — не приложение, а поведение агента. Вот несколько настоящих записей из нашей вертикали тестирования, они же — самые дорогие грабли проекта:
Агент чинит тест вместо того, чтобы найти дефект. Тест упал. Агент правит тест, чтобы он проходил. Тест зелёный, баг уехал в прод. Правило: сначала докажи, что дефект в тесте, и только потом трогай тест.
Агент замокал то, ради чего писался тест. Фича-тест с моками на всё подряд проверяет, что моки настроены правильно. Это не тестирование.
Агент ходит по приложению через прямые переходы, а не как пользователь. Быстро, стабильно, зелено — и мимо реальных сценариев: половина ошибок навигации так не ловится.
Агент воюет с авторизацией. Вместо штатного механизма логина начинает изобретать обходные пути, потому что «так проще пройти». Стоило нам нескольких часов разбирательств, откуда в тестах взялись странные токены.
Агент тестирует только happy path. Классика, которая у людей лечится ревью, а у агентов — явным правилом.
Агент «завершает» работу на блокере. Уперся в стену, не смог, отрапортовал «готово». Отдельное правило: блокер — это стоп и доклад, а не молчаливое закрытие задачи.
Заметьте: ни одна из этих граблей не техническая. Все они — про то, как тестировщик срезает углы под давлением «сделай, чтобы прошло». Модель воспроизводит наши профессиональные слабости с пугающей точностью, и лечится это ровно тем же, чем у людей — писаными правилами и ревью.
Что это дало в цифрах

Что можно измерить честно:
Написание автотеста: было 1–2 дня на тест с учётом ожидания разработчиков — стало 43–45 тестов за 30 минут вместе с отладкой. По направлению целиком — ускорение примерно в 6 раз.
Покрытие: с 1 автотеста до 878 (518 web + 360 mobile) за пять месяцев.
Разработчики полностью исключены из подготовки тестовой инфраструктуры — раньше проставление testTag в код приложения было отдельной задачей в их спринт, и она регулярно проигрывала приоритет фичам.
Тестовая модель за это время выросла втрое (600 → 1700 кейсов), при этом длительность регресса осталась прежней.
Инструмент забрали три соседние вертикали компании — то есть он оказался полезен вне контекста, в котором создавался.
Что измерить честно нельзя: сколько времени съел сам харнесс. Прилично. Это не проект выходного дня.
Чего я не буду утверждать
Несколько оговорок, без которых статья была бы рекламой.
Это не «QA больше не нужен». Наоборот: чем больше кода пишут агенты, тем дороже стоит человек, который умеет спросить «а мы точно проверили то, что нужно?». Роль сместилась с написания тестов на проектирование правил и разбор пограничных случаев, но никуда не делась.
Порог входа высокий. Чтобы это заработало, у команды уже должны быть архитектура автотестов, стабильные прогоны, ферма устройств и внятные конвенции. Агенты не создают порядок — они масштабируют тот, который есть. Если порядка нет, вы получите быстро сгенерированный беспорядок.
Гейт стоит денег. Каждый RED/GREEN — это лишние прогоны на реальных исходниках, иногда на нескольких моделях. Мы сознательно платим за это, потому что альтернатива — сто непроверенных промптов, но платить придётся.
Часть инструментов не выжила. Это нормальный результат гейта и, по-моему, главный признак, что он работает. Система, где ни один кандидат не отсеивается, — это не гейт, а ритуал.
Итог
Если убрать всю специфику, вывод простой: когда код начинают писать агенты, узким местом становится не скорость производства, а доверие к результату. А выстраивание доверия к результату — это ровно то, чем профессионально занимается тестирование.
Поэтому в харнессе из ИИ-агентов роль QA не уменьшается. Она становится архитектурной: кто-то должен решить, что считается доказательством пользы, что считается регрессом поведения и по какому правилу инструмент выкидывается из системы. Мой опыт говорит, что лучше всех эти вопросы задаёт тот, кто десять лет задавал их разработчикам.
Готов ответить в комментариях на вопросы про устройство гейта, структуру ролей и грабли — их у меня накопилось сильно больше, чем поместилось в статью.

