RAG Deep Dive: Principles, Optimization & Production Implementation

This comprehensive guide explains RAG from first principles through production deployment, covering offline indexing (loading, chunking, embedding, vector storage), online query pipeline (retrieval, reranking, prompt assembly), hybrid search with BM25 and dense vectors, RRF fusion, cross-encoder reranking, evaluation metrics (recall@k, MRR, nDCG), query rewriting, metadata filtering, contextual retrieval, Agentic RAG, and a real-world case study building a style-matching writing assistant with 197 articles.

Su San Talks Tech
Su San Talks Tech
Su San Talks Tech
RAG Deep Dive: Principles, Optimization & Production Implementation

01 RAG Is an Open-Book Exam

Large language models suffer from three fundamental problems: hallucination (fabricating plausible but incorrect answers), stale knowledge (training cutoff dates), and ignorance of private data (internal docs, proprietary knowledge). The root cause is that LLMs operate as closed-book examinees — they rely solely on parametric memory and never admit ignorance. RAG solves this by turning the model into an open-book examinee: before answering, retrieve relevant passages from a knowledge base and inject them into the prompt. The model itself does not change; only the context it sees changes. If retrieval fails, even the strongest generator produces garbage — hence all downstream optimizations target retrieving the right passage.

One-liner: RAG = open-book exam. The model stays the same; what changes is whether it can find the right page before answering.

02 End-to-End Pipeline: Offline Four Steps + Online Four Steps

The complete RAG pipeline splits into two phases that must be memorized:

【Offline: Build Index】 — one-time / periodic, answers "how knowledge enters system"
Document Load → Chunk Splitting → Embedding → Vector Store

【Online: Query】 — per request, answers "how question finds answer"
User Query → Vector Retrieval → Rerank → Prompt Assembly → LLM Generation

2.1 Offline Phase: Turning a Refund Policy into a Searchable Index

Scenario: an e-commerce company wants to automate customer-service queries using its 5,000-word "Refund Policy v2.1" (Markdown).

① Document Loading

Parse various formats into clean text. PDFs are the hardest: scanned PDFs require OCR; tables often become garbled; code blocks must preserve formatting and language tags. Markdown sources are clean by comparison. For PDF-heavy corpora, allocate at least one-third of engineering time to this step.

② Chunk Splitting

Why chunk? Documents exceed context windows; embedding models have input limits (typically a few hundred tokens); chunking enables precise retrieval of the relevant segment rather than dumping the whole document.

The policy is split recursively by section:

7-Day No-Reason Return — ~500 words — Conditions, scope, non-eligible items

Refund Timeliness — ~400 words — Review time, arrival time, payment methods

Shipping Cost Rules — ~300 words — Buyer vs. seller bears cost, quality exceptions

Special Product Returns — ~350 words — Perishables, custom goods, electronics rules

Three chunking strategies compared:

Fixed-size — Every N characters — Simple, predictable — Ignores structure, splits paragraphs/tables

Structure-aware — Recursive by heading → paragraph → sentence — Respects document structure — Slightly complex

Semantic — Cut where adjacent-sentence embedding similarity drops — Purest topic coherence per chunk — Extra similarity computation, higher cost

Chunk size: no universal value; empirical starting point 256–1024 tokens with 10–20% overlap, then tune against actual retrieval quality. Overlap prevents boundary truncation — key info falling exactly on a split line would otherwise be lost.

③ Embedding

Embedding maps text to vectors so semantically similar texts have nearby vectors. Analogy: assign each fruit coordinates (sweetness, acidity, hardness); apples and oranges cluster together, potatoes lie far away. Real embeddings learn hundreds/thousands of dimensions automatically. They also capture semantic directions: King - Man + Woman ≈ Queen — the vector offset for gender. Similarity measured by cosine (direction only, ignoring magnitude).

⚠️ Critical Pitfall: Indexing and querying must use the same embedding model. If indexing used a 1536-dim model and query falls back to a 384-dim local model, the vector spaces are incompatible — retrieval returns nonsense silently. No error, no timeout, just garbage results. Fix: store model name in metadata at index time; at query time verify match and hard-fail on mismatch.

④ Vector Store Selection

Chroma — Lightweight embedded, local file persistence — Personal projects, ≤100k chunks

