Web Research Agent

March 8, 2026 ยท View on GitHub

A production-ready autonomous web research agent built with LangChain, LangGraph, and OpenAI. This agent accepts natural language research queries, intelligently breaks them into sub-questions, searches the web for current information, and synthesizes findings into professional, structured reports.

Features

  • ๐Ÿค– Autonomous Research - Automatically plans, searches, and synthesizes information
  • ๐Ÿ”Ž Multi-Provider Search - Supports Tavily, SerpAPI, and DuckDuckGo
  • ๐Ÿ“Š Structured Reports - Clean, professional output with sources and citations
  • ๐ŸŒ REST API - FastAPI backend with async support
  • ๐Ÿ–ฅ๏ธ React Frontend - Modern chat interface with markdown rendering
  • ๐Ÿณ Docker Ready - Multi-stage containerized deployment
  • โ˜๏ธ Cloud Deploy - Railway, Render, and Fly.io configs included
  • ๐Ÿ“… Real-time Date Aware - Always searches with current date context
  • โš™๏ธ Type-Safe Configuration - Pydantic-based settings management
  • ๐Ÿ›ก๏ธ Production-Ready - Proper error handling, logging, and security best practices

Architecture

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                        User Query                               โ”‚
โ”‚              (CLI / REST API / Chat Frontend)                   โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                              โ”‚
                              โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                 LangGraph ReAct Agent                           โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚  โ”‚                    Planning Phase                         โ”‚  โ”‚
โ”‚  โ”‚    โ€ข Analyze research goal                                โ”‚  โ”‚
โ”‚  โ”‚    โ€ข Decompose into sub-questions                         โ”‚  โ”‚
โ”‚  โ”‚    โ€ข Prioritize information needs                         โ”‚  โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
โ”‚                              โ”‚                                  โ”‚
โ”‚                              โ–ผ                                  โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚  โ”‚                   Research Phase                          โ”‚  โ”‚
โ”‚  โ”‚    โ€ข Tavily Search (AI-optimized, primary)                โ”‚  โ”‚
โ”‚  โ”‚    โ€ข SerpAPI (Google results)                             โ”‚  โ”‚
โ”‚  โ”‚    โ€ข DuckDuckGo (free fallback)                           โ”‚  โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
โ”‚                              โ”‚                                  โ”‚
โ”‚                              โ–ผ                                  โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚  โ”‚                   Synthesis Phase                         โ”‚  โ”‚
โ”‚  โ”‚    โ€ข Cross-reference sources                              โ”‚  โ”‚
โ”‚  โ”‚    โ€ข Resolve conflicts                                    โ”‚  โ”‚
โ”‚  โ”‚    โ€ข Generate structured report                           โ”‚  โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                              โ”‚
                              โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                   Structured Report                             โ”‚
โ”‚    โ€ข Objective       โ€ข Pros & Cons                              โ”‚
โ”‚    โ€ข Key Findings    โ€ข Final Recommendation                     โ”‚
โ”‚    โ€ข Analysis        โ€ข Sources                                  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Project Structure

