Final Project: Build Your Own Mini RAG Pipeline
Every piece from this course now exists on its own: collecting documents, chunking, embedding, storing vectors, embedding a query, retrieving, augmenting, and generating an answer. This final project assembles all of it into one complete, working RAG pipeline.
Requirements
Your finished rag_pipeline.py should satisfy every one of these:
- Collect at least 3 source "documents" as plain strings with a bit of metadata (
raw_documents). - Chunk every document with
chunk_text(), tuningchunk_size/overlapfor your content. - Embed every chunk (
toy_embed(), or a real embedding model, see stretch goals) and store it in aVectorStorealong with its source metadata. - Accept a natural-language query and embed it with the exact same embedding function used for the chunks.
- Retrieve the top-K most similar chunks with
retrieve()/cosine_similarity(). - Build an augmented prompt with
build_prompt()that includes the retrieved context and instructs the model to answer only from it. - Feed the prompt to an LLM (
generate_answer(), a real OpenAI or OpenRouter call) and print the grounded answer.
Bringing every earlier lesson's code together in order (collect → chunk → embed → store → query → retrieve → augment → generate) is the whole pipeline:
def run_pipeline(query, raw_documents, top_k=2):
# 1-4: build the knowledge base
store = VectorStore()
for doc in raw_documents:
for chunk in chunk_text(doc['text']):
store.add(chunk, toy_embed(chunk), metadata={'source': doc['source']})
# 5: embed the query
query_vector = toy_embed(query)
# 6: retrieve
retrieved = retrieve(store, query_vector, top_k=top_k)
# 7: augment
prompt = build_prompt(query, retrieved)
# 8: generate (needs a real API key, see the LLM Response lesson)
return generate_answer(prompt)
print(run_pipeline('How do I reset my password?', raw_documents))
Stretch goals
- Swap
toy_embed()for a real embedding model (OpenAI'stext-embedding-3-small, or a local model via thesentence-transformerspackage) for genuinely semantic, not just word-overlap, retrieval. - Swap the in-memory
VectorStorefor a real vector database like FAISS (runs locally, no account needed) or Pinecone. - Add source citations to the final answer, e.g. "According to faq.md: ...", using each retrieved chunk's
metadata. - Try a smarter chunking strategy, split on paragraphs or sentences instead of a fixed word count, and compare retrieval quality.
- Add a simple cache so an identical query doesn't re-embed or re-call the LLM twice.
Submit a link to your finished project (a repo or gist) below, an instructor will review it before you can mark this lesson complete.