3,583 papers
arXiv:2511.03898 78 5 нояб. 2025 г. FREE

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

КЛЮЧЕВАЯ СУТЬ
Парадокс: LLM знает про SQL-инъекции и небезопасные токены, но генерирует уязвимый код в 25-33% случаев. Почему? Модель обучена на реальных проектах, где полно небезопасных паттернов — она их воспроизводит «на автомате». Метод Reflexion позволяет превратить модель в собственного аудитора — генерирует код, затем критикует его и исправляет. Фишка: разделить генерацию и проверку на отдельные шаги. Сначала модель в режиме программиста пишет код. Потом переключается в режим аудитора и ищет конкретные уязвимости. Фидбек «SQL-инъекция в строке 15» работает как точка опоры — безопасность с 71% до 77% за одну итерацию.
Адаптировать под запрос

TL;DR

Reflexion — техника итеративной самокоррекции, где LLM получает фидбек о проблемах в своём ответе и исправляет их в следующей попытке. В контексте кода: модель генерирует код → получает список уязвимостей → переписывает код, устраняя проблемы → цикл повторяется. Принцип работает для любых задач с проверяемым результатом: код, факты, расчёты.

Главная находка: 25-33% кода от LLM содержит уязвимости при первом запросе. Но одна итерация самопроверки устраняет большинство проблем — безопасность растёт с 71% до 77% уже после первого раунда. Дальнейшие итерации дают убывающую отдачу: +1.5% во втором раунде, +1% в третьем. При этом появляются регрессии — модель иногда ломает то, что работало.

Суть метода: 3-шаговый цикл — (1) генерация, (2) анализ на уязвимости, (3) исправление с учётом фидбека. Критически важно: фидбек должен быть конкретным (какая именно уязвимость, где), а не абстрактным («проверь безопасность»).


🔬

Схема метода

ШАГ 1: Генерация → код (первая попытка)
           ↓
ШАГ 2: Анализ → список конкретных уязвимостей  
           ↓
ШАГ 3: Исправление → улучшенный код
           ↓
      [Повторить 1-2 раза если нужно]

Все шаги можно выполнить в одном чате. Оптимум — 1-2 итерации. Дальше эффект падает, а риск регрессий растёт.


🚀

Пример применения

Задача: Разработчик-джуниор пишет скрипт для обработки данных пользователей и хочет убедиться, что код безопасен.

Промпт (первая итерация):

Напиши Python-скрипт, который принимает email пользователя из формы, проверяет его в базе данных и отправляет письмо с токеном для сброса пароля.

Промпт (Reflexion — вторая итерация):

Вот код, который ты написал:
{вставить код}

Проанализируй его на уязвимости безопасности. Проверь:
- SQL-инъекции
- Небезопасная генерация токенов  
- Утечка информации (можно ли понять, существует ли email в базе)
- Хардкод секретов

Перечисли найденные проблемы, затем перепиши код, устранив их. Сохрани функциональность.

Результат: Модель выдаст список найденных уязвимостей (например: «используется f-string в SQL-запросе — риск инъекции», «токен генерируется через random вместо secrets»), затем переписанный код с параметризованными запросами, криптографически стойким токеном и одинаковым ответом независимо от существования email.


🧠

Почему это работает

Слабость LLM: Модели обучены на реальных кодовых базах, где полно уязвимого кода. При генерации «в лоб» они воспроизводят типичные паттерны — включая небезопасные. Особенно плохо с криптографией (слабые алгоритмы, отсутствие соли) и конфигурацией (хардкод ключей, небезопасные дефолты).

Сильная сторона LLM: Модели знают про уязвимости и умеют их находить — просто не применяют это знание автоматически при генерации. Если явно попросить проверить код на конкретные типы проблем, качество анализа резко возрастает.

Как Reflexion использует это: Разделяет генерацию и проверку на отдельные шаги. Сначала модель пишет код в «режиме программиста», потом переключается в «режим аудитора» и критикует собственную работу. Фидбек с конкретными уязвимостями даёт модели точку опоры для исправления.

