Quick answer: CrewAI is an open-source Python framework for orchestrating multiple AI agents that collaborate on a task. You define agents with roles, give them tasks, assemble them into a crew, and pick a process that controls how work flows between them. It is one of the easiest ways to try multi-agent patterns, and also one of the easiest ways to burn tokens on problems a single agent would have solved fine.
I will walk through how it works, show a minimal crew, wire in a web-research tool, and then give you my honest take on when multi-agent is actually worth it.
What CrewAI Is
CrewAI's core idea is role-playing agents. Instead of one general-purpose assistant, you build a small team: a researcher, an analyst, a writer. Each agent gets a role, a goal, and a backstory that shapes how the LLM behaves, plus optionally its own tools and even its own model.
The framework's vocabulary maps cleanly onto that idea:
| Concept | What it is |
|---|---|
| Agent | An LLM persona with a role, goal, backstory, and tools |
| Task | A unit of work with a description and an expected output |
| Crew | A set of agents plus their tasks |
| Process | How tasks execute: sequential, or hierarchical with a manager |
Sequential process runs tasks in order, passing each task's output as context to the next. Hierarchical process adds a manager agent that delegates and reviews. My advice: start sequential. The manager pattern sounds great and frequently turns into an expensive game of telephone.
A Minimal Crew
Here is the shape of a two-agent research crew. Treat the exact imports as a snapshot; CrewAI moves fast, so check the current docs.
from crewai import Agent, Task, Crew, Process
researcher = Agent(
role="Research Analyst",
goal="Find accurate, current information on the assigned topic",
backstory="You are a meticulous researcher who always cites sources.",
verbose=True,
)
writer = Agent(
role="Technical Writer",
goal="Turn research notes into a clear, honest summary",
backstory="You write plainly and never overstate findings.",
)
research_task = Task(
description="Research the current state of {topic}.",
expected_output="Bullet-point findings with source URLs.",
agent=researcher,
)
writing_task = Task(
description="Write a 300-word summary from the research findings.",
expected_output="A markdown summary with a sources section.",
agent=writer,
)
crew = Crew(
agents=[researcher, writer],
tasks=[research_task, writing_task],
process=Process.sequential,
)
result = crew.kickoff(inputs={"topic": "EU AI Act enforcement"})
print(result)
This runs, and it will produce something that looks like research. The problem is the researcher has no actual access to the web, so "findings" means "whatever was in the training data." For a topic that moves, that is somewhere between stale and wrong.
Adding a Real Web-Research Tool
CrewAI supports custom tools, and this is where the crew goes from theater to useful. I back mine with link.sc because it collapses the two annoying halves of web research into one API: search that returns structured results, and a fetch endpoint that turns any result URL into clean markdown, with rendering and anti-bot handling done server-side.
import os
import requests
from crewai.tools import tool
HEADERS = {
"x-api-key": os.environ["LINKSC_API_KEY"],
"Content-Type": "application/json",
}
@tool("web_search")
def web_search(query: str) -> str:
"""Search the web and return the top results with titles, URLs,
and descriptions. Use for current events or anything you are unsure of."""
r = requests.post(
"https://api.link.sc/v1/search",
headers=HEADERS,
json={"q": query, "engine": "google"},
timeout=60,
)
r.raise_for_status()
results = r.json()["serpData"]["results"][:5]
return "\n\n".join(
f"{item['title']}\n{item['targetUrl']}\n{item['description']}"
for item in results
)
@tool("fetch_page")
def fetch_page(url: str) -> str:
"""Fetch a specific URL and return its content as clean markdown."""
r = requests.post(
"https://api.link.sc/v1/fetch",
headers=HEADERS,
json={"url": url, "format": "markdown"},
timeout=60,
)
r.raise_for_status()
return r.json()["content"]
Then hand the tools to the agent that needs them:
researcher = Agent(
role="Research Analyst",
goal="Find accurate, current information with sources",
backstory="You verify claims by fetching the actual pages.",
tools=[web_search, fetch_page],
)
Two practical notes from doing this in anger. First, only give tools to the agents that need them; a writer with a search tool will wander. Second, full-page content is a feature and a hazard: it grounds the agent properly, but stuff it into every task context and your token bill grows fast. Have the researcher summarize with citations rather than passing raw pages downstream. I go deeper on that pattern in building a deep research agent.
When Multi-Agent Helps
Multi-agent earns its complexity when the task has genuinely different phases that benefit from different instructions, tools, or models:
- Research then synthesis. A researcher with web tools and a cheap fast model, a writer with no tools and a stronger model.
- Generate then critique. A worker and a reviewer with adversarial instructions catch errors a single agent glosses over.
- Parallel fan-out. Several researchers covering different subtopics, merged at the end.
The common thread: separation of concerns you could articulate even if LLMs did not exist.
When It Is Overkill
Here is the honest part. Most tasks people throw at CrewAI would be done better, faster, and cheaper by one agent with good tools and a good prompt. Signs you have over-crewed:
- Your agents mostly reformat each other's output.
- The "manager" adds a round trip but no judgment.
- You cannot say what an agent would do differently if it were merged with its neighbor.
- Latency and cost tripled and quality did not move.
A single agent with a search tool covers a surprising share of "research crew" use cases; I sketched that simpler setup in giving your AI agent internet access. Start there. Split into a crew only when you hit a wall you can name.
My Verdict
CrewAI is a good on-ramp to multi-agent systems: the abstractions match how people naturally think about teams, the code reads well, and custom tools are easy. Its weakness is the same as every multi-agent framework: it makes the expensive pattern feel like the default. Reach for a crew when the task decomposition is real, keep the process sequential until proven otherwise, and give the agents actual web access so the collaboration is grounded in something. The link.sc free tier's 500 monthly credits are enough to prototype a crew end to end; see pricing for scale-up costs.
Give your CrewAI researchers real web access. link.sc turns search and fetch into two small tools. Start free.