Четыре AI-агента сожгли 40 млн токенов, споря о коде. Я научил их вовремя останавливаться
Я пишу свою IDE как пет-проект. У неё есть название, но здесь обойдёмся без презентации продукта. Хочу рассказать про одну функцию, которая в итоге вытащила меня в отдельное исследование.
Если вы хоть раз долго чинили баг вместе с coding-агентом, ситуация, скорее всего, знакомая. Модель находит правдоподобную причину, уверенно меняет код. Не помогло. Вы пишете: «Проверь себя».
И тут иногда начинается самое неприятное. Модель уже зацепилась за свою версию и продолжает её достраивать. Здесь добавит условие, там исключение, потом ещё одну проверку. Вокруг изначально посредственного решения вырастает набор костылей. Вы уже обсуждаете, как заставить всё это работать, хотя стоило бы вернуться на шаг назад: а причину ошибки мы вообще нашли?
Мне захотелось поставить такую остановку до первой правки кода. Пусть сначала появятся несколько независимых версий, и кто-нибудь попробует оспорить решение, пока оно ещё не превратилось в десять изменённых файлов.
Сама идея давно существует: есть multi-agent debate, есть AutoGen и разные способы организовать обсуждение между LLM. Я взял эту основу, встроил многоролевое планирование в IDE и описал собственную схему управления обсуждением в своей работе.
На экране всё выглядело здорово. Но мне хотелось знать, сколько пользы скрывается за этим красивым разговором.
В итоге — 480 основных запусков, две модели и несколько миллионов токенов, которые можно было не тратить. А самая полезная находка оказалась вообще не в итоговой таблице.

Для начала я устроил моделям совещание
Четыре роли: архитектор, разработчик, рецензент и тестировщик.
У каждой свой вопрос. Где причина ошибки? Что менять? Что от этого сломается? Как проверить, что исправление сработало?
Это не четыре разные нейросети, собранные в одном чате. В каждом эксперименте роли исполняла одна и та же LLM, но отдельными вызовами и с разными инструкциями. Сначала DeepSeek, затем весь набор задач прошёл Qwen.

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

Так появился Budgeted Verified Council — BVC. У полного совета появилась развилка перед критикой.
Роли должны были вернуть структурированные позиции: предполагаемую причину ошибки, способ исправления, затрагиваемые зависимости и тесты. Система сравнивала эти поля и решала, нужен ли второй круг.
Если оснований продолжать нет — сразу собираем план. Получается шесть вызовов вместо десяти. Если есть — запускаем критику и укладываемся в прежние десять.
На бумаге звучит почти слишком просто: убрал четыре лишних вызова, получил экономию.
Но вся сложность прячется в слове «лишних». Если ранняя остановка выбрасывает полезную проверку, то я просто обменял качество на меньший счёт.
И ещё надо было убедиться, что система вообще правильно понимает, когда участники расходятся во мнениях. С этим, как выяснилось позже, были проблемы.

И ТУТ НАЧАЛИСЬ ТЕСТЫ
Я взял 60 задач SWE-bench Verified из 11 Python-проектов. Настоящие issue и исходники: нужно получить патч, который применится к нужному состоянию репозитория и пройдёт тесты.
Выборка намеренно была сложнее средней: самые лёгкие задачи, оценённые менее чем в 15 минут работы, в неё не вошли. Поэтому дальше — результаты именно на этих 60 задачах, а не оценка всего SWE-bench.
Для каждой задачи сравнивались четыре режима:
Режим | Что происходит | Вызовов на задачу |
|---|---|---|
Сразу к коду | Сразу генерируем патч | 1 |
Один план | Сначала план, потом патч | 2 |
Полный совет | Четыре роли, обязательная критика, план, патч | 10 |
BVC | Тот же совет, но критика включается условно | 6 или 10 |
Один план здесь особенно важен. Иначе можно было бы приписать четырём агентам пользу, которую даёт обычная просьба сначала подумать.
Внутри каждой модельной серии методы получали одинаковое описание задачи и одинаковые файлы. Контекст выбирался поиском по репозиторию; все 245 выбранных файлов я сверил с исходными ревизиями — совпали побайтно. Эталонные патчи и проверочные тесты в запросы к модели не попадали.
Настройки и список задач были зафиксированы до получения результатов. Неудачные ответы тоже оставались в таблице: пустой патч, сломанный формат, неприменимое изменение. Нельзя же считать процент успеха только среди попыток, которые понравились.
Важное ограничение: это был контролируемый тест планирования перед одним патчем. Агент не мог бесконечно запускать тесты и дописывать исправление по их подсказкам.
Сначала 240 запусков на DeepSeek. Затем те же 60 задач и четыре режима на Qwen — ещё 240.
60 задач × 4 режима × 2 модели = 480 запусков. Не 480 разных задач.
Каждый патч проходил официальный SWE-bench evaluator в контейнере: должны были заработать тесты на исходный баг и сохраниться проверки ранее работавшего поведения. Мнение самой модели о том, как хорошо она справилась, в результат не входило.

