RAGEngineering Hub
Chapter 11 · concept 3 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

Index lifecycle operations

An index is not built once. New documents, deletes, permission changes, new chunking and new models all change it. Build versioned indexes, gate them on the golden set, swap by alias, keep a rollback.

A real question

The index works today. What happens next month?

Documents are added, edited and deleted, permissions change, and you will want new chunking or a new model. Each is an index operation. Treat the index like a release: versioned, tested, swapped, and reversible.

The problem

Why this matters

Build the index once and it stays correct.
The belief

Build the index once and it stays correct.

In RAG-12, updating one tariff sheet left 2 orphan chunks, including a plan that was no longer for sale. In RAG-25, a half-done model change dropped recall from 44 to 27 of 47. Indexes go wrong quietly unless every change goes through a process.
What really happens

In RAG-12, updating one tariff sheet left 2 orphan chunks, including a plan that was no longer for sale. In RAG-25, a half-done model change dropped recall from 44 to 27 of 47. Indexes go wrong quietly unless every change goes through a process.

Why not the simpler way

Most RAG incidents in production are not model failures. They are stale chunks after an update, documents that were deleted at the source but not in the index, permissions that changed without a re-sync, or a model upgrade done halfway. All of these are lifecycle problems.

The idea

The idea in plain words

The index lifecycle covers how indexes are built, updated, tested, promoted and retired. Incremental updates handle document changes. Full rebuilds handle chunking and model changes. Blue-green swaps make promotion and rollback instant.

A shop restocks shelves every day, but a new store layout is set up overnight and checked before the doors open.

How it works

Step by step

  1. Each build has an id and a manifest: corpus snapshot, chunking settings, embedding model, build date.
    1

    Build a versioned index

    Each build has an id and a manifest: corpus snapshot, chunking settings, embedding model, build date.

  2. 2

    Gate on the golden set

    Run retrieval checks against the new build. No question that passed may fail without an explicit decision (RAG-44).

  3. Point the live alias at the new build. Keep the previous one until the new one has served real traffic.
    3

    Swap and keep

    Point the live alias at the new build. Keep the previous one until the new one has served real traffic.

In detail

Manifest. { build_id, corpus_snapshot, chunker, chunk_size, embed_model, prefix, created_at, golden_result }, stored with the index.

Incremental path. Change events from the source (or a nightly diff) → re-parse → re-chunk → hash compare → embed new chunks, delete removed ones, update metadata for permission changes (RAG-12, RAG-46).

Full path. New build in parallel, golden gate, alias swap, old build kept N days.

Housekeeping. Remove chunks whose documents no longer exist; expire caches by document id (RAG-30); alert when the corpus size jumps or drops unexpectedly.

The code

Try it in Python

import json, time

def build(corpus, chunker, model, golden, baseline):
    manifest = {"build_id": f"idx-{int(time.time())}", "chunker": chunker.name,
                "embed_model": model.name, "docs": {d.id: d.hash for d in corpus}}
    index = make_index(corpus, chunker, model)
    result = run_golden(index, golden)
    broke = [q for q, ok in baseline.items() if ok and not result[q]]
    if broke:
        raise SystemExit(f"{manifest['build_id']} blocked, broke {broke}")
    manifest["golden"] = sum(result.values())
    save(index, manifest)
    set_alias("live", manifest["build_id"])     # the old build stays for rollback

See it

What we measured

Measured · index builds and updates on the lab corpus

Polder corpus, 34 recursive 512 token chunks, bge-small q8 on a laptop CPU. Update numbers from RAG-12, migration from RAG-25.

Embed all 34 chunks879 ms
Build the BM25 indexabout 1 ms
Index file with vectors130 KB
Orphan chunks after one update without deletes2
Recall@3 with half-migrated models44 of 4727 of 47

Measured 2026-11-04 with corpus/scripts/measure-part-8.mts; earlier numbers measured 2026-11-03 and 2026-11-04.

Try it on a real example

Three changes, and what each one requires

Change

Incremental

Re-chunk the changed document, compare content hashes, embed only new chunks, delete the old ones.

Cheap, but deletes are where it goes wrong: our tariff update left 2 orphans without them (RAG-12).

Choosing

Use it when, avoid it when

Use it when
  • Versioned builds with manifests
  • Golden-set gates and alias swaps
  • Incremental updates with deletes for document edits
Avoid it when
  • Rebuilding the live index in place
  • Updates that add chunks but never delete

What it costs · Storage for two indexes during a swap, and a golden run per build.

In production

Measure build time and cost per chunk, so you know when a full rebuild stops being cheap. Track freshness: the time from a source edit to the index reflecting it. Run a daily consistency check: every indexed document still exists at the source with the same hash and permissions.

Watch out

Common mistakes

  • Indexes only grow. Deletes and permission changes matter as much as additions.
  • Incremental is always better. For small corpora a full rebuild is simpler and safer.
  • A successful build is a good build. Only the golden gate says that.

Check yourself

Remember this

Remember these

  • Every corpus, chunking or model change is an index operation.
  • Version builds with a manifest of what went into them.
  • Gate each build on the golden set; swap by alias.
  • Deletes and permission changes must reach the index too.

Say it in an interview

  1. 01I treat the index as a build artifact: versioned, gated, swapped by alias, with rollback.
  2. 02Document edits go incremental with hash diffs and deletes; chunking and model changes rebuild fully.
  3. 03On my corpus a full rebuild takes under a second, so I rebuild fully; at scale I would plan it.
  4. 04Each build stores a manifest of corpus, chunker and model.
  5. 05A daily check confirms every indexed document still exists with the same hash and permissions.

Quick quiz

Three questions

Question 1

Q1

Why swap indexes through an alias rather than rebuilding in place?

Question 2

Q2

How long did a full rebuild of our lab index take?

Question 3

Q3 · from RAG-25

What does mixing two embedding models in one index do?

Saved on this device. No account needed.