
Building a Deep Research Agent: Multi-Agent Guide
A technical walkthrough for ML engineers on constructing a multi-agent research system that handles synthesis and citations.
Building a Deep Research Agent
Most LLM applications fail at research tasks not because the model lacks knowledge, but because the architecture cannot manage the complexity of multi-step reasoning and source verification. A "Deep Research" agent is not a single prompt; it is a stateful, multi-agent system that decomposes complex questions, retrieves evidence, and synthesizes answers with strict citation integrity. This walkthrough details the mechanical construction of such a system, focusing on the data flow between ai agents and the mechanisms that prevent hallucination. By treating this as an orchestration of specialized ai agents, we can build a robust research agent that handles the nuances of professional inquiry without human intervention.
The Multi-Agent Architecture
The core insight is decoupling. A monolithic RAG pipeline attempts to retrieve, read, and write in one pass. This fails for deep research because the context window becomes overloaded with irrelevant text, and the model loses track of which claim came from which source. We instead use a directed graph of specialized llm agents.
- The Planner: Decomposes a user’s high-level question into sub-queries. It maintains the global state of what has been answered and what remains unknown.
- The Researcher: Executes the sub-queries using hybrid search (vector + keyword). It extracts raw text chunks and preserves their metadata (URL, title, date) for citation.
- The Synthesizer: Takes the collected evidence and writes the final report. It is constrained by a strict schema that requires every claim to be linked to a specific evidence chunk.
This separation ensures that the Researcher focuses on recall (getting the right text) while the Synthesizer focuses on precision (correctly attributing the text). The research agent architecture allows for modular scaling, where each component can be optimized independently. This multi agent synthesis approach ensures that the final output is not just a collection of facts, but a coherent narrative derived from verified sources.
The Retrieval Mechanism
The Researcher agent is the engine of data ingestion. It does not simply return text; it returns structured evidence objects. To achieve high recall, we use hybrid search. Dense vectors capture semantic meaning (e.g., "quantum entanglement"), while sparse BM25 keywords capture exact terms (e.g., "Bell's Theorem"). As noted in information retrieval research, combining dense and sparse retrieval methods significantly improves recall over either method alone.
The key technical detail here is metadata preservation. When the Researcher retrieves a chunk, it must attach the source identifier to the content. This is not optional; it is the foundation of citation management. By automating this process, the system enables automated research workflows that can handle thousands of queries without manual curation or verification steps.
# Pseudocode for the Researcher's output structure
class EvidenceChunk:
content: str
source_url: str
source_title: str
chunk_id: str # Unique ID for cross-referencing
relevance_score: float
def retrieve(query: str) -> List[EvidenceChunk]:
vector_results = vector_store.search(query, top_k=5)
keyword_results = bm25_search(query, top_k=5)
# Merge and deduplicate by chunk_id
combined = merge(vector_results, keyword_results)
return [EvidenceChunk.from_doc(doc) for doc in combined]By enforcing this structure, we ensure that every piece of text flowing downstream carries its provenance. This allows the Synthesizer to verify claims against the exact source material rather than relying on the model’s internal memory.
Citation Integrity and Grounded Generation
The Synthesizer agent receives the list of EvidenceChunk objects. Its job is to generate a coherent narrative. However, unlike a standard chatbot, it is penalized for generating claims that cannot be traced back to a chunk_id.
This is achieved through "grounded generation." The prompt instructs the model to output JSON where each paragraph or claim includes a reference to the specific chunk ID that supports it. If the model cannot find support for a claim in the provided chunks, it must omit the claim rather than hallucinate one.
{
"summary": "Quantum entanglement allows particles to remain connected...",
"claims": [
{
"statement": "Entangled particles affect each other instantaneously.",
"citations": ["chunk_id_101", "chunk_id_105"]
}
]
}This structure forces the model to act as an editor rather than a creator. It can only arrange existing facts. This significantly reduces hallucination rates because the model’s vocabulary is constrained by the retrieved evidence. The trade-off is increased latency and token usage, but for research tasks, accuracy is paramount.
The Iterative Feedback Loop
A single pass of retrieval and synthesis is rarely sufficient. The Planner agent monitors the Synthesizer’s output. If the summary is vague, or if certain sub-questions remain unanswered, the Planner generates new, targeted queries.
For example, if the initial query is "Compare the energy efficiency of nuclear vs. solar power," the Synthesizer might find data on cost but not on carbon footprint. The Planner detects this gap (missing dimension) and instructs the Researcher to search specifically for "lifecycle carbon emissions nuclear solar."
This loop continues until the Planner determines that the evidence is sufficient. The termination condition is usually based on a confidence score from the Synthesizer or a maximum iteration limit. This iterative refinement is what distinguishes a "deep research" agent from a simple Q&A bot. It actively seeks out missing information rather than settling for the first plausible answer.
Conclusion
Building a deep research agent requires moving beyond simple RAG patterns. By decomposing the task into Planning, Retrieval, and Synthesis, and by enforcing strict citation structures, we create a system that is transparent, verifiable, and accurate. The complexity lies in the orchestration, but the result is an agent that can handle the nuances of professional research.
Related posts
Designing Tools an LLM Can Actually Use
A guide for backend developers and API designers on creating effective tool schemas, descriptions, and error handling for LLM agents.
Prompt Assembly, Citations, and Grounding
Explore prompt assembly, citations, and grounding techniques for RAG systems. Learn how context ordering and attribution improve accuracy and trust.
Building an LLM Load Test That Reflects Real Traffic
A guide to building LLM load tests that reflect real traffic patterns using capacity planning, arrival rates, and saturation metrics.