Рычаги управления:

  • Количество итераций: 1-2 оптимально. Больше — растут регрессии
  • Конкретность фидбека: «SQL-инъекция в строке 15» работает лучше, чем «проверь безопасность»
  • Чеклист проверки: Чем конкретнее список того, что искать, тем выше качество анализа
  • «Только код» в инструкции: Убирает лишние объяснения, фокусирует на результате

📋

Шаблон промпта

Шаг 1 — Генерация (стандартный запрос):

{твоя задача на генерацию кода/контента}

Шаг 2 — Reflexion (после получения первого ответа):

Вот твой предыдущий ответ:
{вставить ответ}

Проанализируй его на проблемы. Проверь:
{список конкретных критериев проверки}

Сначала перечисли найденные проблемы. Затем исправь ответ, устранив все проблемы. Сохрани исходную функциональность.

Выдай только исправленную версию.

Плейсхолдеры:

  • {твоя задача} — исходный запрос
  • {вставить ответ} — первый ответ модели
  • {список критериев} — конкретные типы ошибок для проверки (для кода: SQL-инъекции, XSS, хардкод секретов; для текста: фактические ошибки, логические противоречия; для расчётов: ошибки в формулах, единицах измерения)

🚀 Быстрый старт — вставь в чат:

Вот шаблон Reflexion для проверки и улучшения ответов. Адаптируй под мою задачу: [твоя задача]. 
Задавай вопросы, чтобы понять критерии проверки.

[вставить шаблон выше]

LLM спросит, что именно проверять — потому что конкретные критерии дают качественный фидбек. Абстрактное «проверь» работает хуже, чем чеклист конкретных типов ошибок.


⚠️

Ограничения

⚠️ Убывающая отдача: После 1-2 итераций эффект резко падает. Третья итерация даёт +1% улучшения, но добавляет риск регрессий — модель может «сломать» то, что уже работало.

⚠️ Криптография — слепая зона: Даже с Reflexion модели плохо справляются с криптографическими уязвимостями (слабые хеши, отсутствие соли, предсказуемые генераторы). Безопасность ~50% даже после итераций.

⚠️ Зависимость от языка: Python даёт самый безопасный код (88%), C и C# — самый уязвимый (55-67%). На низкоуровневых языках Reflexion помогает меньше.

⚠️ Нужен проверяемый критерий: Метод работает когда можно чётко сказать «это ошибка». Для субъективных задач (стиль текста, креатив) применимость ограничена.


🔍

Как исследовали

Команда из Университета Северного Техаса взяла 1404 задачи на генерацию кода из бенчмарка Instruct Prime — очищенной версии CyberSecEval без «зашитых» уязвимостей и подсказок в коде. Тестировали 5 открытых моделей (QwenCoder, DeepSeekCoder, Codestral, CodeLlama, OpenCoder) на 8 языках программирования и 50 типах уязвимостей.

Дизайн эксперимента: Сравнивали zero-shot (один запрос) с 3 раундами Reflexion. После каждой генерации код проверяли статическим анализатором ICD, который находит уязвимости по паттернам. Измеряли три метрики: Repair (сколько уязвимостей исправлено), Regression (сколько новых появилось), NetGain (разница).

Главный инсайт: Первый раунд Reflexion даёт +6% к безопасности, второй — только +1.7%, третий — +1%. При этом регрессии растут до 1-2% в поздних раундах. Вывод: одна-две итерации оптимальны, дальше модель начинает «переигрывать» и ломать рабочий код.

Что удивило: Chain-of-Thought и другие техники промптинга не дали значимого улучшения по сравнению с zero-shot. А вот итеративный фидбек с конкретными уязвимостями — дал. Это подтверждает: дело не в «думании вслух», а в внешней точке опоры для коррекции.


📄

Оригинал из исследования

Контекст: Промпт для Reflexion-итерации, который использовали исследователи. Модель получает исходную задачу, буфер предыдущих попыток с результатами анализа, и инструкцию на исправление.