PGVector — PostgreSQL extension — Existing PG infra, avoid extra ops

Milvus — Distributed professional vector DB — Production scale, high availability

FAISS — Local library (not a service) — Offline batch experiments

Choose "good enough", not "strongest" — if data hasn't reached 100k chunks, Milvus's distributed capabilities are wasted. Three indexing details: store original text alongside vectors (retrieval returns text, not vectors); store metadata (source section, category, chunk ID) for later filtering; batch inserts to avoid memory spikes.

2.2 Online Phase: User Asks "Bought 3 Days Ago, Who Pays Return Shipping?"

Step 1: Vector Retrieval (Coarse Filter)

Query embedded, top-20 fetched by cosine similarity. Example results:

Rank  Section                 Snippet                                              Score
1     7-Day No-Reason Return  "Within 7 days of receipt..."                      0.89
2     Refund Process          "1-3 business days review, original payment..."    0.85
3     Shipping Cost Rules     "Return shipping borne by buyer; quality issues..." 0.83
4     Special Product Returns "Perishables, custom goods not eligible..."        0.78
5     Return Timeliness       "7 natural days from receipt..."                   0.76

User asked about shipping cost, but "Shipping Cost Rules" ranks only 3rd because coarse retrieval optimizes for overall semantic similarity to "return", not the specific keyword "shipping".

Step 2: Rerank (Fine Filter)

Top-5 fed to a cross-encoder for pairwise scoring:

Rank  Section                 Cross-Encoder Score  Change
1     Shipping Cost Rules     8.72                 ↑ from 3 to 1
2     7-Day No-Reason Return  6.35                 ↓ from 1 to 2
3     Special Product Returns 4.18                 ↑ from 4 to 3
4     Refund Process          2.05                 ↓ from 2 to 4
5     Return Timeliness       1.32                 ↓

"Shipping Cost Rules" jumps to #1. Coarse retrieval compares overall semantics; cross-encoder does token-level interaction — user's "shipping" matches document's "shipping cost" exactly, so score spikes.

Coarse retrieval is a headhunter scanning résumés in 5 seconds; rerank is the interviewer deep-diving one by one. Coarse for breadth, fine for precision.

Step 3: Prompt Assembly

Top-3 original texts inserted into prompt with source labels for traceability and an explicit "say I don't know if missing" guardrail:

You are an e-commerce support assistant. Answer using only the references below.
If the references lack the answer, say "I cannot answer" — do not fabricate.

[Ref 1] Shipping Cost Rules
Return shipping borne by buyer; quality issues → seller bears cost.
Shipping cost deducted from refund, no separate payment.

[Ref 2] 7-Day No-Reason Return
Within 7 days of receipt, item must be intact, packaging complete.
Exclusions: perishables, custom goods, opened electronics.

[Ref 3] Special Product Returns
Perishables, custom goods not eligible for no-reason return.
Opened electronics require inspection report.

User question: Bought 3 days ago, want to return, who pays shipping?

Step 4: LLM Generation

You are within the 7-day no-reason return window and can apply for return. Return shipping is borne by you and deducted from the refund. If the return is due to product quality, the seller bears the shipping cost.

Every number and rule traces to a specific reference: "7 days" from Ref 2, "buyer bears shipping" and "quality → seller" from Ref 1. Without the correct retrieval, the model would hallucinate.

One-liner: Offline four steps turn knowledge into searchable vectors; online four steps turn questions into precise answers. Both phases must use the same embedding model, otherwise vector spaces misalign and retrieval breaks.

03 How to Retrieve Accurately

3.1 Retrieval Landscape

Dense Vector — Semantic similarity — Synonyms, paraphrases, fuzzy queries — Exact codes, proper nouns — Fast

BM25 (Sparse) — Term frequency + rarity — Exact matches, model numbers, error codes — Synonyms, semantic rewrites — Fast

Hybrid — Parallel dense + sparse + RRF fusion — Blind spots complement — Double cost — Medium

Examples: Vector search for "puppy" finds "young dog" but misses exact "HTTP-403". BM25 nails "HTTP-403" but misses "kitty" when corpus says "cat". Hybrid runs both, fuses via RRF.

3.2 Hybrid Retrieval: Complementary Blind Spots

Dense scores 0–1, BM25 scores unbounded — cannot directly add. Solution: Reciprocal Rank Fusion (RRF) ignores scores, uses only ranks:

