Агент не видит, что получилось. Он видит только то, что ответили ему
инструменты. Отвечать нечем — тестов нет, сборка идёт десять минут, ошибка
вылезает только в браузере — и он не знает, стало лучше или хуже. Дальше он
угадывает, а вы читаете диф, в котором правда перемешана с фантазией.
Это главная причина, по которой агент буксует. Чинится она не промптом, а
проектом.
По убыванию пользы — а польза здесь измеряется скоростью, не строгостью:
| Проверка | Сколько ждать | Что ловит |
|---|---|---|
| Типы, компилятор | секунды | несуществующее поле, не тот аргумент |
| Линтер | секунды | мусор, неиспользованное, очевидные глупости |
| Юнит-тесты | секунды–минута | сломанное поведение |
| Сборка | минуты | то, что разваливается только целиком |
| Браузер, e2e | минуты | то, что видит человек |
| Человек | часы | всё остальное |
Верхние три — это глаза агента. Он зовёт их сам, десятки раз за сессию, и
чинит красное без вашего участия. Нижние — ваши: до них он добирается редко,
а ответ приходит слишком поздно, чтобы что-то ему подсказать.
Правило скорости: цикл «поменял — проверил» должен укладываться в десятки
секунд. Всё, что дольше минуты, агент начинает пропускать, а заодно
перестаёт понимать, какое именно изменение сломало сборку: между причиной и
следствием набирается слишком много шагов.
Отсюда неочевидное следствие: пять быстрых тестов полезнее ста медленных.
Не потому, что качество проверки выше, а потому, что первые он запускает, а
вторые — нет.
Проект без единого теста не надо покрывать целиком — надо дать агенту хоть
какой-то сигнал.
npm run check, make check,go test ./.... Одна, а не семь: агент должен звать её не думая.Тест позеленел не потому, что код починился. Варианты, в порядке частоты:
3, получилось 4 —4»;skip, t.Skip, xit) или закомментирован;expect(true);Всё это агент делает не со зла: задача была «сделай, чтобы тесты проходили»,
и он её выполнил буквально.
Правило: диф тестов читается отдельно и всегда. Задача была «почини
баг», а в дифе поменялись тесты — это не починка, пока не доказано
обратное.
Хорошо работает обратный порядок: сначала падающий тест на баг, показать
падение, и только потом чинить. Тогда зелёный цвет что-то значит.
Что выходит хорошо: рутина. Таблица случаев, граничные значения, разбор
форматов, регрессия на конкретный найденный баг, заполнение однотипных
проверок по образцу соседнего файла.
Что выходит плохо: тесты, написанные по готовому коду. Такой тест списан
с реализации, а не со смысла, и закрепляет ровно то, что код делает, —
включая ошибку. Просить надо от поведения: «вот что должно происходить в
таких-то случаях», а не «вот файл, покрой его».
Что выходит вредно: тесты ради процента покрытия. Поставленное целью
покрытие модель набивает мгновенно и бессмысленно — сотнями проверок
геттеров. Цифра растёт, сигнал не меняется.
Тест, который падает раз в пять запусков, для человека — раздражение. Для
агента — катастрофа: он получает случайный сигнал и принимается чинить то,
что не ломалось. Дальше он «стабилизирует» его таймаутом, потом ретраями,
потом отключает — и утаскивает за собой соседние.
Флакающий тест чинится или удаляется в тот же день. Третьего варианта нет.
Критерии приёмки перестают быть словами и становятся командой:
Готово — это когда
npm run checkпроходит и добавлен тест, который падал
до правки. Тесты не менять, кроме нового.
Такую формулировку агент может проверить сам, и вы получаете результат, а не
рассказ о результате. Подробнее про постановку — Как писать промпты для
кода.