На первой модели экономия действительно появилась
DeepSeek прошёл по короткому маршруту в 32 задачах из 60.
Полный совет использовал 600 вызовов, BVC — 472. По токенам получилось 18,37 млн против 14,28 млн: минус 22,2%.
По зафиксированному тарифу стоимость снизилась с 2 402,61 до 1 838,46 рубля. Разница — 564,15 рубля, или 23,5%. Это расчёт для учтённых цепочек вызовов, а не полный счёт провайдера со всеми техническими повторами.
Для пет-проекта полтысячи рублей не выглядит переворотом. Но мне было важно другое: правило остановки реально меняло расход вычислений. Можно было открыть конкретную задачу и увидеть, где система не сделала четыре дополнительных вызова.
При этом тесты прошли пять патчей BVC и шесть патчей полного совета. Так что поздравлять себя с «тем же качеством дешевле» было рано.
А затем экономия почти исчезла.
Я заменил модель. Совет снова стал спорить почти всегда
На Qwen короткий маршрут сработал только в трёх задачах из 60. В остальных 57 система отправляла роли на дополнительный круг.
Экономия токенов упала с 22,2% до 2,1%. Роли те же. Задачи те же. Правило то же.
По одной итоговой таблице можно было бы решить, что Qwen просто чаще не соглашается сам с собой. Но у меня оставались ответы ролей и решения алгоритма по каждому запуску. Я пошёл разбирать, что именно считалось разногласием.
Для сравнения система ждала структурированный ответ. Если обязательных полей не хватало или ответы нельзя было нормально сопоставить, первая экспериментальная реализация тоже включала критику.
Получается, она смешивала две разные ситуации:
участники предложили несовместимые решения;
система не получила достаточно корректно оформленных ответов, чтобы сравнить решения.
Во втором случае мы ещё не знаем, есть ли спор. А платим уже как за спор.
При повторном разборе сохранённых ответов в 54 из 57 таких Qwen-запусков одновременно не хватало обязательных данных и общего набора полей для сравнения. В одном из разобранных ответов модель упёрлась в лимит 4096 выходных токенов: почти весь бюджет ушёл на рассуждение, а финальный JSON оказался пустым или обрезанным.
Вот это уже была находка. Я добавлял обсуждение, чтобы ловить ошибки в коде, а эксперимент поймал ошибку в самом управлении обсуждением.

