- BrainTools - https://www.braintools.ru -

Опыт использования сабагентов в AI-агенте для IDE: что реально работает на больших задачах, а что нет

 Архитектура «оркестратор + сабагенты» на одном экране: оркестратор держит план и раздаёт подзадачи сабагентам.

 Архитектура «оркестратор + сабагенты» на одном экране: оркестратор держит план и раздаёт подзадачи сабагентам.

Архитектура «оркестратор + сабагенты» на одном экране: оркестратор держит план и раздаёт подзадачи сабагентам.

Один AI-агент в чате – это удобно, пока задача помещается в контекст. Как только она начинает разъезжаться по 30 файлам, четырём ролям и циклу «исследуй – реализуй – отревьюй – поправь», единый чат превращается в свалку: модель путает, какой шаг где, тащит решения из первой задачи в третью и стабильно проседает по качеству начиная с заполнения окна примерно наполовину. Схема «оркестратор + сабагенты» – это инженерный ответ на проблему: оркестратор держит план и раздаёт подзадачи изолированным сабагентам.

Готовы поделиться нашим опытом [1]: как это устроено

Дисклеймер. Сравнений с Claude Code, Junie, Cursor, JetBrains AI Assistant, OpenAI Swarm, LangGraph и другими реализациями оркестратора с сабагентами в этой статье нет – это отдельный жанр, требующий одинакового бенча. Цель статьи – показать архитектурные решения и причины, по которым мы к ним пришли. Материал – конспект внутреннего доклада и практики на нашем плагине.

TL;DR

  • Качество ответа LLM падает по мере заполнения контекста. На наших внутренних замерах в JetBrains-плагине просадка становится заметной после ~50% заполненности и резко обваливается после ~85%. Похожая картина описана в Lost in the Middle (Liu et al., 2023) [2] и в Anthropic Engineering: Effective context engineering [3].

  • Сабагент – это не «агент, который зовёт агента». Это изолированный подпроцесс со своими тулами и единственным каналом возврата – report_result(summary). Сабагентов вызывает только оркестратор.

  • Оркестратор с сабагентами даёт выигрыш на трёх классах задач: project-wide read-only (ревью, триажинг, инвентаризация), сложные пайплайны с явной разбивкой ролей по разным scope (TDD, SDD, итеративная фича), loop-based задачи (review-loop, поиск code smells).

  • На задачах, помещающихся в контекст одного агента, оркестратор с сабагентами почти всегда проигрывает одиночному агенту. Anthropic в посте «How we built our multi-agent research system» [4] пишут о 3–10× расходе токенов на эквивалентный результат – на наших задачах цифра близкая.

  • Главный инженерный выбор – где провести границу декомпозиции. Делить по ролям (planner / coder / reviewer на одной фиче) почти всегда плохо: координация съедает больше токенов, чем сама работа. Делить по контекстным границам – хорошо.

  • Промпт «сделай через сабагентов» работает плохо, скилл (markdown-файл с алгоритмом, acceptance criteria и явным списком сабагентов) – хорошо.

Почему один чат деградирует на крупных задачах

В презентации внутри команды у нас есть слайд, который мы потом вынесли наружу: «качество ответа = качество контекста». У контекста есть три неприятных свойства, и все три бьют ровно в крупную задачу.

Первое – предвзятое отношение к прошлым ответам. LLM считает свои собственные предыдущие сообщения частью истины. Если в чате вы зацепили неудачное направление и потом передумали, модель будет к нему возвращаться даже после фразы «забудь». Это особенно видно на ревью-лупах: вторая итерация почти всегда «защищает» решение первой, а не оценивает его заново.

Второе – жёсткое ограничение размера. У нас агент по умолчанию читает не целые файлы, а диапазоны строк, предварительно прочитав структуру файла (благо есть возможность получить эту информацию из IDE); даже так окно 200k токенов уходит за 20–30 tool calls на enterprise-репозитории ~4M LoC. На чтении файлов целиком, как делает большинство grep-агентов, бюджет кончается ещё быстрее.

