How to Configure Hybrid Search Combining Vector Embeddings with Tantivy Full-Text Search

To configure hybrid search combining vector embeddings with Tantivy full-text search, instantiate a HybridIndexFactory in your Pathway YAML configuration that orchestrates USearchKnnFactory for dense vector retrieval and TantivyBM25Factory for BM25 keyword matching, then assign this factory to your DocumentStore's retriever_factory parameter.

The pathwaycom/llm-app template provides a declarative way to configure hybrid search combining vector embeddings with Tantivy full-text search without writing custom Python code. By leveraging Pathway's indexing factories, you can simultaneously query dense embeddings for semantic similarity and BM25 indexes for precise keyword matching within the same retrieval pipeline.

Understanding the Hybrid Search Architecture

The hybrid retrieval system in Pathway operates through two independent index factories that work in parallel. When a query arrives, the system automatically routes the query text through both an embedding model for vector search and the Tantivy engine for BM25 scoring, then merges the results.

Vector Index Component: The USearchKnnFactory (built on the ultra-fast usearch library) stores dense embeddings and handles approximate nearest neighbor search using metrics like cosine similarity.

Full-Text Index Component: The TantivyBM25Factory wraps the Tantivy search engine to provide traditional inverted-index BM25 keyword matching.

Hybrid Orchestration: The HybridIndexFactory coordinates these sub-retrievers, sending queries to both indexes and merging result sets based on configurable scoring or weighting strategies before passing documents downstream to your RAG components.

Step-by-Step YAML Configuration

Pathway's LLM templates use YAML declarations to build the retrieval pipeline. To configure hybrid search combining vector embeddings with Tantivy full-text search, modify your templates/question_answering_rag/app.yaml file as follows.

Configure the Vector Index (USearchKnnFactory)

First, define the vector index that will store embeddings for semantic search:

$knn_index: !pw.indexing.USearchKnnFactory
  reserved_space: 1000
  embedder: $embedder
  metric: !pw.indexing.USearchKnnMetricKind.COS
  dimensions: 1536

The reserved_space parameter pre-allocates capacity for vectors, while dimensions must match your embedding model's output size (1536 for OpenAI's text-embedding-ada-002, for example).

Configure the Full-Text Index (TantivyBM25Factory)

Next, instantiate the BM25 index for keyword search:

$bm25_index: !pw.indexing.TantivyBM25Factory

This factory automatically handles tokenization and inverted index construction using the Tantivy Rust engine; no additional parameters are required for basic functionality.

Combine with HybridIndexFactory

Merge both retrievers using the HybridIndexFactory, which queries sub-indexes in parallel:

$hybrid_index_factory: !pw.indexing.HybridIndexFactory
  retriever_factories:
    - $knn_index
    - $bm25_index

Update the Document Store

Finally, assign the hybrid factory to your document store's retriever_factory:

$document_store: !pw.xpacks.llm.document_store.DocumentStore
  docs: $sources
  parser: $parser
  splitter: $splitter
  retriever_factory: $hybrid_index_factory

Running the Application

With the YAML configuration in place, the application requires no code changes. Execute the pipeline from the template directory:

cd templates/question_answering_rag
pip install -r requirements.txt
python app.py

The app.py file loads the configuration via pw.load_yaml and automatically provisions the underlying Rust engines (usearch and Tantivy). The REST API will now return results that blend semantic similarity with keyword relevance when you query endpoints like POST /v1/retrieve.

Advanced Configuration: Tuning Retrieval Weights

For finer control over result ranking, adjust the influence of each sub-retriever using weight_factors:

$hybrid_index_factory: !pw.indexing.HybridIndexFactory
  retriever_factories:
    - $knn_index
    - $bm25_index
  weight_factors: [0.7, 0.3]

This configuration assigns 70% weight to semantic (vector) matches and 30% to BM25 keyword matches. Refer to the Pathway API documentation for additional options such as k values for top-k retrieval from each index.

Key Source Files

Summary

  • Pathway enables hybrid search combining vector embeddings with Tantivy full-text search through declarative YAML configurations using HybridIndexFactory.
  • The architecture combines USearchKnnFactory (dense vector search via usearch) and TantivyBM25Factory (BM25 keyword search via Tantivy).
  • Configuration requires only updating templates/question_answering_rag/app.yaml to define both indexes and assign the hybrid factory to the DocumentStore.
  • No Python code changes are necessary; the application automatically provisions Rust-based indexing engines when loading the configuration.
  • Optional weight_factors parameter allows fine-tuning the balance between semantic and keyword relevance.

Frequently Asked Questions

Do I need to install separate dependencies for Tantivy and usearch?

No. The requirements.txt in templates/question_answering_rag already includes Pathway with its indexing extensions. When you run pip install -r requirements.txt, both the usearch and Tantivy Rust engines are installed automatically. Pathway provisions these engines transparently when you reference USearchKnnFactory or TantivyBM25Factory in your YAML configuration.

How does the hybrid index handle query routing?

The HybridIndexFactory automatically duplicates incoming queries: it sends the raw text to the TantivyBM25Factory for keyword matching and embeds the text (using your configured embedder) for the USearchKnnFactory. It then merges the two result sets according to your configuration before returning the final ranked documents to the RAG pipeline.

Can I use different embedding dimensions or metrics?

Yes. The USearchKnnFactory accepts any dimension size that matches your embedding model—common values include 384, 768, or 1536. You can also change the metric parameter to !pw.indexing.USearchKnnMetricKind.IP for inner product or L2 for Euclidean distance, depending on your specific embedding model's requirements.

What happens if Tantivy or usearch indexes are empty?

If either sub-index contains no documents, the HybridIndexFactory gracefully handles the empty result set by relying solely on the populated index. The hybrid retriever merges available results, so your application continues functioning even if one indexing backend has no matches for a particular query.

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 →