CodeRescue: как код-агенту решить, когда попробовать ещё раз, а когда звать GPT-5.4

CodeRescue: как код-агенту решить, когда попробовать ещё раз, а когда звать GPT-5.4

Когда ваш код-агент тратит два доллара на попытку решить задачу, получает Wrong Answer и молча повторяет ту же ошибку ещё пять раз — вы платите не за вычисления, а за отсутствие решения. Современные код-агенты умеют запускать тесты, читать stderr и итерировать, но почти никто из них не отвечает на вопрос: а что именно делать после провала — подумать ещё, переформулировать или позвать модель подороже?

Исследование CodeRescue (arXiv, июль 2026) формализует этот момент как задачу обучения с учителем и показывает, что один обученный роутер может заменить жёсткую стратегию «сначала дешёвая, потом дорогая» — и при этом давать гарантии по бюджету без единого ретрейна.

В чём проблема cascade-подхода

Большинство cost-aware систем работают по принципу каскада: сначала вызови дешёвую модель, а если она не справилась — эскалируй к сильной. Это FrugalGPT, RouteLLM, AutoMix — все они решают задачу «до генерации»: какую модель выбрать для данного входа. Но в код-агентах ситуация другая. Здесь уже есть выполнение, уже есть вердикт (wrong answer, timeout, compile error) и уже есть stderr. Дешёвая модель не просто «не справилась» — она оставила диагностический след, который можно использовать для решения следующего шага.

CodeRescue вводит понятие recovery routing: после неудачной попытки роутер получает тройку (условие задачи, вердикт исполнения, трассу ошибки) и выбирает одно из трёх гетерогенных действий — reflect (переосмыслить текущий код), replan (написать заново с новым подходом) или escalate (передать более сильной модели). Ключевое наблюдение: дешёвое восстановление и эскалация имеют комплементарные паттерны успеха. Есть задачи, которые GPT-5.4-nano решает после reflect, но не решает даже GPT-5.4 — и наоборот.

Архитектура роутера и конкретные цифры

Роутер — это классификатор, обученный на rollout'ах. Для каждой неудачной попытки из пяти бенчмарков (APPS, TACO, BigCodeBench, LiveCodeBench, CodeContests) собирается множество успешных действий S(x), и меткой становится cheapest successful action — самое дешёвое действие, которое привело к решению. Задачи, где ни одно действие не сработало, исключаются из обучения.

Вход роутера — это не просто текст задачи, а структурированный recovery context: условие, тип ошибки и stderr. Это принципиально отличает его от pre-generation роутеров вроде Weave или Fugu, которые видят только запрос и решают по нему. Здесь же роутер опирается на диагностическую информацию, недоступную до исполнения.

Выходы — нормализованные вероятности трёх действий, из которых при деплое вычитается штраф за стоимость, умноженный на коэффициент λ. Меняя λ, можно двигаться по frontier'у «solve rate vs cost» — без переобучения модели.

Конкретные цифры из работы показывают масштаб экономии. В таблице базовых стратегий (Table 1) средние затраты на восстановление для GPT-5.4-nano/GPT-5.4 составляют: always-reflect — 1.24 миллидоллара на задачу, always-replan — 1.59 миллидоллара, always-escalate — 7.22 миллидоллара. CRC-калиброванная рабочая точка (argmax без ограничений) даёт 5.51 миллидоллара — это 76% от стоимости always-escalate при сопоставимом solve rate. На одном из CRC-оператинг-поинтов работа показывает 35% от средней стоимости восстановления при сохранении solve rate уровня always-escalate.

Это не просто «дешевле на 20-30%». Это качественное изменение экономики: если ваш агент обрабатывает 1000 задач в день, переход с always-escalate на CRC-роутер экономит примерно 1.7 миллидоллара в день, или $51 в месяц. Для production-систем с тысячами агентных прогонов это существенная разница.

Почему комплементарность действий работает