Третье – деградация при заполнении. На наших внутренних замерах (актуальные на апрель 2026 модели семейств Claude Opus, Claude Sonnet и GPT – у всех похожая форма кривой) качество держится примерно линейным до 40–50% заполненности окна. На участке 50–85% начинается заметная просадка: модель чаще теряет нить, путает, какой шаг где, начинает «склеивать» куски разных задач. На 95–99% она формально отвечает, но содержательно нет. Эти наблюдения совпадают с описанием в Lost in the Middle [2]: информация в середине длинного контекста используется хуже, чем на краях.

Проблемы:

– Loop-based пайплайны (ревью, итеративная разработка, поиск code smells) в одном чате системно искажаются: каждая следующая итерация смотрит на предыдущую как на «уже почти ок».

– Context-heavy задачи целиком в один чат не лезут. Суммаризация частично спасает, но теряет детали.

– Сложные пайплайны нельзя гонять в автоматическом режиме: пользователь вынужден быть оркестратором руками.

– Стратегичность скатывается в тактику. Модель начинает решать «следующую очевидную подпроблему», а не план целиком.

– Параллельности нет.

Оркестратор с сабагентами решает ровно эти пять проблем, но не бесплатно.

Анатомия сабагентов: что есть и чего нет

Сабагент в нашей реализации – это не «агент, который умеет звать агента». Это отдельный процесс с пустым контекстом на старте, со своим (часто урезанным) набором тулов, запущенный с общей папкой для обмена данными и с единственным тулом штатного завершения – вызовом report_result(summary).

Если в одной строке: сабагент – это изолированный агент-ассистент, к которому оркестратор обращается как к чёрному ящику.

reportresult

 Жизненный цикл одного вызова: оркестратор формирует SubagentCall, сабагент работает в своём контексте, возвращает компактный summary через report_result.

Контракт вызова из оркестратора (упрощённая сигнатура):

data class SubagentCall(
    val shortDescription: String,   // одна фраза для UI и логов
    val fullDescription: String,    // полный промпт задачи для сабагента
    val context: String,            // выжимка релевантного контекста от оркестратора
    val sharedDir: Path,            // папка, через которую идёт обмен файлами
)

Несколько решений в этом контракте, которые на первый взгляд выглядят странно, и причины, по которым мы к ним пришли.

Почему сабагент не может звать сабагентов – в ранних прототипах мы это разрешали. На второй неделе обнаружили дерево сабагентов глубиной 6, в котором листья тратили токены на пересказ задачи родителя бабушке-родителю, и обратно. Иерархия сворачивается в координационный ад быстрее, чем вы успеваете её отдебажить. Поэтому в текущей версии сабагенты звать сабагентов не могут, и это дисциплинирует декомпозицию у оркестратора.

Почему сабагент не общается с пользователем – это by design. Если сабагенту нужно что-то спросить, он либо отвечает на основе контекста, либо завершает работу с пометкой «не хватает данных». Спрашивать пользователя – задача оркестратора. Иначе у пользователя одновременно живут пять чатов от пяти сабагентов, и никто, включая сам оркестратор, не понимает, кто что делает.

Почему общая папка, а не передача через аргументы – контекст в аргументе тула дорогой и узкий. Если сабагенту нужно отдать обратно дифф на 800 строк или JSON с разметкой 200 issue, он кладёт это в файл в sharedDir, а в report_result возвращает короткую сводку и путь. Все участники, включая оркестратора, могут читать и писать в эту папку, у нас это решено через directory-bound тулы (read_in_dirwrite_in_dir), которые ограничены ровно этой папкой.

sharedDir

 Обмен крупными артефактами идёт через sharedDir (<projectRoot>/.tasks по умолчанию, путь конфигурируется); тулы сабагента ограничены ровно этой папкой.

Почему report_result(summary), а не «верни всё, что наработал» – сабагент по построению генерирует много промежуточного шума: тысячи строк grep-выдачи, прочитанные файлы, чужие классы. Если всё это вернуть в чат оркестратора, мы возвращаемся к проблеме захламлённого контекста, ради ухода от которой всё и затевалось. Поэтому return – это всегда сжатая сводка, а детали через файлы в sharedDir.

