CrewAI Tutorial 2026: Build Multi-Agent Systems in Python

Share on SNS

CrewAI is the fastest path to a working multi-agent system in Python — and the clearest example of what role-based agent collaboration looks like when the workflow resembles an org chart rather than a flowchart.

CrewAI tutorial 2026 multi-agent Python Claude step by step

The LangGraph vs CrewAI post in this series established when to choose each framework: CrewAI wins when your workflow has clear roles, sequential handoffs, and you need a working prototype this week. LangGraph wins when you need durable state, conditional branching, or human-in-the-loop approval gates. This CrewAI tutorial is the implementation companion to that decision: if you chose CrewAI, here’s every line of code you need to go from installation to a production-ready multi-agent research and writing system.


Setup: Install CrewAI in 3 Minutes

CrewAI requires Python 3.10 or higher (3.12 recommended). It enforces strict Python version bounds and depends on compiled C extensions — check your version first.

# Check your Python version (must be 3.10–3.13)
python --version

# Install CrewAI with the tools package
pip install "crewai[tools]" python-dotenv
# .env — CrewAI uses LiteLLM internally, which wraps any provider
ANTHROPIC_API_KEY=sk-ant-your-key-here

# CrewAI defaults to OpenAI if no model is specified.
# We're using Claude — set this to override the default:
MODEL=claude/claude-sonnet-5

CrewAI uses LiteLLM internally, which means any provider supported by LiteLLM works — Claude, GPT-5.6, Gemini, or local Ollama models. The MODEL=claude/claude-sonnet-5 environment variable sets Claude as the default for all agents in the crew.


Part 1: Your First Crew — Research and Write in 50 Lines

The minimal working CrewAI system: two agents (Researcher and Writer), two tasks (research and write), one crew that runs them sequentially. The Researcher gathers information; the Writer uses that output to produce a polished article.

import os
from dotenv import load_dotenv
from crewai import Agent, Task, Crew, Process

load_dotenv()

# ─── Define Your Agents ─────────────────────────────────────────
# Each agent has: role, goal, and backstory.
# The backstory is surprisingly important — it shapes how Claude
# approaches its role. Write it like a job description.

researcher = Agent(
    role="Senior Research Analyst",
    goal="Find accurate, current information on {topic} "
         "and produce a comprehensive research brief",
    backstory="""You are an expert researcher with a talent for
    finding relevant information quickly and synthesizing it into
    clear, well-organized briefs. You prioritize accuracy over
    comprehensiveness — if you're unsure, you say so.""",
    verbose=True,
    llm="claude/claude-sonnet-5",    # researcher uses Sonnet 5
    allow_delegation=False            # prevents delegation loops
)

writer = Agent(
    role="Technical Content Writer",
    goal="Transform the research brief into a clear, "
         "engaging article for a technical audience",
    backstory="""You are a technical writer who excels at making
    complex topics accessible without sacrificing accuracy. You
    write in an active voice, avoid jargon unless necessary, and
    always lead with the most important point.""",
    verbose=True,
    llm="claude/claude-sonnet-5",
    allow_delegation=False
)

# ─── Define Your Tasks ──────────────────────────────────────────
# Tasks specify: what to do, who does it, and what the output looks like.
# {topic} is a placeholder filled at crew.kickoff() time.

research_task = Task(
    description="""Research the following topic thoroughly: {topic}

    Your research brief must include:
    1. A concise definition (2-3 sentences)
    2. Why it matters in 2026 (3-4 key points)
    3. The top 3 real-world use cases with specific examples
    4. Common misconceptions or pitfalls to avoid
    5. Recommended resources for deeper learning

    Cite sources where possible. If information is uncertain, flag it.""",
    expected_output="""A structured research brief with all five
    sections above, formatted with headers. Total length: 400-600 words.""",
    agent=researcher
)

write_task = Task(
    description="""Using the research brief provided, write a complete
    article on: {topic}

    Requirements:
    - Lead with the most compelling point (inverted pyramid structure)
    - Technical audience: assume programming knowledge, not AI expertise
    - Include 1-2 concrete code examples or real-world scenarios
    - End with a clear "what to do next" recommendation
    - Target length: 600-800 words""",
    expected_output="A complete, publication-ready article in markdown format.",
    agent=writer,
    context=[research_task]    # Writer receives researcher's output as context
)

# ─── Assemble and Run the Crew ──────────────────────────────────
crew = Crew(
    agents=[researcher, writer],
    tasks=[research_task, write_task],
    process=Process.sequential,    # tasks run in order
    verbose=True
)

# kickoff() runs the crew. The inputs dict fills {topic} placeholders.
result = crew.kickoff(inputs={"topic": "RAG (Retrieval-Augmented Generation)"})

print("\n" + "="*60)
print("FINAL ARTICLE")
print("="*60)
print(result.raw)

Run this and you’ll see both agents working in the terminal — the researcher gathering information, then the writer using that output to produce a polished article. The verbose=True setting shows each agent’s reasoning steps, which is invaluable for debugging unexpected outputs.


Part 2: Adding Tools — Give Agents Real Capabilities

The crew above uses only the agents’ training knowledge. Add tools and agents can search the web, read files, scrape URLs, and call APIs. CrewAI’s tools package includes ready-built tools for the most common use cases.

from crewai_tools import SerperDevTool, ScrapeWebsiteTool, FileReadTool
from crewai.tools import tool
# ─── Built-in tools from crewai-tools ───────────────────────────
# SerperDevTool: Google search via Serper API (free tier: 100 searches/month)
# Requires: SERPER_API_KEY in .env
search_tool = SerperDevTool()
# ScrapeWebsiteTool: Reads and returns a webpage's text content
scraper_tool = ScrapeWebsiteTool()
# ─── Custom tool with the @tool decorator ───────────────────────
# Use this for any function you want to expose to agents
@tool("Save to File")
def save_to_file(filename: str, content: str) -> str:
    """
    Save content to a file on disk.
    Use when the user wants to save the final output.
    Args:
        filename: The name of the file to create (e.g., 'report.md')
        content: The text content to write
    """
    with open(filename, "w") as f:
        f.write(content)
    return f"Successfully saved to {filename}"
