Multi-Domain Research Agent Tutorial

A comprehensive guide to building and deploying a multi-agent research application using OpenAI's Agents SDK.

Introduction

This tutorial will walk you through understanding and implementing a sophisticated multi-domain research agent that automatically delegates research queries to specialized AI agents based on the topic domain. The application features a triage system that intelligently routes queries to Computer Science, Biology, or General Research specialists.

The system demonstrates advanced concepts in AI agent orchestration, structured data handling, and interactive web application development using modern Python frameworks.

Architecture Overview

The Multi-Domain Research Agent employs a hierarchical agent architecture:

  1. Triage Agent: Acts as the central dispatcher, analyzing incoming queries and routing them to appropriate specialists

  2. Domain-Specific Agents: Three specialized researchers handling:

    • Computer Science topics (algorithms, programming, systems)

    • Biology topics (biological processes, experiments, life sciences)

    • General Research (all other topics)

  3. Structured Output: All agents return standardized research results with titles, abstracts, citations, and detailed findings

  4. Interactive Interface: Streamlit-powered web UI for seamless user interaction.

Prerequisites and Setup

Required Dependencies

The project requires several key Python packages as defined in the requirements file:

openai-agents
openai
streamlit
pydantic
python-dotenv
asyncio

Environment Setup

  1. Clone the Repository

git clone https://github.com/jenilsoni-ai/master-ai-agents.git
cd master-ai-agents/openai-agents-sdk/beginner/multi-domain-research-agent
  1. Install Dependencies

pip install -r requirements.txt
  1. Configure OpenAI API Key

export OPENAI_API_KEY='your_openai_api_key'

Data Models and Structure

ResearchResult Schema

The application uses Pydantic for structured data validation and type safety:

class ResearchResult(BaseModel):
    title: str
    abstract: str
    domain: str
    citations: List[str]
    details: str

This model ensures consistent output format across all research agents, providing:

  • title: A descriptive title for the research findings

  • abstract: A concise summary of key points

  • domain: The research domain (Computer Science, Biology, or General)

  • citations: List of sources and references used

  • details: Comprehensive research findings and analysis

Agent Implementation

Computer Science Research Agent

cs_researcher = Agent(
    name="CS Researcher",
    instructions="""You are a computer science researcher. For the given query, conduct research using the available tools and compile your findings into a ResearchResult object. Include a title, an abstract summarizing the key points, set the domain to 'Computer Science', list citations from the sources used, and provide detailed information in the details field.""",
    model="gpt-4o-mini",
    tools=[WebSearchTool()],
    output_type=ResearchResult
)

Biology Research Agent

biology_researcher = Agent(
    name="Biology Researcher",
    instructions="""You are a biology researcher. For the given query, conduct research using the available tools and compile your findings into a ResearchResult object. Include a title, an abstract summarizing the key points, set the domain to 'Biology', list citations from the sources used, and provide detailed information in the details field.""",
    model="gpt-4o-mini",
    tools=[WebSearchTool()],
    output_type=ResearchResult
)

General Research Agent

general_researcher = Agent(
    name="General Researcher",
    instructions="""You are a general researcher. For the given query, conduct research using the available tools and compile your findings into a ResearchResult object. Include a title, an abstract summarizing the key points, set the domain to 'General', list citations from the sources used, and provide detailed information in the details field.""",
    model="gpt-4o-mini",
    tools=[WebSearchTool()],
    output_type=ResearchResult
)

Each specialized agent is configured with:

  • Domain-specific instructions for targeted research

  • WebSearchTool for accessing current information

  • Structured output type ensuring consistent results

  • GPT-4o-mini model for efficient processing

Triage System Implementation

Intelligent Query Routing

triage_agent = Agent(
    name="Triage Agent",
    instructions="""You are a triage agent. Analyze the user's query and determine which specialized agent should handle it:
    - If the query mentions algorithms, programming, or systems, hand off to the CS Researcher.
    - If the query involves biological concepts or experiments, hand off to the Biology Researcher.
    - For all other queries, hand off to the General Researcher.
    """,
    handoffs=[
        handoff(cs_researcher),
        handoff(biology_researcher),
        handoff(general_researcher)
    ],
    model="gpt-4o-mini"
)

The triage agent acts as a smart router that:

  • Analyzes query content to identify domain-specific keywords and concepts

  • Makes routing decisions based on predefined criteria

  • Delegates to specialists using the handoff mechanism

  • Ensures proper coverage with fallback to general research

Core Research Execution

Asynchronous Research Function

async def run_research(query):
    with trace("Academic Research"):
        result = await Runner.run(triage_agent, query)
    return result.final_output

This function:

  • Handles asynchronous execution for non-blocking research operations

  • Implements tracing for debugging and monitoring

  • Returns structured results from the agent pipeline

  • Manages the complete workflow from query to final output

Research Execution and Results Display

Main Research Pipeline

query = st.text_input("Enter your research query:", key="research_query", placeholder="e.g., What are the latest trends in machine learning?")

if st.button("Start Research", type="primary"):
    if query:
        with st.spinner("🔍 Conducting research... Please wait."):
            try:
                # Run the asynchronous research function
                result = asyncio.run(run_research(query))
                
                # Display the research results
                st.subheader("📄 Research Results")
                st.markdown(f"**Title**: {result.title}")
                st.markdown(f"**Domain**: {result.domain}")
                st.markdown(f"**Abstract**: {result.abstract}")
                st.markdown("**Citations**:")
                for citation in result.citations:
                    st.markdown(f"- {citation}")
                st.markdown("**Details**:")
                st.write(result.details)
                
                # Optional: Display the result as JSON for debugging
                with st.expander("View Raw JSON"):
                    st.json(result.dict())
            except Exception as e:
                st.error(f"An error occurred during research: {str(e)}")
    else:
        st.warning("Please enter a research query to proceed.")

This implementation provides:

  • Input validation ensuring queries are provided

  • Loading indicators for user feedback during processing

  • Structured result display with clear formatting

  • Error handling for robust operation

  • Debug information accessible through expandable sections

Running the Application

Local Development

  1. Start the Application

streamlit run multi_domain_agent.py
  1. Access the Interface

    • Open your browser to http://localhost:8501

    • The application will display the Multi-Domain Research Agent interface

  2. Conduct Research

    • Enter a research query or select from sample queries

    • Click "Start Research" to begin the process

    • View structured results including title, abstract, domain, citations, and details

Thankyou for reading. Happy Programming!!