Параллельность – оркестратор может запустить несколько сабагентов одним шагом и блокируется до завершения всех. Это упрощает синхронизацию (никаких очередей и колбэков на стороне оркестратора), но накладывает естественное ограничение: задача делится на параллельные ветви, у которых нет кросс-зависимостей. Если зависимости есть, лучше последовательный вызов.

Автономность через «Продолжай» – сабагент должен сам решить, что закончил, и вызвать report_result. Если он этого не сделал, мы пинаем его сообщением «Продолжай или вызови report_result» до 10 раз. После – принудительная остановка и возврат с ошибкой [5] в оркестратор. На практике даже на слабых моделях этой эвристики в 10 итераций хватает для завершения задачи.

Когда оркестратор с сабагентами реально выигрывает у одиночного агента

Это место, где много маркетинга. Мы у себя сформулировали честно: оркестратор с сабагентами даёт выигрыш на трёх классах задач, и почти везде вне этих трёх классов проигрывает одиночному агенту.

 Пример: пайплайн для end-to-end подготовки домашнего задания для студентов.

 Пример: пайплайн для end-to-end подготовки домашнего задания для студентов.

Project-wide read-only

Задачи, в которых нужно пройти по всему проекту, что-то посмотреть и вернуть структурированный отчёт. Состояние нигде не меняется, шаги независимы.

Что мы у себя гоняем через сабагентов:

– Прогон ревью-чеклистов по всему PR / по всему модулю (пакет → сабагент).

– Триажинг issue из трекера (GitHub / GitLab / YouTrack): воспроизводится / не воспроизводится, severity, дубли (один сабагент на батч issue).

– Инвентаризация фич продукта (один сабагент на функциональную область).

– Сборка полной документации проекта (по модулям).

– Поиск code smells по списку правил (батч связанных правил → один сабагент).

Параллельность тут даёт реальный выигрыш по реальному времени, а изоляция контекста – по precision: сабагент, у которого в контексте связанные правила по организации кода по пакетам, не отвлекается на проверку IDE-специфичных дедлоков.

Сложные пайплайны с явной разбивкой на роли

Когда у задачи действительно есть разные этапы или разные роли, и они работают на разных кусках кода. Не «одна фича + три роли», а именно «разные scope».

Примеры из нашей практики:

– TDD-пайплайн: сабагент-1 пишет тесты по описанию задачи, сабагент-2 пишет реализацию под зелёные тесты, сабагент-3 ревьюит. Каждому в контексте лежит ровно его кусок, не больше.

– SDD + TDD: перед всем этим оркестратор зовёт сабагента-планировщика, который читает issue из трекера или спеку и раскладывает её на task-01.md [6]task-02.md [7], … в sharedDir.

– Итеративная разработка через спеку: один сабагент-кодер на каждую итерацию, один общий ревьюер в конце каждой итерации, обновление спеки между итерациями, планирование следующей итерации.

– Автогенерация домашних заданий по шаблону.

Loop-based пайплайны

Внутри одного агента loop работает плохо: к третьей итерации модель уже «знает», что было в первых двух, и не может посмотреть на свой код свежим глазом. С отдельным сабагентом на каждую итерацию это перестаёт быть проблемой, у каждого свой контекст.

Кейсы, где это даёт самый явный выигрыш:

– Поиск багов: сабагенты ищут параллельно, пока оркестратор собирает агрегированный отчёт.

– Поиск code smells: один проход – один сабагент, оркестратор склеивает.

– Параллельный сбор информации о проекте.

Те же задачи можно делать одним чатом с Ralph Wiggum loop (паттерн Geoff Huntley [8]: один и тот же промпт зациклен в while-true, пока не выполнено условие), но тогда нужно вручную следить за размером контекста. На длинной дистанции это всё равно сваливается в захламление.

Где сабагенты строго хуже

