Код пишет ИИ. Кто и как его проверяет?
Инструмент внедрили за неделю, а правила приёмки не сформулировали вовсе. Для многих команд это уже не исключение, а привычный сценарий: ИИ-ассистент есть практически у каждого разработчика, сгенерированный код ежедневно попадает в продукт, но единого ответа на вопрос "что считать готовым" по-прежнему нет.
Изменений стало заметно больше, а количество ревьюеров почти не изменилось. В результате проверяют далеко не всё, а фраза "выглядит правдоподобно" постепенно подменяет понятие "прошло контроль". Ошибка, которую не заметили на входе, возвращается спустя неделю или две в виде переделки, инцидента или срочного исправления.
Проблема не в том, что искусственный интеллект обязательно создаёт плохой код. Опасность в другом: он способен быстро генерировать большие объёмы убедительного, но не всегда корректного решения. А правдоподобие - слишком слабый критерий для приёмки.
Почему обычного ревью уже недостаточно
Когда задачу описывают ассистенту словами, первые сотни строк могут появиться за несколько минут. Однако быстро написать - не значит быстро проверить. Разработчику нужно понять архитектурные решения, проверить граничные случаи, сопоставить результат с бизнес-логикой и убедиться, что изменения не нарушили существующие ограничения.
На практике этот этап часто сокращают. Код отправляют в ветку, а иногда и сразу в релиз. Через несколько дней выясняется, что функция реализована не так, как ожидалось, или работает только в типовом сценарии. Начинается второй цикл: повторная генерация, дополнительное ревью, исправление тестов и ручная проверка.
Время расходуется трижды: сначала на написание, затем на разбор результата и наконец на переписывание. Формально ИИ ускоряет разработку, но без нового процесса контроля общая продолжительность задачи может даже увеличиться.
Особенно опасны ошибки, которые внешне выглядят как обычный функциональный дефект, но на деле связаны с безопасностью. Например, endpoint получает идентификатор объекта из URL и возвращает данные без проверки принадлежности текущему пользователю. Юнит-тесты при этом могут проходить: запрос выполняется под тем же пользователем, который создавал сценарий, и проблема с горизонтальным повышением привилегий не проявляется.
Классический SAST также не всегда обнаруживает такую уязвимость. Он видит отдельные конструкции, но не понимает бизнес-контекст и связи между маршрутом, объектом и политикой доступа. Поэтому простое добавление ещё одного сканера не устраняет разрыв между генерацией и приёмкой.
Что происходит с качеством кодовой базы
Исследование GitClear "The Maintainability Gap", в котором анализировались 623 млн изменений за 2023-2026 годы, зафиксировало сразу несколько тревожных тенденций:
- дублирование фрагментов выросло на 81%;
- конструкции, скрывающие ошибки, стали встречаться на 47% чаще;
- копирование кода внутри одного изменения увеличилось на 41%;
- доля нового кода, переписанного в первые две недели, поднялась с 16 до 19%;
- объём работ по улучшению и упорядочиванию существующего кода сократился на 70%.
Эти показатели характеризуют не отдельные неудачные ответы модели, а изменение поведения команд. Разработчики получают возможность создавать больше функций, но всё реже тратят время на повторное использование компонентов, устранение дублирования и обработку исключительных ситуаций.
Так формируется новый вид технического долга. Он возникает не только из-за устаревших решений, но и из-за массового производства похожих фрагментов, скрытого подавления ошибок и недостаточной проверки контекста.
Для AppSec последствия очевидны. Уязвимые шаблоны могут масштабироваться вместе с объёмом генерации. SQL-инъекция через конкатенацию строк, SSRF с неконтролируемым URL или отсутствие проверки доступа способны повторяться в нескольких сервисах, потому что модель воспроизводит распространённый, но небезопасный паттерн.
Если раньше команда создавала тысячу строк в неделю, а после внедрения ИИ - пять тысяч, поверхность атаки потенциально увеличивается в пять раз. При неизменном количестве ревьюеров, тестов и проверок именно контроль становится главным ограничением.
Почему нельзя поручать финальную проверку той же модели
На первый взгляд логично попросить ассистента проверить собственный результат. Такой подход действительно способен найти опечатки, очевидные нарушения стиля и часть простых ошибок. Но полагаться на него как на независимый контроль нельзя.
Модель не обладает настоящей ответственностью за решение и часто сохраняет исходные предположения. Если в запросе не была указана проверка прав доступа, ассистент может не заметить, что именно это является главным риском. Более того, он склонен считать собственную архитектуру приемлемой, если она выглядит согласованной с контекстом запроса.
Это не означает, что ИИ нельзя использовать для ревью. Его следует применять как один из инструментов: для поиска подозрительных мест, составления списка сценариев, анализа изменений и подготовки вопросов автору. Но окончательное решение должно приниматься независимым контуром, который проверяет не только синтаксис, но и требования продукта.
Минимальный стандарт приёмки ИИ-кода
Правила для такого кода должны быть оформлены не как декларация, а как исполняемый набор проверок. Минимальный стандарт может включать несколько обязательных условий:
1. Понятное происхождение изменений. Должно быть ясно, какие участки созданы или существенно изменены с помощью ИИ.
2. Связь с задачей. Каждое изменение должно соответствовать конкретному требованию, а не просто выглядеть логичным.
3. Проверка границ доступа. Для endpoint, фоновых задач и операций с данными необходимо тестировать сценарии чужого пользователя, просроченной сессии и недостаточных прав.
4. Негативные сценарии. Нужно проверять не только успешное выполнение, но и неверные входные данные, тайм-ауты, отсутствие объекта, повторные запросы и частичные сбои.
5. Отсутствие опасных шаблонов. Сюда относятся небезопасная работа с SQL, динамическими URL, секретами, файлами и сериализацией.
6. Контроль дублирования. Новая реализация не должна копировать уже существующую без обоснования.
7. Владение изменением. У кода должен быть человек, который способен объяснить его устройство и последствия.
Такие требования лучше превращать в автоматические политики. Если правило важно, оно должно проверяться в IDE, pre-commit, pull request или CI/CD, а не оставаться рекомендацией в корпоративном документе.
Два режима и три прохода
Единого способа проверки для всех изменений быть не может. Для небольшого исправления в пользовательском интерфейсе достаточно одного набора проверок, а для изменения авторизации, платежей или схемы данных нужен значительно более строгий режим.
Практично разделить процесс на два режима.
Обычный режим подходит для низкорисковых изменений. Он включает автоматические тесты, статический анализ, проверку зависимостей, обзор diff и подтверждение владельца компонента.
Усиленный режим требуется для кода, который работает с персональными данными, правами доступа, внешними интеграциями, финансовыми операциями и критичной инфраструктурой. Здесь необходимы негативные тесты, анализ потоков данных, проверка угроз, независимое ревью и подтверждение специалиста по безопасности.
Сама проверка может проходить в три этапа.
Первый - автоматический: форматирование, линтеры, типизация, тесты, SAST, анализ секретов и зависимостей.
Второй - смысловой: сопоставление реализации с задачей, оценка архитектуры, проверка обработчиков ошибок и граничных сценариев.
Третий - независимый: другой человек или отдельный контрольный агент оценивает изменение с позиции пользователя, злоумышленника и владельца системы.
Один файл не показывает, что в проекте отсутствует единый подход. Поэтому анализировать нужно не только diff, но и связанные маршруты, модели данных, политики доступа, конфигурацию и историю похожих исправлений.
Проверяет не тот, кто писал
Ключевой принцип - автор генерации не должен быть единственным человеком, принимающим результат. Это не вопрос недоверия к разработчику. Независимый взгляд нужен потому, что создатель решения неизбежно привязан к первоначальным допущениям.
При этом ревью не должно превращаться в ручную очередь. Проверка должна приходить к разработчику автоматически: система определяет риск, назначает нужный сценарий контроля и показывает конкретные причины блокировки. Если изменение затрагивает права доступа, CI должен сам включить соответствующие тесты и запросить подтверждение владельца.
Так ревью становится частью потока разработки, а не отдельной процедурой, которую вспоминают перед релизом.
Три продукта и единый контур контроля
В зрелом процессе обычно взаимодействуют три класса инструментов:
- ассистент в IDE, который помогает писать и объяснять код;
- система анализа изменений и pull request, оценивающая смысл и риск;
- CI/CD-контур, принимающий финальное решение о выпуске.
Главная проблема возникает, когда эти инструменты не связаны между собой. Ассистент генерирует код, ревью проверяет только оформление, а CI запускает общий набор тестов. В итоге ни один этап не видит полной картины.
Контроль должен быть сквозным. Информация о риске изменения передаётся между этапами, а важные требования проверяются повторно на разных уровнях. Если проверка зависит только от человеческого внимания, она неизбежно будет пропущена при высокой нагрузке.
Технический долг необходимо измерять
Фраза "ИИ увеличивает технический долг" слишком общая, если за ней нет показателей. Команде нужно отслеживать конкретные признаки:
- сколько изменений переписывается вскоре после релиза;
- как часто повторяются одинаковые фрагменты;
- сколько ошибок подавляется без обработки;
- сколько дефектов обнаруживается после приёмки;
- сколько времени уходит на устранение последствий;
- какая доля изменений касается критичных компонентов;
- сколько исключений из правил накоплено в проекте.
Полезно считать не только количество найденных проблем, но и стоимость их исправления. Если дефект обнаружен до слияния, это одна цена. Если он найден после релиза, цена включает откат, расследование, поддержку пользователей и возможный ущерб безопасности.
Что делать команде уже сейчас
Запрещать ИИ в разработке поздно и, скорее всего, бессмысленно. Но оставлять его без контроля дорого. Начинать стоит не с покупки нового инструмента, а с ревизии процесса.
Сначала нужно определить категории риска и критичные участки системы. Затем - описать обязательные критерии приёмки для каждой категории, встроить автоматические проверки и назначить владельцев правил. После этого следует собрать статистику: какие проблемы чаще всего пропускаются, где возникают повторные переделки и какие проверки дают слишком много ложных срабатываний.
Важно также обучить разработчиков не только формулировать запросы к модели, но и проверять её предположения. Хороший результат начинается с точного контекста: ограничений архитектуры, требований безопасности, формата ошибок и ожидаемых сценариев.
ИИ способен резко увеличить производительность команды, но только при условии, что скорость генерации сопровождается такой же зрелостью контроля. В противном случае компания получает не ускорение разработки, а ускоренное накопление ошибок, дубликатов и уязвимостей. Код может писать модель, однако ответственность за его проверку, эксплуатацию и последствия всё равно остаётся на людях.
