Skip to content
← Blog
Article

RAG Architecture Explained, Stage by Stage

How a production RAG system works end to end, from ingestion and chunking to embeddings, retrieval, reranking, generation, and evaluation, plus the design decision at each stage.

8 min readStallwart

What RAG actually is

Retrieval augmented generation is a pattern where a language model answers using text fetched from your own data at query time, rather than only what it learned during training. The pipeline runs in two phases: an offline phase that ingests documents, splits them, embeds them, and writes them to a store, and an online phase that embeds the user query, retrieves the most relevant chunks, optionally reranks them, and passes them to the model as context for generation.

The reason RAG exists is grounding. A model asked a question about your contracts, your codebase, or last quarter's tickets has no reliable knowledge of them, and asking it anyway produces confident invention. RAG changes the question from "what do you know" to "here are the relevant passages, answer using only these," which makes answers checkable against a source.

Every stage below is a place where a design decision either preserves or destroys the signal that reaches the model. A RAG system fails far more often in chunking and retrieval than in the model itself, so the engineering effort belongs there.

Ingestion and chunking: the two stages that decide the ceiling

Ingestion is parsing source documents into clean text plus metadata. The hard part is not reading a PDF, it is preserving structure: headings, tables, code blocks, and the parent document a passage came from. Tables flattened into run-on text and headings dropped are information you can never retrieve later, because it is no longer in the index.

Chunking then splits that text into retrievable units. This is the single highest-leverage decision in the pipeline, because a chunk is the smallest thing retrieval can return. Too large, and one chunk mixes several topics so the embedding is a blurred average and the model wastes context on irrelevant text. Too small, and a chunk loses the surrounding context needed to make it meaningful on its own.

There is no universal chunk size. The design decision is to chunk along the document's own structure rather than by a fixed character count. A few strategies, from crudest to most faithful:

  1. Fixed-size with overlap: split every N tokens with an overlap window so a sentence cut in half still appears whole in one chunk. Simple, cheap, and a reasonable default for uniform prose.
  2. Structure-aware: split on headings, paragraphs, list items, or code function boundaries so each chunk is a coherent unit. Better recall because chunks map to how the content is actually organized.
  3. Sentence or semantic: group sentences until the topic shifts, detected by a drop in similarity between adjacent sentences. Keeps a single idea in a single chunk.
  4. Parent-child: embed and retrieve on small precise chunks, but hand the model the larger parent passage they belong to, so retrieval is sharp and context is complete.

Embeddings and the vector store

An embedding model turns each chunk into a vector, a list of numbers positioning that text in a high-dimensional space where similar meanings sit close together. At query time the same model embeds the question, and retrieval becomes a nearest-neighbor search: find the chunk vectors closest to the query vector.

Closeness is usually cosine similarity, the cosine of the angle between two vectors, cos(θ) = (A·B)/(‖A‖‖B‖). It ranges from -1 to 1 and ignores magnitude, so it compares direction, that is, meaning, rather than text length. This is why a two-line answer and a paragraph on the same topic can score as highly similar.

The embedding model choice matters more than the vector database. Use the same model for indexing and querying, match it to your domain and languages, and remember its context limit caps useful chunk size. Dimensionality is a tradeoff: more dimensions can capture more nuance but cost more memory and search time.

The vector store holds these vectors and serves approximate nearest-neighbor search, trading a small amount of recall for large speed gains at scale using an index such as HNSW. Choose it on operational fit: metadata filtering, hybrid keyword-plus-vector search, update and delete behavior, and whether you want a managed service or a library embedded in your own service.

Retrieval, reranking, and generation

Retrieval fetches the top-k candidate chunks for a query. Pure vector search is strong on meaning but weak on exact terms like error codes, product SKUs, or names, where lexical search wins. Hybrid retrieval runs both a keyword search and a vector search and fuses the results, which is why it is the common production default rather than vector search alone.

Reranking is a second, more precise pass. The first retrieval optimizes for speed and casts a wide net, say the top 50 candidates. A reranker, typically a cross-encoder that reads the query and each candidate together rather than comparing precomputed vectors, then scores and reorders them so the best few reach the model. It is slower per item, which is exactly why it runs only on the shortlist, not the whole corpus.

Generation is the final stage: the reranked chunks go into the prompt with an instruction to answer only from the provided context and to cite or abstain when the context does not contain the answer. The design decisions here are the prompt contract, how much context to include before quality degrades, and whether to return citations back to the source chunks so a human can verify the answer.