Тоже честно. Если задача попадает в этот список, оркестратор с сабагентами дороже и хуже одиночного агента.

 Три типичных анти-паттерна: маленькая задача, связный контекст между подзадачами, обязательная ручная валидация после каждого шага.

 Три типичных анти-паттерна: маленькая задача, связный контекст между подзадачами, обязательная ручная валидация после каждого шага.

Первый случай – задача целиком помещается в контекст. Фикс мелкого бага, мелкое улучшение существующей фичи, рефакторинг до 100 LoC и до 10 файлов. Один чат справится за один шаг, оркестратор будет 4 шага собирать контекст для сабагентов и ещё 2 склеивать ответы.

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

Третий случай – нужно каждый шаг смотреть глазами. Если задача требует ручной валидации после каждого шага, оркестратор просто добавляет лишний слой между вами и кодом. Все передачи между сабагентами всё равно ложатся на вас.

Эмпирическое правило по объёму, к которому мы пришли:

Объём задачи

LoC

Файлов

Что использовать

Small

до 100

до 10

Одиночный агент

Medium

100–300

10–20

Одиночный агент

Large

300

20

Оркестратор + сабагенты

Сложный пайплайн

любой

любой

Оркестратор + сабагенты

Граница «medium / large» наша. У вас она может проходить иначе: зависит от того, насколько связан код в проекте.

Как мы декомпозируем и почему по ролям почти всегда плохо

Самая дорогая ошибка при работе с оркестратором и сабагентами: «давайте у нас будет сабагент-планировщик, сабагент-кодер, сабагент-тестировщик и сабагент-ревьюер на каждой задаче». На бумаге логично [9], на практике эти четверо проводят 70% токенов на пересказ друг другу того, что предыдущий уже сделал.

То же самое формулирует Anthropic в своих заметках по оркестратору с сабагентами: при разделении работы по ролям внутри одной задачи сабагенты тратят больше токенов на координацию, чем на саму работу. По нашим замерам, на задачах, помещающихся в контекст одного агента, оркестратор с сабагентами съедает в 3–10 раз больше токенов на эквивалентный результат.

Правильный критерий декомпозиции – не «какие роли в команде разработки», а где можно изолировать контекст.

Опыт использования сабагентов в AI-агенте для IDE: что реально работает на больших задачах, а что нет - 6

Хорошие границы для разделения:

– Независимые исследовательские области (исследование разных модулей, разных issue, разных правил ревью).

– Слабо связанные модули с чистым интерфейсом (фронт и бэк по контракту).

– Чёрный ящик-проверка: тесты, прогон линтера, прогон бенчмарка, не нужен контекст реализации.

Плохие границы:

– Последовательные фазы одной фичи (план → код → тест), слишком много общего контекста.

– Сильно связанные компоненты, которым нужно много синхронизироваться.

– Задачи, требующие общего разделяемого состояния.

 Хороший случай: разбиение по слабо связанным модулям с чистым интерфейсом.

 Хороший случай: разбиение по слабо связанным модулям с чистым интерфейсом.

В таблице ниже – что мы у себя пробовали и к чему пришли:

Стратегия разбивки

Подход

Итог

По ролям (planner/coder/reviewer) на одной фиче

Каноничная схема разбивки по ролям

Плохо. Дорого, медленно, теряется контекст между ролями

По участкам кода: пакет / класс → сабагент

На каждый класс свой сабагент

Плохо. Слишком долго, оверхэд на координацию

По модулям, если модули слабо связаны

Один сабагент на модуль

Ок

По мини-подзадачам

Каждый таск – сабагент

Плохо. Слишком долго

По группам связанных подзадач

Несколько связанных тасков рядом

Ок

По итерациям loop-а

Каждая итерация – свой сабагент

Хорошо

По группам правил для ревью

Группа правил → сабагент

Хорошо

Скиллы вместо промпта в чате

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

Решение оказалось не в «более умном оркестраторе», а в скиллах – markdown-файлах, которые описывают конкретный пайплайн.

 Скилл – это просто markdown-файл: вход, шаги, какие сабагенты вызывать, acceptance criteria, лимит итераций.

 Скилл – это просто markdown-файл: вход, шаги, какие сабагенты вызывать, acceptance criteria, лимит итераций.

