Проблема агента-монолита

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

  • Размывается контекст. В промпте намешаны инструкции пяти разных ролей; модель «распыляется» и хуже следует каждой.
  • Страдает выбор инструмента. Из 15 похоже названных функций LLM всё чаще берёт не ту — особенно когда описания пересекаются.
  • Сложно улучшать. Подкрутил промпт под отчёты — поехало поведение в саппорте. Всё связано, любое изменение рискованно.
  • Невозможно тестировать по частям. Нельзя проверить «аналитическую» способность отдельно — она вплетена в общий клубок.

Это та же болезнь, что и «God object» в обычном коде: сущность, которая делает слишком много, становится непредсказуемой и неподдерживаемой. Решение в программировании известно — разделение ответственности. Оно же работает и для агентов.

ℹ️ Это знакомо по модулю 03

В уроке про Supervisor мы уже видели механику: команда узких агентов + координатор. Там был фокус на как собрать это в LangGraph. Здесь — на зачем: какой принцип за этим стоит и как решать, где провести границы. Это концептуальный фундамент всего модуля про мультиагентов.

Принцип: один агент — одна зона ответственности

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

100%
колёсико — масштаб  ·  зажать и тянуть — перемещение
❌ Один агент «на всё» mega-agent промпт на 3 экрана · 5 ролей search sql email code ticket browser calc files 15 инструментов → берёт не тот размытый контекст → посредственно везде меняешь одно — ломается другое ✅ Команда специалистов researcher search · scrape analyst sql · calc writer docs critic — (только ревью) узкий промпт · 1–2 инструмента каждый силён в своём улучшаешь и тестируешь по отдельности роли переиспользуются в других системах

Это прямой перенос принципа single responsibility из инженерии на агентов: у каждого агента — одна причина для изменения. Хочешь улучшить аналитику — правишь только аналитика, не задевая остальных.

Почему специализация работает лучше

фокус контекста
Короткий промпт под одну роль — модель чётко понимает задачу и не отвлекается на чужие инструкции.
точный выбор инструмента
Из 2–3 инструментов ошибиться трудно. Чем уже набор, тем надёжнее tool calling.
независимое развитие
Каждого агента улучшаешь, тестируешь и версионируешь отдельно — без риска сломать соседей.
переиспользование
Агент-«ресёрчер» один раз сделан — и встаёт в любой пайплайн, где нужен поиск.
Можно даже разные модели

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

Из чего состоит специализированный агент

«Специализированный» — это не просто «маленький». Хороший узкий агент описывается четырьмя вещами:

  1. Роль (persona) — кто он и за что отвечает: «ты — исследователь, твоя задача находить факты и источники».
  2. Узкий набор инструментов — только то, что нужно роли. Ресёрчеру — поиск; писателю — ничего, кроме генерации.
  3. Сфокусированный системный промпт — инструкции одной роли, без примесей. Короткий и предметный.
  4. Чёткий контракт входа/выхода — что агент получает и что обязан вернуть. Это интерфейс, по которому его подключают к команде.
Спецификация роли как контракт (псевдокод)
python
# Каждый агент = роль + узкие инструменты + сфокусированный промпт + контракт

researcher = Agent(
    role="Исследователь",
    goal="Найти достоверные факты и источники по теме",
    tools=[web_search, scrape_page],          # ← только поиск, ничего лишнего
    prompt="Ты исследователь. Возвращай факты с ссылками. Не делай выводов.",
    # контракт:  вход = тема (str)        →  выход = список фактов с источниками
)

analyst = Agent(
    role="Аналитик",
    goal="Сделать выводы из собранных фактов",
    tools=[run_sql, calculator],              # ← только анализ
    prompt="Ты аналитик. На основе фактов делай обоснованные выводы.",
    # контракт:  вход = факты              →  выход = выводы и цифры
)

writer = Agent(
    role="Писатель",
    goal="Оформить выводы в читаемый отчёт",
    tools=[],                                  # ← инструменты не нужны
    prompt="Ты редактор. Преврати выводы в структурированный отчёт.",
    # контракт:  вход = выводы             →  выход = готовый текст
)

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

Как проводить границы между ролями

