Что произошло
Мы гоняем разные модели против одной батареи задач — чтобы понимать, какую работу кому можно отдать. Одна из проверок в батарее посвящена не способностям модели, а её самооценке: умеет ли она найти дыры в том, что сама построила.
Ответ оказался устойчивым и одинаковым у флагманских моделей: нет, пока не попросить прямо. Модель, закончив работу, пишет «готово, проверено» — и это не ложь, а следствие того, что проверяет она соответствие собственному замыслу. Тот же слепой угол воспроизводится в её тестах: тест пишется под то поведение, которое автор имел в виду, а баг живёт ровно там, где замысел разошёлся с реальностью.
| Случай | Что показала самопроверка | Что нашёл внешний проход |
|---|---|---|
| Мини-приложение | 20 из 20 тестов зелёные | 8 реальных багов |
| Обработчик заявок | код прочитан, «логика верна» | POST обнулял базу; ошибка жила 2 дня, PHP локально не запускали ни разу |
| Расчёт себестоимости моделей | таблица сведена, итоги сходятся | 3 ошибки, в том числе доля считалась по количеству вместо стоимости |
| Правка шаблона страниц | целевая страница чинится | регрессия у соседних страниц из той же пачки |
Общее у всех четырёх — не невнимательность. Общее в том, что проверку выполнял тот же, кто делал работу, и проверка отвечала на вопрос «сделал ли я то, что задумал», а не «работает ли это».
Почему больше тестов не помогает
Естественная реакция на такой разбор — «напишем больше тестов». Она не работает, потому что новые тесты пишет тот же автор и с той же картиной мира в голове. Двадцать тестов из примера выше покрывали двадцать сценариев, которые автор считал важными; восемь багов сидели в тех, которые он важными не считал — иначе он бы их и обработал.
Второе наблюдение из батареи, менее очевидное: слабость не лечится выбором модели подороже. Мы ожидали, что провалы окажутся у дешёвых моделей, а флагманы их закроют. Вышло наоборот: почти все пробелы обнаружились именно у флагманских моделей — то есть это свойство класса инструментов, а не признак экономии на модели.
Следствие для планирования работы. Бюджет на проверку нельзя считать «сэкономленным» после перехода на модель посильнее. Стоимость внешней приёмки — постоянная часть сметы, как регулярный техосмотр: она не исчезает от того, что машины новые.
Что мы поставили вместо самоприёмки
- Проверяет не автор. Работу принимает другая модель или другой человек, и формулировка задания состязательная: «найди ошибку», а не «проверь, всё ли хорошо». Разница в формулировке даёт разный результат на одном и том же материале — это мы наблюдали неоднократно, включая расчёт себестоимости, где внешний проход снял три ошибки.
- Перепрогон именно той проверки, которая ловит дефект. Правка внесена — это ещё не починка. Починка — это когда та самая проверка, что была красной, стала зелёной. Отдельным пунктом: если правился общий шаблон, перепрогоняется вся затронутая пачка, а не одна страница.
- Живой прогон вместо чтения кода. Изменилось поведение — запускается сам сценарий: реальный запрос, реальная форма, реальный файл. Именно этого шага не хватило в случае, где обработчик обнулял базу.
- Обе ветки, а не удобная. Новый пользователь и вернувшийся, телефон и десктоп, пустой ввод и переполненный. Один из наших багов был виден только на новом пользователе, а тест гонял вернувшегося.
- Источник истины вместо пересказа. Вывод проверяется по коду, по живому сайту и по истории изменений — не по чьему-то отчёту о том, что там написано.
Как применить это у себя за один день
Ниже — минимальный вариант для команды, у которой нет ни батареи тестов, ни отдельного проверяющего.
- Разделите роли на уровне поручения. Один сотрудник делает задачу с ИИ, второй получает отдельное поручение — сломать результат. Второму не показывают, как первый рассуждал.
- Проверяйте то, что дорого, а не то, что удобно. Список «что здесь может обнулиться, уйти клиенту или попасть в отчётность» короче, чем список всех функций.
- Требуйте не вердикт, а пруф. «Проверил, всё работает» — не приёмка. Приёмка — это «вот запрос, вот ответ, вот строка в базе после него».
- Считайте числа отдельно. Модель формулирует метод, числа считает таблица или скрипт. Арифметика — самое частое место, где уверенный тон расходится с результатом.
Честная граница. Состязательная проверка не даёт гарантии — она снижает долю пропущенного. Про наш собственный контур мы говорим так же: часть проверок у нас закрыта машинными гейтами, часть — только правилом в документе, и это разные уровни надёжности. Правило, которое никто не читает, гарантией не работает.