The Daily Newsstand · Free, Always
Tuesday, September 15, 2026

Код пишет ИИ. Кто и как его проверяет?

Translate

Инструмент внедрили за неделю, а правила приёмки не написали вовсе. Это не преувеличение. За последний год картина в большинстве команд стала одинаковой: ИИ-ассистент стоит почти у каждого разработчика, его код ежедневно уходит в продукт, а общего стандарта «что считать принятым» у компании нет. Проверять успевают не всё, т.к. изменений стало в разы больше, а ревьюеров в лучшем случае осталось столько же. «Выглядит правдоподобно» подменяет «проверено». Ошибка, не пойманная на входе, возвращается переделкой через одну-две недели.

Скорость выросла у всех, а дисциплина почти ни у кого. Эта статья про то, почему обычное ревью и обычный SAST в эпоху vibe coding перестают быть достаточным контуром контроля, какой стандарт приёмки ИИ-кода мы считаем минимально рабочим и как устроена проверка, в которой модель, написавшая код, не является тем, кто его принимает. Мы разберём, что именно ломается в инженерном процессе, когда код пишет не человек, и какие слои контроля должны появиться до репозитория, в IDE, в pull request и в CI/CD.

Что происходит с кодовой базой, когда ассистент пишет быстрее, чем команда успевает думать

Проблема не в том, что ИИ пишет «плохой код». Проблема в том, что он пишет много правдоподобного кода, а правдоподобие точно плохой критерий приёмки.

GitClear в исследовании «The Maintainability Gap» разобрал 623 млн изменений кода за 2023–2026 годы и отследил восемь признаков качества. Картина неприятная и очень узнаваемая:

  • дублирование блоков кода +81%: одно и то же пишется заново вместо переиспользования;

  • конструкции, маскирующие ошибки +47%: сбой молча проглатывается вместо обработки;

  • копирование внутри одного изменения +41%: фрагмент размножен по файлам за один заход;

  • код, переписанный за первые две недели, вырос с 16% до 19% от всего нового кода +15%;

  • работа по наведению порядка в коде −70%: чинить некогда, все пишут новое.

Скорость выросла. Стоимость сопровождения растёт следом. Это уже не «технический долг в бэклоге», а измеримое изменение характера кодовой базы: больше копий, меньше обработки ошибок, меньше времени на «уборку».

Для AppSec-команд это имеет прямое следствие. Классические уязвимости, например, SQL через конкатенацию или SSRF через неконтролируемый URL, начинают тиражироваться не потому, что разработчик «не знает OWASP», а потому что модель предлагает статистически вероятный паттерн из обучающей выборки. Паттерн выглядит привычно, проходит unit-тесты и уходит в ветку.

Если раньше команда писала тысячу строк в неделю, а теперь с помощью ИИ стала писать пять тысяч. Поверхность атаки растёт пропорционально скорости генерации. Контроль, который остался прежним, становится узким местом не в теории, а в арифметике.

Дальше не будет манифеста «ИИ плохой» и обзора рынка... Мы хотим честно ответить на вопрос, который нам самим пришлось решать: если код пишет не человек, кто и по каким правилам его проверяет, чтобы это не превратилось ни в театр ревью, ни в кладбище ложных срабатываний.

Где реально теряются недели

Задачу описали ИИ-ассистенту словами и через пять минут есть код. Смотреть 400 строк долго. Ушло в ветку или вообще сразу в релиз. Через неделю на стенде или в проде: сделано не то. Или то, но без проверки владельца объекта. Дальше второй заход. Токены списали дважды. Время ушло трижды: написать, понять, что написали, переписать. Плюс 1-2 недели к сроку.

С точки зрения ИБ «сделано не то» часто оказывается не багом UI, а дырой в доступе. Endpoint живой, юнит-тесты зелёные, авторизация «как все пишут»: достали объект по id из URL. Классический SAST видит плохо, юнит-тест тоже молчит, т.к. ходит под тем же пользователем, под которым писали фичу. Именно поэтому разговор «давайте просто включим ещё один сканер» не дает нужного результата. Сканер не виноват. Виновата дыра между генерацией и приёмкой.

