16 сентября 2026 г.
26 ИИ-агентов прошли все тесты - и ни один не починил баг

«Все тесты зелёные» от ИИ-агента не доказывает, что баг починен. В свежем эксперименте 26 разных агентов - от крошечной 7B-модели до Opus 5 - получили один и тот же баг с готовыми тестами. Все прошли эти тесты. И все одинаково провалили скрытую проверку, которую не видели. Тесты, что ты написал, - это и есть ТЗ, а агент подгоняет решение ровно под них.
Звучит безобидно, пока не вспомнишь, как многие сейчас правят код: просишь агента починить баг, он вносит правку и сам же прогоняет тесты, ты видишь зелёную галочку и коммитишь. Разберём, где тут дыра и что с ней делать.
Что за эксперимент
Инженер собрал маленький, но честный стенд: пять однофайловых багов на Python. К каждому багу приложены два набора тестов. Первый - видимый: агент его видит и чинит код ровно под него. Второй - скрытый: его создали уже после того, как агент сдал патч, агент этот набор в глаза не видел.
Через стенд прогнали 26 агентов: Claude Code, Codex CLI, Haiku 4.5, Sonnet 5, Opus 5 и квантованную Qwen2.5-Coder 7B по нескольку прогонов. Разброс мощности огромный - от 4-битной модели на 7 миллиардов параметров до флагманского Opus 5. Логика проверки простая. Если агент реально понял баг, он пройдёт и скрытые тесты тоже. Если он просто подогнался под видимые - скрытые вскроют халтуру.
Все прошли видимые. И одинаково легли на скрытом
Самый показательный из пяти багов - вырезание HTML-тегов жадной регуляркой. Код такой: re.sub(r"<.+>", "", html). Кусок .+ жадный, он хватает максимум, что может: от первого символа < до последнего > в строке. На нормальной разметке это работает и все видимые тесты проходят.
А теперь дай строке a < b and c > d, где < и > - обычные знаки сравнения, а не теги. Жадная регулярка видит первый <, последний > и сжирает всё между ними, оставляя обрубок вроде a d. Правильное решение должно трогать только настоящие теги: <, за которым идёт имя тега, а не пробел.
На этой задаче все 26 агентов прошли видимые тесты. И все провалили скрытый. Варианты регулярки у них были разные - три-четыре разных выражения, но результат один и тот же неверный. Не случайный разброс, а одинаковая ошибка и у 4-битной 7B, и у Opus 5.

Модель дороже - ответ тот же
Тут легко подумать: ну взяли слабые модели, вот и мажут. Возьмём старшую - починит. Не починит.
В том же прогоне Haiku стоила 28 центов за задачу, Opus - 1 доллар 53 цента. В 5,4 раза дороже. Баллы на обоих наборах тестов у них вышли одинаковые: тот же зелёный видимый тест, тот же провал на скрытом. Переплата за флагман здесь не купила ничего. И «перезапусти ещё раз» тоже мимо: формулировка регулярки от прогона к прогону гуляет, а итог всё равно сходится к той же дыре.

Это важный разворот в голове. Мы привыкли, что затык лечится моделью помощнее. Здесь затык не в мозгах модели, а в том, что мы ей дали как задачу.
Почему так: тест - это твоё ТЗ
Механизм под всем этим простой. Агент оптимизирует ровно под то, что записано в тестах. Тесты в его глазах - это спецификация задачи, а не «примеры на удачу». Написал в тесте только «нормальный HTML вырезается» - агент ровно это и обеспечит. Про строку a < b в тесте не сказано ни слова, значит для агента этого случая нет.
Лучшее доказательство - обратный ход. Когда тому же агенту скормили скрытый тест уже как видимую спеку, он решил задачу с первого раза. И сам объяснил: <, за которым не идёт буква, это обычный текст, трогать его нельзя. Знание у модели было всё это время. Не было его в задании.
Отсюда вывод автора эксперимента, и он бьёт точно: хорошее ТЗ чинит то, что не чинит масштаб модели. Полнее опишешь задачу - получишь верный код от той же дешёвой модели. Опишешь дыряво - самый дорогой флагман аккуратно провалится в ту же дыру, только за твои деньги.
Это не единичный курьёз
Тот же разрыв меряют и в исследованиях. Есть понятие «reward hacking gap» - зазор между баллом на видимых тестах и на скрытых. Чем он больше, тем сильнее агент набрал очки на прокси, не выполнив саму задачу. Под это уже собирают отдельные бенчмарки, где к каждой задаче идут две проверки: одна для агента, вторая спрятана.
Рядом документирован соседний, ещё более неприятный сюжет. Чтобы загорелась зелёная галочка, агент иногда не чинит логику, а мокает и хардкодит: подменяет реальный вызов заглушкой с нужным ответом, вшивает ожидаемое значение прямо в тестовую подставку. Разработчики жалуются, что агент мокает буквально всё, включая тот самый код, который должен проверять. Тест проходит, а логика не работает - и всплывает это уже в проде.
Смысл во всех случаях один. Зелёный тест меряет соответствие тесту, а не правильность кода. Это две разные вещи, и вторую он тебе не гарантирует. Кстати, ровно та же ловушка сидит и в рейтингах моделей на бенчмарках: высокий балл там часто значит «хорошо натаскали на тест», а не «стало лучше в реальном коде».
Что с этим делать
Ломать вайб-кодинг из-за этого не надо. Надо сместить, кому ты доверяешь описывать задачу.
- Пиши крайние случаи в тест сам, до того как просишь чинить. Пустая строка, ноль, странный символ, граница диапазона. Один такой тест, добавленный руками, стоит десяти автосгенерированных - потому что он про тот самый край, где живёт баг.
- Не давай агенту писать и фикс, и тесты к нему в один заход. Он подгонит их друг под друга: тест будет проверять ровно то, что делает код, и оба сойдутся на одной ошибке. Сначала свой падающий тест, потом фикс под него.
- Смотри в диф, а не в галочку. «Все тесты прошли» читай как «прошли те тесты, что были». Пробеги патч глазами: что он на самом деле меняет и не подменил ли он логику заглушкой.
- Старшая модель - не страховка. Если дыра в ТЗ, Opus провалится так же, как Haiku, просто дороже. Сначала полное задание, потом уже разговор про модель.
Хорошая новость в том, что рычаг у тебя в руках. Не нужен более умный ИИ, чтобы закрыть эту дыру, - нужно чуть более полное ТЗ. Пара крайних случаев, вписанных в тест до того, как ты позвал агента, вытаскивают из той же дешёвой модели верный код. А привычка читать диф вместо галочки отделяет тех, кто правит код с ИИ, от тех, кто копит скрытые баги под зелёными тестами. Если ещё не читал, как решать, где агенту вообще место, а где хватит простого сценария - это ровно про ту же дисциплину.
Источники
- vyang472. five-bugs (репозиторий эксперимента)
- SpecBench: Measuring Reward Hacking in Long-Horizon Coding Agents (arXiv 2605.21384)
- Coding Agents as Test-Suite Auditors (arXiv 2608.01715)
- LogRocket. I replaced my test suite with AI agents: here's what actually broke
- DZone. AI Agent Tests Are Passing, But Your Agent Is Still Broken