Главный вопрос проектирования: на сколько агентов и каких бить задачу? Плохие границы хуже монолита — появляются агенты с размытыми, пересекающимися обязанностями, которые мешают друг другу.

  • Делить по способности/домену, а не произвольно. «Поиск», «анализ», «письмо» — естественные границы. «Агент для чётных дней» — нет.
  • Высокая связность внутри, низкая — между. Внутри роли действия тесно связаны; между ролями — минимум зависимостей и чёткий контракт.
  • Без пересечений ответственности. Если два агента могут сделать одно и то же, координатор будет путаться, кому поручить. Роли должны быть взаимоисключающими.
  • Роль должна быть осмысленной для человека. Хороший признак: роль легко назвать должностью («аналитик», «ревьюер»). Если название натянутое — граница плохая.
⚠️ Не дроби ради дробления

Специализация — не «чем больше агентов, тем лучше». Каждый агент добавляет накладные расходы на координацию (передачи, лишние вызовы LLM, задержку). Дроби, пока это снижает сложность каждой части; как только агенты начинают больше общаться, чем работать, — ты перестарался. Баланс и случаи, когда мультиагенты не нужны, — отдельный урок этого раздела.

Цена разделения

Честно обозначим: специализация — это компромисс, а не бесплатный выигрыш. За преимущества платят:

  • Координацией — кто-то должен раздавать работу и собирать результаты (супервайзер, конвейер). Это дополнительная логика и вызовы.
  • Задержкой — передачи между агентами добавляют шаги; последовательная команда может быть медленнее одного агента (частично лечится параллелизмом — следующий урок).
  • Числом «движущихся частей» — больше компонентов сложнее отлаживать и наблюдать (отсюда важность трейсинга из модуля 03).

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

Типичные ошибки

Ошибка 1: агент-монолит «на всё»

Один агент с 15 инструментами и промптом на пять ролей — посредственно везде. Если обязанности явно из разных доменов, это сигнал к разделению.

Ошибка 2: пересекающиеся роли

Два агента, умеющие одно и то же, ставят координатора в тупик и дублируют работу. Роли должны быть чёткими и взаимоисключающими.

Ошибка 3: нет контракта между ролями

Если непонятно, что именно агент принимает и возвращает, собрать его в команду нельзя — передачи рассыпаются. Определи вход/выход каждой роли как интерфейс.

Ошибка 4: слишком мелкое дробление

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

Шпаргалка

Разделение ответственности — всё в одном месте
text
ПРИНЦИП: один агент → одна зона ответственности (single responsibility)

Монолит «на всё»          →   Команда специалистов
 • промпт на 5 ролей            • узкий промпт под одну роль
 • 15 инструментов              • 1–2 инструмента
 • берёт не тот tool            • точный выбор
 • правка ломает всё            • независимое развитие/тесты
 • посредственно везде          • силён в своём + переиспользуем

СПЕЦИАЛИЗИРОВАННЫЙ АГЕНТ = 4 вещи:
 1. Роль (persona)          — кто он и за что отвечает
 2. Узкие инструменты       — только нужное роли
 3. Сфокусированный промпт  — инструкции одной роли
 4. Контракт вход/выход     — интерфейс для команды

ГРАНИЦЫ РОЛЕЙ:
 • делить по домену/способности, не произвольно
 • высокая связность внутри, низкая между
 • без пересечений ответственности
 • роль = понятная «должность»

ЦЕНА: координация + задержка + больше частей
 → специализация оправдана для МНОГОдоменных задач

Практическое задание

Потренируй проектирование ролей (без кода — это упражнение на декомпозицию):

Задание: разбей монолит на специалистов

  1. Возьми «агента-монолита»: помощник, который по запросу «подготовь обзор рынка X» ищет данные, считает метрики, пишет текст и проверяет его. Выпиши все инструменты и обязанности, которые ему пришлось бы дать.
  2. Раздели его на специализированных агентов. Для каждого определи 4 вещи: роль, набор инструментов, одну фразу системного промпта и контракт вход/выход.
  3. Проверь границы: нет ли двух агентов, умеющих одно и то же? Можно ли каждую роль назвать «должностью»?
  4. Нарисуй, как выход одного агента становится входом следующего (цепочка контрактов).
  5. Подумай, какой роли нужна сильная модель, а какой хватит дешёвой — и почему.
  6. Со звёздочкой: найди в своей декомпозиции место, где разделение избыточно (две роли проще слить), и обоснуй, почему дробить дальше не стоит.

Что дальше

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