Почему нельзя попросить ту же модель проверить то, что она написала

Идея «пусть ИИ-ассистент сам сделает ревью» выглядит логично, пока не посмотришь, как ИИ-модели ошибаются.

Есть исследование 2026 года: тысяча изменений, полторы тысячи подтверждённых ошибок высокой критичности. Две модели проверяли свой код и чужой. Первый ИИ-ассистент проверил свой код и нашел 53,7% уязвимостей, проверили «чужой» моделью этот же код и получили 60%. Вторая ИИ-модель показала примерно такие же результаты: 50,5% найденных в своем коде и 62% при поиске другой моделью. Разрыв в качестве проверки составляет 8–10 процентных пунктов. Просить ассистента проверить свой же код – это самопроверка контрольной. Типы дыр, которые модель чаще вносит, она же чаще пропускает. Это не мистика. Она смотрит на код тем же статистическим вкусом, которым его собирала. Свой дефолт ей кажется нормальным.

У людей та же болезнь. Поэтому MR от автора без второго взгляда давно считается плохой практикой. С моделью почему-то многие решили, что вторые глаза не нужны.

Вторая проблема ещё злее, и она не про diff. Кусок инженерии теперь происходит до репозитория. В модель улетают соседние файлы, .env, кусок лога, stack trace, контракт API, иногда тикет с внутренними хостами. Потом из этого всего рождается патч, его чуть правят и пушат. Формально у вас есть review и SAST, но фактически часть решений принята там, куда AppSec не смотрит.

Возникают вопросы, на которые без отдельного контура нельзя ответить честно:

  • какие данные ушли в модель;

  • были ли среди них секреты, персональные данные, внутренние алгоритмы;

  • какой фрагмент написал человек, а какой модель;

  • не предложила ли модель зависимость с известным CVE или пакет-омоним;

  • не появился ли класс уязвимости, который старые правила не покрывают.

Контроль должен сместиться не только влево (Shift Left), но и выше по цепочке – к моменту взаимодействия с ИИ.

Стандарт приёмки ИИ-кода

Мы собрали минимальный набор, который закрывает то, что ассистент повторяет из раза в раз. Это не вкусовщина. Это наблюдаемые классы дефектов.

Контекст и правила

1. Файл инструкций для ассистента существует, заполнен по делу и не устарел вместе с проектом.

2. В нём нет секретов, внутренних адресов и боевых доступов, иначе всё это уходит в модель.

3. Новый код не нарушает конвенции, записанные в этом файле.

Гигиена сгенерированного кода

4. Нет следов генерации: заглушки, пояснения модели, «вставьте сюда свой ключ».

5. Все подключённые библиотеки существуют и объявлены – защита от выдуманных имён и supply-chain подмены.

6. Проверки не отключены пачкой ради того, чтобы код «прошёл».

7. Нет дублирования: блок скопирован вместо переиспользования.

8. Ошибки обрабатываются, а не проглатываются молча.

Соответствие задаче

9. Изменение делает ровно то, что просили: не меньше и не больше.

10. Один и тот же файл не переписывается по кругу, т.к. это признак того, что агент потерялся.

Безопасность

11. Классика на сгенерированном коде: инъекции, XSS, секреты, права доступа.

12. Нарушения, видные только в связке файлов: три библиотеки на одну задачу, обход общего слоя авторизации.

Процесс

13. Проверяет не та модель, которая писала.

14. Критичное подтверждено доказательством, а не мнением модели.

Четырнадцать пунктов – это и есть стандарт приёмки. Его можно превратить в автоматическую проверку на каждом изменении и тогда он начнет работать. Иначе снова стандарт по памяти: вспомнили – применили, не вспомнили – ну и ладно.

Правила компании как код проверки, а не как документ