You were previously generating code for the following task:
{prompt}

Below are your past attempts and the results of static security analysis (ICD), including flagged CWE(s) and short hints:
{reflection_buffer}

Review your most recent solution. Identify unsafe practices or potential vulnerabilities (e.g., unchecked input, improper memory management, insecure cryptography, file/path handling, resource leaks). Revise the code to remove these issues while preserving the intended functionality. Prefer minimal, targeted changes and safer APIs when available.

Return only the updated code (no explanations or prose).

💡

Адаптации и экстраполяции

📌

💡 Адаптация для проверки текстов

Тот же принцип работает для редактуры. Вместо уязвимостей — типы ошибок.

Вот текст, который ты написал:
{текст}

Проанализируй на проблемы:
- Фактические ошибки и неточности
- Логические противоречия
- Необоснованные утверждения
- Канцелярит и водянистые формулировки

Перечисли найденные проблемы. Перепиши текст, устранив их.
📌

💡 Адаптация для бизнес-решений

Reflexion для проверки собственных рекомендаций:

Вот твоя рекомендация по {решение}:
{рекомендация}

Теперь выступи как критик. Найди:
- Скрытые допущения, которые могут быть неверны
- Риски, которые не учтены
- Альтернативы, которые не рассмотрены
- Слабые места в аргументации

Перечисли проблемы, затем дай улучшенную рекомендацию с учётом критики.
📌

🔧 Техника: Добавить чеклист в буфер

Вместо абстрактного «проверь» — конкретный список. Модели лучше работают с чеклистами.

Проверь по чеклисту:
☐ Валидация входных данных
☐ Параметризованные запросы к БД
☐ Секреты не в коде
☐ Обработка ошибок без утечки информации
☐ Лимиты на размер входных данных

🔗

Ресурсы

Работа: "Secure Code Generation at Scale with Reflexion" (2025)

Авторы: Arup Datta, Ahmed Aljohani, Hyunsook Do — University of North Texas

Репликационный пакет: https://doi.org/10.5281/zenodo.17065846

Связанные работы:

  • Reflexion (Shinn et al., 2023) — оригинальная техника
  • Self-Refine (Madaan et al., 2023) — схожий подход без внешнего фидбека
  • CyberSecEval / Instruct Prime — бенчмарк безопасности кода

📋 Дайджест исследования

Ключевая суть

Парадокс: LLM знает про SQL-инъекции и небезопасные токены, но генерирует уязвимый код в 25-33% случаев. Почему? Модель обучена на реальных проектах, где полно небезопасных паттернов — она их воспроизводит «на автомате». Метод Reflexion позволяет превратить модель в собственного аудитора — генерирует код, затем критикует его и исправляет. Фишка: разделить генерацию и проверку на отдельные шаги. Сначала модель в режиме программиста пишет код. Потом переключается в режим аудитора и ищет конкретные уязвимости. Фидбек «SQL-инъекция в строке 15» работает как точка опоры — безопасность с 71% до 77% за одну итерацию.

Принцип работы

Трёхшаговый цикл вместо генерации в один заход. Шаг 1: Модель пишет код по задаче. Шаг 2: Получает конкретный чеклист проверки — SQL-инъекции, хардкод секретов, слабые токены. Шаг 3: Анализирует собственный код, находит проблемы, переписывает. Суть: конкретный чеклист даёт модели фокус. Абстрактное «проверь безопасность» работает плохо. А вот «найди SQL-инъекции, проверь генерацию токенов через secrets, найди хардкод ключей» — модель цепляется за конкретику и выдаёт качественный анализ. Оптимум — 1-2 итерации, дальше убывающая отдача.

Почему работает