Combined Score = Σ 1 / (60 + rank)   # rank = position in that retriever's list

Manual example:

Doc A: dense rank 2, BM25 rank 3 → 1/62 + 1/63 = 0.0320
Doc B: dense rank 1, BM25 rank 50 → 1/61 + 1/110 = 0.0255

Doc A beats Doc B because both retrievers agree it's top-tier; Doc B is a "specialist" only in one. RRF logic: you're truly good only if both say so.

Hybrid is not mandatory. Use it only when users search exact strings (error codes, model numbers, names). Pure semantic tasks need only dense vectors.

3.3 Rerank: Precision After Coarse Filter

Coarse retrieval uses bi-encoder (query and doc encoded independently, then distance computed) for speed — document vectors precomputed offline. Rerank uses cross-encoder (query and doc concatenated, joint attention) for accuracy — token-level interaction but slower, so only applied to top-20–50 candidates.

Bi-Encoder (Dense Retrieval) — Query & doc encoded separately, then distance — No cross-attention during encoding — Very fast (offline doc vectors) — Recall (massive coarse filter)

Cross-Encoder (Rerank) — Query & doc concatenated, single forward pass — Full token-level cross-attention — Slow (realtime per pair) — Precision (dozens fine sort)

Bi-encoder = headhunter filtering by degree/years; cross-encoder = interviewer matching JD line by line. Coarse then fine yields both breadth and precision.

3.4 Quantifying Retrieval Quality

Three metrics, each answering a distinct question:

recall@k — Did we find the right answer at all? — Is the correct chunk in top-k?

MRR — Is the right answer ranked high enough? — Reciprocal rank of first relevant result

nDCG — Is the whole list well ordered? — Relevant items top, irrelevant bottom

Using the shipping-cost example (ground truth = "Shipping Cost Rules"):

Scheme A (dense only, no rerank):  1.7-Day  2.Refund  3.Shipping  4.Special  5.Timeliness
Scheme B (dense + rerank):        1.Shipping  2.7-Day  3.Special  4.Refund  5.Timeliness

recall@3: both 1 (correct chunk in top-3).

MRR: Scheme A = 1/3 ≈ 0.33; Scheme B = 1.0. MRR captures "how fast you find it".

nDCG: Scheme B higher because relevant item at top, irrelevant pushed down.

Evaluation protocol: sample 30–50 real user queries, human-label ground truth, run each config, compare metrics. Gut feeling "seems better" does not count.

One-liner: Hybrid search patches exact-match gaps, rerank promotes the truly relevant, RRF fuses by rank only; optimization lives or dies by recall@k numbers.

04 How to Retrieve Intelligently

4.1 Three Power Tools: Rewrite, Filter, Contextualize

Query Rewriting

User queries often contain unresolved references ("that thing"). Let an LLM rewrite into a self-contained query before retrieval:

User: "How to return that thing?"
→ LLM rewrite: "What is the refund/return process?"
→ Retrieval hits: Refund Policy, Refund Timeliness...

Cost: one extra LLM call. Gain: huge for ambiguous queries. User doesn't know your corpus terminology; LLM does — use it as translator.

Metadata Filtering

Filter by tags before vector search. In the e-commerce corpus, categories include "After-sales", "Loyalty Points", "Delivery Times". User asks about returns → filter category="After-sales" → vector search only within that slice. Cuts irrelevant noise in half. Misclassification cost is low — worst case falls back to full-corpus search.

Contextual Retrieval (Anthropic)

Chunking breaks cross-chunk references. Example: chunk contains "The company's revenue grew 3%" — "the company" resolved in previous chunk, now lost. Fix: before embedding, have LLM prepend context summary to each chunk:

Original chunk: "The company's revenue grew 3%, Q3 revenue broke 5B."
→ LLM adds context: "This document discusses Xiaomi Group's 2024 earnings.
The company's revenue grew 3%, Q3 revenue broke 5B."
→ Embed enriched chunk; vector now carries "Xiaomi" semantics.

Cost: one LLM call per chunk at index time. Benefit: Anthropic reports 67% reduction in retrieval failure rate when combined with BM25 + Rerank.

4.2 Agentic RAG: Retrieval as a Tool, Not a Mandatory Step

