TL;DR
- A useful CrewAI system starts with task boundaries, not agent personas. Give each agent distinct inputs, tools, expected output, and failure conditions.
- Use a Crew for open-ended collaboration and a Flow for deterministic application control. Most production systems need a Flow around one or more small Crews.
- The minimal working pattern is Agent → Task → Crew → kickoff. Start with sequential execution so outputs and failures are easy to inspect.
- Do not give every agent every tool. Least-privilege tool access reduces cost, prompt-injection exposure, and hard-to-debug side effects.
- Add structured outputs, guardrails, traces, and human approval before scaling the team. More agents increase coordination overhead and do not guarantee a better answer.
- For web-research crews, separate data acquisition from reasoning. Nstproxy Crawl can prepare bounded site content while CrewAI agents analyze and report on it.
What you are building with CrewAI?
A CrewAI multi-agent system is a set of role-scoped agents assigned to tasks under a defined process. The Crew coordinates those agents and tasks; a Flow can wrap the crew when the surrounding application needs explicit state, branching, persistence, or recovery. If the agents need approved website evidence, Nstproxy Crawl can provide the acquisition layer instead of letting each agent browse without boundaries.
The CrewAI concepts guide distinguishes autonomous Crews from event-driven Flows. This matters because many tutorials model a fixed business process as a conversation between agents. In practice, deterministic code should decide when a job starts, what state is valid, and whether an approval is required; agents should handle the parts that genuinely need interpretation.
This tutorial builds a small sequential research crew with two agents:
- A researcher turns supplied source material into an evidence brief.
- An editor converts that brief into a decision memo and must preserve uncertainties.
The example deliberately avoids live browsing tools. A web tool can be added later, after its domain policy, output contract, and error behavior are tested.
Why task design matters more than agent count
An agent should exist only when it has a different responsibility, context, or tool boundary. Splitting “research,” “analysis,” and “writing” across three agents is useful if each produces an inspectable artifact. It is wasteful if all three receive the same giant prompt and repeat the same search.
Before writing code, define this contract:
| Component | Researcher | Editor |
|---|---|---|
| Input | Topic and approved source packet | Researcher's evidence brief |
| Allowed tools | Retrieval over approved data only | No retrieval tool in the minimal example |
| Output | Claims, supporting evidence, conflicts, unknowns | Concise memo with cited claims and open questions |
| Failure condition | Missing support or inaccessible source | Unsupported claim or hidden uncertainty |
| Human gate | Source policy | Final publication or business action |
This design resembles a dependable agent harness: roles are less important than permissions, state, traces, and acceptance checks.
Prerequisites and project creation
Use a CrewAI-supported Python version, a model-provider credential stored outside source control, and the current uv-based installation path. The CrewAI documentation home links to the maintained installation and quickstart pages; follow those pages for the current Python compatibility range and CLI command rather than relying on an old pip tutorial.
After installation, scaffold a project with the CrewAI CLI and inspect the generated structure. A standard project separates YAML configuration for agents and tasks from the Python assembly code. Keep secrets in environment variables or an approved secret manager, never in YAML committed to Git.
The generated layout is useful because it makes prompt changes reviewable:
src/research_crew/ ├── config/ │ ├── agents.yaml │ └── tasks.yaml ├── crew.py └── main.py
Method 1: build the minimal crew in Python
The smallest instructive implementation keeps definitions in one file. It makes the data flow visible before a team introduces decorators, YAML, custom tools, or Flows.
Step 1: define two agents
Create crew_demo.py with the following code. The model name is passed through an environment variable so the example does not freeze an identifier that may be retired.
import os from crewai import Agent, Crew, Process, Task model_name = os.environ["CREWAI_MODEL"] researcher = Agent( role="Evidence researcher", goal="Build a traceable evidence brief for the requested topic", backstory="You separate supported claims, conflicts, and unknowns.", llm=model_name, allow_delegation=False, verbose=True, ) editor = Agent( role="Decision-memo editor", goal="Turn an evidence brief into a concise, qualified recommendation", backstory="You preserve citations and never hide uncertainty.", llm=model_name, allow_delegation=False, verbose=True, )
role, goal, and backstory influence behavior, but the important controls are the model, available tools, and delegation setting. Start with delegation disabled. Unbounded agent-to-agent delegation makes token use and termination harder to predict.
Step 2: define outputs before instructions
Append two tasks. The second task refers to the first through context, which makes the dependency explicit.
research_task = Task( description=( "Research {topic} using only the source packet supplied in {source_path}. " "List supported claims, citations, contradictions, and unknowns." ), expected_output=( "A Markdown evidence brief with sections for claims, sources, " "conflicts, and unanswered questions." ), agent=researcher, ) memo_task = Task( description=( "Create a decision memo from the evidence brief. Preserve source " "references, qualify uncertainty, and recommend a next test." ), expected_output=( "A Markdown memo containing a recommendation, evidence, risks, " "unknowns, and next action." ), agent=editor, context=[research_task], )
An expected_output is an acceptance target, not a guarantee. Production code should validate required sections or use a structured Pydantic result where the task supports it.
Step 3: assemble and run the crew
Append the crew and kickoff call:
crew = Crew( agents=[researcher, editor], tasks=[research_task, memo_task], process=Process.sequential, verbose=True, ) result = crew.kickoff( inputs={ "topic": "Whether to adopt a new retrieval model", "source_path": "data/approved-sources.md", } ) print(result.raw)
Run it only after setting the model selector and the credential required by that provider. This article's code was syntax-checked, but a live kickoff requires a supported Python runtime, the CrewAI package, a provider account, and a real source packet. Those external prerequisites cannot be validated by a static article build.
Method 2: move a stable crew to YAML and annotations
Once the prototype works, move long role and task descriptions to config/agents.yaml and config/tasks.yaml. Then assemble them in crew.py with @CrewBase, @agent, @task, and @crew. The CrewAI annotations guide explains that configuration keys and decorated method names must correspond.
This structure is better for review because prompt changes do not get mixed with orchestration changes. It also makes environment-specific model selection easier. Keep three rules:
- Give configuration keys stable names; renaming only one side breaks the mapping.
- Keep tool construction in Python, where credentials and allowlists can be enforced.
- Test the final assembled task order; declaration order and context dependencies can produce different behavior.
Give Your Crew a Controlled Evidence LayerUse Nstproxy Crawl to prepare bounded website content while CrewAI agents focus on analysis, validation, and reporting. Try Nstproxy Crawl |
Markdown
JSON
{
"title": "...", "url": "..." } Screenshot
|
Add web data without giving agents an unrestricted browser
A research crew needs fresh evidence, but direct browsing is not the only architecture. A safer pattern is to acquire approved pages first, store provenance, and expose read-only retrieval to the researcher. Nstproxy Crawl can bound collection by site depth, page count, and path rules, render JavaScript, and return selected outputs such as Markdown, HTML, JSON, links, or PDF.
The workflow becomes:
- A deterministic job validates the target domains against policy.
- The crawler collects authorized pages and records URL plus retrieval time.
- A parser stores clean content and metadata in the evidence repository.
- The research agent receives read-only retrieval over that repository.
- The editor sees the evidence brief, not raw browsing instructions.
This is the same boundary used in many AI agent projects: tools acquire or transform data, while the agent decides how to use it. Review the web index guide before adding embeddings so document identity, freshness, and deduplication are defined first.
When to wrap the crew in a Flow
Use a Flow when execution must branch, pause, resume, or update durable state. Examples include routing low-confidence memos to review, retrying a failed acquisition step, and stopping a job after a policy violation. The CrewAI Flows documentation describes event-driven steps, state, routing, and persistence.
A sensible production boundary is:
- Flow validates the request and source policy.
- Flow starts the acquisition job and handles retryable failures.
- A small Crew analyzes the retrieved evidence.
- Deterministic validation checks the crew output.
- Flow requests human approval before publishing or taking an external action.
Do not use an agent to decide whether its own output passed validation. Structural checks, allowed-domain rules, required citations, and maximum run budgets belong in deterministic code.
Test the system before adding more agents
Evaluation should measure the whole task, not how convincing the transcript sounds. Build a small test set with expected evidence and known failure cases, then track:
- claim support rate and citation validity;
- missing or contradictory evidence surfaced;
- structured-output validity;
- tool calls outside the intended scope;
- total model and tool usage per completed memo;
- retries, timeouts, and human rejection reasons.
Test adversarial source text that tells the agent to ignore its task, malformed tool responses, empty retrieval, and duplicated documents. If the two-agent version cannot pass these cases consistently, a manager agent or a larger crew will add more failure paths rather than solve the design flaw.
An automated data collection policy should also define retention, refresh intervals, access rights, and deletion. Technical access to a page does not by itself establish permission to collect or reuse it.
Final verdict: begin with one explicit handoff
To build a multi-agent system with CrewAI, start with two agents, two observable task outputs, and a sequential process. Move deterministic validation and lifecycle control into a Flow, grant each agent only the tools it needs, and add agents only when a new role creates a real context or permission boundary.
The next step is to run the minimal crew against a small approved evidence packet, save its trace, and write failure assertions before connecting live tools. For website-backed research, Nstproxy Crawl can supply bounded, reusable source material while the Crew remains focused on analysis.
Prepare traceable web evidence for your CrewAI system
Use Nstproxy Crawl to turn authorized sites into controlled source artifacts for retrieval, evaluation, and citation instead of giving every agent independent browsing access.
FAQ
Q: What is CrewAI?
CrewAI is a Python framework for building role-based agents, tasks, Crews, and event-driven Flows. Crews support autonomous collaboration, while Flows provide more explicit application control.
Q: How many agents should a first CrewAI project use?
Two agents are usually enough for a first project when they have a meaningful handoff, such as researcher to reviewer. Add another agent only if it needs distinct context, tools, permissions, or evaluation criteria.
Q: Should a CrewAI process be sequential or hierarchical?
Start sequential when task order is known because it is easier to trace and test. Consider hierarchical coordination only when dynamic delegation produces measurable gains that justify the additional model calls and failure modes.
Q: Can CrewAI browse the web?
CrewAI agents can use web tools when those tools are configured, but access should be domain-scoped, read-only where possible, and protected against untrusted instructions. A separate acquisition layer can offer tighter control.



