In the era of GenAI, Large Language Models (LLMs) are evolving from single-task assistants to collaborative agents capable of complex, multi-step reasoning. This guide provides a hands-on walkthrough for implementing multi-agent workflows using LlamaIndex, a robust framework that simplifies coordination between specialized LLM agents. This article demonstrates building agents that can research, write, and review content. Each agent has a focused role, shared memory, and seamless handoff. It enables well-structured and modular AI systems, far beyond a single prompt.
Table of Contents
- Understanding multi-agent workflow
- Why use a multi-agent system instead of one LLM call?
- Overview of LlamaIndex and Its Capabilities
- Step-by-step guide: Building a multi-agent system
Understanding multi-agent workflow
Multi-agent workflows originate from the broader field of multi-agent systems in artificial intelligence, where autonomous agents collaborate to solve problems too complex for a single entity. Traditionally used in robotics, simulations, and distributed systems, this concept has recently evolved with the rise of large language models (LLMs). Instead of one model handling everything, modern multi-agent workflows use a team of specialized LLM-based agents. These agents communicate, share memory, and coordinate through a structured workflow.
Why use a multi-agent system instead of one LLM call?
A genuine concern over the workflow can be regarding its effectiveness given that the same task can be performed with a single prompt to any of the available LLMs. Though it might appear to be a logical idea, in reality, a multi-agent workflow offers a structured, modular approach that can significantly outperform a single LLM query, especially for complex tasks like writing a detailed report.
Overview of LlamaIndex and its capabilities
LlamaIndex is a powerful framework that helps to connect language models (like GPT) with external data such as documents, databases, APIs, and even real-time tools.
Steps to building a multi-agent system
Step 1. Installing the necessary libraries
Ensuring that all core modules and integrations are available for the agents to function effectively.
!pip install llama-index openai llama-index-llms-openai llama-index-tools-tavily_research llama-index-agent-openai llama-index-core
Step 2. Setting up the OpenAI LLM
Initializing a language model instance using the “gpt-4o-mini” model using the llamaindex framework.
from google.colab import userdata
import os
os.environ["OPENAI_API_KEY"] = userdata.get('OPENAI_API_KEY')
from llama_index.llms.openai import OpenAI
llm = OpenAI(model="gpt-4o-mini")
Step 3. Initialize a web-search tool with Tavily
Integrating web search capability into the agent system using the Tavily tool.
from llama_index.tools.tavily_research import TavilyToolSpec
os.environ["TAVILY_API_KEY"] = userdata.get("TAVILY_API_KEY")
tavily_tool = TavilyToolSpec(api_key = userdata.get("TAVILY_API_KEY"))
search_web = tavily_tool.to_tool_list()[0]
Step 4. Recording research notes into the agent’s memory
Defining an asynchronous function that enables agents to store research findings or observations during the workflow.
from llama_index.core.workflow import Context
async def record_notes(ctx: Context, notes: str, notes_title: str) -> str:
current_state = await ctx.get("state")
if "research_notes" not in current_state:
current_state["research_notes"] = {}
current_state["research_notes"][notes_title] = notes
await ctx.set("state", current_state)
return "Notes recorded."
Step 5. Writing the final report to agent memory
Defining another asynchronous function that allows the agent to store the final version of a report within the shared workflow memory.
async def write_report(ctx: Context, report_content: str) -> str:
current_state = await ctx.get("state")
current_state["report_content"] = report_content
await ctx.set("state", current_state)
return "Report written."
Step 6. Submitting a review of the report
Defining another asynchronous function called that allows the agent to submit feedback or a review for a previously written report.
async def review_report(ctx: Context, review: str) -> str:
current_state = await ctx.get("state")
current_state["review"] = review
await ctx.set("state", current_state)
return "Report reviewed."
Step 7. Initializing the research-agent
Defining a Research Agent, designed to search the web for information on a given topic and take notes.
from llama_index.core.agent.workflow import FunctionAgent
research_agent = FunctionAgent(
name="ResearchAgent",
description="Useful for searching the web for information on a given topic and recording notes on the topic.",
system_prompt=(
"You are the ResearchAgent that can search the web for information on a given topic and record notes on the topic. "
"Once notes are recorded and you are satisfied, you should hand off control to the WriteAgent to write a report on the topic."
),
llm=llm,
tools=[search_web, record_notes],
can_handoff_to=["WriteAgent"],
)
Step 8. Initializing the write-agent
Defining the Write Agent for drafting a report based on previously gathered research.
write_agent = FunctionAgent(
name="WriteAgent",
description="Useful for writing a report on a given topic.",
system_prompt=(
"You are the WriteAgent that can write a report on a given topic. "
"Your report should be in a markdown format. The content should be grounded in the research notes. "
"Once the report is written, you should get feedback at least once from the ReviewAgent."
),
llm=llm,
tools=[write_report],
can_handoff_to=["ReviewAgent", "ResearchAgent"],
)
Step 9. Initializing the review agent
Defining the Review Agent for reviewing reports generated by the WriteAgent.
review_agent = FunctionAgent(
name="ReviewAgent",
description="Useful for reviewing a report and providing feedback.",
system_prompt=(
"You are the ReviewAgent that can review a report and provide feedback. "
"Your feedback should either approve the current report or request changes for the WriteAgent to implement."
),
llm=llm,
tools=[review_report],
can_handoff_to=["WriteAgent"],
)
Step 10. Creating the multi-agent workflow
Creating the multi-agent workflow, which defines how the different agents e.g. research_agent, write_agent, and review_agent will work together to complete the task.
from llama_index.core.agent.workflow import AgentWorkflow
agent_workflow = AgentWorkflow(
agents=[research_agent, write_agent, review_agent],
root_agent=research_agent.name,
initial_state={
"research_notes": {},
"report_content": "Not written yet.",
"review": "Review required.",})
Step 11. Running the workflow with a user prompt
Asking the AI system to create a report on the worldwide stock market crash on 7th April 2025, including a brief explanation of the causes, recovery prospects, and a dedicated section focused on the Indian context.
from llama_index.core.agent.workflow.workflow_events import AgentOutput
from llama_index.core.agent.workflow import ToolCallResult, ToolCall
handler = agent_workflow.run(
user_msg="""
Write me a report on the worldwide stock market crash on 7th April 2025.
Briefly describe the reasons and recovery prospects,
include a separate report in Indian context.
"""
)
Step 12. Streaming the output
Providing visibility into how each agent operates step by step.
current_agent = None
current_tool_calls = ""
async for event in handler.stream_events():
if (
hasattr(event, "current_agent_name")
and event.current_agent_name != current_agent
):
current_agent = event.current_agent_name
print(f"\n{'='*25}")
print(f"Agent: {current_agent}")
print(f"{'='*25}\n")
elif isinstance(event, AgentOutput):
if event.response.content:
print("Output:", event.response.content)
if event.tool_calls:
print(
"Planning to use tools:",
[call.tool_name for call in event.tool_calls],
)
elif isinstance(event, ToolCallResult):
print(f"Tool Result ({event.tool_name}):")
print(f"Arguments: {event.tool_kwargs}")
print(f"Output: {event.tool_output}")
elif isinstance(event, ToolCall):
print(f"Calling Tool: {event.tool_name}")
print(f"With arguments: {event.tool_kwargs}")
The output is as follows:
=========================
Agent: ResearchAgent
=========================
Planning to use tools: [‘search’]
Calling Tool: search
With arguments: {‘query’: ‘worldwide stock market crash April 7 2025 reasons recovery prospects’, ‘max_results’: 6}
Tool Result (search):
Arguments: {‘query’: ‘worldwide stock market crash April 7 2025 reasons recovery prospects’, ‘max_results’: 6}
Output: [Document(id_=’cb559958-0985-4729-a2dc-6f9e7cfd0fbc’, embedding=None, metadata={‘url’:
‘https://www.cnbc.com/2025/04/06/stock-market-today-live-updates.html‘},
excluded_embed_metadata_keys=[], excluded_llm_metadata_keys=[], relationships={},
metadata_template='{key}: {value}’, metadata_separator=’\n’,
text_resource=MediaResource(embeddings=None, data=None, text=”Beyond that, however, Lefkowitz
expects that structural growth themes like artificial intelligence will
support market recovery in the long term, saying that the S&P 500 can reach 5,800 by the end of
2025. That reflects more than 14% upside from Friday’s closing level.\n\n— Sean Conlon\n\n
…………
Output: Agent WriteAgent is now handling the request due to the following reason: I have gathered all
necessary information regarding the worldwide stock market crash on April 7, 2025, and its impact on
the Indian market.. Please continue with the current request.
=========================
Agent: WriteAgent
=========================
Planning to use tools: [‘write_report’]
Calling Tool: write_report
With arguments: {‘report_content’: “# Worldwide Stock Market Crash on April 7, 2025\n\nOn April 7, 2025, a historic
stock market crash occurred globally, wiping out over **$10 trillion** from major markets. This
crash was primarily attributed to **uncertainty surrounding new tariff policies** from the Trump
administration and growing economic concerns.
………
Tool Result (handoff):
Arguments: {‘to_agent’: ‘ReviewAgent’, ‘reason’: ‘The report on the worldwide stock market crash on April 7,
2025, and its impact on the Indian market is ready for review.’}
Output: Agent ReviewAgent is now handling the request due to the following reason: The report on the
worldwide stock market crash on April 7, 2025, and its impact on the Indian market is ready for
review.. Please continue with the current request.
=========================
Agent: ReviewAgent
=========================
Planning to use tools: [‘review_report’]
Calling Tool: review_report
With arguments: {‘review’: ‘The report on the worldwide stock market crash on April 7, 2025, is well-structured and
provides a comprehensive overview of the reasons behind the crash and its recovery prospects.
………
Output: The report on the worldwide stock market crash on April 7, 2025, has been successfully reviewed and
approved. It provides a comprehensive overview of the reasons behind the crash, recovery prospects,
and the impact on the Indian stock market. If you need any further assistance or additional reports,
feel free to ask!
Final Words
This hands-on guide demonstrated how to build a multi-agent workflow using LlamaIndex, integrating OpenAI-powered agents that collaborate to perform complex tasks in a modular, efficient way. By dividing responsibilities between ResearchAgent, WriteAgent, and ReviewAgent, we created a system that mirrors human-like teamwork—capable of real-time web search, structured writing, and iterative refinement. This approach enhances reliability, relevance, and clarity.