Идея простая: стандарты компании становятся проверкой на каждом изменении.

Правила пишутся обычным текстом, без отдельного языка политик. Их заводит архитектор или руководитель ИБ. Набор хранится рядом с кодом, в самом репозитории, и живёт вместе с проектом. За каждым правилом закреплён класс проблемы – модель его не выдумывает. Порог важности и блокировка слияния настраиваются отдельно по проекту. Проверка не зависит от того, кто сегодня дежурный и в каком он настроении.

Правило написали один раз, и оно применяется на каждом изменении. Это важный сдвиг относительно классического AppSec. Классический контур отвечает на вопрос «есть ли тут конструкция из базы CWE». Контур приёмки ИИ-кода отвечает ещё и на вопросы, которых у CWE нет: устарел ли файл инструкций, ушла ли в модель боевая строка подключения, не заглушил ли ассистент линтер пачкой # noqa, не предложил ли пакет, которого нет ни в одном реестре.

Без этого слоя компания получает парадокс: безопасность «есть» (SAST в пайплайне зелёный или красный по сотне неподтверждённых алертов), а стандарт разработки с ИИ – отсутствует.

Два режима и три прохода: один файл не покажет, что в проекте нет единого подхода

Проверка, которая пытается быть и быстрой, и полной, обычно не является ни тем, ни другим. Поэтому режимов два.

Быстрый – в темпе разработки. Смотрит только то, что изменилось с прошлой проверки. Успевает за сборкой и работает как ворота: не пускает дальше то, что нарушает стандарт.

Глубокий – для приёмки и аудита. Разбирает весь репозиторий целиком. Нужен для приёмки работ подрядчика, разбора унаследованного кода, регулярного аудита. Запускается по расписанию или по требованию.

В обоих режимах важен разбор в связке файлов. Часть проблем не видна, пока смотришь на один файл.

Практически получаем три прохода вместо одного взгляда:

  • Описание каждого файла. По файлу собирается короткая карточка: что подключено, как проверяется ввод, где логика работы. Без этой карточки следующее правило применяется вслепую.

  • Каждое правило – по своим файлам. Правило применяется не ко всему подряд, а к тем файлам, которых оно реально касается. Иначе шум убивает проверку за неделю.

  • Связи между файлами. Три разные библиотеки для одной задачи, расчёт цены на стороне браузера, самописная проверка пароля – в одном файле такое не заметно. Класс уязвимости при этом закреплён за правилом, а не угадывается моделью.

Отдельный файл не покажет, что в проекте нет единого подхода. А именно это является типичным следом vibe coding: каждый диалог с моделью решает локальную задачу, и через месяц в репозитории оказывается четыре способа авторизации.

Проверяет не тот, кто писал. Доказывает не тот, кто «считает»

Два принципа, без которых автоматическое ревью ИИ-кода превращается в ещё один генератор мнений.

Первый. Автор изменения и проверяющий – разные контуры. Платформа определяет автора по истории изменений: след в сообщении коммита, префикс ветки, метаданные запроса на слияние. Проверку получает другая модель. Если автора определить нельзя, проверка всё равно идёт и это отображается в журнале. Внешние вызовы для этого не требуются: обе модели могут стоять на вашем сервере.

Второй. Находка ревью не остаётся один на один со своим суждением. Она уходит в движки, которые могут воспроизвести проблему, а не просто согласиться с формулировкой.

На входе: правило, файл, строка и класс проблемы. Дальше попытка подтвердить: фаззинг по найденной точке, проверка работающего приложения, разбор кода и цепочки вызовов, зависимости и секреты.

На выходе: три разных состояния, которые нельзя смешивать.

  • Доказано. Проблема воспроизведена: есть падение, ответ от приложения или восстановленная цепочка от ввода до опасного вызова. Это останавливает выпуск.

  • Не подтверждено. Проверка была, доказательства нет. Находка остаётся в списке со своим статусом, при этом её не удаляют и не прячут. Выпуск не блокирует.

  • Доказывать нечем. Правило про стиль, архитектуру или дисциплину контекста. Воспроизвести тут нечего и платформа честно это говорит. Замечание без доказательства.