web-research-agent/
โ”œโ”€โ”€ src/
โ”‚   โ”œโ”€โ”€ __init__.py           # Package initialization
โ”‚   โ”œโ”€โ”€ config.py             # Pydantic settings management
โ”‚   โ”œโ”€โ”€ exceptions.py         # Custom exception classes
โ”‚   โ”œโ”€โ”€ logging_config.py     # Structured logging setup
โ”‚   โ”œโ”€โ”€ prompts.py            # System prompts with real-time date
โ”‚   โ”œโ”€โ”€ agent.py              # ResearchAgent class (LangGraph)
โ”‚   โ”œโ”€โ”€ agui_agent.py         # AG-UI Protocol streaming agent
โ”‚   โ””โ”€โ”€ tools/
โ”‚       โ”œโ”€โ”€ __init__.py       # Tool exports
โ”‚       โ”œโ”€โ”€ registry.py       # Tool registry and discovery
โ”‚       โ”œโ”€โ”€ tavily_search.py  # Tavily search (primary)
โ”‚       โ”œโ”€โ”€ serpapi_search.py # SerpAPI Google search
โ”‚       โ””โ”€โ”€ duckduckgo_search.py  # DuckDuckGo fallback
โ”œโ”€โ”€ frontend/                 # Next.js React UI
โ”‚   โ”œโ”€โ”€ app/
โ”‚   โ”‚   โ”œโ”€โ”€ page.tsx          # Chat interface component
โ”‚   โ”‚   โ”œโ”€โ”€ layout.tsx        # Root layout
โ”‚   โ”‚   โ”œโ”€โ”€ globals.css       # Tailwind styles
โ”‚   โ”‚   โ””โ”€โ”€ api/research/     # Research API proxy route
โ”‚   โ”œโ”€โ”€ package.json
โ”‚   โ””โ”€โ”€ tailwind.config.ts
โ”œโ”€โ”€ main.py                   # CLI entry point
โ”œโ”€โ”€ api.py                    # FastAPI REST API
โ”œโ”€โ”€ api_agui.py               # AG-UI Protocol API server
โ”œโ”€โ”€ Dockerfile                # Multi-stage container build
โ”œโ”€โ”€ docker-compose.yml        # Local Docker setup
โ”œโ”€โ”€ render.yaml               # Render deployment
โ”œโ”€โ”€ railway.json              # Railway deployment
โ”œโ”€โ”€ fly.toml                  # Fly.io deployment
โ”œโ”€โ”€ Procfile                  # Process definition
โ”œโ”€โ”€ DEPLOYMENT.md             # Deployment guide
โ”œโ”€โ”€ pyproject.toml            # Python packaging & tooling config
โ”œโ”€โ”€ requirements.txt          # Python dependencies
โ””โ”€โ”€ requirements-api.txt      # API-specific dependencies

Quick Start

Prerequisites

  • Python 3.10+
  • Node.js 18+ (for frontend)
  • OpenAI API key

Option 1: CLI Usage

# Clone the repository
git clone https://github.com/senisinsane/Research-Agent.git
cd Research-Agent

# Create virtual environment
python -m venv venv
source venv/bin/activate  # Windows: venv\Scripts\activate

# Install dependencies
pip install -r requirements.txt

# Configure environment
cp .env.example .env
# Edit .env and add your API keys

# Run research
python main.py "What are the latest trends in AI?"

Option 2: REST API

# Start the API server
python api.py

# Or with AG-UI Protocol support
python api_agui.py

# Make a request
curl -X POST http://localhost:8000/research \
  -H "Content-Type: application/json" \
  -d '{"query": "What is quantum computing?"}'

Option 3: Full Stack (Frontend + Backend)

# Terminal 1: Start the backend
python api_agui.py

# Terminal 2: Start the frontend
cd frontend
npm install
npm run dev

# Open http://localhost:3000 in your browser

Option 4: Docker

# Build and run with Docker Compose
docker-compose up --build

# API available at http://localhost:8000

Configuration

Environment Variables

VariableRequiredDefaultDescription
OPENAI_API_KEYโœ… Yes-OpenAI API key
OPENAI_MODELNogpt-4o-miniModel to use
OPENAI_TEMPERATURENo0.0Response temperature
TAVILY_API_KEYโญ Recommended-Tavily API key (free tier)
SERPAPI_API_KEYNo-SerpAPI key for Google search
MAX_ITERATIONSNo25Max agent iterations
SEARCH_MAX_RESULTSNo5Results per search query
LOG_LEVELNoWARNINGLogging level

Search Providers

ProviderAPI KeyBest For
TavilyRequiredAI-optimized results (recommended)
SerpAPIRequiredGoogle search results
DuckDuckGoNoneFree fallback (always available)

The agent automatically uses available providers. Configure Tavily for best results.

API Reference

REST Endpoints (api_agui.py)

