3,583 papers
arXiv:2609.33987 78 27 сент. 2026 г. FREE

Opera: критик-наблюдатель для кодовых агентов, который ведёт замечания как задачи в трекере

КЛЮЧЕВАЯ СУТЬ
Проблема: кодовый агент в длинной сессии ходит по кругу, правит не тот файл и пишет «готово», ничего не проверив. Метод Opera позволяет ловить такие сбои на ходу: второй чат следит за агентом и выдаёт ему замечания строго по одному. Фишка: вопросы «агент выполнил совет?» и «проблема ушла?» проверяются отдельно. Добавил проверку и тест всё равно падает? Значит, совет выполнен, а проблема осталась. Каждое замечание — это постоянная заметка с доказательствами, следующим шагом и критерием закрытия, который не меняется. Одна заметка, один критерий, закрытие только по фактам. Никаких списков из десяти советов.
Адаптировать под запрос
⚡

TL;DR

Opera — схема, в которой второй LLM следит за работой кодового агента и выдаёт ему замечания по одному. Каждое замечание оформляется как постоянная заметка с доказательствами, конкретным следующим шагом и критерием закрытия, который не меняется. Заметка живёт, пока проблема реально не исчезнет. Критик смотрит на агента по таймеру (каждые k шагов) и по событиям: застрял, повторяет одно и то же, ошибка инструмента, объявил «готово», отдаёт финальный патч. Он вправе промолчать.

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

Метод закрывает эти дыры тремя ходами. Первый: критик называет проблему по типу из фиксированного списка из 9 типов (поиск, чтение, правка, тест, сдача). Каждый тип описан контрактом: когда применим, какие нужны доказательства, что можно просить, когда считается решённым, что исключено. Второй: замечание сначала проходит аудит («доказательства подтверждают диагноз? правка нужна?»), и только потом уходит агенту. Третий: «агент попробовал» и «проблема решена» проверяются отдельно, а закрыть заметку можно только по доказательствам.

🔬

Схема метода

ТРИГГЕР:  каждые k шагов ИЛИ событие (idle / repeat / error / claim / submission)
   ↓
ШАГ 1: Критик смотрит задачу + историю + открытую заметку
        → "continue" (молчать) ИЛИ одна проблема + тип (оператор)
   ↓
ШАГ 2: Замечание: тип, доказательства, где, что сейчас, что изменить,
        как проверить → кандидат на заметку
   ↓
ШАГ 3: АУДИТ допуска: доказательства подтверждают диагноз? правка нужна?
        проверка сможет показать решение? → принять / отклонить (без переписывания)
   ↓
ШАГ 4: Заметка уходит агенту (не больше ОДНОЙ открытой заметки)
   ↓
ШАГ 5: Следующий обзор: Попытка? (по фактам действий) отдельно от Решено? (по критерию)
        → решено + аудит закрытия → заметка закрыта, из контекста убрана
        → не решено → уточнить совет, критерий тот же

Критик и агент — разные запросы. В оригинале это код-обвязка вокруг агента. Вручную это два чата или субагент.

🚀

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

Задача: Вы фрилансер и дорабатываете интернет-магазин на Python. Агент в Cursor или Claude Code чинит расчёт стоимости доставки через API СДЭК. Он 20 шагов правит shipping.py, дважды запускал один и тот же падающий тест, а потом пишет «Готово, всё исправлено». Тесты по пустой корзине и по ПВЗ без тарифа он не запускал. Вы вставляете лог сессии во второй чат с критиком.

Промпт:

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

Задача агента: починить расчёт стоимости доставки СДЭК в магазине (shipping.py). Требование: корректная цена для ПВЗ и курьера, пустая корзина возвращает ошибку валидации, а не 500.

Триггер обзора: агент объявил "готово" (Claim).

Открытая заметка: нет.

История сессии:
[вставьте лог агента: команды, вывод тестов, правки]

Правила:
1. Если агент движется нормально — ответь только: continue.
2. Иначе выбери ОДНУ проблему и один тип из списка (ниже).
3. Каждое утверждение подкрепи цитатой из лога.
4. Не предлагай необязательных улучшений.

Формат замечания:
- Тип:
- Доказательства (цитаты из лога):
- Где:
- Что происходит сейчас:
- Что нужно изменить (минимально):
- Как проверить:
- Критерий решения (фиксированный, не менять):

