Reflexion

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

Суть

Обычный агентный цикл (ReAct) исправляется внутри одного прогона: увидел плохое наблюдение — поменял следующее действие. Reflexion добавляет второй, внешний цикл: прогон целиком признаётся неудачным, агент формулирует словами, почему он провалился, и эта формулировка становится частью входа для следующей попытки.

Три роли, которые при этом играет модель:

  • Actor — собственно агент, который действует и порождает траекторию;
  • Evaluator — оценивает траекторию и выдаёт сигнал: скалярный балл или свободный текст;
  • Self-Reflection — превращает сигнал в разбор: что именно пошло не так и что сделать иначе.

Разборы копятся в эпизодической памяти — буфере, который подмешивается в контекст следующей попытки.

Зачем это нужно

Обучение с подкреплением требует градиентов, размеченных наград и много прогонов. Reflexion заменяет это текстом: сигнал об ошибке остаётся в естественном языке и потому конкретен («забыл проверить пустой список», а не «награда −0,3»). Ничего не дообучается, работает поверх закрытой модели за API.

Как работает

Внешний цикл на попытку: траектория → оценка → разбор → добавить разбор в память → новая попытка. Условие остановки — успех либо исчерпание лимита попыток.

Память ограничена жёстко. Буфер разборов — скользящее окно на 1–3 записи, и ограничение продиктовано не идеей, а размером контекста: разборы конкурируют за то же окно, что и сама задача. Отсюда практическое следствие — Reflexion не накапливает опыт бесконечно, старые уроки вытесняются (Context Compaction).

Качество оценщика решает всё, и ошибка здесь накапливается. Разовая ошибка судьи стоит одной неверной оценки; ошибка судьи внутри петли рефлексии записывается в память разбором и переносится во все следующие попытки. То есть смещения из LLM as Judge — предпочтение машинного текста, самоуверенность без калибровки — здесь не усредняются, а закрепляются. На задачах, где есть объективная проверка — компиляция, юнит-тесты, результат в среде, — Evaluator берётся из среды и не врёт. На открытых задачах его роль исполняет та же модель, и тогда петля наследует все искажения судьи (LLM as Judge): агент может уверенно «отрефлексировать» себя в неверный ответ и закрепить его в памяти.

Что измерено в исходной статье

Shinn et al., 2303.11366. Прирост есть, но он не универсален, и это видно по самим таблицам.

Бенчмарк Reflexion Базовый GPT-4
HumanEval, Python 91% pass@1 80%
HumanEval, Rust 68% 60%
MBPP, Python 77,1% 80,1%
MBPP, Rust 75,4% 70,9%
LeetcodeHardGym 15% 7,5%

Строка MBPP на Python — единственная, где Reflexion проигрывает базовой модели, и она полезнее остальных: приём не бесплатный, и там, где первая попытка и так близка к потолку, лишний цикл разбора скорее уводит в сторону, чем помогает.

На последовательных задачах отрыв устойчивее. ALFWorld: 130 задач из 134, причём качество продолжает расти на протяжении двенадцати попыток, тогда как обычный ReAct выходит на плато уже к шестой-седьмой. Число не сопоставимо напрямую с 71% у ReAct на том же бенчмарке: там успех за один проход, здесь — сходимость за двенадцать попыток. Разница куплена бюджетом, и при сравнении методов трайл-бюджет надо называть наравне с процентом. На HotpotQA — около 20 процентных пунктов прироста на выборке из ста вопросов.

Где ломается

Авторы называют ограничения прямо, и оба сводятся к природе приёма.

Оптимизация в тексте застревает в локальных минимумах. Разбор — это шаг оптимизации политики, выраженный словами; он двигает агента в сторону, которая кажется правильной по последней неудаче, и ничто не мешает этому направлению быть тупиковым. Накопленные разборы усиливают эффект: агент раз за разом чинит одно и то же, вместо того чтобы попробовать другой подход.

Задачи, требующие разнообразия и исследования, приём не вытягивает — показано на WebShop. Причина та же: рефлексия улучшает уже выбранную линию поведения, но не заставляет искать принципиально другую.

Практический вывод для проектирования: Reflexion уместен там, где есть дешёвая объективная проверка результата и небольшое число осмысленных попыток. Где проверки нет, петля превращается в дорогой способ убедить себя в первом же ответе; где вариантов много и они непохожи, дешевле запустить несколько независимых попыток, чем итеративно чинить одну.

Третий уровень: когда попытки перестают различаться

Локальный минимум из раздела выше — не только свойство накопленных разборов. Он возникает и без них: если давать модели одну и ту же задачу заново, ответы будут выглядеть разными, а решением окажется одно и то же, пересказанное другими словами. Показательная проверка — попросить рассказать анекдот пять раз подряд: к пятому разу видно, что менялись место действия и действующие лица, а устройство шутки то же.

Для агента это означает, что внешний цикл попыток упирается в потолок, которого не видно: попытки идут, бюджет тратится, разнообразия нет.

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

Существенно, чем это отличается от соседних приёмов, с которыми легко спутать:

  • не сброс контекста — тот убирает историю рассуждений, оставляя результаты работы на месте, и потому колею не разрывает (Context Window);
  • не уплотнение — оно сохраняет ту же линию в сжатом виде, то есть закрепляет её;
  • не Reflexion — тот переносит вперёд вывод из неудачи, то есть усиливает выбранное направление, а здесь направление намеренно теряется.

Область применимости узкая и названа прямо: задачи, где исследовать надо в разные стороны и заранее неизвестно, какая верна, — то самое, на чём Reflexion, по замерам его же авторов, не вытягивает. На задаче с одним правильным ответом и дешёвой проверкой приём только тратит время.

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

Чем отличается от соседних паттернов

  • Generator Evaluator — критику даёт другая роль или модель, и цикл идёт внутри одной задачи; в Reflexion разбор пишет сам агент и переносит его в следующую попытку.
  • Validation Loops — проверка детерминированная (схема, тип, правило) и чинит конкретное поле; Reflexion работает со стратегией целиком и опирается на текстовый разбор.
  • Лимит попыток здесь — не предохранитель от зацикливания, как в ReAct, а параметр метода: именно за эти попытки и происходит улучшение.

Связано с

  • ReAct — внутренний цикл, поверх которого надстраивается внешний цикл попыток
  • Generator Evaluator — критика отдельной ролью против самокритики
  • LLM as Judge — чем оценивать траекторию, когда объективной проверки нет
  • Validation Loops — детерминированная проверка как более дешёвая альтернатива
  • Context Compaction — почему буфер разборов ограничен единицами записей
  • Agent CostControl — каждая попытка оплачивается целиком, лимит попыток это статья бюджета
  • Context Window — сброс контекста как соседний приём: убирает историю, но не колею