Что мы кладём в скилл оркестратора:

– Какие сабагенты вызывать и в каком порядке.

– Какой возвращаемый результат ожидается от каждого.

– Сколько итераций в loop-е (мы не уходим выше 4 для ревью и 5 для генерации, после этого качество перестаёт расти, а токенов жжёт всё больше).

– Acceptance criteria и checklists для итогового результата.

– Всю необходимую инфу в начале скилла, чтобы оркестратору не пришлось «исследовать» задачу самому.

Чего не кладём:

– Слишком сложной логики. LLM-модели всё ещё тупят, и скилл из 12 ветвлений ломается на пятой задаче.

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

 Несколько скиллов в общем доступе у команды: пайплайны воспроизводятся, не надо переписывать промпт каждый раз.

 Несколько скиллов в общем доступе у команды: пайплайны воспроизводятся, не надо переписывать промпт каждый раз.

Скиллы, которые у нас закрепились в общем доступе:

– Скилл поиска всех фич в проекте.

– Скилл итеративной разработки через спеку.

– Скилл поиска code smells.

– Скилл написания/исправления других скиллов (мета).

Что мы наблюдали под капотом

Расход токенов

На задачах, где оркестратор с сабагентами обоснован, мы видим 1.5–2× больше токенов по сравнению с одиночным агентом – это плата за параллельность и изоляцию. На задачах, где он не обоснован, расход уходит в 3–10×. Цифры – наш замер на 24 задачах внутреннего бенчмарка (старшая модель Claude Opus, апрель 2026; 6 задач на каждый класс: ревью PR, триажинг issue, TDD-пайплайн, поиск code smells), методологию опубликуем отдельно (скоро в отдельной статье).

Время выполнения

Параллельный шаг оркестратора с N сабагентами идёт дольше самого медленного из N. На review-loop с 5 сабагентами на PR ~10k LoC у нас выходит около 70 минут реального времени (старшая модель Claude Opus, ~180 tool calls суммарно по всем сабагентам, в основном чтение PSI и файлов). Дорого, но один человек руками это делал бы день.

Что LLM пытается хакнуть

Реальные кейсы, которые мы ловили:

– Claude в роли сабагента просил оркестратора «верни мне содержимое всех изменённых файлов», попытка обойти контракт на компактный summary через social-engineering оркестратора.

– Сабагент-ревьюер периодически решал, что задача не «отревьюить», а «исправить и отревьюить», и начинал писать в файлы.

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

sharedDir накапливается

Папка .tasks (по умолчанию <projectRoot>/.tasks, путь конфигурируется) копит артефакты, которые нужны были на минуту: дифф, который уже применён, отчёт, который уже сведён. У нас она в .gitignore и периодически чистится скриптом.

Известные ограничения

В сабагентах приходится заново собирать контекст для каждого вызова. Это ровно та цена, которую вы платите за изоляцию. Часть контекста (AGENTS.md [10], правила проекта, общие скиллы) кэшируется автоматически, но «релевантные файлы под эту задачу» сабагенту приходится искать заново.

Координационный оверхэд тоже значимый. На каждом вызове сабагента вы тратите токены на обязательные тулы: report_progress для апдейтов, report_result для возврата. На задачах, где сама работа измеряется минутами, это терпимо. На быстрых задачах это и есть основной расход.

Важно:

– Контекст – главный ограничитель LLM-агента. Не промпт, не модель, не RAG. Если контекст захламлён, деградация модели становится существенной.

– Оркестратор с сабагентами – это инженерное решение проблемы контекста, а не «более умный AI». Поэтому такая схема помогает только там, где проблема контекста реально есть.

– Делите по контекстным границам, не по ролям. Planner / coder / reviewer на одной фиче – это анти-паттерн. Но роль reviewer в любом виде важна: без отдельного ревью-шага (в виде сабагента-ревьюера, отдельной итерации в loop’е или по группам правил) результат не выверить.

– На малых задачах (≤100 LoC, ≤10 файлов) одиночный агент дешевле и часто лучше. Не зовите оркестратор на каждый чих.

