Skip to content
reaatechREAATECH

@reaatech/hybrid-rag-retrieval

npm v0.1.0

Orchestrates hybrid RAG pipelines by combining Qdrant-based vector search, in-process BM25 keyword search, and cross-encoder reranking. It provides a `HybridRetriever` class that manages score normalization and fusion strategies like RRF or weighted sum to return a unified list of search results.

@reaatech/hybrid-rag-retrieval

npm version License: MIT CI

Status: Pre-1.0 — APIs may change in minor versions. Pin to a specific version in production.

Hybrid retrieval engine combining vector search (via Qdrant), BM25 keyword search, cross-encoder reranking, and configurable score fusion strategies. The core retrieval stack for hybrid RAG systems.

Installation

terminal
npm install @reaatech/hybrid-rag-retrieval
# or
pnpm add @reaatech/hybrid-rag-retrieval

Feature Overview

  • Vector search — semantic search via Qdrant with configurable distance metrics and metadata filtering
  • BM25 keyword search — Okapi BM25 ranking with configurable k1/b parameters, stopword removal, stemming, n-gram tokenization
  • Three fusion strategies — Reciprocal Rank Fusion (RRF), Weighted Sum, Normalized Score fusion
  • Score normalization — Min-Max, Z-Score, and Rank normalization
  • Cross-encoder reranking — Cohere, Jina, OpenAI, and local provider support
  • Hybrid retriever — single interface orchestrating vector search, BM25 search, fusion, and optional reranking

Quick Start

typescript
import {
  HybridRetriever,
  VectorSearchEngine,
  BM25SearchEngine,
  RerankerEngine,
} from '@reaatech/hybrid-rag-retrieval';
 
const retriever = new HybridRetriever({
  vector: {
    qdrant: {
      url: process.env.QDRANT_URL,
      collectionName: 'documents',
    },
    embedding: {
      provider: 'openai',
      model: 'text-embedding-3-small',
      apiKey: process.env.OPENAI_API_KEY,
    },
    topK: 20,
  },
  bm25: {
    k1: 1.2,
    b: 0.75,
    topK: 20,
  },
  fusion: {
    strategy: 'rrf',
  },
  topK: 10,
});
 
await retriever.initialize();
 
// Ingest chunks
await retriever.indexChunks(chunks);
 
// Retrieve
const results = await retriever.retrieve('How do I configure SSO?', {
  topK: 10,
  retrievalMode: 'hybrid', // 'hybrid' | 'vector' | 'bm25'
});

API Reference

VectorSearchEngine

Orchestrates Qdrant + embedding into a single search interface.

typescript
const engine = new VectorSearchEngine({
  qdrant: { url: '...', collectionName: 'docs' },
  embedding: { provider: 'openai', model: 'text-embedding-3-small' },
  topK: 10,
  distance: 'Cosine',
});
 
await engine.initialize();
await engine.indexChunks(chunks);
const results = await engine.search('query text', { topK: 10 });
MethodDescription
initialize()Connect to Qdrant and ensure collection exists
indexChunks(chunks)Generate embeddings and upsert to Qdrant
search(query, options?)Embed query and search Qdrant
searchByVector(vector, options?)Search with a pre-computed embedding
healthCheck()Verify Qdrant connectivity

BM25SearchEngine

In-process BM25 search with configurable parameters.

typescript
const engine = new BM25SearchEngine({
  k1: 1.2,
  b: 0.75,
  topK: 10,
});
 
await engine.indexChunks(chunks);
const results = engine.search('query text', { topK: 10 });
MethodDescription
indexChunks(chunks)Tokenize and index all chunks
search(query, options?)Tokenize query and rank by BM25 score

BM25Engine

Low-level BM25 implementation with tokenization control.

Constructor ParamTypeDefaultDescription
k1number1.2Term frequency saturation parameter
bnumber0.75Length normalization parameter

Tokenizer

Configurable text tokenizer supporting stopword removal, stemming, and n-grams.

OptionTypeDefaultDescription
removeStopWordsbooleantrueFilter common English stop words
applyStemmingbooleantrueApply Porter stemmer
minTokenLengthnumber2Minimum token length
ngramRange[number, number][1, 1]N-gram range for tokenization

Reranking

RerankerEngine

Cross-encoder reranking supporting multiple providers.

typescript
const reranker = new RerankerEngine({
  provider: 'cohere',
  model: 'rerank-english-v3.0',
  apiKey: process.env.COHERE_API_KEY,
});
 
const reranked = await reranker.rerankResults('query text', retrievalResults);

RerankerConfig

PropertyTypeDescription
providercohere' | 'jina' | 'openai' | 'localReranker provider
modelstringProvider-specific model name
apiKeystringAPI key for cloud providers
MethodDescription
rerankResults(query, results)Rerank retrieval results using cross-encoder scoring

Fusion Strategies

Strategy Types

StrategyTypeFormulaWhen to Use
RRFrrfΣ 1/(k + rank_i)No tuning required, robust
Weighted Sumweighted-sumw1*score + w2*scoreWhen scores are on similar scales
Normalizednormalizedw1*norm(score) + w2*norm(score)Different score distributions

FusionConfig

PropertyTypeDefaultDescription
strategyFusionStrategyTyperrfFusion algorithm
vectorWeightnumber0.7Weight for vector scores in weighted/normalized mode
bm25Weightnumber0.3Weight for BM25 scores in weighted/normalized mode
knumber60RRF constant

Functions

FunctionDescription
applyFusion(vectorResults, bm25Results, config)Fuse two result sets
reciprocalRankFusion(v, b, k?)RRF-specific helper
weightedSumFusion(v, b, w1, w2)Weighted sum helper
normalizedFusion(v, b, w1, w2)Normalized fusion helper

Normalization

FunctionDescription
minMaxNormalize(results)Scale scores to [0, 1] range
zScoreNormalize(results)Center around 0 with unit variance
rankNormalize(results)Convert to rank-based scores
normalize(results, method)Apply the specified normalization

Hybrid Retriever

HybridRetriever

The high-level orchestrator. Coordinates vector search, BM25 search, fusion, and optional reranking.

typescript
const retriever = new HybridRetriever(config);
await retriever.initialize();
await retriever.indexChunks(chunks);
 
const results = await retriever.retrieve('query', {
  topK: 10,
  vectorWeight: 0.7,
  bm25Weight: 0.3,
  filter: { department: 'engineering' },
  retrievalMode: 'hybrid',
});

HybridRetrievalOptions

PropertyTypeDefaultDescription
topKnumber10Number of results to return
vectorWeightnumber0.7Vector weight in fusion
bm25Weightnumber0.3BM25 weight in fusion
filterRecord<string, unknown>Metadata filter for vector search
retrievalModehybrid' | 'vector' | 'bm25hybridSearch mode

License

MIT