CrewAI is a Python framework for building multi-agent AI systems — teams of specialized AI agents that collaborate on complex tasks. Instead of one AI doing everything, you define agents with specific roles, tools, and goals. A researcher agent gathers information, a writer agent creates content, a reviewer agent checks quality. The agents work together autonomously.
Installation
pip install crewai crewai-tools
# Optional: browser tools
pip install 'crewai[tools]'
Core Concepts
Agent
An agent is an AI with a specific role, goal, and backstory. These context cues significantly affect how the underlying LLM responds.
from crewai import Agent
researcher = Agent(
role="Senior Research Analyst",
goal="Uncover comprehensive technical information about any topic",
backstory="You are an expert researcher with 10 years in cybersecurity, known for thorough analysis and accurate sourcing.",
verbose=True,
allow_delegation=False
)
Task
A task defines what an agent should do and what output is expected:
from crewai import Task
research_task = Task(
description="Research the latest techniques for bypassing Windows Defender using living-off-the-land binaries. Compile a comprehensive technical overview.",
expected_output="A detailed report covering 5+ LOLBAS techniques with examples and detection rates.",
agent=researcher
)
Crew
A crew assembles agents and tasks into a workflow:
from crewai import Crew, Process
crew = Crew(
agents=[researcher, writer],
tasks=[research_task, write_task],
process=Process.sequential, # or Process.hierarchical
verbose=True
)
result = crew.kickoff()
print(result)
LLM Configuration
By default, CrewAI uses OpenAI. Configure it to use other providers:
OpenAI
import os
os.environ["OPENAI_API_KEY"] = "your-key"
Anthropic Claude
os.environ["ANTHROPIC_API_KEY"] = "your-key"
researcher = Agent(
role="Researcher",
goal="...",
backstory="...",
llm="claude-opus-4-6" # or claude-sonnet-4-6
)
Local LLM via Ollama
from crewai import LLM
local_llm = LLM(
model="ollama/llama3.1:8b",
base_url="http://localhost:11434"
)
researcher = Agent(
role="Researcher",
goal="...",
backstory="...",
llm=local_llm
)
Tools
Tools give agents the ability to take actions — search the web, read files, execute code.
Built-in CrewAI tools
from crewai_tools import SerperDevTool, FileReadTool, DirectoryReadTool
search_tool = SerperDevTool() # Google search (requires SERPER_API_KEY)
file_tool = FileReadTool()
dir_tool = DirectoryReadTool(directory="/path/to/data")
researcher = Agent(
role="Researcher",
goal="Research using web search",
backstory="...",
tools=[search_tool, file_tool]
)
Custom tools
from crewai.tools import BaseTool
class SecurityScanner(BaseTool):
name: str = "Security Scanner"
description: str = "Scans a URL for common web vulnerabilities"
def _run(self, url: str) -> str:
# your scanning logic here
import subprocess
result = subprocess.run(['nikto', '-h', url, '-Format', 'txt'], capture_output=True, text=True)
return result.stdout
scanner = SecurityScanner()
Real-World Example: Security Report Generator
from crewai import Agent, Task, Crew, Process
from crewai_tools import SerperDevTool
search = SerperDevTool()
# Agent 1: Threat Researcher
threat_researcher = Agent(
role="Cybersecurity Threat Researcher",
goal="Research current cybersecurity threats and CVEs",
backstory="Expert threat researcher tracking global vulnerability landscape.",
tools=[search],
verbose=True
)
# Agent 2: Technical Writer
report_writer = Agent(
role="Technical Security Writer",
goal="Transform research into clear, actionable security reports",
backstory="Security writer specializing in translating technical findings for executive audiences.",
verbose=True
)
# Task 1: Research
research = Task(
description="Find the 5 most critical new CVEs from the last 30 days. For each: CVE ID, CVSS score, affected software, exploit availability.",
expected_output="Structured list of 5 CVEs with all technical details.",
agent=threat_researcher
)
# Task 2: Write report
report = Task(
description="Using the CVE research, write a 1-page executive security brief. Lead with business impact, include recommended actions.",
expected_output="Professional security brief in markdown format.",
agent=report_writer,
context=[research] # report_writer gets researcher's output as context
)
crew = Crew(
agents=[threat_researcher, report_writer],
tasks=[research, report],
process=Process.sequential
)
result = crew.kickoff()
print(result.raw)
Process Types
Sequential: tasks execute in order, each agent receives previous agent’s output.
Hierarchical: a manager agent orchestrates other agents, delegates tasks, and quality-controls output. Requires an LLM as manager:
crew = Crew(
agents=[researcher, writer, reviewer],
tasks=[...],
process=Process.hierarchical,
manager_llm="claude-sonnet-4-6"
)
Memory
CrewAI supports memory to maintain context across interactions:
crew = Crew(
agents=[...],
tasks=[...],
memory=True, # Enable all memory types
embedder={
"provider": "openai",
"config": {"model": "text-embedding-3-small"}
}
)
Memory types: short-term (conversation context), long-term (vector database), entity memory (tracks people/companies mentioned).
CrewAI vs. AutoGen vs. LangGraph
| Framework | Best For |
|---|---|
| CrewAI | Role-based agent teams, simple setup |
| AutoGen | Complex multi-agent conversations, code execution |
| LangGraph | Fine-grained workflow control, graph-based state |
CrewAI’s role-based design makes it the most intuitive starting point for multi-agent systems.