RAGEngineering Hub
Chapter 11 · concept 4 of 6 · show all
  1. 1What RAG is, and why
    1. 1.1Why models need outside knowledge, and what hallucination means
    2. 1.2What RAG is: anatomy of a request
    3. 1.3RAG vs fine tuning vs long context and prompt caching
    4. 1.4Use cases and the quality, latency and cost triangle
    5. Chapter overview
  2. 2Tokens, cost and your first RAG
    1. 2.1Tokens and context windows for RAG
    2. 2.2The RAG lifecycle and your first RAG in miniature
    3. Chapter overview
  3. 3Getting documents in
    1. 3.1Content sources and file formats
    2. 3.2Parsing, layout and OCR
    3. 3.3Tables, images and mixed content
    4. 3.4Cleaning, normalization and quality gates
    5. 3.5Metadata, document identity and versioning
    6. 3.6Updates, deletes, reindexing and ingestion pipelines
    7. Chapter overview
  4. 4Chunking
    1. 4.1Why we chunk, and the main chunking strategies
    2. 4.2Structure aware chunking and tables
    3. 4.3Chunk size, overlap and token based sizing
    4. 4.4Contextual chunking and late chunking
    5. 4.5Parent child and multi representation indexing
    6. 4.6Chunk metadata, provenance and the chunking debugging playbook
    7. Chapter overview
  5. 5Embeddings
    1. 5.1Embeddings and similarity from first principles
    2. 5.2What embeddings cannot do
    3. 5.3Choosing an embedding model: size, cost, language
    4. 5.4Embedding model migration and index rebuilds
    5. Chapter overview
  6. 6Vector stores and scores
    1. 6.1Vector databases, ANN indexes and choosing a store
    2. 6.2Score calibration and thresholds
    3. 6.3Late interaction and multivector retrieval
    4. Chapter overview
  7. 7Finding the right chunks
    1. 7.1Query understanding, rewriting and expansion
    2. 7.2Dense retrieval and keyword search with BM25
    3. 7.3Hybrid retrieval and rank fusion
    4. 7.4topK, no good match, and metadata filtering
    5. 7.5Routing, diversity, deduplication and caching
    6. 7.6Reranking: two stage, cross encoder and LLM rerankers
    7. Chapter overview
  8. 8When retrieval fails
    1. 8.1Retrieval failure analysis playbook
    2. Chapter overview
  9. 9Building the answer
    1. 9.1Context selection, packing and citations
    2. 9.2Grounding prompts and abstention
    3. 9.3Lost in the middle and context management
    4. 9.4Conflicts, staleness and freshness rules
    5. 9.5Hallucination checks and answer verification
    6. 9.6Conversational RAG, answer UX and RAG APIs
    7. Chapter overview
  10. 10Measuring
    1. 10.1Why measure, and what to measure
    2. 10.2Building a golden dataset
    3. 10.3Retrieval metrics: precision, recall, MRR, nDCG
    4. 10.4Faithfulness and answer correctness
    5. 10.5LLM as judge, and judging the judge
    6. 10.6Offline and online evals, regression tests and slices
    7. Chapter overview
  11. 11Safety and operations
    1. 11.1Prompt injection and poisoned documents
    2. 11.2Access control, privacy and governance
    3. 11.3Index lifecycle operations
    4. 11.4Observability and tracing
    5. 11.5Latency, cost, caching and model routing
    6. 11.6Reliability, degraded modes and launch readiness
    7. Chapter overview
  12. 12Scale and advanced RAG
    1. 12.1Scaling, multi tenancy and enterprise architecture
    2. 12.2Choosing an architecture: naive, advanced, agentic, graph
    3. 12.3Agentic RAG and RAG as an MCP tool
    4. 12.4GraphRAG, structured data and multimodal RAG
    5. Chapter overview

Observability and tracing

Log enough about each request to replay it: the rewritten query, every retrieved chunk with its rank, the prompt size, each stage's time, the model and the feedback. A real trace from our pipeline shows where the time goes.

A real question

A user says yesterday's answer was wrong. Can you find out why?

Only if you logged enough. A trace records each step of one request, the query search actually used, which chunks came back at what rank, what went into the prompt and how long each step took, under one id you can look up.

The problem

Why this matters

Logging the question and the answer is enough.
The belief

Logging the question and the answer is enough.

What really happens

With only those two, a wrong answer could be a bad rewrite, a missing document, a ranking miss, a filter or the model. Logging the chunk ids and ranks per stage turns the five-step playbook (RAG-32) into a lookup.

Why not the simpler way

RAG fails in many places, and almost always quietly: a wrong answer looks just like a right one. Without traces, every investigation starts from scratch. With them, you can replay a request, see what search found and compare it with what the golden set expects.

The idea

The idea in plain words

Observability means you can understand what the system did from its outputs. Tracing is the main tool: one trace per request, made of spans, one per step, each with timing and attributes. Standards such as OpenTelemetry define the format, and many LLM tools now offer semantic conventions for model calls.

A parcel tracking page: every scan along the way, with time and place. When the parcel is late, you see exactly where it waited.

