RAG Explained: Building AI Apps That Know Your Data
Retrieval-Augmented Generation is the standard pattern for grounding LLMs in your own documents. How it works, how to build it, and where it goes wrong.
Elena Ruiz
AI & Tools Writer
Marcus Webb
Fact Checked
Ask a large language model about your data — your product docs, your codebase, your company wiki — and you hit the wall immediately: the model has never seen any of it. It will either admit ignorance or, worse, improvise something plausible. Fine-tuning on your documents is expensive, slow to update, and doesn’t reliably teach facts anyway.
Retrieval-Augmented Generation (RAG) is the pattern that solved this, and years after the term was coined it remains the backbone of virtually every “chat with your docs” product, support bot and internal knowledge assistant in production. The concept fits in one sentence:
Don’t expect the model to remember — hand it the relevant pages at question time.
It’s an open-book exam instead of a closed-book one. This guide covers how the pattern works, how to build a solid version, and the failure modes that separate demos from products.
Why RAG instead of the alternatives?
Three ways exist to make a model answer from knowledge it wasn’t trained on:
| Approach | Update speed | Cost | Access control | Traceability |
|---|---|---|---|---|
| Fine-tuning | Days (retrain) | High | None | None |
| Long context (paste everything) | Instant | Per-request tokens | Awkward | Weak |
| RAG | Instant (re-index) | Low per query | Natural (filter at retrieval) | Strong (citations) |
Fine-tuning changes behavior well (tone, format, domain style) but is an unreliable way to inject facts — and it can’t forget yesterday’s version of a document. Pasting everything into the context works beautifully until your corpus outgrows the window or your token bill outgrows your patience; it also can’t respect per-user permissions. RAG updates instantly (add or remove a document from the index), retrieves only what’s relevant, filters by access rights at query time, and can cite its sources.
The approaches also compose: modern systems retrieve generously because windows are long, and may fine-tune for domain tone while using RAG for facts.
The pipeline, end to end
Every RAG system is two pipelines meeting at a prompt.
Indexing (offline)
- Load and clean your documents — markdown, PDFs, tickets, code.
- Chunk them into retrievable pieces. This is the first place quality is won or lost: chunks must be small enough to be specific, large enough to be self-contained. Splitting by structure (headings, paragraphs, functions) beats splitting every N characters; 200–500 tokens with modest overlap is the classic starting zone.
- Embed each chunk: an embedding model converts text into a vector — a point in a space where similar meanings sit near each other. (If embeddings are new to you, our plain-English guide to how LLMs work builds the intuition.)
- Store vectors plus the original text and metadata (source, date, permissions) in a vector store — pgvector, Qdrant, or your cloud’s offering. If you already run Postgres, pgvector is the pragmatic default.
Query time (online)
- Embed the user’s question with the same model.
- Retrieve the top-K most similar chunks (with metadata filters: tenant, language, permissions).
- Assemble the prompt: instructions + retrieved chunks (with source labels) + the question. The instruction block matters:
Answer using ONLY the provided context.
Cite the source id for each claim, like [doc-42].
If the context does not contain the answer, say so explicitly.
- Generate, and ideally render the citations as links so users can verify.
A minimal implementation is genuinely small — the pattern’s popularity owes a lot to how far a hundred lines can go:
question_vec = embed(question)
chunks = store.search(question_vec, top_k=8, filter={"tenant": tenant_id})
context = "\n\n".join(f"[{c.id}] {c.text}" for c in chunks)
answer = llm(f"{INSTRUCTIONS}\n\nContext:\n{context}\n\nQuestion: {question}")
Where RAG systems actually fail
Production RAG lives or dies in retrieval. When users say “the AI is wrong,” inspect what was retrieved — nine times out of ten the model faithfully summarized the wrong or insufficient text. The recurring failure modes:
Vocabulary mismatch. Pure vector search is semantic, which is great until a user searches for error code E1042 or a product SKU — exact strings that embeddings blur. The fix is hybrid search: run keyword search (BM25) alongside vector search and merge results. Every serious system ends up hybrid.
Chunks without context. A retrieved paragraph saying “it defaults to 30 seconds” is useless if the chunk doesn’t say what “it” is. Fixes: prepend each chunk with its document title and section heading at indexing time; or use contextual-retrieval techniques where a model writes a one-line situating summary per chunk.
Top-K isn’t the best K. Similarity search returns roughly relevant chunks. Adding a reranker — a small model that scores each candidate against the query properly — before final selection is routinely the single biggest quality jump available (retrieve 50, rerank, keep 8).
Questions that need synthesis. “Compare our Q3 and Q4 refund policies” needs chunks from two documents; “what changed?” needs versions over time. Techniques like query decomposition (split into sub-questions), multi-query expansion, or agentic retrieval (let the model search iteratively) address this — at the cost of latency and complexity. Add them when logs show you need them, not before.
Stale indexes. A RAG bot answering from last quarter’s pricing doc is worse than no bot. Re-indexing must be wired into your content pipeline from day one, and metadata should carry dates so the prompt can prefer recent sources.
Evaluation: the unglamorous differentiator
Teams that ship reliable RAG all converge on the same discipline: a golden set of 50–200 real questions with known-good answers and known-source documents, run on every change. Measure two things separately:
- Retrieval hit rate: did the right chunk appear in the retrieved set? (No model involved — pure search metric.)
- Answer faithfulness: does the generated answer follow from the retrieved context? (An LLM judge grading answers against context works well in practice.)
Separating these tells you which half of the system to fix. Skipping evaluation and iterating on vibes is the most common way RAG projects stall at 80% quality forever.
Do long contexts make RAG obsolete?
With million-token context windows, you might wonder whether to skip retrieval and paste the whole knowledge base per question. For small, stable, public corpora — honestly, yes, sometimes. But RAG remains necessary when:
- the corpus is larger than any window (most real ones are),
- cost and latency matter (shipping a million tokens per question is neither fast nor cheap),
- permissions differ per user (retrieval filters; a stuffed context can’t un-see documents),
- you need citations users can check.
The honest synthesis: long windows made RAG easier (retrieve 30 chunks instead of agonizing over 5) rather than unnecessary. And if your knowledge is on the open web rather than private, note that answer engines now do RAG over the internet at large — which is reshaping how technical content gets discovered, a shift with real consequences for anyone publishing docs or blogs.
For experimenting locally without API costs, pairing an open-weight model with a local vector store is a perfectly viable lab — our local LLM guide covers the model side, and the prompting patterns in our prompt engineering guide (especially structured instructions and citation formats) apply verbatim.
Final Thoughts
RAG endures because it matches how organizations actually hold knowledge: living documents, changing daily, with owners and permissions — not frozen training corpora. Ground the model in retrieved evidence and you convert an eloquent guesser into a system that answers from your sources and shows its work.
Start embarrassingly simple: chunk by headings, pgvector, hybrid search, top-8, strict “answer from context” instructions. Build the golden-question set the same week. Then let real query logs — not architecture blog posts — tell you which sophistication to add. The teams that ship great RAG aren’t the ones with the fanciest pipeline; they’re the ones who watched their retrieval like a hawk.