RAG Beginner Learning Notes
Starting point: the asset semantic-search project from [[20260522.SearchToolDesign(Private)]]
Goal: understand the principles of RAG → run a minimal demo against local image data
1. What Is RAG?
RAG = Retrieval-Augmented Generation
In one sentence: first find relevant content from a knowledge base, then use that content to help the AI answer the question.
1.1 Why Do We Need RAG?
| Problem | How RAG Solves It |
|---|---|
| LLM training data has a cutoff date and misses new information | The retrieval stage can query the latest data in real time |
| LLMs don’t know about private data (e.g. a company’s internal asset library) | Index the private data so it can be retrieved and injected into the LLM |
| LLMs “hallucinate” — they make up facts out of thin air | Provide real retrieved documents as the basis for answers |
| LLMs have a limited token window and can’t fit all the material | Only retrieve the few most relevant document chunks |
2. The Complete RAG Pipeline
1 | ╔══════════════════════════════════════════════════════════╗ |
The asset-search tool only does the first two stages — it turns an artist’s query into a vector, finds the most similar assets, and returns them directly. This is the retrieval subset of RAG, academically called Semantic Search or Dense Retrieval.
3. Core Concept Explanations
3.1 Embedding (Vectorization)
Compress any content (text, images) into a fixed-length list of numbers (a vector), such that:
- Semantically similar content → vectors that are close in space
- Semantically different content → vectors that are far apart in space
1 | "a willow tree" → [0.12, -0.34, 0.87, ..., 0.05] (768-dim) |
Common Embedding Models:
| Model | Input Type | Dim | Highlights |
|---|---|---|---|
| BGE-M3 (BAAI) | text | 1024 | Strongest for Chinese, friendly to local deployment |
| CLIP (OpenAI) | image + text | 512 | Images and text share the same vector space ⭐ |
| SigLIP (Google) | image + text | 768 | Improved version of CLIP, better zero-shot |
| GTE-Qwen2 (Alibaba) | text | 768 | Multilingual, commercial Apache 2.0 |
3.2 FAISS (Vector Similarity Search Library)
FAISS = Facebook AI Similarity Search (open-sourced by Meta)
Why do we need it?
When you have 20,000 vectors and want to find the Top-10 most similar to a query vector, comparing them one by one needs 20,000 computations. FAISS uses special data structures to speed this up by tens to thousands of times.
An analogy:
- Brute-force search = flip through every book in a library to find the one closest to your interests
- FAISS = the library is partitioned by topic, and you go straight to the “Botany” shelf
Three Main Index Types:
| Type | Principle | Accuracy | Speed | Suitable Scale | Our Choice |
|---|---|---|---|---|---|
IndexFlatL2 |
Exact; compare one by one | 100% | medium (but more than enough) | < 100K | ✅ preferred |
IndexIVFFlat |
Cluster first, then search | ~98% | fast | 100K–10M | future expansion |
IndexHNSWFlat |
Graph-structure navigation | ~99% | fastest | any | over-engineered |
It’s exact, the code is simplest, single-query latency < 1ms, fully meets the need.
3.3 Similarity Metrics
| Metric | Formula Meaning | When to Use |
|---|---|---|
| L2 distance (Euclidean) | Straight-line distance in vector space; smaller = more similar | FAISS default; image retrieval |
| Cosine similarity | Cosine of the angle between two vectors; closer to 1 = more similar | More common for text retrieval |
| Inner product (dot product) | Direction + magnitude together | OpenAI CLIP’s official recommendation |
4. Image RAG (The Special Power of CLIP)
The core innovation of CLIP: make images and text share the same vector space.
1 | "a willow tree" (text) → CLIP text encoder → vector A |
This means you can:
- text → image: input “give me a flowchart” and find the most similar images in the library
- image → image: upload a reference image to find assets with similar style
- image → text: input an image to find the most relevant descriptive documents
This is exactly the principle behind the “text-to-image search” feature of the asset-search tool.
5. Local Demo Plan
5.1 Goal
Run a minimal image semantic-retrieval demo using the blog images (PNG/JPG) in D:\Project\UGit\MyPicGo\Images\:
- Input: a piece of text description (e.g. “code screenshot”, “flowchart”, “UI interface”)
- Output: paths to the Top-5 most similar images in the library
5.2 Tech Stack
1 | D:\Project\UGit\MyPicGo\Images\ (blog images, ~100+ PNGs/JPGs) |
5.3 Hands-on Process
- Create project directory
D:\Project\UGit\PicGoRAGDemo\+ Python venv - Install deps:
torch / transformers / faiss-cpu / modelscope / Pillow / numpy - Write
build_index.py(indexing stage) +search.py(query stage) - Run
python build_index.py: encode 225 images into 225 × 512-dim vectors, build FAISS index and dump to disk (~15s on CPU) - Run
python search.py "query"to validate retrieval (single query < 100ms)
Three key pitfalls:
- transformers 5.x changed the CLIP API:
get_image_features(...)now returnsBaseModelOutputWithPooling(not a bare Tensor anymore); you must call.pooler_outputto get the 512-dim vector. - HuggingFace is unreachable from mainland China: direct connection times out and mirrors are unstable; switch to ModelScope (Alibaba’s ModelScope — domestic servers, no obstacles).
- ModelScope uses different naming: HF’s
OFA-Sys/chinese-clip-vit-base-patch16corresponds toAI-ModelScope/chinese-clip-vit-base-patch16on ModelScope (AI-ModelScopeis the HF-format mirror namespace on ModelScope; the file structure is identical to HF andtransformers.AutoModelcan load it directly).
5.4 Test Findings: Comparing Chinese vs English Query Effectiveness
Real testing found that English queries are slightly more accurate:
| Query | Model | Retrieval Result |
|---|---|---|
"code screenshot" |
OpenAI CLIP | ✅ Top-3 are all code screenshots |
"flowchart" |
OpenAI CLIP | ✅ Top-3 are all flowcharts |
"代码截图" (code screenshot) |
Chinese-CLIP | ✅ Top-3 are all code screenshots |
"流程图" (flowchart) |
Chinese-CLIP | ⚠️ Top-3 contains flowcharts but mixes in a few unrelated images |
Possible reason: the blog images are mostly English-language technical screenshots (code, terminal, UI text are mostly in English). OpenAI CLIP simultaneously recognizes English text + visual features, so its hits are more reliable; Chinese-CLIP’s training data leans toward Chinese everyday/news content and isn’t sharp enough on the boundaries of technical visual concepts like “flowchart”.
This validates the core point from §6.1: the performance of an embedding model on your domain depends on the training data distribution — choose models based on the scenario.
5.5 Complete Code
build_index.py (indexing stage)
1 | """build_index.py — encode N images into N 512-dim vectors and build the FAISS index |
search.py (query stage)
1 | """search.py — text query → CLIP text encoding → FAISS Top-K → print paths |
6. Learning Resources
6.1 Introductory Articles (Easy → Deep)
| Resource | Type | Stage |
|---|---|---|
| IBM Technology: What is RAG? | 5-min video | Absolute beginner; concepts explained clearly |
| Retrieval-Augmented Generation — LangChain official docs | illustrated tutorial | understand the pipeline, code samples |
| Building RAG from Scratch — Towards Data Science | blog post | no framework needed; raw FAISS + Python |
| LlamaIndex official tutorial | hands-on | engineering framework, production-grade RAG |
| OpenAI Cookbook — RAG | code samples | advanced, includes evaluation metrics |
6.2 Must-Read Papers (Optional)
| Paper | Year | Why Read |
|---|---|---|
| RAG for Knowledge-Intensive NLP Tasks (Lewis et al.) | 2020 | The conceptual origin of RAG |
| CLIP: Learning Transferable Visual Models (Radford et al.) | 2021 | Foundation of image-text alignment |
| SigLIP: Sigmoid Loss for Language Image Pre-Training | 2023 | Improved version of CLIP; follow-up progress |
6.3 Chinese Resources
- BAAI BGE series documentation: official docs for Chinese embedding models; directly guides model selection
- Zhihu “RAG Practice”: notes on pitfalls by Chinese engineers; very practical
- Bilibili @跟李沐学AI: deep-learning fundamentals; necessary background for understanding embeddings
7. Notes
Module 1: RAG Overview
1. RAG Architecture

