CrewAI: мультиагентные системы и оркестрация | QantCore
QantCore Руководства для разработчиков
👥

CrewAI: мультиагентные системы и оркестрация

Создание команды AI-агентов с разделением ролей. Полный гайд по CrewAI — определение агентов с ролями и целями, постановка задач, оркестрация через последовательные и иерархические процессы, подключение инструментов, интеграция с LangChain и различными LLM-провайдерами. Готовые примеры для продакшн-использования.

advanced ⏱ 15 мин
👤 Задача Сложный проект 🚢 Crew Оркестратор Process: sequential Process: hierarchical crew.kickoff() 🔍 Researcher Role: Исследователь Goal: Сбор данных allow_delegation=False ✍️ Writer Role: Автор Goal: Создание текста backstory: Копирайтер ✅ Reviewer Role: Редактор Goal: Проверка verbose=True 🔧 Инструменты SerperDevTool calculator FileReadTool LangChain tools 📦 CrewOutput result + token_usage 🧠 LLM Providers OpenAI · Anthropic · Groq · Ollama

# 1. Установка CrewAI и настройка окружения

CrewAI — это фреймворк для оркестрации ролевых AI-агентов. В отличие от одиночных агентов, CrewAI позволяет создавать команды (crews) из нескольких агентов, каждый со своей ролью, целью и предысторией. Агенты работают совместно над общей задачей, передавая результаты друг другу. Фреймворк построен поверх LangChain и поддерживает множество LLM-провайдеров.

Установка проста: базовый пакет crewai включает всё необходимое для начала работы. Для продакшн-инструментов (веб-поиск, парсинг) потребуется отдельный пакет crewai-tools. Рекомендуется Python 3.10+ из-за использования современных возможностей asyncio и typing.

# Создаём окружение
python3 -m venv crew-env
source crew-env/bin/activate

# Установка CrewAI и инструментов
pip install crewai crewai-tools

# Для работы с разными LLM-провайдерами
pip install langchain-openai langchain-anthropic langchain-groq

# API-ключи (минимум один LLM-провайдер)
export OPENAI_API_KEY="sk-your-key"
export SERPER_API_KEY="your-serper-key"  # Для веб-поиска

# Быстрая проверка
python -c "from crewai import Agent, Task, Crew; print('CrewAI готов')"

# 2. Создание агентов с ролями, целями и бэкстори

Агент в CrewAI определяется тремя ключевыми параметрами: role (роль — кем является агент), goal (цель — что агент должен достичь) и backstory (предыстория — контекст, определяющий поведение). Это не просто системный промпт — это полноценная ролевая модель, которая влияет на все решения агента.

Дополнительные параметры: verbose включает подробное логирование, allow_delegation разрешает агенту делегировать подзадачи другим членам команды, max_iter ограничивает количество итераций. Агентам также можно выдать инструменты и указать конкретную LLM-модель.

from crewai import Agent
from langchain_openai import ChatOpenAI

# Настраиваем модель
gpt4 = ChatOpenAI(model="gpt-4o", temperature=0.3)
gpt4_mini = ChatOpenAI(model="gpt-4o-mini", temperature=0.5)

# Агент-исследователь: собирает информацию
researcher = Agent(
    role="Senior Research Analyst",
    goal="Найти и структурировать всю релевантную информацию по заданной теме",
    backstory="""Ты опытный аналитик с 15-летним стажем. Работал в McKinsey и BCG.
Твоя специализация — глубокий анализ рынков, технологий и трендов.
Ты помешан на точности данных и всегда проверяешь несколько источников.""",
    verbose=True,
    allow_delegation=False,
    llm=gpt4,
    max_iter=5,
)

# Агент-копирайтер: создаёт контент
writer = Agent(
    role="Technical Content Writer",
    goal="Создать убедительный, точный и структурированный текст на основе исследований",
    backstory="""Ты автор технического контента с опытом в разработке ПО.
Пишешь для аудитории CTO и senior-разработчиков. Твой стиль — чёткий,
без воды, с акцентом на практическую пользу. Знаешь Python, архитектуру и DevOps.""",
    verbose=True,
    allow_delegation=True,
    llm=gpt4,
)

