Skip to content
← All writing
June 17, 2026·6 min read

RAG Explained for App Developers

Retrieval-Augmented Generation (RAG) is one of those terms that sounds far more complicated than it is. Strip away the jargon and RAG is a simple idea: before you ask the model a question, go find the relevant facts and hand them to the model along with the question. That's it. Everything else — embeddings, vector databases, chunking strategies — is plumbing in service of that one sentence.

I've built this pipeline more than once (including a browser-side demo that runs the whole thing locally), and the pattern is remarkably consistent across projects. This post explains how it works, when it's worth the effort, and where it actually goes wrong in practice.

The problem RAG solves

A language model only knows what it learned during training. It doesn't know your app's data, your company's documents, or anything that happened after its training cutoff. Ask it about your content and it will either say it doesn't know — or worse, confidently make something up ("hallucinate"). For a customer-facing feature, a fluent wrong answer is worse than no answer, because users can't tell the difference.

You could retrain the model on your data, but fine-tuning is expensive, slow, and has to be redone every time the data changes — and even then, a fine-tuned model can still misremember. RAG sidesteps all of that: instead of baking knowledge into the model, you fetch the right knowledge at question time and include it in the prompt. The model's job shrinks from "know everything" to "read this context and answer from it," which is something LLMs are genuinely good at.

The pipeline, step by step

RAG has two phases: an offline indexing phase and an online retrieval phase.

Indexing (done ahead of time):

  1. Chunk your documents into small passages — a few hundred words each. Respect natural boundaries (sections, paragraphs) rather than cutting mid-sentence.
  2. Embed each chunk. An embedding model turns text into a vector (a list of numbers) that captures its meaning.
  3. Store those vectors in a vector database, alongside the original text and metadata like the source document and section title.

Retrieval (done per request):

  1. Embed the user's question with the same model you used for indexing — mixing embedding models silently breaks everything, because vectors from different models aren't comparable.
  2. Search the vector store for the chunks whose vectors are closest to the question's vector — these are the most semantically relevant passages.
  3. Assemble a prompt: "Using the context below, answer the question. Context: [top chunks]. Question: [user question]."
  4. Send it to the LLM, which now answers grounded in your actual data.

None of these steps is individually hard. A minimal RAG system is a weekend project; the quality work is in the details, which is where the practical tips below come in.

Why embeddings, not keyword search?

Keyword search matches exact words. Embeddings match meaning. A user asking "how do I get my money back?" should find a passage titled "Refund Policy" even though it shares no words with it. That semantic matching is what makes RAG feel smart, and it's what plain full-text search can't do.

But the reverse failure exists too: pure semantic search is surprisingly bad at exact tokens — product codes, error messages, function names, part numbers. The embedding for "ERR_CONN_RESET" doesn't reliably sit closest to documents containing that literal string. That's why many production systems run hybrid retrieval — keyword and vector search, with the results merged — because each catches cases the other misses. If your content is full of identifiers, hybrid isn't optional.

When you actually need RAG

RAG is worth it when:

  • You have a body of knowledge the model doesn't know (docs, help center, product catalog, the user's own notes).
  • That knowledge changes often, so anything baked into the model goes stale.
  • You need answers grounded in real sources, ideally with citations the user can check.

RAG is overkill when:

  • The task is general reasoning the model already handles ("summarize this text the user pasted").
  • Your entire knowledge base is small enough to just paste into the prompt every time. With today's large context windows, "small enough" covers more cases than people assume — a few dozen pages of docs can simply ride along in every request, and that's a perfectly legitimate architecture. Retrieval earns its complexity when the corpus outgrows the context window or the cost of resending it every call.

Practical tips

  • Chunk thoughtfully. Too big and you dilute relevance (the one matching sentence is buried in 2,000 words of noise); too small and you lose the context that makes the passage meaningful. Start around 300–500 words with a little overlap between neighbours, and prefer splitting on headings and paragraphs over fixed character counts.
  • Return sources. Showing which document an answer came from builds user trust and makes debugging possible. When an answer is wrong, the first question is always "what context did the model see?" — make that answerable.
  • Measure retrieval separately from generation. This is the single most useful debugging habit. Most "the AI gave a bad answer" bugs are actually retrieval bugs — the right chunk was never fetched, so the model never stood a chance. Build a small test set of questions with known-correct source passages and check whether retrieval surfaces them, before you touch a single prompt.
  • Keep the prompt disciplined. Tell the model to answer only from the provided context and to say "I don't know" when the context doesn't cover the question. Without that instruction, the model happily blends retrieved facts with trained guesses, and you lose the groundedness that justified building RAG in the first place.
  • Plan for updates. Documents change. Decide early how re-indexing works — a nightly job, a hook on document save — and store a content hash per chunk so you only re-embed what actually changed.

Where it goes wrong

The failure modes are predictable enough to list. Retrieval returns plausible-but-wrong chunks because the corpus has near-duplicate content. Answers cite the right document but the wrong version, because stale chunks were never purged. Questions that span two documents fail because each chunk alone is insufficient. And user questions that are really conversations ("what about the second option?") retrieve nothing useful because the question text alone is meaningless — you need to rewrite follow-up questions into standalone ones before embedding them. None of these is fatal; all of them are invisible until you test with real user questions rather than your own well-formed ones.

Summary

RAG isn't a model — it's an architecture: chunk your data, embed it, store the vectors, and at question time fetch the most relevant pieces to ground the model's answer. It's the most reliable way to make an LLM speak accurately about information it was never trained on, and for most "chat with my data" features it's the right first tool to reach for. Build the minimal version, test retrieval with real questions, and add sophistication (hybrid search, re-ranking, query rewriting) only where measurement says you need it.

Further reading