The Retriever Component in RAG: Vector Databases and Semantic Search
Learning Objectives: By the end of this lesson, you will be able to:
- Explain the role of the retriever in Retrieval Augmented Generation (RAG)
- Describe and implement document chunking, embedding, and vector database indexing
- Perform semantic search and evaluate retrieval quality
1. Welcome and Introduction (5 minutes)
Icebreaker Activity
Have you ever tried to search for information in a large document or website? What made it easy or difficult to find what you needed?
Lesson Overview
- Duration: Approximately 2.5 hours including all exercises (or 60–90 minutes when selected activities are assigned)
- Prerequisites: Familiarity with LLMs, RAG basics, and Python programming
- Materials Needed: Python environment, Hugging Face Transformers, FAISS or ChromaDB, sample text documents
2. Learning Objectives and Session Outline (5 minutes)
What We’ll Cover Today:
- Document preprocessing and chunking strategies
- Embedding models for semantic search
- Vector databases: FAISS, ChromaDB, Pinecone, etc.
- Performing similarity search and evaluating retrieval
- Hands-on: Building a simple retriever pipeline
Success Criteria:
By the end of this session, you should be able to preprocess documents, generate embeddings, index them in a vector database, and perform semantic search.
3. Foundation Knowledge (15-20 minutes)
Core Concepts
Why Chunk and Embed Documents?
LLMs have limited context windows. To retrieve relevant information, documents are split into manageable chunks, each converted into a vector (embedding) that captures its meaning. This enables fast, semantic search over large corpora.
Real-World Analogy: Imagine a library where every paragraph is summarized on a card. To answer a question, you search the cards for the most relevant summaries, not the whole books.
Why This Matters:
- Enables efficient search over large datasets
- Improves retrieval relevance and LLM grounding
- Supports up-to-date and domain-specific knowledge
Embedding Models
- Convert text chunks into high-dimensional vectors
- Examples: Sentence-BERT, OpenAI Ada, MiniLM
- Similarity between vectors reflects semantic similarity
Vector Databases
- Store and index embeddings for fast retrieval
- Examples: FAISS (local), Pinecone, ChromaDB, Weaviate, Milvus
- Support similarity search (cosine, dot product, ANN)
Key Terminology
- Chunking: Splitting documents into smaller pieces for embedding
- Embedding: Numeric vector representation of text
- Vector Database: Specialized database for storing and searching embeddings
- Semantic Search: Retrieval based on meaning, not just keywords
4. Detailed Explanation and Examples (25-30 minutes)
Document Preprocessing and Chunking
- Fixed-size chunks (e.g., 512 tokens)
- Semantic or recursive chunking (split at sentence/paragraph boundaries)
- Trade-off: Larger chunks = more context, but risk of context window overflow
Embedding Generation
- Use pre-trained models to convert text to vectors
- Normalize vectors for cosine similarity
Indexing and Similarity Search
- Index embeddings in a vector database
- Query: Embed the question, search for nearest neighbors
- Retrieve top-k most similar chunks
Practical Applications
- Q&A over large document sets
- Knowledge management and search
- Chatbots with access to private or up-to-date data
Common Misconceptions
- Misconception: Keyword search is enough Reality: Semantic search finds relevant info even if keywords differ
- Misconception: All vector databases are the same Reality: They differ in scalability, speed, and features
5. Live Coding Demonstration (20-25 minutes)
Example 1: Chunking and Embedding Documents
from sentence_transformers import SentenceTransformer
# Sample documents
docs = [
"The Eiffel Tower is in Paris.",
"Mount Everest is the tallest mountain.",
"The capital of Japan is Tokyo."
]
# Chunking (trivial here, but use NLTK or spaCy for real docs)
chunks = docs
# Embedding
model = SentenceTransformer('all-MiniLM-L6-v2')
embeddings = model.encode(chunks, normalize_embeddings=True)
Example 2: Indexing with FAISS
import faiss
import numpy as np
index = faiss.IndexFlatIP(embeddings.shape[1]) # Inner product (cosine if normalized)
index.add(np.array(embeddings))
# Query
query = "Where is the Eiffel Tower?"
q_emb = model.encode([query], normalize_embeddings=True)
D, I = index.search(np.array(q_emb), k=2)
print("Top results:", [chunks[i] for i in I[0]])
Example 3: Using ChromaDB (Optional)
import chromadb
from chromadb.utils import embedding_functions
chroma_client = chromadb.Client()
collection = chroma_client.create_collection("docs")
ids = [f"chunk-{i}" for i in range(len(chunks))]
collection.add(ids=ids, documents=chunks, embeddings=embeddings.tolist())
# Because vectors were supplied explicitly at indexing time, use the same
# SentenceTransformer to embed queries rather than Chroma's default function.
query_embedding = model.encode([query], normalize_embeddings=True)
results = collection.query(query_embeddings=query_embedding.tolist(), n_results=2)
print(results)
Chunk size and overlap are retrieval hyperparameters, not universal constants; tune them on held-out queries. Embedding similarity is a useful approximation of relevance, so production systems often add metadata filters or reranking.
Debugging Demonstration
Show a common error: inconsistent chunk sizes
# Problem: Some chunks are too large for the LLM context window
# Solution: Use consistent, manageable chunk sizes (e.g., 256-512 tokens)
6. Hands-On Practice (30-40 minutes)
Exercise 1: Basic Practice (10 minutes)
Objective: Chunk and embed a set of documents
Instructions:
- Create a list of 5-10 short text passages
- Use SentenceTransformer to generate embeddings
- Print the shape of the embeddings array
Starter Code:
from sentence_transformers import SentenceTransformer
docs = [
"Python is a popular programming language.",
"The sun rises in the east.",
# ...more documents...
]
model = SentenceTransformer('all-MiniLM-L6-v2')
# Your embedding code here
Solution:
embeddings = model.encode(docs, normalize_embeddings=True)
print(embeddings.shape)
Exercise 2: Intermediate Challenge (15 minutes)
Objective: Build a simple FAISS index and perform semantic search
Requirements:
- Index the embeddings
- Query with a new question
- Print the top-2 most relevant passages
Hints:
- Use FAISS IndexFlatIP for cosine similarity
- Normalize embeddings
Exercise 3: Creative Application (15 minutes)
Objective: Experiment with chunking strategies
Challenge:
- Try splitting a long document into sentences, paragraphs, or fixed token chunks
- Compare retrieval results for different chunking methods
Extension Ideas:
- Use a different embedding model (e.g., OpenAI Ada)
- Try ChromaDB or Pinecone for indexing
7. Common Pitfalls and Troubleshooting (10 minutes)
Frequent Mistakes
- Problem: Chunks too large for LLM context Cause: Not splitting documents properly Solution: Use sentence/paragraph boundaries or fixed token sizes
- Problem: Poor retrieval quality Cause: Low-quality embeddings or bad chunking Solution: Use strong embedding models and experiment with chunk sizes
Debugging Tips
- Visualize chunk sizes and embedding distributions
- Test retrieval with known queries
- Monitor retrieval speed and accuracy
8. Best Practices and Professional Tips (5 minutes)
Industry Standards
- Use semantic chunking for better context
- Normalize embeddings for cosine similarity
- Choose vector database based on scale and requirements
Next Steps in Your Learning Journey
- Integrate retriever with LLM generator (full RAG pipeline)
- Explore advanced retrieval (re-ranking, hybrid search)
- Read about vector database scaling and deployment
9. Summary and Review (5 minutes)
Key Takeaways
- The retriever is essential for grounding LLMs in external knowledge
- Chunking, embedding, and indexing enable fast, semantic search
- Retrieval quality depends on chunking, embeddings, and database choice
Quick Review Questions
- Why do we chunk documents for RAG?
- What is the purpose of a vector database?
- How does semantic search differ from keyword search?
For Instructors
Teaching Tips
- Demonstrate chunking and embedding visually
- Encourage students to experiment with chunk sizes and models
- Address confusion about vector database setup
Assessment Ideas
- Quiz: Identify chunking and embedding steps in code
- Project: Build a retriever for a custom document set
- Peer review: Compare retrieval quality for different strategies
Adaptation Notes
- For beginners: Focus on chunking and basic FAISS usage
- For advanced: Try ChromaDB, Pinecone, or hybrid retrieval
- Online: Provide Colab notebooks; In-person: Live coding demos