# Агент-редактор: проверяет качество
reviewer = Agent(
    role="Quality Assurance Editor",
    goal="Проверить контент на точность, полноту и соответствие стандартам качества",
    backstory="""Ты главный редактор технического издания. 10 лет опыта в проверке
фактов и редактировании. Не пропускаешь ни одной неточности.
Твой девиз: 'Лучше перепроверить трижды, чем опубликовать ошибку'.""",
    verbose=True,
    allow_delegation=False,
    llm=gpt4_mini,
)

print(f"Создано агентов: {len([researcher, writer, reviewer])}")

# 3. Определение задач: связываем агентов с работой

Задачи (Tasks) в CrewAI — это не просто промпты. Каждая задача привязывается к конкретному агенту, содержит детальное описание и ожидаемый результат. Задачи поддерживают параметр context, который позволяет передавать результаты предыдущих задач последующим агентам. Это ключевой механизм для построения конвейера обработки.

Важный параметр async_execution позволяет запускать задачи параллельно, когда между ними нет зависимости. human_input включает режим подтверждения человеком — полезно для критических операций. output_file автоматически сохраняет результат в файл.

from crewai import Task

# Задача 1: Исследование (выполняет researcher)
research_task = Task(
    description="""Проведи всестороннее исследование технологии AI-агентов в 2026 году.
Включи следующие аспекты:
1. Ключевые фреймворки (CrewAI, AutoGen, LangGraph, OpenAI Agents SDK)
2. Сравнение архитектур: реактивные vs проактивные агенты
3. Тренды рынка: объём инвестиций, ключевые игроки, прогнозы
4. Производственные кейсы: кто и как использует агентов в продакшене
Собери минимум 5 конкретных фактов с указанием источников.""",
    expected_output="""Структурированный отчёт об исследовании в формате Markdown.
Минимум 800 слов, с разделами, подзаголовками и ссылками на источники.""",
    agent=researcher,
)

# Задача 2: Написание статьи (выполняет writer, зависит от research_task)
writing_task = Task(
    description="""На основе предоставленного исследования напиши техническую статью
для блога компании. Статья должна быть практической и содержать:
1. Введение: почему AI-агенты важны в 2026
2. Основная часть: обзор фреймворков с примерами кода
3. Сравнительная таблица фреймворков (минимум 5 критериев)
4. Рекомендации по выбору фреймворка в зависимости от задачи
5. Заключение с прогнозом на 2027 год""",
    expected_output="""Готовая статья в формате Markdown, 1500+ слов,
с таблицей сравнения и практическими рекомендациями.""",
    agent=writer,
    context=[research_task],  # Получает результат research_task
    output_file="article_draft.md",
)

# Задача 3: Рецензирование (выполняет reviewer, зависит от writing_task)
review_task = Task(
    description="""Проверь статью по следующим критериям:
1. Техническая точность всех утверждений
2. Полнота покрытия темы (не упущены ли важные аспекты)
3. Читабельность и структура
4. Качество примеров кода (работают ли они)
5. Соответствие tone-of-voice компании
Если найдены проблемы — внеси правки. Если всё хорошо — подтверди готовность.""",
    expected_output="""Отредактированная финальная версия статьи с комментариями о внесённых правках.
В начале укажи: '✅ Проверено' или '⚠️ Требует доработки' с пояснениями.""",
    agent=reviewer,
    context=[writing_task],
    output_file="article_final.md",
)

print(f"Создано задач: {len([research_task, writing_task, review_task])}")
print(f"Контекст writing_task: research_task (результат исследования)")
print(f"Контекст review_task: writing_task (черновик статьи)")

# 4. Сборка Crew: последовательный и иерархический процессы

Crew (команда) — это оркестратор, который объединяет агентов и задачи в единый рабочий процесс. CrewAI поддерживает два режима оркестрации: Process.sequential — задачи выполняются строго по порядку, результат каждой передаётся следующей; и Process.hierarchical — создаётся специальный агент-менеджер, который распределяет задачи между членами команды.

Выбор процесса зависит от задачи. Sequential хорош для конвейерной обработки (исследование → написание → редактура). Hierarchical лучше для сложных проектов, где нужна динамическая маршрутизация. Метод kickoff() запускает выполнение и возвращает CrewOutput с результатами и статистикой.

