How to Use Hybrid Retrieval Mode in RAGAnything: Combining Vector Similarity and Graph Traversal
Use mode="hybrid" in RAGAnything.aquery() or aquery_with_multimodal() to activate hybrid retrieval, which merges dense vector similarity search with graph-based chunk expansion through LightRAG.
RAGAnything provides multiple retrieval strategies through its integration with LightRAG, and the hybrid retrieval mode stands out for combining the semantic precision of vector embeddings with the structural context of document graphs. This article explains how hybrid retrieval works internally, how to configure it, and how to use it in both text-only and multimodal scenarios.
Understanding RAGAnything Retrieval Modes
RAGAnything delegates all retrieval operations to LightRAG, exposing them through a unified mode parameter. The available modes offer different trade-offs between speed, coverage, and context richness:
| Mode | Behavior |
|---|---|
local |
Pure vector similarity on the local LightRAG store |
global |
Vector similarity on a remote vector database |
mix |
Runs both local and global vector searches, merging results |
hybrid |
Combines vector similarity with graph traversal — the focus of this guide |
naive, bypass |
Specialized fallback behaviors |
The hybrid retrieval mode is unique because it performs two distinct operations: first, a standard vector similarity search to find semantically relevant chunks; second, a graph traversal that expands the context by following relationships between chunks in the document structure.
How Hybrid Retrieval Works Internally
Hybrid retrieval in RAGAnything follows a clear pipeline defined in the source code. Understanding this flow helps you optimize configuration and debug issues.
Entry Point: Query Methods
The public API exposes hybrid retrieval through two methods in raganything/raganything.py:
RAGAnything.aquery()— asynchronous text queryRAGAnything.query()— synchronous wrapperRAGAnything.aquery_with_multimodal()— hybrid retrieval with multimodal enrichment
All methods forward to QueryMixin in raganything/query.py (lines 102-110), which handles the mode parameter and builds a QueryParam object for LightRAG (lines 209-214).
LightRAG Processing Pipeline
When mode="hybrid" reaches LightRAG, the pipeline executes:
- Vector similarity phase — Retrieves
top_knearest neighbors using the configured embedding function - Graph traversal phase — Expands each retrieved chunk by following edges in the document graph, pulling in
related_chunk_numberadjacent chunks with their ownchunk_top_kvector limits - Merge and deduplicate — Combines both result streams, removing duplicates while preserving structural relevance
This dual-phase approach ensures you capture both semantic similarity and document structure — critical for queries that depend on context spanning multiple sections or pages.
Configuring Hybrid Retrieval Parameters
All hybrid retrieval tuning happens through RAGAnythingConfig in raganything/config.py (lines 45-63). The relevant fields are:
| Parameter | Default | Purpose |
|---|---|---|
top_k |
10 | Primary vector similarity limit |
related_chunk_number |
3 | Graph expansion depth — how many adjacent chunks to traverse |
chunk_top_k |
5 | Secondary vector limit for graph-expanded chunks |
Adjust these based on your documents:
- Increase
related_chunk_numberfor highly structured documents where context flows across sections (contracts, research papers) - Reduce
top_kand increasechunk_top_kwhen you want fewer initial matches but deeper exploration of each match's neighborhood
Code Examples: Using Hybrid Retrieval Mode
Basic Hybrid Text Query
from raganything import RAGAnything, RAGAnythingConfig
# Configure hybrid retrieval parameters
config = RAGAnythingConfig(
top_k=10, # vector similarity limit
related_chunk_number=3, # graph traversal depth
)
rag = RAGAnything(
config=config,
llm_model_func=my_llm,
embedding_func=my_embed
)
# Index documents (builds vector store and graph)
await rag.process_document_complete("reports/annual_report.pdf")
# Execute hybrid retrieval query
answer = await rag.aquery(
"What were the main revenue drivers in Q3?",
mode="hybrid", # activates vector + graph retrieval
)
print(answer)
This example follows the pattern shown in examples/raganything_example.py (lines 224-226), where mode="hybrid" triggers the dual-phase retrieval pipeline.
Hybrid Retrieval with Multimodal Content
# Prepare multimodal content to enrich the final answer
multimodal_items = [
{
"type": "image",
"img_path": "figures/architecture.png",
"image_caption": "System architecture diagram"
},
{
"type": "table",
"table_data": "Metric,Value\nLatency,120ms\nThroughput,3.2k req/s",
"table_caption": "Performance benchmarks"
}
]
# Hybrid retrieval still applies to text context
answer = await rag.aquery_with_multimodal(
"Compare the architecture diagram with the performance numbers.",
multimodal_content=multimodal_items,
mode="hybrid", # vector similarity + graph traversal for text context
)
print(answer)
The multimodal example in examples/raganything_example.py (lines 300-322) demonstrates this combined approach. The hybrid retrieval operates on the text corpus; the multimodal processor in raganything/modalprocessors.py then enriches the response with vision-LLM processed images and tables.
Fine-Tuning Hybrid Parameters
# Deeper graph exploration for highly structured documents
config = RAGAnythingConfig(
top_k=15,
related_chunk_number=5, # more graph neighbors
chunk_top_k=8, # richer context per neighbor
)
rag = RAGAnything(config=config, llm_model_func=my_llm, embedding_func=my_embed)
# Process documents...
answer = await rag.aquery(
"Explain the relationship between section 4 and the appendix.",
mode="hybrid",
)
These configuration fields are defined in raganything/config.py (lines 45-63), with inline comments noting their specific role in hybrid mode operation.
Key Files for Hybrid Retrieval
| File | Purpose | Key Lines |
|---|---|---|
raganything/query.py |
QueryMixin implementation, mode parameter handling, QueryParam construction |
102-110, 209-214 |
raganything/raganything.py |
RAGAnything class, public aquery/aquery_with_multimodal methods |
orchestration layer |
raganything/config.py |
RAGAnythingConfig, hybrid-specific parameters (top_k, related_chunk_number, chunk_top_k) |
45-63 |
examples/raganything_example.py |
Working examples of hybrid and multimodal hybrid queries | 224-226, 300-322 |
raganything/modalprocessors.py |
Multimodal enrichment layer that receives hybrid-retrieved context | processing pipeline |
Summary
- Hybrid retrieval mode combines vector similarity search with graph-based chunk traversal to deliver context that is both semantically relevant and structurally grounded.
- Activate it by passing
mode="hybrid"toRAGAnything.aquery()oraquery_with_multimodal(). - Tune the balance between vector and graph contributions through
RAGAnythingConfigparameters:top_k,related_chunk_number, andchunk_top_k. - The pipeline is delegated to LightRAG, with RAGAnything providing configuration, multimodal enrichment, and a simplified API surface.
Frequently Asked Questions
What is the difference between mode="mix" and mode="hybrid" in RAGAnything?
mode="mix" runs local and global vector searches separately and merges their results — it is purely vector-based. mode="hybrid" first performs vector similarity, then traverses the document graph to expand context with related chunks. Use hybrid when you need structural relationships between document sections, not just semantic similarity.
How do I configure the graph traversal depth in hybrid mode?
Set the related_chunk_number parameter in RAGAnythingConfig. This controls how many graph-adjacent chunks are pulled in for each vector match. Increase it for highly interlinked documents (research papers, legal contracts); decrease it for linear documents where excessive traversal dilutes relevance.
Can I use hybrid retrieval with images and tables?
Yes. Call aquery_with_multimodal() with mode="hybrid". The method performs standard hybrid retrieval on your text corpus, then enriches the LLM prompt with base64-encoded images, table data, or equations. The graph traversal operates on the underlying text chunks; multimodal content is added downstream in raganything/modalprocessors.py.
Does hybrid mode slow down queries compared to pure vector search?
Hybrid mode adds graph traversal overhead proportional to related_chunk_number and chunk_top_k. Each vector match triggers additional chunk lookups and secondary vector searches. For latency-sensitive applications, reduce related_chunk_number to 1-2, or fall back to mode="local" for pure vector retrieval.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →