- unwind ai
- Posts
- Build a Multi-Agent Researcher with OpenAI Agents SDK
Build a Multi-Agent Researcher with OpenAI Agents SDK
Fully functional AI agent app with step-by-step instructions (100% opensource)
OpenAI just released its Agents SDK, a rebranded, production-ready, and advanced version of the OpenAI Swarm framework to build multi-agent applications. We couldn't wait to get our hands on it and build something useful.
In this tutorial, we'll walk you through building a multi-agent research assistant using OpenAI's Agents SDK. You'll create a system where multiple specialized agents work together to research any topic, collect facts, and generate comprehensive reports—all within a user-friendly application that's easy to use and extend.
The Agents SDK elegantly orchestrates the workflow between our three specialized agents, enabling seamless handoffs as research progresses. Its built-in tracing gives us visibility into the entire process, allowing us to monitor how information flows between agents and identify any bottlenecks. This lightweight framework lets us focus on creating specialized agent roles rather than building complex coordination mechanisms from scratch.
What We’re Building
A multi-agent research application built with OpenAI's Agents SDK and Streamlit. This application enables users to conduct comprehensive research on any topic by leveraging multiple specialized AI agents.
Features
Multi-Agent Architecture:
Triage Agent: Plans the research approach and coordinates the workflow
Research Agent: Searches the web and gathers relevant information
Editor Agent: Compiles collected facts into a comprehensive report
Automatic Fact Collection: Captures important facts from research with source attribution
Structured Report Generation: Creates well-organized reports with titles, outlines, and source citations
Interactive UI: Built with Streamlit for easy research topic input and results viewing
Tracing and Monitoring: Integrated tracing for the entire research workflow
How The App Works
This is how our research application uses a multi-agent workflow:
Research Planning (Triage Agent): This agent takes the user's query, creates a structured research plan including search queries and focus areas, and coordinates the entire workflow.
Information Gathering (Research Agent): When handed off from the Triage Agent, the Research Agent uses web search tools to gather relevant information, saving important facts with source attribution along the way.
Report Creation (Editor Agent): After information gathering is complete, the Editor Agent compiles all the collected facts, organizes them into a coherent structure, and produces a comprehensive research report with proper citations.
The entire process is traced for monitoring and debugging, while the Streamlit interface provides a user-friendly way to input topics and view results.
Prerequisites
Before we begin, make sure you have the following:
Python installed on your machine (version 3.10 or higher is recommended)
Your OpenAI API key
A code editor of your choice (we recommend VS Code or PyCharm for their excellent Python support)
Basic familiarity with Python programming
Step-by-Step Instructions
Setting Up the Environment
First, let's get our development environment ready:
Clone the GitHub repository:
git clone https://github.com/Shubhamsaboo/awesome-llm-apps.git
Go to the opeani_research_agent folder:
cd ai_agent_tutorials/opeani_research_agent
Install the required dependencies:
pip install -r requirements.txt
Set up your API keys: Set OpenAI API Key as an environment variable.
export OPENAI_API_KEY='your-api-key-here'
Creating the Streamlit App
Let’s create our app. Create a new file research_agent.py and add the following code:
Let's import our libraries:
import os
import uuid
import asyncio
import streamlit as st
from datetime import datetime
from dotenv import load_dotenv
from agents import (
Agent,
Runner,
WebSearchTool,
function_tool,
handoff,
trace,
)
from pydantic import BaseModel
Define data models for structured input and output:
class ResearchPlan(BaseModel):
topic: str
search_queries: list[str]
focus_areas: list[str]
class ResearchReport(BaseModel):
title: str
outline: list[str]
report: str
sources: list[str]
word_count: int
Create a custom tool for saving facts during research:
@function_tool
def save_important_fact(fact: str, source: str = None) -> str:
"""Save an important fact discovered during research.
Args:
fact: The important fact to save
source: Optional source of the fact
Returns:
Confirmation message
"""
if "collected_facts" not in st.session_state:
st.session_state.collected_facts = []
st.session_state.collected_facts.append({
"fact": fact,
"source": source or "Not specified",
"timestamp": datetime.now().strftime("%H:%M:%S")
})
return f"Fact saved: {fact}"
Define the Research Agent - Searches the web and collects information:
research_agent = Agent(
name="Research Agent",
instructions="You are a research assistant. Given a search term, you search the web for that term and"
"produce a concise summary of the results. The summary must 2-3 paragraphs and less than 300"
"words. Capture the main points. Write succintly, no need to have complete sentences or good"
"grammar. This will be consumed by someone synthesizing a report, so its vital you capture the"
"essence and ignore any fluff. Do not include any additional commentary other than the summary"
"itself.",
model="gpt-4o-mini",
tools=[
WebSearchTool(),
save_important_fact
],
)
Define the Editor Agent - Creates comprehensive reports
editor_agent = Agent(
name="Editor Agent",
handoff_description="A senior researcher who writes comprehensive research reports",
instructions="You are a senior researcher tasked with writing a cohesive report for a research query. "
"You will be provided with the original query, and some initial research done by a research "
"assistant.\n"
"You should first come up with an outline for the report that describes the structure and "
"flow of the report. Then, generate the report and return that as your final output.\n"
"The final output should be in markdown format, and it should be lengthy and detailed. Aim "
"for 5-10 pages of content, at least 1000 words.",
model="gpt-4o-mini",
output_type=ResearchReport,
)
Define the Triage Agent - Coordinates the workflow:
triage_agent = Agent(
name="Triage Agent",
instructions="""You are the coordinator of this research operation. Your job is to:
1. Understand the user's research topic
2. Create a research plan with the following elements:
- topic: A clear statement of the research topic
- search_queries: A list of 3-5 specific search queries that will help gather information
- focus_areas: A list of 3-5 key aspects of the topic to investigate
3. Hand off to the Research Agent to collect information
4. After research is complete, hand off to the Editor Agent who will write a comprehensive report
Make sure to return your plan in the expected structured format with topic, search_queries, and focus_areas.
""",
handoffs=[
handoff(research_agent),
handoff(editor_agent)
],
model="gpt-4o-mini",
output_type=ResearchPlan,
)
Create the Streamlit UI:
st.set_page_config(
page_title="OpenAI Researcher Agent",
page_icon="📰",
layout="wide",
initial_sidebar_state="expanded"
)
# App title and description
st.title("📰 OpenAI Researcher Agent")
st.subheader("Powered by OpenAI Agents SDK")
# Create sidebar for input and controls
with st.sidebar:
st.header("Research Topic")
user_topic = st.text_input(
"Enter a topic to research:",
)
start_button = st.button("Start Research", type="primary", disabled=not user_topic)
# Example topics
st.divider()
st.subheader("Example Topics")
example_topics = [
"What are the best cruise lines in USA for first-time travelers who have never been on a cruise?",
"What are the best affordable espresso machines for someone upgrading from a French press?",
"What are the best off-the-beaten-path destinations in India for a first-time solo traveler?"
]
for topic in example_topics:
if st.button(topic):
user_topic = topic
start_button = True
Implement the research process workflow:
async def run_research(topic):
# Reset state for new research
st.session_state.collected_facts = []
st.session_state.research_done = False
st.session_state.report_result = None
with tab1:
message_container = st.container()
# Create a trace for the entire workflow
with trace("News Research", group_id=st.session_state.conversation_id):
# Start with the triage agent
with message_container:
st.write("🔍 **Triage Agent**: Planning research approach...")
triage_result = await Runner.run(
triage_agent,
f"Research this topic thoroughly: {topic}. This research will be used to create a comprehensive research report."
)
# Display research plan
with message_container:
st.write("📋 **Research Plan**:")
st.json(plan_display)
# Display facts as they're collected
fact_placeholder = message_container.empty()
# Editor Agent phase
with message_container:
st.write("📝 **Editor Agent**: Creating comprehensive research report...")
report_result = await Runner.run(
editor_agent,
triage_result.to_input_list()
)
st.session_state.report_result = report_result.final_output
with message_container:
st.write("✅ **Research Complete! Report Generated.**")
Run the app when the start button is clicked:
if start_button:
with st.spinner(f"Researching: {user_topic}"):
try:
asyncio.run(run_research(user_topic))
except Exception as e:
st.error(f"An error occurred during research: {str(e)}")
Display the results:
with tab2:
if st.session_state.research_done and st.session_state.report_result:
report = st.session_state.report_result
# Display the full report in markdown
if hasattr(report, 'report'):
report_content = report.report
st.markdown(report_content)
else:
report_content = str(report)
st.markdown(report_content)
# Add download button for the report
st.download_button(
label="Download Report",
data=report_content,
file_name=f"{title.replace(' ', '_')}.md",
mime="text/markdown"
)
Running the App
With our code in place, it's time to launch the app.
In your terminal, navigate to the project folder, and run the following command
streamlit run research_agent.py
Streamlit will provide a local URL (typically http://localhost:8501). Open this in your web browser, enter a research topic or select one of the examples, and click "Start Research" to begin the process.
Working Application Demo
Conclusion
Your sophisticated multi-agent research assistant powered by OpenAI's new Agents SDK is now ready.
Here are some ways you could enhance this project:
Add a dedicated agent that verifies collected information against multiple sources, providing confidence scores for each fact and flagging potential misinformation.
Integrate DALL-E or other image generation tools to automatically create relevant visuals, diagrams, and infographics that complement the text report.
Implement memory systems to improve context between research sessions.
Allow multiple users to contribute to and guide research simultaneously, with agents adapting to different user inputs and preferences.
Keep experimenting with different agent configurations and features to build more sophisticated AI applications.
We share hands-on tutorials like this 2-3 times a week, to help you stay ahead in the world of AI. If you're serious about leveling up your AI skills and staying ahead of the curve, subscribe now and be the first to access our latest tutorials.
Reply