Самое интересное наблюдение — структура успешных действий. Анализ 720 задач из калибровочного и тестового множеств показывает, что примерно треть задач решаются только дешёвыми действиями (reflect или replan), треть — только эскалацией, и треть — обоими способами. Это означает, что нет универсальной стратегии: для одних задач достаточно поправить код, для других нужна более мощная модель, а для третьих работают оба подхода.

На APPS и TACO, где задачи более шаблонные (парсинг, сортировка, динамическое программирование), дешёвое восстановление выигрывает: модель видит stderr, понимает ошибку и исправляет её за 1-2 итерации. На LiveCodeBench и CodeContests, где задачи требуют нетривиальных алгоритмических идей (графы, комбинаторная оптимизация, сложная математика), дешёвое восстановление чаще не срабатывает: если модель не увидела идею с первого раза, несколько reflect-шагов не помогут — нужен качественный скачок, который даёт более мощная модель.

Роутер учится распознавать эти паттерны. Когда stderr показывает банальную ошибку (ошибка индекса, неправильный тип данных), он выбирает reflect. Когда ошибка указывает на фундаментальную проблему с алгоритмом (timeout, memory limit exceeded), он сразу эскалирует. Это не эвристика — это обученная модель, которая оптимизирует ожидаемую стоимость.

Conformal Risk Control: гарантии без ретрейна

Самая практичная часть работы — это CRC-слой. Conformal Risk Control позволяет задать целевой бюджет B и получить гарантию: средний расход на восстановление не превысит B с заданной вероятностью. Калибровка происходит по холд-аут множеству за O(1) операций — не нужно переобучать роутер при изменении бюджета.

Это решает реальную боль production-систем: вчера бюджет был $50 на агентный прогон, сегодня $20, завтра $100 — и каждый раз перестраивать пайплайн? CRC даёт один обученный роутер и множество рабочих точек. В главном эксперименте (GPT-5.4-nano как дешёвая модель, GPT-5.4 как дорогая) одна CRC-калиброванная точка превышает solve rate always-escalate, используя при этом 35% от средней стоимости восстановления.

Что показывают эксперименты

Бенчмарки охватывают весь спектр: от interview-level (APPS) до competitive programming (CodeContests). На каждом из них дешёвое восстановление и эскалация дополняют друг друга. Роутер, обученный на разметке «cheapest successful action», превзошёл три базовых подхода — always-reflect, always-escalate и prompt-only роутер (где LLM сама выбирает, что делать, без обучения).

Наиболее интересный результат — на LiveCodeBench и CodeContests, где задачи требуют нетривиальных алгоритмических идей. Здесь cheap recovery чаще не срабатывает: если модель не увидела идею с первого раза, несколько reflect-шагов не помогут. Роутер учится это распознавать и сразу эскалирует. А на APPS и TACO, где задачи более шаблонные, reflect и replan выигрывают у эскалации по стоимости при сопоставимом качестве.

Почему это важно для инженерии агентов

Практический вывод: если вы строите код-агента с multi-step execution, жёсткий cascade — не оптимальная стратегия. Лучше обучить роутер на собственных rollout'ах, используя diagnostic feedback (stderr, вердикт) как признак, и обернуть его в CRC для гибкого контроля бюджета. Это не требует новой модели, не требует переразметки и не требует RL — достаточно supervised learning на уже собранных траекториях исполнения.

Стоит отметить ограничения работы: CRC-гарантии выполняются при условии exchangeability (обменимости) данных, что в production может нарушаться при дрейфе задач. Также роутер обучается на одном наборе дешёвая/дорогая пара — смена пары моделей требует нового набора rollout'ов, хотя сам CRC-слой переносится.

Часто задаваемые вопросы

Чем CodeRescue отличается от обычного cascade «сначала GPT-4o-mini, потом GPT-5.4»?