Classic RAG retrieves for every query — wasteful for common knowledge, noisy for irrelevant retrievals. Agentic RAG lets the model decide: whether to search, what to search, how many hops.

No search: "What is 7-day no-reason return?" — general knowledge, model knows, answer directly.

Single hop: "Bought 3 days ago, who pays shipping?" — one retrieval of "Shipping Cost Rules" suffices.

Iterative hops: "Double-11 purchase, can I still use the coupon if I return?" — touches two distinct policies.

Hop 1: Think → need return policy for promo period.
       Query: "Double-11 return policy"
       Found: "Promo items returned → coupon not refunded."
       But user may also ask "How is refund amount calculated?" — promo price ≠ original.
Hop 2: Think → need promo-order refund calculation.
       Query: "Promo order refund calculation"
       Found: "Refund based on actual paid amount; coupon portion not returned."
Synthesize: "Double-11 items returnable. Refund = actual paid. Coupon not restored."

Traditional RAG either misses the second fact or jumbles both in one noisy retrieval. Agentic RAG mimics a researcher: read, identify gaps, search again, synthesize.

One-liner: Query rewrite rescues vague questions, metadata filter cuts noise in half, contextual retrieval restores broken references; retrieval frequency follows content reusability — common knowledge answers directly, Agentic RAG lets the model decide.

05 Hands-On: Real Project Walkthrough

Project article-writer — an AI agent that writes WeChat articles. Key difference from the e-commerce bot: support retrieves "answers"; writing retrieves "style" . User says "Write an article about RAG" — the LLM already knows RAG; it needs the author's stylistic fingerprints: opening hooks, metaphor habits, paragraph rhythm, tone.

5.1 Offline: 197 Articles → Style Reference Library

Corpus: 197 Markdown articles across 11 directories (Spring 39, Java/JVM 30, Personal Growth 29, Management 28, etc.). Each chunk tagged with two metadata fields: style (technical/personal) and category (directory name). At query time, filter by style to retrieve only style-relevant chunks — filter style, not knowledge.

Chunking: One Real Article Dissected

Article: "Manually Build a Redis Distributed Lock" (7,745 chars). Params: 1,000 chars/chunk, 150-char overlap, back-scan to nearest blank line for paragraph boundary. Yields 10 chunks. Representative samples:

Chunk 1 (988 chars): Opening
"Hey folks, I'm Louzi. For Java devs, we don't need to hand-roll a distributed lock...
But these packaged libs make us lazier..."

Chunk 2 (796 chars): Core Problem — Lock Timeout
"Compare with current time to judge timeout. If not expired, return; if expired,
reset expiry, acquire lock. Other issues? Sure! In concurrency, threads A and B..."

Chunk 3 (907 chars): Concurrency Analysis
"Extending or shortening timeout — any issues? In real concurrency, both arrive
'simultaneously', time diff tiny..."

Chunk 1 shows typical tech-article opener: colloquial greeting + conversational lead-in. Chunk 2 uses rhetorical question pivot. Chunks 8–10 are boilerplate footer ("Follow my channel...") — pure noise, should have been cleaned pre-indexing.

Indexing: Actual Parameters

CHUNK_SIZE — 1,000 chars (~500–700 Chinese tokens) — Tried 2,000 → topic mixing; tried 500 → fragmented semantics. 1,000 sweet spot.

CHUNK_OVERLAP — 150 chars (~15%) — Prevents key info straddling split boundary.

Paragraph Boundary Back-scan — From split point, scan backward for blank line — Avoids mid-paragraph cuts.

Embedding Model — OpenAI text-embedding-3-small (1,536-dim) primary; fallback local bge-small-zh-v1.5 (384-dim) — Primary for quality; fallback for resilience. Must match at query time.

Batch Insert — 50 chunks/batch — Avoids memory spikes.

Metadata — style (technical/personal) + category (directory) — Auto-derived from folder structure; used for style filtering.

197 articles → ~2,800 chunks → 28 MB vector store. Fits in a single ChromaDB embedded file.

5.2 Online: Writing an RAG Article — How the System Finds Style References

Step 1: Style Classification

User prompt: "Write a technical article about RAG principles and practice." Keywords "RAG", "principles", "practice" → filter style=technical, excluding personal-style chunks ("My Anxiety", "Mid-Career Crisis").

Step 2: Vector Retrieval (Coarse)

Query: "RAG principles practice technical article". Top-20 fetched. These are not RAG knowledge — they are style exemplars from past technical articles. Top-5 coarse results:

Rank  Source Article                              Score  Style Signal
1     Manually Build Redis Distributed Lock       0.842  Colloquial opener: "Hey folks, I'm Louzi"
2     MySQL Single-Table Row Limit                0.817  Data-driven: lead with numbers
3     Redis High-Availability Principles          0.814  Analogy: life examples for technical concepts
4     Single-Node Cron? Multi-Node YYDS!          0.794  Rhetorical question: "What other strategies?"
5     MySQL-Redis Consistency                     0.788  Table comparison: solution diffs

Noise present: test logs, "Recommended Reading" footers — retrieved due to keyword overlap but irrelevant to style.

Step 3: Rerank (Fine)

Cross-encoder rescoring:

Rank  Source Article                              Cross-Encoder  Change
1     Manually Build Redis Distributed Lock       0.998          stays #1
2     MySQL Single-Table Row Limit                0.996          stays #2
3     Redis High-Availability Principles          0.994          ↑ (noise dropped)
4     MySQL-Redis Consistency                     0.992          ↑ from #5
5     Single-Node Cron? Multi-Node YYDS!          0.990          ↓ from #4

Noise chunks (test logs, footers) fall out of top-5 — cross-encoder token-level matching reveals low relevance to "RAG technical article". Same pattern as e-commerce: coarse = overall similarity; fine = local token alignment.

Step 4: Prompt Assembly

You are a WeChat article writing assistant. Mimic the style of the following historical articles.

[Style Ref 1] (Source: Manually Build Redis Distributed Lock)
"Hey folks, I'm Louzi. For Java devs, we don't need to hand-roll a distributed lock...
But these packaged libs make us lazier."

[Style Ref 2] (Source: MySQL Single-Table Row Limit)
"I said MySQL single table best under 20M rows, interviewer said go wait for notice?"

[Style Ref 3] (Source: Single-Node Cron? Multi-Node YYDS!)
"Leave a question: if one record always fails, every fetch gets it first.
What strategy can defer it?"

Now, using the above tone, sentence patterns, paragraph cadence, write a technical article about RAG principles and practice.

The agent imitates voice, syntax, rhythm from retrieved fragments. RAG supplies style; knowledge comes from LLM's own weights.

Pipeline identical to Chapter 2 — chunk, index, coarse, fine, prompt. Same plumbing, different purpose.

Honest caveat: RAG for style matching works poorly. RAG retrieves by semantic similarity (topic proximity), not stylistic similarity. Two articles on totally different topics can share identical style — RAG cannot detect that. This case study demonstrates pipeline adaptability; real RAG sweet spot is knowledge retrieval (policies, docs, procedures) — the e-commerce bot is the true main battlefield.

One-liner: 197 articles → 2,800 chunks → 28 MB vector store → full coarse-to-fine query trace. Theory and artifact side by side — that's when RAG clicks.

06 Closing Summary

Chapter 1 — Why RAG: hallucination, stale knowledge, private-data blindness. RAG = open-book exam.

Chapter 2 — Full pipeline: offline 4 steps (load, chunk, embed, store) + online 4 steps (retrieve, rerank, prompt, generate). E-commerce case study end-to-end.

Chapter 3 — Accurate retrieval: dense for semantics, BM25 for exact terms, RRF fusion, cross-encoder rerank. Evaluation via recall@k, MRR, nDCG.

Chapter 4 — Intelligent retrieval: query rewrite for ambiguity, metadata filter for noise, contextual retrieval for broken references, Agentic RAG for on-demand multi-hop.

Chapter 5 — Real project validation: 197 articles → 2,800 chunks, complete coarse-to-fine walkthrough. Theory meets artifact.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

RAGEvaluation Metricsretrieval-augmented generationVector DatabasesEmbedding ModelsHybrid SearchAgentic RAGRerankingContextual RetrievalChunking Strategies
Su San Talks Tech
Written by

Su San Talks Tech

Su San, former staff at several leading tech companies, is a top creator on Juejin and a premium creator on CSDN, and runs the free coding practice site www.susan.net.cn.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.