Вкратце
В рамках нашего более широкого внимания к оптимизации агентов мы опубликовали исследование, демонстрирующее эффективность как горизонтальных, так и вертикальных стратегий масштабирования для SWE-агентов. Однако в наших экспериментах мы традиционно применяли единый вычислительный бюджет для всех задач, как будто каждая задача имеет одинаковую сложность.
Но за пределами контролируемой лабораторной среды это предположение не оправдывает себя.
На самом деле мы знаем, что сложность задач следует распределению с тяжелым хвостом: значительная часть задач решается с низкими затратами усилий, в то время как другие требуют большого бюджета. Например, в предыдущем посте, в котором подробно описывались наши усилия по достижению передового результата на SWE-rebench, мы обнаружили, что примерно 50% задач, взятых из этого бенчмарка, решаются одним прогоном GPT-5.2, хотя наша первоначальная политика предусматривала пять прогонов для каждой из них. Это деньги, которые остаются неиспользованными.
В момент, когда так много компаний изучают свое потребление токенов и ищут способы сократить расходы, мы представляем наше последнее исследование: стратегии выполнения задач с учетом бюджета, которые могут быть адаптированы в соответствии со сложностью задачи, чтобы вы тратили больше только тогда, когда это необходимо. Продолжая нашу работу над SWE-rebench, мы показываем, как каскадные и параллельные стратегии выполнения задач, обе в сочетании с ранним остановлением, позволяют вам оптимизировать затраты или скорость, сохраняя при этом качество; каскадное выполнение экономит вам стоимость последнего прогона, а параллельное выполнение избавляет вас от времени ожидания последнего прогона, как показано на иллюстративной диаграмме ниже. В этом посте мы рассказываем, как мы разработали эти стратегии выполнения задач и какие результаты получили.
Обзор: наша существующая архитектура SWE-мультиагента
Прежде чем углубляться в эти стратегии выполнения задач, давайте сначала напомним архитектуру агента, с которой мы работаем (см. диаграмму ниже). Полный обзор можно найти в нашей предыдущей статье о том, как выбор правильной стратегии выполнения задач SWE-агента помог нам достичь передового результата на SWE-rebench, но вот основные моменты:
- Параллельная генерация: Для каждого запроса наш агент генерирует N кандидатских патчей (прогонов) параллельно, причем финальный шаг каждого прогона включает оценку самоуверенности. В то же время тестовый агент пишет и собирает тесты, которым должен удовлетворять правильный патч.
- Фильтрация: Любые кандидаты, которые не проходят собранные тесты, исключаются.
- Извлечение: Извлекается исходный код репозитория, относящийся к оставшимся кандидатам.
- Уменьшение: Агент выбирает один, окончательный кандидат из отфильтрованного и обогащенного контекстом пула.
Поскольку генерация прогонов является как доминирующей статьей расходов, так и параллелизуемой, это основной рычаг, с которым мы экспериментируем в этой работе, контролируя количество прогонов и порядок их выполнения.
Адаптация стратегий выполнения задач Best-of-N для задач SWE-агента
Работая с бенчмарками, такими как BrowseComp-Plus и DeepResearch-Bench, мы уже изучили различные стратегии выполнения задач, которые используют самоуверенность агента для принятия решения о том, сколько вычислительных ресурсов инвестировать в каждую задачу, включая:
- Каскадное выполнение с ранним остановлением (оптимизированное по стоимости): Начните с дешевых моделей и переходите к более дорогим только в случае их неудачи или низкой уверенности; экономия затрат от дешевого решения простых запросов компенсирует стоимость дорогой модели для сложных задач в длинном хвосте.
- Параллельное выполнение с ранним остановлением (оптимизированное по задержке): Запускайте все прогоны одновременно; как только идентифицируется приемлемый кандидат, любые прогоны, все еще находящиеся в процессе выполнения, могут быть немедленно остановлены. Это позволяет избежать оплаты завершений, которые никогда не будут использованы, и на запросах, которые решаются уверенно в начале.
В вышеуказанных стратегиях выполнения задач мы предполагали, что каждая кандидатская задача может быть оценена изолированно. Однако, как мы обнаружили в нашей последней публикации о SWE-rebench, выбор кандидата на основе только индивидуальных оценок самоуверенности заметно хуже, чем использование LLM Judge (также известного как селектор). Вместо анализа одного кандидата селектор рассматривает весь пул сгенерированных кандидатов вместе с соответствующим исходным кодом перед принятием окончательного решения.
Поскольку селектор опирается на это целостное представление, нам пришлось скорректировать наш подход. Мы больше не можем просто спрашивать: «Достаточно ли это индивидуальное решение, чтобы остановиться рано?» Вместо этого наши критерии принятия должны перейти к групповой динамике: «Имеем ли мы достаточно хороший пул кандидатов, с которым селектор может успешно работать?»
Прогнозирование производительности селектора
Это изменение меняет способ проверки нашей системы. Поскольку селектор принимает окончательное решение или синтез из коллективного пула, нам нужен способ уверенно предсказать, содержит ли этот пул достаточно сигнала для того, чтобы селектор мог дать хороший результат (единственное исключение — если список содержит только одного кандидата, в этом случае селектор не нужен вообще).
Мы обнаружили, что для информирования общего прогноза пригодности селектора нужны были два прогноза:
- Прогноз №1: Запуск селектора на списке кандидатов решит задачу. Мы назвали этот прогноз Resolve-Now (RN), рассчитанный с помощью специального классификатора — с калиброванным порогом p_target (p для точности) — который мы обучили для этой цели.
- Прогноз №2: Генерация большего количества кандидатов, а затем запуск селектора решит задачу. Мы назвали этот прогноз Resolve-Later (RL). Мы рассчитываем его, обучая другой классификатор предсказывать вероятность того, что селектор, работающий на большем пакете кандидатов, решит задачу, и вычитая из этого Resolve-Now, что дает нам оценку маржинального прироста от генерации еще одного пакета прогонов. Мы также обучаем калиброванный порог g (g для прироста) для него.
Если либо p_target, либо g проходят наш порог, мы рассматриваем это как сигнал, что в данный момент есть достаточно хороший список кандидатов. В этом случае мы останавливаем генерацию дополнительных прогонов и продолжаем нашу систему. Важно, что p_target и g — это параметры, с которыми мы можем экспериментировать в соответствии с нашими собственными критериями; например, повышение порога p_target или понижение порога g делает ранние остановки менее частыми, но более безопасными (более дорогими, но более точными).
Генерация большего сигнала
Однако мы обнаружили, что самоуверенность не является достаточно сильным сигналом для принятия решения о раннем остановлении задачи SWE. Нам нужно было сгенерировать некоторые дополнительные признаки для наших классификаторов, чтобы более уверенно принимать решение о раннем остановлении. Вот некоторые из признаков, которые мы разработали:
- Тестовый агент: Как упоминалось ранее, это агент, который работает одновременно с фазой параллельной генерации, пишет и собирает тесты, которым должен удовлетворять патч, и запускает их против каждого кандидата. Работая на основе меньшей, более дешевой модели (в данном случае GPT-5-Mini), его выход — сколько тестов пройдено или сколько кандидатов прошло все тесты — четкий, легко агрегируемый и дешевле, чем один дополнительный прогон.
- Согласованность патчей: Вариация в git-патчах, сгенерированных нашими прогонами.
- Согласованность поиска репозитория: Вариация и покрытие путей в репозитории, которые ищутся в наших прогонах.
- Другие метаданные: количество шагов, сделанных агентами, частота ошибок инструмента и другие метаданные.
Затем мы можем объединить их в вектор признаков и подать его нашим классификаторам для предсказания RN и RL. Самыми сильными среди этих признаков являются самоуверенность и тестовые признаки; однако даже эти признаки все еще посредственны, поскольку предсказать, является ли исправление SWE правильным, действительно сложно.
К счастью, нам не нужен идеальный классификатор, чтобы принимать успешные решения о остановке – нам нужен только калиброванный хвост.
Результаты
Часть I: Каскад с ранним остановлением (оптимизированный по стоимости)
Чтобы адаптировать вышеупомянутую каскадную стратегию к настройке агента SWE, мы выполнили следующие шаги:
- Предварительно определить последовательность из N значений (например, [1, 3, 5]).
- Запустить N=1 роллов и дождаться, пока он завершится.
- Оценить наши классификаторы RN и RL, чтобы решить, остановиться или сгенерировать больше запусков.
- Если классификаторы недостаточно уверены в том, чтобы остановиться, мы запускаем больше роллов, чтобы достичь нашего следующего значения N (N=3), снова оценивая наши классификаторы, чтобы решить, должны ли мы остановиться.
- Это «каскадирование» продолжается до тех пор, пока мы не остановимся или не достигнем нашего резервного максимального значения N, которое в данном случае равно 5.
Применяя стратегию каскадного выполнения к нашему агенту SWE с значениями N [1, 3, 5, 10], мы видим, что более 50% задач останавливаются досрочно, тратя лишь часть нашего полного бюджета:
Мы оценили наши результаты на том же срезе набора данных SWE-rebench, который мы использовали в нашей предыдущей работе над бенчмарком (декабрь 2025 — март 2026, 123 задачи, из которых мы выбрали обучающий набор данных и тестовый набор данных), сравнивая каждую стратегию с базовым вариантом, при котором всегда выполняется максимальное значение N.
Игры с порогами для RN и RL рисуют фронтир Парето, где каждая точка представляет собой разные компромиссы между стоимостью, задержкой и качеством. Оптимальные конфигурации, изученные на основе нашего обучающего набора данных, отмеченные на графиках ромбами, не работают идеально на нашем тестовом наборе данных, но все же демонстрируют хорошую обобщающую способность (то же качество и меньшая стоимость, чем у базового варианта), оставляя нам небольшой разрыв в обобщающей способности: как видно из точек с той же скоростью разрешения, что и ромбы, но падающих к их левому краю, что означает, что существуют возможные конфигурации, которые предлагают то же качество с меньшей стоимостью и задержкой.
Таким образом, с одной стороны, преимущества очевидны: мы достигаем идентичного качества, сокращая вычислительные затраты до 44%. С другой стороны, есть один нюанс: каскадирование обменивает стоимость на задержку. Поскольку этапы выполняются последовательно, пропуск раннего остановления означает ожидание совершенно новой волны роллов, чтобы выполнить их до конца. По сравнению с одновременным запуском всех N роллов это вводит премию задержки от 20% до 41%.
Кроме того, стремление к максимальной экономии затрат путем добавления большего количества этапов приводит к небольшому снижению общей скорости разрешения (-0,6%) — как потому, что наши классификаторы становятся слабее по мере увеличения N, так и потому, что добавление большего количества последовательных шагов естественно увеличивает кумулятивную вероятность ложного срабатывания, что приводит к ошибочному раннему остановлению.
В конечном итоге каскадирование представляет собой наш самый ориентированный на стоимость вариант: это самая дешевая стратегия, но она работает медленнее, чем базовый вариант.
Часть II: Параллельное выполнение с ранним остановлением (оптимизированное по задержке)
Если вы не можете позволить себе премию задержки, вы можете применять те же решения об остановке по-другому, используя параллельное выполнение с ранним остановлением.
Таким образом, вместо того чтобы ждать между этапами, мы запускаем все максимальные N роллов параллельно заранее. По мере завершения роллов и достижения наших заданных порогов этапов мы запускаем те же классификаторы RN/RL на завершенных кандидатах. В момент срабатывания сигнала остановки мы немедленно прекращаем любые оставшиеся активные роллы и сокращаем затраты.
Это изменяет профиль производительности двумя основными способами, сохраняя при этом идентичными базовые классификаторы, пороги и результаты разрешения:
- Задержка снижается, а не увеличивается: самые медленные роллы — это именно те, которые мы останавливаем досрочно. Вместо того чтобы ждать отстающих, выполнение завершается в момент, когда критерии остановки выполняются.
- Экономия затрат более скромна: прерванные роллы все равно потребляют некоторое количество вычислительных ресурсов перед тем, как быть остановленными (оплата пропорционально их времени выполнения). Вы жертвуете частью своей экономии затрат, чтобы вернуть скорость.
Это означает, что обе оси улучшаются – параллельное выполнение строго доминирует над стандартным подходом «запустить все и ждать». Обратите внимание, что добавление большего количества этапов увеличивает преимущества задержки, хотя это сопровождается небольшим компромиссом качества в -2%.
Аргументы в пользу отказа от единообразных бюджетов
Оба метода – каскадирование и параллельное выполнение с ранним остановлением – рисуют фиксированный фронтир Парето качества, который затем может быть настроен в зависимости от желаемой стоимости или задержки. При фиксированном качестве N=3 (показано ниже) компромиссы очевидны; тот же принцип действует даже при увеличении N до 5 или 10.
Визуализация показывает это четко: единообразный вычислительный бюджет строго субоптимален. Однако победа над базовым вариантом потребовала полного переосмысления наших предыдущих стратегий бенчмаркинга. Поскольку задачи SWE уникально сложны, сырая самоуверенность не была достаточно сильным сигналом, на котором можно было бы основывать решения о раннем остановлении.
Вместо этого мы сместили наш фокус на предсказание производительности последующего селектора и разработку богатого набора признаков. Это наконец позволило нам получить точный сигнал, который нам нужен был, чтобы адаптировать наши стратегии выполнения и успешно превзойти базовый вариант.
Выводы
Результатом этой инженерной работы является динамический регулятор, который позволяет вам управлять компромиссом между стоимостью и задержкой с минимальным снижением качества задач:
- Каскадирование с ранним остановлением максимизирует экономию: сокращает вычислительные затраты до 44%, жертвуя временем выполнения из-за своих последовательных этапов.
- Параллельное выполнение с ранним остановлением максимизирует скорость: обеспечивает до 25% ускорение по сравнению с базовым вариантом, прекращая неэффективные роллы в воздухе.
Для разработчиков это означает, что вам больше не нужно придерживаться жесткого, универсального бюджета выполнения, что дает вам больше гибкости для оптимизации по стоимости или скорости, сохраняя при этом превосходное качество агента.










