CrewAI Multi-Agents

Course Content

CrewAI Multi-Agents

9 sections · 53 lessons

What is a Crew in CrewAI, and how does it manage execution?


What you need to know

What happens inside kickoff

  1. Before kickoff — optional hooks (@before_kickoff in a @CrewBase class) can clean or add inputs.
  2. Interpolate — {placeholders} in agent and task text are filled from inputs.
  3. Run tasks — in list order; each task goes to its agent (sequential) or to the manager (hierarchical).
  4. Pass context — each task receives earlier outputs, all of them by default or those named in context.
  5. Check — output_pydantic conversion and guardrails; failed checks retry the task.
  6. Return — a CrewOutput; @after_kickoff hooks can post-process it.

Reading the result

Python
result = crew.kickoff(inputs={"city": "Indore", "category": "cloud kitchens"})result.raw            # last task's textresult.pydantic       # last task's model, if it set output_pydanticresult.tasks_output   # list of TaskOutput, one per task, in orderresult.token_usage    # prompt, completion and total tokens

tasks_output and token_usage are the cheapest debugging and cost data you get: which task produced what, and what it cost.

Running many times

MethodBehaviour
kickoff(inputs)one run, blocking
kickoff_for_each(inputs=[...])one run per input, one after another
akickoff(inputs)one run with native async, for use inside async code
akickoff_for_each(inputs=[...])one run per input, concurrently
replay(task_id=...)re-run from a task, reusing saved outputs of earlier tasks

From the command line, crewai run runs the project, crewai log-tasks-outputs lists the saved task IDs from the last run, and crewai replay -t <task_id> replays from one.

Crew-wide settings worth knowing

  • memory=True — shared memory across tasks and runs.
  • cache=True — reuse identical tool results (off by default since CrewAI 1.15.3).
  • max_rpm — a request-rate limit for the whole crew.
  • step_callback, task_callback — your functions called after each agent step and each task.
  • planning=True — a planner writes a plan for every task before the run.

A real-life example

A market-research team at a cloud-kitchen chain needs the same competitor scan for 12 cities every Monday. The crew has a researcher, a pricing analyst and a writer.

They first called kickoff_for_each with 12 inputs and wondered why it took 18 minutes: it runs the cities one after another, about 90 seconds each. Switching to await crew.akickoff_for_each(inputs=cities) ran them concurrently, and with max_rpm=60 to respect the provider's limit the whole batch took about 4 minutes.

One Monday the writer task failed for Pune because the model timed out. Instead of re-running research (the expensive part), they used crewai log-tasks-outputs to find the writer task's ID and crewai replay -t <id>, which reused the saved research and analysis. token_usage from each result went into a cost dashboard: about Rs 14 per city.

Follow-up questions to expect

  • "Where do I put setup logic, like loading a customer record?" — In a @before_kickoff method in the @CrewBase class, or in the Flow step that calls the crew.
  • "Is a Crew object reusable?" — Yes for repeated kickoffs, but kickoff_for_each copies it per input so runs do not share task outputs. Create fresh crews per request in a web server to avoid shared state.
  • "How do I stream output to a UI?" — Set stream=True on the crew and iterate the streaming output, or listen to CrewAI events.