Типы: submission_readiness_review (объявил готовность без доказательств), minimal_repro_or_focused_verifier (нет проверки, нужной для следующего решения), requirement_contract_review (нарушено требование), diff_scope_review (лишние или недостающие правки), и остальные из шаблона.

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

🧠

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

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

Сильная сторона. LLM хорошо работает по узкой схеме: найти в логе доказательство, отнести его к типу, назвать минимальное исправление. Ещё надёжнее она проверяет готовый тезис («доказательства подтверждают диагноз?»), чем придумывает его.

Как метод это использует. Он режет задачу критика на узкие проверки: тип проблемы с контрактом, один вопрос за раз, отдельный аудит, фиксированный критерий. Критерий не плывёт вслед за последним советом, поэтому «закрыто» значит «исходная проблема ушла».

Рычаги управления: - k (частота обзоров) → меньше для длинных рискованных задач, больше для простых (экономия токенов). - Список событий-триггеров → добавь свои (например, «агент правит файл вне заявленной области»). - Список типов проблем → подгони под свой стек: для вёрстки, аналитики, текстов замени типы по этапам вашей работы. - Право на «continue» → уберёшь, и критик начнёт вмешиваться в нормальную работу. - Лимит «одна открытая заметка» → ослабь только если агент успешно справляется с несколькими правками сразу.

📋

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

В статье полного текста промптов нет (он в приложении). Шаблон ниже собран по описанию механики: типы с контрактами, одна проблема за раз, аудит, фиксированный критерий.


Ты — критик-наблюдатель за кодовым агентом. Ты не пишешь код и не выполняешь задачу. Ты читаешь трассу работы и решаешь: молчать или выдать ОДНО замечание.



Задача: {задача}
Триггер обзора: {periodic | idle | repeat | error | claim | submission}
История работы агента: {лог / трасса}
Открытая заметка: {текст заметки или "нет"}



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

Поиск:
- repo_localization_search — цель ещё не найдена
- implementation_target_shift — агент правит не то место
Чтение:
- implementation_readiness_review — агент перечитывает код, хотя исправление уже ясно
- failure_signature_triage — неверно понят вывод инструмента или ошибки
Правка:
- requirement_contract_review — нарушено требование задачи
- diff_scope_review — не хватает нужных правок или есть лишние
- state_transition_review — неверная логика выполнения
Тест:
- minimal_repro_or_focused_verifier — нет доказательства, нужного для следующего решения
Сдача:
- submission_readiness_review — "готово" заявлено без достаточных доказательств



1. Если нет открытой заметки:
   - Агент продвигается разумно → верни: continue
   - Иначе выбери ОДНУ проблему, один тип и минимально необходимое исправление.
2. Если есть открытая заметка:
   - Оцени отдельно:
     Попытка: пытался ли агент выполнить совет? (по действиям в логе)
     Решение: ушла ли исходная проблема по ФИКСИРОВАННОМУ критерию заметки? (по результатам запуска или видимым правкам)
   - Решено → предложи закрыть и укажи доказательства.
   - Не решено → можешь уточнить совет, но критерий НЕ менять.
3. Не вмешивайся ради необязательных улучшений.
4. Не повторяй уже данный совет без новых доказательств.



Тип:
Доказательства (цитаты из трассы):
Где:
Что происходит сейчас:
Что изменить (минимально):
Как проверить:
Критерий решения (фиксированный):



Перед выдачей перепроверь себя:
- Доказательства из трассы реально подтверждают диагноз?
- Исправление необходимо для задачи?
- Предложенная проверка может показать, что проблема решена?
- Это не дубль прежней заметки?
Если хоть один ответ "нет" — верни: continue.

Подставляйте: {задача} — исходное требование к агенту; {лог / трасса} — вывод сессии; {текст заметки} — замечание из прошлого обзора (на первом обзоре — «нет»).

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

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

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

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

⚠️

Ограничения

⚠️ Критик не заменяет способности агента: слабая модель с длинной сложной задачей не решила ни одной задачи ни с критиком, ни без него. Выигрыш там, где агент достаточно умён, чтобы выполнить совет, но сам своих ошибок не замечает.

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

