Back to Projects
AI Engineering / Agent Systemsv1 · Work in Progress

ScoutAI — Agentic Web Research System

A modular research system that determines when external research is needed, plans focused research tasks, executes web searches through MCP, synthesizes the collected findings, and streams execution progress to the frontend in real time.

Orchestration

LangGraph

Tool Layer

MCP + Tavily

Backend

FastAPI

Streaming

SSE

Problem & Approach.

The problem

A basic research assistant can be implemented as a simple sequence: send a question to an LLM, call a search tool, and generate an answer.

That approach becomes harder to maintain as the system grows. Not every message requires research, complex questions need decomposition, tool execution should be separated from synthesis, and long-running workflows need a way to communicate progress to the user.

The approach

ScoutAI treats research as an explicit workflow rather than a single LLM operation. A Router first determines the required execution path. Research requests then move through planning, research execution, and synthesis.

External capabilities are isolated through MCP, while FastAPI exposes the workflow as an SSE stream that the Next.js client consumes incrementally.

System Architecture.

The core workflow is implemented as a conditional LangGraph pipeline. The Router provides the decision layer, while the research path is divided into planning, execution, and synthesis.

                         [ User Query ]
                              │
                              ▼
                       ┌─────────────┐
                       │    Router   │
                       └──────┬──────┘
                              │
               ┌──────────────┴──────────────┐
               │                             │
        needs_research = false       needs_research = true
               │                             │
               ▼                             ▼
        ┌─────────────┐              ┌─────────────┐
        │    Casual   │              │   Planner   │
        └──────┬──────┘              └──────┬──────┘
               │                            │
               │                            ▼
               │                     ┌─────────────┐
               │                     │  Researcher │
               │                     └──────┬──────┘
               │                            │
               │                            ▼
               │                     ┌─────────────┐
               │                     │  MCP Client │
               │                     └──────┬──────┘
               │                            │
               │                            ▼
               │                     ┌─────────────┐
               │                     │  MCP Server │
               │                     └──────┬──────┘
               │                            │
               │                            ▼
               │                     ┌─────────────┐
               │                     │ Tavily Search│
               │                     └──────┬──────┘
               │                            │
               │                            ▼
               │                     ┌─────────────┐
               │                     │ Synthesizer │
               │                     └──────┬──────┘
               │                            │
               └────────────┬───────────────┘
                            ▼
                     [ Final Answer ]
                            │
                            ▼
                       [ SSE Stream ]
                            │
                            ▼
                     [ Next.js UI ]

Agentic Workflow.

Each stage has a defined responsibility and communicates through shared LangGraph state. This keeps the workflow composable and makes individual stages easier to modify independently.

01

Router

Classifies the incoming request and determines whether external research is necessary. Casual requests bypass the research pipeline entirely.

02

Planner

Decomposes a research question into focused tasks using structured output backed by a Pydantic schema.

03

Researcher

Executes each planned task and retrieves external information through the MCP tool layer while emitting execution progress.

04

MCP

Provides a protocol boundary between the agent and external capabilities. The current implementation exposes a Tavily-powered web search tool.

05

Synthesizer

Receives the collected research and produces the final response using the gathered evidence as its primary context.

Intent-Aware Routing.

The Router introduces an explicit decision layer before research execution. It uses the LLM to determine whether the request needs external information rather than relying on a hardcoded list of phrases.

Casual request

User → Router → Casual → Final Answer

Simple conversation bypasses the research pipeline and is handled directly by the configured LLM.

Research request

User → Router → Planner → Researcher → Synthesizer

Requests requiring external or current information enter the full research workflow.

LangGraph State

class ResearchState(TypedDict):
    query: str
    needs_research: bool
    plan: list[str]
    research: list[str]
    answer: str

Structured Planning.

Broad questions are converted into focused research tasks before any web search is performed. The Planner uses structured output backed by Pydantic so the Researcher receives a predictable data structure.

Example

Compare Python and TypeScript for building AI-powered web applications.

ResearchPlan
├── AI/ML libraries
├── Ecosystem maturity
├── Performance
├── Web development
└── Developer experience

Contract

class ResearchPlan(BaseModel):
    tasks: list[str]

The structured result is stored in graph state and becomes the input contract for the Researcher.

MCP Tool Architecture.

Web search is deliberately separated from the core agent through the Model Context Protocol. The Researcher interacts with an MCP client rather than directly depending on the search provider.

Researcher
    │
    ▼
MCP Client
    │
    ▼
MCP Server
    │
    ▼
search()
    │
    ▼
Tavily
    │
    ▼
Research Result

This creates a clean capability boundary. Additional tools can be exposed through MCP without embedding their implementation directly into the LangGraph research workflow.

Evidence & Synthesis.

Research execution and final answer generation are intentionally separate. The Researcher collects information while the Synthesizer receives the accumulated findings and produces the final response.