Inside a RAG system, there is first a retriever that has access to the database and fires off a query (similar to a database). The retriever then receives the result of the query (the information deemed most relevant). It then uses this written, possibly most relevant information to generate an augmented prompt.
1 | # ============================================================ |
2. Understanding RAG Through LLMs
LLMs are essentially constantly predicting the probability distribution of the next value to appear; RAG changes that distribution.
3. Information Retrieval: RAG Retrieve vs Search Engine vs Database Query
All three are “looking for things”, but the underlying matching logic is completely different:
| Dimension | Search Engine (BM25/TF-IDF) | Database Query (SQL) | RAG Retrieve (Vector Search) |
|---|---|---|---|
| Matching method | keyword term-frequency stats | exact field matching | semantic similarity (vector distance) |
| Query language | natural-language bag of words | structured SQL | any content (text / image / audio) |
| Understands synonyms? | ❌ partially (needs dictionary) | ❌ not at all | ✅ natively supported |
| Cross-modal? | ❌ text only finds text | ❌ | ✅ text finds images (CLIP) |
| Result ranking basis | TF-IDF score | no ranking (exact match / filter) | vector-space distance (cosine / L2) |
| Data-structure requirement | needs inverted index | needs strict schema | only needs vectors; raw structure unrestricted |
| Suited for | “find docs containing these words” | “find records matching these conditions” | “find semantically most relevant content” |
A one-line distinction of essence:
1 | Database query — "Are they exactly equal?" (exact) |
RAG is not a “perfect replacement” for the first two; in production, vector retrieval + BM25 are often combined, then re-ranked with a Re-ranker. Vector retrieval handles semantic generalization; BM25 handles keyword anchoring; the two complement each other.
Module 2: Information Retrieval & Search Techniques
1. Retriever Architecture Overview
Metadata Filtering
Before or after vector retrieval, use structured fields to hard-filter the candidate set, shrinking the retrieval scope.
- Principle: documents are ingested with metadata fields (e.g. source, date, category); during query, filter first, then rank by vector similarity.
- Advantage: dramatically reduces interference from irrelevant documents, improves both precision and retrieval efficiency.
- Limitation: relies on metadata quality at ingestion time; missing or misclassified fields can wrongly filter out effective documents. It doesn’t understand content and is almost never used alone.
Keyword Searching
Searches documents by exact-word matching; the most classical search method. Mainly includes TF-IDF and BM25.
- Principle: split the query into tokens, compute term frequency (e.g. BM25), return documents containing those words.
- Advantage: fast, results explainable, accurate hits on proper nouns (codes, IDs, model numbers).
- Limitation: doesn’t understand synonyms or paraphrases — say it differently and you might not find it.
Both score by term frequency, but BM25 improves on TF-IDF: TF-IDF grows linearly with term frequency; BM25 adds term-frequency saturation (diminishing returns for high-frequency words) and document-length normalization, making weight more reasonable whether a term appears once in a short doc or many times in a long one. In practice BM25 is better.
Semantic Searching
Encode text into vectors and compute vector similarity to match “similarly-meaningful” content.
- Principle: use an Embedding model to map both query and documents into a high-dimensional vector space; measure distance using cosine similarity, etc.
- Advantage: captures semantic generalization; finds related content even when phrased differently.
- Limitation: higher compute cost; less reliable than keyword search for exact terms (e.g. specific IDs).
2. Two Common Keyword-Retrieval Algorithms in Detail
TF-IDF
Core formula: Score = TF(term, doc) × log(total docs / docs containing term)
- TF (term frequency): the more a term appears in the current doc, the more relevant
- IDF (inverse document frequency): the more docs contain a term, the more “filler” it is — weight drops; rarer terms get higher weight
- Result: high-frequency function words like “the”, “is” score near zero; proper nouns like “quantum entanglement” or “BM25” score high
BM25 (the industry-grade improvement of TF-IDF; Elasticsearch’s default algorithm)
Core improvements:
| Problem | TF-IDF | BM25 |
|---|---|---|
| Term-frequency stacking | 100 occurrences = 100× score | term frequency saturates; diminishing returns (parameter k1, default 1.2–2.0) |
| Long documents naturally favored | over-penalizes | normalized by average doc length (parameter b, default 0.75) |
k1: controls how fast term frequency saturates; higher means “saying it more makes it more important”; lower means “3 times and 100 times are nearly the same”.b: controls length penalty strength;b=0ignores length,b=1strictly scores by density; 0.75 is an industry empirical default.
3. Similarities and Differences Between Semantic Search and Keyword Search
1. Common ground: Digitization
- Prompt and documents each get a vector:
No matter the search type, the computer can’t directly “read” text. The first step is always turning both the user’s question and the documents in the database into a list of numbers, called a vector. - Vectors compared to generate scores:
Once converted into numbers, the computer can use math formulas (e.g. cosine similarity) to compute the “distance” between two vectors. The closer, the higher the score, the more relevant.
2. Core difference: How is the vector generated?
Keyword Search: Count word occurrences
- Principle: the result is called a sparse vector.
- Logic: each position of the vector represents a specific word. If the document contains that word, the corresponding position gets a score (based on term frequency, e.g. BM25).
- Characteristic: literal matching; only recognizes “identical-looking” words.
Limitation: searching for “doctor” won’t find a document containing “physician” but not “doctor”, because it doesn’t understand word meaning.
Semantic Search: Use an embedding model
- Principle: the result is called a dense vector.
- Logic: instead of counting words directly, text is fed into a pre-trained deep learning model (Embedding Model, e.g. BERT). The model “maps” the text into a multidimensional semantic space.
- Characteristic: understands meaning; the numbers in the vector represent abstract “features” or “concepts”.
Advantage: recognizes synonyms; even if words don’t match, as long as the “meaning” is close (e.g. “cat” and “kitten”, “doctor” and “physician”), their vectors are mathematically close in space.
3. RRF Algorithm (Balancing Keyword and Semantic)
It is the core technique in hybrid retrieval. When you run both “keyword retrieval” and “semantic retrieval” in your RAG system, you get two completely different scoring lists. RRF (Reciprocal Rank Fusion) merges these two lists fairly into one final ranking list.
1. Core problem: The “apples and oranges” comparison dilemma
Hybrid retrieval faces a fundamental difficulty:
- Keyword (BM25) scores may be
15.4,12.8, etc. - Semantic (vector-search) scores (cosine similarity) typically range between
0.8and0.9. - Problem: these two scores have different units and cannot be directly summed or compared.
RRF’s solution: completely ignore raw scores; only look at documents’ positions (ranks) in the lists.
2. Core mechanism
- Reward “consensus” documents: if a document ranks high in both keyword search and semantic search, RRF gives it an extremely high final score.
- Normalize weights across searches: provides a fair comparison across strategies; neither algorithm can dominate just because its score range is larger.
- Score = reciprocal of rank (the origin of the algorithm’s name):
- Rank 1 →
1/1 = 1.0score - Rank 2 →
1/2 = 0.5score - Rank 10 →
1/10 = 0.1score - Logic: higher rank = higher score; the score drops faster as rank drops.
- Rank 1 →
- Aggregate scores: sum each document’s reciprocal score across all lists; the one with the highest total wins the final ranking.
3. Formula
$$RRF(d) = \sum_{i=1}^{n} \frac{1}{k + rank_i(d)}$$
rank_i: documentd‘s ranking in thei-th retrieval list (starting from 1).k: smoothing constant, the industry default is usually 60.
Why is k needed?
Without k, the gap between rank 1 (1.0 score) and rank 100 (0.01 score) is enormous, giving the first-ranked document overwhelming power. k acts as a “shock absorber” — compressing extreme differences and weakening the influence of noisy documents that happen to land at rank 1.
| Parameter Value | Effect | Risk |
|---|---|---|
k = 0 (extremely sensitive) |
Rank 1 has absolute dominance | If one algorithm accidentally puts a noisy doc at rank 1, it disrupts the whole RAG result |
k = 60 (smooth and robust, industry default) |
High rank in a single list no longer monopolizes | No obvious risk; requires multiple retrieval strategies to agree for a doc to win |
4. RRF’s core advantage: Only cares about rank
- No score normalization needed: no need to convert BM25’s 20 score and vector search’s 0.9 score — compare positions directly.
- Seamless cross-strategy merging: with 2 or 5 different retrieval techniques, as long as each gives a rank list, RRF can fuse fairly.
5. Parameters for tuning semantic vs keyword weights
Standard RRF itself has no direct “semantic vs keyword” weight parameter — k is just a smoothing constant, not a control over their ratio.
But Weighted RRF introduces an independent weight w for each retrieval strategy in the formula:
$$RRF(d) = \sum_{i=1}^{n} \frac{w_i}{k + rank_i(d)}$$
- Increase
w_semantic→ results skew toward semantic understanding (synonyms, conceptual relevance) - Increase
w_keyword→ results skew toward exact literal matching
Where do you tune this weight in an actual implementation?
Take LangChain‘s EnsembleRetriever as the most intuitive example:
1 | from langchain.retrievers import BM25Retriever, EnsembleRetriever |
weights=[0.3, 0.7]arew_keywordandw_semanticfrom the formula. Increase semantic → better at understanding intent; increase keyword → better at exact proper-noun matching.
4. Evaluation Metrics
Quantifying how good a retriever is with numbers is the scientific basis of system tuning.
Three core metrics
| Metric | Core Goal | One-Line Explanation |
|---|---|---|
| Recall@K | “find all of them” | Among the top-K results, how many genuinely relevant docs were found |
| Precision & MAP | “find precisely + rank well” | Precision measures how much noise is in what you return; MAP further evaluates whether relevant docs are at the top |
| MRR (Mean Reciprocal Rank) | “first hit” | The earlier the first relevant doc appears, the higher the score |
A concrete example to understand Precision and Recall
Scenario: the knowledge base has 100 docs, of which 10 are truly relevant (Ground Truth). The retriever returns 8, of which 6 are truly relevant.
$$Precision = \frac{\text{returned and relevant}}{\text{total returned}} = \frac{6}{8} = 75%$$
$$Recall = \frac{\text{returned and relevant}}{\text{all relevant docs in the library}} = \frac{6}{10} = 60%$$
Precision: from the perspective of “the docs you returned” — how many are real, how much is noise?
Recall: from the perspective of “the knowledge base” — of the 10 correct answers, how many did you find?
The intrinsic tension between Precision and Recall
The two naturally pull against each other:
| Action | Precision | Recall | Reason |
|---|---|---|---|
| Larger K (e.g. 8 → 50) | ⬇️ drops | ⬆️ rises | catch more; more noise, fewer misses |
| Smaller K (e.g. 8 → 3) | ⬆️ rises | ⬇️ drops | only the surest picks; precise but incomplete |
Practical uses of metrics
- Establish baseline performance: score your current system and make clear where you are
- Validate optimization impact: when changing Embedding model, adjusting Chunk size, or modifying hybrid-retrieval weights, compare before/after metrics to confirm whether the change actually worked
The most critical prerequisite: Ground Truth
All metrics depend on a “ground truth” dataset
- What is Ground Truth? A human-annotated dataset. For example, for question A, pre-annotate that “doc 1” and “doc 5” are the only correct answers in the knowledge base.
- Why does it matter? Recall, Precision, MAP, MRR all require comparing “system’s answers” against “standard answers”. Without Ground Truth, scientific tuning is impossible.
5. Embedding Model In-Depth
Contrastive Training Process
Training objective: pull vectors of similar content closer, push vectors of dissimilar content apart.
Positive Samples: From “Natural Pairings on the Internet”
Humans’ natural behavior on the internet inherently produces massive paired data:
| Data Source | Positive Sample Pairing | Who “labels” it? |
|---|---|---|
Image alt attributes on web pages |
<img alt="willow tree at sunset"> → (image, “willow tree at sunset”) |
Web authors writing alt text unconsciously create the pairing |
| Forum Q&A (StackOverflow, Zhihu) | (question, best answer) | Users asking and answering unconsciously create the pairing |
| Wikipedia | (article title, first paragraph) | Humans writing encyclopedias — the structure naturally pairs |
| News images | (photo, caption) | Editors writing captions unconsciously create the pairing |
Core idea: the internet itself is a huge “implicit-annotation dataset”. When humans create content in daily life, they are unconsciously labeling data for AI.
Negative Samples: Automatically Generated by Algorithms
| Negative Type | Source | Needs Human? |
|---|---|---|
| In-batch negatives | other samples in the batch automatically play the role | ❌ fully automatic |
| Random negatives | sampled at random from the dataset | ❌ fully automatic |
| Hard negatives | use a weak model to first retrieve “close but wrong” samples | ⚠️ partly needs human verification |
| LLM-generated hard negatives | let GPT-4 generate semantically similar but different sentences | ❌ AI-generated |
Rare Scenarios That Need Human Annotation
Only when you need a high-precision Benchmark (used to test how good a model is) do you bring in human annotation:
1 | STS (Semantic Textual Similarity) dataset: |
Training process: forward pass generates vectors → build similarity matrix → InfoNCE loss penalizes cases where “positive samples don’t rank high” → backprop updates weights.
CLIP’s 400M training pairs are almost entirely auto-acquired. The internet itself is the implicit-annotation dataset; human annotation is only used for evaluation benchmarks, not as the main training data.
I also feel that this training process is quite similar to the node graph on my personal website — the node graph has repulsive and attractive forces, the entire node-graph system needs to maintain a stable state. Therefore, to maintain the balance of repulsion and attraction, it needs an adjustment process. And I think this adjustment process may be exactly what embedding is.
A common misconception — LLM parameters vs Embedding dimensions: parameters are the total weights inside the neural network (CLIP has ~150M), i.e. the knowledge learned during training; the dimension is the length of the output vector (e.g. 512), a fixed spec at design time. Parameters are the total knowledge the model learned (the more, the “smarter”); the dimension is the length of the output vector (it bounds the upper limit of expressiveness). They are not the same thing.
Module 3: Information Retrieval with Vector Data
1. From Brute-Force Search to ANN
All vector-retrieval algorithms share one key variable — K: the number of vectors most similar to the query (Top-K) to return. Around “how to efficiently find these K vectors”, two major schools have evolved: exact retrieval and approximate retrieval (ANN).
The most basic algorithm: brute-force search (Brute Force / Flat Search / Linear Scan)
The simplest direct approach — compute the distance (cosine / Euclidean) between the query vector and every vector in the database, then sort and take the Top-K.
In FAISS it’s called
IndexFlatL2; in academia it’s called Exact KNN; in engineering it’s often called Brute Force or Linear Scan. They’re all the same thing: build no index, brute force to the end.
- Pros: trivial to implement (one line of numpy); Recall = 100%, the accuracy ceiling and evaluation baseline of all ANN algorithms
- Fatal problem: complexity is O(N×D) (N = number of vectors, D = dimension). The bigger the database, the slower a single query — millions of vectors is already hard; billions are outright unusable
- Suitable for: small datasets (< 100K), offline evaluation, providing ground truth for ANN
The solution: ANN (Approximate Nearest Neighbor) search
Core idea: pre-build an index, skip most vectors that can’t possibly be relevant, only do fine-grained comparison in a small range — sacrificing a tiny bit of accuracy in exchange for orders-of-magnitude faster queries.
Mainstream implementations:
- HNSW (Hierarchical Navigable Small World graphs): based on “skip-list + small-world networks”; complexity drops to O(log N); high accuracy and fast queries — industry mainstream
- IVF (Inverted File Index): first K-means clustering; at query time only scan the nearest few clusters — suited for very large scale
- PQ (Product Quantization): splits high-dim vectors into segments then replaces with cluster codes — compresses vectors 64× or more, dramatically saving memory
In engineering you must trade off between accuracy (Recall) ↔ speed (QPS) ↔ memory; common combinations are IVF+PQ, HNSW+PQ.
2. Vector Databases
A vector database is a database system designed specifically for storing, managing, and retrieving high-dimensional vectors. Ordinary databases store structured rows and columns; vector databases store Embedding vectors — and have ANN indexes built in, making semantic retrieval a first-class citizen.
Core differences from traditional databases
| Dimension | Relational DB (MySQL) | Vector DB (Qdrant / Milvus) |
|---|---|---|
| Core data | structured rows & columns | high-dim float vectors |
| Query method | SQL exact matching | ANN approximate-similarity retrieval |
| Index type | B-Tree, Hash | HNSW, IVF, PQ |
| Typical question | “find record with id=42” | “find Top-10 semantically most similar” |
Vector databases usually store vectors + metadata together, supporting “first hard-filter by metadata, then do vector retrieval” — i.e. the combination of Metadata Filtering and semantic retrieval mentioned earlier.
Mainstream Vector Database Comparison
- Qdrant: written in Rust; strong performance; REST/gRPC API; supports payload filtering; open source, self-hostable
- Milvus: designed for very large scale (billions); cloud-native architecture; suited for production distributed scenarios
- ChromaDB: lightest, starts in a few lines of code; first pick for dev/debugging, not suited for large-scale production
- pgvector: PostgreSQL extension; add vector retrieval to an existing PG database with no new system
- FAISS: strictly speaking a library, not a database — no persistence, no CRUD, but the source of all vector DB algorithms underneath
Basic Process for Creating a Vector Database
Step 1 — Database Setup
Create a collection and define its schema — specifying which fields to store, the vector dimension, and which distance metric to use (cosine / L2 / inner product). This is the container for all subsequent operations, equivalent to creating a table.
Step 2 — Loading Documents
Read raw data (text, PDFs, images, etc.) into memory, chunking as needed — splitting long documents into small chunks suitable for embedding, to avoid semantic dilution when a chunk is too long.
Step 3 — Sparse Vectors (for keyword retrieval)
Use algorithms like BM25 to generate sparse vectors for each document chunk — most positions are zero; only positions for terms that appear have weights. Designed for exact keyword matching; this is the keyword side of hybrid retrieval.
Step 4 — Dense Vectors (for semantic retrieval)
Pass document chunks through an Embedding model (e.g. BGE, CLIP), outputting a dense vector for each chunk — every dimension has a value, carrying semantic information. The core of semantic search; understands synonyms and intent.
Step 5 — Build the HNSW Index
Build an HNSW (Hierarchical Navigable Small World) index on top of the dense vectors. Pre-weave a “navigation network” among the vectors; at query time you follow graph jumps to locate, reducing complexity from O(N) to O(log N) and achieving millisecond-level ANN search. This step can be skipped; if skipped, you have brute-force retrieval.
3. Chunk (Chunking Techniques)
Splitting long documents into small chunks suitable for embedding is the key pre-processing step of the RAG indexing stage. Too-large a chunk dilutes semantics; too-small a chunk loses context; whether you split well directly affects retrieval quality.
Why do we need chunking?
Embedding models have a token limit (e.g. BERT series 512 tokens, BGE-M3 8192 tokens). Stuffing an entire book in only yields one fuzzy “average semantic”, and retrieval will struggle to hit specific passages. After chunking, each chunk has its own independent vector, and retrieval precision improves dramatically.
Main chunking strategies
- Fixed-size Chunking: hard-cut by character or token count; crude. Downside: may cut mid-sentence and lose context. Usually paired with Overlap — adjacent chunks share some tokens — to mitigate the truncation issue.
- Semantic Chunking: cuts along sentence boundaries, paragraphs, heading hierarchy; preserves natural semantic integrity. Suited for structured documents (Markdown, PDF).
- Recursive Character Splitting: LangChain’s default strategy; tries priorities like
\n\n → \n → period → spacein order, cutting on natural boundaries as much as possible; balances simplicity with semantic completeness.
4. Some More Advanced Chunking Techniques
Using LLMs for Semantic Chunking
Traditional chunking relies on rules (paragraphs, headings, fixed size); “LLM semantic chunking” lets the model truly understand the semantic boundaries of content before deciding how to cut — higher quality but also higher cost.
① Embedding-similarity-based Semantic Chunking (SemanticChunker)
Principle: split text into sentences first → compute embedding for each sentence → compute cosine similarity of adjacent sentences → when similarity drops sharply, the topic has shifted; cut there.
1 | sentence1 → sentence2 → sentence3 ↘↘sharp drop↘↘ sentence4 → sentence5 |
- Tool: LangChain’s
SemanticChunkerdirectly wraps this logic - Pros: no LLM inference needed; low cost; truly cuts by semantic breakpoints, not by character count
- Cons: needs a similarity threshold; a badly-chosen threshold cuts too finely or too coarsely
② Proposition Chunking
Principle: use an LLM to further distill each text segment into several atomic propositions — each proposition is an independent, complete, self-contained minimal fact unit.
Example: original text “Einstein published the special theory of relativity in 1905 and won the Nobel Prize for the photoelectric effect”
→ Proposition 1: “Einstein published the special theory of relativity in 1905”
→ Proposition 2: “Einstein won the Nobel Prize for his research on the photoelectric effect”
- Pros: at retrieval time, query and proposition map one-to-one; precision is extremely high; each proposition is self-contained, understandable without context
- Cons: every chunk must invoke an LLM to distill — token-heavy and slow; indexing is expensive
- Suited for: scenarios that demand the highest knowledge-base retrieval quality (medical, legal, precision Q&A)
③ Agentic Chunking
Hand the whole document directly to the LLM, letting it autonomously decide semantic boundaries, output split points, or output the chunks directly. Most flexible; can handle complex unstructured documents (e.g. dialogue records, mixed-format docs) but highest cost; generally only used in offline preprocessing pipelines.
Comparison of the three approaches
| Approach | Calls LLM? | Cost | Precision | Suited Scenarios |
|---|---|---|---|---|
| Embedding similarity | only Embedding model | low | medium | general scenarios; quick build |
| Proposition chunking | yes (distill propositions) | high | high | precision Q&A, knowledge bases |
| Agentic chunking | yes (understand + cut) | highest | highest | complex unstructured docs |
The most common pragmatic compromise: first use recursive character splitting for rough cuts, then use embedding similarity for semantic-boundary correction; only enable proposition chunking on core knowledge-base passages.
5. Query Parsing
User questions are often colloquial, vague, and contain multiple sub-intents — using them directly for retrieval, vector similarity will drift, missing genuinely relevant documents. The goal of “query parsing” is to use an LLM to make the question more retrieval-friendly before retrieval.
Core idea: before Retrieval, use one (or more) LLM calls to transform the Query, then retrieve.
Query Rewriting
Principle: directly use an LLM to rewrite the user’s original question into one (or more) new queries that are more precise and closer to the language of the knowledge-base documents.
Example: user asks “how to fix this bug” → rewritten: “how to fix an IndexError array-out-of-bounds exception?”
Why it works: Embedding models use symmetric similarity — the more alike the user’s words and the document’s words, the closer the vectors. Rewriting bridges the “colloquial ↔ document language” vocabulary gap.
1 | # Rewrite prompt sketch |
- Pros: simple to implement; one LLM call; significantly improves vocabulary-mismatch
- Cons: the rewrite may drift from the original meaning; adds one LLM’s latency
Query Decomposition
Principle: faced with a complex query containing multiple sub-questions, let the LLM break it into several independent sub-questions; each sub-question retrieves separately; finally aggregate the answers.
Example: user asks “What are the pros and cons of Python vs JavaScript in web development, and which should I choose?”
→ sub-question 1: “What are the pros of Python for web development?”
→ sub-question 2: “What are the cons of Python for web development?”
→ sub-question 3: “What are the pros of JavaScript for web development?”
→ sub-question 4: “What are the cons of JavaScript for web development?”
Each sub-question retrieves separately; the per-sub-question retrieval results are merged and handed to the LLM for the final answer.
Why it works: a complex question often corresponds to multiple scattered pieces of information in the knowledge base. Without decomposition, it’s hard for a single query to hit all relevant passages at once; with decomposition each query is more focused, and retrieval precision improves dramatically.
- Pros: especially suited for multi-hop reasoning and comparison questions
- Cons: number of sub-questions is uncontrolled; multiple retrievals multiply cost; aggregation logic is complex
HyDE — Hypothetical Document Embeddings
Principle: instead of embedding the Query directly, first let the LLM generate a hypothetical “ideal answer”, then embed that hypothetical answer and use it for retrieval.
1 | User Query → LLM generates "hypothetical answer" → Embed(hypothetical answer) → vector retrieval |
Example: user asks “Why is HNSW fast to query?”
→ LLM generates a hypothetical answer: “HNSW is based on a hierarchical graph structure; at query time, it quickly locates a general area from the high-level sparse graph, then does fine-grained search layer by layer…”
→ Embedding this hypothetical answer → compared to embedding the question directly, the vector is closer to the real documents in the knowledge base
Intuition: question embeddings and answer embeddings are not in the same place in semantic space. A hypothetical answer is more like a “real document”; therefore its vector is closer to documents in the knowledge base, so retrieval Recall is higher.
- Pros: very effective for “knowledge-intensive Q&A”; doesn’t depend on keywords; purely semantically driven
- Cons: the hypothetical answer may contain hallucinations, but the retrieval stage doesn’t rely on the answer’s correctness, only its vector, so hallucinations don’t directly affect results
- Suited for: specialized-domain Q&A; scenarios where document phrasing differs greatly from question phrasing
Multi-Query
Principle: let an LLM generate N variants of the same question from multiple angles, retrieve each separately, then deduplicate and merge the results (often combined with RRF).
Example: original question “the limitations of RAG”
→ variant 1: “In what scenarios does RAG perform poorly?”
→ variant 2: “What are the drawbacks of Retrieval-Augmented Generation?”
→ variant 3: “Failure cases of RAG systems”
Each of the three queries retrieves separately; after merging, re-rank with RRF; final Top-K coverage far exceeds any single query.
- Pros: fills coverage blind spots of a single query; naturally pairs with RRF
- Cons: N embeddings + LLM call; latency and cost scale linearly
Summary / Comparison of Approaches
| Approach | Core Idea | Suited Scenarios | Extra LLM Calls | Risk |
|---|---|---|---|---|
| Query Rewriting | swap words; sound more like doc language | colloquial / technical vocab mismatch | 1 | drift from original meaning |
| Query Decomposition | split into sub-questions; retrieve separately | multi-hop / comparison complex questions | 1 (split) + N retrievals | sub-question explosion |
| HyDE | generate hypothetical answer then retrieve | question phrasing differs a lot from docs | 1 | hallucination shifts the vector |
| Multi-Query | generate multiple variants for blind-spot coverage | low recall; narrow coverage | 1 (generate) + N retrievals | high cost |
In engineering practice: the most common lightweight recipe is Query Rewriting + Multi-Query (N=3) + RRF — only one extra LLM call, and retrieval quality improves noticeably. HyDE and Decomposition are reserved for scenarios with extreme quality requirements (e.g. legal-doc Q&A).
6. Reranker & Re-ranking Strategy
Background: vector retrieval (the regular two-encoding kind called Bi-Encoder) is fast but coarse — it compresses the Query and Document into one vector each and takes the dot product, losing lots of fine-grained interaction information. A Reranker is the second-stage module that does fine-grained scoring and re-ranking on Top-N candidates after coarse retrieval.
Two-stage retrieval (Bi-Encoder) pipeline
1 | User Query |
Cross-Encoder
Principle: concatenate the Query and Document and input them to the same Transformer, letting all tokens of the two text segments attend to each other — directly output a relevance score.
1 | Input: [CLS] Query tokens [SEP] Document tokens [SEP] |
- Pros: full attention; most accurate scoring; the precision ceiling
- Cons: Document vectors can’t be precomputed — every query has to rerun each candidate document with the Query; 100 candidates = 100 model inferences; high latency
- Suited for: small candidate sets (within Top-100), scenarios that demand the highest precision
ColBERT (Contextualized Late Interaction over BERT)

