3,583 papers
arXiv:2512.02567 75 2 дек. 2025 г. FREE

Feedback Loops в LLM: многократные циклы "генерация → ошибка → исправление"

КЛЮЧЕВАЯ СУТЬ
LLM часто лажает с первого раза — без обратной связи успех 69%. Возвращаешь детальную ошибку обратно в модель — успех подскакивает до 78%. Первый цикл обратной связи даёт +24% к результату, второй и третий почти ничего не добавляют. Метод позволяет исправлять ошибки LLM без бесконечных итераций — оптимум 1-2 цикла, потом выгоднее начать новый диалог. Работает через конкретный контекст проблемы: вместо "не работает, исправь" модель видит "UnicodeDecodeError в строке 15" — точечный фокус для исправления.
Адаптировать под запрос

TL;DR

Исследование показывает как работает паттерн "generate-and-check" с автоматическими циклами обратной связи: LLM генерирует решение → система проверяет результат → при ошибках возвращает их обратно в LLM для исправления. Главная находка — первый цикл обратной связи (feedback loop) даёт наибольший прирост к успеху (+24%), а дальнейшие итерации почти не помогают.

LLM часто выдаёт решение с ошибками с первого раза. Без обратной связи успех — 69%. Но когда система возвращает детальные сообщения об ошибках (компилятор, тесты, конкретные различия), модель исправляет проблему и успех подскакивает до 78% уже после одного цикла. Разница между моделями сглаживается при использовании feedback loops — слабая модель с обратной связью догоняет сильную без неё.

Вместо бесконечных итераций исправлений внутри одного диалога, эффективнее делать новые запуски с нуля — каждый новый запрос может "попасть" в другую область решений. Бонус-находка: одинаковая задача, сформулированная по-разному (другие термины, примеры, структура), даёт разные результаты от LLM — это можно использовать для улучшения качества.


🔬

Схема метода

Исследовали автоматическую систему, но принцип применим вручную:

ШАГ 1: Сгенерировать решение (код/текст/структуру)
ШАГ 2: Проверить результат (компиляция/тесты/формат)
ШАГ 3: При ошибке → вернуть конкретное описание ошибки в LLM
ШАГ 4: LLM исправляет с учётом ошибки

Критично: После 2-3 безуспешных циклов лучше начать новый диалог, чем продолжать исправления.


🚀

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

Задача: Ты автоматизируешь отчёты для бизнеса — попросил Claude написать Python-скрипт для обработки выгрузки из 1С в Excel. Код упал с ошибкой при запуске.

Промпт (первая попытка):

Напиши Python скрипт который читает CSV-файл с данными из 1С 
и создаёт сводную таблицу в Excel с группировкой по менеджерам.

После получения ошибки — промпт с feedback:

Скрипт упал с ошибкой:

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xed in position 15

Вот код который ты дал:
[вставить код]

Исправь с учётом этой ошибки.

Результат: Модель увидит конкретную ошибку и контекст, исправит кодировку (скорее всего предложит encoding='cp1251' для 1С). Одна итерация с детальной ошибкой работает лучше чем три попытки с абстрактным "не работает, исправь".

Если после 2 циклов проблема не ушла — начни новый чат и переформулируй задачу: добавь конкретный пример данных, опиши структуру файла подробнее, используй другие термины.


🧠

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

LLM генерирует вероятностно и может ошибаться с первого раза. Но модель хорошо умеет исправлять, когда видит конкретный контекст проблемы. Детальное сообщение об ошибке — "UnicodeDecodeError в строке 15" или "ожидал число, получил строку" — даёт точечный фокус для исправления. Вместо абстрактного "что-то не так", модель видит на что смотреть.

Первый feedback loop самый эффективный (+24% к успеху) потому что исправляет очевидные ошибки: синтаксис, типы, забытые импорты. Второй и третий циклы уже борются с более тонкими проблемами (логика, архитектура), где простое исправление не поможет — тут нужен другой подход. Поэтому после 1-2 циклов выгоднее начать заново, чем углубляться в исправления.

Multiple runs эффективнее deep iterations потому что каждый новый запрос может "попасть" в другую область решений. LLM не детерминирована — это как несколько попыток решить задачу с разных сторон вместо упорного продолжения одного неудачного пути. Разнообразие подходов побеждает упорство в одном направлении.

Рычаги управления: - Детальность ошибки — чем конкретнее ("строка 15, переменная X") тем лучше исправление - Число циклов — 1-2 оптимально по цене/качеству, дальше убывающая отдача - Момент рестарта — если 2 цикла не помогли, начни новый чат с переформулировкой


📋

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

Базовый feedback loop:

[Сгенерированное решение получено ранее]

При проверке получил ошибку:

{конкретный_текст_ошибки}

Контекст: {где_именно_произошло}

Исправь код учитывая эту ошибку.

Structured feedback (сильнее):

Проблема: {что_именно_не_работает}
Ожидал: {какой_результат_должен_быть}
Получил: {какой_результат_получился}
Ошибка: {текст_ошибки_если_есть}

Исправь решение.

Где: - {конкретный_текст_ошибки} — копируй полностью из терминала/IDE/браузера - {где_именно_произошло} — строка кода, файл, этап выполнения - Чем детальнее контекст, тем точнее исправление

Правило рестарта: Если 2 цикла не дали результат → новый чат + переформулируй задачу (другие термины, добавь примеры, измени структуру описания).


⚠️

Ограничения

⚠️ Глубокие проблемы логики: Если ошибка не в синтаксисе или очевидном баге, а в архитектуре решения или неправильном понимании задачи, feedback loops помогают слабо. После 2-3 безуспешных циклов лучше начать диалог заново с другой формулировкой.

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

⚠️ Стоимость растёт: Каждый цикл = новый запрос = токены. Исследование показало что 1-2 feedback loop оптимальны по соотношению цена/результат. Больше 3-4 циклов — убывающая отдача, проще начать заново.

⚠️ Застревание в локальном минимуме: Если LLM пошла по неправильному пути решения, исправления в том же диалоге могут усугублять проблему. Модель "привязана" к предыдущему контексту. Новый чат = чистый лист, шанс на другой подход.


🔍

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

Команда из Bosch Research и университета Магдебурга собрала 50 C-файлов (30 из automotive embedded кода, 10 из open-source библиотек, 10 из соревнований по программированию) и прогнала через систему автоматического перевода на Rust. Система работала так: LLM переводит C → Rust → компилятор rustc проверяет → differential fuzzer тестирует эквивалентность поведения → при ошибках возвращает их LLM.

Для каждого файла делали 20 запусков с разным числом feedback loops (от 1 до 5 итераций) и тремя моделями: GPT-3.5 Turbo (старая, мощная), GPT-4o mini (коммерческая, популярная), Phi-4 (новая, открытая). Измеряли pass@5 — успех хотя бы в одном из пяти прогонов.

Главная находка удивила: без feedback успех 69%, с одним циклом — 78% (+9 процентных пунктов!), со вторым — 78%, с третьим — 78%, с четвёртым — 78%, с пятым — 79%. Первый цикл даёт весь прирост, дальше почти ничего. Разница между моделями без feedback — до 9%, но с feedback почти исчезает — слабая модель с обратной связью работает как сильная без неё.

Что удивило с perturbations: изменения кода которые не меняют поведение (переименования переменных, другие комментарии, форматирование, замена for на while) влияют на результат LLM. Один и тот же алгоритм, записанный по-разному, даёт разный процент успеха. Это значит: если задача не решается — переформулируй её, используй другие термины, структуру, примеры.

Инсайт для практики: не трать 5 запросов на исправления в одном чате. Лучше 1 feedback loop + 2-3 новых диалога с разными формулировками. И всегда возвращай детальные ошибки обратно в модель — это даёт 24% буст с первой же итерации.


🔗

Ресурсы

Martin Weiss, Jesko Hecking-Harbusch, Jochen Quante, Matthias Woehrle — "Feedback Loops and Code Perturbations in LLM-based Software Engineering: A Case Study on a C-to-Rust Translation System"

Otto von Guericke University Magdeburg, Bosch Research (Renningen, Germany)

Связанные работы из исследования: - c2rust — классический rule-based транслятор - libFuzzer (LLVM) — инструмент для fuzzing - SWE-Bench, SWE-Lancer — бенчмарки для code generation


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

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

LLM часто лажает с первого раза — без обратной связи успех 69%. Возвращаешь детальную ошибку обратно в модель — успех подскакивает до 78%. Первый цикл обратной связи даёт +24% к результату, второй и третий почти ничего не добавляют. Метод позволяет исправлять ошибки LLM без бесконечных итераций — оптимум 1-2 цикла, потом выгоднее начать новый диалог. Работает через конкретный контекст проблемы: вместо "не работает, исправь" модель видит "UnicodeDecodeError в строке 15" — точечный фокус для исправления.

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

Не держи всё в одном диалоге до победного. Схема: генерируешь решение → проверяешь → возвращаешь детальную ошибку в LLM → исправление. Критично: после 2 безуспешных циклов лучше начать новый чат, чем продолжать исправления. Каждый новый запуск может "попасть" в другую область решений — это как несколько попыток решить задачу с разных сторон вместо упорного продолжения одного тупикового пути.

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

