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 query
  • RAGAnything.query() — synchronous wrapper
  • RAGAnything.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:

  1. Vector similarity phase — Retrieves top_k nearest neighbors using the configured embedding function
  2. Graph traversal phase — Expands each retrieved chunk by following edges in the document graph, pulling in related_chunk_number adjacent chunks with their own chunk_top_k vector limits
  3. 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_number for highly structured documents where context flows across sections (contracts, research papers)
  • Reduce top_k and increase chunk_top_k when 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" to RAGAnything.aquery() or aquery_with_multimodal().
  • Tune the balance between vector and graph contributions through RAGAnythingConfig parameters: top_k, related_chunk_number, and chunk_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.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →