Мультиагентные системы: когда одного мало
Два главных паттерна связки агентов — и честный разговор о том, когда они вообще нужны.
Лестница сложности
Документация выделяет уровни: одиночный агент → делегирование → программная передача управления → графы → «глубокие» автономные агенты. Правило простое: поднимайся на ступеньку только когда текущей не хватает. Большинство реальных задач решается одним агентом с хорошими инструментами.
Паттерн 1. Делегирование: агент вызывает агента
Один агент использует другого как инструмент. Например, «отборщик» просит «генератора» сделать десять вариантов и выбирает лучший:
joke_selection_agent = Agent(
'openai:gpt-5.2',
instructions='Через joke_factory получи шутки и выбери одну лучшую.',
)
joke_generation_agent = Agent(
'google:gemini-3-flash-preview', # другая, более дешёвая модель!
output_type=list[str],
)
@joke_selection_agent.tool
async def joke_factory(ctx: RunContext, count: int) -> list[str]:
r = await joke_generation_agent.run(
f'Сгенерируй {count} шуток.',
usage=ctx.usage, # общий счётчик токенов на всю связку
)
return r.output
Заметь: агенты работают на разных моделях. Дорогая думает, дешёвая генерирует массу вариантов — так экономят бюджет.
Важная деталь — usage=ctx.usage: расход токенов вложенного агента записывается в общий счёт. Вместе с UsageLimits это страховка: вся связка агентов не потратит больше заданного лимита.
Паттерн 2. Программная передача управления
Агенты работают по очереди, а кто следующий — решает обычный код, не нейросеть. Пример из документации: сначала агент поиска рейса добивается результата FlightDetails, и только потом код запускает агента выбора места:
opt_flight = await find_flight(usage) # агент 1: ищет рейс
if opt_flight is not None:
seat = await find_seat(usage) # агент 2: выбирает место
Здесь видна философия Pydantic AI: каркас процесса — обычный, предсказуемый код (if, циклы), а нейросеть работает внутри отдельных шагов. Надёжность процесса не зависит от «настроения» модели.
Как выбрать паттерн
| Ситуация | Решение |
|---|---|
| Задача одного профиля: квалифицировать лид, сделать конспект | Один агент с инструментами |
| Внутри задачи есть подзадача другого профиля или под другую модель | Делегирование |
| Чёткие этапы: сначала собрать данные, потом оформить, потом проверить | Передача управления кодом |
| Сложные ветвления, циклы согласований, возвраты на шаг назад | Графы (pydantic-graph) — тяжёлая артиллерия, нужна редко |
Пример из твоей практики
Конвейер «эфир → урок в GetCourse» — это передача управления: код по очереди запускает агента-конспектировщика, агента-составителя квиза, агента-проверщика. А внутри проверщика может жить делегирование: он просит дешёвую модель прогнать квиз «глазами ученика». Каждый агент — простой и тестируемый отдельно, связка — обычный понятный код.
Наблюдаемость связки
Когда агентов несколько, важно видеть, кто что сделал и сколько потратил. Подключается двумя строками:
import logfire
logfire.configure()
logfire.instrument_pydantic_ai()
В интерфейсе Logfire видно каждый шаг: какой агент, какие инструменты, сколько токенов, где задержка.