Deep Researcher Agent#
The Deep Researcher coordinates a structured research pipeline that separates
source routing, planning, evidence collection, and final synthesis. It uses
task subagents under an orchestrator plus reusable researcher workers created
with the deepagents
and LangChain libraries.
Location: src/aiq_agent/agents/deep_researcher/agent.py
For optional DeepAgents sandbox execution and operational notes, refer to Deep Research Sandbox.
Purpose#
The deep path handles queries that require comprehensive investigation: multi-step research, comparative analyses, and topics that benefit from structured planning and evidence gathered from multiple sources. It produces the output shape requested by the user, including long-form reports, brief answers, tables, comparisons, predictions, and data extractions.
Internal Flow#
retain unmapped configured tools] B --> C[Build orchestrator and shared runtime] C --> D{Source router enabled?} D -->|yes| E[task: source-router-agent] E --> F[Write advisory SourceRoutingPlan
to /shared/source_routing.json] D -->|no| G[task: planner-agent] F --> G G --> H[Return structured ResearchPlan
persisted to /shared/plan.json] H --> I[Orchestrator calls run_research_batch
with planned ResearchQuery objects] I --> J[Concurrent reusable researcher workers
one worker per ResearchQuery] J --> K[Return structured ResearchNotes
and persist /shared/research_note_*.json] K --> L[Normative task: writer-agent] L --> M[Writer reads plan, notes, and captured sources
then writes /shared/output.md] M --> O[Runtime loads writer output] K -.->|Defensive path if writer delegation is missed| S[Orchestrator emits inline Markdown] S --> U{Passes substantive report gate?} U -->|yes| O U -->|no| V[Error: no final Markdown] O --> T{Citation verification enabled?} T -->|yes| P[Verify citations against captured sources] T -->|no| Q[Skip citation verification] P --> R[Sanitize and return final Markdown] Q --> R style A fill:#e1f5fe style E fill:#e8eaf6 style G fill:#fff8e1 style J fill:#fce4ec style L fill:#e8eaf6 style R fill:#e8f5e9
Coordination and Data Handoffs#
The orchestrator serializes dependent stages and tracks progress. It does not call source tools directly. The normative flow delegates final synthesis to the writer; source access is delegated to the planner and researcher workers. If the writer output file is missing, the runtime has a defensive fallback for a substantive report emitted inline by the orchestrator.
Runtime Roles#
Participant |
Invocation |
Responsibility and output |
|---|---|---|
Orchestrator |
Root |
Coordinates stage order, reads the persisted plan, dispatches research batches, and normally delegates final synthesis. It has |
|
Optional DeepAgents |
Looks up the configured source catalog, chooses one advisory domain route, and writes a |
|
DeepAgents |
Grounds the requested answer strategy with available source tools and returns a structured |
Researcher workers |
Reusable LangChain runnable invoked by |
Each worker executes one self-contained |
|
DeepAgents |
Reads the plan, research-note files, and captured sources; performs final-answer synthesis on the normative path; and writes |
The source router, planner, and writer are task subagents registered with the
DeepAgents root graph. Researcher workers are different: they are invocations
of one reusable, structured-output runnable behind the orchestrator-only
run_research_batch tool. They do not appear as task() subagents and do
not manage top-level workflow todos.
Data Source Boundary#
DeepResearchAgentState.data_sources is a hard per-request boundary for
tools mapped in data_source_registry. The registration layer filters those
mapped tools before constructing the active deep-research agent. Configured
tools that are not mapped to a registry source remain active:
Nonemakes all configured tools available.[]removes mapped data-source tools while retaining unmapped configured tools, including utilities.A populated list admits only tools mapped to those source IDs, plus unmapped configured tools, including utilities.
The optional source router receives a catalog containing only mapped sources within this boundary. Unmapped configured or utility tools do not appear in that catalog even though they remain active. Router recommendations are advisory and cannot restore a filtered-out mapped source.
The planner records exact available tool names in each
ResearchQuery.preferred_tools and fallback_tools as structured guidance.
Those fields do not narrow the callable tool set at runtime. Every researcher
worker is bound to the full request-filtered tool set and is prompted to try
the preferred and fallback tools in the recorded order.
Middleware and Tool Boundaries#
The roles use middleware appropriate to their contracts:
Role |
Relevant behavior |
|---|---|
Orchestrator |
DeepAgents task, todo, and filesystem support; source-routing guard; tool-name validation restricted to helpers and |
Source router |
Minimal filesystem and retry middleware; catalog lookup and |
Planner |
Source capture, retries, filesystem access, todo suppression, structured |
Researcher worker |
Filesystem context, optional skills, summarization, source capture, retries, and structured |
Writer |
Filesystem context, optional synthesis skills, source-registry access, retries, and todo suppression; no source-search tools |
The root graph is constructed with create_deep_agent. The reusable
researcher runnable is constructed separately with create_agent, which is
what lets run_research_batch invoke independent queries concurrently.
State Model#
DeepResearchAgentState#
Field |
Type |
Default |
Description |
|---|---|---|---|
|
|
required |
Input query and conversation messages managed by the LangGraph message reducer |
|
|
|
Hard per-request filter for registry-mapped source tools; unmapped configured tools remain active |
|
|
|
Authenticated user context available to prompts |
|
|
|
Available-tool metadata |
|
|
|
Top-level progress list managed by the orchestrator |
|
|
|
Merge-reduced virtual filesystem containing plans, notes, output, and optional parent-report context |
|
|
|
Status of configured DeepAgents task subagents; researcher worker invocations are not stored here |
|
|
|
Optional DeepAgents rubric state |
|
|
|
Clarification log containing missing context or requested output-shape preferences gathered before research |
|
|
|
User-uploaded documents and summaries available as research context |
When present, clarifier_result is injected as context. The planner
independently creates the ResearchPlan inside the deep-research workflow.
Configuration#
The architecture is configured through DeepResearchAgentConfig (NeMo Agent
Toolkit type name: deep_research_agent). The workflow-shaping parameters
are summarized here; refer to the
Configuration Reference
for configuration details.
Parameter |
Type |
Default |
Description |
|---|---|---|---|
|
|
required |
LLM for workflow coordination |
|
|
|
LLM for optional advisory routing; falls back to |
|
|
|
LLM for structured planning; falls back to |
|
|
|
LLM used by every researcher worker; falls back to |
|
|
|
LLM for final synthesis; falls back to |
|
|
|
Explicit source tools; an empty list inherits tools from the data-source registry |
|
|
|
Tool names removed from inherited tools |
|
|
|
Optional YAML or JSON domain catalog used by the source router |
|
|
|
Run the advisory source-router stage before planning |
|
|
|
Maximum |
|
|
|
Optional built-in skill assignments by agent name |
|
|
|
Optional sandbox profile for DeepAgents |
|
|
|
Verify generated citations against captured sources after final report extraction |
|
|
|
Enable detailed logging |
Example YAML:
functions:
deep_research_agent:
_type: deep_research_agent
orchestrator_llm: nemotron_llm
source_router_llm: nemotron_super_llm
planner_llm: nemotron_llm
researcher_llm: nemotron_llm
writer_llm: nemotron_super_llm
enable_source_router: true
enable_citation_verification: true
max_research_concurrency: 6
verbose: true
tools:
- web_search_tool
Note
Nemotron Super — Build Endpoint Availability: Nemotron Super (nvidia/nemotron-3-super-120b-a12b) is compatible and tested with AIQ, but Build API endpoints have limited availability due to high demand (HTTP 429/503 responses). The default configs use Nemotron Super for the researcher_llm role. For production deployments requiring consistent throughput, self-hosting via a Brev Launchable is recommended. Refer to Troubleshooting for details.
Prompt Templates#
Located in src/aiq_agent/agents/deep_researcher/prompts/:
Template |
Purpose |
|---|---|
|
Coordinates the ordered router, planner, batch-research, and writer handoffs |
|
Selects an advisory route from the allowed source catalog and writes |
|
Builds the structured |
|
Executes one |
|
Reads persisted artifacts and captured sources, then performs final synthesis into |
Workflow Phases#
Phase 1: Advisory Source Routing#
When enable_source_router is true, source-router-agent selects one
domain route and source ordering from the already-allowed source catalog. It
writes /shared/source_routing.json. Planning continues without this stage
when it is disabled, and the route does not override the user’s source
selection.
Phase 2: Research Planning#
The planner uses available source tools to ground a structured
ResearchPlan containing:
Task analysis and the intended answer shape
Required answer components and constraints
Self-contained
ResearchQueryobjectsPreferred and fallback tool guidance for each query
The planner reads source-routing guidance when available and records the final
query-level tool preference order. This is prompt guidance rather than runtime
tool enforcement. The runtime persists the validated plan to
/shared/plan.json.
Phase 3: Concurrent Evidence Collection#
The orchestrator passes the plan’s independent ResearchQuery objects to
run_research_batch. The tool invokes one reusable researcher worker per
query concurrently, bounded by max_research_concurrency. Each worker:
Reads the relevant plan context
Is prompted to follow the query’s preferred and fallback tool order while remaining bound to the full request-filtered tool set
Returns validated
ResearchNoteswith findings, sources, gaps, and an evidence judgment
The batch tool returns the notes to the orchestrator and persists them under
/shared/research_note_*.json. If only part of a batch fails, successful
notes remain registered and persisted; only failed or missing queries are
eligible for another call.
Phase 4: Writer-First Final Synthesis#
The orchestrator delegates once the plan and research notes are available.
The writer reads /shared/plan.json, all research-note files, and the
captured source registry. It may also read parent-report context for a report
edit. The writer performs no new research, writes the complete final answer to
/shared/output.md, and returns a short completion marker. The runtime loads
the Markdown from that file.
This is the normative synthesis contract. As a defensive compatibility path,
_salvage_inline_report() accepts the orchestrator’s final message when the
output file is missing, but only if the message is substantive Markdown: at
least 400 characters with a Markdown heading and not merely the writer
completion marker. Otherwise, missing writer output remains an error.
Phase 5: Citation Verification (Post-Processing)#
Citation verification is enabled by default and configurable with
enable_citation_verification. When enabled, a deterministic
post-processing pipeline checks citations against sources captured from
configured tools. Report sanitization runs after final report extraction
regardless of this setting.
Location: src/aiq_agent/common/citation_verification.py
Source Registry#
During planning and research, SourceRegistryMiddleware records URLs and
citation keys returned by allowed source tools in a per-session
SourceRegistry. Research-note source locators identify the compact set
carried forward for writer-facing citation selection.
Citation Verification#
The verify_citations() function validates citations in the report against
the source registry using five URL matching strategies:
Exact match – raw or normalized URL
Truncation match – report URL is a prefix of exactly one registry URL
Prefix match – normalized report URL is a prefix of a registry URL
Child-path match – report URL path is a subpath of a registry URL
Query-subset match – same host and path, with a subset of query parameters
Unmatched citations are removed and recorded with an audit reason. Knowledge
layer citations, such as report.pdf, p.15, are matched against citation
keys with lenient page-number comparison.
Report Sanitization#
The sanitize_report() function removes potentially unsafe or unreliable
URLs from the report body:
Shortened URLs
Truncated or garbled URLs
IP-address URLs
Non-HTTP schemes such as
javascript:,data:,vbscript:, andfile:
After removals, citations are renumbered to close gaps in the reference list.
Verification Result#
The verification result includes:
Field |
Description |
|---|---|
|
Report text after citation verification |
|
Removed citations with reasons |
|
Retained citations with reference numbers |
Evaluation#
The Deep Researcher is evaluated using the Deep Research Bench (DRB), which measures research reports using RACE and FACT metrics. Refer to Deep Research Bench for full documentation.