Lesson 08 RAG Basics
Theme:
Lesson 08 · Slide 1

RAG Basics

Retrieval-Augmented Generation lets you ground LLM answers in your own data — no fine-tuning required. This lesson covers embeddings, vector stores, and the core RAG pipeline.

Learning Objectives

Lesson 08 · Slide 2

Why RAG?

LLMs have three fundamental limitations that RAG addresses directly:

The Problems

  • Knowledge cutoff — models only know what was in their training data
  • No private data — your company docs, databases, and notes are invisible to the model
  • Hallucination — without grounding, models confidently fabricate facts

RAG Solution

  • Retrieve relevant documents at query time — always up to date
  • Inject private data into the prompt — no training needed
  • Ground answers in retrieved evidence — reduces hallucination

RAG is the most cost-effective way to give an LLM access to domain-specific knowledge.

Lesson 08 · Slide 3

Embedding Models

An embedding model converts text into a dense numeric vector that captures semantic meaning. Similar texts produce similar vectors.

from sentence_transformers import SentenceTransformer

model = SentenceTransformer("all-MiniLM-L6-v2")
embeddings = model.encode(["Python is great", "I love Python programming"])
# embeddings.shape == (2, 384)

Popular models: all-MiniLM-L6-v2 (fast, 384d), all-mpnet-base-v2 (better quality, 768d), OpenAI text-embedding-3-small (API-based, 1536d).

Lesson 08 · Slide 4

Vector Stores — ChromaDB

A vector store indexes embeddings for fast similarity search. ChromaDB is a lightweight, local-first option perfect for prototyping.

import chromadb

chroma_client = chromadb.Client()  # in-memory
collection = chroma_client.create_collection("my_docs")

# Add documents (ChromaDB can auto-embed with a configured model)
collection.add(
    ids=["doc1", "doc2"],
    documents=["Python pathlib guide", "JavaScript async patterns"],
    metadatas=[{"topic": "python"}, {"topic": "javascript"}]
)

# Query
results = collection.query(query_texts=["file handling in Python"], n_results=2)
print(results["documents"])

Pattern: Store → Query → Get top-k documents → Inject into prompt.

Lesson 08 · Slide 5

The RAG Pipeline

The complete pipeline has two phases: indexing (offline) and querying (online).

Indexing Phase

  1. Chunk — split documents into retrievable units (256–512 tokens)
  2. Embed — convert each chunk to a vector
  3. Store — index vectors + metadata in a vector store

Query Phase

  1. Embed query — same model as indexing
  2. Retrieve — find top-k similar chunks
  3. Inject — place retrieved chunks into the prompt as context
  4. Generate — Claude answers grounded in the retrieved context

Critical rule: Always use the same embedding model for indexing and querying. Mixing models produces meaningless similarity scores.

Lesson 08 · Slide 6

Chunking for Retrieval

How you split documents directly impacts retrieval quality. Chunks that are too large dilute relevance; chunks that are too small lose context.

Chunk SizeProsCons
128 tokensPrecise retrievalMay miss surrounding context
256–512 tokensGood balance of precision and contextStandard choice for most use cases
1024+ tokensRich context per chunkDiluted relevance; fewer chunks fit in context

Overlap Matters

Adding 10–20% overlap between consecutive chunks prevents information from being split across chunk boundaries. A sentence that spans two chunks would otherwise be lost to both.

# Simple chunking with overlap
def chunk_text(text, chunk_size=500, overlap=50):
    words = text.split()
    chunks = []
    for i in range(0, len(words), chunk_size - overlap):
        chunk = " ".join(words[i:i + chunk_size])
        if chunk:
            chunks.append(chunk)
    return chunks
Lesson 08 · Slide 7

Demo

Live demonstration: build a RAG system over 10 Python documentation files.

Demo Steps

  1. Load 10 sample documents from demo/sample_docs/
  2. Embed using all-MiniLM-L6-v2 and store in ChromaDB
  3. Ask a question: "How do I read a JSON file in Python?"
  4. Show retrieved chunks and their similarity scores
  5. Pass retrieved context to Claude and get a grounded answer
  6. Compare: answer with RAG vs answer without RAG
Notes: Emphasise the difference in answer quality when Claude has relevant context vs when it must rely on training data alone. Show the metadata filtering capability.
Lesson 08 · Slide 8

Lab & Homework

Lab Exercises

  1. Embed & Store — load 10 sample docs, embed with sentence-transformers, store in ChromaDB
  2. RAG Answer — implement rag_answer(question, collection, top_k=3)
  3. Metadata Filtering — add topic metadata and compare filtered vs unfiltered retrieval

Homework Tasks

  1. RAG over your own documents — 10 questions, rate quality 1–5
  2. Chunk size experiment: 128 / 256 / 512 tokens
  3. Add date metadata filtering
1 / ?