TL;DR
Исследователи проверили как ChatGPT-4, Claude 3 и LLaMA 4 находят баги в коде через многоступенчатый промптинг — когда ты даёшь код не сразу со всем контекстом, а добавляешь информацию порциями: сначала чистый код, потом структуру данных, потом ожидаемое поведение. Каждая стадия — новый чат, без истории предыдущих запросов.
LLM отлично видят локальные проблемы (синтаксис, null pointer, опечатки), средне — security уязвимости, плохо — сложные баги в продакшн-коде. Парадокс: чем больше контекста даёшь сразу, тем хуже модель фокусируется. А вот пошаговое добавление улучшает детекцию на 20-40% — модель каждый раз смотрит свежим взглядом, не застревает на одной гипотезе.
Метод работает в три стадии: (1) дать код без контекста → базовая детекция, (2) добавить зависимости/структуру данных → улучшенная детекция, (3) добавить тесты/ожидаемое поведение → точная локализация. Ключевой трюк — запускать каждую стадию в отдельном чате, чтобы модель не тащила ошибочные выводы из прошлого запроса.
Схема метода
СТАДИЯ 1: Код без контекста → базовая детекция (синтаксис, типы)
↓
СТАДИЯ 2: Код + структура данных/API → улучшенная детекция (логика)
↓
СТАДИЯ 3: Код + ожидаемое vs реальное поведение → точная локализация
⚠️ Каждая стадия — отдельный чат (новая сессия, без истории)
Если после стадии 1 модель нашла что-то — проверь. Если нет или неточно — двигайся к стадии 2. Если всё ещё не нашла — к стадии 3 с конкретным описанием бага.
Пример применения
Задача: Ты маркетолог, написал Python-скрипт для автоматических отчётов по продажам из Excel. Локально работает, а на сервере коллеги падает с ошибкой cannot convert NaN to int. GPT за один проход не увидел проблему — код показался ему нормальным.
Промпт (Стадия 1):
Найди баги в этом коде — синтаксис, логику, потенциальные ошибки:
import pandas as pd
df = pd.read_excel('sales.xlsx')
total = int(df['Сумма'].sum())
print(f'Итого: {total} руб')
Промпт (Стадия 2 — добавляешь структуру данных):
Код должен обрабатывать Excel со столбцами:
- A: Дата
- B: Сумма (могут быть ПУСТЫЕ ячейки)
- C: Регион
Проверь ещё раз — где может сломаться?
[тот же код]
Промпт (Стадия 3 — добавляешь конкретное поведение):
Вот что происходит:
- Input: Excel с пустой ячейкой в столбце "Сумма"
- Expected: Сумма = 0 для пустой ячейки
- Actual: Ошибка "cannot convert NaN to int"
Где баг?
[тот же код]
Результат:
Стадия 1: GPT скажет "код выглядит нормально" или предложит общие улучшения.
Стадия 2: Заметит "а что если в Сумме NaN?" и предложит fillna(0).
Стадия 3: Точно локализует строку int(df['Сумма'].sum()) и даст фикс: int(df['Сумма'].fillna(0).sum()).
Без стадийности модель часто упускает контекстуальные баги — те, что зависят от структуры данных или поведения окружения.
Почему это работает
LLM видят код как текст, не как выполняемую программу. Это как читать инструкцию по сборке мебели без картинок — слова понятны, но как оно работает в сборе — не всегда ясно. Поэтому модели отлично ловят локальные проблемы (опечатки, null pointer, несовпадение типов), но пропускают контекстуальные (как данные придут из API, что если пользователь передаст не то).
Многоступенчатое добавление контекста работает потому что имитирует отладку человеком — сначала смотришь код глазами, потом проверяешь на тестовых данных, потом воспроизводишь баг. LLM делает то же: на стадии 1 анализирует синтаксис, на стадии 2 — логику с учётом данных, на стадии 3 — конкретное поведение.
Отдельный чат на каждой стадии — критично. Если кидать всё в один чат, модель зацикливается на первой гипотезе. Сказала "проблема в строке 5" → дальше видит только строку 5, даже если баг в строке 12. Свежий чат = свежий взгляд.
Рычаги управления:
- Сколько стадий — для простых задач хватает двух (код → контекст), для сложных нужны три (код → контекст → поведение)
- Что добавлять на стадии 2 — структуру данных (Excel/JSON/API response) или зависимости (версии библиотек, настройки окружения)
- Что добавлять на стадии 3 — логи ошибок, ожидаемое vs реальное поведение, unit-тесты
- Новый чат vs продолжение — новый чат = свежий взгляд, продолжение = углубление текущей гипотезы. Используй новый если модель уперлась.
Шаблон промпта
СТАДИЯ 1 (чистый код):
Найди баги в этом коде — compile-time, runtime, логические:
{код}
---
СТАДИЯ 2 (+ контекст):
Код должен работать с {описание_данных_или_API}.
Проверь ещё раз, где может сломаться:
{код}
---
СТАДИЯ 3 (+ поведение):
Вот что должно произойти: {ожидаемое_поведение}
Вот что происходит реально: {реальное_поведение}
Где баг? Какой фикс?
{код}
Подставляй:
{код}— твой код целиком или проблемный фрагмент{описание_данных_или_API}— структура входных данных (столбцы Excel, JSON schema, формат response от API), версии библиотек{ожидаемое_поведение}— что должно получиться (например: "сумма должна быть 15000"){реальное_поведение}— что происходит (например: "ошибка NaN" или "сумма = 0")
⚠️ Каждую стадию запускай в НОВОМ чате — без истории предыдущих запросов. Это ключевое отличие от обычного подхода "добавь контекст в тот же чат".
🚀 Быстрый старт — вставь в чат:
Вот шаблон многоступенчатого промптинга для поиска багов.
Адаптируй под мою задачу: [опиши свой код и проблему].
Задавай вопросы, чтобы заполнить стадии.
[вставить шаблон выше]
LLM спросит про структуру твоих данных, ожидаемое поведение, логи ошибок — потому что для каждой стадии нужен свой уровень детализации. Она возьмёт паттерн из шаблона и заполнит под твою задачу.
Ограничения
⚠️ Сложность кода: В продакшн-коде с 1000+ строк и множественными зависимостями метод работает плохо. Даже с контекстом все модели детектируют только 30-50% багов — теряют нить, не видят связи между модулями.
⚠️ Неочевидные баги: Race conditions, memory leaks, тонкости runtime поведения — все модели пропускают. Они видят что написано, не как оно выполнится.
⚠️ Затраты времени: Три отдельных запроса вместо одного. Для простых задач (опечатка, забыл скобку) — избыточно. Используй когда с первого раза не вышло.
⚠️ Контекст ≠ понимание: Даже если дал всю структуру данных и API — модель может не увидеть edge cases (пустые значения, null, огромные числа, спецсимволы). Человек всё равно нужен для финальной проверки.
Как исследовали
Команда собрала три уровня сложности багов: простые ошибки новичков (забыли инициализировать переменную, double delete, buffer overflow), security уязвимости из SEED Labs (format string bugs, race conditions), продакшн-баги из реальных проектов — OpenSSL (криптографические ошибки, ошибки типов) и библиотек NumPy/Pandas (edge cases в работе с данными).
Все баги локально скомпилировали и протестировали — убедились что они реально воспроизводятся, это не теоретические примеры. Потом каждый баг прогнали через ChatGPT-4, Claude 3, LLaMA 4 с трёхстадийным промптингом. Критично: каждая стадия — новый чат, без carry-over истории. Оценивали по шкале от "не нашёл" (0%) до "полностью детектировал" (100%) + качество объяснений.
Результаты удивили:
- Простые баги (новички): все модели 90-100% — отлично ловят null pointer, memory leaks, опечатки
- Security баги: ChatGPT и Claude 70-80%, LLaMA 50-60% — видят buffer overflow, но пропускают chain exploits (связанные уязвимости типа "сначала format string, потом shell injection")
- Продакшн-баги: все модели 30-50% — сильно проседают на большом коде с зависимостями
Инсайт который вытекает: Контекст решает, но есть потолок. Без контекста модель видит только локальные проблемы (строка 12: null pointer). С контекстом — лучше (а, данные из Excel, там могут быть NaN). Но на сложном коде даже с контекстом модель теряет нить — размер контекстного окна ≠ глубина понимания. Модель не строит mental model кодовой базы как человек.
Что удивило: LLaMA 4 (самая свежая на момент исследования) показал себя слабее на security — не видел chain exploits. ChatGPT и Claude умеют думать "а что если атакующий сделает ТАК, а потом ещё ТАК" — видят последовательности уязвимостей. LLaMA видел только первую уязвимость, дальше не копал.
Адаптации и экстраполяции
💡 Адаптация для анализа текстов:
Принцип многоступенчатого добавления контекста работает не только для кода. Используй для проверки текстов, документов, контрактов — где с первого раза модель не увидела ошибку или несоответствие.
СТАДИЯ 1: Проверь текст на ошибки:
{текст}
---
СТАДИЯ 2: Текст должен соответствовать {требованиям_или_шаблону}.
Проверь ещё раз — где не соответствует:
{текст}
---
СТАДИЯ 3: В тексте должно быть {конкретное_требование}.
Нашёл ли ты это? Если нет — где пропущено?
{текст}
Пример: проверка договора. Стадия 1 — общие ошибки. Стадия 2 — соответствие корпоративному шаблону. Стадия 3 — наличие конкретных пунктов (срок действия, реквизиты, штрафы).
🔧 Техника: Объединить стадии → экономия времени
Если задача простая и контекста немного — можно объединить стадии 1 и 2 в один промпт:
Найди баги в коде. Код работает с {краткое_описание_данных}:
{код}
Но стадию 3 оставь отдельной — если модель не нашла с первого раза, fresh start помогает.
🔧 Техника: Реверс-промптинг → модель генерирует тест-кейсы
Вместо того чтобы ты сам придумывал edge cases для стадии 3, попроси модель:
СТАДИЯ 2.5:
Какие edge cases могут сломать этот код?
Сгенерируй 5 тест-кейсов где код упадёт.
{код + контекст из стадии 2}
Модель выдаст список. Потом в стадии 3 проверяешь эти кейсы один за одним.
Ресурсы
LLM-GUARD: Large Language Model-Based Detection and Repair of Bugs and Security Vulnerabilities in C++ and Python
GitHub: github.com/NoujoudNader/LLM-Bugs-Detection
Akshay Mhatre, Noujoud Nader, Patrick Diehl, Deepti Gupta
Texas A&M University, Louisiana State University, Los Alamos National Laboratory