⚠️ Сильный агент выигрывает мало: где модель и так решает почти всё, критик добавляет единицы процентов, а лишнее вмешательство может испортить удачную траекторию.

⚠️ В оригинале это код: критик подключён к обвязке агента и сам получает трассу, срабатывает по событиям и хранит заметки. Вручную нужно самому вставлять логи и переносить замечания. Автоматические триггеры и отдельный аудитор в чате придётся имитировать.

⚠️ Критик тоже ошибается: диагноз может быть правдоподобным, но неверным. Поэтому в метод встроены аудит и право молчать. Слепо доверять критику нельзя.

⚠️ Данные неполные: в доступном тексте нет полного анализа (раздел 5) и приложений с самими промптами. Шаблон выше — реконструкция по описанию.

🔍

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

Команда Salesforce проверила Opera на трёх бенчмарках кодовых агентов: Terminal-Bench 2.1 (89 задач), срез SWE-Bench Pro (100 задач) и DeepSWE v1.1 (113 задач). Агентами выступили четыре разные модели в трёх разных обвязках. Критиком по умолчанию взяли сильную закрытую модель, но проверяли и слабых критиков, и агента, критикующего самого себя. Против Opera поставили агента без критика и четыре известных критика: два следят за ходом работы (SWE-PRM, SWE-Search), два оценивают готовое решение (LLM-as-verifier, Agentic Rubrics). Первых для честности поставили на то же расписание обзоров.

Opera получила лучший средний результат на всех трёх бенчмарках. На агенте Qwen3.8-27B она подняла долю решённых задач с 65,9% до 73,8% на Terminal-Bench, а на DeepSWE с 32,4% до 41,3%. Самый большой прирост дала слабой модели Qwen3.5-9B (+12,4 и +15,0 пункта). Сильная DeepSeek-V4-Flash выросла на единицы пунктов там, где уже была хороша, и заметно на трудном DeepSWE. Закономерность: чем больше у агента запаса для исправления, тем полезнее критик. Но если агенту не хватает способностей, критик не поможет.

Отдельная часть работы про обучение. Опера-сессии (действия студента + замечания критика) использовали как данные для дообучения маленькой модели и сравнили с обучением на траекториях модели-учителя. На целевой задаче результат одинаков (около +10 пунктов). На другом бенчмарке обучение на траекториях учителя обрушило результат с 23,6% до 7,9%, а данные с Opera сохранили его (25,8%). Причина: в этих данных все действия принадлежат самому студенту, а критик влияет только через заметки в контексте. Для читателя этот кусок справочный: обучать модели он не будет.

💡

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

🔧 Техника: перенести правила критика в файл инструкций агента → агент сам себя проверяет

Самую дешёвую часть метода можно положить прямо в CLAUDE.md или AGENTS.md. Это не оригинальная схема с отдельным критиком, а перенос её принципов:

Перед тем как написать "готово":
1. Выпиши исходные требования списком.
2. Для каждого требования покажи доказательство: вывод запущенного теста или конкретную правку.
3. Если доказательства нет — это не готово, запусти проверку.
Если ты дважды подряд делаешь одно и то же действие с тем же результатом — остановись и смени подход, назвав, что именно не работало.

🔧 Техника: убрать «одну заметку» и добавить свой список типов → критик для не-кода

Для маркетинговых агентов или аналитики замените 9 типов своими по этапам работы (сбор данных → вывод → отчёт → отправка). Для каждого оставьте контракт: когда применим, какие нужны доказательства, когда решено, что исключено.

🔗

Ресурсы

  • Opera: A Verbal Critic Framework for Long-horizon Coding Agents — Salesforce AI Research (препринт). Имена авторов в предоставленном тексте не указаны.
  • Базовые работы, на которые опирается статья: Self-Refine (Madaan et al., 2023), Reflexion (Shinn et al., 2023), CRITIC (Gou et al., 2023), SWE-PRM (Gandhi et al., 2025), SWE-Search (Antoniades et al., 2024), Agentic Rubrics (Raghavendra et al., 2026).
  • Принцип контрактов операторов: Design by Contract (Meyer, 1992).
  • Бенчмарки: Terminal-Bench 2.1, SWE-Bench Pro, DeepSWE v1.1.

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

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

