# iaadi4/deep-research-agent architecture

> Architecture diagram of the GitHub repository iaadi4/deep-research-agent, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-23). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/iaadi4/deep-research-agent
- Repository: https://github.com/iaadi4/deep-research-agent

## Overview

1. **What this repo is**
   - This is a Python-based, multi-agent research pipeline rather than a traditional app.
   - The system uses **LangGraph** to route a research task through specialized LLM-driven roles, then returns a synthesized markdown report.

2. **Top-level runtime shape**
   - `main.py` is the entrypoint, so the project likely runs as a command-line or script-driven workflow.
   - `src/` contains the actual application logic; `pyproject.toml` and `uv.lock` define the Python environment and locked dependencies.

3. **Core orchestration boundary**
   - `src/graph.py` is the central coordination layer.
   - It likely compiles the LangGraph state machine, defines node transitions, and controls the loop between clarification, planning, research, judging, and synthesis.

4. **Shared state model**
   - `src/state.py` is the shared contract between agents.
   - This is the key architectural boundary: each agent reads from and writes to a common workflow state rather than passing ad hoc objects around.
   - For diagramming, treat this as the “data spine” of the whole system.

5. **Agent subsystem**
   - `src/agents/` contains the role-specific LLM behaviors:
     - `clarifier_agent.py` resolves vague user queries.
     - `planner_agent.py` decomposes the clarified intent into research steps.
     - `researcher_agent.py` gathers evidence using tools.
     - `synthesizer_agent.py` turns validated evidence into the final report.
   - These are not independent services; they are nodes in a single stateful graph.

6. **Prompt subsystem**
   - `src/prompts/` holds the instruction templates for each agent.
   - This separates prompt engineering from orchestration logic, which is important for maintainability and diagramming: the agent “brains” are split between code and prompt assets.

7. **Tooling and external data sources**
   - `src/tools/` contains the retrieval and preprocessing utilities used by the researcher:
     - `tavily_search_tool.py` for general web search.
     - `arxiv_search_tool.py` for academic paper discovery.
     - `firecrawl_scrapping_tool.py` for web page scraping/extraction.
     - `summarizer_tool.py` for condensation and likely hallucination reduction.
   - These tools form the external-data boundary of the system.

8. **LLM and provider integration**
   - `src/llm.py` centralizes model setup.
   - The README indicates **Google Gemini** via `langchain-google-genai`, so the agents share a common model integration rather than configuring providers separately in each agent.

9. **End-to-end data flow**
   - The flow starts with a user query entering the clarifier.
   - If ambiguous, the system loops back for clarification.
   - Once scoped, the planner creates sub-tasks.
   - The researcher retrieves and filters information from web and academic sources.
   - The synthesizer produces the final report from the validated context.

10. **Quality-control loop**
   - The README describes a judge-like verification step even though the file tree only explicitly shows four agents.
   - Architecturally, this means the research phase is not linear: gathered evidence can be sent back for more searching when coverage is incomplete or contradictory.
   - For a diagram, this is the main feedback loop in the system.

11. **Verification and hallucination handling**
   - The system emphasizes source checking and hallucination reduction.
   - The summarizer tool and judge feedback loop suggest evidence is filtered before synthesis, not just dumped into the final report.

12. **External dependencies that matter architecturally**
   - The project depends on **LangGraph** for stateful orchestration, **LangChain** for model/prompt abstractions, and **Pydantic** for structured state/output validation.
   - Environment variables in `.env.sample` indicate required external APIs, especially **Google API key** and **Tavily API key**.

13. **How to draw the architecture**
   - The cleanest diagram is: User input → Clarifier → Planner → Researcher → Judge/verification loop → Synthesizer → Final markdown output.
   - Surround the researcher with external tools/services: Tavily, arXiv, Firecrawl, and summarization.
   - Place `state.py` as the shared workflow context that connects all nodes.