A useful way to see the pipeline is as a series of filters that each narrow a large corpus down to the handful of passages the model reads. Retrieval trades recall for speed, reranking trades speed for precision, and generation trades context length for focus. Get the balance wrong at any one stage and the others cannot recover it.

Evaluation: the stage most teams skip

A RAG system that is never measured drifts silently as data and queries change. Evaluation is what turns "it seems to work" into a number you can defend, and it splits cleanly into retrieval quality and generation quality, because a wrong answer can come from either.

Measure retrieval on its own first, since the generator cannot answer from context it never received. Standard measures are recall at k, whether the relevant chunk is in the retrieved set, and precision, how much of what was retrieved is actually relevant. If recall is low, no prompt engineering will fix the answer.

Then measure generation against the retrieved context: faithfulness, whether the answer is supported by the context rather than invented, and answer relevance, whether it addresses the question. Build a fixed evaluation set of real questions with known-good answers, run it on every change, and you convert tuning from guesswork into a controlled experiment. This is also where using a model as an automated judge, scored against that reference set, earns its place.

This is the discipline that separates a demo from a system you can run in production. At Stallwart we treat the evaluation set as a first-class deliverable built around the customer's real queries and data, because a RAG pipeline you cannot measure is one you cannot safely change.

Common failure points, in order of likelihood

When a RAG answer is wrong, the cause is usually upstream of the model. Diagnosing in pipeline order saves time:

  1. The answer was never indexed: ingestion dropped a table or the source was never loaded. No retrieval step can find what is not there.
  2. The chunk split the answer: relevant information landed across two chunks and neither is self-contained. A chunking or overlap change fixes it.
  3. Retrieval missed it: the relevant chunk exists but ranked below k. Add hybrid search or raise k, then rerank.
  4. The reranker or context budget dropped it: it was retrieved but trimmed before the model saw it.
  5. The model ignored the context: a prompt problem, not a retrieval one. Tighten the instruction to answer only from context and to abstain otherwise.

The short version

  • RAG runs in two phases: an offline index build (ingest, chunk, embed, store) and an online answer path (embed query, retrieve, rerank, generate).
  • Chunking is the highest-leverage decision, because a chunk is the smallest unit retrieval can return; chunk along document structure, not a fixed character count.
  • Hybrid retrieval (keyword plus vector) plus a cross-encoder reranker outperforms pure vector search, especially on exact terms like codes and names.
  • Most RAG errors happen before the model: not indexed, badly chunked, or not retrieved. Diagnose in pipeline order.
  • Evaluate retrieval and generation separately against a fixed reference set, or you cannot safely change the system.
The short answers

Questions this raises

How is RAG different from fine-tuning a model?
Fine-tuning changes the model's weights to shift its behavior and style, while RAG leaves the model unchanged and supplies fresh facts at query time as retrieved context. RAG is the right tool when knowledge changes often or must be traceable to a source, because you update an index rather than retraining. The two are complementary: fine-tune for how to respond, use RAG for what is true right now.
What is the best chunk size for RAG?
There is no single best size, because the right unit depends on how your documents are structured and what a good answer looks like. Chunk along natural boundaries like headings, paragraphs, or code functions rather than a fixed character count, and add overlap so a split sentence still appears whole in one chunk. If you must start with a number, a few hundred tokens with modest overlap is a reasonable baseline to then tune against your evaluation set.
Do I need a reranker, or is vector search enough?
Vector search alone is often good enough for a prototype, but a reranker meaningfully improves precision on the passages the model actually reads. Retrieval casts a wide, fast net; a cross-encoder reranker then reads the query and each candidate together and reorders them, so the strongest few reach the prompt. Because it runs only on the shortlist, the added latency is small relative to the accuracy gain.
How do I know if my RAG system is actually working?
Measure retrieval and generation separately against a fixed set of real questions with known-good answers. For retrieval, track recall at k and precision; for generation, track faithfulness to the retrieved context and relevance to the question. Run that set on every change so tuning becomes a controlled experiment instead of guesswork.
Why does my RAG system give wrong or made-up answers?
The cause is usually upstream of the model. Check in pipeline order: the answer may never have been indexed, the chunk may have split the answer across units, retrieval may have ranked the relevant chunk below k, or the context budget may have trimmed it before the model saw it. Only if the right context did reach the model is it a prompt problem, fixed by instructing the model to answer only from context and to abstain otherwise.

Recognize this in your own operation?

Bring us the version of it happening in your business and we will tell you which part a system can take over.