Lesson 08 RAG Basics
Theme:

Lab Guide — RAG Basics

Three exercises building an end-to-end RAG pipeline with ChromaDB and Claude.

Setup: Open lab.pdf in Jupyter. Run the setup cell first — it installs/imports sentence-transformers, chromadb, and the Anthropic client. The 10 sample documents are in demo/sample_docs/.

📥 Lab Notebooks

⬇ lab.pdf ⬇ lab_answer.pdf

📥 Demo Files

⬇ doc_01_pathlib.txt ⬇ doc_02_collections.txt ⬇ doc_03_itertools.txt ⬇ doc_04_functools.txt ⬇ doc_05_datetime.txt ⬇ doc_06_json.txt ⬇ doc_07_os.txt ⬇ doc_08_sys.txt ⬇ doc_09_logging.txt ⬇ doc_10_typing.txt

Exercise 1 — Embed and Store Documents

EX 1

Load, embed, and index 10 documents in ChromaDB

The demo/sample_docs/ directory contains 10 text files about Python standard library modules. Your task:

  1. Load all 10 .txt files into a list of strings
  2. Embed them using sentence-transformers model all-MiniLM-L6-v2
  3. Create a ChromaDB collection and add the documents with their embeddings
  4. Add metadata: topic="python" for docs 1-5, topic="stdlib" for docs 6-10

Test your implementation

# Verify: query the collection
results = collection.query(query_texts=["file path handling"], n_results=3)
print(results["documents"][0])
# Should return pathlib doc as top result

Checkpoint: Collection contains 10 documents. Query returns relevant results.

Exercise 2 — RAG Answer Function

EX 2

Implement rag_answer(question, collection, top_k=3)

Build a function that:

  1. Embeds the question using the same model
  2. Retrieves the top-k most similar documents from the collection
  3. Builds a prompt with the retrieved context
  4. Sends the prompt to Claude and returns the answer

Prompt template

prompt = f"""Use the following context to answer the question.
If the context does not contain enough information, say so.

Context:
{context}

Question: {question}"""

Test your implementation

answer = rag_answer("How do I read a JSON file in Python?", collection)
print(answer)
# Should reference the json module documentation from the retrieved context

answer2 = rag_answer("What is a defaultdict?", collection)
print(answer2)
# Should reference the collections module

Checkpoint: Function returns grounded answers that reference specific information from the retrieved documents.

Exercise 3 — Metadata Filtering

EX 3

Query with metadata filters and compare results

Use ChromaDB's where parameter to filter by topic metadata.

  1. Query for "iteration patterns" with where={"topic": "python"}
  2. Query for the same question without any filter
  3. Compare the retrieved documents — does filtering improve relevance?

Test your implementation

# Filtered query
filtered = collection.query(
    query_texts=["iteration patterns"],
    n_results=3,
    where={"topic": "python"}
)
print("Filtered:", [doc[:50] for doc in filtered["documents"][0]])

# Unfiltered query
unfiltered = collection.query(
    query_texts=["iteration patterns"],
    n_results=3
)
print("Unfiltered:", [doc[:50] for doc in unfiltered["documents"][0]])

Checkpoint: You can observe and document the difference between filtered and unfiltered results.

Tip: If retrieval quality seems poor, try increasing top_k to 5 or adjusting the query phrasing. Embedding models are sensitive to how questions are worded.