How it works

Step by step

  1. 1

    One id per request

    Create a trace id at the start, pass it through every step, return it to the client with the answer.

  2. Rewrite, embed, search, fuse, rerank, pack, generate, verify: each records its inputs, outputs and time.
    2

    A span per stage

    Rewrite, embed, search, fuse, rerank, pack, generate, verify: each records its inputs, outputs and time.

  3. Latency per stage, tokens and cost per request, abstention and flag rates, feedback. Alert on changes, not just failures.
    3

    Dashboards and alerts

    Latency per stage, tokens and cost per request, abstention and flag rates, feedback. Alert on changes, not just failures.

In detail

What to record. Trace id, user role (not identity, where you can), original and rewritten query, filters applied, candidate ids and ranks per retriever, reranker scores, packed chunk ids and token counts, model and prompt version, answer, citations, verification flags, abstention, per-span duration, feedback.

Privacy. Questions and answers can contain personal data. Mask what you can, restrict access and set retention (RAG-46).

Sampling. Keep full traces for a share of traffic and for every error, flag or thumbs down; keep metrics for all.

RAG pipeline: documents are loaded, chunked, embedded and indexed offline; at question time the index is searched, the best chunks are packed into the prompt, and the model writes a cited answer.OFFLINE · BUILD THE INDEXLoadPDF, HTML, MDChunk256–512 tokensEmbedtext → vectorIndexvectors + BM25ONLINE · ANSWER A QUESTIONQuestionuser asksRetrievetop k chunksPack promptwithin budgetGeneratecited answersearch the index
Quality is decided offline more often than online: a chunk that splits the answer cannot be rescued by a better prompt.

The code

Try it in Python

import time, uuid, contextlib

class Trace:
    def __init__(self, question, role):
        self.data = {"trace_id": uuid.uuid4().hex, "question": question, "role": role, "spans": []}

    @contextlib.contextmanager
    def span(self, name, **attrs):
        t = time.perf_counter()
        rec = {"name": name, **attrs}
        try:
            yield rec
        finally:
            rec["ms"] = round((time.perf_counter() - t) * 1000, 2)
            self.data["spans"].append(rec)

tr = Trace(question, role="customer")
with tr.span("bm25") as s:
    s["ids"] = [c.id for c in bm25_search(question, 10)]

See it

What we measured

Measured · per-stage latency, median over 47 golden questions

Polder corpus, 34 recursive 512 token chunks, laptop CPU, Node. bge-small q8 for the query, bge-reranker-base q8 for 10 candidates. Model generation not included.

Embed the question3.4 ms
BM25 search0.04 ms
Vector search (exact, 34 chunks)0.02 ms
RRF fusion0.01 ms
Rerank 10 candidates1,406 ms
Generate the answernot measured

Measured 2026-11-04 with corpus/scripts/measure-part-8.mts. Generation time needs model calls: not measured yet.

Try it on a real example

A trace of one question, measured on our pipeline: “How much notice is given for a price change during a fixed term?”

Show

trace (median timings over 47 questions, laptop CPU)

embed query 3.4 ms · BM25 0.04 ms · vector 0.02 ms · fuse 0.01 ms · rerank 10 1,406 ms · generate: not measured

Retrieval time is almost all reranking. Without spans you would not know which step to speed up.

Choosing

Use it when, avoid it when

Use it when
  • A trace id per request, returned to the client
  • Spans per stage with ids, ranks, tokens and time
Avoid it when
  • Logging only question and answer
  • Keeping full traces with personal data forever

What it costs · A little code per stage and storage for traces; sample full traces at scale.

In production

Build three views: a request view (one trace, every span), a stage view (p50 and p95 latency, cost per stage over time) and a quality view (abstention, verification flags, feedback by slice). Alert on change: a rising abstention rate after an index swap is often the first sign of a broken build.

Watch out

Common mistakes

  • Observability is for outages. In RAG it is mostly for quality.
  • Model calls are the only slow part. Our reranker took 1.4 s before the model was even called.
  • More logs are always better. Personal data in logs is a liability; log what you need.

Check yourself

Remember this

Remember these

  • Give every request a trace id and return it with the answer.
  • Record each stage: inputs, outputs, ranks, tokens, time.
  • In our pipeline, reranking was over 99% of retrieval time.
  • Tie feedback to the trace id so bad answers can be replayed.

Say it in an interview

  1. 01Every request gets a trace id, with a span per stage, returned with the answer.
  2. 02I log the rewritten query, chunk ids and ranks per retriever, prompt tokens and model version.
  3. 03In my pipeline reranking was 1.4 s of retrieval time; everything else was under 4 ms.
  4. 04Feedback is tied to the trace, so a bad answer can be replayed and diagnosed.
  5. 05Traces follow privacy rules: masking, access control and retention limits.

Quick quiz

Three questions

Question 1

Q1

Why log retrieved chunk ids and ranks, not just the answer?

Question 2

Q2

In our traced pipeline, which stage took the most time?

Question 3

Q3 · from RAG-44

What should a CI gate check?

Saved on this device. No account needed.