As shown in the image, each word in the question will resonate with every word in the article, yielding more precise results.
Principle: Query and Document are still encoded separately (so Documents can be precomputed), but instead of compressing to a single vector, the vector of each token is preserved. The relevance score is computed via MaxSim: for each token of the Query (split by token), find the most similar token across all Document tokens, sum across.
1 | Query → [q₁, q₂, q₃, ...] one vector per token |
- Pros: Documents can be precomputed offline and stored; interaction is much richer than a single-vector Bi-Encoder
- Cons: large storage (one vector per token, longer docs cost more); slower than Bi-Encoder, faster than Cross-Encoder
- Position: the middle tier between precision and speed; suited for larger candidate sets (Top-1000)
Side-by-side comparison
| Bi-Encoder | ColBERT | Cross-Encoder | |
|---|---|---|---|
| Encoding | one vector per Query/Doc | token-level vectors per Query/Doc | concatenated then jointly encoded |
| Doc precompute | ✅ | ✅ | ❌ |
| Interaction granularity | coarse (single-vector dot product) | medium (token-level MaxSim) | fine (full attention) |
| Speed | fastest | medium | slowest |
| Precision | lowest | medium | highest |
| Typical use | stage-1 coarse retrieval | medium-scale reranking | small candidate set for precise ranking |
7. ReRanking
Re-ranking is not a specific model; it’s a pipeline-position concept — re-scoring and re-ordering the candidate set after coarse retrieval.
There are multiple implementations; §6 already detailed Cross-Encoder and ColBERT; here are two more paths.
Three paths for re-ranking (overview)
| Path | Core Mechanism | See |
|---|---|---|
| Cross-Encoder | Query+Doc concatenated and jointly encoded; full token-level interaction | §6 ① |
| ColBERT | Keep token vectors; MaxSim late interaction | §6 ② |
| RRF | Merge ranks from multiple retrieval sources; no scoring required | below ↓ |
| Direct LLM scoring | Let a large model judge relevance | below ↓ |
① RRF (Reciprocal Rank Fusion)
Suited when: you’ve run multiple retrieval sources in parallel (e.g. sparse BM25 + dense CLIP) and need to merge two rank lists into one.
Core formula:
1 | RRF_score(doc) = Σ 1 / (k + rank_i) k usually taken as 60 |
For each retrieval source, compute each document’s contribution from its rank position (not its score), then sum up.
Concrete example:
1 | Query: "stone covered with moss" |
Why not just sum the two raw scores?
BM25 scores (term-frequency stats) and CLIP cosine similarities have completely different units; summing directly is meaningless. RRF only cares about rank position, not absolute values, naturally sidestepping the unit-alignment problem.
② Direct LLM scoring
Feed the candidate result’s text description to an LLM, letting the model judge relevance to the Query directly:
1 | Prompt example: |
| Notes | |
|---|---|
| Pros | strongest semantic understanding; customizable scoring criteria (style, scene fit, etc.) |
| Cons | each candidate requires an LLM call; high cost and latency |
| Suited for | very small candidate sets (within Top-5), or when explainable scoring rationale is needed |
Quick selection guide
| Candidate Set Size | Recommended Strategy |
|---|---|
| All 100K+ | only Bi-Encoder (vector retrieval) |
| Top-1000 | ColBERT or RRF fusing multiple sources |
| Top-100 | Cross-Encoder (recommended; best precision/latency balance) |
| Top-10 | Direct LLM scoring (optional; when maximum precision or explainability is needed) |
- Done (M1): FTS5 keyword retrieval (sparse)
- Done (M4): CLIP FAISS visual retrieval (dense)
- In progress (M5): Cross-Encoder re-ranking, Top-100 → Top-10
- Optional upgrade: first fuse FTS5 and CLIP results with RRF, then send them to a Cross-Encoder —
sparse covers exact keyword hits; dense covers semantic territory; complementary.
Module 4: LLMs & Text Generation
The first three modules all covered Retrieve — finding the most relevant content. This module enters the final RAG stage — Generate: hand the retrieved content to a large language model (LLM) and generate a grounded answer.
1 | User question → [Retrieve] Top-K relevant chunks → [Assemble Prompt] → [LLM Generate] → answer |
Our asset-search tool is “retrieve-only, no generation”, so Module 4 is optional for it; but the local starting-ragchatbot-codebase (Q&A bot) is full RAG, with Claude handling the generation step.
Transformer Architecture Overview
In one sentence: Transformer is the common foundation of nearly all modern LLMs, Embedding models, and Rerankers. Throughout these notes: BERT, CLIP, BGE, Cross-Encoder, GPT/Claude — all are Transformer variants.
1. Why Transformer? (vs RNN)
First, the naming: why “Transformer” instead of “Attention”?
- Attention is a component, Transformer is the whole machine. Attention appeared as early as 2014 (Bahdanau) as an RNN accessory for machine translation; by 2017 it was a common technique — if the new architecture had also been called Attention, it would have collided with “RNN+attention”.
- The paper title is the argument, the architecture name is the product name. “Attention Is All You Need” reads between the lines: “previously it was RNN plus attention; drop RNN and keep only attention is enough.” The title shouts the slogan, the new architecture chose a new name — Transformer — to cut ties with the RNN era.
- “Transform” = transforming representation layer by layer. The model rewrites each token’s vector layer by layer through stacked layers, ultimately turning “isolated word vectors” into “context-rich semantic vectors”. Attention only describes an operation at one layer (Q·K→weighted V); Transformer describes the whole machine — different abstraction levels.
So why does it matter? Before “Attention Is All You Need” (2017), text was handled mainly by RNN/LSTM (RNN, Recurrent Neural Network), which reads one word at a time in sequence, with two hard flaws:
| Problem | RNN/LSTM | Transformer |
|---|---|---|
| Parallelism | must be sequential; cannot parallelize | processes the entire sentence in one parallel pass ⭐ |
| Long-range dependencies | info decays with distance | any two words can directly establish connection |
| Training speed | slow | fast (can fully utilize the GPU) |
Transformer solves both at once with self-attention, the prerequisite for LLMs scaling to hundreds of billions of parameters.
2. Core mechanism: Self-Attention
Self-attention makes every word in a sentence “look at” every other word, absorbing information weighted by relevance.
The key triad Q / K / V:
| Symbol | Meaning | Analogy (like retrieval?) |
|---|---|---|
| Query | what I’m looking for | the user’s search term |
| Key | what “label” I offer | the document’s index |
| Value | what I actually contain | the document body |
Computation flow:
1 | For each word: |
Concrete example — understanding what “it” refers to in a sentence:
1 | Sentence: This stone is covered with moss because it is very damp |
Query·Key → softmax → weighted sum of Values — this mechanism is the same math idea as the dense retrieval covered in Modules 2 and 3 (vector similarity → Top-K → fetch content), just happening inside the model, performed in real time on every token. Once you understand vector retrieval, you’ve understood half of attention.
3. Multi-Head Attention + Positional Encoding + Overall Structure
- Multi-Head Attention: run multiple Q/K/V groups in parallel; each “head” focuses on a different angle (one head looks at syntax, one at coreference, one at semantics…). Then concatenate. Analogy: multiple experts reviewing the same sentence from different dimensions simultaneously.
- Positional Encoding: self-attention itself doesn’t distinguish word order (“dog bites man” and “man bites dog” look the same), so position info must be injected for each word.
- Residual connections + Layer Normalization + Feed-Forward Networks (FFN): the standard accessories of every layer, ensuring that deep networks (tens to hundreds of layers) train stably.
4. Three Architecture Variants (Decide the model’s use)
| Architecture | Representative Models | Strength | Role in these Notes |
|---|---|---|---|
| Encoder-only | BERT, BGE-M3 | understanding, vectorization | Embedding models (§3.1), Cross-Encoder (§6) |
| Decoder-only | GPT, Claude, Qwen, Llama | text generation | this module’s protagonist, responsible for “generation” |
| Encoder-Decoder | T5, BART | translation, summarization | less used in chat |
- You use CLIP/BGE (Encoder) to vectorize assets → this is Transformer
- You use Cross-Encoder (Encoder) for re-ranking → this is Transformer
- You use Claude/Qwen (Decoder) to generate answers → still Transformer
All three share the same lineage; the difference is only “how it’s wired, which half is used, how it’s trained”.
LLM Sampling Strategies
Retrieval decides “what content to feed”; sampling strategy decides “how the model says the content” — with the same context and different parameters, the output can be rigorous or wide-ranging. For RAG this section directly affects hallucination rate.
1. How does the LLM “spit out” words?
At each step, the Decoder model does only one thing: predict the probability distribution of the next word.
1 | Input: "Stones covered with moss usually appear in" |
The “sampling strategy” is the rule for picking a word from this distribution. After picking, append it to the input, predict the next, and loop.
2. Deterministic decoding
| Strategy | How | Characteristics |
|---|---|---|
| Greedy decoding | always pick the highest-probability word | stable but bland; easily gets stuck in repetition |
| Beam Search | keep N candidate paths simultaneously; final pick the globally optimal | high quality but slow; mostly used in translation/summarization |
3. Stochastic sampling (mainstream for chat/creative writing)
① Temperature — adjusts how “peaked” or “flat” the distribution is:
1 | logits are divided by T before softmax: |
② Top-k: sample from only the highest-probability k words (e.g. k=40); cut off the long tail.
③ Top-p / Nucleus sampling: accumulate probabilities from high to low; stop once p (e.g. 0.9) is reached; only sample within this dynamic set. Smarter than Top-k — fewer candidates when distribution is steep, more when flat.
1 | Candidates (sorted by probability): damp 0.45 shade 0.25 forest 0.15 moss 0.08 ... |
④ min-p (relatively new): uses the highest-probability word as the baseline; sets a dynamic minimum ratio; more robust than Top-p.
⑤ Repetition / frequency penalty: downweight words that have already appeared; avoid the “repeater” effect.
4. How to tune for RAG?
If temperature is too high during generation, the model will easily detach from retrieved facts and improvise → hallucination.
| Scenario | Temperature | Top-p | Notes |
|---|---|---|---|
| RAG factual Q&A ⭐ | 0 ~ 0.3 | 0.9 | maximize faithfulness; rarely fabricate |
| Summarization / rewriting | 0.3 ~ 0.5 | 0.9 | a little flexibility without going off |
| Creative writing / naming | 0.8 ~ 1.2 | 0.95 | encourage diversity |
| Code generation | 0 ~ 0.2 | — | needs determinism |
If we ever add a feature to the asset search that “explains in natural language why an asset is recommended”, temperature should be set to around 0.2 — making the model speak faithfully based on the asset’s metadata description, rather than inventing properties that don’t exist.
Choosing a Suitable LLM
There’s no “best” model — only “most suited to the current task + budget + compliance requirements”. Here’s a reusable selection framework.
1. Seven evaluation dimensions
| Dimension | Key Question | Impact on RAG |
|---|---|---|
| Capability tier | are reasoning and complex instruction following strong enough | sets the upper bound on answer quality |
| Context window | how many retrieved chunks can fit | directly relevant to RAG, see below ↓ |
| Cost | input/output price per million tokens | main expense at high call rates |
| Latency / throughput | time to first token, tokens per second | affects user experience |
| Privacy / compliance | can data leave the local environment | red line for private assets / code ⭐ |
| Chinese ability | Chinese understanding and generation | a must in Chinese scenarios |
| Structured output / tool use | can stably output JSON, call functions | required for Agentic RAG |
2. Closed-source API vs open-source local
| Closed-source API (Claude / GPT / Gemini) | Open-source local (Qwen / Llama / DeepSeek…) | |
|---|---|---|
| Capability | usually strongest | top open-source is approaching closed-source |
| Deployment | API call; zero ops | you run it on your own GPU; ops required |
| Cost | pay-as-you-go; no upfront investment | hardware upfront; marginal cost near zero |
| Privacy | data leaves local ⚠️ | data stays local ✅ |
| Customization | limited | finetune / quantize; fully controllable |
3. Mid-2026 mainline model quick view
The table below is cross-verified against Anthropic’s official claude-api reference (cached 2026-06-04) and public pricing comparison sites (morphllm LLM API, verified 2026-06-09, LLM API Pricing 2026). Models and prices change extremely fast — refer to the official site as truth.
Closed-source APIs (price = input/output, per million tokens):
| Model | Position | Context | Price (in/out) |
|---|---|---|---|
| Claude Fable 5 | strongest; long-horizon agents | 1M | $10 / $50 |
| Claude Opus 4.8 ⭐ | flagship; strong coding/agents | 1M | $5 / $25 |
| Claude Sonnet 4.6 | speed/intelligence balance | 1M | $3 / $15 |
| Claude Haiku 4.5 | fast, cheap | 200K | $1 / $5 |
| GPT-5.5 (OpenAI) | strong reasoning / math | ~256K | ~$5 / $30 |
| Gemini 3.1 Pro (Google) | ultra-long context, multimodal, cost-effective | huge (≥1M) | ~$2 / $12 |
| DeepSeek V4 | extreme cost-performance | large | ~$0.14 from |
Open-source / locally deployable (suited to private data):
| Model Family | Highlights | Notes |
|---|---|---|
| Qwen 3.5 (Tongyi Qianwen) | top tier for Chinese; full size range | small sizes run on 8GB; first pick for local ⭐ |
| Llama 4 (Meta) | largest ecosystem | medium-to-large sizes |
| DeepSeek V4 | strong reasoning, open source | full version needs large VRAM |
| GLM-5 (Zhipu) | Chinese-friendly | |
| Mistral / Gemma / Phi | Europe / Google / Microsoft small models | Phi suited for edge |
4. Context window vs RAG
RAG must stuff [system prompt] + [Top-K retrieved chunks] + [conversation history] + [user question] into the context all at once. The larger the window, the more retrieval evidence you can include.
- Stuffing too many irrelevant chunks dilutes useful info, raises cost, and may trigger “lost in the middle” (see next section).
- The right move remains: first re-rank to Top-5~10 high-quality chunks (Module 3 §6/§7 Reranker), rather than dumping Top-100 in. Good retrieval > large windows.
5. Quick selection guide
| Your Situation | Recommendation |
|---|---|
| Private art assets / private code, data must not leave local | Local Qwen 3.5 series (run on your DGX Spark node; 128GB unified memory can load quantized medium-large models) ⭐ |
| Want the highest answer quality and can accept API | Claude Opus 4.8 (claude-opus-4-8) or Fable 5 |
| High frequency, cost-sensitive | Claude Haiku 4.5 / Gemini Flash / DeepSeek |
| Need ultra-long context | Gemini 3.1 Pro / Claude (1M window) |
- Asset-library project (private art assets) → privacy first → local Qwen on DGX Spark
starting-ragchatbot-codebase(course Q&A bot) → already uses Claude (Anthropic’s official default recommendedclaude-opus-4-8+ adaptive thinkingthinking:{type:"adaptive"}); just call the API, no ops needed
Prompt Engineering
Once the model is chosen and retrieval is done, the prompt is your only control lever at inference time — without retraining, you can dramatically change output quality just by organizing the input. For RAG, the core goal of prompt engineering is: make the model answer strictly based on retrieved content and refuse to hallucinate.
1. Basic structure of a prompt
1 | ┌── System: set role, rules, tone, boundaries |
2. General techniques
| Technique | How | When to Use |
|---|---|---|
| Role setting | “You are a senior art director…” | almost always |
| Few-shot | provide 1–3 “input → ideal output” examples | when output format/style must be stable |
| Chain-of-Thought (CoT) | “Reason step by step before concluding” | complex reasoning (note: RAG factual Q&A usually doesn’t need much divergence) |
| Structured output | require JSON output / specified fields | downstream code parses; Agentic RAG |
3. RAG-specific prompt template (key)
A qualified RAG prompt must include three “anti-hallucination” instructions: ① use only provided content ② if not found, say so ③ cite sources.
1 | You are the retrieval assistant for the game asset library. Strictly observe: |
Without instruction 2, the model “confidently makes stuff up” when retrieval is empty; without instruction 3, users can’t verify — answers aren’t traceable.
4. “Lost in the Middle” phenomenon
Research shows: when the context is very long, the model remembers the beginning and end most firmly, while the middle is most easily ignored — recall curves take a U-shape.
1 | Model attention ▲ |
Place the most relevant retrieved chunks at the very beginning or very end of the prompt, not buried in a pile of chunks in the middle. This again confirms the value of re-ranking: instead of stuffing 50 chunks and letting key info drown in the middle, re-rank to 5 chunks and put them in the most visible positions.
5. Good vs bad prompt comparison
| ❌ Bad | ✅ Good | |
|---|---|---|
| Role | (none) | “You are an asset-library assistant” |
| Anti-hallucination | (none; let the model ramble) | “Use only retrieved results; if not found, say so” |
| Source | (not required) | “Tag the basis with [asset ID]” |
| Chunk order | randomly piled | most relevant at the very beginning/end |
| Output | “answer freely” | specify format / fields |
- Prompt engineering: temporary, zero-cost; guides via the current input → this section
- RAG: dynamically injects external knowledge; knowledge updates in real time → this whole set of notes
- Fine-tuning: bake knowledge / style into model weights; high cost; slow to update
The three are often combined: RAG supplies facts + prompts constrain behavior + (optional) fine-tuning unifies style.
Module 5: RAG Systems in Production
1. What challenges does production face?
When RAG leaves the demo, it hits a string of “walls” that demos don’t see:
| Dimension | Demo State | Production Reality |
|---|---|---|
| Data | dozens of clean documents | millions of dirty documents (duplicates, outdated, permission-sensitive) |
| Users | internal testers | real users with wildly varied phrasing, typos, colloquialisms |
| Recall | “good enough” | must be traceable, explainable, SLA-bound |
| Cost | runs on one card | QPS, cost, latency pulling against each other |
| Feedback | none | needs logging, monitoring, A/B, observability |
Demo is “can it answer“; production is “does it answer stably, cheaply, quickly, safely, and is the improvement measurable“.
2. Implement an RAG Evaluation Strategy
Evaluation = answering “how good is my RAG really right now?”. Three steps:
1 | Offline eval set (gold set) → Automated scoring → Regression comparison |
- Gold set: human-annotated question + expected answer / relevant chunks
- Metrics: retrieval (Recall@k, MRR), generation (faithfulness, answer relevance), end-to-end (hit rate)
- Tools: RAGAS, ARES, LangSmith Evaluation, DeepEval
Same data + same code = same score. Otherwise one version change and you can’t tell whether “the model improved” or “the prompt changed”.
3. Logging, Monitoring, and Observability
Production RAG is a black-box pipeline; no logging = no debuggability. Three layers:
| Layer | What to Record | Used For |
|---|---|---|
| Trace | every query’s retriever / reranker / LLM call, inputs and outputs, timings | reproduce problems |
| Metric | QPS, latency percentiles, token usage, hit rate, error rate | dashboard alerting |
| Feedback | user 👍/👎, manual audits, explicit ratings | feed back into eval set, iterate the model |
LangSmith / Langfuse / Arize Phoenix / MLflow — pick any one, don’t run naked.
4. Customized Evaluation
Generic metrics (e.g. “semantic similarity”) often don’t align with the business. Business says it’s good, then it’s actually good.
- Domain-expert scoring: legal / medical / customer-service leads score 1–5 by business criteria
- Rule-based validation: must include a certain field, must cite a certain type of source, must not contain certain words
- Behavioral proxy metrics: like rate, copy rate, follow-up rate (user keeps asking = wasn’t answered clearly)
- LLM-as-a-Judge: use a strong model as judge, but must calibrate against a gold set, otherwise the judge itself drifts.
5. Quantization
Swap a model’s/vector’s “high-precision numbers” for “low-precision representation” to save VRAM, save money, save latency.
| Object | Method | Effect |
|---|---|---|
| Embedding model | int8 / binary | vector-DB memory ↓ 4–32×, recall slightly drops |
| LLM | GPTQ / AWQ / GGUF | VRAM ↓ 2–4×, speed ↑, quality slight loss |
| Vector storage | Product Quantization (PQ) | tens of millions of vectors runnable on one machine |
Recall / generation quality drops 1–3%; must regress on the gold set — don’t push to production on gut feel.
6. Cost vs Response Quality
1 | Quality ▲ |
Common cost-saving strategies:
- Model routing: simple questions → small model / rules; complex questions → large model
- Caching: same query hits the cache, return directly, save one LLM
- Token reduction: re-rank to Top-3, truncate long docs, use smaller context
- Batching / async: non-real-time tasks batch requests
Finding “where 1% quality improvement costs 10× the money” is the ROI key for engineering optimization.
7. Latency vs Response Quality
1 | Time to first token ▲ |
Hard production latency requirements:
| Scenario | Target TTFT |
|---|---|
| Chat / search | < 1s |
| Customer-service auto-reply | < 2s |
| Offline analysis | not sensitive |
Means: streaming output (SSE), parallel retrieval (vector + BM25 in parallel), re-ranking first, speculative decoding.
8. Security
RAG’s attack surface = retriever + LLM; defend at both ends:
| Risk | Example | Defense |
|---|---|---|
| Prompt injection | user question contains “ignore all previous instructions” | input sanitization + strict segmenting of instructions vs data |
| Data leakage | retrieval returns someone else’s private document | metadata ACL filter + tenant isolation |
| Unauthorized answers | internal wiki answered to an external user | permission gateway + source watermarking |
| Hallucination | fabricates non-existent assets | force citation + “say ‘not found’ when none” |
| Toxic output | LLM parrots retrieved malicious text | content moderation + output filtering |
Only by combining input sanitization + output review + permission isolation across the three layers; single-point defense will always be bypassed.
9. Multimodal Retrieval-Augmented Generation
RAG isn’t limited to feeding text. The more modalities you can retrieve/generate, the wider your application scope:
1 | text ←─────► text (most common; Q&A / search) |
Key techniques:
- Unified embedding: CLIP / SigLIP / BGE-M3 map multiple modalities into one vector space
- Multimodal LLM: GPT-4o, Gemini, Qwen-VL — can see images, hear audio, read docs
- Structured parsing: PDF tables, scans, charts → specialized models convert to Markdown/JSON before feeding RAG
First OCR + structure-parse all PDFs / PPTs / screenshots → convert to text + image blocks → push into one vector DB. A single RAG system consumes an enterprise’s entire knowledge assets.
Production RAG = evaluation system + observability + engineering trade-offs + security/compliance + multimodal extension. Beyond the technology itself, engineering capability is what decides whether it can really “live”.
8. References
- [[20260522.SearchToolDesign(Private)]]: complete design doc for the asset-search tool
- [[20260521.ArtPipelineAIIntegration(Private)]]: upstream AI pipeline integration doc
- Andrew Ng’s RAG Course — Instructor Zain
- Zain’s RAG course official link
The local repo path is D:\Project\UGit\starting-ragchatbot-codebase