14. **Key architectural takeaway**
   - This repo is a single-process, graph-orchestrated research engine with strong separation between orchestration, agent prompts, retrieval tools, and shared state.
   - Its defining characteristic is the iterative research-and-validate loop before final synthesis, not a one-pass generation pipeline.

Main entry points: [`src/agents/researcher_agent.py`](https://github.com/iaadi4/deep-research-agent/blob/main/src/agents/researcher_agent.py) (Researcher), [`src/graph.py`](https://github.com/iaadi4/deep-research-agent/blob/main/src/graph.py) (Graph), [`src/llm.py`](https://github.com/iaadi4/deep-research-agent/blob/main/src/llm.py) (LLM), [`src/agents/synthesizer_agent.py`](https://github.com/iaadi4/deep-research-agent/blob/main/src/agents/synthesizer_agent.py) (Synthesizer)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_runtime["Runtime"]
  node_main["main.py<br/>entrypoint<br/>[main.py]"]
end

subgraph group_core["Core"]
  node_graph{{"Graph<br/>orchestrator<br/>[graph.py]"}}
  node_state[("State<br/>[state.py]")]
  node_llm["LLM<br/>model setup<br/>[llm.py]"]
  node_verification(("Judge<br/>quality gate"))
end

subgraph group_agents["Agents"]
  node_clarifier["Clarifier<br/>agent<br/>[clarifier_agent.py]"]
  node_planner["Planner<br/>agent<br/>[planner_agent.py]"]
  node_researcher["Researcher<br/>agent"]
  node_synthesizer["Synthesizer<br/>agent"]
end

subgraph group_prompts["Prompts"]
  node_clarifier_prompt["Clarifier prompt"]
  node_planner_prompt["Planner prompt<br/>[planner_prompt.py]"]
  node_researcher_prompt["Researcher prompt"]
  node_synthesizer_prompt["Synth prompt"]
end

subgraph group_tools["Tools"]
  node_tavily["Tavily<br/>search tool"]
  node_arxiv["arXiv<br/>search tool"]
  node_firecrawl["Firecrawl<br/>scraper"]
  node_summarizer["Summarizer<br/>condensation tool<br/>[summarizer_tool.py]"]
end

subgraph group_external["External"]
  node_gemini(("Gemini<br/>LLM provider"))
  node_web[("Web sources<br/>data source")]
  node_papers[("arXiv index<br/>data source")]
end

node_main -->|"starts"| node_graph
node_graph -->|"uses"| node_state
node_graph -->|"routes"| node_clarifier
node_graph -->|"routes"| node_planner
node_graph -->|"routes"| node_researcher
node_graph -.->|"loops"| node_verification
node_graph -->|"routes"| node_synthesizer
node_llm -->|"powers"| node_clarifier
node_llm -->|"powers"| node_planner
node_llm -->|"powers"| node_researcher
node_llm -->|"powers"| node_synthesizer
node_clarifier_prompt -->|"guides"| node_clarifier
node_planner_prompt -->|"guides"| node_planner
node_researcher_prompt -->|"guides"| node_researcher
node_synthesizer_prompt -->|"guides"| node_synthesizer
node_clarifier -->|"updates"| node_state
node_planner -->|"updates"| node_state
node_researcher -->|"updates"| node_state
node_verification -.->|"requests more"| node_researcher
node_researcher -->|"queries"| node_tavily
node_researcher -->|"queries"| node_arxiv
node_researcher -->|"extracts"| node_firecrawl
node_researcher -->|"condenses"| node_summarizer
node_tavily -->|"reads"| node_web
node_firecrawl -->|"reads"| node_web
node_arxiv -->|"reads"| node_papers
node_synthesizer -->|"reads"| node_state
node_synthesizer -->|"returns"| node_main
node_graph -->|"uses"| node_llm

click node_main "https://github.com/iaadi4/deep-research-agent/blob/main/main.py"
click node_graph "https://github.com/iaadi4/deep-research-agent/blob/main/src/graph.py"
click node_state "https://github.com/iaadi4/deep-research-agent/blob/main/src/state.py"
click node_llm "https://github.com/iaadi4/deep-research-agent/blob/main/src/llm.py"
click node_clarifier "https://github.com/iaadi4/deep-research-agent/blob/main/src/agents/clarifier_agent.py"
click node_planner "https://github.com/iaadi4/deep-research-agent/blob/main/src/agents/planner_agent.py"
click node_researcher "https://github.com/iaadi4/deep-research-agent/blob/main/src/agents/researcher_agent.py"
click node_synthesizer "https://github.com/iaadi4/deep-research-agent/blob/main/src/agents/synthesizer_agent.py"
click node_clarifier_prompt "https://github.com/iaadi4/deep-research-agent/blob/main/src/prompts/clarifier_prompt.py"
click node_planner_prompt "https://github.com/iaadi4/deep-research-agent/blob/main/src/prompts/planner_prompt.py"
click node_researcher_prompt "https://github.com/iaadi4/deep-research-agent/blob/main/src/prompts/researcher_prompt.py"
click node_synthesizer_prompt "https://github.com/iaadi4/deep-research-agent/blob/main/src/prompts/synthesizer_prompt.py"
click node_tavily "https://github.com/iaadi4/deep-research-agent/blob/main/src/tools/tavily_search_tool.py"
click node_arxiv "https://github.com/iaadi4/deep-research-agent/blob/main/src/tools/arxiv_search_tool.py"
click node_firecrawl "https://github.com/iaadi4/deep-research-agent/blob/main/src/tools/firecrawl_scrapping_tool.py"
click node_summarizer "https://github.com/iaadi4/deep-research-agent/blob/main/src/tools/summarizer_tool.py"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_main toneBlue
class node_graph,node_state,node_llm,node_verification toneAmber
class node_clarifier,node_planner,node_researcher,node_synthesizer toneMint
class node_clarifier_prompt,node_planner_prompt,node_researcher_prompt,node_synthesizer_prompt toneRose
class node_tavily,node_arxiv,node_firecrawl,node_summarizer toneIndigo
class node_gemini,node_web,node_papers toneTeal
```

## Components

### Runtime

Entry point and Python packaging/runtime layer

- [main.py](https://github.com/iaadi4/deep-research-agent/blob/main/main.py): entrypoint · Starts the research workflow · `main.py`

### Core

Graph orchestration and shared workflow state

- [Graph](https://github.com/iaadi4/deep-research-agent/blob/main/src/graph.py): orchestrator · Builds the LangGraph state machine and routing loop · `src/graph.py`
- [State](https://github.com/iaadi4/deep-research-agent/blob/main/src/state.py): workflow state · Shared data contract passed between nodes · `src/state.py`
- [LLM](https://github.com/iaadi4/deep-research-agent/blob/main/src/llm.py): model setup · Centralized provider and model configuration · `src/llm.py`
- **Judge**: quality gate · Checks coverage and sends weak evidence back for more research

### Agents

LLM-driven roles in the research loop

- [Clarifier](https://github.com/iaadi4/deep-research-agent/blob/main/src/agents/clarifier_agent.py): agent · Resolves vague or incomplete user requests · `src/agents/clarifier_agent.py`
- [Planner](https://github.com/iaadi4/deep-research-agent/blob/main/src/agents/planner_agent.py): agent · Breaks clarified intent into research steps · `src/agents/planner_agent.py`
- [Researcher](https://github.com/iaadi4/deep-research-agent/blob/main/src/agents/researcher_agent.py): agent · Gathers and filters evidence from tools · `src/agents/researcher_agent.py`
- [Synthesizer](https://github.com/iaadi4/deep-research-agent/blob/main/src/agents/synthesizer_agent.py): agent · Produces the final markdown report · `src/agents/synthesizer_agent.py`

### Prompts

Instruction templates for each role

- [Clarifier prompt](https://github.com/iaadi4/deep-research-agent/blob/main/src/prompts/clarifier_prompt.py): prompt · Instruction template for clarification · `src/prompts/clarifier_prompt.py`
- [Planner prompt](https://github.com/iaadi4/deep-research-agent/blob/main/src/prompts/planner_prompt.py): prompt · Instruction template for task decomposition · `src/prompts/planner_prompt.py`
- [Researcher prompt](https://github.com/iaadi4/deep-research-agent/blob/main/src/prompts/researcher_prompt.py): prompt · Instruction template for evidence gathering · `src/prompts/researcher_prompt.py`
- [Synth prompt](https://github.com/iaadi4/deep-research-agent/blob/main/src/prompts/synthesizer_prompt.py): prompt · Instruction template for report writing · `src/prompts/synthesizer_prompt.py`

### Tools

Retrieval and preprocessing utilities

- [Tavily](https://github.com/iaadi4/deep-research-agent/blob/main/src/tools/tavily_search_tool.py): search tool · General web search retrieval · `src/tools/tavily_search_tool.py`
- [arXiv](https://github.com/iaadi4/deep-research-agent/blob/main/src/tools/arxiv_search_tool.py): search tool · Academic paper discovery · `src/tools/arxiv_search_tool.py`
- [Firecrawl](https://github.com/iaadi4/deep-research-agent/blob/main/src/tools/firecrawl_scrapping_tool.py): scraper · Web page extraction and scraping · `src/tools/firecrawl_scrapping_tool.py`
- [Summarizer](https://github.com/iaadi4/deep-research-agent/blob/main/src/tools/summarizer_tool.py): condensation tool · Compresses evidence and reduces noise · `src/tools/summarizer_tool.py`

### External

Model and data-source boundaries

- **Gemini**: LLM provider · Shared model backend for the agents
- **Web sources**: data source · General online pages used for research
- **arXiv index**: data source · Academic paper corpus

## Connections

- main.py → Graph: starts · CLI entrypoint launches the workflow
- Graph → State: uses · Workflow routes through shared state
- Graph → Clarifier: routes · Sends the initial query into clarification
- Graph → Planner: routes · Moves scoped intent into planning
- Graph → Researcher: routes · Executes research and evidence gathering
- Graph → Judge: loops · Routes incomplete or conflicting evidence back for more work
- Graph → Synthesizer: routes · Hands validated context to final synthesis
- LLM → Clarifier: powers · Provides the model backend
- LLM → Planner: powers · Provides the model backend
- LLM → Researcher: powers · Provides the model backend
- LLM → Synthesizer: powers · Provides the model backend
- Clarifier prompt → Clarifier: guides · Clarification instructions
- Planner prompt → Planner: guides · Planning instructions
- Researcher prompt → Researcher: guides · Research instructions
- Synth prompt → Synthesizer: guides · Synthesis instructions
- Clarifier → State: updates · Writes clarified intent back to workflow state
- Planner → State: updates · Stores research plan and steps
- Researcher → State: updates · Stores evidence and source context
- Judge → Researcher: requests more · Triggers another search pass when coverage is weak
- Researcher → Tavily: queries · Uses web search for evidence
- Researcher → arXiv: queries · Uses academic search for evidence
- Researcher → Firecrawl: extracts · Scrapes and extracts page content
- Researcher → Summarizer: condenses · Reduces retrieved material into usable notes
- Tavily → Web sources: reads · Fetches general web sources
- Firecrawl → Web sources: reads · Fetches page content from the web
- arXiv → arXiv index: reads · Fetches paper metadata and abstracts
- Synthesizer → State: reads · Consumes validated workflow context
- Synthesizer → main.py: returns · Emits the final markdown report
- Graph → LLM: uses · Centralized model setup shared across nodes
