Skip to content

Memory and Knowledge

Retrieval-augmented generation

The RAG pipeline, chunking, reranking

A base model answers only from what it memorized. RAG fetches the right passages from an external corpus at query time and puts them in the prompt - so the agent answers from evidence, with citations, without retraining. This lesson is the full pipeline, end to end.

Two memories, one prompt

Every LLM ships with parametric memory: facts compressed into its weights during training. That memory is frozen at the knowledge cutoff, cannot cite a source, and confabulates when asked about something it only half-remembers. RAG adds a second, swappable store - : an external corpus you index and query at inference time, injecting the retrieved passages into the prompt as context.[1] The framing - parametric plus non-parametric memory - comes from the paper that coined RAG (Lewis et al., NeurIPS 2020), which paired a dense retriever over Wikipedia with a generator and proposed two variants: RAG-Sequence (one retrieved set for the whole answer) and RAG-Token (a different doc can inform each token).[1]

Production RAG usually skips the joint fine-tuning: an off-the-shelf embedding model, a vector database, and a frozen instruction-tuned LLM, wired together. The architecture - retrieve, then generate - is what matters. Teams reach for it because it buys four things a bare model cannot:

What RAG buysWhy it matters
FreshnessUpdate the index, not the weights. New docs are searchable the moment they are chunked and embedded.
Grounding and citationsEvery claim can point at a source passage - auditability and compliance, not just vibes.
Less hallucinationThe evidence sits in front of the model, so it answers from the passage instead of guessing from memory.
Cost and privacyKeep proprietary data out of training; swap the corpus per tenant without touching the model.
Four things a retrieve-then-generate architecture buys that a bare model cannot.

The pipeline: an offline index and an online query

RAG is two paths that meet at a shared index. Offline, you build the index once (and re-build as the corpus changes). Online, every user query travels the second path and reads from that index. Seven stages total - load, chunk, embed, index offline, then embed, retrieve, rerank, generate online - and each one is an independent failure point.

Tap a node to see what it does.

The RAG pipeline. The offline lane writes to the index; the online lane reads the top-k. The embedding model is the same on both lanes - queries and passages must live in one vector space.

Offline - build once

Load - parse PDFs, HTML, DB rows; broken extraction poisons everything downstream. Chunk - split into retrievable units (the highest-leverage stage). Embed - a bi-encoder maps each chunk to a vector. Index - store vectors in an ANN structure; also build a BM25 inverted index for hybrid.

Online - every query

Embed the query with the same model. Retrieve - ANN + BM25 in parallel, fused; cast a wide net (recall stage). Rerank - a cross-encoder re-scores the shortlist to a precise top handful. Generate - pack system prompt + top chunks + question; the LLM answers, ideally with citations.

Where quality is actually won

2025 to 2026 practitioner consensus: retrieval, not generation, is the bottleneck. Generation is largely "solved" relative to getting the right evidence in front of the model, which is why effort has moved to hybrid, reranked, and agentic retrieval.[2] And within retrieval, chunking is the highest-leverage thing to get right - bad chunks cap your ceiling no matter how good the embeddings or reranker.

Chunking - the highest-leverage stage

You chunk because embeddings represent a bounded span and lose fidelity over long inputs, and because you want to retrieve precise evidence, not whole documents. The tension: a that is too small fragments a fact across chunks; too large dilutes the embedding with irrelevant text and wastes context budget. Strategies, roughly by sophistication:[3]

StrategyHow it splitsWhen to use
Fixed-sizeEvery N tokens, optional overlap.Baseline only - semantically blind, will cut a sentence or table in half.
RecursiveHierarchy of separators: paragraphs, sentences, words, until it fits.The pragmatic default. Highest end-to-end accuracy (~69%) in a 2026 benchmark; fast and cheap.
Structure-awareOn Markdown headings, HTML tags, code functions; keep tables/lists intact.Documents with reliable structure.
SemanticNew chunk where consecutive-sentence similarity drops (a topic edge).Better recall on some corpora, but 2 to 3x indexing cost - an embed call per sentence.
Late / ContextualGive each chunk its surrounding context before embedding.Fixes lost context at chunk boundaries. See below.
Chunking strategies, roughly ordered by sophistication and cost.

