Мультиагентная система с нуля: оркестратор, инструменты, память
Один LLM-агент ломается на задачах из десятка шагов. Разбираем, как собрать систему из нескольких агентов: кто кем управляет, как передавать состояние и где всё это чаще всего падает.

Один агент на базе LLM неплохо справляется с задачей в два-три шага: получить запрос, дёрнуть API, вернуть ответ. Но как только шагов становится десять, а инструментов — пятнадцать, качество проседает: модель забывает промежуточные результаты, путает инструменты, зацикливается. Отсюда популярность мультиагентных схем, где задачу дробят между несколькими специализированными агентами. Ниже — разбор архитектуры с нуля: из чего она состоит, какие паттерны оркестрации есть и на чём такие системы ломаются в проде.
Что считать агентом
Агент1 — это не просто вызов модели. Это цикл: модель получает контекст, решает, какой инструмент вызвать, получает результат вызова, снова думает — и так до достижения цели или лимита шагов. Минимальный агент состоит из трёх вещей: системного промпта (роль и правила), набора инструментов (функций, которые он умеет вызывать) и цикла управления, который прокручивает эти вызовы.
Мультиагентная система — это несколько таких циклов, между которыми ходят сообщения. Смысл дробления в том, что у каждого агента узкий контекст и короткий список инструментов. Агент, который умеет только искать в базе, ошибается реже, чем агент с тридцатью инструментами на все случаи жизни.
Мультиагентность решает не проблему интеллекта модели, а проблему контекста. Вы не делаете систему умнее — вы делаете каждый отдельный шаг проще и предсказуемее.
Три паттерна оркестрации
Прежде чем писать код, выберите, как агенты связаны между собой. От этого зависит всё остальное.
Оркестратор и воркеры
Один центральный агент (оркестратор) получает задачу, разбивает её на подзадачи и раздаёт специализированным воркерам, затем собирает результаты. Это самый управляемый вариант: поток решений сходится в одной точке, легко логировать и отлаживать. Минус — оркестратор становится узким местом и точкой отказа.
Цепочка (pipeline)
Агенты выстроены последовательно: выход одного — вход другого. Подходит, когда задача линейна: например, извлечь данные → нормализовать → сформировать отчёт. Прозрачно и дёшево в отладке, но не переживает ветвления: если на третьем шаге нужно вернуться ко второму, цепочка ломается.
Свободный граф (handoff)
Агенты передают управление друг другу по ситуации, без центрального дирижёра. Гибко, но именно здесь возникают бесконечные циклы и ситуации, когда два агента перекидывают задачу друг другу. Для старта не берите этот паттерн — с ним сложно предсказать поведение.
| Паттерн | Когда брать | Главный риск |
|---|---|---|
| Оркестратор + воркеры | Задача дробится на независимые куски | Оркестратор — узкое место |
| Цепочка | Линейный процесс без ветвлений | Не переживает возвраты назад |
| Свободный граф | Динамические сценарии, много ролей | Зацикливание, потеря контроля |
Для первой версии почти всегда правильный выбор — оркестратор с воркерами. Его легко превратить в цепочку и трудно — сломать непредсказуемо.
Собираем скелет
Возьмём паттерн «оркестратор + воркеры». Ниже — упрощённый цикл одного агента на Python без привязки к конкретному фреймворку, чтобы видеть механику. Клиент модели абстрагирован за функцией call_model.
def run_agent(system_prompt, tools, user_input, max_steps=8):
messages = [
{"role": "system", "content": system_prompt},
{"role": "user", "content": user_input},
]
for step in range(max_steps):
response = call_model(messages, tools=tools)
if response.tool_calls:
for call in response.tool_calls:
result = tools[call.name].run(**call.args)
messages.append({
"role": "tool",
"name": call.name,
"content": str(result),
})
else:
return response.content # финальный ответ
return "Достигнут лимит шагов"
Ключевая деталь — max_steps. Без жёсткого лимита агент, попавший в цикл, будет жечь токены, пока не упрётся в ваш кошелёк. Это первое, что нужно добавить, и последнее, что стоит убирать.
Оркестратор — тот же цикл, но его инструменты — это вызовы других агентов:
orchestrator_tools = {
"search_agent": Tool(run=lambda q: run_agent(SEARCH_PROMPT, search_tools, q)),
"writer_agent": Tool(run=lambda q: run_agent(WRITER_PROMPT, writer_tools, q)),
}
Так воркер для оркестратора выглядит как обычная функция. Это удобно: модель не знает и не должна знать, что за инструментом стоит ещё одна модель.
Память и передача состояния
Главная сложность мультиагентной системы — не логика вызовов, а то, что агенты не помнят друг о друге. Есть три уровня памяти, и их не стоит смешивать:
- Контекст шага — сообщения внутри одного цикла агента. Живёт, пока агент работает над задачей, и выбрасывается после.
- Разделяемое состояние — объект, который оркестратор передаёт воркерам и наполняет их результатами. Здесь копятся промежуточные данные: найденные факты, ID документов, флаги.
- Долгая память — база (векторная или обычная), из которой агент достаёт знания между сессиями. Отдельная инфраструктура, не путайте её с состоянием запроса.
Частая ошибка новичка — пихать всю историю в контекст каждого агента. Это раздувает промпт, повышает стоимость и путает модель. Передавайте воркеру только то, что нужно для его конкретной подзадачи.
Порядок сборки
Не начинайте с пяти агентов сразу. Правильный путь короткий:
- Соберите одного агента с двумя-тремя инструментами и добейтесь, чтобы он стабильно решал задачу. Если один агент не работает — мультиагентность его не спасёт.
- Добавьте лимит шагов, таймауты на инструменты и логирование каждого вызова. Без наблюдаемости отладка превратится в гадание.
- Выделите второго агента только тогда, когда у первого явно перегружен список инструментов или промпт стал нечитаемым.
- Поставьте оркестратор поверх двух воркеров и проверьте передачу состояния на реальных запросах.
- Прогоните набор из 20–30 типовых сценариев и посмотрите на цену и латентность каждого. Мультиагентная система в разы дороже одиночной по токенам.
Где всё ломается
Три беды повторяются почти в каждом проекте:
- Стоимость. Каждый агент — это отдельный вызов модели, а оркестратор вызывает их по кругу. Реальный запрос легко превращается в 15–20 обращений к API. Считайте бюджет заранее.
- Латентность. Последовательные вызовы складываются. Там, где можно, запускайте воркеров параллельно, а не цепочкой.
- Отладка. Когда система дала плохой ответ, надо понять, какой из агентов ошибся. Без трассировки каждого шага это невозможно. Логируйте вход, выход и вызовы инструментов для каждого агента с самого начала.
И честный вопрос перед стартом: а нужна ли вам вообще мультиагентность. Если задачу решает один агент с продуманным набором инструментов — оставьте его. Несколько агентов оправданы, когда роли действительно разные и контекст одного не помещается в разумный промпт.
Prompt-инженер: Идеальные запросы для Midjourney, ChatGPT и других моделей.
Спросить за 15 ₽Источники: Anthropic — Building effective agents, OpenAI — A practical guide to building agents
Частые вопросы
С какого фреймворка начинать — LangGraph, CrewAI, AutoGen или свой код?
Сколько агентов оптимально для первой системы?
Почему мультиагентная система работает медленнее одного агента?
Как не разориться на токенах?
Что делать, если агенты зацикливаются и перекидывают задачу друг другу?
Нужна ли векторная база сразу?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.