A single LLM call does one thing. Ask it to research a topic, fact-check itself, and write a polished report in one prompt and you get hallucinations dressed up as confidence. Multi-agent systems split the work across specialized agents that each focus on one job.
CrewAI is an open-source Python framework for building these systems. You define agents with roles, give them tools, and assemble them into crews that execute tasks sequentially or hierarchically.
Prerequisites
- Python 3.10 to 3.13 (check with
python3 --version) - An OpenAI API key (or Anthropic, or a local Ollama model)
uvorpipfor package management- 30 minutes
Step 1: Install CrewAI
CrewAI 1.15.6 is the latest stable release as of July 2026. Install it along with the tools package:
mkdir crewai-demo && cd crewai-demo
python3 -m venv .venv && source .venv/bin/activate
pip install crewai crewai-tools
The crewai-tools package gives your agents access to web search, file reading, code interpretation, and a dozen other built-in capabilities.
Step 2: Set Up Your LLM
CrewAI defaults to OpenAI. Set your key:
export OPENAI_API_KEY="sk-..."
Want a different provider? CrewAI supports any LLM through LiteLLM. For Anthropic:
from crewai import LLM
claude = LLM(model="claude-sonnet-4-20250514", api_key="...")
For a free local model via Ollama:
ollama_llm = LLM(model="ollama/llama3.1:8b", base_url="http://localhost:11434")
The rest of this tutorial uses the default (OpenAI). Swap the llm parameter on any agent if you want to mix models per agent.
Step 3: Create Your Agents
Every agent in CrewAI has a role, a goal, and a backstory. The backstory isn't just fluff — it shapes how the agent approaches its work.
Create crew.py:
from crewai import Agent, Task, Crew, Process
from crewai_tools import SerperDevTool
# Give the researcher a real search tool
search_tool = SerperDevTool()
researcher = Agent(
role="Senior Research Analyst",
goal="Find accurate, up-to-date information and identify key trends",
backstory=(
"You spent years as a research analyst at a major consulting firm. "
"You verify facts across multiple sources before citing them. "
"When information is contradictory, you flag it instead of picking a side."
),
tools=[search_tool],
verbose=True,
allow_delegation=False,
)
writer = Agent(
role="Technical Content Writer",
goal="Transform research into clear, engaging prose that non-experts can follow",
backstory=(
"You write for a general audience. You cut jargon, use short paragraphs, "
"and lead with the most important finding. You never fabricate details — "
"if the research doesn't support a claim, you drop it."
),
verbose=True,
allow_delegation=False,
)
verbose=True prints the agent's thought process to your terminal. Keep it on while developing, turn it off in production.
allow_delegation=False means these agents work on their own tasks without handing work off to each other. In a sequential process, delegation isn't needed because tasks flow in order.
Step 4: Define Tasks
Tasks tell each agent what to do. A task has a description, an expected output, and is assigned to an agent.
research_task = Task(
description=(
"Research the current state of AI-assisted software development in 2026. "
"Focus on: which tools have real adoption data (not just hype), "
"measurable productivity impacts, and major limitations that remain unsolved. "
"Find at least 3 specific data points or studies."
),
expected_output=(
"A structured research brief with: "
"1) Key findings with citations, "
"2) Adoption data from credible sources, "
"3) Major limitations and open problems."
),
agent=researcher,
)
writing_task = Task(
description=(
"Using the research brief, write an 800-word article for a technical audience. "
"Open with a specific, surprising data point. Avoid AI vocabulary — "
"no \"pivotal\", \"landscape\", \"testament\", \"showcase\". "
"One em dash max per paragraph."
),
expected_output="A polished 800-word article in markdown format.",
agent=writer,
context=[research_task], # writer gets the researcher's output
)
context=[research_task] is how you pass one agent's output to another. The writer receives the full research brief before it starts writing. Without this, each agent works in isolation.
Step 5: Assemble the Crew
A crew bundles agents, tasks, and a process strategy:
crew = Crew(
agents=[researcher, writer],
tasks=[research_task, writing_task],
process=Process.sequential, # task 1 runs, then task 2
verbose=True,
)
result = crew.kickoff()
print(result)
Process.sequential runs tasks in order: research completes, then writing starts with the research as context. Process.hierarchical lets a manager agent delegate and review. Start with sequential unless you have 4+ agents.
Step 6: Run It
export SERPER_API_KEY="your-serper-key" # free tier: serper.dev
python crew.py
The first run takes 30-60 seconds. You'll see the researcher searching the web, synthesizing findings, and the writer turning them into prose.
Real Output Example
Here's what a run looks like (trimmed):
[Senior Research Analyst] Starting task...
> Searching: "AI assisted software development adoption 2026"
> Searching: "developer productivity AI tools study 2025 2026"
> Found 10 results. Synthesizing...
[Senior Research Analyst] Task completed.
[Technical Content Writer] Starting task...
> Using research brief as context.
> Writing draft...
[Technical Content Writer] Task completed.
## AI-Assisted Development in 2026: The Gap Between Hype and Data
Stack Overflow's 2025 survey of 65,000 developers found 76% are using or planning to use AI coding tools — up from 44% in 2023. But usage and productivity are different things...
When to Use CrewAI vs Other Frameworks
You have options. Here's a practical breakdown.
Use CrewAI when:
- You want role-based agents that feel like a team (researcher, writer, reviewer)
- You need built-in tools (web search, code execution, file reading) without wiring everything yourself
- Sequential or hierarchical processes match your workflow
- You want to ship a multi-agent prototype in hours, not days
Use LangGraph when:
- You need fine-grained control over agent state and transitions
- Your workflow is a graph with conditional branching and cycles
- You're building something closer to a state machine than a team
Use raw OpenAI function calling when:
- You have one agent doing one thing
- You don't need agent-to-agent communication
- You want minimum dependencies
CrewAI and LangGraph aren't mutually exclusive. Some teams use CrewAI for quick prototypes and LangGraph when the workflow gets complex enough to need explicit graph control.
Common Mistakes
No search tool for research agents. Without SerperDevTool or an equivalent, agents hallucinate data because they have no way to look things up. Always give research agents a search tool.
Skipping context between tasks. If the writer doesn't receive the research as context, it either hallucinates or asks you to provide information it should already have.
Vague task descriptions. "Write a blog post" produces generic output. "Write an 800-word article opening with a specific data point, avoiding AI vocabulary, targeting technical readers" produces something useful.
Running with verbose=False during development. You can't debug what you can't see. Turn verbosity off only after the crew produces consistent results.
Next Steps
- Add a third agent: a fact-checker that reviews the writer's output against the research brief
- Switch to
Process.hierarchicaland add a manager agent that assigns tasks dynamically - Replace OpenAI with a local Ollama model (
ollama/llama3.1:8b) to cut costs - Browse CrewAI's cookbook examples for marketing, finance, and HR automation patterns
- Explore CrewAI Flows for event-driven, long-running automations