Разница практическая. Настоящий конфликт стоит отправлять на критику. Повреждённый ответ сначала нужно попытаться восстановить или заново запросить в коротком формате. Если не получилось — переходить к запасному плану, а не созывать ещё одно совещание.
Именно эту границу я затем поправил в исходниках BVC. Ниже приведены результаты прежней, зафиксированной версии: я не подменял её исправленной посреди эксперимента.
Что удалось показать цифрами
Если сложить расход полного совета и BVC по двум модельным сериям, получается:
Ресурсы на 120 запусках каждого режима | Полный совет | BVC |
|---|---|---|
Вызовы | 1200 | 1060 |
Токены, входные и выходные | 40 394 012 | 35 839 813 |
Это те самые 40 млн из заголовка — расход всей цепочки полного совета, включая общий план и генерацию патча.
BVC использовал на 4 554 199 токенов и 140 вызовов меньше. В сумме — 11,3% токенов и 11,7% вызовов. Это описательная сумма двух серий на одних и тех же задачах; большая часть экономии пришлась на DeepSeek.
С качеством картина сложнее. Вот все четыре режима, чтобы не выбирать для сравнения только удобного соперника:
Патчи, прошедшие тесты | Сразу к коду | Один план | Полный совет | BVC |
|---|---|---|---|---|
DeepSeek, 60 задач | 4 | 7 | 6 | 5 |
Qwen, те же 60 задач | 3 | 5 | 4 | 7 |
Да, в сумме у BVC 12 успешных запусков против 10 у полного совета. Но это ещё не доказательство более качественного исправления кода. На первой модели один план оказался впереди BVC, на второй — наоборот. При этом один план был дешевле BVC в обеих сериях.
Коротко про статистику
Основное сравнение исследования — BVC против одного предварительного плана, отдельно для каждой модели. В обоих случаях точный двусторонний критерий Мак-Немара дал p = 0,625. Интервалы разности включают ноль.
Данных недостаточно, чтобы объявить BVC лучше. Отсутствие значимого различия также не доказывает равное качество или отсутствие потерь.
Зато ресурсный результат можно проверить по журналам вызовов. В этой конфигурации условная критика действительно обходилась дешевле обязательной. А разбор Qwen показал, почему такое преимущество нельзя автоматически переносить на другую модель.
Заодно пришлось проверить того, кто ставил оценки
После таблицы успехов возникает неудобный вопрос: а тестовому стенду мы почему верим?
Я отдельно прогнал через него три набора: пустые изменения, все 22 успешных патча из основной DeepSeek-серии и эталонные исправления из датасета. Каждый набор — дважды, уже без новой генерации ответов LLM.
Пустые изменения не прошли ни разу: 0 из 60 в обоих повторах. Все 22 ранее успешных патча снова прошли тесты в обоих повторах.
А вот эталонные — только 58 из 60. Оба раза.
Два «правильных ответа» применялись и исправляли целевой баг, но падали на других проверках в зафиксированной среде. В случае requests среди них были сетевые и timeout-тесты. Значит, и отрицательный результат стенда нельзя безоговорочно читать как «модель написала неправильный код».
Эти две задачи не меняли основного статистического вывода, но ограничение всё равно пришлось оставить в исследовании. Проверка не прошла собственный критерий 60 из 60.
Для меня это была ещё одна причина сохранять всю цепочку: запрос, ответ, патч, результат тестов. Когда цифра вызывает вопросы, нужно иметь возможность дойти до того места, где она получилась.

Ради чего всё это стоило делать
В моей IDE теперь есть совет агентов — с независимыми версиями решения, критикой и общим планом до первой правки кода. Тот самый процесс, которого мне не хватало, когда очередное «проверь себя» заканчивалось новыми костылями.
Я встроил его в рабочий процесс и добавил управление бюджетом обсуждения. Второй круг больше не обязателен по сценарию: у системы есть правило, по которому она решает, продолжать разбор или уже собирать план. Для меня это важная часть функции — управлять не только тем, о чём говорят агенты, но и тем, сколько стоит этот разговор.
Дальше я проверил эту схему на отдельном экспериментальном стенде. В сумме двух модельных серий BVC использовал на 4,55 млн токенов и 140 вызовов меньше, чем полный совет с обязательной критикой. Это 11,3% экономии токенов в проведённых тестах. У идеи появилась измеримая цена — и измеримая экономия.
Исследование помогло доработать и сам алгоритм: в исходниках новой версии восстановление ответа отделено от содержательной критики. А весь стенд с задачами, патчами и журналами остался для следующих проверок. Теперь каждое изменение можно сравнивать с предыдущей версией на тех же условиях.
Вот ради чего стоило пройти весь этот путь. Я написал свою IDE, встроил в неё совет агентов и разработал способ сократить расходы на его обсуждения. Функция работает в IDE, а экономия проверена отдельным экспериментом. Для пет-проекта, который начинался с желания удобнее писать код, это уже вполне осязаемый результат.

Если хочется копнуть глубже
Код проекта — на GitHub. Режим BVC в IDE отвечает за планирование; описанный здесь эксперимент с патчами и контейнерными тестами — отдельный исследовательский стенд.
Multiagent Debate — Yilun Du и соавторы, 2023: независимые ответы и обсуждение между экземплярами модели.
AutoGen — Qingyun Wu и соавторы, 2023: организация многоагентных диалогов.
Rethinking the Bounds of LLM Reasoning — Qineng Wang и соавторы, ACL 2024: сравнение обсуждения агентов с одиночной моделью.
P.S. Деняк на исследования не собираю. Но если хочется поддержать такие эксперименты и не потерять продолжение — можно подписаться на мой Telegram. Вот за это немного поагитирую :)
KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.