CrewAI

Низкопороговый фреймворк для мультиагентных «команд»: агент описывается как должностная инструкция (role + goal + backstory + tools), задачи и процесс задают workflow. Самый быстрый способ собрать рабочий crew — ~20 строк кода. Сильная сторона — линейные пайплайны research→write→review, понятные бизнесу; слабая — дебаг циклов с feedback-loop и высокая стоимость токенов на длинных задачах.

Суть

CrewAI смотрит на MAS как на команду, а не граф (MAS Frameworks): вы «нанимаете» спец-агентов под одну бизнес-цель. Базовые объекты:

  • Agent — role («Senior Research Analyst»), goal, backstory, tools, llm.
  • Task — description, expected_output, agent (кому назначить), context (что подать на вход — обычно output другой задачи).
  • Crew — команда агентов + список задач + Process; manager_llm добавляется только к иерархическому процессу.
  • Process — sequential или hierarchical. Третьего значения нет: в перечислении лежит закомментированный consensual, но он не реализован. Параллельности как режима процесса в CrewAI не существует вовсе — задачи внутри процесса идут по порядку, а параллелизм достигается асинхронным запуском самих команд.

Три классические роли — PM/Planner (декомпозирует, назначает), Developer (исполняет), QA/Critic (ищет дефекты).

Как работает

  • Память (memory=True) — векторное хранилище: short-term (сессия), long-term (постоянная), entity memory (извлечённые сущности: люди, места, концепции). Для production-памяти между сессиями подключают Mem0.
  • Planning (planning=True) — доп. фаза: отдельный LLM-запрос анализирует все задачи и строит execution plan до запуска.
  • allow_delegation — может ли агент делегировать подзадачи другим (в простом пайплайне выключают: allow_delegation=False).
  • Дифференцированные модели: «умная» на планирование/критику, дешёвая на исполнение (см. Agent CostControl, Agent Routing).
  • Минусы: токен-стоимость высокая (context передаётся между задачами); cycles с feedback-loop дебажить сложно — для жёсткого контроля берут LangGraph; streaming ограничен.

Пример

Эволюция на учебном примере (CRM follow-up для лидов): Stage 1 — один Writer-агент; Stage 2 — crew {Researcher, Planner, Writer, Critic}; Stage 3 — тот же crew + Mem0 (память между сессиями, scoped по user_id=lead_id).

from crewai import Agent, Task, Crew, Process, LLM

llm_strong = LLM(model="openrouter/anthropic/claude-haiku-4.5",   # через OpenRouter
                 api_key=os.environ["OPENROUTER_API_KEY"],
                 base_url="https://openrouter.ai/api/v1", temperature=0.3)

writer = Agent(
    role="B2B Sales Follow-up Writer",
    goal="Написать персонализированное follow-up письмо лиду по истории взаимодействий.",
    backstory="Опытный B2B sales-копирайтер EdTech-платформы…",
    llm=llm_strong, verbose=True, allow_delegation=False,
)

crew = Crew(
    agents=[researcher, planner, writer, critic],
    tasks=build_tasks(lead_id),
    process=Process.hierarchical,                  # manager_llm работает только здесь
    manager_llm=supervisor_llm,
    memory=True,
)
result = await crew.kickoff_async()

Три места, где учебный код разошёлся с текущим API

Заметка собрана по материалу, который с тех пор устарел: CrewAI переехал. Расхождения перечислены отдельно, потому что каждое ломается по-своему: одно падает валидацией, второе молчит, третье молча ничего не делает.

Что в учебном коде Что на самом деле
Process.parallel Значения нет в перечислении — AttributeError
manager_llm при Process.sequential Параметр читается только на иерархическом пути. Валидация ругается лишь на обратное — отсутствие manager_llm при hierarchical. Здесь же supervisor просто никогда не вызывается, и это не видно ни по ошибке, ни по логу
memory_config={"provider": "mem0", …} Параметра нет. Поле memory принимает bool либо объект Memory / MemoryScope / MemorySlice, и внешняя память подключается через него

Второй случай стоит отдельного внимания: это не сломанный код, а инертный параметр. Команда работает, результат приходит, стоимость растёт на ровном месте только если supervisor всё-таки где-то дёргается, — а его нет. Ошибку такого рода не ловит ни запуск, ни тест на результат; ловит только чтение того, при каком процессе параметр вообще читается.

Встроенная память или внешний слой

Встроенная память фреймворка привязана к нему и к жизненному циклу запуска: она удобна, пока память нужна одной команде агентов внутри одного процесса и не переживает смену инструмента. Внешний слой (Mem0) нужен, когда выполняется хотя бы одно из трёх: память переживает фреймворк (сегодня CrewAI, завтра граф — переписывать хранилище не хочется); память общая для нескольких систем, а не для одной команды; нужны операции, которых у встроенной нет — извлечение фактов из диалога, разрешение противоречий, дедупликация.

Если ни одно не выполняется, внешний слой добавляет зависимость и сетевой вызов, ничего не покупая. Практический порядок обратный привычному: начинать со встроенной и выносить наружу по первому из трёх признаков, а не проектировать «правильно» сразу.

Связано с

  • MAS Frameworks — место CrewAI среди AutoGen/LangGraph/Mastra
  • Multi Agent Systems — когда вообще нужна «команда»
  • Multi Agent Patterns — роли исполнитель/критик, параллелизм
  • Mem0 — память между сессиями для crew
  • Agent CostControl — дорогая токен-стоимость как главный минус