Cascade принимает бинарное решение — escalate или нет. CodeRescue принимает решение из трёх действий: reflect (исправить текущий код), replan (написать заново) или escalate. Это даёт больше возможностей для дешёвого восстановления, и роутер учится, когда какое действие оптимально.

Нужен ли RL для обучения роутера?

Нет. Роутер обучается через supervised learning на rollout'ах, где метка — самое дешёвое успешное действие. Это проще, стабильнее и не требует reward model.

Работает ли это с открытыми моделями, а не только с OpenAI?

В работе использовались GPT-5.4-nano и GPT-5.4, но метод универсален: нужна любая пара «дешёвая + дорогая» модель с execution environment. Qwen-Plus и Qwen-Max, DeepSeek-V3-Lite и DeepSeek-R1 — принцип тот же.

Как быстро пересчитывается CRC при смене бюджета?

Калибровка CRC — это сортировка и квантиль на холд-аут множестве. Занимает миллисекунды. Новый бюджет → новый λ → новая рабочая точка без ретрейна.

Ablation и кросс-модельная проверка

Аблационное исследование (Table 2) показывает, что каждый компонент вносит вклад. Удаление метаданных (вердикт и stderr) из входа снижает accuracy роутера с 0.697 до 0.656 — это 6 процентных пунктов, что подтверждает: диагностическая информация критически важна. Soft-лейблинг (взвешенное копирование по всем успешным действиям вместо одного cheapest) даёт 0.653, что чуть хуже hard-лейблинга. Это означает, что для обучения роутера лучше чётко указывать «самое дешёвое успешное действие», чем размывать метку по всем вариантам.

Кросс-модельная проверка на паре Gemini (Table 4, n=229) подтверждает переносимость подхода: роутер, обученный на данных одной модели, работает и на другой. Это важно для production: вы можете собрать rollout'ы на одной паре моделей и перенести роутер на другую без полного пересбора.

Ещё один интересный результат — из Figure 4 (CRC frontiers на TACO difficulty ladder). На лёгких задачах TACO escalation работает монотонно — чем сильнее модель, тем лучше. Но на сложных подмножествах кривая становится немонотонной: escalation в среднем ухудшает результат для этой подпопуляции. Это контринтуитивный вывод — иногда сильная модель хуже справляется, потому что она «переусложняет» простые задачи, тратя вычислительный бюджет на ненужную рефлексивность.

Ограничения и что дальше

Стоит отметить несколько ограничений работы. CRC-гарантии выполняются при условии exchangeability (обменимости) данных, что в production может нарушаться при дрейфе задач — если ваш агент начинает получать принципиально новые типы задач, калибровка устаревает. Также роутер обучается на одном наборе дешёвая/дорогая пара — смена пары моделей требует нового набора rollout'ов, хотя сам CRC-слой переносится.

Перспективное направление — объединение CodeRescue с multi-step recovery, где роутер работает не один раз, а на каждой итерации восстановления. Текущая работа рассматривает одношаговое решение, но реальные агенты делают 3-5 попыток, и каждая следующая решение могла бы использовать обновлённый контекст. Это требует dynamic routing, а не статического классификатора — задача следующего поколения.

Итог

CodeRescue показывает, что для код-агентов «неудача» — это не бинарный сигнал, а структурированная диагностическая информация, которую можно использовать для обучения роутера между гетерогенными действиями. CRC-слой превращает одного обученного роутера в семейство бюджетных конфигураций. Для production-агентов это означает: вместо жёсткого cascade — обученная стратегия восстановления, которая экономит 65% стоимости при той же solve rate.

Если вы строите агента, который исполняет код и итерирует — обратите внимание на diagnostic feedback как признак для роутинга. Это бесплатный сигнал, который уже есть в вашем пайплайне, и CodeRescue показывает, как его использовать. Код открыт на GitHub (github.com/Qijia-He/agent-budget-control) под лицензией CC BY 4.0 — можно интегрировать в свой stack уже сегодня.

← Все записи