Проблема: кодовый агент в длинной сессии ходит по кругу, правит не тот файл и пишет «готово», ничего не проверив. Метод Opera позволяет ловить такие сбои на ходу: второй чат следит за агентом и выдаёт ему замечания строго по одному. Фишка: вопросы «агент выполнил совет?» и «проблема ушла?» проверяются отдельно. Добавил проверку и тест всё равно падает? Значит, совет выполнен, а проблема осталась. Каждое замечание — это постоянная заметка с доказательствами, следующим шагом и критерием закрытия, который не меняется. Одна заметка, один критерий, закрытие только по фактам. Никаких списков из десяти советов.

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

Критик не пишет код. Он читает журнал работы агента и решает: молчать или выдать одно замечание. Работает это как процесс: 1. Сигнал. Обзор запускается каждые k шагов. Или по событию: агент застрял, повторяется, получил ошибку, заявил «готово», сдаёт патч. 2. Диагноз. Критик выбирает одну проблему и один тип из фиксированного списка из 9 типов: поиск, чтение, правка, тест, сдача. У каждого типа есть контракт: когда применим, какие нужны доказательства, что можно просить, когда считается решённым, что исключено. 3. Аудит. Замечание проверяется до отправки: доказательства подтверждают диагноз? Правка вообще нужна? Проверка покажет решение? Если хоть один ответ «нет», критик молчит. 4. Закрытие. На следующем обзоре критик отдельно отвечает на два вопроса: пытался ли агент и ушла ли проблема по исходному критерию. Открытая заметка может быть только одна, а критерий её закрытия нельзя переписывать. Это как задача в трекере: нельзя закрыть её словами «я старался», нужен результат.

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

Обычный критик ломает дело с двух сторон. Он принимает промежуточный шаг за ошибку, потому что видит незавершённую работу. Или сыплет общими советами вроде «подумай про граничные случаи», за которые агенту нечем зацепиться. Opera использует то, что LLM хорошо делает по узкой схеме. Найти в журнале цитату, отнести её к типу, назвать минимальное исправление. Проверить готовый тезис («доказательства подтверждают диагноз?») модель умеет надёжнее, чем придумать его с нуля. Поэтому один широкий вопрос «что не так?» разрезан на несколько узких. Критерий замораживается в момент выдачи замечания, поэтому «закрыто» значит «исходная проблема ушла», а не «последний совет выполнен». Честно про цифры. Над другими критиками метод впереди всего на пару процентных пунктов. На одном бенчмарке разрыв меньше разброса между запусками. Основной выигрыш даёт сам хорошо устроенный критик, а не волшебство конкретной схемы. Слабому агенту критик не поможет. Сильному даёт единицы процентов, а лишнее вмешательство может испортить удачную траекторию.

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

Разработка с агентом (Cursor, Claude Code и похожие) → длинные сессии на 20+ шагов, особенно когда агент повторяет один и тот же падающий тест или объявляет «готово» без запуска нужных проверок. Схему можно перенести на другие многошаговые задачи: вёрстку, аналитику, тексты. Для этого замени типы проблем на этапы своей работы. НЕ подходит для коротких задач на 3-5 шагов: обвязка дороже выгоды. Не поможет и слабой модели на сложной задаче: если агент не может выполнить совет, критик ничего не изменит.

Мини-рецепт

1. Заведи два чата: один у агента, второй у критика. В оригинале это код-обвязка, вручную придётся самому переносить журнал и замечания.
2. Выбери момент обзора: агент написал «готово», повторил одно и то же дважды или поймал ошибку инструмента. Для длинных рискованных задач смотри чаще, для простых реже.
3. Вставь критику четыре вещи: задачу, причину обзора, журнал работы и открытую заметку (или слово «нет»).
4. Дай право молчать: «Если агент движется нормально, ответь только: continue». Уберёшь это правило, и критик начнёт лезть во всё подряд.
5. Потребуй формат: тип, доказательства-цитаты, где, что сейчас, что изменить минимально, как проверить, критерий решения.
6. Прогони аудит: попроси критика самого проверить замечание. Цитаты подтверждают диагноз? Правка нужна? Не дубль ли это? Хоть одно «нет» означает, что замечание не отправляется.
7. Передай агенту только заметку и не больше одной за раз.
8. Вставь новый журнал на следующем обзоре: попроси отдельно оценить «Попытка?» и «Решено?». Решено — закрываем. Не решено — уточняем совет, но критерий не трогаем.
9. Подгони типы под себя: попроси LLM адаптировать список типов проблем под твой стек и частые сбои.

