RAG: read before answering
How do you give a model your own knowledge without retraining it?
Lesson complete
If you like:
A customer asks an electric bike shop’s chatbot: “How long is the battery warranty?” The answer is in the shop’s manual.
No voice: the lesson advances on its own with subtitles.
The voice for this lesson is being recorded: for now it advances on its own with subtitles.
Review modeComment on this stepI finished the lesson
What you will achieve
- Explain what a RAG system does: prepare the library once (chunk and index) and, with every question, retrieve, build the prompt with sources, and answer with citations.
- Predict which chunks a question retrieves and whether the right one reaches the prompt, given the chunk size and the value of k.
- Recognize the three typical failures (not finding, contradictions, hidden instructions) and measure retrieval with your own questions.
Key ideas
- RAG does not retrain the model: with every question it looks up the chunks of your documents that are most similar and pastes them into the prompt, along with the question.
- It is prepared once (chunk, turn into vectors, index) and, with every question, you retrieve, build the prompt with numbered sources, and answer with citations.
- Chunk size and the number k of chunks pasted are decisions with a cost: you choose them by testing, not by hunch. A reranker can improve the order, but not always.
- Word search fails on paraphrases; embeddings compare meanings and rescue many of them, not all.
- Typical failures: not finding the right chunk, documents that contradict each other, and instructions hidden in the text. Quality depends mostly on retrieval: measure it with your own questions.
What many people believe
Common belief RAG “trains” the model on your documents: after reading them, the model knows them.
What is true The model learns nothing: its weights do not change. With every question the chunks are looked up and pasted into the prompt; if the search does not bring them, the model never sees them.
Check yourself
Four questions. No grade, no account: they just show whether the idea stuck.
Under the hoodFor those who want the math and the code. You do not need it to follow the course.
TF-IDF and cosine similarity
This is how the scene’s word search is computed. First, very common words are removed (“the,” “of,” “and”…) and each word is cut down to its stem in a simple way (“batteries” and “battery” count the same). With that, the lesson’s manual has 228 distinct terms: each chunk is a vector of 228 numbers.
Given chunks, is how many times term appears in chunk , and is how many chunks it appears in. With the variants used in the lesson:
With : “cycles” appears in 1 chunk () and “warranty” in 6 (); that is why “cycles” weighs more. Each vector is normalized, , and the question gets the same treatment with the index’s values. Cosine similarity becomes a dot product:
Weighting by rarity goes back to Karen Spärck Jones (1972): a term that appears in few documents tells them apart better.
BM25, the other word-based score
BM25 (Robertson and Zaragoza, 2009) scores each chunk with a saturating term frequency and a length correction:
with and as values that, according to its authors, work reasonably well in many cases. It is a hard baseline to beat with words alone, and many systems combine it with embeddings (hybrid search).
Embeddings and approximate search
With embeddings (lesson 14) the vector has a few hundred dense numbers and the words do not need to match: cosine similarity compares meanings. Comparing the question with all vectors costs ; with millions of chunks, approximate indexes such as HNSW (Malkov and Yashunin) trade a little exactness for a lot of speed. In the paper that named RAG (Lewis et al., 2020), Wikipedia was cut into 100-word pieces, 21 million in all, indexed with FAISS and HNSW; during training, or were retrieved per question.
Reranking
A dense retriever (bi-encoder), such as DPR (Karpukhin et al., 2020), the one RAG uses, encodes the question and the chunk separately, so chunks are turned into vectors only once. A reranker (cross-encoder) reads the question and the chunk together in one model pass and returns a score: it is finer, but it costs one pass per candidate, so it is only applied to the top of the list. Nogueira and Cho (2019) used BERT to rerank the top 1,000 passages returned by BM25.
In the lesson, the embedding and reranker figures were measured offline (see build-dense.py) with two open models: intfloat/multilingual-e5-small (Wang et al., 2024) and cross-encoder/mmarco-mMiniLMv2-L12-H384-v1, trained on mMARCO (Bonifacio et al., 2021). The reranker is applied to the top 5 candidates.
How retrieval is measured
For each test question you record the right chunk and its position in the ranked list ( if it does not appear). With questions:
On the scene’s 10 questions, with : word search, 7 of 10; embeddings, 9 of 10; embeddings plus reranker, 8 of 10 (in both languages). Ten questions are far too few for general conclusions: the point is the method.
This measures only the first half. The second, whether the answer relies on what was retrieved, is evaluated with test cases and with human review or a model as judge (lesson 34). Ragas (Es et al., 2023) splits it into three measures: faithfulness (what the answer says follows from the context), answer relevance, and context relevance.
Updating without retraining
The RAG paper tested swapping only the index: for 82 world leaders who changed between 2016 and 2018, the model was right 70% of the time with the 2016 Wikipedia index for 2016 leaders, and 68% with the 2018 index for 2018 leaders; with the mismatched index, only 12% and 4%. To update what it knows, you change documents, not weights.
In code
A complete TF-IDF search, with no libraries. It is the same recipe as the lesson, without stemming:
import math, re
from collections import Counter
STOP = {"the", "has", "an", "or", "you", "can", "your", "of", "on", "is", "at", "how", "long"}
def terms(text):
return [w for w in re.findall(r"[a-z0-9]+", text.lower()) if w not in STOP]
chunks = [
"the battery has an 18 month warranty or 500 charge cycles",
"you can cancel your purchase within 30 days of delivery",
"shipping is free on purchases over 1500",
"charge the battery at room temperature",
]
N = len(chunks)
bags = [Counter(terms(c)) for c in chunks]
df = Counter(t for b in bags for t in b)
idf = {t: math.log((N + 1) / (df[t] + 1)) + 1 for t in df}
def vector(bag):
v = {t: (1 + math.log(c)) * idf[t] for t, c in bag.items() if t in idf}
norm = math.sqrt(sum(x * x for x in v.values())) or 1.0
return {t: x / norm for t, x in v.items()}
index = [vector(b) for b in bags]
def search(question, k=2):
q = vector(Counter(terms(question)))
scores = [sum(w * d.get(t, 0.0) for t, w in q.items()) for d in index]
return sorted(enumerate(scores), key=lambda p: -p[1])[:k]
for i, s in search("how long is the battery warranty"):
print(f"{s:.2f} {chunks[i]}")
# 0.51 the battery has an 18 month warranty or 500 charge cycles
# 0.27 charge the battery at room temperature
What comes next
Here the model only reads. In lesson 32 it can also use tools: search, calculate, write. Prompt injection comes back in lesson 35, and full system evaluation in lesson 34.
Decision lens
What this idea means if your job is to decide, not to code.
- RAG gives answers grounded in your data, with sources that can be checked, without retraining: to update what it knows, you change documents, not the model. In the original paper, swapping the 2016 Wikipedia index for the 2018 one was enough to answer about the new world leaders. Ask how the index is updated and how often.
- Quality is decided at retrieval: if the right chunk never reaches the prompt, no model can cite it. Ask for the retrieval hit rate measured on your own questions, not on a demo.
- Govern the documents: version, date, owner, and permissions. Whatever the system can retrieve, it can say: old versions that contradict new ones, and data that not everyone should see.
- All retrieved text deserves limited trust: a review, a web page, or an email can carry hidden instructions. Limit what the system can do with what it reads, and log which sources it used for each answer.
Terms in this lesson
- RAG (retrieval-augmented generation) A technique that, before generating, looks up in a collection of documents the chunks most similar to the question and includes them in the prompt, so the model answers from those sources without being retrained.
- Chunking Cutting documents into pieces, or chunks, that are indexed and retrieved separately. If they are too small, a fact can lose its context; if they are too large, the answer gets diluted.
- Vector database Software that stores vectors together with their text and metadata (source, date), and very quickly finds the ones most similar to a query vector, usually with approximate nearest-neighbor search.
- Retrieval The step that turns the question into a vector, compares it with the index, and fetches the k most similar chunks.
- Grounding Making every claim in the answer rest on a specific, checkable source, cited next to it.
- Reranking A second step that reorders the top search candidates with a finer, slower model that reads the question and each chunk together.
- Vector An ordered list of numbers. In machine learning, each example reaches the model as a vector.
- Embedding A vector of numbers, learned from data, that represents something (a word, a sentence, an image) so that similar things end up close. Each word has a row in an embedding table.
- Cosine similarity The cosine of the angle between two vectors: 1 if they point the same way, 0 if they are perpendicular, −1 if they oppose. It ignores length and measures direction only.
- Semantic search Search by meaning: the query and the documents are turned into vectors and the closest documents are returned, even if they share no words.
- Context window The maximum number of tokens the model can read at once. The system prompt, the conversation, documents, and the answer it is writing all count. Whatever does not fit does not exist for the model.
- System prompt Fixed instructions that whoever builds the app places at the front of the context: role, tone, and rules. The person chatting does not see them, but they ride along and take up room on every turn.
- Lost in the middle An effect measured in several models: they make better use of information at the start or end of a long context than of what sits in the middle.
- Token A piece of text (a word, a word fragment, a symbol, or a basic code) taken from the vocabulary. It is the unit the model reads and generates, and the unit you are billed for.
- Weight (w) In a linear model, the number that multiplies the input: the slope of the line. It tells how much the prediction rises for each unit the input grows.
- Prompt The text used to ask a generative model for something; in an image generator, the description of the desired image.
Full transcript
Sources
- Lewis, P., Perez, E., Piktus, A., Petroni, F., Karpukhin, V., Goyal, N., Küttler, H., Lewis, M., Yih, W., Rocktäschel, T., Riedel, S., Kiela, D. (2020). Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks
- Karpukhin, V., Oğuz, B., Min, S., Lewis, P., Wu, L., Edunov, S., Chen, D., Yih, W. (2020). Dense Passage Retrieval for Open-Domain Question Answering
- Spärck Jones, K. (1972). A statistical interpretation of term specificity and its application in retrieval
- Robertson, S., Zaragoza, H. (2009). The Probabilistic Relevance Framework: BM25 and Beyond
- Malkov, Y. A., Yashunin, D. A. (2016). Efficient and robust approximate nearest neighbor search using Hierarchical Navigable Small World graphs
- Nogueira, R., Cho, K. (2019). Passage Re-ranking with BERT
- Wang, L., Yang, N., Huang, X., Yang, L., Majumder, R., Wei, F. (2024). Multilingual E5 Text Embeddings: A Technical Report
- Bonifacio, L., Jeronymo, V., Abonizio, H. Q., Campiotti, I., Fadaee, M., Lotufo, R., Nogueira, R. (2021). mMARCO: A Multilingual Version of the MS MARCO Passage Ranking Dataset
- Greshake, K., Abdelnabi, S., Mishra, S., Endres, C., Holz, T., Fritz, M. (2023). Not what you’ve signed up for: Compromising Real-World LLM-Integrated Applications with Indirect Prompt Injection
- Es, S., James, J., Espinosa-Anke, L., Schockaert, S. (2023). Ragas: Automated Evaluation of Retrieval Augmented Generation
CommentsThis lesson’s public conversation: questions, facts to check, ideas.
Comments live in GitHub Discussions, in the course’s public repository; writing one requires a GitHub account. They load from giscus.app when you open this section. The course reviewers read them, and if a change is accepted, it is applied in both languages. Open the thread on GitHub