«Кажется небезопасно» и «вот воспроизведение» – это разные основания для блокировки. Если pipeline падает на каждое неподтверждённое предупреждение, разработчики начинают обходить контроль. Если падает только на доказанном High/Critical, блокировка воспринимается как инженерный факт, а не как каприз сканера.

Этот слой опирается на единый контур, а не на набор разрозненных отчётов: SAST, SCA, Secrets, DAST, AI-пентест в песочнице, Code Fuzzing и API Fuzzing. Нормализация и дедупликация сводят семь списков в один реестр. Достижимость по графу вызовов отвечает на вопрос эксперта: дойдёт ли до этой строки реальный пользовательский ввод. Короткий прицельный фаззинг по конкретной SAST-находке (файл, строка, CWE) даёт crash-proof либо честный статус «не подтверждено». API Fuzzing на OpenAPI / GraphQL schema / .proto / AsyncAPI закрывает то, чего нет в стеке процесса: роли, лишние поля, mass assignment, JWT bypass.

Подробно механику моста «SAST → фаззинг» и слои фильтрации ложных срабатываний мы уже разбирали отдельно в статье на HABR. Здесь достаточно принципа: мнение модели не является Quality Gate.

Проверка приходит к разработчику, а не разработчик к проверке

Контур, который требует «зайди в отдельное окно сканера», в темпе vibe coding не живёт. Разработчик генерирует быстрее, чем готов переключать контекст.

Поэтому проверка стоит в трёх точках, которые и так есть в дне инженера.

  • Редактор. Во время написания кода нарушение подсвечивается прямо на строке. Рядом выдает объяснение и готовое исправление. Разработчик видит сразу всё еще до коммита.

  • Запрос на слияние. Комментарии на проблемных строках. Повторный прогон обновляет их, а не плодит новые.

  • Сборка. Ворота по порогу важности. Не пускают дальше то, что нарушает стандарт. Порог настраивается по проекту.

В продукт уходит то, что прошло все три точки. Модели рекомендуем разворачивать на вашем сервере. И та, что проверяет, и та, что предлагает исправление. Исходный код наружу не выходит, находки лежат в общем списке вместе с остальными, а не в отдельном «окне для ИИ».

Отдельного шага «сходить и прогнать сканер» в процессе не появляется. Это не мелочь. Любой дополнительный ритуал в условиях кратно выросшего потока изменений просто не выполняется.

Три продукта и один контур. Разрыв между этапами – это место, где теряются месяцы

Проверка кода после генерации недостаточна, если не контролируется то, что происходит до неё и во время работы ИИ-ассистента.

До генерации стоит шлюз. Все запросы разработчика должны проходить через фильтр: ключи, токены, пароли и исходники «снимаются» с запроса до отправки. Дальше оценивается сложность задачи. Простое (переименовать, дописать тест, объяснить кусок, поправить формат) уходит на дешёвую модель. Сложное (проектирование, разбор незнакомого кода, работа с несколькими файлами) – на сильную. Бюджет на ИИ токены задаётся заранее на команду и на человека, а не «пришёл счёт в конце месяца». Видна стоимость конкретной задачи. Журнал обращений – кто, когда, о чём и по какой цене.

Во время работы агента нужен другой контроль. Агент работает часами и не всегда над тем, о чём его просили. Имеет смысл ловить «потерявшихся»: работа идёт, а продвижения к цели нет. Имеет смысл ловить зацикливание, когда один и тот же файл переписывается по кругу. Сверять сделанное с исходной задачей: уход в сторону виден сразу, а не через неделю. Ограничивать полномочия. Необратимое действие типа удаление, запись в базу, отправка наружу должно требовать согласия человека (HITL).

