Skip to content

All lessons

Area 02 // RAGLesson 32 / 14016 min read

What RAG is: the whole pipeline

Retrieval-augmented generation (RAG) means finding the most relevant pieces of your own documents for each question and putting them into the prompt, so the model answers from your data instead of from memory.

Think of it like this

Analogy

An open-book exam. A student who has to answer from memory may get details wrong or make things up. Give them the textbook and a good index, and they find the right page, read it, and answer with a page reference.

RAG is the open-book exam for a language model: retrieve the right pages, then generate the answer from them.

The problem it solves

Models only know what was in their training data, up to a cut-off date. They've never seen your company's policies, product docs, contracts or yesterday's support tickets. Ask about them and the model either refuses or, worse, hallucinates a confident answer.

You can't retrain a model every time a document changes, and you can't paste ten thousand documents into every prompt. You need a way to give the model the few paragraphs that matter, for each question, at the moment it's asked.

How it works: the RAG pipeline end to end

RAG has two halves: an offline ingestion pipeline that prepares your documents, and an online query pipeline that runs for each question.

Offline: ingestion (runs when documents are added or change)

  1. Load documents from where they live: PDFs, web pages, Google Drive, Notion, a database, support tickets.
  2. Parse them into clean text with structure (headings, tables, page numbers) (document parsing).
  3. Chunk the text into pieces of a few hundred tokens, each a self-contained idea (chunking).
  4. Embed each chunk with an embedding model, turning it into a vector of meaning (embeddings).
  5. Store the vectors with their text and metadata (source, date, owner, permissions) in a vector database or a search engine.

Online: query (runs for every question)

  1. Embed the question with the same embedding model.
  2. Retrieve the most similar chunks (often with keyword search too: hybrid search), filtered by metadata and the user's permissions.
  3. Rerank the candidates with a more accurate model and keep the best few (reranking).
  4. Build the prompt: instructions ("answer only from the sources, cite them, say if unknown") + the chunks + the question.
  5. Generate the answer with the LLM, with grounding in the sources.
  6. Cite and check: show which sources were used and verify the citations (citations).
Architecture
Loading diagram…
Ingestion (top) prepares the index once; every question runs the query path (bottom).
  • Documents to Parse + chunk
  • Parse + chunk to Embed chunks
  • Embed chunks to Vector DB
  • User question to Embed question
  • Embed question to Retrieve + rerank
  • Vector DB to Retrieve + rerank: top chunks
  • Retrieve + rerank to LLM

How it works: long context vs RAG

As of November 2026 many models accept around 1M tokens, so "just paste everything in" is sometimes a real option. Choose with these questions:

  1. How big is the knowledge? A few documents or one long contract (under a few hundred thousand tokens): long context can work. Thousands of documents: RAG.
  2. How often does it change? Long context needs you to resend the latest version anyway; RAG updates one chunk when one paragraph changes.
  3. How many questions per document? Many questions about the same document → long context plus prompt caching is attractive.
  4. Who may see what? Per-user permissions are much easier to enforce at retrieval time (access control in RAG).
  5. Cost and latency? Sending 500K tokens on every question is slow and expensive; RAG sends a few thousand.
  6. Quality? Very long contexts can bury the relevant part (lost in the middle); good retrieval puts the right text front and centre.

Many systems combine both: retrieve generously (say 20–50 chunks or whole sections) into a large context window.

Loading the playground…

See it in code

Install
pip install scikit-learn
Needs
Python 3.10+. Runs offline; TF-IDF stands in for an embedding model so you can see every step.

All six steps of a working (tiny) RAG pipeline. The final prompt is what you'd send to the LLM.

tiny_rag.py
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity
 
# 1) INGEST: your documents (in real life: PDFs, web pages, tickets…)
docs = {
    "refunds.md": "Refunds are available within 30 days. Opened software cannot be refunded.",
    "shipping.md": "Standard shipping takes 3-5 working days. Express shipping takes 1 day.",
    "warranty.md": "All laptops have a 2-year warranty covering hardware faults.",
}
# 2) CHUNK: split into small pieces (here: one sentence each)
chunks = [(name, s.strip() + ".") for name, text in docs.items() for s in text.split(".") if s.strip()]
 
# 3) EMBED + 4) STORE: turn every chunk into a vector (TF-IDF here; an embedding model in real life)
vectorizer = TfidfVectorizer().fit([c for _, c in chunks])
index = vectorizer.transform([c for _, c in chunks])
 
# 5) RETRIEVE: embed the question the same way and take the most similar chunks
question = "How long does express shipping take?"
scores = cosine_similarity(vectorizer.transform([question]), index)[0]
top = scores.argsort()[::-1][:2]
 
# 6) GENERATE: put the retrieved chunks into the prompt for the LLM
context = "\n".join(f"[{i + 1}] ({chunks[j][0]}) {chunks[j][1]}" for i, j in enumerate(top))
prompt = f"Answer using only the sources below and cite them.\n\n{context}\n\nQuestion: {question}"
print(prompt)
Output
Answer using only the sources below and cite them.
 
