Retrieval-Augmented Generation (RAG) Architecture

Learning Objectives
After reading this guide, you will be able to:
- Deconstruct a production-grade Retrieval-Augmented Generation (RAG) architecture into its ingestion, retrieval, and generation phases.
- Select and implement optimal document-chunking strategies based on document structure, syntax, and semantic limits.
- Compare vector index types (Flat, IVF, HNSW) to balance search recall, query-per-second (QPS) throughput, and RAM constraints.
- Design a hybrid retrieval pipeline that mathematically fuses sparse (BM25) and dense (vector) search results using Reciprocal Rank Fusion (RRF).
- Integrate a two-stage retrieval process employing cross-encoder re-rankers to maximize semantic precision.
- Implement a production-ready, modular RAG system in Python with strict data schemas, metadata filtering, and comprehensive error handling.
- Evaluate RAG performance using the RAGAS framework across four dimensions: faithfulness, answer relevance, context recall, and context precision.
Prerequisites
This guide is designed for software engineers, data scientists, and systems architects.
- Required Knowledge:
- Proficient in Python (object-oriented patterns, type hinting, asynchronous operations).
- Familiarity with vector spaces, high-dimensional matrices, and basic probability.
- Conceptual understanding of Large Language Models (LLMs) and transformer architectures.
- Estimated Reading Time: ~45 minutes.
- Difficulty: Intermediate to Advanced.
Why This Matters {#whyThis Matters}
Large Language Models (LLMs) are historically constrained by two core limitations: parametric state locking and hallucination.
An LLM's knowledge is frozen at the point of its last pre-training or fine-tuning run. If an expat seeks the updated processing times for a specific digital nomad visa in Portugal or Spain, a vanilla LLM cannot reliably answer. It will either confess ignorance or, more dangerously, hallucinate an outdated or entirely fabricated policy.
Fine-tuning an LLM to inject this dynamic information is expensive, slow, and alters model behavior in unpredictable ways. This is where Retrieval-Augmented Generation (RAG) comes in.
RAG decouples the reasoning engine (the LLM) from the knowledge source (external databases). By retrieving highly relevant, real-time context from a non-parametric data store and appending it to the user's query, we constrain the LLM's generation to verifiable facts.
Enterprise engineering teams at Stripe, Cloudflare, Meta, and Bloomberg rely on RAG to power internal code search, external support automation, compliance auditing, and complex document intelligence systems. Mastery of RAG architecture is a fundamental skill for building dependable, production-grade AI applications in 2026.
First Principles
To understand why RAG is architected the way it is, we must look at how semantic search operates from first principles.
Parametric vs. Non-Parametric Memory
An LLM contains parametric memory. These are the billions of weights learned during training. They store syntax, style, logic, and broad historical patterns.
A database (SQL, NoSQL, or Vector) contains non-parametric memory. This is an external, structured repository of raw data that can be updated, deleted, and audited instantly without modifying the LLM's weights.
RAG bridges these two worlds. It uses the non-parametric memory to locate precise, factual documents, and uses the parametric memory of the LLM to synthesize those documents into a coherent, natural-language response.
The High-Dimensional Vector Space
At the heart of dense retrieval is the transformation of unstructured text into a vector—a list of floating-point numbers representing a point in a high-dimensional space (typically 384 to 3072 dimensions).
When an embedding model processes a string of text, it maps the semantic concepts within that text to spatial coordinates. Text pieces with similar meanings are mapped to coordinates close to one another in this multi-dimensional space, regardless of whether they share the same vocabulary.
For example, the sentences "How do I apply for a student visa in Germany?" and "German educational permit application procedures" share very few words, but their semantic vectors will lie close together.
The Mathematics of Text Similarity
To find the most relevant context for a query, we calculate the geometric distance between the query's vector and a document candidate's vector . There are three dominant metrics used to measure this distance:
1. Dot Product
The dot product measures the alignment of two vectors. It is highly sensitive to the magnitude (length) of the vectors.
Use Case: Use when your embedding model outputs vectors where the length represents document importance or frequency, or when vectors are already normalized to unit length.
2. Cosine Similarity
Cosine similarity measures the cosine of the angle between two vectors, completely ignoring their magnitudes. It ranges from -1 to 1 (or 0 to 1 for non-negative coordinates).
Use Case: This is the industry default for semantic search. It prevents longer chunks from dominating search results purely because they contain more total words.
3. Euclidean Distance ( Distance)
Euclidean distance measures the straight-line distance between two points in high-dimensional space.
Use Case: Preferred when using clustering algorithms or specific models (like legacy dense passage retrieval models) trained to minimize Euclidean loss. Note that a smaller distance indicates greater similarity, unlike dot product and cosine similarity where higher values indicate greater similarity.
Core Concepts
A production RAG architecture consists of three interconnected pipelines:
- The Ingestion Pipeline: Reading, cleaning, chunking, embedding, and indexing documents.
- The Retrieval Pipeline: Parsing the query, searching the vector/sparse database, filtering, and re-ranking candidates.
- The Generation Pipeline: Formulating the system prompt, enforcing structured constraints, and invoking the LLM.
1. Document Chunking Strategies
You cannot feed an entire 200-page immigration handbook into an embedding model at once. Embedding models have strict input token limits (e.g., 512, 2048, or 8192 tokens), and larger inputs dilute the precision of the resulting vector. Therefore, documents must be split into "chunks".
- Fixed-Size Chunking: Splitting text into a predetermined number of characters or tokens (e.g., 500 characters) with a sliding window overlap (e.g., 50 characters). This is computationally cheap but frequently breaks paragraphs, sentences, or even words in half, severing critical context.
- Recursive Character Chunking: Splitting text using a hierarchy of separators—typically double newlines
\n\n(paragraphs), single newlines\n(lines), spaces, and finally empty strings""(characters)—until the chunk falls under the target size limit. This preserves paragraph and sentence boundaries. - Semantic Chunking: Analyzing the semantic difference between consecutive sentences. When the semantic shift between sentence and sentence exceeds a defined threshold (calculated via embedding cosine distance), a chunk boundary is placed.
- Document-Structure-Aware Chunking: Parsing Markdown, HTML, or PDF elements to respect native structures like headers (
#,##), tables, and list items. This ensures tables or list options are never split into separate, unreadable fragments.
2. Vector Indexing Algorithms
Once text chunks are embedded, they are indexed in a vector database. Standard flat indexes (calculating cosine similarity against every single document in the DB) have a time complexity of . At millions of vectors, search latency becomes unacceptable. Modern vector databases use Approximate Nearest Neighbor (ANN) indexing:
- IVF (Inverted File Index): Uses k-means clustering to partition the vector space into centroids. During search, the query vector is compared only against the nearest centroids, reducing search scope from to a fraction of . This saves memory but can miss close vectors that lie near cluster boundaries.
- HNSW (Hierarchical Navigable Small World): Builds a multi-layer graph structure where the bottom layer contains all vectors and higher layers contain increasingly sparse skip-lists. Search navigates down through the layers with complexity. HNSW provides exceptional recall and extremely low query latency, but has high memory overhead and long build times.
3. Sparse vs. Dense Retrieval
- Sparse Retrieval (BM25): Matches exact keywords, acronyms, and product codes based on term frequency-inverse document frequency (). It is highly reliable for looking up exact passport form codes (e.g., "DS-11") or visa names ("Subclass 189").
- Dense Retrieval (Embeddings): Matches semantic intent and synonyms. It excels when the user's vocabulary does not align with the document's vocabulary (e.g., querying "getting a work permit" and finding documents containing "authorization of employment").
Production systems rarely use dense retrieval alone. They combine both approaches in a hybrid retrieval pipeline.
Deep Dive
To move from basic ("naive") RAG to an enterprise-grade system that can handle complex queries over messy real-world data, we must implement several advanced patterns.
Advanced Query Transformation
Users often write poorly structured, ambiguous queries. If a user asks "Can I travel to France while my talent visa is processing, and what about Spain?", a direct vector lookup will fail because the query is too complex, containing multiple intents.
Query Decomposition
An intermediary LLM step breaks a compound query down into discrete sub-queries:
- "Can I travel to France while my French talent visa is processing?"
- "Can I travel to Spain while my Spanish talent visa is processing?"
Each sub-query runs through the retrieval pipeline independently, and the aggregated context is fed to the generator.
Query Expansion (HyDE - Hypothetical Document Embeddings)
Often, the semantic vector of a query (which is in the form of a question) does not align well with the semantic vector of the answer (which is in the form of an assertion).
HyDE prompts an LLM to generate a hypothetical answer to the user's query first. Even if this hypothetical answer contains minor factual errors, its vector representation will be structurally and semantically close to the actual documents in your database.
We embed this hypothetical document and use its vector to retrieve real documents.
Advanced Retrieval Patterns
Parent-Document Retrieval (Sentence-Window Retrieval)
There is an inherent conflict in chunking:
- Small chunks (e.g., 1-2 sentences) yield highly precise embeddings because they contain focused, undiluted ideas.
- Large chunks (e.g., 1000 tokens) provide the LLM with the necessary surrounding context to answer questions comprehensively without losing track of pronouns or document flow.
The Parent-Document Retrieval pattern resolves this by decoupling the data stored in the index from the data passed to the generator.
During ingestion, we chunk the document into tiny fragments (e.g., 100 tokens, representing the "child chunks"). Each child chunk maps to its parent document (the larger context).
We embed and query only the child chunks. However, when a child chunk is matched, we retrieve its corresponding parent document (or a larger surrounding text window) and pass that larger block to the LLM.
Re-ranking with Cross-encoders
Vector databases use Bi-encoders (where queries and documents are embedded separately and compared via dot-product or cosine similarity). This is exceptionally fast but lacks token-to-token interaction during search.
A Cross-encoder processes the query and a document candidate together in a single pass through a Transformer, allowing full self-attention across every query token and document token.
Cross-encoders are computationally expensive and cannot be used to search millions of documents. However, we can use them in a two-stage retrieval pipeline:
- Use a fast Bi-encoder (Vector DB) + BM25 to retrieve the top 50 candidates.
- Use a Cross-encoder re-ranker (e.g.,
CohereRerankor a localBGE-Reranker) to score and re-rank those top 50 candidates, passing only the top 5 highly verified contexts to the LLM context window.
Practical Examples
To demonstrate these concepts, let us build a system that indexes and queries immigration and visa policy documents. This domain contains many complex terms, numerical rules, and nested conditions.
Scenario
An agency needs to build an immigration-related search system for expats and students. The system must process PDF guides, support search over exact form IDs (e.g., "Form I-765") and semantic visa paths (e.g., "post-study work options"), and synthesize precise, grounded answers.
Workflow
- Parse a sample policy document.
- Chunk it using a custom recursive method.
- Index the chunks in an in-memory vector store (with metadata support) alongside a sparse BM25 index.
- Execute a hybrid search query.
- Apply a re-ranking model to selection candidates.
- Synthesize the final response with strict schema boundaries using an LLM.
Code Examples
The following Python code blocks provide a modular, production-ready implementation of an advanced hybrid search, re-ranked RAG system. It uses numpy for core vector math, rank_bm25 for sparse lookup, sentence-transformers for embeddings and re-ranking, and the official openai SDK for constrained generation.
Make sure you have these packages installed:
Module 1: Document Models and Chunking Engine
We define clean, production-grade schemas for our documents, maintaining explicit IDs and metadata fields.
Module 2: In-Memory Hybrid Vector Store with Cross-Encoder Re-ranking
This module encapsulates vector embedding (via SentenceTransformers), sparse tokenization, BM25 indexing, retrieval, Reciprocal Rank Fusion, and Cross-Encoder re-ranking.
Module 3: Strict Orchestration and Constrained LLM Generation
This module defines the structured prompt templates and validates output formats using strict programmatic parsing.
Module 4: Pipeline Execution Execution Example
To demonstrate end-to-end functionality, let us write a driving script with complex visa rules.
Explanation of Code Design decisions:
- Recursion separator order: We step down from large blocks (paragraphs) to single lines, down to spaces to preserve sentence structure boundaries dynamically.
- Normalized Dot Product: Multiplying normalized arrays yields standard Cosine Similarity values, bypassing computation-heavy square root algorithms dynamically on every database query.
- Reciprocal Rank Fusion (RRF): Traditional rank metrics scale unpredictably across sparse indexes (which score absolute Term Frequency frequencies) and dense models (which score Cosine values). RRF circumvents this scaling issue by fusing results based solely on their rank indexes, converting arbitrary search scores into a unified, mathematically consistent ranking.
- Structured JSON Validation: Using structured models restricts output structures to conform to native client classes, eliminating erratic manual parsing logic of string prompts.
Diagrams
The following diagrams illustrate the structural differences and workflows inside a production RAG system.
Figure 1: Ingestion Pipeline Workflow
Figure 2: The Two-Stage Hybrid Retrieval and Re-ranking Engine
Comparison Tables
1. Vector Database Indexing Algorithmic Trade-offs
| Index Type | Search Latency | Recall Precision | RAM Footprint | Build/Index Time | Ideal Production Use Case |
|---|---|---|---|---|---|
| Flat Index (Exact) | High (Linear ) | Perfect | Extremely Low | Immediate () | Small corpora ( documents) where flawless search accuracy is non-negotiable. |
| IVF (Inverted File) | Medium () | High (can miss edge cluster anomalies) | Low (Saves space via clustering) | Low | Large, cost-sensitive databases where RAM space is constrained. |
| HNSW (Hierarchical Navigable Small World) | Low (Logarithmic ) | Very High () | High (Requires keeping graphs in RAM) | High (Requires building graphs) | High-throughput, low-latency enterprise applications (sub-20ms search times on millions of items). |
2. Standard Document Chunking Methodologies
| Chunking Method | Pros | Cons | Algorithm Complexity | Primary Match Target |
|---|---|---|---|---|
| Fixed-Size Sliding Window | Exceptionally fast; zero document parsing or structures required. | Breaks sentences and arguments mid-thought, creating semantic fragmentation. | Simple unstructured text files. | |
| Recursive Character | Keeps paragraphs and sentences intact, minimizing fragment noise. | Vulnerable to structural anomalies (e.g., parsing a table splits rows unpredictably). | Native text books, immigration policy reports. | |
| Semantic Similarity | Groupings are determined by changes in semantic topic. | Highly compute-heavy (requires calling embedding model for every sentence). | Conversational transcripts or unstructured streams. | |
| Structural-Aware (Markdown/PDF) | Preserves tables, bullet points, headers, and structural hierarchy. | Highly dependent on clean input document markup or PDF extraction tools. | Complex regulatory documentation, visa guidelines, and APIs. |
Common Mistakes
1. The "Lost in the Middle" Phenomenon
Many developers think that larger context windows (e.g., 128k to 2M tokens) mean they can stuff hundreds of retrieved chunks into the prompt. However, research shows that LLMs are highly proficient at parsing facts located at the very beginning and very end of long context payloads, but frequently miss details buried in the middle.
- The Fix: Keep retrieved contexts tight. Use hybrid search and re-ranking to limit your inputs to the top 3-5 most relevant chunks. Do not stuff context windows with low-confidence documents.
2. Missing Co-Reference Resolution
If a chunk states: "Under this visa category, they are eligible to apply after two years," the pronoun they and the phrase this visa category have no clear referents out of context. An embedding model processing this chunk in isolation will yield a low semantic match for queries about "Spain digital nomad residency eligibility."
- The Fix: Use Parent-Document Retrieval, or use a pre-processing LLM step to enrich child chunks with global context metadata (e.g., appending
"Document Subject: Spain Digital Nomad Visa | Section: Eligibility"to the top of every chunk before embedding).
3. Mixing Up Embedding Models
A common production bug occurs when teams update their retrieval embedding model (e.g., from all-MiniLM-L6-v2 to text-embedding-3-small) but forget to re-embed their existing vector database. Since vectors from different models occupy entirely different high-dimensional coordinate spaces, search returns meaningless noise.
- The Fix: Implement strict database schema versioning. Tie your vector collection directly to a specific embedding model tag in your codebase, and automate migration checks during deployment.
4. Over-reliance on Vector Search for Exact Numbers and IDs
If a student queries "What rules apply to form I-20?", vector embeddings might pull up documents about "Form I-765" or "F-1 visa guidelines" because they are semantically related. This happens because individual character identifiers are often washed out in high-dimensional semantic spaces.
- The Fix: Implement hybrid search. Make sure exact token identifiers, reference codes, or numeric policies are matched via BM25 or Postgres exact phrase matching, then merge them using Reciprocal Rank Fusion.
Real Industry Examples
Stripe: Support Automation and API Document Grounding
Stripe handles developer support by running a hybrid RAG pipeline across API references, community forums, and help center guides. To ensure search returns correct API parameters (e.g., payment_intent.succeeded), Stripe uses custom markdown parsers that prevent API tables from being split. They use hybrid retrieval to match exact code variables alongside natural-language semantic explanations, resolving documentation lookups instantly.
Cloudflare: Scalable Zero-Trust Secure Search
Cloudflare utilizes RAG pipelines internally over highly confidential engineering, legal, and operational manuals. In secure corporate environments, a general index search could leak sensitive information if a user queries a topic they do not have clearance to view.
Cloudflare solves this by enforcing Document-Level Security (DLS). They append encrypted authorization lists (Access Control Lists - ACLs) as metadata to every chunk in their vector store. When a query is run, the system applies a metadata filter matching the user's active JSON Web Token (JWT) credentials, preventing unauthorized chunks from ever reaching the LLM.
Best Practices
1. The RAGAS Evaluation Framework
To scale a RAG system, you must be able to measure how changes to your chunking strategy, embedding models, or system prompts affect output quality. The RAGAS framework decomposes pipeline quality into four core, quantitative metrics:
Run regression evaluations against a golden test set of ~100 query-and-ground-truth pairs before pushing pipeline updates to production.
2. Latency Optimization Patterns
A complex hybrid search with re-ranking and LLM synthesis can easily take several seconds. To keep response times sub-second:
- Asynchronous Database I/O: Execute sparse database lookups and dense vector indexing concurrently using Python's
asyncio. - Streaming Outputs: Stream response tokens from the LLM back to the client in real time. This lowers Time to First Token (TTFT), improving the perceived performance of the application.
- Vector Quantization: Use Product Quantization (PQ) or Scalar Quantization (SQ) in your vector database to compress floating-point vectors from 32-bit to 8-bit integers, reducing memory bandwidth usage and boosting lookup speeds.
3. Data Governance and Drift Auditing
Documents change over time. If a policy document is revised or deleted, stale chunks must be purged from the index immediately.
- Deterministic Chunk ID Generation: Generate chunk IDs deterministically by hashing the source document URL/filepath and chunk index (e.g.,
hash(doc_path + "_chunk_" + index)). This allows you to easily overwrite old chunks when a document is updated, or delete them when a document is removed.
Interview Questions
Junior Level
- What is the difference between parametric and non-parametric memory in LLMs, and how does RAG leverage both?
- Answer: Parametric memory refers to the static weights learned by the LLM during pre-training. Non-parametric memory refers to external data sources (like databases). RAG uses dense and sparse retrieval to query non-parametric databases for accurate, up-to-date facts, then feeds those facts into the LLM's prompt. This allows the LLM to use its parametric language skills to write a factual response without needing to store every real-world fact in its weights.
- Why is recursive character chunking preferred over simple fixed-character splitting?
- Answer: Recursive character chunking respects natural text structure by trying to split text along a hierarchy of separators (like double newlines for paragraphs, then single newlines, then spaces). This keeps complete paragraphs, sentences, and lists together. Fixed-character splitting cuts text off at arbitrary character limits, which often splits words or thoughts in half, breaking the semantic meaning of the chunk.
Intermediate Level
- How does Reciprocal Rank Fusion (RRF) combine sparse and dense search results without normalizing their raw similarity scores?
- Answer: Sparse search (BM25) and dense search (cosine vector similarity) produce scores on completely different scales. Sparse scores are unbounded and depend on term frequency, while dense scores are bounded (usually between 0 and 1). Normalizing these raw scores directly is unreliable. RRF bypasses score normalization entirely by looking only at a document's rank position within each result list. It calculates a fused score using the formula: where is the document's rank in search run , and is a constant (typically 60) that prevents highly ranked outliers from dominating the scores.
- Explain the structural differences between Bi-encoders and Cross-encoders. Why don't we use Cross-encoders to search the entire vector database?
- Answer: A Bi-encoder embeds queries and documents separately into independent vector spaces. Search is fast because we only need to compute simple vector similarity (like dot product) between pre-computed vectors. A Cross-encoder processes the query and document together as a single input through a Transformer, allowing every query token to attend to every document token. This is highly accurate but computationally expensive. We cannot run a Cross-encoder over millions of documents in real time. Instead, we use a two-stage pipeline: a fast Bi-encoder retrieves the top 50-100 candidates, and a Cross-encoder re-ranks only those top candidates.
Senior Level
- Design an architecture for a real-time, multi-tenant RAG system handling millions of files. The system must prevent document-level data leaks and update index deletions in under 5 seconds.
- Answer: The system should be built on three core pillars:
- Tenant Isolation: Use a vector database (like Pinecone, Milvus, or Qdrant) that supports metadata partitioning or namespace isolation. Tag every chunk with metadata fields like
tenant_idand an access listuser_groups. During query execution, apply strict, un-bypassable database-level filters matching the user's active JWT credentials (e.g.,tenant_id == user.tenant_id AND user_groups INTERSECT user.roles). - Near Real-Time Updates (CDC): Implement a Change Data Capture (CDC) pipeline using tools like Debezium and Apache Kafka. When a document is modified or deleted in the primary database, a CDC event is published to a Kafka topic. A streaming consumer reads this event, computes the deterministic IDs of the document's chunks, and issues an asynchronous batch delete query to the vector and BM25 indexes.
- Query Engine Routing: Scale search throughput using an event-driven framework like FastAPI/asyncio, deploying read-replicas for vector indices, and applying Product Quantization (PQ) to reduce RAM usage and optimize query speeds.
- Tenant Isolation: Use a vector database (like Pinecone, Milvus, or Qdrant) that supports metadata partitioning or namespace isolation. Tag every chunk with metadata fields like
- Answer: The system should be built on three core pillars:
Exercises
Easy: Overlapping Chunk Validation
Write a Python function that takes a string of text, splits it into words, and generates chunks of words with an overlap of words.
- Input:
"The Spain Digital Nomad Visa provides non-EU foreign nationals remote working capability within Spain in 2026.", , - Expected Output Chunks:
"The Spain Digital Nomad Visa provides""Nomad Visa provides non-EU foreign""non-EU foreign nationals remote working""remote working capability within Spain""within Spain in 2026."
Medium: Custom RRF Rank Merger
Implement a Reciprocal Rank Fusion (RRF) function in pure Python.
- Input: Two lists of document IDs, sorted from best to worst.
dense_list = ["doc_A", "doc_B", "doc_C", "doc_D"]sparse_list = ["doc_C", "doc_A", "doc_E", "doc_B"]
- Goal: Fuse these rankings with a constant and output the final ranked IDs with their scores.
Hard: Agentic Routing Pipeline
Build a routing mechanism that analyzes a user's query and routes it to the correct retrieval tool:
- Route to SQL Tool if the query contains structural keywords (e.g., "How many visa applications...", "average processing fee...").
- Route to Vector RAG Tool if the query is semantic and open-ended (e.g., "What is the lifestyle like for expats...", "how do I apply...").
- Route to Fallback Tool for general conversational queries.
- Requirement: Implement this router using Python and regular expressions, or design an structural LLM router using OpenAI Structured outputs.
Cheat Sheet
Retrieval Metrics Math At-A-Glance
| Metric | Mathematical Formula | Range | Best Applied When |
|---|---|---|---|
| Dot Product | Vector lengths carry semantic importance, or when vectors are already normalized. | ||
| Cosine Similarity | The default for standard text search; prevents longer texts from skewing search results. | ||
| Euclidean () Distance | Using clustering algorithms (like IVF centroids) or specific distance-based models. |
High-Yield Architecture Guidelines
- Overlap Rule of Thumb: Set your chunk overlap to of your target chunk size to ensure context is preserved across chunk boundaries.
- The Two-Stage Retrieval Flow: Retrieve 50 chunks using speed-optimized hybrid search (BM25 + HNSW Vector), then narrow down to the top 3-5 chunks using a Cross-Encoder re-ranker before passing context to the LLM.
- Structured Outputs: Always enforce strict JSON schemas (e.g., via OpenAI's structured outputs or instructor packages) to guarantee that retrieved citations can be parsed programmatically.
Glossary
- Parametric Memory: The static knowledge encoded in an LLM's weights during training.
- Non-Parametric Memory: External data stores (databases, indexes, files) that can be updated dynamically without retraining the model.
- Semantic Vector Embedding: The transformation of unstructured text into a dense, high-dimensional numerical vector representing its semantic meaning.
- Cosine Similarity: A geometric metric that measures the cosine of the angle between two vectors, focusing on direction rather than magnitude.
- Inverted File Index (IVF): An approximate nearest neighbor indexing technique that groups vectors into clusters to speed up searches.
- Hierarchical Navigable Small World (HNSW): An ANN graph-based indexing algorithm that navigates multi-layered graphs for low-latency vector search.
- BM25 (Best Match 25): A tf-idf-based search algorithm used by sparse search engines to rank documents based on exact keyword matches.
- Reciprocal Rank Fusion (RRF): An algorithm that merges multiple ranked search result lists into a single ranking based on the rank positions of items.
- Cross-encoder: A deep learning model that evaluates queries and documents together to calculate highly precise relevance scores.
- Bi-encoder: A model that embeds queries and documents separately, allowing fast similarity lookups but losing token-to-token contextual interaction.
- Hypothetical Document Embeddings (HyDE): A query expansion technique where an LLM generates a hypothetical answer to a query, and that hypothetical answer's vector is used to search the database.
- Sentence-Window Retrieval (Parent-Document Retrieval): A pattern where small chunks are used for embedding lookup, but their larger parent documents are retrieved and passed to the LLM.
- RAGAS (RAG Assessment): An evaluation framework used to measure RAG pipelines across key metrics like faithfulness, answer relevance, context precision, and recall.
- Hallucination: A phenomenon where an LLM generates plausible-sounding but factually incorrect or unsupported claims.
References
- Original RAG Paper: Lewis, P., et al. (2020). "Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks." NeurIPS. arXiv:2005.11401
- Sentence-BERT Paper: Reimers, N., & Gurevych, I. (2019). "Sentence-BERT: Sentence Embeddings using Siamese BERT-Networks." EMNLP. arXiv:1908.10084
- BM25 Algorithm Reference: Robertson, S., & Zaragoza, H. (2009). "The Probabilistic Relevance Framework: BM25 and Beyond." Foundations and Trends in Information Retrieval.
- HNSW Research Paper: Malkov, Y. A., & Yashunin, D. A. (2018). "Efficient and robust approximate nearest neighbor search using Hierarchical Navigable Small World graphs." IEEE Transactions on Pattern Analysis and Machine Intelligence. arXiv:1603.09320
- "Lost in the Middle" Study: Liu, N. F., et al. (2023). "Lost in the Middle: How Language Models Use Long Contexts." Transactions of the Association for Computational Linguistics. arXiv:2307.03172
- RAGAS Evaluation Framework: Es, S., et al. (2023). "Ragas: Automated Evaluation of Retrieval Augmented Generation." arXiv:2309.15217
FAQ Schema (Markdown Representation)
What is the primary difference between RAG and Fine-Tuning?
Fine-tuning updates the internal parameters (weights) of an LLM, teaching it new styles, formats, or behavioral rules. RAG retrieves external, factual documents and appends them to the prompt as context. Fine-tuning is slow and expensive, whereas RAG updates instantly when documents in your database are modified.
Why shouldn't I use only vector search for my RAG system?
Vector search excels at semantic matching and finding synonyms, but it is poor at matching exact character strings, product codes, or specific numbers (like visa form IDs or legal statute codes). A production RAG system should use hybrid search, combining vector search with sparse keyword search (BM25) to handle both semantic queries and exact term matches.
How can I stop my RAG system from hallucinating when it doesn't know the answer?
You can prevent hallucinations by implementing three guardrails:
- Use strict system prompts that forbid the LLM from answering using any facts outside the provided context.
- Set the generation temperature to
0.0for deterministic outputs. - Use structured output JSON schemas that require the model to explicitly return a boolean flag indicating if the context was sufficient, alongside verbatim citations to support every claim it makes.
