Как проверить код, написанный AI: методы верификации, тестирования и аудита безопасности
Я работаю над проектом, где примерно 40% кода сгенерировано нейросетью.
Не потому что мы ленивые. Просто это быстрее.
Но недавно мы нашли баг, который сидел в продакшене три недели. AI написал идеальный с первого взгляда код обработки заказов. Проходил все тесты. Работал на тестовых данных. На реальных - тоже работал. Почти.
Ошибка проявлялась только при одном условии: если у пользователя было больше трёх промокодов и скидка совпадала с днём рождения.
Три недели.
Никто не заметил. Ни статический анализатор, ни unit-тесты, ни даже code review, потому что код выглядел как работа опытного инженера.
Именно в этом главная опасность современного AI-кода.
Он не выглядит подозрительным.
Раньше, когда я только начинал работать с AI-ассистентами, ошибки были очевидными. Нейросеть могла вызвать несуществующий метод или перепутать типы. Это было заметно сразу.
Сейчас модели стали умнее. Они генерируют синтаксически идеальный код. Он проходит линтеры, компилируется, даже unit-тесты проходят.
Но внутри - скрытые проблемы.
Бизнес-логика, нарушенная незаметно. Производительность, которая падает только под нагрузкой. Дыры в безопасности, которые не видны на первый взгляд.
И самое неприятное: чем лучше код выглядит, тем сложнее найти эти ошибки.
Я веду внутреннюю памятку по проверке AI-кода уже больше года. Туда попадают проблемы, которые мы реально находили в продакшене. Не теоретические, а те, которые горели.
Вот что встречается чаще всего.
Бизнес-логика.
AI генерирует технически корректное решение, которое нарушает реальные правила системы.
Например, мы нашли функцию расчёта доставки. Она работала идеально, пока мы не заметили, что при сумме корзины больше 10 тысяч рублей она почему-то считала доставку платной, хотя в правилах компании - бесплатной.
Ошибка была в логике. AI просто не знал этого правила.
Статический анализ такую ошибку не найдёт.
Производительность.
У нас был сервис, который AI переписал с использованием циклов вместо batch-запросов. На тестовой базе с сотней записей - летал. Когда база выросла до десяти тысяч - начал тормозить. На ста тысячах - упал.
Мы не сразу поняли, в чём дело. Код выглядел корректным. Просто алгоритм оказался с квадратичной сложностью.
AI не думает о масштабе. Он решает задачу на том объёме данных, который видит в тесте.
Безопасность.
Классика.
Я сам видел, как AI сгенерировал такой код:
//python
query = f"SELECT * FROM users WHERE id = '{user_id}'"
cursor.execute(query)Выглядит невинно. Проходит все проверки. До тех пор, пока кто-нибудь не подставит в user_id специально сформированную строку.
Я переписал на параметризованный запрос:
//python
cursor.execute(
"SELECT * FROM users WHERE id = %s",
(user_id,)
)Разница в одной строчке. Цена ошибки - вся база данных.
И таких примеров у меня десятки. SQL-инъекции, ошибки авторизации, неправильная обработка файлов, небезопасная работа с пользовательским вводом.
AI учится на старом коде. А старый код полон дыр.
Я перепробовал много методов проверки за последний год.
Вот что реально работает.
Статический анализ - первый этап.
Он ловит технические дефекты: типизацию, утечки памяти, небезопасные конструкции. Это хороший фильтр.
Но он не видит бизнес-логику. Он не знает, что доставка должна быть бесплатной от 10 тысяч.
Так что статический анализ - это только начало.
Code Review - не для галочки.
Я перестал доверять поверхностным проверкам. Сейчас мы на каждом ревью задаём вопросы не только про код, но и про логику.
Почему выбран этот алгоритм? Что будет, если данных станет в десять раз больше? Как поведёт себя система при нестандартном сценарии?
Именно во время таких вопросов чаще всего всплывают проблемы AI-кода.
Тесты - и не только unit.
Это моя главная ошибка в начале. Я доверял unit-тестам. Они проходили - значит, всё работает.
Потом я понял, что большинство проблем проявляется на уровне взаимодействия компонентов.
Теперь мы добавляем интеграционные тесты, нагрузочные испытания и обязательно проверяем граничные условия. Те самые, которые AI обычно игнорирует.
Аудит безопасности отдельно.
Я перестал считать, что проверка безопасности - это часть code review. Это отдельный этап.
У нас есть чек-лист: SQL-инъекции, XSS, ошибки авторизации, работа с файлами, валидация ввода. Каждый сгенерированный блок проходит этот список.
Да, это время. Но оно окупается, когда ты не ищешь три недели баг с промокодами.
В этом году я начал использовать новые подходы.
LLM-as-a-Judge - когда одна модель проверяет код, сгенерированный другой моделью. Звучит как магия, но работает.
Иногда.
Я не доверяю этому полностью, но как дополнительный фильтр - даёт результат. Особенно когда одна модель находит то, что пропустила другая.
Self-review - когда AI сам анализирует свой код и предлагает улучшения.
Тоже полезно. Но я всё равно перепроверяю. Потому что ошибки становятся всё менее заметными.
Меня часто спрашивают: «Можно ли использовать AI-код без проверки?»
Нет.
Абсолютно нет.
Даже если код проходит все тесты. Даже если он выглядит идеально. Даже если его написала самая умная модель.
Проверять нужно всегда.
Нашёл недавно старую заметку. Я вёл её, когда только начинал использовать AI в разработке. Там был пункт: «Проверить код на очевидные ошибки».
Сейчас я смеюсь.
Очевидные ошибки AI больше не делает. Он делает неочевидные. И это намного страшнее.
Я не знаю, когда модели научатся генерировать код, который можно сразу отправлять в продакшен.
Может, через пару лет. Может, никогда.
Но пока я проверяю каждый сгенерированный блок. Потому что отвечаю за него. И моя команда отвечает.
И ты, когда используешь AI-код, тоже отвечаешь.
Комментарии
Чтобы оставить комментарий, войдите в аккаунт.