Один агент — это один мозг. Он думает, вызывает инструменты, помнит контекст. Для простых задач этого хватает. Но когда задача сложная — нужна команда. Один агент ищет информацию, другой пишет текст, третий проверяет качество. Каждый специалист в своём деле. В этом уроке — как устроены мульти-агентные системы, когда они нужны (и когда нет), и как построить свою.
В уроке 3.5 один агент выполнял мульти-шаговые задачи — сам планировал, сам делал, сам проверял. Это работает, пока задача помещается в «голову» одного агента. Но есть четыре ситуации, когда одного агента недостаточно:
Проблема 1: Контекстное окно переполняется
Агент прочитал 50 файлов, вызвал 20 инструментов — окно забито.
Старая информация начинает теряться.
Проблема 2: Нужна специализация
Один агент пытается быть экспертом по безопасности, стилю кода,
бизнес-логике и документации одновременно. Результат — средний во всём.
Проблема 3: Задача слишком сложная для одного плана
15 подзадач в разных областях. Агент теряет нить, путает шаги,
забывает, что уже сделал.
Проблема 4: Независимые задачи идут последовательно
Агент делает шаг 1, потом шаг 2, потом шаг 3 — хотя шаги 2 и 3
не зависят друг от друга и могли бы выполняться параллельно.
Один агент — это фрилансер. Отличный специалист для небольших проектов. Но строить дом в одиночку невозможно: нужен архитектор (планирование), электрик (проводка), сантехник (трубы) и прораб (координация). Каждый знает своё дело. Прорабу не нужно уметь паять трубы — ему нужно знать, кого вызвать и когда.
Мульти-агентная система — это команда агентов, где каждый выполняет свою роль, а координатор (оркестратор) управляет процессом.
Anthropic в своём исследовании «Building Effective Agents» (декабрь 2024) предупреждает:
«Самая частая ошибка — строить мульти-агентную систему там, где один агент с хорошими инструментами справился бы сам.»
Вот простое правило выбора:
Задача решается одним вызовом API?
ДА → Не нужен даже агент. Просто промпт.
Один агент с инструментами справляется в цикле?
ДА → Один агент (как в уроке 3.5).
Задача требует разных специализаций?
Контекстное окно одного агента переполняется?
Подзадачи можно выполнять параллельно?
ДА на любой → Рассмотри мульти-агентную систему.
Принцип: начинай с простого. Добавляй сложность только когда простое не работает.
Источник: Anthropic — Building Effective Agents
https://www.anthropic.com/research/building-effective-agents
В уроке 3.5 были 5 паттернов Anthropic. Три из них — это мульти-агентные паттерны. Добавим ещё один (конвейер) и разберём каждый подробно.
┌─────────────────┐
│ ОРКЕСТРАТОР │
│ (прораб) │
└───┬────┬────┬───┘
│ │ │
┌─────────▼┐ ┌▼────┴────┐
│ Рабочий A│ │ Рабочий B│ (параллельно или
│(электрик)│ │(сантехник)│ последовательно)
└─────┬────┘ └────┬─────┘
│ │
┌─────▼───────────▼─────┐
│ Оркестратор собирает │
│ результаты → Итог │
└───────────────────────┘
Оркестратор — «менеджер». Он получает задачу, сам решает, какие подзадачи нужны (не по шаблону, а динамически), создаёт рабочих агентов, собирает их результаты и формирует итог.
Это самый мощный и гибкий паттерн. Именно его использует Claude Code — когда сложная задача, он запускает суб-агентов через встроенный инструмент Agent (из урока 3.4).
Агент 1 Агент 2 Агент 3
(Исследователь) → (Писатель) → (Редактор)
"Найди факты" "Напиши статью" "Проверь и отредактируй"
Каждый агент — специалист со своим системным промптом и инструментами. Выход одного агента становится входом для следующего. Как конвейер на заводе: каждый делает свою операцию и передаёт дальше.
Когда использовать: задача имеет чёткие последовательные этапы, где каждый этап требует других навыков.
Генератор ──► Оценщик ──► "Оценка: 6/10. Проблемы: ..."
▲ │
└──────────────┘ (цикл, пока оценка < 9/10)
Два агента с разными ролями: один создаёт, другой критикует. Генератор улучшает работу на основе обратной связи. Это как отношения «автор + редактор» или «разработчик + ревьюер».
Когда использовать: есть чёткие критерии качества и задача выигрывает от итеративного улучшения.
┌─ Агент безопасности: ищет уязвимости
Задача ───────┼─ Агент стиля: проверяет форматирование
└─ Агент логики: ищет ошибки
│
Агрегатор: объединяет все находки
Несколько агентов получают одни и те же данные и обрабатывают их одновременно и независимо. Результаты объединяются.
Когда использовать: задачу можно разделить на независимые аспекты (безопасность, стиль, логика).
У агентов нет «телепатии». Им нужен способ передать информацию друг другу. Есть три основных механизма:
Самый простой. Выход одного агента вставляется во вход следующего.
# Агент 1 выполняет задачу и возвращает результат
research = researcher_agent("Мульти-агентные системы")
# Результат передаётся Агенту 2 как входные данные
article = writer_agent(f"Напиши статью на основе:\n{research}")
Аналогия: Передать папку с документами из одного отдела в другой.
Все агенты читают и пишут в общее хранилище — словарь, файл или базу данных.
shared = {}
# Исследователь записывает в общую память
shared["facts"] = researcher_agent("...")
# Писатель читает оттуда
shared["draft"] = writer_agent(shared["facts"])
# Редактор читает и дополняет
shared["feedback"] = editor_agent(shared["draft"])
Аналогия: Общий Google Doc, где каждый участник работает в своём разделе.
Один агент полностью передаёт управление другому вместе со всей историей разговора. Используется в OpenAI Agents SDK.
Агент A → обработал сообщение → передал управление Агенту B
Агент B → видит всё, что делал Агент A → продолжает
Аналогия: Перевод звонка в колл-центре — «Переключаю вас на отдел оплаты» — новый оператор видит заметки предыдущего.
| Механизм | Плюсы | Минусы |
|---|---|---|
| Передача сообщений | Простой, понятный | Нужно форматировать данные |
| Общая память | Гибкий, любой агент видит всё | Сложнее отлаживать |
| Handoff | Сохраняется полный контекст | Контекстное окно заполняется |
Для большинства задач передача сообщений — лучший выбор. Просто и предсказуемо.
Никакие фреймворки не нужны. Каждый агент — это функция, которая вызывает Claude API со своим системным промптом.
Система из трёх агентов: 1. Оркестратор — получает задачу, определяет тему и стиль 2. Исследователь — собирает ключевые факты 3. Писатель — превращает факты в статью
Пользователь: "Напиши статью про RAG для новичков"
│
┌────▼─────┐
│Оркестратор│ → Тема: "RAG", Стиль: "для начинающих"
└────┬─────┘
│
┌────▼──────────┐
│ Исследователь │ → 5 ключевых фактов про RAG
└────┬──────────┘
│
┌────▼────┐
│ Писатель│ → Готовая статья на основе фактов
└─────────┘
# multi_agent.py — мульти-агентная система без фреймворков
import os
from dotenv import load_dotenv
from anthropic import Anthropic
load_dotenv()
client = Anthropic() # ключ из ANTHROPIC_API_KEY
# === АГЕНТ 1: ИССЛЕДОВАТЕЛЬ ===
def researcher_agent(topic):
"""
Агент-исследователь.
Получает тему → возвращает список ключевых фактов.
У него свой системный промпт (специализация).
"""
print(f" [Исследователь] Ищу факты по теме: {topic}")
response = client.messages.create(
model="claude-haiku-4-5-20251001", # дешёвая модель для рабочих агентов
max_tokens=1024,
system=(
"Ты — агент-исследователь. Твоя задача — собрать "
"5-7 ключевых фактов по заданной теме. "
"Формат: нумерованный список. Без вступлений, только факты. "
"Каждый факт — 1-2 предложения."
),
messages=[{
"role": "user",
"content": f"Собери ключевые факты по теме: {topic}"
}]
)
facts = response.content[0].text
print(f" [Исследователь] Готово ({len(facts)} символов)\n")
return facts
# === АГЕНТ 2: ПИСАТЕЛЬ ===
def writer_agent(facts, style):
"""
Агент-писатель.
Получает факты + стиль → возвращает статью.
"""
print(f" [Писатель] Пишу статью (стиль: {style})")
response = client.messages.create(
model="claude-haiku-4-5-20251001",
max_tokens=2048,
system=(
f"Ты — агент-писатель. Твоя задача — написать короткую статью "
f"(3-4 абзаца) на основе предоставленных фактов. "
f"Стиль: {style}. Используй простые аналогии. "
f"Не добавляй факты от себя — используй только то, что дано."
),
messages=[{
"role": "user",
"content": f"Напиши статью на основе этих фактов:\n\n{facts}"
}]
)
article = response.content[0].text
print(f" [Писатель] Готово ({len(article)} символов)\n")
return article
# === ОРКЕСТРАТОР ===
def orchestrator(task):
"""
Главный агент — оркестратор.
1. Анализирует задачу
2. Определяет тему и стиль
3. Вызывает рабочих агентов в нужном порядке
4. Возвращает итоговый результат
"""
print(f"[Оркестратор] Анализирую задачу...\n")
# Шаг 1: Оркестратор понимает задачу
plan_response = client.messages.create(
model="claude-haiku-4-5-20251001",
max_tokens=256,
system=(
"Ты — оркестратор. У тебя есть два рабочих агента:\n"
"1. researcher — находит факты по теме\n"
"2. writer — пишет статью по фактам\n\n"
"Проанализируй задачу и определи:\n"
"- Какую тему передать исследователю\n"
"- В каком стиле писать статью\n\n"
"Ответь СТРОГО в формате:\n"
"ТЕМА: <тема>\n"
"СТИЛЬ: <стиль>"
),
messages=[{"role": "user", "content": task}]
)
plan = plan_response.content[0].text
print(f"[Оркестратор] План:\n{plan}\n")
# Шаг 2: Извлекаем тему и стиль из ответа
topic = task # fallback
style = "для начинающих"
for line in plan.split("\n"):
if line.upper().startswith("ТЕМА:"):
topic = line.split(":", 1)[1].strip()
elif line.upper().startswith("СТИЛЬ:"):
style = line.split(":", 1)[1].strip()
# Шаг 3: Вызываем исследователя
facts = researcher_agent(topic)
# Шаг 4: Передаём факты писателю
article = writer_agent(facts, style)
return article
# === ЗАПУСК ===
if __name__ == "__main__":
print("=" * 50)
print(" МУЛЬТИ-АГЕНТНАЯ СИСТЕМА")
print(" Оркестратор → Исследователь → Писатель")
print("=" * 50 + "\n")
task = input("Задача: ").strip()
if not task:
task = "Напиши статью про искусственный интеллект для школьников"
result = orchestrator(task)
print("=" * 50)
print("\nИТОГОВАЯ СТАТЬЯ:\n")
print(result)
pip install anthropic python-dotenv
# Убедись, что .env содержит ANTHROPIC_API_KEY
python multi_agent.py
==================================================
МУЛЬТИ-АГЕНТНАЯ СИСТЕМА
Оркестратор → Исследователь → Писатель
==================================================
Задача: Напиши статью про RAG для новичков
[Оркестратор] Анализирую задачу...
[Оркестратор] План:
ТЕМА: RAG (Retrieval-Augmented Generation)
СТИЛЬ: для начинающих, простым языком с аналогиями
[Исследователь] Ищу факты по теме: RAG (Retrieval-Augmented Generation)
[Исследователь] Готово (487 символов)
[Писатель] Пишу статью (стиль: для начинающих, простым языком)
[Писатель] Готово (1203 символов)
==================================================
ИТОГОВАЯ СТАТЬЯ:
RAG — это способ дать AI доступ к вашим документам...
Каждый агент — это ОТДЕЛЬНЫЙ вызов client.messages.create()
Что у каждого своё:
• Системный промпт (специализация)
• Контекст (не забит чужими данными)
• Роль (исследователь не пишет статьи, писатель не ищет факты)
Что общее:
• Один API-клиент (один API-ключ)
• Одна модель (можно разные — haiku для рабочих, sonnet для оркестратора)
• Данные передаются через аргументы функций
Превратим конвейер в цикл «генератор-оценщик»:
def evaluator_agent(article, criteria):
"""
Агент-оценщик.
Проверяет статью по критериям, ставит оценку.
"""
response = client.messages.create(
model="claude-haiku-4-5-20251001",
max_tokens=512,
system=(
"Ты — агент-оценщик. Оцени текст по критериям. "
"Поставь оценку от 1 до 10. "
"Если оценка < 8, напиши конкретные замечания для улучшения.\n\n"
"Формат ответа:\n"
"ОЦЕНКА: <число>\n"
"ЗАМЕЧАНИЯ: <что улучшить>"
),
messages=[{
"role": "user",
"content": f"Критерии: {criteria}\n\nТекст:\n{article}"
}]
)
return response.content[0].text
def write_with_review(facts, style, max_rounds=3):
"""
Писатель + Оценщик в цикле.
Писатель пишет → Оценщик оценивает → Писатель переписывает.
Максимум max_rounds итераций.
"""
article = writer_agent(facts, style)
for round_num in range(max_rounds):
print(f" [Оценщик] Раунд {round_num + 1}...")
evaluation = evaluator_agent(article, "Понятность, точность, стиль")
# Извлекаем оценку
score = 0
for line in evaluation.split("\n"):
if "ОЦЕНКА:" in line.upper():
try:
score = int(''.join(c for c in line.split(":")[-1] if c.isdigit()))
except ValueError:
score = 0
print(f" [Оценщик] Оценка: {score}/10")
if score >= 8:
print(f" [Оценщик] Статья принята!\n")
break
# Передаём замечания писателю для улучшения
print(f" [Оценщик] Отправляю замечания писателю...\n")
response = client.messages.create(
model="claude-haiku-4-5-20251001",
max_tokens=2048,
system=f"Ты — писатель. Улучши статью на основе замечаний. Стиль: {style}.",
messages=[{
"role": "user",
"content": f"Статья:\n{article}\n\nЗамечания:\n{evaluation}\n\nУлучши статью."
}]
)
article = response.content[0].text
return article
Теперь вместо writer_agent(facts, style) вызываем write_with_review(facts, style) — и статья проходит через цикл улучшений.
Если подзадачи независимы — можно запустить агентов одновременно:
import asyncio
from anthropic import AsyncAnthropic
async_client = AsyncAnthropic()
async def review_code(code):
"""Три агента проверяют код параллельно."""
async def check(system_prompt, code_text):
response = await async_client.messages.create(
model="claude-haiku-4-5-20251001",
max_tokens=512,
system=system_prompt,
messages=[{"role": "user", "content": code_text}]
)
return response.content[0].text
# Запускаем три проверки одновременно
security, style, logic = await asyncio.gather(
check("Ты — эксперт по безопасности. Найди уязвимости.", code),
check("Ты — эксперт по стилю кода. Найди проблемы форматирования.", code),
check("Ты — эксперт по логике. Найди ошибки и edge cases.", code),
)
return {
"security": security,
"style": style,
"logic": logic
}
# Запуск: asyncio.run(review_code("def foo(): ..."))
Без asyncio.gather три проверки заняли бы 6-15 секунд (последовательно). С параллельным запуском — 2-5 секунд (время самого медленного агента).
Можно строить всё вручную (как в примерах выше), а можно использовать фреймворк:
Что тебе нужно?
│
├── Учёба, простые проекты
│ → Без фреймворка (просто функции + anthropic)
│ → Понимаешь, что происходит на каждом шаге
│
├── Команда агентов с ролями
│ → CrewAI: Agent("Исследователь"), Agent("Писатель")
│ → Самый простой фреймворк для начала
│
├── Агенты обсуждают задачу между собой
│ → AutoGen (Microsoft): агенты ведут диалог
│
├── Сложные графы с ветвлениями
│ → LangGraph: визуальные графы, контрольные точки
│
├── Передача управления (handoff)
│ → OpenAI Agents SDK: агенты переключают друг друга
│
└── Суб-агенты как инструменты
→ Claude Agent SDK: агент запускает подчинённых
→ Так работает Claude Code
| Фреймворк | Подход | Сложность | Модели |
|---|---|---|---|
| Без фреймворка | Функции + API | Минимальная | Любые |
| CrewAI | Команда с ролями | Простая | Любые |
| AutoGen | Диалог агентов | Средняя | Любые |
| LangGraph | Граф с узлами | Высокая | Любые |
| OpenAI Agents SDK | Handoff | Простая | Только OpenAI |
| Claude Agent SDK | Суб-агенты | Простая | Только Claude |
Для обучения — начинай без фреймворка (как в этом уроке). Когда поймёшь принципы — фреймворк будет не магией, а удобным инструментом.
Источники:
CrewAI: https://docs.crewai.com/
AutoGen: https://microsoft.github.io/autogen/
LangGraph: https://langchain-ai.github.io/langgraph/
OpenAI Agents SDK: https://openai.github.io/openai-agents-python/
┌──────────────────────────────────────────────────────────┐
│ КТО ИСПОЛЬЗУЕТ МУЛЬТИ-АГЕНТОВ │
│ │
│ Claude Code (Anthropic) │
│ Главный агент запускает суб-агентов через │
│ инструмент Agent. Каждый суб-агент получает │
│ своё контекстное окно и фокусную задачу. │
│ │
│ Devin (Cognition) │
│ «AI-программист»: планировщик + кодер + │
│ браузер + терминал. Агенты делят рабочее │
│ пространство через файлы. │
│ │
│ GitHub Copilot Workspace │
│ Конвейер: спецификация → план → реализация → │
│ валидация. Человек может вмешаться на каждом шаге. │
│ │
│ Cursor (редактор кода) │
│ Разные агенты для разных задач: автодополнение │
│ (быстрая модель), чат (большая модель), │
│ применение изменений (специализированный агент). │
│ │
│ ChatGPT │
│ Маршрутизация: текстовый запрос → один обработчик, │
│ генерация изображения → DALL-E, код → Code │
│ Interpreter. Каждый — отдельный специалист. │
│ │
└──────────────────────────────────────────────────────────┘
Источники:
Anthropic — Claude Code: https://docs.anthropic.com/en/docs/claude-code
Devin: https://devin.ai/
GitHub Copilot Workspace: https://github.blog/news-insights/product-news/github-copilot-workspace/
Один агент: 1 задача = 1-5 вызовов API = $0.01-0.05
Три агента: 1 задача = 3 × 3-5 вызовов = $0.05-0.30
+ оркестратор = $0.10-0.50
Итого: в 5-10 раз дороже одного агента
Решение: дешёвая модель (Haiku) для рабочих агентов, дорогая (Sonnet) — только для оркестратора или сложных задач.
Если Агент 1 нашёл неправильные факты, Агент 2 напишет уверенную статью с неправильными фактами, а Агент 3 отредактирует грамматику — но факты останутся неверными.
Решение: добавляй проверки между агентами. Агент-оценщик может ловить ошибки.
С одним агентом — один лог. С пятью агентами — нужно проследить, как данные прошли через всех пятерых, и понять, кто сломал результат.
Решение: логируй вход и выход каждого агента. Как print() в примере выше — но для продакшна используй logging.
Каждый вызов API — 2-10 секунд. Цепочка из 4 агентов = 8-40 секунд ожидания.
Решение: параллельные агенты (asyncio) для независимых задач.
Скопируй код multi_agent.py, запусти его с разными задачами:
- «Напиши статью про квантовые компьютеры для детей»
- «Напиши обзор AI-фреймворков для разработчиков»
- «Напиши пост в блог про Python»
Посмотри, как оркестратор определяет тему и стиль для каждой задачи.
Добавь в систему evaluator_agent и функцию write_with_review. Запусти и посмотри:
- Сколько раундов улучшений проходит статья?
- Как меняется текст после каждого раунда?
- Увеличился ли счёт за API?
Добавь агента-переводчика, который берёт готовую статью и переводит её на английский. Встрой его в конвейер после писателя.
Задача 1: В чём главное отличие мульти-агентной системы от мульти-шагового агента?
Задача 2: Почему Anthropic рекомендует начинать с одного агента?
Задача 3: Какой паттерн лучше подходит для код-ревью (проверка кода)?
Задача 4: Что такое handoff?
| Термин | Что значит |
|---|---|
| Мульти-агентная система | Система из нескольких AI-агентов, которые вместе решают задачу |
| Оркестратор | Главный агент, который координирует работу других агентов |
| Рабочий агент (worker) | Агент-специалист, выполняющий конкретную подзадачу |
| Конвейер (pipeline) | Паттерн: агенты работают последовательно, каждый передаёт результат дальше |
| Генератор-оценщик | Паттерн: один агент создаёт, другой оценивает, цикл до нужного качества |
| Параллельные агенты | Паттерн: несколько агентов работают одновременно над разными аспектами |
| Message passing | Передача данных между агентами через аргументы функций |
| Shared state | Общая память, доступная всем агентам (словарь, БД, файл) |
| Handoff | Передача управления от одного агента к другому (с историей) |
| CrewAI | Фреймворк: агенты как команда с ролями |
| AutoGen | Фреймворк (Microsoft): агенты ведут диалог друг с другом |
| LangGraph | Фреймворк (LangChain): агенты как узлы в графе |
| Суб-агент | Подчинённый агент, запущенный основным (так работает Claude Code) |
| asyncio.gather | Функция Python для запуска нескольких задач параллельно |
Мульти-агентная система = команда AI-агентов
Когда нужна:
• Контекстное окно одного агента переполняется
• Задача требует разных специализаций
• Подзадачи можно выполнять параллельно
• Нужен цикл «создай → проверь → улучши»
Когда НЕ нужна:
• Один агент справляется (большинство задач)
• Бюджет ограничен (в 5-10 раз дороже)
• Нужна скорость (каждый агент = +2-10 секунд)
4 паттерна:
1. Оркестратор + рабочие — менеджер делегирует задачи
2. Конвейер — каждый агент передаёт результат дальше
3. Генератор + оценщик — цикл улучшений
4. Параллельные агенты — одновременная работа
Реализация без фреймворка:
Агент = функция, которая вызывает client.messages.create()
со своим системным промптом. Данные передаются через аргументы.
Реальные примеры:
Claude Code, Devin, Copilot Workspace, Cursor, ChatGPT
Мы научились строить команды агентов. Следующий урок — fine-tuning: как дообучить модель под свои задачи. Это альтернатива RAG — вместо поиска данных в базе, знания «вшиваются» в модель.