Module A-12·32 min read

Chunking and ingestion, retrieval plus rerank, prompt and response caching, tokens as a capacity unit, and designing around a non-deterministic dependency.

JJS
Written by Jatin Jain Saraf · Senior Software Engineer

Module A-12 — RAG and LLM-Serving Architecture

What this module covers: A dependency with properties nothing else in this course has — non-deterministic output, seconds of latency, cost measured per token, a hard context limit, and a failure mode that is a confidently wrong answer rather than an error. Why retrieval rather than fine-tuning is the mechanism for facts, with the architectural argument that decides it: you cannot enforce access control in model weights. The query side of RAG, which Module P-21 left open — query rewriting for multi-turn conversations, reranking, and context assembly as an explicit budget rather than a hope. Access control in retrieval, where a leak is worse than usual because the answer is laundered. Latency architecture around time-to-first-token, and what streaming commits you to. Caching something non-deterministic, including the semantic cache's sharp edge and the prefix cache that actually pays. Tokens as a capacity unit and the agentic loop as an unbounded cost risk. Then evaluation, because a prompt change is a deploy with no type checking, and prompt injection, because retrieved text reaches the model and the model is a confused deputy.


An LLM Is Unlike Every Other Dependency in This Course

PropertyA normal RPCAn LLM call
Determinismsame input, same outputdifferent output each time
Latency10–100 ms1–30 s, and proportional to output length
Costper request, negligibleper token, and output tokens cost several times input tokens
Response shapecompletestreamed, token by token
Input limita body sizea context window that is a hard resource to budget
Failure modean error you can catcha plausible wrong answer, indistinguishable from a right one

Every one of those changes an architectural decision. Non-determinism breaks caching and testing. Second-scale latency forces streaming (Module A-10). Per-token cost makes capacity planning a token-budget exercise rather than a request-rate one. And the last row is the important one:

A confidently wrong answer produces no error, no latency anomaly, and no alert. Your dashboards are green while the product tells users something false.

Everything below is a response to one of those six rows.

Analogy: hiring a fast, articulate, well-read graduate who has no access to your files, no memory of yesterday, will never say "I don't know" unless taught to, and is paid by the word. You would not fix their ignorance of your business by sending them on a writing course — you would put the relevant documents on the desk in front of them, and require them to cite which document each claim came from. And you would not let them sign contracts on your behalf just because they sound confident.


Retrieval, Not Fine-Tuning, Is How You Supply Facts

Fine-tuning adjusts the model's weights on your examples. It is the right tool for form: tone, output format, domain vocabulary, a consistent classification scheme. It is the wrong tool for facts, for four reasons that are architectural rather than a matter of quality:

  • You cannot update a fact. A price change means retraining; retrieval means updating a row.
  • You cannot unlearn a fact. An erasure request over training data has no clean answer (Module O-9); retrieval deletes a chunk.
  • You cannot cite. A weight-encoded fact has no provenance, so the user cannot verify it and you cannot debug it.
  • And decisively: you cannot enforce access control. A model trained on all your customers' documents will answer any user's question from any customer's data, because the weights have no notion of who is asking. Retrieval applies a filter at query time.

That last point is the one to lead with in a design review. Per-user authorisation is expressible in a retrieval filter and is not expressible in model weights, which settles the question for any multi-tenant or permissioned corpus regardless of what fine-tuning might do for quality.

The ingest half of retrieval — chunking, embeddings, indexes, recall measurement — is Module P-21, and everything there applies unchanged: parent-document retrieval, denormalised metadata on chunks, hybrid search with reciprocal rank fusion, and recall measured against a brute-force ground truth. This module covers what happens at query time.


The Query Path, Where Most RAG Quality Is Won or Lost

text

1. Query rewriting, and the multi-turn bug that everyone ships first. The user's message is often not a searchable query:

text

Embedding "What about annual?" retrieves documents about annual reports. The conversation history must be collapsed into a standalone query before retrieval, usually with a cheap fast model. This single step is frequently the largest quality improvement available in a chat-shaped RAG system, and its absence presents as "the bot forgets context" — which sounds like a model problem and is a retrieval problem.

