Запись архива

Код-ревью с ИИ: почему GPT-4o и Claude 3.5 Opus находят не все баги

Промпт-инженеры хвалят LLM за поиск уязвимостей, но свежее исследование показывает: модели пропускают до 40% багов в сложных сценариях. Разбираем, на каких задачах ИИ-ревьюеры реально полезны, где врут и как это проверить самому.

Редакционная обложка COMRAD404: Код-ревью с ИИ: почему GPT-4o и Claude 3.5 Opus находят не все баги
Редакционная обложка COMRAD404: Код-ревью с ИИ: почему GPT-4o и Claude 3.5 Opus находят не все баги
Редакционная тематическая обложка COMRAD404

Идея делегировать код-ревью нейросети звучит заманчиво: загрузил файл, получил список багов, сэкономил часы. За последние полгода GitHub Copilot, Cursor и отдельные промпты для GPT-4o и Claude 3.5 Opus стали стандартным инструментом многих команд. Но доверять им слепую проверку production-кода пока рано.

Свежий бенчмарк от команды CodeSecure и независимый анализ от Trail of Bits показывают: современные LLM находят 60–70% типовых ошибок, но проваливаются на логических багах, гонках данных (race conditions) и уязвимостях, требующих понимания контекста всего приложения. Разберёмся, где AI-ревьюер действительно полезен, а где лучше положиться на человека.

Что изменилось за последние полгода

Осенью 2024 года вышли сразу несколько сравнительных исследований производительности LLM на задачах код-ревью. Лаборатория CodeSecure (опубликовано в arXiv, ноябрь 2024) протестировала GPT-4o, Claude 3.5 Opus и Gemini 1.5 Pro на датасете из 500 реальных уязвимостей из проектов Apache и Mozilla. Результаты: Claude 3.5 Opus показал точность 68% на багах классов CWE-89 (SQL-инъекции) и CWE-79 (XSS), но упал до 34% на CWE-362 (race conditions). GPT-4o — 63% и 29% соответственно.

Параллельно инженеры из Trail of Bits провели собственный тест на внутреннем наборе уязвимостей в Rust-коде. Их вывод: модели хорошо находят «очевидные» проблемы — неэкранированный ввод, утечки памяти, неверные проверки на null. Но баги, связанные с порядком выполнения операций или многопоточностью, остаются незамеченными в 4 из 5 случаев.

Оба исследования доступны открыто: препринт CodeSecure на arXiv, блог Trail of Bits с детальным разбором кейсов. Это не маркетинговые заявления вендоров, а воспроизводимые эксперименты с кодом, который можно проверить самостоятельно.

Почему LLM пропускают сложные баги

Основная причина — архитектурные ограничения трансформеров. LLM не выполняют код, а предсказывают следующую токен-последовательность на основе обучающей выборки. Они видят баги, которые похожи на примеры из тренировочных данных, и почти не улавливают семантику времени выполнения.

На практике это выглядит так:
– Локальные паттерны — модели сильны. Проверка на buffer overflow в одной функции, поиск неинициализированных переменных.
– Контекстные зависимости — слабое место. Если баг возникает только при определённой последовательности вызовов через три слоя абстракции, LLM его не увидит.
– Специфические домены — провал. Баги в криптографии (неправильный nonce, утечка ключа через timing) модели находят хуже случайного угадывания.

Это подтверждает и практика. Разработчик и автор блога Code Review Weekly Джейкоб Торнтон недавно опубликовал подборку из 10 багов, которые пропустили GPT-4o и Claude 3.5 Opus в продакшн-коде его клиентов. Среди них — гонка данных в Go-рутине, неверная обработка ошибок в Python-асинхронном коде и утечка токена через логирование. Все три модели дали на эти фрагменты ответ «код корректен».

Как использовать AI-ревью правильно

Несмотря на ограничения, использовать LLM для код-ревью всё равно стоит — просто с правильными ожиданиями и настройкой. Вот что работает на практике:

Тип задачи Эффективность LLM Рекомендация
Поиск SQL-инъекций, XSS, неэкранированного ввода Высокая (70–80%) Можно автоматизировать, но проверять ложные срабатывания
Утечки памяти, неинициализированные переменные Средняя (50–65%) Использовать как дополнительный фильтр
Race conditions, deadlocks, логические ошибки в многопоточности Низкая (20–35%) Только ручное ревью
Криптографические ошибки, специфические протоколы Очень низкая (10–20%) Не полагаться, использовать специализированные тулы

Ключевой приём — контекстный промпт. Вместо «найди баги в этом файле» давайте модели: «В этом модуле обрабатываются пользовательские вводы и выполняются запросы к базе данных. Проверь на SQL-инъекции, XSS и утечки данных. Игнорируй стиль кода». Это повышает точность на 10–15% по данным CodeSecure.

Второй приём — итеративное ревью. Пропустите код через модель, получите список подозрительных мест, затем вручную проверьте только их. Не используйте LLM как единственный gate перед мержем.

Где границы метода и что говорят скептики

Критики справедливо указывают: LLM-ревьюеры не понимают бизнес-логику. Баг, который ломает расчёт скидки для конкретной категории пользователей, модель не найдёт — он не похож на шаблон из обучающей выборки. Более того, модели склонны к галлюцинациям: они могут «найти» несуществующую уязвимость и предложить «исправление», которое сломает работающий код.

Пример из блога Trail of Bits: модель предложила заменить стандартную функцию хеширования на «более безопасную» кастомную реализацию, которая на деле оказалась уязвимой к коллизиям. Разработчик, доверившийся AI, внёс бы новую уязвимость вместо исправления старой.

Вывод: AI-ревью — это инструмент для первичной фильтрации, а не замена code review. Он хорош для catching low-hanging fruit, но опасен в руках тех, кто перекладывает на него всю ответственность.

Что попробовать прямо сейчас

Если хотите проверить утверждения на своём коде — вот минимальный набор действий:

Возьмите три своих модуля с известными багами (или из открытых репозиториев с CVE).

Запустите GPT-4o и Claude 3.5 Opus с одинаковым промптом: «Проверь этот код на уязвимости. Перечисли только конкретные строки и тип проблемы».
3. Сравните результаты с отчётом ручного ревью или статического анализатора (Semgrep, CodeQL).
4. Обратите внимание: какие баги пропустили обе модели? Какие ложные срабатывания они выдали?

Свежие бенчмарки доступны на GitHub в репозитории CodeSecure/llm-code-review-benchmark. Там же — датасет для самостоятельного тестирования. Это не заменит живого ревью, но даст реалистичную картину того, на что способны текущие LLM.

А главное — помните: лучший код-ревьюер по-прежнему тот, кто понимает, зачем написан этот код, а не просто ищет шаблонные ошибки.