EndpointMethodDescription
/GETAPI info and available endpoints
/healthGETHealth check with configuration status
/researchPOSTExecute research query (JSON response)
/research/streamPOSTStreaming research with SSE events
/aguiPOSTAG-UI Protocol streaming endpoint
/langgraphPOSTLangGraph agent endpoint
/docsGETInteractive Swagger documentation

POST /research

Request:

{
  "query": "Your research question"
}

Response:

{
  "success": true,
  "query": "Your research question",
  "report": "**Objective**: This report investigates...\n\n**Key Findings**:..."
}

CLI Usage

Basic Usage

python main.py "your research query"

With Options

# Use a specific model
python main.py "Compare React vs Vue.js" --model gpt-4o

# Enable verbose logging
python main.py "Latest AI developments" --verbose

# Save to file
python main.py "Elon Musk net worth" --output report.txt

# Increase iteration limit
python main.py "Complex research topic" --max-iterations 40

CLI Arguments

ArgumentShortDefaultDescription
query-RequiredResearch query
--model-From configOpenAI model
--max-iterations-25Max iterations
--verbose-vFalseDebug logging
--output-ostdoutOutput file

Output Format

Reports follow this structure:

  1. Objective - What was researched
  2. Key Findings - 3-5 critical discoveries
  3. Detailed Analysis - In-depth exploration with context
  4. Pros & Cons - Balanced assessment
  5. Final Recommendation - Evidence-based conclusion
  6. Sources - Cited references with URLs

Programmatic Usage

from src.agent import create_agent

# Create agent
agent = create_agent(model="gpt-4o-mini")

# Run research
result = agent.research("What is quantum computing?")

# Access result
print(result.content)
print(f"Success: {result.success}")
print(f"Query: {result.query}")

Async Usage

import asyncio
from src.agent import create_agent

async def main():
    agent = create_agent()
    result = await agent.research_async("Latest AI news")
    print(result.content)

asyncio.run(main())

Error Handling

from src.exceptions import (
    ConfigurationError,
    AgentExecutionError,
    EmptyResponseError,
    SearchProviderUnavailableError,
)

try:
    result = agent.research(query)
except ConfigurationError as e:
    print(f"Config issue: {e}")
except AgentExecutionError as e:
    print(f"Agent error: {e}")
except EmptyResponseError as e:
    print(f"No response generated: {e}")

Deployment

Quick Deploy Options

PlatformConfiguration
Railwayrailway.json
Renderrender.yaml
Fly.iofly.toml
DockerDockerfile + docker-compose.yml

See DEPLOYMENT.md for detailed deployment instructions.

Docker Deployment

# Build image
docker build -t research-agent .

# Run container
docker run -p 8000:8000 \
  -e OPENAI_API_KEY=your_key \
  -e TAVILY_API_KEY=your_key \
  research-agent

Development

Install Dev Dependencies

pip install -e ".[dev]"

Code Quality

# Lint code
ruff check .

# Format code
black src/ main.py api.py api_agui.py

# Type check
mypy src/

Running Tests

# Run all tests
pytest

# With coverage
pytest --cov=src --cov-report=html

Adding a New Search Provider

  1. Create src/tools/your_provider.py:
from langchain_core.tools import tool
from src.config import get_settings
from src.logging_config import get_logger

logger = get_logger(__name__)

@tool
def your_search(query: str, max_results: int = 5) -> str:
    """Search description for the LLM."""
    settings = get_settings()
    # Your implementation
    return formatted_results
  1. Register in src/tools/registry.py:
from src.tools.your_provider import your_search

_TOOL_REGISTRY["your_search"] = your_search

Tech Stack

  • Backend: Python 3.10+, FastAPI, LangChain, LangGraph
  • Frontend: Next.js 14, React 18, Tailwind CSS
  • AI: OpenAI GPT-4o-mini (default), GPT-4o
  • Search: Tavily, SerpAPI, DuckDuckGo
  • Deployment: Docker, Railway, Render, Fly.io

License

MIT License - See LICENSE for details.


Repository: github.com/senisinsane/Research-Agent

Built with LangChain, LangGraph, and OpenAI