Handbooks / RAG & AI Agents / Chapter 1

The RAG Pipeline

7 pages · ~5 min✓ Reviewed

Start here. Next up: Chunking and Retrieval.

RAG & AI AgentsPage 1

Why RAG and the Mental Model

1. What RAG Is

  • RAG = retrieve text at query time, add it to the prompt
  • Model stays frozen; knowledge lives outside it
  • Gap 1: stale knowledge (training cutoff)
  • Gap 2: private data it never saw
  • Gap 3: hallucination with no source to check

2. Two Pipelines

Offline: indexing
  1. 1Ingest
  2. 2Chunk
  3. 3Embed
  4. 4Index
Online: query
  1. 1Embed query
  2. 2Retrieve
  3. 3Rerank
  4. 4Assemble prompt
  5. 5Generate + cite

3. Pick the Tool

RAGFine-tuningLong context
Best forFresh or private facts, citationsStyle, format, behaviourSmall, static corpus
Cost per queryLowLowHigh
Weak spotRetrieval missesFacts go staleRecall drops in the middle
Remember

Fine-tune the behaviour, retrieve the facts.

4. Interview Point

  • Why not fine-tune facts? They go stale, give no citations, and cost a retrain to update
  • Two pipelines? Offline indexing; online query
  • Skip RAG when? The corpus is small and static, so it fits in context
RAG & AI AgentsPage 2

Ingestion and Chunking

1. Ingestion

  1. LoadPDF, HTML, DB rows
  2. Parseclean text
  3. Stripheaders, footers, nav
  4. Tagmetadata
  • Metadata on every document: source, title, page, date, ACL

2. Chunking

  • Too big: diluted embedding
  • Too small: lost context
  • Start at 200-500 tokens with 10-20% overlap
StrategyStrengthCatch
Fixed-sizefastcuts mid-sentence
Recursivegood defaultparagraph, then sentence
Structure-awarebest for docsneeds headings or code blocks
Semanticfollows meaningcostly

3. Split on Headings

  • Prepend the section title so an orphan paragraph keeps context
python
for sec in split_on_headings(doc):
    for part in cap_tokens(sec.text, 400):
        chunks.append({
            "text": sec.title + "\n" + part,
            **sec.meta})

pseudocode: 400-token cap per chunk

RAG & AI AgentsPage 3

Embeddings and Indexing

1. Embeddings

  • Embedding model: text → fixed-length vector, similar meaning lands close
  • Compare by cosine or dot product; equal when normalised
  • Same model for chunks and queries
  • Model change → re-embed corpus
  • Check max input tokens: no silent truncation

2. Search and ANN

  • ANN trades a little recall for speed
Flat (exact)HNSW (ANN)IVF (ANN)
MethodCompare allGraph hopsNearest clusters
RecallPerfectSlightly lowerSlightly lower
SpeedO(N)FastFast

3. Vector Stores

StoreKindUse when
pgvectorPostgres extensionYou already run Postgres
FAISSIn-memory libraryLocal, in-process
Pinecone, Qdrant, Weaviate, OpenSearchManaged or dedicatedScale and filtering
Store beside vector

Keep chunk text and metadata next to each vector.

4. Interview Point

  • Same model? Different models, different spaces: distances mean nothing
  • HNSW? Graph hops skip most vectors: faster, may miss a true neighbour
  • Flat enough? Small corpus: an O(N) scan is fast
RAG & AI AgentsPage 4

Retrieval and Reranking

1. Search and Fusion

  • Embed the query, fetch top-k chunks (k often 5-20)
  • Similarity threshold drops weak matches
  • Dense = meaning; BM25 = IDs, names, error codes
  • Merge both lists with RRF: score = Σ 1/(60 + rank)

2. Rerank

  1. Top 50bi-encoder, fast
  2. Rescorecross-encoder
  3. Top 5precise
Bi-encoderCross-encoder
Readsquery, chunk apartquery + chunk together
Latencylowhigher
Precisionlowerhigher

3. Filters and Rewriting

  • Metadata filters at query time: tenant, date, doc type, permissions
  • Query rewriting and HyDE help vague or multi-turn questions
ACL in retrieval

Filter before the prompt so users never see forbidden chunks.

4. Interview Point

  • Why BM25 plus vectors? Vectors miss exact IDs; BM25 misses meaning.
  • Cross-encoder edge? Reads query and chunk jointly, so scores are sharper.
  • Measure quality? recall@k (right chunk in top-k), MRR (mean of 1/rank of the first right chunk).
RAG & AI AgentsPage 5

Prompt Assembly and Cited Generation

1. Prompt Layout

  1. System rulesanswer from context only
  2. Chunks [1] [2]each with source ID
  3. Questionuser query
  • Rule: answer only from the context
  • Answer missing → say "I don't know"
  • Top-k must fit the window, room left for the answer
  • Dedupe near-identical chunks; order by relevance
  • Best chunks first and last; middle recalled worst

2. Citations

  1. 1Tag chunks[1], [2] with source + page
  2. 2Cite inlinemodel writes IDs
  3. 3Check IDsmust exist in retrieved set
  4. 4Map to linksunverified = failure

3. Mistakes and Evaluation

  • Chunks too large or too small
  • No reranking
  • Stuffing too much context
  • No refusal rule
  • Index not versioned
  • Never evaluating
Evaluate separately

Retrieval: recall@k. Generation: faithfulness and answer relevance.

RAG & AI AgentsPage 6

RAG Cheat Sheet

1. Pipeline

PathStages
Offlineingest + metadata → chunk → embed → index
Onlineembed query → hybrid retrieve → rerank → assemble prompt → generate + cite

2. Defaults and Debug

  • Chunk 200-500 tokens, 10-20% overlap
  • Retrieve top 20-50, rerank to 5
  • Same embedding model for index and query; cosine similarity
  • HNSW index for scale
  1. In index?chunk exists
  2. In top-k?retrieved
  3. In prompt?reaches LLM
  4. Follows context?grounded
Debug rule

Fix the earliest failing stage first.

3. Quality Checklist

  • Hybrid search + reranker
  • Metadata and ACL filters
  • Refusal instruction, verified citations
  • Index versioning
  • Eval set: recall@k, faithfulness

4. Interview Point

  • 60 seconds: index the docs offline; online embed, retrieve, rerank, prompt, cite
  • Top 3 levers: hybrid search, reranking, chunking
  • Fresh index: re-ingest and re-embed changed docs by doc ID, delete removed ones
  • Model change: bump the index version, re-embed everything
RAG & AI AgentsPage 7

Check yourself

You switch to a new embedding model and re-embed only the new chunks. Queries use the new model too. Old documents stop appearing. Why?
  • Old vectors live in a different vector space, so distances to new query vectors mean nothing.
  • Re-embed the whole corpus whenever the model changes.
RRF with 60: doc A is rank 1 dense and rank 3 BM25. Doc B is rank 2 in both. Which ranks higher?
  • A: 1/61 + 1/63 ≈ 0.03227. B: 2/62 ≈ 0.03226.
  • A wins, barely.
The answer cites [4], but only 3 chunks were retrieved. What is wrong, and what is the fix?
  • The citation is invented, so the answer is unverified.
  • Check that every cited ID is in the retrieved set. Treat a miss as a failure.