Пока агент умеет немного, один промпт и пять инструментов отлично работают вместе. Но представьте помощника для отдела продаж, которому нужны CRM, календарь, почта, база знаний и аналитика — в сумме три десятка инструментов. Модели становится труднее выбрать нужный, промпт разрастается до нескольких страниц правил для разных областей, а контекст забивается результатами инструментов, которые к текущему вопросу не относятся.
Решение — разделить работу между несколькими специализированными агентами, как в обычной команде. Каждый отвечает за свою область, у него короткий промпт и свой небольшой набор инструментов. Главный агент понимает запрос и решает, кому его поручить. После урока вы сможете собрать такую систему, понимать, когда она оправдана, и оценивать, во что она обходится.
Что уже умеем
Вы создавали агентов через create_agent, оборачивали функции в инструменты декоратором @tool и знаете, что модель выбирает инструмент по его имени и описанию. В уроке 4.1 вы видели, что агент — это граф, который можно вызвать как обычную функцию. Сегодня объединим эти идеи: агент станет инструментом другого агента.
Что вы узнаете в рамках статьи
- когда одного агента становится мало и чем помогает разделение ролей;
- как устроен паттерн supervisor с субагентами;
- как обернуть агента в инструмент и передать его главному агенту;
- почему так важны имя и описание инструмента-субагента;
- чем паттерн handoffs отличается от субагентов и сколько стоит мультиагентность.
Ключевые термины
- Мультиагентная система — несколько агентов, которые вместе решают задачу, каждый в своей роли.
- Субагент — специализированный агент со своим промптом и инструментами, которого вызывает другой агент.
- Supervisor (главный агент) — агент, который принимает запрос пользователя, поручает части работы субагентам и собирает итоговый ответ.
- Изоляция контекста — субагент видит только поставленную ему задачу, а не всю историю главного агента.
- Handoff (передача управления) — паттерн, в котором активный агент передаёт разговор другому агенту, и дальше с пользователем общается уже тот.
Субагенты: каждый в своей области
Начнём с двух специалистов. Агент по заказам умеет искать заказ, агент по базе знаний отвечает на вопросы о правилах магазина. Это обычные агенты из второго модуля, ничего нового в них нет.
from langchain.agents import create_agent
from langchain.tools import tool
@tool
def find_order(order_id: str) -> str:
"""Возвращает статус и сумму заказа по его номеру."""
return f"Заказ {order_id}: 4990 руб., передан в доставку 12 марта"
@tool
def search_policy(query: str) -> str:
"""Ищет правила магазина: доставка, возврат, гарантия."""
return "Возврат возможен в течение 14 дней при сохранении упаковки."
orders_agent = create_agent(
model="openai:gpt-6-luna",
tools=[find_order],
system_prompt="Ты специалист по заказам. Отвечай фактами из инструментов, кратко.",
)
policy_agent = create_agent(
model="openai:gpt-6-luna",
tools=[search_policy],
system_prompt="Ты специалист по правилам магазина. Цитируй найденное правило.",
)
У каждого субагента один инструмент и короткий промпт про свою область. Такого агента легко проверить отдельно и улучшать, не трогая остальную систему.
Supervisor: агент, у которого агенты — инструменты
Главный агент не знает, как искать заказы. Зато у него есть инструменты, внутри которых работают субагенты. Обёртка — обычная функция с @tool: она передаёт субагенту задачу как сообщение пользователя и возвращает текст его последнего сообщения.
@tool("orders_agent", description="Вопросы о конкретных заказах: статус, сумма, доставка. Передай номер заказа и вопрос.")
def call_orders_agent(task: str) -> str:
result = orders_agent.invoke({"messages": [{"role": "user", "content": task}]})
return result["messages"][-1].content
@tool("policy_agent", description="Вопросы о правилах магазина: возврат, гарантия, условия доставки.")
def call_policy_agent(task: str) -> str:
result = policy_agent.invoke({"messages": [{"role": "user", "content": task}]})
return result["messages"][-1].content
supervisor = create_agent(
model="openai:gpt-6-luna",
tools=[call_orders_agent, call_policy_agent],
system_prompt=(
"Ты координатор поддержки. Разбей вопрос клиента на части, "
"поручи каждую подходящему специалисту и собери единый ответ."
),
)
result = supervisor.invoke({"messages": [{
"role": "user",
"content": "Где мой заказ A-17 и смогу ли я его вернуть, если не подойдёт?",
}]})
print(result["messages"][-1].content)
Что увидим в консоли: ответ вроде «Заказ A-17 передан в доставку 12 марта. Вернуть его можно в течение 14 дней при сохранении упаковки». За кулисами главный агент вызвал оба инструмента-субагента, каждый из них прошёл свой цикл с собственной моделью и инструментами, а главный агент собрал результаты в один ответ.
Субагент возвращает только последнее сообщение. Промежуточные вызовы инструментов, длинные выдержки из документов и рассуждения остаются внутри него и не засоряют контекст главного агента. Это и есть изоляция контекста. Отсюда практическое правило: в промпте субагента требуйте, чтобы всё важное было в финальном ответе, — остального главный агент не увидит.
Имя и описание — главный рычаг управления
Главный агент выбирает субагента так же, как любой инструмент: по имени и описанию. Поэтому описание — это не формальность, а часть промпта. Хорошее описание говорит, какие задачи субагент решает и какие данные ему нужно передать. Сравните: "Помощник" ничего не сообщает модели, а "Вопросы о конкретных заказах: статус, сумма, доставка. Передай номер заказа и вопрос." сразу подсказывает и область, и формат задачи.
Помните и о том, что субагент по умолчанию не видит переписку с пользователем. Если клиент назвал номер заказа три сообщения назад, главный агент должен явно включить его в аргумент task. Если ответы субагента выглядят так, будто он не понял вопрос, первым делом проверьте, что именно ему передали.
Handoffs и цена мультиагентности
Субагенты — не единственная схема. В паттерне handoffs агенты передают друг другу управление: например, агент первой линии переключает разговор на агента по возвратам, и дальше клиент общается напрямую с ним. Такая схема удобна для долгих диалогов внутри одной области, но работает последовательно и не умеет параллельно советоваться с несколькими специалистами. Субагенты дают централизованный контроль: всё проходит через главного агента.
За этот контроль приходится платить. Даже простой вопрос в схеме с одним субагентом требует минимум четыре обращения к модели: главный агент решает вызвать субагента, субагент вызывает свой инструмент, субагент формулирует ответ, главный агент отвечает пользователю. Один агент с тем же инструментом справился бы за два обращения. Поэтому начинайте с одного агента и переходите к нескольким, когда инструментов и правил становится слишком много, области заметно различаются или над частями системы работают разные команды. Для простых субагентов часто достаточно дешёвой gpt-6-luna, а более сильную gpt-6.1-sol разумно ставить только туда, где нужна сложная работа.
Частые ошибки
- Делить на агентов без необходимости. Три субагента там, где хватило бы одного агента с тремя инструментами, увеличивают стоимость и задержку без выигрыша в качестве.
- Размытые описания субагентов. Главный агент путает специалистов, если их области пересекаются или описаны общими словами. Описывайте границы чётко.
- Ожидать, что субагент знает историю. Субагент получает только
task. Все нужные факты главный агент должен передать явно. - Терять результат внутри субагента. Главный агент видит лишь последнее сообщение субагента. Требуйте в промпте полного и самодостаточного итогового ответа.
Наиболее частые вопросы
- Можно ли дать субагентам разные модели? — Да, у каждого
create_agentсвоя модель. Простые роли отдайте дешёвой модели, сложные — более сильной. - Может ли субагент вызывать своих субагентов? — Технически да, но каждый уровень добавляет обращения к модели. Обычно хватает одного уровня.
- Помнит ли субагент прошлые вызовы? — В нашей схеме нет: каждый вызов начинается с чистого листа. Это упрощает отладку, но означает повторную передачу контекста.
- Чем это отличается от графа из урока 4.1? — В графе маршрут задаёте вы кодом, а в схеме supervisor субагента выбирает модель. Их можно сочетать: например, поставить классификатор-маршрутизатор перед несколькими агентами.
Итоги
Поздравляем, теперь вы умеете собирать из агентов команду! Вы разобрались, зачем делить ответственность между специалистами, собрали главного агента, у которого субагенты подключены как обычные инструменты, и поняли, почему имя, описание и изоляция контекста решают успех такой системы. Вы также знаете, чем субагенты отличаются от handoffs и почему каждая дополнительная роль стоит лишних обращений к модели.
В следующем уроке вы подключите к агентам внешние инструменты по стандартному протоколу MCP — без необходимости писать обёртку для каждого сервиса вручную.