from crewai import Crew, Process

# === Режим 1: SEQUENTIAL (конвейер) ===
sequential_crew = Crew(
    agents=[researcher, writer, reviewer],
    tasks=[research_task, writing_task, review_task],
    process=Process.sequential,
    verbose=True,
    memory=True,              # Включаем память между запусками
    planning=True,            # CrewAI сам планирует шаги
    max_rpm=10,               # Лимит запросов в минуту к API
)

# Запуск
result = sequential_crew.kickoff()
print(f"Result type: {type(result)}")
print(f"Final output (первые 300 символов):\n{result[:300]}")

# === Режим 2: HIERARCHICAL (менеджер распределяет) ===
manager_llm = ChatOpenAI(model="gpt-4o", temperature=0.2)

hierarchical_crew = Crew(
    agents=[researcher, writer, reviewer],
    tasks=[research_task, writing_task, review_task],
    process=Process.hierarchical,
    manager_llm=manager_llm,   # LLM для агента-менеджера
    verbose=True,
    memory=True,
    planning=True,
)

# В иерархическом режиме менеджер сам решает порядок и распределение
result_h = hierarchical_crew.kickoff()
print(f"\n=== Иерархический результат ===")
print(f"Тип результата: {type(result_h)}")
print(f"Использовано токенов: {result_h.token_usage}")

# 5. Инструменты: веб-поиск, вычисления, чтение файлов

CrewAI предоставляет богатый набор встроенных инструментов через пакет crewai-tools. Каждый инструмент — это обёртка над API или утилитой, которую агент может вызывать в процессе работы. Инструменты передаются агенту через параметр tools при создании. Также поддерживаются любые инструменты из экосистемы LangChain.

Рассмотрим три ключевых инструмента: SerperDevTool для поиска в интернете через Google Serper API, CalculatorTool для математических вычислений, и FileReadTool для чтения файлов с диска. Комбинируя их, агент получает возможность искать информацию, производить расчёты и анализировать локальные данные.

import os
from crewai import Agent, Task, Crew, Process
from crewai_tools import (
    SerperDevTool,
    CalculatorTool,
    FileReadTool,
    ScrapeWebsiteTool,
)
from langchain_openai import ChatOpenAI

# Инициализируем инструменты
search_tool = SerperDevTool(
    serper_api_key=os.environ.get("SERPER_API_KEY"),
    country="ru",        # Региональный поиск
    locale="ru",         # Язык результатов
    n_results=5,      # Количество результатов
)

calc_tool = CalculatorTool(
    allowlist=["add", "multiply", "divide", "subtract", "power", "sqrt"],
)

file_tool = FileReadTool(
    file_path="/opt/data/report_2026.json",
)

scrape_tool = ScrapeWebsiteTool(
    website_url="https://example.com/ai-agents-report",
)

# Создаём агента с полным набором инструментов
analyst = Agent(
    role="Market Intelligence Analyst",
    goal="Собрать и проанализировать рыночные данные, подготовить аналитический отчёт",
    backstory="""Ты ведущий аналитик с доступом к поисковым системам, финансовым данным
и внутренним отчётам. Умеешь собирать разрозненные данные в единую картину.""",
    verbose=True,
    allow_delegation=False,
    tools=[search_tool, calc_tool, file_tool, scrape_tool],
    llm=ChatOpenAI(model="gpt-4o", temperature=0.3),
    max_iter=7,
)

analysis_task = Task(
    description="""Проведи анализ рынка AI-агентов:
1. Найди последние новости о внедрении AI-агентов в enterprise
2. Прочитай внутренний отчёт report_2026.json
3. Посчитай CAGR рынка: если в 2024 было $5.1B, а в 2026 прогнозируют $14.2B
4. Составь сводный отчёт с графиками (в текстовом описании)""",
    expected_output="Аналитический отчёт на 1000+ слов с рыночными данными и расчётами",
    agent=analyst,
    output_file="market_report.md",
)

crew = Crew(
    agents=[analyst],
    tasks=[analysis_task],
    process=Process.sequential,
    verbose=True,
)

# Запускаем анализ
report = crew.kickoff()
print(f"Отчёт сохранён. Токенов использовано: {report.token_usage}")