LLM хорошо умеет исправлять когда видит конкретный контекст. "UnicodeDecodeError в строке 15" или "ожидал число, получил строку" — модель знает на что смотреть. Первый цикл закрывает очевидные баги: синтаксис, типы, забытые импорты — отсюда +24% к успеху. Второй и третий циклы уже борются с тонкими проблемами логики, где простое исправление не работает. Разнообразие подходов побеждает упорство в одном направлении — поэтому multiple runs (несколько запусков с нуля) эффективнее deep iterations (бесконечные исправления в одном диалоге). Модель не детерминирована — каждый новый запрос может зайти с другой стороны.

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

Автоматизация и код → конкретно для задач где есть чёткий критерий проверки: компилятор, тесты, формальный формат, математическая проверка. Особенно когда LLM генерирует решение с ошибками с первого раза (скрипты, конфиги, структурированные данные). НЕ подходит для субъективных задач — "улучши стиль текста" или "сделай дизайн красивее" не имеют однозначной "ошибки".

Мини-рецепт

1. Получи решение: Попроси LLM сгенерировать код/структуру/формат
2. Проверь результат: Запусти компилятор, тесты, валидацию — получи конкретную ошибку
3. Верни ошибку с контекстом: Проблема: {что не работает}. Ожидал: {какой результат}. Получил: {что получилось}. Ошибка: {текст ошибки}. Исправь решение.
4. Правило рестарта: Если 2 цикла не дали результат → новый чат + переформулируй задачу (другие термины, добавь примеры данных, измени структуру описания)

Примеры

[ПЛОХО] : Код не работает, исправь — модель не видит где проблема, тыкает наугад
[ХОРОШО] : Скрипт упал с ошибкой: UnicodeDecodeError: 'utf-8' codec can't decode byte 0xed in position 15. Вот код: [код]. Исправь с учётом этой ошибки — модель видит конкретную проблему (кодировка) и место (позиция 15), исправит за один цикл (скорее всего предложит encoding='cp1251' для 1С)
Источник: Feedback Loops and Code Perturbations in LLM-based Software Engineering: A Case Study on a C-to-Rust Translation System
ArXiv ID: 2512.02567 | Сгенерировано: 2026-01-08 22:47

Методы

МетодСуть
Цикл обратной связи с детальной ошибкойДаёшь модели задачу. Получаешь решение. Проверяешь (компиляция, тест, формат). При ошибке возвращаешь конкретное описание проблемы модели: текст ошибки, номер строки, что ожидал vs что получил. Модель исправляет с учётом контекста. Почему работает: детальная ошибка даёт точечный фокус для исправления. Вместо "что-то не так" модель видит "UnicodeDecodeError в строке 15" — это прямая подсказка куда смотреть. Лимит: 1-2 цикла оптимально. После 2-3 неудачных попыток начинай новый диалог с переформулировкой. Когда применять: есть чёткий критерий правильности (код компилируется, тест проходит, формат валиден). Когда не работает: субъективные задачи без однозначной ошибки (стиль текста, дизайн)

Тезисы

ТезисКомментарий
Первый цикл обратной связи даёт основной прирост, дальше убывающая отдачаКогда модель видит ошибку первый раз — исправляет очевидное: синтаксис, забытые импорты, типы данных. Это даёт резкий скачок качества. Второй-третий цикл уже борется с глубокими проблемами — логика, архитектура. Там простое исправление не помогает. Применяй: делай максимум 2 цикла исправлений в одном диалоге. Не помогло — переходи к следующему тезису
📖 Простыми словами

Feedback Loops в LLM: многократные циклы "генерация → ошибка → исправление"

arXiv: 2512.02567

Суть в том, что современные нейронки работают по принципу generate-and-check: сначала выдают сырой результат, а потом допиливают его, глядя на ошибки. Это не просто «исправь баг», а замкнутый цикл, где LLM получает по лбу от компилятора или тестов и тут же пробует снова. Исследование на примере перевода кода с C на Rust показало, что первый же такой цикл обратной связи дает бешеный буст к успеху — сразу +24% к качеству. Модель не становится умнее, она просто получает контекст своего провала и точечно его латает.

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

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

Хотя ученые мучили перевод кода, этот принцип универсален для любой работы с AI. Будь то написание скрипта для Excel или создание сложного SQL-запроса — не пытайся вылизать промпт до идеала с первой попытки. Дай модели ошибиться, скорми ей текст ошибки и посмотри, как она вывезет. Это экономит время и нервы, потому что нейронка лучше всего соображает, когда её тыкают носом в конкретный косяк.

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

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

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

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