Recursive Retriever¶
📖 Overview¶
A Recursive Retriever is a retrieval strategy that allows the retrieval system to follow relationships between nodes and retrieve additional information connected to the initially retrieved results.
Instead of treating every retrieved node as an isolated piece of text, recursive retrieval understands that nodes can reference:
Parent Nodes
Child Nodes
Related Nodes
Summary Nodes
Metadata Nodes
Generated Question Nodes
Other Retrieval Sources
The core idea is:
LlamaIndex's RecursiveRetriever supports retrieval over node relationships and can recursively follow references from an initially retrieved node. LlamaIndex examples use this pattern for small-to-big retrieval, where smaller child chunks are indexed and linked back to larger parent chunks. :contentReference[oaicite:0]{index=0}
This makes recursive retrieval particularly useful for:
Small-to-Big Retrieval
Parent-Child Retrieval
Hierarchical Documents
Summary → Source Retrieval
Generated Question → Source Retrieval
Multi-Representation Retrieval
Embedded Tables
Document Agents
🎯 Learning Objectives¶
After completing this chapter, you will be able to:
- Understand recursive retrieval
- Understand node references
- Understand parent-child relationships
- Understand child-to-parent retrieval
- Understand small-to-big retrieval
- Understand recursive traversal
- Understand node mappings
- Build a basic recursive retrieval architecture
- Understand recursive retrieval in LlamaIndex
- Combine vector search with recursive traversal
- Understand summary-to-source retrieval
- Understand multi-representation retrieval
- Understand recursive retrieval with tables
- Understand recursive retrieval with document agents
- Evaluate recursive retrieval
- Understand performance and cost trade-offs
- Design production-ready recursive retrieval systems
1. What Is Recursive Retrieval?¶
Traditional retrieval looks like:
Recursive retrieval adds another dimension:
The retrieval process can therefore traverse a graph of related nodes.
2. Basic Mental Model¶
Imagine:
The vector retriever may identify:
But C2 may not contain enough context.
Recursive retrieval follows:
and returns:
instead of using only the small child chunk.
3. Why Do We Need Recursive Retrieval?¶
Suppose a document contains:
and is split into:
The query:
may match:
But Child Chunk 2 might contain only:
The parent section may contain the broader architecture.
Recursive retrieval allows:
to restore the missing context.
4. Recursive Retrieval Architecture¶
flowchart TD
A["User Query"] --> B["Initial Retriever"]
B --> C["Retrieved Node"]
C --> D{"Has References?"}
D -->|No| E["Return Node"]
D -->|Yes| F["Follow Reference"]
F --> G["Related Node"]
G --> H{"More References?"}
H -->|Yes| F
H -->|No| I["Expanded Context"]
E --> I
The important operation is:
5. Node References¶
A node can contain a relationship to another node.
Conceptually:
or:
The reference itself does not necessarily mean that the referenced node is automatically retrieved by a normal vector search.
The recursive retriever explicitly follows the relationship.
6. Node Graph¶
Consider:
This forms a node relationship graph.
Recursive retrieval can traverse this graph.
7. Parent-Child Relationship¶
A common structure is:
The retrieval direction can be:
This is particularly useful for small-to-big retrieval.
8. Small-to-Big Retrieval¶
The small-to-big pattern works like this:
Large Parent Chunk
↓
Split into smaller children
↓
Index children
↓
Retrieve child
↓
Follow reference
↓
Return parent
LlamaIndex's recursive-retriever example explicitly demonstrates this pattern by subdividing parent chunks into child chunks, linking children to their parent, indexing the children, and recursively retrieving related nodes. :contentReference[oaicite:1]{index=1}
9. Small-to-Big Architecture¶
flowchart TD
A["Document"] --> B["Parent Chunks"]
B --> C["Child Chunks"]
C --> D["Embedding"]
D --> E["Vector Index"]
F["Query"] --> G["Vector Retriever"]
E --> G
G --> H["Child Node"]
H --> I["Parent Reference"]
I --> J["Parent Node"]
J --> K["Expanded Context"]
This architecture separates:
from:
10. Why Retrieve Small Chunks?¶
Small chunks can provide better retrieval precision.
Example:
This is highly focused.
A large parent:
may contain:
The small child is easier to match to the query.
11. Why Return the Parent?¶
The small child may not provide sufficient context.
Therefore:
This is the central small-to-big principle.
12. Search Small, Generate Big¶
This is one of the most useful patterns for long enterprise documents.
13. Recursive Retriever vs Parent Document Retriever¶
These concepts are closely related.
Parent Document Retrieval¶
Recursive Retrieval¶
Recursive retrieval is the more general mechanism.
Parent-child retrieval is one important use case.
14. Recursive Retrieval Can Traverse More Than Parents¶
A node could reference:
Therefore:
is broader than:
15. Reference Graph¶
Example:
A recursive retriever can follow these references according to the configured retrieval graph.
16. LlamaIndex RecursiveRetriever¶
LlamaIndex provides a RecursiveRetriever abstraction for recursively retrieving nodes through references.
A typical configuration conceptually looks like:
recursive_retriever = RecursiveRetriever(
"vector",
retriever_dict={
"vector": vector_retriever
},
node_dict=node_mappings
)
The LlamaIndex recursive-retriever examples use a retriever dictionary together with node mappings to resolve referenced nodes. :contentReference[oaicite:2]{index=2}
17. What Is retriever_dict?¶
Conceptually:
Example:
This allows the recursive system to know which retriever should be used for a particular retrieval step.
18. What Is node_dict?¶
A node dictionary can provide mappings such as:
Conceptually:
When recursive retrieval encounters a reference:
it can resolve it to:
19. Node Mapping¶
flowchart LR
A["Reference ID"] --> B["Node Mapping"]
B --> C["Node Object"]
C --> D["Referenced Content"]
This is the mechanism that makes reference traversal possible.
20. Basic Recursive Retrieval Example¶
Conceptually:
from llama_index.core.retrievers import RecursiveRetriever
recursive_retriever = RecursiveRetriever(
"vector",
retriever_dict={
"vector": vector_retriever
},
node_dict=node_dict
)
results = recursive_retriever.retrieve(
"How does OAuth token validation work?"
)
for result in results:
print(result.node.text)
The exact imports and APIs can vary by LlamaIndex version.
21. Initial Retriever¶
The recursive retriever normally needs an initial retrieval mechanism.
For example:
could identify:
Then:
follows the node reference.
Therefore:
22. Initial Retrieval + Recursive Expansion¶
flowchart TD
A["Query"] --> B["Vector Retriever"]
B --> C["Child Node"]
C --> D["Reference Resolver"]
D --> E["Parent Node"]
E --> F["Additional References"]
F --> G["Expanded Result Set"]
This is the simplest useful recursive architecture.
23. Recursive Depth¶
A recursive retriever may need a limit on how far it traverses.
Conceptually:
means:
while:
means:
and:
means:
The exact supported configuration depends on the implementation/version.
24. Why Limit Recursive Depth?¶
Without a limit, a highly connected node graph could cause:
Therefore:
should always be controlled.
25. Recursive Depth Example¶
The system should stop according to its traversal policy.
26. Cycle Detection¶
Consider:
This creates a cycle.
A recursive retriever must avoid:
A visited-node set is a common conceptual safeguard:
27. Recursive Traversal with Visited Nodes¶
flowchart TD
A["Node A"] --> B["Node B"]
B --> C["Node C"]
C --> A
C --> D{"Already Visited?"}
D -->|Yes| E["Stop Traversal"]
D -->|No| F["Continue"]
This prevents infinite traversal.
28. Recursive Retrieval Is Graph Traversal¶
A useful mental model is:
The graph may look like:
The recursive retriever starts from a retrieved node and follows configured edges.
29. Retrieval Graph¶
graph TD
A["Document"] --> B["Parent Section"]
B --> C["Child Chunk 1"]
B --> D["Child Chunk 2"]
B --> E["Child Chunk 3"]
D --> F["Summary"]
D --> G["Generated Question"]
G --> H["Source Node"]
This demonstrates why recursive retrieval can support more than one representation of the same knowledge.
30. Multi-Representation Retrieval¶
A powerful pattern is to represent the same source information in multiple forms:
All representations can point back to:
Example:
31. Why Multiple Representations Help¶
Different representations can be optimized for different retrieval behavior.
Child Chunk
→ Precise semantic matching
Summary
→ Broad semantic matching
Generated Question
→ Query-style matching
Parent
→ Contextual synthesis
Source Node
→ Evidence
Recursive retrieval can connect these representations.
32. Summary → Source Retrieval¶
Suppose:
is easy to retrieve.
But the LLM needs:
The relationship can be:
The summary becomes the retrieval representation.
The source becomes the evidence.
33. Summary-Based Recursive Retrieval¶
flowchart TD
A["User Query"] --> B["Summary Retriever"]
B --> C["Summary Node"]
C --> D["Source Reference"]
D --> E["Original Source Node"]
E --> F["Context"]
This is conceptually similar to the document-summary pattern discussed in the previous chapter, but recursive retrieval provides the explicit node-reference mechanism.
34. Generated Question → Source Retrieval¶
Another useful pattern:
At query time:
This decouples:
from:
35. Generated Question Architecture¶
flowchart TD
A["Source Node"] --> B["Question Generator"]
B --> C["Question Node 1"]
B --> D["Question Node 2"]
B --> E["Question Node 3"]
C --> A
D --> A
E --> A
F["User Query"] --> G["Question Retriever"]
G --> C
G --> D
G --> E
A --> H["Source Evidence"]
The user query searches generated questions, but the final result comes from the source node.
36. Decoupling Retrieval and Synthesis¶
This is one of the most important ideas behind recursive retrieval.
Traditional:
Recursive retrieval allows:
For example:
or:
This is powerful for enterprise RAG.
37. Retrieval Representation vs Evidence¶
Knowledge
│
┌─────────┼─────────┐
▼ ▼ ▼
Summary Question Child Chunk
│ │ │
└─────────┼─────────┘
▼
Source Node
│
▼
LLM
The retrieval representation is optimized for finding the information.
The source node is optimized for trustworthy synthesis.
38. Recursive Retrieval with Tables¶
Some documents contain:
A table may be represented as a separate node.
For example:
A text node can reference a table node.
Recursive retrieval can follow:
when the table contains relevant information.
LlamaIndex has demonstrated recursive retrieval with embedded tables by parsing document elements, creating node relationships, and recursively retrieving through those relationships. :contentReference[oaicite:3]{index=3}
39. Table Retrieval Architecture¶
flowchart TD
A["Document"] --> B["Text Node"]
A --> C["Table Node"]
B --> D["Table Reference"]
D --> C
E["Query"] --> F["Vector Retriever"]
F --> B
B --> D
D --> C
C --> G["Structured Evidence"]
This can be useful for:
Financial Reports
Product Specifications
Architecture Tables
Configuration Matrices
Benchmark Results
40. Why Tables Need Special Handling¶
Suppose the query is:
The relevant information may exist in:
rather than:
Recursive references allow a text representation to point toward the table containing the actual evidence.
41. Recursive Retrieval with Heterogeneous Data¶
A knowledge base may contain:
Recursive relationships can connect these representations.
or:
This becomes especially useful in multimodal RAG.
42. Recursive Retriever + Document Agents¶
Recursive retrieval can also be combined with document agents.
The LlamaIndex documentation describes combining recursive retrieval with document agents for heterogeneous documents, allowing document-level summaries to guide retrieval and agents to perform tasks within selected documents. :contentReference[oaicite:4]{index=4}
Conceptually:
43. Document Agent Architecture¶
flowchart TD
A["User Query"] --> B["Document Retrieval"]
B --> C["Document Summary"]
C --> D["Selected Document"]
D --> E["Document Agent"]
E --> F["Vector Search"]
E --> G["Summary Tool"]
E --> H["Other Tools"]
F --> I["Evidence"]
G --> I
H --> I
I --> J["Response"]
Recursive retrieval provides the bridge between retrieval representations and document-level capabilities.
44. Recursive Retrieval + Agentic Retrieval¶
A more advanced architecture:
This can support dynamic retrieval workflows.
However, agentic behavior introduces additional:
and should be introduced only where deterministic retrieval is insufficient.
45. Recursive Retrieval vs Router Retrieval¶
These are different concepts.
Router Retriever¶
Chooses between:
LlamaIndex's RouterRetriever selects one or multiple candidate retrievers based on a selector and retriever metadata. :contentReference[oaicite:5]{index=5}
Recursive Retriever¶
Follows:
Therefore:
46. Router + Recursive Retrieval¶
They can also work together:
This creates a more capable retrieval architecture.
47. Recursive Retrieval vs Multi-Query¶
Multi-Query¶
Recursive Retrieval¶
They solve different problems.
They can be combined.
48. Recursive + Multi-Query¶
flowchart TD
A["Original Query"] --> B["Query Rewriter"]
B --> C["Query 1"]
B --> D["Query 2"]
B --> E["Query 3"]
C --> F["Retriever"]
D --> G["Retriever"]
E --> H["Retriever"]
F --> I["Recursive Expansion"]
G --> J["Recursive Expansion"]
H --> K["Recursive Expansion"]
I --> L["Fusion"]
J --> L
K --> L
This can improve recall, but complexity increases quickly.
49. Recursive + Re-ranking¶
A useful pipeline is:
Initial Retriever
↓
Top-20 Child Nodes
↓
Recursive Expansion
↓
Candidate Parents
↓
Re-ranking
↓
Top-5 Evidence
Re-ranking can remove parents that were expanded but are not actually useful for the query.
50. Recursive + MMR¶
Recursive expansion can produce duplicate context.
Example:
Without deduplication:
MMR or explicit node deduplication can solve this.
51. Deduplication¶
A simple strategy:
unique_nodes = {}
for result in results:
node_id = result.node.node_id
unique_nodes[node_id] = result
Then:
This is conceptual code; production systems should also define how scores are merged.
52. Recursive Retrieval and Context Explosion¶
Suppose:
each reference:
and each parent references:
Potential result count:
This can quickly exceed the desired context budget.
Therefore recursive expansion must be controlled.
53. Context Budget¶
Initial Retrieval
↓
Recursive Expansion
↓
Many Candidates
↓
Deduplicate
↓
Re-rank
↓
Context Budget
↓
LLM
Recursive retrieval should not mean:
54. Recursive Expansion Policies¶
Possible policies include:
Maximum Depth
Maximum Nodes
Reference Type Filter
Score Threshold
Per-Reference Limit
Total Token Budget
Example:
The values are illustrative.
55. Reference-Type Filtering¶
Suppose a node references:
You may want:
but not:
Therefore recursive retrieval can conceptually use:
to control traversal.
56. Recursive Traversal Policy¶
flowchart TD
A["Retrieved Node"] --> B["Reference Resolver"]
B --> C{"Reference Type"}
C -->|Parent| D["Follow"]
C -->|Table| E["Follow"]
C -->|Summary| F["Follow"]
C -->|External Document| G["Ignore"]
D --> H["Expanded Context"]
E --> H
F --> H
This prevents uncontrolled traversal.
57. Recursive Retrieval Quality¶
Recursive retrieval can improve:
Context Completeness
Parent Context
Evidence Recovery
Document Structure Awareness
Multi-Representation Retrieval
But it can reduce quality if:
Therefore relationship quality is as important as vector quality.
58. Relationship Quality¶
A recursive system depends on:
If:
then recursive retrieval produces incorrect context.
59. Reference Integrity¶
Treat node relationships similarly to database foreign keys.
Conceptually:
Validation should detect:
60. Reference Validation¶
This is a simple conceptual validation.
Production validation should also check:
61. Reference Versioning¶
Suppose:
then parent becomes:
The child reference must point to the correct version.
Otherwise:
can create inconsistent context.
62. Versioned Node Graph¶
The node graph should be rebuilt or updated consistently when document versions change.
63. Tenant Isolation in Recursive Retrieval¶
This is especially important.
Suppose:
but the parent belongs to:
Recursive traversal could accidentally cross tenant boundaries if relationships are not validated.
Therefore:
must be enforced together.
64. Secure Recursive Retrieval¶
flowchart TD
A["User"] --> B["Authentication"]
B --> C["Tenant Context"]
C --> D["Initial Retrieval"]
D --> E["Referenced Node"]
E --> F{"Same Tenant / Authorized?"}
F -->|Yes| G["Continue Traversal"]
F -->|No| H["Reject Reference"]
G --> I["Context"]
Do not assume that node references are automatically safe.
65. Recursive Retrieval and Provenance¶
Every expanded node should retain:
Example:
{
"node_id": "child-42",
"parent_id": "section-8",
"source": "payment-architecture.pdf",
"reference_path": [
"child-42",
"section-8"
]
}
This enables traceable citations.
66. Reference Path¶
A recursive result can have:
The provenance path becomes:
This is valuable for:
67. Recursive Retrieval Trace¶
flowchart LR
A["Query"] --> B["Child-42"]
B --> C["Parent-8"]
C --> D["Table-3"]
D --> E["Evidence"]
A -. trace .-> F["Retrieval Path"]
The retrieval path can be stored as trace metadata.
68. Recursive Retrieval Observability¶
Track:
Initial Retriever
Initial Result Count
Recursive Depth
References Followed
Nodes Expanded
Duplicate Nodes
Cycles Detected
Final Result Count
Latency
Example:
{
"retriever": "recursive",
"initial_results": 5,
"max_depth": 2,
"references_followed": 11,
"nodes_expanded": 18,
"duplicates_removed": 4,
"latency_ms": 74
}
69. Recursive Retrieval Performance¶
Latency can come from:
Initial Search
+
Reference Resolution
+
Additional Retrieval
+
Node Loading
+
Deduplication
+
Re-ranking
If references require remote calls:
can become significant.
70. Parallel Recursive Expansion¶
If multiple references are independent:
the system can potentially resolve them concurrently.
Conceptually:
This can reduce wall-clock latency.
71. Recursive Retrieval Cost¶
Potential costs include:
Initial Embedding
Vector Search
Node Fetches
LLM Summary Generation
Additional Retrieval
Re-ranking
LLM Context Tokens
Therefore:
Every additional node has operational cost.
72. Recursive Retrieval Evaluation¶
Evaluate:
Compare:
against:
73. Evaluation Example¶
| Metric | Vector Only | Recursive |
|---|---|---|
| Recall@10 | 0.78 | 0.91 |
| Context Precision | 0.82 | 0.76 |
| Answer Quality | 0.80 | 0.88 |
| P95 Latency | 90 ms | 140 ms |
| Context Tokens | 3,000 | 5,200 |
Values are illustrative.
The goal is not to maximize one metric.
74. Recursive Retrieval Quality Trade-Off¶
More Expansion
↓
Higher Context Recall
↓
Potentially More Noise
↓
Higher Token Cost
↓
Higher Latency
Therefore recursive depth and expansion limits should be tuned.
75. Small-to-Big Evaluation¶
Compare:
against:
Measure:
This demonstrates whether parent expansion actually improves the application.
76. Recursive Retrieval for Long Documents¶
Long documents often benefit from:
because:
This creates a useful division of responsibilities.
77. Recursive Retrieval for PDFs¶
A PDF may be represented as:
Recursive references can connect:
or:
This preserves document structure.
78. Recursive Retrieval for Documentation¶
Technical documentation can be represented as:
A query may retrieve:
and recursively expand to:
for context.
79. Recursive Retrieval for Code¶
Code knowledge can be represented as:
A query:
may retrieve:
then recursively resolve:
This provides structural context.
80. Recursive Retrieval for Enterprise Knowledge¶
A knowledge graph-like structure could be:
Payment Service
│
├── Architecture Document
│
├── API Specification
│
├── Runbook
│
├── Incident
│
└── Database Schema
A retrieved node can lead to related enterprise knowledge.
81. Recursive Retrieval + Knowledge Graphs¶
Recursive node references can resemble a lightweight knowledge graph:
However:
is not automatically equivalent to:
A dedicated knowledge graph provides richer entity/relationship semantics.
82. Recursive Retrieval + Graph RAG¶
A production architecture can combine them:
This can support complex relational questions.
83. Recursive Retrieval + SQL¶
A retrieved node could reference:
or:
The system can then transition from:
to:
Example:
This is an advanced enterprise pattern.
84. Recursive Retrieval as a Retrieval Bridge¶
One of the strongest architectural uses is to bridge different retrieval mechanisms:
Vector
↓
Recursive Reference
↓
BM25
or:
Vector
↓
Recursive Reference
↓
SQL
or:
Summary
↓
Recursive Reference
↓
Source Node
Therefore recursive retrieval can become a retrieval orchestration mechanism.
85. Multi-Stage Retrieval Architecture¶
flowchart TD
A["Query"] --> B["Initial Retriever"]
B --> C["Candidate Node"]
C --> D["Recursive Resolver"]
D --> E["Related Nodes"]
E --> F["Secondary Retriever"]
F --> G["Candidates"]
G --> H["Re-ranking"]
H --> I["Context"]
This is more powerful than simple parent expansion.
86. Recursive Retriever + Router¶
A router can decide:
Recursive retrieval can decide:
Combined:
This creates two levels of retrieval orchestration.
87. Recursive Retriever + Query Fusion¶
Another architecture:
This can increase recall substantially, but should be used only when the additional complexity is justified.
88. Production Recursive Retrieval Pipeline¶
A mature pipeline might look like:
User Query
↓
Authentication
↓
Authorization
↓
Query Processing
↓
Initial Retrieval
↓
Candidate Nodes
↓
Reference Resolution
↓
Recursive Expansion
↓
Tenant / Security Validation
↓
Deduplication
↓
Re-ranking
↓
Context Compression
↓
Context Selection
↓
Prompt Assembly
↓
LLM
↓
Response Validation
↓
Citation
Recursive retrieval is therefore one stage inside a larger RAG system.
89. Production Configuration¶
A conceptual configuration might look like:
retrieval:
strategy: recursive
initial:
strategy: vector
top_k: 10
recursive:
max_depth: 2
max_nodes: 30
allowed_reference_types:
- parent
- source
- table
reranking:
enabled: true
top_k: 8
context:
max_tokens: 6000
security:
tenant_isolation: true
These values are illustrative.
They should be calibrated through evaluation.
90. Framework-Agnostic Abstraction¶
A production application can expose:
LlamaIndex can be an adapter:
class LlamaIndexRecursiveRetriever(
RecursiveRetriever
):
def __init__(self, retriever):
self.retriever = retriever
def retrieve(self, query):
return self.retriever.retrieve(query)
The application should not depend directly on LlamaIndex internals.
91. Capability-Based Retrieval Architecture¶
flowchart LR
A["Enterprise RAG"] --> B["Recursive Retrieval Port"]
B --> C["LlamaIndex Adapter"]
B --> D["Custom Graph Adapter"]
B --> E["Other Framework Adapter"]
C --> F["RecursiveRetriever"]
This follows a Ports & Adapters architecture.
92. Retriever Factory¶
A retrieval factory can expose:
class RetrieverType:
VECTOR = "vector"
BM25 = "bm25"
DOCUMENT_SUMMARY = "document_summary"
RECURSIVE = "recursive"
HYBRID = "hybrid"
Then:
def create_retriever(
retriever_type,
config
):
if retriever_type == "recursive":
return RecursiveRetrieverAdapter(config)
...
This keeps retrieval strategy selection centralized.
93. Indexing Pipeline for Recursive Retrieval¶
flowchart LR
A["Documents"] --> B["Parse"]
B --> C["Parent Nodes"]
C --> D["Child Nodes"]
D --> E["Create References"]
E --> F["Generate Embeddings"]
F --> G["Vector Index"]
E --> H["Node Mapping"]
G --> I["Recursive Retriever"]
H --> I
The important difference from normal vector indexing is:
must also be constructed and maintained.
94. Reference-Aware Ingestion¶
The ingestion pipeline should create:
Example:
{
"node_id": "child-17",
"parent_id": "section-4",
"reference_type": "parent",
"document_id": "payment-001"
}
This becomes the foundation for recursive traversal.
95. Reference Graph Validation¶
Before publishing an index:
☐ All node IDs unique
☐ All references resolvable
☐ No unintended cycles
☐ Parent-child relationships valid
☐ Tenant boundaries valid
☐ Version relationships valid
☐ Source metadata preserved
This should be part of the index quality gate.
96. Index Versioning¶
Recursive retrieval requires versioning not only the vectors but also the relationships.
Track:
Index Version
Node Version
Embedding Version
Chunking Version
Reference Graph Version
Summary Version
A vector index can be correct while the reference graph is stale.
97. Reference Graph Freshness¶
Example:
but reference graph still contains:
This can produce incorrect context.
Therefore:
should be updated atomically or through a controlled publication process.
98. Blue-Green Recursive Index¶
Validate:
before switching production traffic.
99. Retrieval Failure Modes¶
Failure 1¶
Correct child retrieved, parent missing.
Possible cause:
Failure 2¶
Correct parent retrieved, unrelated children included.
Possible cause:
Failure 3¶
Retrieval loops.
Possible cause:
Failure 4¶
Wrong tenant data returned.
Possible cause:
100. Debugging Recursive Retrieval¶
Inspect the complete path:
For each step capture:
This makes recursive retrieval much easier to debug.
101. Retrieval Trace Example¶
{
"query": "How are OAuth tokens validated?",
"steps": [
{
"node": "child-42",
"depth": 0,
"score": 0.91
},
{
"node": "section-8",
"depth": 1,
"reference": "parent"
}
]
}
This provides a clear retrieval explanation.
102. Recursive Retrieval Observability Dashboard¶
Recursive Retrieval
────────────────────────────
Initial Recall 91%
Expansion Rate 2.4
Average Depth 1.3
Max Depth 2
Duplicate Rate 8%
Cycle Rate 0.01%
P95 Latency 145 ms
Context Tokens 4,200
These metrics are illustrative.
103. Cost Optimization¶
Reduce recursive cost through:
Depth Limits
Reference Filtering
Top-K Limits
Node Deduplication
Caching
Parallel Resolution
Early Stopping
Re-ranking
Do not expand every reference automatically.
104. Early Stopping¶
Suppose the system already has:
and the context budget is nearly full.
Additional recursive expansion may not be useful.
Conceptually:
This is especially useful in agentic retrieval.
105. Caching References¶
If many queries repeatedly resolve:
the mapping can be cached.
Cache invalidation must account for:
106. Recursive Retrieval and Context Compression¶
Recursive expansion can produce large parent nodes.
A compression stage can follow:
This provides:
107. Small-to-Big + Compression¶
flowchart TD
A["Query"] --> B["Child Vector Search"]
B --> C["Child Nodes"]
C --> D["Parent Expansion"]
D --> E["Large Parent Context"]
E --> F["Contextual Compression"]
F --> G["Focused Evidence"]
G --> H["LLM"]
This is a strong enterprise pattern.
108. Recursive Retrieval and Citations¶
When a child retrieves a parent, preserve:
The final citation should point to the authoritative source location.
Do not cite a generated summary when the answer was derived from the original source.
109. Recursive Retrieval and Response Validation¶
A response validation layer can verify:
This becomes particularly important when recursive expansion retrieves context from multiple related nodes.
110. Recursive Retrieval and Enterprise Response¶
The final enterprise response can contain:
Example:
OAuth tokens are validated by the authorization
service before the payment request is processed.
Source:
Payment Architecture
Section: Authentication
Page: 18
The exact response format belongs to the application layer.
111. Common Anti-Patterns¶
Anti-Pattern 1 — Recursive Everything¶
This causes:
112. Common Anti-Patterns — Continued¶
Anti-Pattern 2 — No Reference Validation¶
Broken references can produce:
Anti-Pattern 3 — No Cycle Protection¶
A graph can contain cycles.
Always protect recursive traversal.
113. Common Anti-Patterns — Continued¶
Anti-Pattern 4 — Returning Only the Parent¶
Parent expansion can restore context, but the exact child passage may still be important.
A better strategy may preserve:
depending on the response and context strategy.
Anti-Pattern 5 — Ignoring Tenant Boundaries¶
References must not bypass authorization.
114. Common Anti-Patterns — Continued¶
Anti-Pattern 6 — Treating Recursive Retrieval as Generation¶
Recursive retrieval finds and expands evidence.
It does not replace:
Anti-Pattern 7 — No Evaluation¶
Always compare:
using a representative evaluation set.
115. Production Checklist¶
☐ Define node hierarchy
☐ Define reference types
☐ Define canonical source nodes
☐ Define initial retriever
☐ Build node mappings
☐ Validate references
☐ Detect cycles
☐ Define maximum depth
☐ Define maximum expanded nodes
☐ Define reference-type filters
☐ Implement deduplication
☐ Preserve provenance
☐ Enforce tenant isolation
☐ Version the reference graph
☐ Measure initial Recall@K
☐ Measure recursive Recall@K
☐ Measure context precision
☐ Measure latency
☐ Measure token usage
☐ Add retrieval tracing
☐ Add failure handling
☐ Implement caching where useful
☐ Add re-ranking
☐ Add context compression
☐ Test deletion/update behavior
☐ Test rollback
116. Key Takeaways¶
- Recursive retrieval follows relationships between retrieved nodes.
- It extends normal retrieval from a flat result list into a connected node graph.
- LlamaIndex provides
RecursiveRetrieverfor this pattern. :contentReference[oaicite:6]{index=6} - Node references are the foundation of recursive retrieval.
retriever_dictand node mappings are central concepts in LlamaIndex's recursive retrieval architecture. :contentReference[oaicite:7]{index=7}- Small-to-big retrieval is one of the most important recursive retrieval patterns.
- Small child chunks provide precise retrieval signals.
- Parent nodes provide broader context for synthesis.
- Recursive retrieval can decouple retrieval representation from generation evidence.
- Summaries can point to source nodes.
- Generated questions can point to source nodes.
- Tables can be represented as separate nodes and reached through references.
- Recursive retrieval can work with heterogeneous document representations.
- Recursive retrieval can be combined with document agents for more advanced document-level reasoning. :contentReference[oaicite:8]{index=8}
- Recursive retrieval is different from router retrieval.
- Router retrieval chooses among retrievers; recursive retrieval follows node relationships. :contentReference[oaicite:9]{index=9}
- Recursive retrieval is different from multi-query retrieval.
- Recursive retrieval can be combined with vector, BM25, hybrid, multi-query, MMR, and re-ranking strategies.
- Recursive traversal should have explicit depth and expansion limits.
- Cycle detection is essential for graph-like node structures.
- Reference integrity is as important as vector index quality.
- Node references must respect tenant and authorization boundaries.
- Recursive retrieval can introduce significant context expansion.
- Deduplication is important when multiple nodes reference the same parent.
- Re-ranking and contextual compression can control recursive expansion.
- Retrieval traces should record node IDs, depth, reference paths, and expansion behavior.
- Recursive indexes require versioning of both vectors and node relationships.
- Document changes must update the reference graph consistently.
- Recursive retrieval should be evaluated independently from generation.
- Stage-one retrieval recall remains important because recursive expansion cannot recover a completely missed candidate.
- Recursive retrieval is best understood as a retrieval graph traversal capability, not merely a parent-child lookup.
The central architecture is:
USER QUERY
│
▼
Initial Retriever
│
▼
Candidate Node
│
▼
Reference Resolution
│
┌─────────┼─────────┐
▼ ▼ ▼
Parent Summary Table
│ │ │
└─────────┼─────────┘
▼
Expanded Evidence
│
▼
Deduplication
│
▼
Re-ranking
│
▼
Context Selection
│
▼
LLM
│
▼
Validated Response
│
▼
Citations
Recursive retrieval separates the question of “what should be retrieved?” from “what context should ultimately be given to the LLM?” — enabling precise retrieval representations to resolve into richer, authoritative source context.
🧭 Chapter Navigation¶
Part V — Advanced Retrieval-Augmented Generation¶
Previous:
05. Document Summary Retriever
Next:
07. Query Fusion Retriever
Section:
03 — LlamaIndex Retrieval Engineering
LlamaIndex Retrieval Engineering Path¶
01 LlamaIndex Retrievers Overview
↓
02 LlamaIndex Indexes
↓
03 Vector Index Retriever
↓
04 BM25 Retriever
↓
05 Document Summary Retriever
↓
06 Recursive Retriever
↓
07 Query Fusion Retriever
↓
08 Auto-Merging Retriever
↓
04 Vector Search Engineering
Enterprise AI Engineering Handbook
Building Production-Grade Enterprise AI Systems — One Chapter at a Time.