Skip to content
IRC-CodingIRC-Coding
crewaiмультиагентные-системыpythonagent-frameworkобучениекоманды-агентов

CrewAI примеры: создание и координация команд агентов

Практические примеры CrewAI команд агентов. Изучите Roles, Tasks, Tools и координацию с кодом Python.

I

IRC-Coding Team

13 min read
CrewAI примеры: создание и координация команд агентов

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(), происходит следующее:

  1. Определяется порядок задач: При Process.sequential задачи выполняются по порядку. При Process.hierarchical порядок решает менеджер-агент.
  2. Выбирается агент: Каждая задача имеет параметр agent. Активируется соответствующий агент.
  3. Вызов LLM: Агент получает свою роль, цель, предысторию, описание задачи и результаты предыдущих задач как контекст.
  4. Использование инструментов: Если у агента есть инструменты, он может их вызвать (веб-поиск, чтение файлов и т.д.).
  5. Результат: Выходные данные агента передаются следующей задаче.
  6. Делегирование: Если 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 — что выбрать?

АспектCrewAILangGraph
ПодходНа основе ролей (метафора команды)На основе графов (теория графов)
Время настройки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.

Назад к блогу
Share:

Nächster Artikel in ИИ-программирование

Weiterlesen
Vibecoding: будущее программирования на ИИ

Похожие статьи