CrewAI: примеры создания и координации команд агентов
CrewAI — это Python-фреймворк для построения команд AI-агентов на основе ролевой модели. Вместо того чтобы описывать сложные графы (как в LangGraph), ты просто определяешь, кто входит в твою команду, что делает каждый и как они взаимодействуют. Это куда интуитивнее — думаешь в категориях ролей и задач, а не узлов и рёбер.
CrewAI разработан João Moura в 2024 году и быстро стал самым доступным фреймворком для мультиагентных систем. Он построен на LangChain, но скрывает сложность под удобным API. Если нужна рабочая команда агентов без погружения в теорию графов, CrewAI — идеальный выбор.
В этом туториале я покажу три полноценных практических примера: команду для создания контента, команду для code review и команду для поддержки клиентов. Все примеры работающие и готовы служить шаблоном для твоих проектов.
TL;DR — CrewAI за 90 секунд
CrewAI — это ролевой фреймворк для мультиагентных систем. Ты определяешь агентов (роль, цель, предыстория), задачи (описание и желаемый результат) и команду (координирует работу).
---
3 ключевых компонента: Agent (кто?), Task (что?), Crew (как работают вместе?).
Главное преимущество: Быстро настраивается. Рабочая команда из 3 агентов за 50 строк Python.
Ограничение: Меньше контроля, чем в LangGraph. Сложные условные потоки и циклы требуют больше работы.
Конец краткого обзора!
Архитектура CrewAI: как это работает
Ролевая модель
CrewAI построен на простой, но мощной идее: ты моделируешь команду агентов как реальную команду людей. Каждый агент имеет:
- Роль (Role): Кто такой агент? “Senior Data Analyst”, “Tech Writer”, “Security Expert”
- Цель (Goal): Что агент хочет достичь? “Найти все уязвимости в коде”
- Предыстория (Backstory): Какой опыт и характер у агента? “Ты специалист по безопасности с 15-летним опытом в тестировании на проникновение”
- Инструменты (Tools): Какие утилиты доступны агенту? Веб-поиск, выполнение кода, доступ к файлам
Предыстория важна — она влияет на то, как LLM “размышляет” и отвечает. Агент с предысторией “Ты строгий рецензент, не идущий на компромиссы” будет отвечать иначе, чем агент с предысторией “Ты полезный наставник, поддерживающий разработчиков”.
Жизненный цикл задачи
Когда ты вызываешь crew.kickoff(), происходит следующее:
- Определяется порядок задач: При
Process.sequentialзадачи выполняются по порядку. ПриProcess.hierarchicalпорядок решает менеджер-агент. - Выбирается агент: Каждая задача имеет параметр
agent. Активируется соответствующий агент. - Вызов LLM: Агент получает свою роль, цель, предысторию, описание задачи и результаты предыдущих задач как контекст.
- Использование инструментов: Если у агента есть инструменты, он может их вызвать (веб-поиск, чтение файлов и т.д.).
- Результат: Выходные данные агента передаются следующей задаче.
- Делегирование: Если
allow_delegation=True, агент может переложить задачу на других агентов.
Последовательное выполнение против иерархического
Последовательное (стандартное): Задачи выполняются одна за другой. Результат задачи 1 автоматически попадает в контекст задачи 2. Просто, предсказуемо, хорошо для линейных потоков.
Иерархическое: Менеджер-агент получает все задачи и решает, кто что делает и в каком порядке. Менеджер может перераспределять задачи, переупорядочивать их и оценивать результаты. Подходит для сложных потоков, но дороже (дополнительный LLM-вызов для менеджера).
Установка и настройка
pip install crewai crewai-tools
API-ключи:
export OPENAI_API_KEY="sk-..."
# Для веб-поиска через SerperDev:
export SERPER_API_KEY="..."
Локальные модели (бесплатно для разработки):
# Установи Ollama и загрузи модель
ollama pull llama3.1:8b
# Используй в CrewAI:
from langchain_community.llms import Ollama
llm = Ollama(model="llama3.1:8b")
3 ключевых компонента: подробно
1. Agent — член команды
from crewai import Agent
researcher = Agent(
role="Senior Research Analyst",
goal="Найди комплексную, актуальную и точную информацию по заданной теме",
backstory="""Ты опытный Research Analyst с 10-летним стажем.
У тебя есть доступ к научным базам данных и ты знаешь,
как отличить надёжные источники от ненадёжных.
Ты всегда структурируешь исследование чётко и указываешь источники.""",
verbose=True, # Детальные логи
allow_delegation=False, # Этот агент не делегирует
tools=[search_tool], # Инструменты для агента
llm=llm # Опционально: собственная LLM для этого агента
)
Важные параметры:
verbose=True: Показывает подробные логи. Незаменимо для отладки.allow_delegation: ЕслиTrue, агент может переложить задачи на других. Полезно для менеджеров, опасно при частых делегированиях (стоимость!).tools: Список инструментов LangChain. Без инструментов агент просто чатбот.llm: На каждого агента может быть своя LLM. Например, GPT-4o для сложных задач, GPT-4o-mini для простых.max_iter: Максимум итераций (по умолчанию 25). Защищает от бесконечных циклов.memory: ЕслиTrue, агент запоминает контекст между задачами.
2. Task — задача
from crewai import Task
research_task = Task(
description="""Исследуй последние разработки в AI-программировании на 2026 год.
Учти новые инструменты, лучшие практики и практические примеры.
Отчёт должен содержать минимум 5 ключевых пунктов.""",
expected_output="""Детальный отчёт с 5 ключевыми пунктами (по 2-3 предложения),
с указанием источников и кратким резюме в конце.""",
agent=researcher,
output_file="output/research_report.md" # Опционально: результат в файл
)
Важные параметры:
description: Будь конкретен. Расплывчатые задачи дают расплывчатые результаты.expected_output: Опиши, как должен выглядеть результат. Это самый важный параметр. Вместо “напиши статью” напиши “напиши статью объёмом 800 слов в Markdown с введением, 3 подразделами и заключением”.agent: Какой агент выполняет эту задачу?context: Список других задач, результаты которых нужны как контекст.output_file: Сохраняет результат в файл. Удобно для отладки.
3. Crew — Команда
from crewai import Crew, Process
crew = Crew(
agents=[researcher, writer, editor],
tasks=[research_task, write_task, edit_task],
process=Process.sequential, # или Process.hierarchical
verbose=True,
memory=True, # Память между несколькими запусками
cache=True, # Кеш результатов инструментов
max_rpm=10 # Rate-limiting: запросы в минуту
)
result = crew.kickoff()
Что делает kickoff(): проверяет агентов и задачи, определяет порядок выполнения, запускает каждую задачу (агент получает контекст + задачу, вызывает LLM, возвращает результат) и возвращает финальный результат.
Пример 1: Content-Creation-Crew (Полный)
Команда из Researcher, Writer и Editor для написания статей в блог с реальными инструментами, детальными промптами и выходными файлами.
import os
from crewai import Agent, Task, Crew, Process
from crewai_tools import SerperDevTool, ScrapeWebsiteTool
# Инициализация инструментов
search_tool = SerperDevTool()
web_scraper = ScrapeWebsiteTool()
# --- AGENTS ---
researcher = Agent(
role="Senior Content Researcher",
goal="Собери обоснованную, актуальную и точную информацию по теме",
backstory="""Ты эксперт по исследованиям с доступом к научным источникам
и технологичным блогам. Ты умеешь отличать надёжные источники от
ненадёжных. Всегда структурируешь исследование чётко и указываешь
все источники с URL.""",
tools=[search_tool, web_scraper],
verbose=True,
allow_delegation=False
)
writer = Agent(
role="Tech Journalist",
goal="Напиши привлекательную, информативную и хорошо структурированную статью",
backstory="""Ты награждённый технический журналист, который объясняет
сложные темы понятным языком. Пишешь для технической аудитории,
ищущей практическое применение. Используешь активный голос, короткие
предложения и конкретные примеры.""",
verbose=True,
allow_delegation=False
)
editor = Agent(
role="Senior Editor",
goal="Обеспечь качество, корректность, читаемость и SEO-оптимизацию",
backstory="""Ты строгий редактор с 20-летним опытом. Проверяешь
грамматику, стиль, фактическую корректность и SEO-ключевые слова.
Даёшь конкретную обратную связь и улучшаешь статью напрямую.
Не приемлешь неточные утверждения или отсутствующие источники.""",
verbose=True,
allow_delegation=True # Редактор может делегировать Researcher или Writer
)
# --- TASKS ---
research_task = Task(
description="""Исследуй тему 'Python Frameworks 2026'.
Найди ТОП 5 Python-фреймворков для веб-разработки в 2026 году с
плюсами и минусами, практическими примерами и сравнением производительности.
Используй веб-поиск для актуальной информации.""",
expected_output="""Структурированное исследование с ТОП 5 фреймворками,
плюсами/минусами каждого, минимум 3 источника на фреймворк,
и рекомендацией для 3 сценариев (стартап, enterprise, прототип).""",
agent=researcher,
output_file="output/research.md"
)
write_task = Task(
description="""Напиши статью в блог (800-1200 слов) на основе исследования.
Структура: введение, основная часть с подзаголовками, таблица сравнения,
практические примеры, заключение. Пиши на русском, обращайся к читателю
на "ты", используй активный голос.""",
expected_output="""Полная статья в Markdown: 800-1200 слов,
структура H1/H2, таблица сравнения, примеры кода, чёткая рекомендация.""",
agent=writer,
output_file="output/article_draft.md"
)
edit_task = Task(
description="""Проверь и улучши статью: грамматика, стиль,
фактическая корректность, SEO (мета-описание, ключевые слова, заголовки),
и практическое применение. Улучши неточные утверждения.""",
expected_output="""Финальная отредактированная статья в Markdown с
SEO-мета-описанием, улучшенной читаемостью, проверенными источниками.""",
agent=editor,
output_file="output/article_final.md"
)
# --- CREW ---
content_crew = Crew(
agents=[researcher, writer, editor],
tasks=[research_task, write_task, edit_task],
process=Process.sequential,
verbose=True,
memory=True
)
result = content_crew.kickoff()
print(result)
Как это работает: Researcher использует веб-поиск, Writer получает исследование в контексте и пишет статью, Editor проверяет и улучшает, может делегировать при необходимости. Каждый шаг сохраняет выходные файлы для отладки. Затраты на GPT-4o: примерно 0.50-2.00$ за один запуск.
Пример 2: Code-Review-Crew (Полный)
Команда для автоматизированных code review с фокусом на безопасность.
from crewai import Agent, Task, Crew, Process
from crewai_tools import DirectoryReadTool, FileReadTool
file_reader = FileReadTool()
dir_reader = DirectoryReadTool(directory="src/")
# --- AGENTS ---
code_reviewer = Agent(
role="Senior Security Code Reviewer",
goal="Определи баги, проблемы безопасности, проблемы производительности и нарушения best practices",
backstory="""Ты эксперт по безопасности с 15-летним опытом. Знаешь
OWASP Top 10, CWE-Top-25 и распространённые security-паттерны.
Ревьюишь код систематично: сначала security, потом баги, потом стиль.
Присваиваешь каждой проблеме уровень серьёзности (Critical/High/Medium/Low).""",
tools=[file_reader, dir_reader],
verbose=True
)
refactorer = Agent(
role="Refactoring Specialist",
goal="Улучши качество кода без изменения функциональности",
backstory="""Ты специализируешься на Clean Code, SOLID-принципах и
Design Patterns. Рефакторишь консервативно: небольшие, безопасные изменения.
Никогда не нарушаешь существующую функциональность. Объясняешь
каждое изменение.""",
tools=[file_reader],
verbose=True
)
doc_writer = Agent(
role="Technical Writer",
goal="Создай ясную, понятную документацию для улучшенного кода",
backstory="""Пишешь понятную техническую документацию для разработчиков.
Используешь примеры кода, диаграммы и таблицы. Документируешь не только
ЧТО, но и ПОЧЕМУ.""",
verbose=True
)
# --- TASKS ---
review_task = Task(
description="""Ревью весь код в директории src/.
Проверь: OWASP Top 10, проблемы с аутентификацией, захардкодированные
секреты, обработку ошибок, производительность (N+1 запросы), code smells.
Используй DirectoryReadTool и FileReadTool для чтения всех файлов.""",
expected_output="""Отчёт code review с таблицей всех проблем
(файл, строка, серьёзность, описание), сгруппированных по серьёзности,
с конкретной рекомендацией для каждой проблемы.""",
agent=code_reviewer,
output_file="output/code_review.md"
)
refactor_task = Task(
description="""Рефактори код на основе review.
Приоритет: 1. Исправь Critical/High проблемы, 2. Закрой security-лазейки,
3. Сократи code smells. ВАЖНО: Не меняй функциональность!""",
expected_output="""Рефакторенный код со всеми изменениями
(файл, что изменилось, почему), сравнение до/после для критических
изменений, обоснование каждого рефакторинга.""",
agent=refactorer,
output_file="output/refactored_code.md"
)
doc_task = Task(
description="""Документируй изменения и новый код.
Создай CHANGELOG.md, документацию функций и security-checklist.""",
expected_output="""Полная документация: CHANGELOG.md,
документация модулей с описаниями функций, примеры кода,
security-checklist для будущих разработок.""",
agent=doc_writer,
output_file="output/documentation.md"
)
# --- CREW ---
code_crew = Crew(
agents=[code_reviewer, refactorer, doc_writer],
tasks=[review_task, refactor_task, doc_task],
process=Process.sequential,
verbose=True
)
result = code_crew.kickoff()
print(result)
Почему это работает: Reviewer читает код и находит проблемы с помощью file-инструментов, Refactorer получает список проблем и улучшает код, Doc Writer документирует всё. Последовательный процесс: каждый шаг строится на предыдущем.
Пример 3: Команда поддержки клиентов (иерархический процесс)
Автоматизированная служба поддержки с координацией через менеджера.
from crewai import Agent, Task, Crew, Process
from crewai_tools import SerperDevTool, FileReadTool
search_tool = SerperDevTool()
kb_reader = FileReadTool()
# --- AGENTS ---
triage_agent = Agent(
role="Support Triage Specialist",
goal="Категоризируй и расставляй приоритеты входящих тикетов поддержки",
backstory="""Ты анализируешь запросы поддержки за секунды. Определяешь
серьёзность, категорию (Technical, Billing, Feature Request) и
срочность. Направляешь каждый тикет нужному агенту.""",
verbose=True
)
solver_agent = Agent(
role="Technical Support Engineer",
goal="Быстро и правильно решай технические проблемы клиентов",
backstory="""Ты универсал в решении технических проблем.
Знаешь базу знаний вдоль и поперёк, можешь искать в документации.
Если решение неизвестно, честно об этом скажешь и предложишь
временные варианты.""",
tools=[search_tool, kb_reader],
verbose=True
)
escalation_agent = Agent(
role="Escalation Manager",
goal="Передавай нерешённые проблемы нужной команде со всем контекстом",
backstory="""Ты решаешь, когда задачу нужно передать специалистам.
Следишь, чтобы вся информация была передана, чтобы специалист
не начинал с нуля. Расставляешь приоритеты эскалаций по влиянию на бизнес.""",
verbose=True
)
# --- TASKS ---
triage_task = Task(
description="""Проанализируй тикет поддержки: 'Клиент не может войти.
Ошибка: Invalid token. Chrome на Windows 11.'
Определи категорию, серьёзность, срочность и рекомендуемого агента.""",
expected_output="""Отчёт триажа с категорией, серьёзностью и обоснованием,
срочностью, рекомендуемым агентом и начальной оценкой (2-3 предложения).""",
agent=triage_agent
)
solve_task = Task(
description="""Попробуй решить проблему. Поищи в базе знаний
'Invalid token' и 'Login problems'. Поищи решения в интернете.
Если решаемо: пошаговая инструкция. Если нет: подготовь эскалацию.""",
expected_output="""Либо предложение решения с пошаговой инструкцией
и ссылкой на статью в БЗ, либо отчёт эскалации со всей информацией
и рекомендацией для команды-получателя.""",
agent=solver_agent
)
escalation_task = Task(
description="""Если проблема не решена, подготовь профессиональную
эскалацию с описанием проблемы, предыдущими попытками решения,
системой клиента, влиянием на бизнес и рекомендацией.""",
expected_output="""Тикет эскалации с кратким резюме, всеми предыдущими
шагами, оценкой влияния на бизнес и рекомендацией по приоритету.""",
agent=escalation_agent
)
# --- CREW (ИЕРАРХИЧЕСКИЙ) ---
support_crew = Crew(
agents=[triage_agent, solver_agent, escalation_agent],
tasks=[triage_task, solve_task, escalation_task],
process=Process.hierarchical, # Менеджер решает порядок!
verbose=True
)
result = support_crew.kickoff()
print(result)
Зачем иерархический процесс? При работе с тикетами поддержки оптимальный порядок не всегда очевиден. Иногда агент может решить проблему сразу. Иногда нужна срочная эскалация. Менеджер принимает решение динамически. Минус: каждое решение менеджера стоит дополнительного LLM-вызова, но гибкость того стоит.
Собственные инструменты для CrewAI
Создавай свои инструменты, когда встроенных недостаточно:
from crewai_tools import BaseTool
class DatabaseQueryTool(BaseTool):
name: str = "Database Query Tool"
description: str = "Выполняет SQL-запросы и возвращает результаты."
def _run(self, query: str) -> str:
import sqlite3
conn = sqlite3.connect("database.db")
cursor = conn.cursor()
try:
cursor.execute(query)
results = cursor.fetchall()
return str(results)
except Exception as e:
return f"Query failed: {str(e)}"
finally:
conn.close()
class APIRequestTool(BaseTool):
name: str = "API Request Tool"
description: str = "Делает HTTP-запросы к API."
def _run(self, url: str, method: str = "GET") -> str:
import requests
response = requests.request(method, url)
return response.text
# Использование:
db_tool = DatabaseQueryTool()
api_tool = APIRequestTool()
analyst = Agent(
role="Data Analyst",
goal="Анализируй данные из базы",
backstory="Ты эксперт в SQL.",
tools=[db_tool, api_tool]
)
Важное в собственных инструментах:
descriptionкритична — LLM решит по ней, использовать инструмент или нет_runдолжна возвращать строку (это видит LLM)- Обработка ошибок в инструменте: всегда возвращай полезную строку, не исключение
- Безопасность: очищай входные данные! LLM может сгенерировать произвольный SQL-запрос
Лучшие практики из реальной работы
1. Backstory важнее, чем ты думаешь
Backstory определяет “характер” агента и сильно влияет на качество. “Ты строгий рецензент, который каждое утверждение подтверждает источниками” даст совсем другие результаты, чем просто “Ты рецензент”.
2. Expected Output должен быть конкретным
“Напиши статью” приведёт к размытому результату. “Напиши статью объёмом 800 слов в Markdown с H1/H2-структурой, 3 примерами кода и таблицей сравнения” даст точный результат.
3. Инструменты делают разницу
Агент без инструментов — это просто чатбот. С веб-поиском, доступом к файлам или API-интеграцией он становится действительно полезным.
4. Контролируй затраты
Каждый агент делает минимум 1 LLM-вызов. При 3 агентах, делегировании и менеджере это легко 10+ вызовов. Используй GPT-4o-mini для простых задач и GPT-4o только для сложных.
5. Используй output-файлы
output_file для каждой задачи сохраняет промежуточные результаты. Бесценно для отладки — ты видишь ровно то, что произвёл каждый агент.
CrewAI vs. LangGraph — что выбрать?
| Аспект | CrewAI | LangGraph |
|---|---|---|
| Подход | На основе ролей (метафора команды) | На основе графов (теория графов) |
| Время настройки | 10 мин на 3 агента | 30-60 мин на один процесс |
| Контроль | Менее детальный | Очень детальный (условные рёбра) |
| Кривая обучения | Пологая, интуитивная | Крутая, требует понимания графов |
| Циклы/петли | Ограничены (max_iter) | Встроены (условные рёбра) |
| Human-in-the-Loop | Вручную | Встроено (interrupt) |
| Делегирование | Встроено (allow_delegation) | Реализуется вручную |
| Manager-агент | Встроен (Process.hierarchical) | Реализуется как узел |
| Подходит для | Стандартные рабочие процессы, прототипы | Сложные условные процессы, production |
Мои рекомендации:
- CrewAI для: создания контента, code review, поддержки клиентов, простых команд из 2-5 агентов
- LangGraph для: сложных production-процессов с циклами, условиями, Human-in-the-Loop
- Оба могут сосуществовать — CrewAI для быстрых прототипов, LangGraph для production-версии
Частые проблемы и решения
Проблема: агент галлюцинирует источники
Решение: дайте агенту инструмент веб-поиска и добавьте в описание задачи: “Все утверждения должны быть подкреплены источниками.”
Проблема: агент слишком много делегирует
Решение: установите allow_delegation=False для агентов, которые должны работать самостоятельно. Только менеджеры и рецензенты должны иметь право делегировать.
Проблема: выполнение Crew занимает слишком много времени
Решение: уменьшите max_iter, используйте более быстрые модели (GPT-4o-mini), сократите количество агентов, отключите memory.
Проблема: результаты поверхностные
Решение: уточните expected_output конкретными требованиями (длина, структура, формат).
Ключевые моменты для экзамена
- CrewAI: фреймворк многоагентной системы на основе ролей, построен на базе LangChain
- 3 основных компонента: Agent (роль, цель, история, инструменты), Task (описание, expected_output, агент), Crew (агенты + задачи + процесс)
- Типы процессов: Sequential (линейный порядок) vs. Hierarchical (менеджер-агент координирует)
- Делегирование:
allow_delegation=Trueпозволяет агентам передавать задачи другим - Инструменты: встроенные (SerperDev, ScrapeWebsite, FileRead, DirectoryRead) и пользовательские (BaseTool)
- Память:
memory=Trueдля сохранения контекста между взаимодействиями - Файлы результатов:
output_fileдля каждой задачи помогает в отладке и отслеживании промежуточных результатов - Затраты: минимум один LLM-вызов на агента; менеджер и делегирование требуют дополнительных вызовов
- Сравнение: CrewAI (быстро, интуитивно, ограниченный контроль) vs. LangGraph (сложно, гибко, готово к боевому применению)
Часто задаваемые вопросы
Может ли CrewAI работать с локальными моделями?
Да, через интеграцию Ollama: from langchain_community.llms import Ollama; llm = Ollama(model="llama3.1:8b"). Вы можете установить llm для каждого агента или глобально в Crew. Локальные модели хороши для разработки, но облачные модели обычно дают лучшие результаты.
Сколько агентов должно быть в Crew? Обычно 3-5 агентов, и их легко координировать. Больше 8 становится сложно управлять — агенты начинают слишком много делегировать, а затраты растут. Для сложных задач лучше разделить на несколько небольших Crew.
Могут ли агенты взаимодействовать друг с другом?
Да, с allow_delegation=True агенты могут делегировать задачи друг другу. При Process.hierarchical менеджер-агент может координировать всех агентов и перераспределять задачи.
Как отлаживать Crew?
Три инструмента: 1) verbose=True для подробных логов. 2) output_file для каждой задачи — промежуточные результаты. 3) LangSmith-трейсинг (переменные окружения: LANGCHAIN_TRACING_V2=true).
Сколько стоит один запуск CrewAI? С GPT-4o и 3 агентами: примерно 0.50-2.00$ за запуск. С GPT-4o-mini: примерно 0.05-0.20$. С локальными моделями (Ollama): 0$, но медленнее и ниже качество.
Рекомендуемая литература
Keine Bücher für Kategorie "ki-agenten" gefunden.


