9 · A full RAG pipeline
Put it all together: ingest docs → chunk → embed → index → retrieve → build a grounded prompt. One small class wires the whole flow and prints the exact messages a real LLM would receive.
A RAG pipeline has two phases. INGEST (offline, once per document): load → chunk → embed → store in an index. QUERY (online, per request): embed the question → retrieve top-k chunks → assemble a grounded messages list → call the model. Everything you've learned this chapter is one stage of this assembly line.
Without this:
Without seeing the whole pipeline, the pieces stay disconnected facts. Wired together, you can reason about where a bad answer came from — wrong chunking, missed retrieval, or a sloppy prompt — and fix the right stage.
Now we connect every stage of the chapter into one pipeline. A RAG system has two phases:
Ingest (done offline, once per document, when data changes):
load documents → chunk → embed each chunk → store (chunk, vector) in an index
Query (done online, on every user request):
embed the question → retrieve the top-k nearest chunks → build a grounded prompt → call the model
The output of the query phase is a messages list — the exact same [{role, content}, ...] shape from lesson 1, except now the user turn is wrapped with retrieved context and a "use only this context" instruction. That messages list is the whole point: it's what a real LLM receives.
Below, a tiny RAGPipeline class ties chunking, a deterministic embed(), an in-memory index, retrieval, and prompt assembly together. We ingest a few short docs, ask a question, and print the assembled messages. Where a real system would now call the model, our pipeline stops and shows you the prompt — because building that prompt correctly is the engineering you control.
Python (in browser)
RAGPipeline: ingest (chunk→embed→store), then query (embed→retrieve→assemble). The printed messages list is the grounded prompt a real model would consume.
Python runs entirely in your browser via Pyodide (~6 MB on first Run, cached after).
In production each stage is a library component, but the assembly line is identical: a loader reads files, a splitter chunks, a vector store embeds + indexes, a retriever fetches top-k, and a chain stuffs the chunks into a prompt and calls the model. Read the LangChain version below — map each line back to a method on our RAGPipeline.
LangChain's loader → splitter → vectorstore → retriever → chain is exactly our RAGPipeline, one library component per stage.
In a RAG pipeline, which steps belong to the OFFLINE ingest phase rather than the per-request query phase?
- RAG has two phases: ingest (offline — load → chunk → embed → index) and query (online — embed question → retrieve → build prompt → generate).
- The query phase's output is a grounded messages list — the same {role, content} shape from lesson 1, with retrieved context wrapped around the user's question.
- Each chapter stage is one pipeline component (loader, splitter, vector store, retriever, chain); knowing the stages lets you debug a bad answer at the right step.
Every 'chat with your docs' product is this exact pipeline; LangChain and LlamaIndex are mostly ergonomic wrappers over loader → splitter → vector store → retriever → chain.
If you remove it: Without an end-to-end mental model you tune random pieces in isolation; with it, a wrong answer points you at a specific failing stage — bad chunks, missed retrieval, or a weak prompt.