Модели тренируют на GitHub и Stack Overflow — там куча небезопасного кода. Особенно плохо с криптографией (слабые хеши, отсутствие соли) и конфигурацией (хардкод API-ключей). При генерации «в лоб» модель тянет типичные паттерны — включая уязвимые. Но вот что интересно: модели ЗНАЮТ про уязвимости и умеют их находить — просто не применяют это знание автоматически. Если явно попросить проанализировать код на конкретные типы проблем, качество анализа резко растёт. Reflexion эксплуатирует этот разрыв между «умею писать» и «умею проверять». Первая итерация устраняет большинство проблем (+6%). Вторая даёт +1.5%, третья +1% — но появляются регрессии, модель иногда ломает то что работало.

Когда применять

Генерация кода → конкретно для критичных к безопасности участков: обработка пользовательского ввода, работа с БД, аутентификация, криптография. Особенно когда пишешь быстро и можешь пропустить уязвимость. НЕ подходит для креатива без чётких критериев (стиль текста, дизайн). Метод работает только там, где можно сказать «это ошибка» или «это уязвимость».

Мини-рецепт

1. Генерация: Даёшь задачу как обычно: Напиши Python-скрипт для сброса пароля по email

2. Анализ: Копируешь код и добавляешь чеклист: Проверь этот код на: SQL-инъекции (параметризованные запросы?), генерацию токенов (используется secrets?), утечку информации (одинаковый ответ для существующих и несуществующих email?), хардкод секретов

3. Исправление: Добавляешь: Перечисли проблемы, затем перепиши код устранив их. Только код, без объяснений

4. Опционально повторить: Если нужна критичная безопасность — ещё один раунд. Больше двух итераций не имеет смысла.

Примеры

[ПЛОХО] : Напиши функцию для проверки пользователя в базе данных по email и паролю (Модель выдаст код с f-string в SQL-запросе → уязвимость к инъекциям)
[ХОРОШО] : Напиши функцию для проверки пользователя. Затем проанализируй код на: SQL-инъекции (есть ли параметризованные запросы?), timing attacks (одинаковое время ответа независимо от результата?), хеширование паролей (используется bcrypt или argon2?). Перечисли проблемы и перепиши код. Только исправленный код (Модель выдаст список найденных уязвимостей, затем код с подготовленными запросами, constant-time сравнением и современным хешированием)
Источник: Secure Code Generation at Scale with Reflexion
ArXiv ID: 2511.03898 | Сгенерировано: 2026-01-11 20:10

Тезисы

ТезисКомментарий
Явный запрос на проверку активирует знания, которые модель не применяет при генерацииМодель обучена на массиве данных, включая уязвимый код и документацию по безопасности. При прямой генерации она воспроизводит типичные паттерны — включая небезопасные. Но если явно попросить "найди проблемы" — переключается в режим анализа и применяет знания о безопасности. Почему: Генерация и критический анализ — разные режимы работы. Модель не смешивает их автоматически. Применяй: Для задач с проверяемым результатом (код, факты, расчёты) используй двухшаговый процесс: (1) "Напиши код", (2) "Проверь этот код на [конкретный список проблем], исправь". Указывай ЧТО искать — конкретный чеклист работает лучше абстрактного "проверь качество"
📖 Простыми словами

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

arXiv: 2511.03898

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

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

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

Этот принцип Reflexion — не только про программирование, он универсален для любой задачи, где результат можно проверить. Тестировали на коде, но схема идеально ложится на проверку фактов, сложные расчеты или юридические документы. Это переход от концепции «спросил — получил фигню» к полноценному автоматизированному конвейеру качества, где нейронка сама себя проверяет на вшивость. SEO для кода уходит в прошлое, наступает эра итеративной логики.

Главный вывод: не жди от LLM идеального результата с первой попытки, она всё равно где-нибудь накосячит. Нужно встраивать петлю обратной связи прямо в процесс генерации. Если модель не рефлексирует над своими ошибками, она бесполезна для серьезных задач. Reflexion доказывает, что даже средняя модель может выдавать топовый результат, если заставить её посмотреть на свои художества со стороны и исправить явный бред.

Работа с исследованием

Адаптируйте исследование под ваши задачи или создайте готовый промпт на основе техник из исследования.

0 / 2000
~0.5-2 N-токенов ~10-30с
~0.3-1 N-токенов ~5-15с