Creating Multi-Agent Research Crews with Specialized Roles: CrewAI and Agno Patterns Explained
Multi-agent research crews combine purpose-specific agents—such as searchers, analysts, and writers—into sequential workflows using frameworks like CrewAI or Agno, where each role processes the output of the previous stage to produce comprehensive, hallucination-resistant reports.
The Arindam200/awesome-ai-apps repository provides production-ready implementations for creating multi-agent research crews with specialized roles. By analyzing the CrewAI starter and the Agno-based Deep Researcher Agent, you can architect AI teams where distinct agents handle search, synthesis, and writing tasks in a coordinated pipeline.
Architectural Blueprint for Research Crews
Both implementations in the repository follow a consistent four-layer architecture that separates concerns between agent definition, task orchestration, and execution flow.
Agent Layer
Each specialized role is encapsulated as a distinct Agent instance with its own description, instructions, and model configuration. In advance_ai_agents/deep_researcher_agent/agents.py, the three agents—searcher, analyst, and writer—bind to the same Nebius model (deepseek-ai/DeepSeek-V3-0324) but operate with different system prompts that shape their specific behaviors and constraints.
Task and Workflow Orchestration
CrewAI utilizes Task and Crew abstractions defined in starter_ai_agents/crewai_starter/main.py, setting process=Process.sequential to enforce strict execution order. Agno implements a Workflow subclass (DeepResearcherAgent) that manually sequences agent execution within its run() method, capturing intermediate outputs and streaming the final report with fine-grained control over error handling and logging.
Tooling and Infrastructure
The Deep Researcher integrates ScrapeGraph via ScrapeGraphTools (line 25 of agents.py) to fetch live web data during the search phase. Both projects include .env.example files for API key management (Nebius and Scrapegraph), while the Deep Researcher additionally provides an MCP server configuration in server.py for external tool invocation.
Building a Single-Agent Crew with CrewAI
The minimal implementation in starter_ai_agents/crewai_starter/main.py demonstrates the fundamental pattern: create an agent, define a task, and launch a crew.
cd starter_ai_agents/crewai_starter
pip install -r requirements.txt # or `uv sync`
cp .env.example .env # add your Nebius API key
python main.py
The script instantiates a researcher agent, wraps it in a Task object, and launches a Crew that prints generated paragraphs directly to the console.
Extending to Multi-Agent Workflows
Adding an Analyst Role to CrewAI
To expand beyond a single researcher, instantiate additional Agent objects and append their corresponding Task definitions to the crew's task list. The following extension to crewai_starter/main.py adds a synthesis step:
# Add after the researcher definition in crewai_starter/main.py
analyst = Agent(
role='Senior Analyst',
goal='Synthesize research findings',
verbose=True,
llm=LLM(model="nebius/Qwen/Qwen3-235B-A22B", api_key=os.getenv("NEBIUS_API_KEY")),
backstory='You have a knack for turning raw data into actionable insights.'
)
analysis_task = Task(
description='Summarize the research paragraphs and highlight key trends',
expected_output='A concise bullet-point summary',
agent=analyst,
)
tech_crew = Crew(
agents=[researcher, analyst],
tasks=[research_task, analysis_task],
process=Process.sequential,
)
Now the crew runs two tasks in strict sequence: research followed by analysis, with the Crew internals passing results implicitly between stages.
Three-Stage Pipeline with Agno
The DeepResearcherAgent class in advance_ai_agents/deep_researcher_agent/agents.py implements a sophisticated search→analysis→writing pipeline. The run() method explicitly chains agent outputs to prevent hallucination, extracting only the links and content that the previous stage supplied (see detailed instruction blocks in lines 64-71).
To execute the Deep Researcher:
cd advance_ai_agents/deep_researcher_agent
uv sync # install deps
cp .env.example .env # fill NEBIUS_API_KEY & SGAI_API_KEY
uv run python agents.py # prints the full report
# Or launch the UI:
uv run streamlit run app.py
The orchestration logic inside DeepResearcherAgent.run() follows this pattern:
research_content = self.searcher.run(topic) # ScrapeGraph + Nebius
analysis = self.analyst.run(research_content.content)
report = self.writer.run(analysis.content, stream=True)
The report iterator streams markdown chunks that are concatenated into the final document (see run_research() at lines 16-30 in the source).
Customizing Roles and Expanding the Crew
New specialized roles can be inserted into either framework by instantiating additional Agent objects with domain-specific prompts. For example, adding a "Trend Detector" to the Agno workflow:
trend_detector = Agent(
model=Nebius(id="deepseek-ai/DeepSeek-V3-0324", api_key=os.getenv("NEBIUS_API_KEY")),
description="You identify emerging trends from the analyst's summary.",
instructions=(
"1. Scan the analysis for repeated keywords and novel concepts.\n"
"2. Output a list of 3–5 concrete trend statements."
),
markdown=True,
)
# Insert after analyst step:
analysis = self.analyst.run(research_content.content)
trends = trend_detector.run(analysis.content)
# Pass trends to writer:
report = self.writer.run(f"{analysis.content}\n\nTrends:\n{trends.content}", stream=True)
This demonstrates how Agno’s workflow architecture supports arbitrary agent expansion while preserving the streaming response pattern. For CrewAI, you would simply add the new agent to the agents list and create a corresponding Task added to the tasks list.
Summary
- Define purpose-driven agents with role-specific descriptions and instructions to shape model behavior without requiring separate fine-tuning.
- Use sequential processing via
Process.sequentialin CrewAI or explicit method chaining in Agno to ensure each agent receives validated output from the previous stage. - Integrate external tools such as ScrapeGraph for live data retrieval by attaching tool classes to specific agents (as shown in line 25 of
deep_researcher_agent/agents.py). - Extend workflows by adding new
Agentinstances and inserting them into the task sequence or workflowrun()method, allowing the same underlying model to serve multiple cognitive roles. - Manage secrets through
.env.exampletemplates provided in bothstarter_ai_agents/crewai_starter/andadvance_ai_agents/deep_researcher_agent/directories.
Frequently Asked Questions
How do I prevent agents from hallucinating when passing data between stages?
In advance_ai_agents/deep_researcher_agent/agents.py, the analyst and writer agents include explicit instructions (lines 64-71) to extract and use only the links and content provided by the previous agent. By constraining the prompt to reference specific variables like research_content.content rather than allowing open-ended generation, you ground each stage in the actual output of its predecessor.
Can I use different LLM providers for different agents in the same crew?
Yes. Both implementations support mixing models. In the CrewAI example, you can pass different llm parameters to each Agent constructor. In the Agno implementation, each Agent instantiation can specify a different model ID or provider (e.g., one agent using nebius/Qwen/Qwen3-235B-A22B while another uses deepseek-ai/DeepSeek-V3-0324), allowing you to optimize for cost or capability per task.
What is the difference between CrewAI's Crew and Agno's Workflow?
CrewAI's Crew (used in starter_ai_agents/crewai_starter/main.py) handles task sequencing automatically when you provide a list of Task objects and set process=Process.sequential. Agno's Workflow (implemented in deep_researcher_agent/agents.py) requires you to subclass Workflow and manually orchestrate agent execution in a run() method, giving you explicit control over data transformation, error handling, and streaming responses between stages.
How do I add external tools like web scraping to my research crew?
In the Deep Researcher implementation, the searcher agent imports ScrapeGraphTools from agno.tools.scrapegraph and instantiates it at line 25 of agents.py. You attach the tool instance to the agent's tools parameter. For CrewAI, you would similarly import the appropriate tool class (e.g., SerperDevTool or a custom scraper) and pass it to the tools list when constructing the Agent.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →