Case Study

Multi-Agent Research System

Autonomous research pipeline built with LangGraph - decomposes any topic into sub-questions, searches multiple sources in parallel, and synthesizes a structured report with self-correcting loops.

LangGraphGPT-4FAISSFastAPIPython

Multi-step reasoning

Self-correcting loops

Parallel search

Problem

Researching any complex topic manually means opening dozens of tabs, reading through noise, and trying to synthesize it all yourself. Single-prompt LLM responses hallucinate and lack depth. There was no system that could autonomously plan, search, verify, and synthesize the way a good researcher actually works.

Solution

Built a multi-agent system using LangGraph where each node has a single responsibility: decompose the query, search for sources, fact-check results, and synthesize a final report. If confidence is low after search, the graph loops back automatically. The same graph pattern used for Houdini SOPs - composable, stateless nodes wired together.

Impact

4

Agent Nodes

6

Max Research Steps

DuckDuckGo

Search Provider

Structured Report

Output Format

Architecture

Queries enter the decomposition node which breaks them into sub-questions. Each sub-question goes to the search agent. Results are scored for confidence and routed to fact-check if needed. Synthesis node merges everything into a structured report.

Query Decomposition

Breaks complex questions into focused sub-questions using chain-of-thought reasoning.

Web Search Agent

DuckDuckGo search with fallback simulation. Retrieves sources per sub-question.

Fact-Check Node

Validates results against source material. Loops back to search if confidence is low.

Synthesis Agent

Merges all findings into a structured report: Executive Summary, Key Findings, Challenges, Applications.

FastAPI Backend

Exposes the agent via POST /agents/chat. Accepts message and conversation history.

Agent Orchestration Pipeline

1

Query Ingestion

Receive user query via FastAPI endpoint

2

Decomposition

LangGraph node breaks query into parallel sub-questions

3

Parallel Search

Search agent fetches sources for each sub-question

4

Confidence Check

Low confidence routes to fact-check node

5

Self-Correction Loop

Fact-check triggers re-search if needed

6

Synthesis

All results merged into structured final report

Implementation

LangGraph Agent Orchestration

from langgraph.graph import StateGraph, END
from typing import Annotated, TypedDict
from langchain_core.messages import add_messages

class ResearchState(TypedDict):
    messages: Annotated[list, add_messages]
    query: str
    sub_tasks: list[str]
    confidence: float
    results: list[dict]

def build_research_graph():
    g = StateGraph(ResearchState)
    g.add_node("decompose",  decompose_agent)
    g.add_node("search",     search_agent)
    g.add_node("fact_check", fact_check_agent)
    g.add_node("synthesize", synthesis_agent)
    g.set_entry_point("decompose")
    g.add_edge("decompose", "search")
    g.add_conditional_edges(
        "search",
        lambda s: "fact_check" if s["confidence"] < 0.7 else "synthesize",
    )
    g.add_edge("fact_check", "search")
    g.add_edge("synthesize", END)
    return g.compile()

Confidence-Based Routing

async def search_agent(state: ResearchState) -> ResearchState:
    results = []
    for task in state["sub_tasks"]:
        hits = await web_search(task)
        scored = [
            {**hit, "confidence": score_relevance(state["query"], hit["text"])}
            for hit in hits
        ]
        results.extend(scored)
    avg_conf = sum(r["confidence"] for r in results) / max(len(results), 1)
    return {**state, "results": results, "confidence": avg_conf}

Engineering Challenges

Infinite Loops

Hard cap of 6 agent steps. After that the graph forces END regardless of confidence.

Search Availability

DuckDuckGo has rate limits. Built a simulated fallback so the agent still runs when search is unavailable.

Report Quality

System prompt enforces structured output: Executive Summary, Key Findings, Challenges, Applications every time.