[1] (shipping.md) Express shipping takes 1 day.
[2] (shipping.md) Standard shipping takes 3-5 working days.
 
Question: How long does express shipping take?

Swap TF-IDF for a real embedding model, the list for a vector database, and add one LLM call, and this is a production RAG system's skeleton. The capstone builds exactly that.

A real example

Example

An HR assistant that knows the company handbook

A 2,000-person company has a 300-page employee handbook, 80 policy documents and different rules per country. Employees ask HR the same questions all day.

The team builds RAG: policies are parsed and chunked by section, tagged with country and last-updated date, embedded and stored. When someone asks "how much parental leave do I get?", the system filters to their country, retrieves the relevant sections, and the model answers with citations to the exact policy paragraphs, or says "I couldn't find this, contact HR". When a policy changes, only that document is re-ingested; the assistant uses the new version within minutes. HR tickets for policy questions dropped by half.

The easy way

Start here

Start with the snippet above, then upgrade one piece at a time: a real embedding model, a vector database (pgvector or Chroma), a real LLM call with "answer only from sources and cite". Build a list of 30 real questions with the documents that answer them, and check retrieval first.

When you grow: the production setup

Production RAG adds: robust parsing for PDFs and tables, incremental ingestion with change detection, hybrid search, reranking, metadata and permission filters, query rewriting, citations with verification, caching, guardrails, and an eval suite that measures retrieval (Recall@k, MRR) and generation (faithfulness, relevance) separately (RAG evals).

Trade-offs

What you gain

  • Gives models private, up-to-date and large knowledge without retraining.
  • Answers can cite sources, so users can verify them.
  • Knowledge updates are instant: change a document, re-index it.

What it costs you

  • More moving parts: parsing, chunking, embeddings, an index, retrieval tuning.
  • Quality depends heavily on retrieval; bad chunks mean bad answers.
  • Adds latency and cost per question (embedding, search, longer prompts).

When not to use it

  • The knowledge is small and stable enough to fit comfortably in the prompt (use long context with caching).
  • The task needs behaviour or style changes rather than knowledge (fine-tuning).
  • Answers must be computed from structured data (use SQL or tools instead of text search).

Common mistakes

  • Blaming the LLM when the real problem is that retrieval returned the wrong chunks.
  • Skipping the "answer only from sources / say if unknown" instruction.
  • Indexing messy, unparsed text (navigation menus, headers, broken tables).
  • Ignoring permissions, so users can retrieve documents they shouldn't see.
  • Never re-indexing, so the bot answers from last year's policy.

Interview questions

Try answering out loud first, then open the model answer.

Explain RAG end to end.

Model answer

Offline, documents are loaded, parsed into clean text, split into chunks, embedded with an embedding model and stored with metadata in a vector index. At query time, the question is (optionally rewritten and) embedded, the most similar chunks are retrieved, often combined with keyword search, filtered by metadata and permissions, reranked, and inserted into a prompt that instructs the LLM to answer only from them with citations. The answer is returned with sources, and both retrieval and generation are evaluated.

When would you use long context instead of RAG?

Model answer

When the relevant material is small to moderate (one or a few documents), mostly static, asked about repeatedly (so prompt caching amortises it), doesn't need per-user filtering, and the latency and cost of sending it are acceptable. RAG wins for large or fast-changing corpora, permissioned data, tight cost or latency budgets, and when you need precise citations. Hybrids retrieve large sections into a long context.

Your RAG system gives wrong answers. How do you debug it?

Model answer

Separate retrieval from generation. For failing questions, inspect retrieved chunks: was the right information in the index at all (parsing, chunking, freshness), and was it retrieved in the top k (embeddings, hybrid search, query rewriting, filters)? If retrieval was right, check the prompt and model: instructions to stay grounded, context ordering, too many irrelevant chunks, citation behaviour. Build a labelled eval set and measure Recall@k and faithfulness to track fixes.

Quiz

Pick an answer to see whether it’s right and why.

  1. 01What problem does RAG solve?
  2. 02Which steps happen offline, before any user asks a question?
  3. 03A RAG bot gives a wrong answer. What should you check first?
  4. 04Why not just paste all your documents into a 1M-token context window every time?
  5. 05What does "augmented" refer to in retrieval-augmented generation?
  6. 06Which statement about RAG vs fine-tuning is right?

0 of 6 answered

Key terms

RAG (retrieval-augmented generation)
Fetching relevant documents for a question and adding them to the prompt, so the model answers from your data.
Chunk
A small piece of a document (often a few hundred tokens) that is embedded, stored and retrieved as one unit.
Embedding
A vector of numbers that represents the meaning of a piece of text (or an image), so that similar meanings get similar vectors.
Vector database
A database that stores embeddings with their text and metadata and quickly finds the ones nearest to a query vector.
Retrieval
Finding the pieces of stored information most relevant to a question, for example by keyword or vector search.
Grounding
Giving the model trusted source material and instructing it to answer only from it, so answers are based on facts rather than guesses.
Context window
The maximum number of tokens a model can consider in one request, counting both the input and the generated output.

Before and after

Progress is saved in this browser only.