Agentic AI Chapter 7 / 16 · RAG

07 RAG · Retrieval-Augmented Generation

Give the model a library
it can look things up in.

This might be the single most important idea in practical AI today. An LLM only knows what it was trained on — not last week's news, and definitely not your company's private documents. You can't cram 500 GB into a context window. So instead of baking knowledge into the model, you retrieve it the moment you need it. That's RAG.

Indexing Retrieval Generation Chunking Agentic RAG

The problem it solves

Three walls every raw LLM hits.

⏳ A cutoff date

It doesn't know what happened after training. Ask about last week and it guesses.

🔒 No private data

Your internal docs, database, and research files were never in its training set.

📦 A finite window

You can't paste your whole knowledge base into every prompt. It won't fit.

RAG's answer to all three: keep the knowledge outside the model, and pull in just the few relevant pieces at question time — right into the context window, exactly when they're needed.

The pipeline

Index → retrieve → generate.

RAG is three phases. Index your documents once: split them into chunks, turn each chunk into a vector (a numerical fingerprint of its meaning), and store them. Then, per question: retrieve the chunks whose vectors are most similar to the question, and generate an answer with those chunks dropped into the prompt. Press play.

1 Index · once

Turn docs into vectors

Done ahead of time, whenever your documents change.

  • 📄 Gather documents (PDFs, wikis, records)
  • ✂️ Split into small chunks
  • 🔢 Embed each chunk → [0.12, −0.4, …]
  • 🗄️ Store vectors in a vector DB
2 Retrieve · per question

Find the relevant chunks

Similarity search, not keyword matching.

  • Take the user's question
  • 🔢 Embed it the same way
  • 🧲 Find the nearest chunk vectors
  • 📎 Pull the top matches out
3 Generate · per question

Answer, grounded in them

The LLM now has the facts in front of it.

  • 🧩 Inject chunks + question into the prompt
  • 🤖 "Answer using this context"
  • Grounded, current, sourced answer
  • 🚫 No hallucinating what it doesn't know
idle
A real question
"What's our refund policy for annual plans?"
Retrieved chunks (most similar first)
…annual plans are refundable within 30 days0.91 …refunds are prorated after 30 days… 0.88 …contact billing to request a refund… 0.83
Grounded answer
Annual plans are fully refundable within 30 days of purchase; after that, refunds are prorated. To request one, contact billing. — sourced from your policy docs, not guessed.
The knowledge lives in the vector store. The model just reasons over what retrieval hands it.
The payoff

No hallucinations about things it doesn't know, no stale information, no "I don't have access to that." Just accurate answers grounded in your data.

The craft

How you chunk decides how well it works.

Chunking is the make-or-break decision. Cut documents too small and each chunk loses the context around it. Cut them too large and retrieval gets imprecise — you drag in paragraphs of irrelevant text. A clever fix is hierarchical chunking: store tiny precise chunks for matching and larger parent chunks for context, so you get the precision of small with the completeness of large.

Too small

Precise matches, but each chunk is stranded without its surrounding context.

Too large

Full context, but fuzzy retrieval — the right sentence hides in noise.

Hierarchical ✓

Match on small chunks, then hand the LLM the larger parent for context.

🧠 Agentic RAG

Instead of a fixed pipeline, let the agent decide when and what to retrieve — do multiple rounds if the first didn't surface enough, and treat retrieval as just another tool in its kit. This is the most powerful pattern for complex, multi-step research. It's the agent loop from Chapter 4 with retrieval bolted on.

In real code

The whole pattern, minus the frameworks.

Strip RAG to its essence and it's four steps: embed the question, search the store, stitch the hits into a prompt, and ask. Here it is against a vector store you've already indexed.

rag.py
# 1. embed the user's question — SAME model used to index
q_vec = embed(question)

# 2. retrieve: nearest chunks in the vector store
hits = store.search(q_vec, top_k=3)

# 3. build a grounded prompt from the retrieved chunks
context = "\n\n".join(h.text for h in hits)
prompt  = f"""Answer using ONLY this context.
Context:
{context}

Question: {question}"""

# 4. generate the grounded answer
answer = llm(prompt)
Notice step 1's comment: index and query must use the same embedding model — that's Chapter 9.

Chapter 7 in one breath

Don't bake in knowledge — retrieve it.

RAG indexes your documents as vectors, retrieves the few most relevant chunks for each question, and generates an answer grounded in them. It's how you give an LLM current, private, trustworthy knowledge. Next: the vector databases that make that retrieval fast.

🧪 Build it yourself

A free Google Colab notebook — build this RAG pipeline with Chroma + Gemini embeddings on the free tier.

⬇ Open the notebook

🖥 Present this chapter

A matching slide deck with speaker notes — press S for notes, F for fullscreen.

Open the slides →