# ─── Assign tools to specific agents ────────────────────────────
# Only the researcher needs search and scraping.
# The writer only needs to save the final article.
researcher_with_tools = Agent(
    role="Senior Research Analyst",
    goal="Find current, accurate information on {topic} using web search",
    backstory="""Expert researcher who knows how to find reliable sources
    quickly. You always verify information from at least two sources before
    including it in the brief.""",
    tools=[search_tool, scraper_tool],    # give tools here
    verbose=True,
    llm="claude/claude-sonnet-5",
    allow_delegation=False
)
writer_with_tools = Agent(
    role="Technical Content Writer",
    goal="Write and save a polished article on {topic}",
    backstory="Expert technical writer who produces clear, accurate content.",
    tools=[save_to_file],    # only the writer saves the output
    verbose=True,
    llm="claude/claude-sonnet-5",
    allow_delegation=False
)
# Tasks and crew assembly remain the same — just swap in the new agents

Part 3: Cost Optimization — Reduce Costs by 60–70%

A two-agent research crew using Claude Sonnet 5 for all agents costs approximately $0.10 to $0.30 per run. For high-volume use cases — running the crew 100 times per day — this compounds quickly. The CrewAI cost optimization pattern: use the most capable model only where it produces meaningfully better output.

# Cost-optimized crew: Haiku does the heavy lifting,
# Sonnet handles the final polished output.
# Reduces cost by 60-70% for research-heavy workflows.

import os
from crewai import Agent, Task, Crew, Process
from dotenv import load_dotenv

load_dotenv()

# Haiku for data gathering and initial analysis (cheap, fast)
RESEARCH_MODEL = "claude/claude-haiku-4-5-20251001"   # $0.80/$4.00 per MTok

# Sonnet for final synthesis and polished output (quality matters here)
WRITING_MODEL = "claude/claude-sonnet-5"               # $2.00/$10.00 per MTok

data_collector = Agent(
    role="Data Collection Specialist",
    goal="Quickly gather raw information on {topic} from multiple sources",
    backstory="Fast, efficient data gatherer. Quality over completeness.",
    llm=RESEARCH_MODEL,    # Haiku: cheap and fast for structured gathering
    verbose=False,          # Turn off verbose for cheaper agents
    allow_delegation=False
)

analyst = Agent(
    role="Research Analyst",
    goal="Synthesize the collected data into a clear research brief",
    backstory="Expert at turning raw data into structured insights.",
    llm=RESEARCH_MODEL,    # Haiku handles structured synthesis too
    verbose=False,
    allow_delegation=False
)

writer = Agent(
    role="Senior Technical Writer",
    goal="Write a polished, publication-ready article from the research brief",
    backstory="Expert writer who elevates good content into great content.",
    llm=WRITING_MODEL,    # Sonnet only for the final quality output
    verbose=True,
    allow_delegation=False
)

# Cost estimate per run:
# Data collection (Haiku): ~$0.002
# Analysis (Haiku): ~$0.003
# Writing (Sonnet): ~$0.05
# Total: ~$0.055 vs ~$0.20 with all-Sonnet crew
# Savings: ~72% reduction

Production Checklist: 5 Common CrewAI Problems and Their Fixes

  1. Delegation loops (agents keep passing tasks to each other): Set allow_delegation=False on all non-manager agents. Delegation loops happen when multiple agents have overlapping roles. Only the manager agent in a hierarchical crew should have delegation enabled.
  2. Agents going off-script: Be more specific in the task description’s expected_output field. Vague expected outputs produce creative interpretations. “A 400-600 word research brief with exactly five sections” beats “a research brief.”
  3. High costs on repeated runs: Enable agent caching to avoid paying for repeated tool call summaries: cache=True on the agent. This caches tool results so the same web search doesn’t get billed twice across runs.
  4. Installation failures (ModuleNotFoundError): CrewAI requires Python 3.10 to 3.13. Python 3.9 and below are not supported. If you have multiple Python installations, use python3.12 -m pip install "crewai[tools]" explicitly.
  5. Context window exceeded on long tasks: Break the task description into smaller, more specific tasks. A single task that asks an agent to “research everything about X” can generate context windows that overflow. Three focused tasks with specific deliverables stay within limits reliably.

For the complete CrewAI documentation including Flows for pipeline orchestration, see CrewAI’s official documentation.


The Builder’s Takeaway

CrewAI is the most intuitive multi-agent framework available in 2026 for workflows that map cleanly to team roles. Define the agents, describe their jobs, specify what each task should produce, and CrewAI handles the coordination. The role-backstory-goal structure takes five minutes to learn and produces working multi-agent systems in under 50 lines. The cost optimization pattern — Haiku for research, Sonnet for output — cuts per-run costs by 60 to 70 percent without meaningful quality loss on the final deliverable. The five production problems above cover 90 percent of the issues builders hit in the first week. Build the two-agent crew from Part 1 today, add tools from Part 2 this week, and apply the cost optimization before you run it at scale. The LangGraph vs CrewAI decision framework tells you when to reach for each — this tutorial gives you the CrewAI implementation once you’ve made that call.


Continue in This Series


This post is part of The Agentic Protocol’s Work series — the connective infrastructure layer beneath every autonomous pipeline. See also: LangGraph vs CrewAI.


Share on SNS