CrewAI Tutorial 2026: Build Multi-Agent AI Systems in Python
What is CrewAI?
CrewAI lets you build teams of AI agents that collaborate to complete complex tasks. Instead of one LLM doing everything, you assign specialized roles — researcher, writer, reviewer — and they work together.
When to use CrewAI: - Tasks too complex for a single LLM call - Tasks that benefit from specialization and review - Workflows with multiple sequential steps - When you need agents to use different tools
Installation
pip install crewai crewai-tools
Core Concepts
- Agent: an LLM with a role, goal, and backstory
- Task: a specific job for an agent to complete
- Crew: a team of agents working on tasks
- Tool: a function agents can call (search, read files, etc.)
Your First Crew: Research and Write
from crewai import Agent, Task, Crew, Process
from crewai_tools import SerperDevTool
search_tool = SerperDevTool()
# Define agents
researcher = Agent(
role="Senior Research Analyst",
goal="Find accurate, up-to-date information on the given topic",
backstory="You are an expert researcher with 10 years of experience finding reliable information.",
tools=[search_tool],
verbose=True
)
writer = Agent(
role="Technical Writer",
goal="Write clear, engaging content based on research",
backstory="You specialize in turning complex information into readable articles.",
verbose=True
)
# Define tasks
research_task = Task(
description="Research the latest developments in {topic}. Find key facts, recent news, and expert opinions.",
expected_output="A detailed research report with bullet points covering key findings.",
agent=researcher
)
write_task = Task(
description="Using the research report, write a 500-word article about {topic}. Make it engaging and factual.",
expected_output="A polished 500-word article ready for publication.",
agent=writer
)
# Create crew
crew = Crew(
agents=[researcher, writer],
tasks=[research_task, write_task],
process=Process.sequential,
verbose=True
)
result = crew.kickoff(inputs={"topic": "Python 3.14 new features"})
print(result.raw)
Using Local Ollama Models
from crewai import Agent, LLM
local_llm = LLM(
model="ollama/llama3.2",
base_url="http://localhost:11434"
)
agent = Agent(
role="Assistant",
goal="Help with tasks",
backstory="A helpful AI assistant.",
llm=local_llm
)
Custom Tools
from crewai.tools import BaseTool
from pydantic import BaseModel, Field
class SearchInput(BaseModel):
query: str = Field(description="The search query")
class DatabaseTool(BaseTool):
name: str = "Database Search"
description: str = "Search our internal database for information"
args_schema: type[BaseModel] = SearchInput
def _run(self, query: str) -> str:
# Implement your database search here
return f"Database results for '{query}': [product data...]"
db_tool = DatabaseTool()
agent = Agent(
role="Data Analyst",
goal="Find and analyze data",
backstory="Expert at querying and interpreting data.",
tools=[db_tool]
)
Hierarchical Process: Manager Agent
from crewai import Agent, Task, Crew, Process
manager = Agent(
role="Project Manager",
goal="Coordinate the team and ensure quality output",
backstory="Senior manager with experience leading technical teams.",
allow_delegation=True # can delegate to other agents
)
crew = Crew(
agents=[researcher, writer, reviewer],
tasks=[research_task, write_task, review_task],
process=Process.hierarchical,
manager_agent=manager,
verbose=True
)
Agent Memory
agent = Agent(
role="Research Assistant",
goal="Maintain context across long research sessions",
backstory="Expert researcher with excellent memory.",
memory=True # enables short-term, long-term, and entity memory
)
Parallel Task Execution
# Tasks with the same agent run sequentially
# Tasks with different agents can run in parallel
task1 = Task(description="Research topic A", agent=researcher_a)
task2 = Task(description="Research topic B", agent=researcher_b)
combine_task = Task(
description="Combine research from topic A and B",
agent=writer,
context=[task1, task2] # waits for both
)
Real Example: Code Review Crew
from crewai import Agent, Task, Crew, Process
developer = Agent(
role="Senior Python Developer",
goal="Write clean, efficient Python code",
backstory="10 years of Python experience, expert in best practices."
)
reviewer = Agent(
role="Code Reviewer",
goal="Find bugs, security issues, and style problems",
backstory="Security-focused developer who catches subtle bugs."
)
write_code = Task(
description="Write a Python function that {requirement}",
expected_output="Working Python code with docstring and type hints",
agent=developer
)
review_code = Task(
description="Review the code for bugs, security issues, and PEP 8 compliance. Suggest improvements.",
expected_output="Detailed code review with specific line-by-line feedback",
agent=reviewer,
context=[write_code]
)
crew = Crew(
agents=[developer, reviewer],
tasks=[write_code, review_code],
process=Process.sequential
)
result = crew.kickoff(inputs={"requirement": "validates an email address and returns a boolean"})
print(result.raw)