Other transformations worth knowing: multi-query expansion (generate three phrasings, retrieve for each, fuse), which improves recall at the cost of latency and tokens; HyDE (generate a hypothetical answer and embed that, since answers are closer to documents than questions are); and decomposition for compound questions ("compare X and Y" is two retrievals).

2 and 3. Retrieve wide, rerank narrow. Hybrid retrieval (Module P-21) returns 50 candidates cheaply; a cross-encoder reranker scores each against the query properly and keeps the best 5. The reranker is usually worth its 100–200 ms because it directly determines what the model sees — and what the model sees dominates output quality far more than the model choice does.

4. Context assembly is a budget, and it must be accounted rather than hoped.

text

Two non-obvious rules here.

Reserve the output allocation up front. The window covers input and output, so a prompt that fills it leaves no room to answer, and the failure is a truncated response mid-sentence.

More context is not monotonically better. Models attend less reliably to material in the middle of a long context — the "lost in the middle" effect — so stuffing 40 chunks in makes the answer worse than 5 good ones, while costing eight times as much and adding latency. Place the most relevant material at the beginning and end of the retrieved block. This runs against the instinct that a larger window should simply be filled.

5. Require citations. Instruct the model to attach chunk IDs to each claim, then verify server-side that the cited IDs were actually in the context and, where cheap, that the claim is supported. Citations do three jobs at once: users can verify, you can debug ("it hallucinated" versus "retrieval returned the wrong document" are entirely different bugs), and an uncited answer becomes a detectable event you can measure.


Access Control in Retrieval, Where a Leak Is Worse Than Usual

Modules P-20 and P-21 both insisted that a tenant filter be applied by a layer no query can omit. In RAG the stakes rise, for a specific reason:

If search returns another tenant's document, the user sees a document with a title and an owner and may recognise it as wrong. If RAG retrieves it, the model summarises it into fluent prose attributed to nobody — a laundered leak that is harder to notice, harder to attribute, and impossible to un-see.

So:

  • ACLs are denormalised onto every chunk at ingest (Module P-21), and the filter is applied inside the retrieval call, not after it — post-filtering breaks under selective filters anyway (Module P-21's trap).
  • The filter is enforced by a server-side layer that no prompt, tool, or query builder can bypass.
  • Permission changes must reach the index. A user removed from a project must stop retrieving its chunks immediately, which means either the filter reads live permissions (a join, or a check after retrieval on IDs) or the index is updated synchronously on permission change. A nightly ACL sync is a multi-hour window of unauthorised retrieval.
  • Nothing containing one user's retrieved context may be cached for another. See the caching section — this is where the leak usually happens in practice.

Latency: Time to First Token Is What Users Feel

Total latency is the wrong metric here. Two responses:

text

B is three times slower and dramatically better, because reading speed and generation speed are comparable. So stream, always — which makes SSE the natural transport (Module A-10), with its automatic reconnection and its fit through ordinary HTTP infrastructure.

Budget the path explicitly:

StageTypical
Query rewrite (small fast model)150–400 ms
Retrieval (hybrid, pgvector or engine)20–80 ms
Rerank (cross-encoder over 50)100–200 ms
Time to first token300–800 ms
Generationoutput tokens ÷ 30–80 tokens/s

The rewrite is on the critical path before retrieval, which is why it should use a small model. A reranker's 150 ms is usually worth it. A second retrieval round (retrieve, generate, retrieve again) rarely is for interactive use — it doubles TTFT — and belongs in an async or agentic path instead.

And streaming commits you before you have validated. You cannot retract the first half of a response the user has already read. Consequences:

Sign in to keep reading

The rest of this module is free — sign in with Google to unlock it and track your progress.

Sign in & Register

Discussion

0

Join the discussion

Loading comments...

© 2026 Jatin Jain Saraf (JJS). All rights reserved.