

The first time I built a working multi-agent system in CrewAI, I had it running in under an hour. That experience sold me on the framework. CrewAI takes opinionated decisions about how a crew of agents should be structured, and those decisions match the way I already think about teams. Agents have roles. Roles have goals. Goals decompose into tasks. Tasks are assigned to agents. The crew runs the work.
In this tutorial I will walk you through building a first CrewAI multi-agent system step by step. We will start with installation, build a hello-world researcher and writer crew, add tools, layer in memory, then explore the difference between sequential and hierarchical processes. I will close with deployment notes and a brief comparison to AutoGen so you know when CrewAI is the right fit and when another framework would serve you better.
This is a hands-on tutorial. The pseudo-code I will share is close to current CrewAI syntax but simplified so the concepts come through clearly. The framework continues to evolve, so check the official docs for the latest API specifics. The patterns I show should carry over even if the function names shift.
CrewAI is the framework I reach for when I want to build a multi-agent system quickly and the topology fits an organisational pattern. It maps a small group of specialised agents to a well-defined task. The vocabulary of role, goal, and backstory is intuitive, and the abstractions stay out of your way once you understand them.
The framework is opinionated. It pushes you toward designs where agents have clear roles and tasks have clear owners. For most production multi-agent systems this is what you want anyway. The opinion matches the use case.
What CrewAI is not good at is highly customised workflows that do not fit its sequential or hierarchical process model. If you need cycles, complex branching, or unusual coordination patterns, LangGraph gives you more flexibility. If you need conversational multi-agent designs with human participants, AutoGen has the edge. CrewAI sits in the sweet spot of medium-complexity production crews.
I have shipped several CrewAI systems to production and they have held up well. The framework is mature enough for serious use in 2026, and the team continues to add capabilities.
CrewAI has four core abstractions. Understanding all four before you write code saves a lot of confusion later.
The relationships are straightforward. Agents have access to tools. Tasks reference agents. The crew bundles agents and tasks together with a process. When you call kickoff on the crew, the work begins.
Role, goal, backstory, task. If you can describe each agent’s identity and each task’s outcome in one sentence, you can build it in CrewAI.
The crew abstraction is what makes CrewAI feel like a team rather than a script. You are designing an organisation, not a pipeline.
Getting started is straightforward. You need Python 3.10 or newer, an API key for whichever LLM provider you plan to use, and a few minutes to install the package.
pip install crewai
pip install 'crewai[tools]'
The first install gives you the core framework. The second adds the standard tool catalogue, which includes search, file system access, and several common integrations. Set your API key as an environment variable, typically OPENAI_API_KEY or ANTHROPIC_API_KEY depending on which provider you use.
I recommend creating a virtual environment for your project before installing. CrewAI pulls in a non-trivial dependency tree, and isolating it from your system Python keeps things tidy. Pin the version in your requirements file so future updates do not surprise you.
For development I also install LangSmith or another tracing platform. CrewAI integrates with several observability backends, and you will want one as soon as your crew gets more complex than the hello world.
The hello world for CrewAI is a two-agent crew where a researcher gathers information and a writer turns it into a summary. Here is the pseudo-code.
from crewai import Agent, Task, Crew, Process
researcher = Agent(
role="Senior Research Analyst",
goal="Find accurate and current information on agentic AI trends",
backstory="You are an experienced analyst who has spent years tracking AI.",
llm=research_llm,
verbose=True
)
writer = Agent(
role="Technical Writer",
goal="Turn research notes into a clear and concise summary",
backstory="You have written for a leading technology publication for ten years.",
llm=writer_llm,
verbose=True
)
task_research = Task(
description="Research the top three agentic AI developments of 2026",
expected_output="A list of three findings with sources",
agent=researcher
)
task_write = Task(
description="Write a 300 word summary based on the research",
expected_output="A polished summary article",
agent=writer,
context=[task_research]
)
crew = Crew(
agents=[researcher, writer],
tasks=[task_research, task_write],
process=Process.sequential,
verbose=True
)
result = crew.kickoff()
A few things to notice. The roles and backstories are detailed enough to give the LLM concrete identity. The tasks have clear descriptions and expected outputs. The context parameter on the writing task tells CrewAI to pass the research output to the writer. The crew uses a sequential process, which means tasks run in order.
When you run this, you will see verbose logs of each agent’s reasoning, tool calls, and outputs. The output of the final task is the result of the crew. For a first run, this is exciting. For production, you will want to capture and persist much more than just the final output.
A researcher with no search tool is mostly imagination. Real research requires fetching real information. Let us add a search tool to the researcher.
from crewai_tools import SerperDevTool
search_tool = SerperDevTool()
researcher = Agent(
role="Senior Research Analyst",
goal="Find accurate and current information on agentic AI trends",
backstory="You are an experienced analyst who has spent years tracking AI.",
llm=research_llm,
tools=[search_tool],
verbose=True
)
The researcher now has access to web search. When the task description mentions finding current information, the agent will use the search tool naturally. The reasoning chain in the verbose output will show the agent thinking, calling the tool, and incorporating the results.
CrewAI ships with a tool catalogue that includes search, file system access, code execution, scraping, and several integrations. You can also write custom tools by subclassing the BaseTool class and providing a name, description, and run method. The description is what the LLM sees when deciding whether to use the tool, so write it carefully.
I have found that fewer, well-described tools work better than many tools with overlapping descriptions. The LLM gets confused when several tools look like they might apply. Give each tool a clear and distinct purpose.
By default each task runs without memory of earlier crews. For a one-off research task this is fine. For an ongoing crew that needs to remember earlier interactions, you turn on memory.
crew = Crew(
agents=[researcher, writer],
tasks=[task_research, task_write],
process=Process.sequential,
memory=True,
verbose=True
)
CrewAI supports several memory types. Short-term memory keeps recent interactions in the current run. Long-term memory persists across runs in a backing store. Entity memory tracks specific entities and their attributes over time.
For most production crews I enable all three. The short-term memory keeps the agents coherent within a session. The long-term memory lets the crew learn from previous runs. The entity memory captures key facts about people, organisations, and topics the crew interacts with regularly.
Configuring memory backends is more involved than the flag suggests. You will want a vector database like Chroma or Qdrant for the embeddings, and you should plan for memory cleanup and pruning as the store grows. Without management, memory becomes a noisy lookup that hurts more than it helps.
CrewAI supports two main processes for crew execution. The sequential process runs tasks in order, with each task’s output flowing to the next. This is what we used in the hello world. It is simple, predictable, and works well for linear workflows.
The hierarchical process introduces a manager agent that delegates tasks dynamically. Instead of a predefined sequence, the manager inspects the current state and decides what should happen next. This is closer to how a human team works, where assignments adapt based on progress.
| Process | When to use |
| Sequential | Linear workflows, predictable steps, simpler debugging |
| Hierarchical | Adaptive workflows, complex coordination, supervisor pattern |
I default to sequential for first builds and migrate to hierarchical when the workflow needs adaptation. The hierarchical process is more powerful but also harder to debug because the order of work depends on the manager’s decisions rather than your code.
Choosing between them is a design decision, not a technical one. Map out the workflow on paper first. If the steps are knowable in advance, use sequential. If they depend on what earlier steps produce, use hierarchical.
Here is what the hierarchical version of our research crew looks like.
manager = Agent(
role="Editorial Manager",
goal="Coordinate the research and writing team to deliver a polished article",
backstory="You manage a small editorial team and pride yourself on quality control.",
llm=manager_llm,
allow_delegation=True
)
crew = Crew(
agents=[researcher, writer],
tasks=[task_research, task_write],
process=Process.hierarchical,
manager_agent=manager,
verbose=True
)
The manager is a separate agent with its own role and goal. The allow_delegation flag tells CrewAI that this agent can assign work to others. When the crew runs, the manager decides which agent handles each task and can reassign if results are unsatisfactory.
The manager agent is typically run on a stronger model because its decisions affect the whole crew. The worker agents can use cheaper models because they each handle narrower tasks. This split saves cost while maintaining quality.
A manager agent that delegates well is the lever that makes hierarchical CrewAI shine. The framework can only do so much. The role, goal, and backstory of the manager carry the burden of effective coordination.
Tools fail. Search APIs go down. File operations time out. Network requests return errors. A robust crew handles failures gracefully rather than crashing.
CrewAI gives you a few mechanisms.
In practice I add try except handling inside custom tools rather than relying on the framework alone. The tool itself is the right place to know how to recover from API errors. CrewAI’s job is to handle higher-level failures like an agent giving up or an output failing validation.
Robustness is a property of the design, not the framework. Build it in from the start.
I also instrument every tool call with logging that captures inputs, outputs, and timing. When something fails in production, the logs are how you figure out whether the failure was a transient API issue or a deeper bug.
Debugging a multi-agent crew is harder than debugging a single agent. There are more moving parts, more interactions, and more places for things to go wrong. CrewAI’s verbose mode is a starting point but not sufficient for serious debugging.
The setup I use includes verbose mode for the crew, structured logging at every agent step, traces sent to LangSmith or a similar platform, and persistence of inputs, intermediate outputs, and final outputs for every run.
When a crew misbehaves, I work through a checklist.
This top to bottom inspection usually identifies the broken link quickly. Most multi-agent failures are concentrated at the handoffs between agents, where one agent’s output becomes another agent’s input. Pay attention to these joints.
For repeatable debugging, I save the inputs that triggered failures and add them to a regression suite. The next time I change the crew, I rerun the suite to make sure nothing regresses.
Without evaluation you cannot tell whether changes to the crew are improving or degrading the output. Evaluation is the most underinvested part of multi-agent design, and it is the part that pays off most over time.
A simple evaluation harness has three components.
For deterministic tasks like fact extraction, exact match works. For generative tasks like writing summaries, you need a rubric-based score, often produced by another LLM acting as a judge. The judge needs its own evaluation to make sure it scores consistently.
I run my evaluation suite after every meaningful change to the crew. Even a small prompt change can shift output quality, and the suite is what tells me whether the shift is in the right direction.
A working CrewAI script on your laptop is one thing. A production deployment is another. The path I follow has several steps.
First, containerise the crew. Wrap it in a FastAPI service that accepts inputs over HTTP and returns outputs. The service is what you actually deploy.
Second, externalise configuration. Prompts, model selections, and tool configurations should come from environment variables or a config service, not hardcoded in the source.
Third, add observability. Traces, metrics, and logs all go to a central platform. You want to know latency, cost, error rate, and output quality for every run.
Fourth, plan for cost control. Multi-agent systems can burn tokens fast. Cap the total tokens per request, the total tool calls per request, and the elapsed time. Without caps, a runaway crew can produce eye-watering bills.
Fifth, plan for safety. Rate limit requests, validate inputs, and filter outputs. The same prompt injection and data leakage risks that apply to single agents apply more strongly to crews.
Production deployment is where many CrewAI experiments stall because the operational work feels heavier than the build work. Plan for it from the start.
CrewAI and AutoGen both target multi-agent design, but they have different opinions about the right abstraction.
| Aspect | CrewAI | AutoGen |
| Mental model | Crews of role-based agents | Group chat between agents |
| Abstractions | Agent, Task, Crew, Tool | Agent, conversation, message |
| Human in the loop | Possible but bolt-on | First class |
| Default process | Sequential or hierarchical | Conversational |
| Best for | Production crews | Conversational and human-in-the-loop |
| Learning curve | Lower | Moderate |
I reach for CrewAI when the workflow has clear roles and a defined deliverable. I reach for AutoGen when the workflow is conversational, exploratory, or needs a human participant. Both are good frameworks. The choice depends on which mental model fits your use case.
You can also use both. Some teams build the conversational research phase in AutoGen and the deliverable production phase in CrewAI. Mixing is unusual but workable.
Here are the patterns I see most often when teams build their first CrewAI crew.
The crew you ship should look almost embarrassingly simple compared to the crew you imagined. Simplicity is the engineering win.
I have made each of these mistakes more than once, and I would not be writing about them if they were rare.
After your first crew is running, the next steps depend on your use case. Some directions worth exploring.
Add more agents, but carefully. Each new agent should have a clear role that the existing crew cannot cover. Justify every addition.
Try hierarchical process. Even if your first crew is sequential, building a hierarchical version teaches you a lot about coordination patterns.
Add a critic agent. A separate agent that reviews the output of the primary crew can catch issues you would otherwise miss. The critic is a multi-agent version of the Reflection pattern.
Integrate with your real data. Crews that work on toy data look good in demos but rarely translate to production. Get the crew working against real inputs as soon as possible.
Build the eval suite. Without it you cannot improve the crew systematically. Without it you also cannot prove to stakeholders that the crew is reliable enough to deploy.
The path from first crew to production crew is two to three months of work for a typical use case. Most of that is the evaluation, observability, and operational work, not the agent design itself.
Brian Jagger is an AI Architect and Software Engineer with over 15+ years of experience in generative AI, AI-first software development, and digital accessibility. As the Co-founder & CTO of TechA11y and Founder of GuardRailz, he has built innovative AI solutions for businesses, education, and enterprise clients. Brian combines deep technical expertise with a creative background in film and media, helping professionals leverage AI to build impactful, scalable solutions.
QUICK FACTS
Python 3.10 or newer. Some integrations require 3.11. Check the docs for current requirements before starting a project.