Default that ships

Start with recursive splitting at ~512 tokens with 10 to 20% overlap, respect document structure (never split code or tables), measure, and only add complexity where your eval moves. Every fancier strategy is more latency, cost, and a new failure mode.[3]

Contextual Retrieval (Anthropic, 2024) is the standout upgrade: have an LLM write a 50 to 100 token blurb that situates each chunk in its parent document, and prepend it before embedding and BM25 indexing. On Anthropic's eval this cut the top-20 retrieval-failure rate by 35% (5.7% to 3.7%); adding contextual BM25 took it to 49% (to 2.9%); adding a reranker to 67% (to 1.9%). One-time cost is about $1.02 per million document tokens with prompt caching.[2] Late chunking (Jina) solves the same problem cheaper, using only the embedding model.[3]

Dense + sparse = hybrid search

Two retrievers with complementary failure modes. (sparse, lexical) scores by term frequency down-weighted by rarity - it nails exact matches: product codes, error strings, function names, rare proper nouns. It has zero notion of meaning ("car" is not "automobile"). Dense embeddings do the opposite - great at paraphrase, synonyms, cross-lingual - but can whiff on that one literal SKU. Most real queries are mixed-intent, so hybrid is the robust production default: run both, then fuse.[4]

Fusion uses , which looks only at each document's rank position in each list - never the raw scores:

score(d) = sum  1 / (k + rank(d))    # summed over every retriever's ranked list
                                     # rank(d) is 1-indexed;  k = 60 (default)
Reciprocal rank fusion: merge rankings by position, not by raw score.

Why not just average the scores?

Because BM25 scores are unbounded positive numbers and cosine is bounded to [-1, 1] - incompatible scales. A naive weighted average lets BM25's giant numbers dominate. RRF normalizes by construction: it only ever sees ordinal rank, so a doc both retrievers ranked highly floats to the top even if neither gave it rank 1.[4]

Rerank with a cross-encoder

First-stage retrieval uses a bi-encoder: query and document are embedded separately, so the model never sees them interact - fast and precomputable, but coarse. A feeds the concatenated (query, document) pair through a transformer, letting attention model every query-token to doc-token interaction. That yields far sharper relevance - the single biggest precision win in most pipelines.[4]

Bi-encoder - first stage

Query and doc go through two separate towers that meet only at a final cosine dot. Fast, precomputable, coarse. Use it to cast a wide net over millions of chunks.

Cross-encoder - rerank

Query and doc go through one tower together, with full attention. Cannot be precomputed, O(n) per candidate. Slow but sharp. Use it to prune the shortlist.