– Используйте скиллы (markdown-файлы с алгоритмом), а не свободные промпты. Это единственный способ получить воспроизводимый пайплайн.

– 3–10× по токенам и заметно дольше по реальному времени – нормальная цена за оркестратор с сабагентами. Если выигрыша по качеству нет, вы платите впустую.

А у вас как? Если использовали сабагентов, по каким границам декомпозиция реально окупилась? Любопытно сверить наш «делите по контексту, не по ролям» с вашим опытом, пишите в комментариях.

Workshop / вебинар через 2 недели

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

Вопросы, на которые ответим вживую

По архитектуре из статьи

1. Как понять, что в моём чате контекст уже «захламлён» и пора создавать новый чат?

2. Как быть, если есть одна большая задача, связанная с одним компонентом?

3. Граница Medium/Large — ваш эмпирический порог. Как найти свой?

По сабагентам в продукте Veai

4. Чем сабагент Veai отличается от sub-agents в Claude Code и task-agent в Cursor?

5. Как выглядит UI оркестратора: видно ли, какой сабагент работает, можно ли его остановить

6. Как сабагенты Veai используют PSI-индекс IntelliJ вместо grep, и почему это выигрывает в токенах?

7. Как запустить свой скилл и расшарить его внутри команды?

По продукту Veai — безопасность, модели, enterprise

8. Какие модели поддерживает плагин и можно ли подключить свой LLM-эндпоинт (on-prem / vLLM / российские провайдеры)?

9. Что уходит в провайдера модели при работе сабагента, а что остаётся локально?

10. Как Veai ведёт себя на monorepo 4M+ LoC и можно ли запустить оркестратор из CI?

11. Чем Veai отличается от Claude Code, Junie, JetBrains AI Assistant и Cursor именно на больших задачах?

По цифрам и экономике

12. Какие реальные ценники по токенам на ревью PR ~10k LoC и на поиск code smells по модулю?

13. Как вы считаете 1.5–2× и 3–10× на внутреннем бенчмарке 24 задач? Какая методология?

14. Когда экономически не окупается звать оркестратор, даже если задача Large?

Как участвовать

Чтобы понять формат, который будет полезен большинству, проголосуйте в коротком опросе:

Что хотите увидеть на воркшопе в первую очередь?

  1. Живой разбор кейсов из комментариев под статьёй

  2. Пошаговая настройка оркестратора и сабагентов в JetBrains IDE

  3. Сравнение «одиночный агент vs оркестратор с сабагентами» на одной и той же задаче

  4. Скиллы (markdown-алгоритмы) и как их писать под свой проект

  5. Замеры: токены, время, качество — методология и цифры

  6. Q&A с разработчиками плагина без сценария

Свой вопрос для разбора — пишите в комментариях или в наш чат: https://t.me/veai_devs [11]. Ссылку на регистрацию опубликуем там же.

Автор: dirvika

Источник [12]


Сайт-источник BrainTools: https://www.braintools.ru

Путь до страницы источника: https://www.braintools.ru/article/30171

URLs in this post:

[1] опытом: http://www.braintools.ru/article/6952

[2] Lost in the Middle (Liu et al., 2023): https://arxiv.org/abs/2307.03172

[3] Anthropic Engineering: Effective context engineering: https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents

[4] «How we built our multi-agent research system»: https://www.anthropic.com/engineering/built-multi-agent-research-system

[5] ошибкой: http://www.braintools.ru/article/4192

[6] task-01.md: http://task-01.md

[7] task-02.md: http://task-02.md

[8] паттерн Geoff Huntley: https://ghuntley.com/ralph/

[9] логично: http://www.braintools.ru/article/7640

[10] AGENTS.md: http://AGENTS.md

[11] https://t.me/veai_devs: https://t.me/veai_devs

[12] Источник: https://habr.com/ru/companies/veai/articles/1034208/?utm_campaign=1034208&utm_source=habrahabr&utm_medium=rss

www.BrainTools.ru

Rambler's Top100