Примеры

[ПЛОХО]: `Проверь работу агента и дай рекомендации по улучшению кода` [ХОРОШО]: `Ты критик кодового агента. Код не пишешь. Задача агента: починить расчёт доставки СДЭК в shipping.py, пустая корзина должна давать ошибку проверки, а не 500. Причина обзора: агент написал «готово». Открытая заметка: нет. Журнал: [вставь]. Если всё идёт нормально, ответь только: continue. Иначе выбери ОДНУ проблему и один тип (например, submission_readiness_review). Каждое утверждение подкрепи цитатой из журнала. Формат: тип, доказательства, где, что сейчас, что изменить минимально, как проверить, критерий решения (фиксированный).` Вместо десяти советов приходит одно замечание: «готовность заявлена без доказательств, тест по пустой корзине не запускался». К нему прилагается критерий: этот тест проходит. [ПЛОХО]: `Агент сказал, что добавил проверку. Значит, проблема решена?` [ХОРОШО]: `Вот новый журнал и заметка. Ответь отдельно. Попытка: делал ли агент то, что просили (по действиям в журнале)? Решение: ушла ли исходная проблема по критерию из заметки (по результату запуска)? Критерий не меняй.`
Источник: Opera: A Verbal Critic Framework for Long-horizon Coding Agents
ArXiv ID: 2609.33987 | Сгенерировано: 2026-10-14 23:40

Проблемы LLM

ПроблемаСутьКак обойти
Модель выполнила совет, а проблема осталасьДаёшь модели замечание: «добавь проверку». Она добавляет и пишет «готово». Тест при этом всё ещё падает. «Сделал, что просили» и «проблема ушла» — разные вещи. Второй проверяющий часто смотрит только на первое. Ещё хуже, когда он сам подгоняет критерий под последний совет. Тогда «закрыто» ничего не значит. Это касается любых долгих задач с правками: код, тексты, анализЗапиши критерий решения один раз, в момент замечания. Например: «тест на пустую корзину проходит». Дальше не меняй его. При проверке отвечай на два вопроса отдельно. «Пытался?» — по действиям. «Решено?» — по критерию и результату. Если не решено, уточняй совет, но не критерий

Методы

МетодСуть
Замечание-заметка с неизменным критерием закрытияКаждое замечание оформляй как заметку в трекере. Поля: Тип, Доказательства (цитаты), Где, Что сейчас, Что изменить (минимально), Как проверить, Критерий решения (не менять). На каждом следующем обзоре задавай два вопроса отдельно: «Попытка?» и «Решено?». Закрывай заметку только по доказательствам. Держи не больше одной открытой заметки. Почему работает: критерий не плывёт за последним советом, поэтому «закрыто» значит «исходная проблема ушла». Одна заметка не даёт исполнителю разбрасываться. Когда да: долгая работа с несколькими итерациями, например код, редактура, анализ данных. Когда нет: разовый короткий ответ
Узкий критик: тип проблемы, цитата, проверка допуска, право промолчатьКритик получает задачу, журнал работы и открытую заметку. Ответ у него один из двух: continue (молчу) или ОДНА проблема. Проблему он выбирает из фиксированного списка типов. У каждого типа есть контракт: когда применим, какие нужны доказательства, что можно просить, когда решено, что исключено. Пример типов: цель не найдена, правит не то место, нарушено требование, нет нужной проверки, «готово» без доказательств. Каждое утверждение подкрепляй цитатой. Перед выдачей критик отвечает себе на вопросы. Доказательства подтверждают диагноз? Правка нужна? Проверка покажет решение? Это не дубль? Если хоть одно «нет», он пишет continue. Почему работает: модель надёжно ищет в журнале доказательство и относит его к типу. Проверить готовый тезис ей проще, чем придумать его с нуля. Право промолчать защищает от шума: незаконченную работу критик не примет за ошибку. Как применить: подгони список типов под свой процесс, например для вёрстки или текстов. Вставляй журнал во второй чат или в отдельного субагента. Критик и исполнитель должны быть разными запросами. Когда нет: короткие задачи, где исполнитель и так справляется. Лишнее вмешательство только мешает

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

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

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