Research Tasks → Evidence Collection → Synthesis → Final Answer

Keeping these responsibilities separate makes the system easier to reason about and gives the final generation stage a clear body of research context instead of mixing search execution with response generation.

Real-Time Agent Streaming.

Research can involve multiple model calls and external searches. Instead of keeping the interface in a generic loading state, ScoutAI streams execution events from LangGraph through FastAPI using Server-Sent Events.

LangGraph
    │
    ├── router
    ├── planner
    ├── researcher
    │     ├── task_started
    │     └── task_completed
    │
    └── synthesizer
          │
          └── final_answer
                  │
                  ▼
           FastAPI SSE
                  │
                  ▼
        EventSourceResponse
                  │
                  ▼
       Browser ReadableStream
                  │
                  ▼
          Next.js UI

planning / plan

Communicates the beginning and result of the research planning stage.

task_started / task_completed

Exposes research execution progress as individual tasks run.

final_answer

Delivers the completed response through the same interface for both execution paths.

Streaming Contract.

Internal LangGraph execution events are translated into a smaller, frontend-oriented SSE event model. This keeps the UI independent from the internal graph implementation.

planning
plan
task_started
task_completed
synthesis_started
final_answer

Internal Agent Execution

Event Translation

FastAPI SSE Endpoint

Browser ReadableStream

React State

Architecture Evolution.

ScoutAI started as a simpler linear research workflow. As the system evolved, explicit routing, stronger boundaries between responsibilities, and real-time execution visibility were introduced.

Before

Every message entered the research workflow.

Now

A Router now decides whether research is necessary before the research pipeline begins.

Before

The workflow was primarily linear.

Now

LangGraph conditionally branches between casual conversation and research execution.

Before

Planning, execution, and synthesis were more tightly coupled.

Now

Each responsibility is isolated into a dedicated graph node with shared typed state.

Before

The user had little visibility during long-running research.

Now

Custom LangGraph events are translated into SSE events and streamed to the frontend in real time.

Key Engineering Decisions.

01

Conditional Agent Execution

The system does not send every message through the research pipeline. A dedicated LLM-based Router determines whether external research is actually required.

02

Separation of Responsibilities

Routing, planning, research execution, and synthesis are implemented as separate LangGraph nodes instead of being combined into a single monolithic agent call.

03

Structured Research Plans

The Planner produces a typed research plan using Pydantic structured output. This gives the Researcher a predictable interface rather than relying on arbitrary model-generated text.

04

MCP as a Tool Boundary

Web search is isolated behind an MCP client and server. The core research workflow therefore does not depend directly on the implementation details of the search provider.

05

Dedicated Synthesis

Research collection and answer generation are separate stages. The Researcher gathers evidence while the Synthesizer is responsible for turning that evidence into the final response.

06

Unified Streaming Contract

Both casual and research paths ultimately emit the same final_answer SSE event, allowing the frontend to maintain a single response pipeline.

Technology.

PythonCore agent and backend development
LangGraphAgent orchestration, state, and conditional routing
LangChainLLM integration and MCP adapter integration
MCPExternal tool integration boundary
FastAPIBackend API and SSE endpoint
Next.jsResearch interface and streaming UI
TypeScriptType-safe frontend development
OpenRouterLLM provider through an OpenAI-compatible API
TavilyWeb search capability
SSEReal-time execution event streaming

My Role.

I designed and implemented the system architecture, agent workflow, backend API, MCP integration, and frontend streaming experience. The project was built as an exploration of how these components work together as a complete AI system.

LangGraph workflow design
Typed agent state
LLM-based intent routing
Structured research planning
MCP client/server integration
Tavily web search integration
Research synthesis
FastAPI API design
SSE event streaming
Next.js streaming interface

Current Limitations.

This is a v1 architecture and is intentionally focused on the core agent workflow rather than production-scale research infrastructure.

The current MCP server exposes a single web-search capability.
Research tasks are executed sequentially rather than through parallel research workers.
The system does not yet maintain persistent research memory across sessions.
Source citation and evidence verification can be expanded further.
The current architecture is primarily an exploration of orchestration and streaming rather than a fully production-hardened research platform.

Future Direction.

The current architecture provides a foundation for expanding the system without replacing its core workflow model.

Parallel research execution
Multiple MCP tools
Source and citation tracking
Research memory
Query refinement
Research validation
Persistent sessions
More advanced agent routing

Engineering takeaway

The interesting part is the system around the model.

Building ScoutAI reinforced that an AI application is not just about prompting an LLM. Once the workflow involves planning, external tools, shared state, multiple execution stages, and long-running operations, architecture becomes part of the AI engineering problem.

ScoutAI is an ongoing exploration of how modular agent systems can be designed so that individual capabilities can evolve without requiring the entire application to be rewritten.

PixelActive
Pixel