Tags: rag, vector-search, embeddings, reranking, hybrid-search, llm
Level: intermediate
TL;DR: Architecture patterns for Retrieval-Augmented Generation, from baseline naive retrieval to advanced hybrid routing and reranking pipelines.
-
Naive RAG uses direct semantic search over chunked documents without post-processing.
-
Advanced RAG adds pre-retrieval query rewriting and post-retrieval reranking stages.
-
Modular RAG decouples indexing, retrieval, routing, synthesis, and evaluation components.
-
Chunking strategies include fixed-size sliding window, semantic boundary, and recursive splitting.
-
Hybrid search merges dense vector similarity with sparse lexical matching via BM25.
-
Reciprocal Rank Fusion combines ranked lists from distinct sparse and dense retrievers.
-
Cross-encoder rerankers rescore candidate chunks by scoring query-document pairs jointly.
-
Contextual compression trims irrelevant sentences before assembling the final prompt payload.
-
Hypothetical Document Embeddings generate synthetic candidate passages to improve dense retrieval.
-
Multi-query expansion decomposes ambiguous questions into parallel domain-specific search vectors.
-
Q: What is the difference between dense retrieval and sparse retrieval in RAG?R: Dense retrieval maps text to semantic embedding spaces capturing conceptual similarity, while sparse retrieval uses exact keyword frequencies via algorithms like BM25; combining both via hybrid search mitigates vocabulary mismatch while preserving context.
-
Q: Why do we use cross-encoders for reranking instead of using them for initial search?R: Cross-encoders process the query and passage together through all attention layers, which is highly accurate but computationally intractable across millions of records; we use bi-encoders to fetch top-k fast, then cross-encoders to rerank only those candidates.
-
Q: How do you handle multi-hop reasoning in complex RAG workflows?R: I use iterative or agentic retrieval patterns, decomposing the user prompt into sub-queries, retrieving intermediate evidence, and feeding findings back to generate follow-up lookups before synthesizing the final output.
-
Embedding entire large documents directly instead of splitting into context-preserving chunks.
-
Failing to include document metadata filters, causing semantic drift across temporal domains.
-
Setting retrieval top-k too high, exceeding context windows and introducing irrelevant distraction.
-
Ignoring out-of-vocabulary terms and specialized acronyms by relying exclusively on dense embeddings.
-
Neglecting chunk overlap, splitting sentences across chunk boundaries and breaking logical context.
```import { Document, VectorStoreIndex, CohereRerank } from "llamaindex";
// Hybrid retrieval with cross-encoder reranker
const index = await VectorStoreIndex.fromDocuments(documents);
const retriever = index.asRetriever({ similarityTopK: 20 });
const reranker = new CohereRerank({ topN: 5 });
const initialNodes = await retriever.retrieve({ query: userQuery });
const finalNodes = await reranker.postprocessNodes(initialNodes, userQuery);
def reciprocal_rank_fusion(dense_ranks, sparse_ranks, k=60):
rrf_scores = {}
for doc_id, rank in dense_ranks.items():
rrf_scores[doc_id] = rrf_scores.get(doc_id, 0.0) + (1.0 / (k + rank))
for doc_id, rank in sparse_ranks.items():
rrf_scores[doc_id] = rrf_scores.get(doc_id, 0.0) + (1.0 / (k + rank))
return sorted(rrf_scores.items(), key=lambda item: item[1], reverse=True)
```
-
[ ] Multi-vector retrieval using summary-to-chunk lookups
-
[ ] Parent document retrieval via recursive chunk hierarchical trees
-
[ ] Self-RAG evaluation loops for hallucination detection
-
[x] Dense vector similarity metrics: Cosine, Dot Product, Euclidean
-
[x] Basic BM25 tokenization and inverse document frequency scoring
-
Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks (Lewis et al.)
-
Precise Zero-Shot Dense Retrieval without Relevance Labels (HyDE paper)
-
Reciprocal Rank Fusion outperforms Condorcet and individual approaches (Cormack et al.)