The cost is that a cross-encoder runs a full forward pass per candidate - nothing precomputes. Hence the standard two-stage pattern: retrieve wide and cheap (top-100 to top-1000 via BM25 + dense + RRF), then rerank down to the final top-5 to top-10 for the prompt.[4] Anthropic found retrieving top-20 candidates beat top-10 and top-5 - recall matters at the retrieval stage; let the reranker do the pruning.[2] Common rerankers: Cohere Rerank 3.5 and Voyage rerank-2.5 (a 32K context, about 8x Cohere's, with instruction-following) plus open-weight BGE rerankers.[4]

Worked example: Q&A over a document set

Corpus: 40,000 internal engineering docs (~30M tokens) - far too big for any context window, so retrieval is mandatory. The index was built offline with recursive ~512-token chunks + contextual blurbs, stored in both an HNSW vector index and a BM25 index. Now a query arrives:

Query

"why did the checkout service throw ERR_2043 after the June deploy?"
  1. Dense retrieval. Embed the query; ANN returns the 100 semantically-nearest chunks (it understands "checkout service", "deploy").
  2. Sparse retrieval. BM25 returns 100 chunks and reliably surfaces the literal ERR_2043 string, which a pure embedding search might smear into "generic error."
  3. Fuse (RRF, k=60). One merged list of ~150 unique candidates; a chunk both retrievers liked floats to the top.
  4. Rerank. A cross-encoder re-scores the top ~100 (query, chunk) pairs; the runbook chunk that literally explains ERR_2043 and references a June config change now scores highest.
  5. Assemble. Top-5 reranked chunks + "answer only from the context and cite chunk IDs" + the question.
  6. Generate. The LLM produces a grounded, cited answer.

Grounded answer

ERR_2043 is a payment-gateway timeout. The June 14 deploy lowered the gateway client timeout from 30s to 5s (config gw.timeout_ms), so slow authorizations now fail with ERR_2043. [chunk 8813, chunk 8815]

Had the contextual-prepend step been skipped, the runbook chunk - whose raw text said "this timeout" without naming the service - might have ranked #60 and been dropped before reranking: a textbook retrieved but below the cutoff miss. Context recall = 1.0, faithfulness = 1.0 on this trace only because every stage did its job.

RAG vs long context

Frontier models now take up to ~1M tokens. So why retrieve at all? Because it depends on corpus size and workload - it is a trade-off, not a war.[5]

Long context wins

Corpus is under ~200K tokens (~500 pages) - Anthropic's rule: just paste it all and prompt-cache it.[2] The task needs the whole document coherent at once. Simpler: no index, no retrieval failure modes.

RAG wins

Large corpora (millions of tokens - cannot fit) and high query volume (re-reading a huge context per query is wasteful). Latency, cost, and freshness (update the index, not the prompt). Auditable citations - retrieval gives you provenance.[6]

Long context is not free of retrieval problems either: attention cost scales roughly quadratically, and models exhibit "lost in the middle" - recall degrades for facts buried mid-context. Stuffing more in also injects more noise. The two compose: use RAG to pre-filter a huge corpus down to a long-context-sized working set.[5] This is a direct extension of context engineering - the art of what to put in the window.

Beyond the fixed pipeline

Agentic RAG

Classic RAG always retrieves once, with the raw query. Agentic RAG makes retrieval a decision: should I retrieve at all? Rewrite or decompose the query first? Which source? Are these chunks good enough, or do I search again (multi-hop)? Named patterns: Self-RAG (the model emits reflection tokens deciding when to retrieve and critiquing support), Corrective RAG (an evaluator grades docs and falls back to web search when they are weak), and HyDE (embed a hypothetical answer). Retrieval becomes one tool an agent calls deliberately - the bridge from RAG into the agent loop and agent memory.

GraphRAG

Baseline vector RAG retrieves the chunks most similar to the query - but some answers live in the aggregate, not any single chunk. Ask "what are the top 5 themes across all 40,000 docs?" and no chunk contains the answer. (Microsoft) fixes this: at index time an LLM extracts entities plus relationships into a knowledge graph, the Leiden algorithm clusters it into a community hierarchy, and an LLM pre-summarizes each community. Global search then map-reduces over those summaries.[7] Reach for it for global / sensemaking questions - not simple fact lookup, where it is overkill.[8]

Evaluate retrieval and generation separately

A wrong answer is either a retrieval miss (the evidence never arrived) or a generation failure (it arrived and the model still blew it) - and the fixes are completely different. This split is the single most useful diagnostic in RAG, and frameworks like RAGAS formalize it.[9]

MetricMeasuresLayer
FaithfulnessOf the claims in the answer, what fraction are supported by the retrieved context? (supported / total). Directly measures hallucination; reference-free.generator
Answer relevancyDoes the answer actually address the question, vs rambling or dodging? Reference-free.generator
Context precisionAre the relevant chunks ranked above the irrelevant ones in the retrieved set? (rank-aware)retriever
Context recallDoes the retrieved context contain all the info needed for the reference answer?retriever
RAGAS metrics split cleanly across the two layers: two grade the generator, two grade the retriever.

Read the pair: low context recall means fix retrieval (chunking, embeddings, top-k, hybrid, reranker). Good recall but low faithfulness means fix generation (prompt, model, or the context is too noisy/long).[10] Build a golden eval set and treat these scores as a regression suite on every pipeline change.

Top failure modes

The well-known "seven failure points of RAG" plus operational issues - most are retrieval problems wearing a generation costume:

FailureWhat happensFix
Missing contentThe answer is not in the corpus; the model confabulates instead of refusing.Coverage checks; instruct 'say I do not know.'
Below the cutoffA relevant chunk was retrieved but ranked past top-k and dropped.Retrieve wider, add a reranker, go hybrid.
Boundary lossA fact split mid-chunk, or a pronoun whose antecedent is in another chunk.Overlap; contextual / late chunking.
Retrieved, not extractedThe answer is in the context but buried in noise ('lost in the middle').Fewer, higher-precision chunks; reranking.
Domain mismatchA general embedder underperforms on legal/medical/code jargon.Domain / fine-tuned embeddings; BM25 backstop.
Stale indexThe corpus changed but the index did not; old and new embeddings coexist.Re-index pipeline; versioned embeddings.
The common RAG failure modes, and the fix each one calls for.

Retrieval is an injection surface

Untrusted documents in your corpus can carry prompt-injection payloads the generator will obey, and corpus poisoning can steer results. Treat every retrieved passage as untrusted input - a theme we harden in security and prompt injection.

Check yourself

Match each RAG stage to what it contributes.

drop here

sets the unit of search and grounding

drop here

cheap high-recall candidate set

drop here

precise reordering of candidates

drop here

catches exact terms similarity misses

A user's answer was wrong. The chunk that literally answered it was retrieved but ranked #14, so it never reached the model. Which fix targets this failure most directly?

What is the main risk of making chunks too large?

Why fuse BM25 and dense results with Reciprocal Rank Fusion instead of averaging their scores?

What is different about the two score scales? Try to state it, then check.

Lock it in

  • RAG = parametric + non-parametric memory. Fetch evidence at query time and put it in the prompt - freshness, citations, and less hallucination, no retraining.[1]
  • Two lanes, one index. Offline: load, chunk, embed, index. Online: embed, retrieve, rerank, generate. Each stage is an independent failure point.
  • Chunk first, then go hybrid, then rerank. Recursive ~512 tokens + overlap; BM25 + dense fused with RRF (k=60); a cross-encoder for the biggest precision win.
  • Retrieve wide, rerank narrow. Recall at stage 1 (top-100+), precision at stage 2 (top-5/10). More context is not better - noise hurts faithfulness.
  • Evaluate retrieval and generation separately. Context recall diagnoses retrieval; faithfulness diagnoses generation. Never ship RAG on vibes.

Primary source

Anthropic, Introducing Contextual Retrieval

The single best practical read: a concrete high-impact recipe (contextual embeddings + contextual BM25 + reranking), the exact failure-rate numbers (35 / 49 / 67%), top-k guidance, prompt-caching cost, and the under-200K- token RAG-vs-long-context heuristic.

Sources

  1. 1.Lewis et al., Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks (NeurIPS 2020)
  2. 2.Anthropic, Introducing Contextual Retrieval
  3. 3.Firecrawl, Best Chunking Strategies for RAG
  4. 4.Digital Applied, Hybrid Search: BM25, Vector, Reranking (2026)
  5. 5.Long Context vs RAG survey (arXiv 2501.01880)
  6. 6.RAG survey (arXiv 2409.01666)
  7. 7.Microsoft Research, GraphRAG: Unlocking LLM discovery on narrative private data
  8. 8.GraphRAG evaluation (arXiv 2408.08921)
  9. 9.RAGAS, Available Metrics
  10. 10.Confident AI, RAG Evaluation Metrics