Остановить агента на десятой минуте дешевле, чем разбирать результат через неделю. После генерации необходима проверка кода по стандарту компании, подтверждение найденного доказательством, ворота перед слиянием и релизом.

В нашей линейке это три связанных контура: INFERA AI.Firewall на входе в модель, INFERA AI.SafeAgent на поведении агента, INFERA AI.SafeCode на коде и пайплайне. Периметр один: ваши модели, ваш код не выходит наружу. Инцидент, который случился однажды, становится правилом проверки. Один журнал на все три контура.

Разрыв между этапами – это место, где теряются месяцы. Пока шлюз, агент и ревью живут в разных системах, каждая из них честно делает свою работу и честно не видит соседнюю.

Долг, который накапливает ИИ, должен стать числом

Ощущение «код стал хуже» бесполезно для управления. Его нужно превратить в цифру и в тренд.

Имеет смысл считать отдельно то, что ассистент делает системно:

  • дублирование: сколько блоков написано заново вместо переиспользования;

  • замаскированные ошибки: где сбой проглатывается молча;

  • отключённые проверки: где линтеры и типы заглушены ради прохождения сборки;

  • выдуманные зависимости: библиотеки, которых нет ни в одном хранилище пакетов;

  • переписывание по кругу: какие файлы правились больше трёх раз за спринт.

Всё это – одна цифра по проекту и её изменение от месяца к месяцу. Нельзя управлять тем, что никто не измеряет. AppSec привык считать открытые Critical/High, MTTR и нарушения SLA. Рядом должен появиться ещё один слой: не только «какие CWE открыты», но и «насколько кодовая база деградирует под ИИ».

Иначе CISO видит зелёный (или вечно красный) security-дашборд, а CTO через полгода обнаруживает, что сопровождение подорожало на те самые проценты из GitClear – без единого «инцидента».

Что это даёт каждой стороне

Разработчику и тимлиду. Проблема видна в редакторе, а не в комментарии через три дня. Рядом объяснение и готовое исправление. Ревью перестаёт быть очередью и формальностью. Меньше бессмысленных замечаний и тогда к проверке возвращается доверие.

Руководителю разработки и CISO. Стандарт компании применяется на каждом изменении, а не когда вспомнят. Расходы на ИИ управляемы: бюджет, маршруты, стоимость задачи. Переделки видны цифрой и сокращаются. Код от ассистента проходит те же ворота, что и код человека. Есть единая картина риска по коду, API, компонентам и зависимостям, а не семь несвязанных отчётов.

Для контуров, где внешняя модель недопустима – объекты КИИ, банки, промышленность, госсектор – это ещё и вопрос режима обработки информации. Отправка кода и конфигураций во внешний LLM может быть не только техническим риском, но и нарушением 152-ФЗ, коммерческой тайны и требований к значимым объектам.

Запрещать ИИ уже поздно, а оставлять его без контроля очень дорого

Команды всё равно будут использовать ИИ-ассистентов: официально или нет. Компании, которые попытаются просто запретить ИИ, скорее всего получат теневое использование без какого-либо контроля (Shadow AI). Компании, которые встроят ИИ в управляемый контур, сохранят скорость и не потеряют возможность ответить на простые вопросы: что ушло в модель, кто принял решение, подтверждена ли находка, почему пайплайн упал.

Минимальная рабочая модель сегодня выглядит так:

  • все обращения к LLM проходят через контролируемый шлюз;

  • агент работает под контролем и в ограниченных полномочиях, останавливается, когда теряет цель;

  • ИИ-сгенерированный код проверяется не той моделью, которая его писала;

  • стандарт компании применяется на каждом изменении, а не живёт в вики;

  • Quality Gate срабатывает по доказанным рискам, а не по списку подозрений;

  • действия людей, моделей и ИИ-агентов остаются в одном журнале.

ИИ ускоряет разработку. Это правда. Правда и в том, что без приёмки часть этого ускорения уходит во второй круг, который никто не считает инцидентом.

View the original on Хабр

KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.