# 6. Интеграция с LLM-провайдерами и продакшн-деплой

CrewAI построен поверх LangChain, что означает поддержку десятков LLM-провайдеров: OpenAI, Anthropic Claude, Google Gemini, Groq, Mistral, локальные модели через Ollama и многие другие. Для production-использования критически важно настроить правильную модель под каждую роль: мощную модель для исследователя, более быструю и дешёвую для простых задач.

Ниже показан полный пример с тремя разными провайдерами и обёрткой в FastAPI для продакшн-деплоя. Агенты используют разные модели в зависимости от сложности задачи. Добавлена обработка ошибок, логирование и health-check эндпоинт для мониторинга.

import os
import logging
from typing import Optional
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from crewai import Agent, Task, Crew, Process
from langchain_openai import ChatOpenAI
from langchain_anthropic import ChatAnthropic
from langchain_groq import ChatGroq

# Логирование
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger("crewai-api")

# Три провайдера для разных ролей
model_smart = ChatOpenAI(model="gpt-4o", temperature=0.2)
model_fast = ChatGroq(model="llama-3.1-70b-versatile", temperature=0.3)
model_creative = ChatAnthropic(model="claude-3-5-sonnet-20241022", temperature=0.5)

# Агенты с разными провайдерами
strategist = Agent(
    role="Strategy Consultant",
    goal="Разработать стратегию на основе запроса",
    backstory="Эксперт по стратегии, 20 лет в консалтинге.",
    llm=model_smart,
    verbose=True,
)

copywriter = Agent(
    role="Creative Copywriter",
    goal="Создать убедительный текст",
    backstory="Креативный копирайтер международного уровня.",
    llm=model_creative,
    verbose=True,
)

executor = Agent(
    role="Task Executor",
    goal="Быстро выполнить рутинные операции",
    backstory="Эффективный исполнитель.",
    llm=model_fast,
    verbose=True,
)

# FastAPI приложение
app = FastAPI(title="CrewAI Production API", version="2.0")

class CrewRequest(BaseModel):
    topic: str
    mode: str = "sequential"  # sequential или hierarchical
    max_iter: int = 5

@app.post("/crew/execute")
async def execute_crew(req: CrewRequest):
    try:
        logger.info(f"Запуск Crew по теме: {req.topic}, режим: {req.mode}")

        task = Task(
            description=f"Подготовь материал на тему: {req.topic}. Стратегия → текст → финальная проверка.",
            expected_output="Готовый материал, структурированный и проверенный",
            agent=strategist,
        )

        process = Process.sequential if req.mode == "sequential" else Process.hierarchical

        crew = Crew(
            agents=[strategist, copywriter, executor],
            tasks=[task],
            process=process,
            verbose=True,
            max_rpm=10,
        )

        result = crew.kickoff()
        logger.info(f"Выполнено. Токенов: {result.token_usage}")

        return {
            "status": "success",
            "output": str(result)[:5000],
            "token_usage": result.token_usage,
            "mode": req.mode,
        }

    except Exception as e:
        logger.error(f"Ошибка: {e}")
        raise HTTPException(status_code=500, detail=str(e))

@app.get("/health")
async def health_check():
    return {
        "status": "healthy",
        "agents": ["strategist", "copywriter", "executor"],
        "providers": ["openai", "anthropic", "groq"],
    }

# Запуск: uvicorn crew_server:app --host 0.0.0.0 --port 8000 --workers 2
if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8000, workers=2)
✅ Итог

CrewAI — это мощный фреймворк для построения мультиагентных систем с ролевой моделью. Мы рассмотрели полный цикл: от создания агентов с ролями и предысториями до продакшн-деплоя через FastAPI с тремя разными LLM-провайдерами. Ключевые концепции — разделение ролей (researcher, writer, reviewer), связывание задач через контекст, два режима оркестрации (sequential и hierarchical), богатый набор инструментов и интеграция с LangChain. CrewAI особенно силён в сценариях, где нужна команда специалистов, работающих над сложным многоэтапным проектом — от исследования до финальной редактуры. Выбирайте sequential для конвейерной обработки и hierarchical для проектов с динамическим распределением задач.