RAG là gì — cách AI 'tra cứu' tài liệu của bạn thay vì bịa
RAG (Retrieval Augmented Generation) là kỹ thuật cho AI search trong knowledge base của bạn TRƯỚC khi trả lời. Hiểu RAG vs Fine-tuning vs Prompt để chọn đúng — build chatbot trả lời chính xác về sản phẩm/policy/docs của công ty trong 1-2 tuần thay vì 6 tháng training model riêng.
Mục lục bài viết(21)

Sơ đồ RAG (Retrieval Augmented Generation) — flow 4 bước: (1) User query → (2) Retrieval system search trong knowledge base (vector DB) → (3) Top-K chunks relevant inject vào prompt — augment context của LLM → (4) LLM generate response dựa cả prompt gốc + retrieved knowledge. Pattern này giúp AI trả lời chính xác về data riêng (sản phẩm, policy, docs) mà không cần retrain model. Nguồn: Wikimedia Commons (CC BY-SA 4.0).
Hiểu đơn giản nhất
Bạn hỏi AI: "Chính sách bảo hành của VietCodex là gì?"
Không có RAG:
- AI không biết VietCodex — không có data trong training set
- AI bịa: "Thường 30 ngày..." (không chính xác)
Có RAG:
- AI search trong knowledge base của bạn → tìm doc "Chính sách bảo hành"
- Doc nói: "Bảo hành 90 ngày link, 6 tháng hosting"
- AI inject doc vào prompt + trả lời chính xác
RAG = Retrieval Augmented Generation = "Tra cứu trước khi trả lời".
| Khái niệm | Đời thực |
|---|---|
| Document | Sách giáo khoa, policy company, FAQ |
| Chunking | Chia sách thành đoạn ~1 trang để index |
| Embedding | Số hoá đoạn thành vector — "tóm tắt ý nghĩa" |
| Vector DB | Thư viện có hệ thống mục lục số |
| Retrieval | Tra cứu — tìm 3-5 đoạn liên quan nhất |
| Generation | AI dùng đoạn tra cứu + câu hỏi → trả lời |
RAG là lý do chatbot Notion AI, Intercom Fin, GitHub Copilot Workspace trả lời được về data riêng của khách hàng.
Tại sao bạn cần biết
- Chatbot trả lời chính xác về sản phẩm/policy/docs. Customer support tự động 24/7 dựa trên knowledge base của bạn.
- Tránh AI bịa. RAG dán "source" với mỗi câu trả lời → user verify được.
- Update data realtime. Sửa policy → upload doc mới → AI áp dụng ngay (không phải retrain).
- Cost-effective. Build chatbot công ty với RAG: $50-500/tháng. Fine-tune model: $5k-50k upfront + retrain mỗi 3 tháng.
- Build SaaS có "AI-native search". Notion, Linear, Slack đều có RAG-powered search 2026 — competitive advantage cho B2B SaaS.
Anatomy của RAG pipeline
Bước 1: Ingestion (indexing)
Chuẩn bị knowledge base — chạy 1 lần khi setup + khi có doc mới.
[Raw documents]
├ Policy PDF (5 trang)
├ Product FAQ (50 câu)
├ Blog posts (200 bài)
└ Customer chat logs (5000 conversation)
↓
[Chunking]
Chia mỗi doc thành chunk 500-800 token, overlap 50 token
↓
[Embedding]
Mỗi chunk → embedding vector 1536 dims (OpenAI)
↓
[Store in Vector DB]
Pinecone / Qdrant / pgvector
+ metadata (doc_id, chunk_index, source_url, last_updated)
Cost ingestion 1 lần:
10.000 chunk × 500 token = 5M token
Cost: 5M × $0.02/M (OpenAI text-embedding-3-small) = $0.10
Cheap. Re-embed khi đổi model.
Bước 2: Query (mỗi request)
[User query] "Bảo hành link bao lâu?"
↓
[Embed query]
Cùng model embedding → vector 1536 dims
↓
[Vector search]
Cosine similarity top-K (thường K=5-10)
Filter by metadata (vd: chỉ docs cho customer's tenant)
↓
[Top chunks]
1. "Bảo hành 90 ngày cho link..." (score 0.92)
2. "Hosting bảo hành 6 tháng..." (score 0.85)
3. "Policy refund toàn bộ..." (score 0.71)
↓
[Augment prompt]
System: "Trả lời dựa trên context dưới đây. Không bịa.
Context: [paste top 3 chunks]"
User: "Bảo hành link bao lâu?"
↓
[LLM generate]
Claude/GPT trả: "Bảo hành link 90 ngày, hosting 6 tháng.
Nguồn: Policy điều 3.2"
Cost mỗi query:
Embedding query (50 token): $0.000001
Vector search: ~$0 (managed) hoặc $0 (pgvector)
LLM call (5k input + 500 output): $0.0225
Total/query: ~$0.023 (~550 VND/câu hỏi)
1000 query/ngày = $23/ngày = $690/tháng. Affordable cho SaaS B2B.
Vector DB — lưu + search embedding
Pinecone (managed SaaS — easiest)
import { Pinecone } from "@pinecone-database/pinecone";
const pc = new Pinecone({ apiKey: process.env.PINECONE_API_KEY });
const index = pc.index("vietcodex-docs");
// Ingest
await index.upsert([
{
id: "chunk-001",
values: embedding, // [0.12, -0.34, 0.56, ...] 1536 dims
metadata: { doc: "policy.pdf", page: 2, text: "Bảo hành 90 ngày..." }
}
]);
// Query
const results = await index.query({
vector: queryEmbedding,
topK: 5,
includeMetadata: true,
filter: { tenant_id: "vc-abc" }
});Pricing: Free tier 100k vector, $70+/tháng paid (1M vector). Khi dùng: Production, không có DevOps team, scale > 100k vector.
pgvector (Postgres extension — free)
-- Setup
CREATE EXTENSION vector;
CREATE TABLE docs (
id TEXT PRIMARY KEY,
content TEXT,
embedding VECTOR(1536),
metadata JSONB
);
CREATE INDEX ON docs USING hnsw (embedding vector_cosine_ops);
-- Ingest
INSERT INTO docs VALUES ('chunk-001', 'Bảo hành...', '[0.12, -0.34, ...]', '{"doc": "policy.pdf"}');
-- Query: top 5 cosine similar
SELECT id, content, 1 - (embedding <=> $1::vector) AS similarity
FROM docs
WHERE metadata->>'tenant_id' = 'vc-abc'
ORDER BY embedding <=> $1::vector
LIMIT 5;Pricing: Free (đã có Postgres). Khi dùng: < 100k vector, đã có Postgres infra, hate vendor lock-in. vietcodex.com đang dùng pattern này.
Qdrant (open-source, Rust)
from qdrant_client import QdrantClient
client = QdrantClient(host="localhost", port=6333)
# Search
results = client.search(
collection_name="docs",
query_vector=query_embedding,
limit=5,
query_filter={"must": [{"key": "tenant", "match": {"value": "vc-abc"}}]}
)Pricing: Free self-host, $25+/tháng cloud. Khi dùng: Performance critical, 1M-100M vector, có Docker infra.
Chunking strategies
1. Fixed-size
Doc 5000 token → chunk_size=500, overlap=50
→ chunk_1 (token 0-500)
chunk_2 (token 450-950)
chunk_3 (token 900-1400)
...
✅ Đơn giản, predictable ❌ Có thể cắt giữa sentence/code block
2. Sentence-based
import nltk
sentences = nltk.sent_tokenize(doc)
# Group sentences đến ~500 token✅ Tôn trọng natural boundary ❌ Sentence dài (vd code) thành chunk lớn
3. Recursive (LangChain default)
Split theo hierarchy: \n\n → \n → → ký tự. Mỗi level fail → tries next.
from langchain.text_splitter import RecursiveCharacterTextSplitter
splitter = RecursiveCharacterTextSplitter(
chunk_size=800,
chunk_overlap=100,
separators=["\n\n", "\n", ".", " "]
)
chunks = splitter.split_text(doc)✅ Smart, work cho hầu hết doc ✅ Phổ biến nhất 2026
4. Semantic (LlamaIndex SemanticSplitter)
Embed each sentence, detect topic shift, chia ở chỗ semantic shift.
✅ Best precision ❌ Slow + tốn embedding cost trong ingestion
Hybrid Search — combine semantic + keyword
Pure semantic miss exact match. Pure BM25 miss synonym. Combine:
# Pseudo-code
semantic_results = vector_db.search(query_embedding, top=10)
keyword_results = bm25.search(query_keywords, top=10)
# Reciprocal Rank Fusion (RRF)
combined = {}
for rank, doc in enumerate(semantic_results):
combined[doc.id] = 1 / (rank + 60)
for rank, doc in enumerate(keyword_results):
combined[doc.id] = combined.get(doc.id, 0) + 1 / (rank + 60)
# Sort by combined score
final = sorted(combined.items(), key=lambda x: x[1], reverse=True)[:5]Improvement: precision +10-30%. Implement: Weaviate có built-in hybrid_query(). Qdrant 1.10+ có sparse vectors. Pgvector tự code với Postgres tsvector.
RAG vs Fine-tuning vs Prompt — quyết định
| Approach | Setup | Update data | Cost ongoing | Quality | Latency |
|---|---|---|---|---|---|
| Prompt | 0 | Edit text | $$ (input tokens) | OK | Low |
| RAG | 1-2 weeks | Upload new doc | $ (embedding cheap) | Good | Medium |
| Fine-tuning | 2-4 weeks + GPU | Retrain (slow) | $$ (train one-time + inference) | Best (style match) | Low |
Quy tắc 2026
| Use case | Khuyến nghị |
|---|---|
| Knowledge base < 100 doc | Prompt (paste vào context) |
| Knowledge base 100-10k doc | RAG với pgvector |
| Knowledge base 10k-1M doc | RAG với Pinecone/Qdrant |
| Match style đặc thù (code convention, brand voice) | Fine-tune trên 1k-10k example |
| Both data lớn + style đặc thù | RAG + Fine-tune (hybrid) |
Ví dụ thực tế: vietcodex.com support chatbot (proposed)
Stack:
Knowledge base:
- Policy docs (10 doc, ~50 page)
- Wiki articles (45 doc — bạn đang đọc 1 cái)
- Pricing page (1 doc)
- Past support conversations (~500)
Embedding: OpenAI text-embedding-3-small
Vector DB: pgvector (đã có Postgres)
Retrieval: top-5 chunks với hybrid (semantic + tsvector BM25)
LLM: Claude Sonnet 4.5
Output: Bilingual VN/EN
Ingestion cost (one-time):
~5000 chunk × 500 token = 2.5M token
× $0.02/M = $0.05
Query cost (per question):
Embed query (50 token): negligible
Retrieve (postgres): $0
LLM call (5k input + 600 output):
5000 × $0.30/M (cached prefix) + 600 × $15/M = $0.0015 + $0.009 = $0.0105
Total/query: ~$0.01 (~250 VND)
Monthly estimate (1000 query/tháng):
$10 (~250k VND)
Workflow:
Customer asks: "Tôi có thể nâng cấp từ Basic lên Pro giữa kỳ không?"
↓
RAG retrieve:
1. Policy 3.5 "Upgrade plan giữa kỳ" (score 0.94)
2. Pricing page section "Tiers" (score 0.81)
3. FAQ Q22 "Đổi gói" (score 0.78)
↓
LLM với context augmented:
"Có. Bạn có thể upgrade Basic → Pro giữa kỳ.
Phí được prorate theo ngày còn lại.
Theo Policy 3.5, downgrade chỉ áp dụng kỳ sau.
[Nguồn: policy.md#3.5, pricing.md, faq.md#Q22]"
Cái gì có thể sai
| Vấn đề | Triệu chứng | Cách fix |
|---|---|---|
| AI vẫn bịa dù có RAG | Top-K chunk thiếu info → AI fill gap | Add system prompt: "Nếu không có info, nói 'tôi không biết'" |
| Retrieve sai chunk | Embedding query khác style với doc | Test với eval set, tinh chỉnh chunk size |
| Slow query > 5s | Vector DB không có index hoặc collection lớn | Add HNSW/IVF index, partition collection |
| Bill embedding cao | Re-embed toàn bộ mỗi đổi 1 doc | Incremental update — chỉ embed doc mới/changed |
| Permission leak | User A retrieve được doc của user B | Add filter by tenant_id/user_id mỗi query |
| Prompt injection qua doc | Doc chứa "ignore instructions" | Sanitize doc upload, separate context với clear delimiter |
| Stale data | Doc updated nhưng vector DB cũ | Webhook trigger re-embed khi doc thay đổi |
| Multilingual search miss | Embedding model EN-only | Dùng multilingual model (BGE-multilingual, Voyage) |
Tóm tắt 1 dòng
RAG (Retrieval Augmented Generation) = AI search knowledge base của bạn TRƯỚC khi trả lời. Pipeline: chunking → embedding → vector DB → query retrieve top-K → augment prompt → LLM generate. Cost ~$0.01/query. RAG > Fine-tuning cho 95% case (cheaper, updatable, debuggable). Vector DB chọn theo scale:
<100kvector pgvector free,>100kQdrant/Pinecone. Hybrid search (semantic + BM25) tăng precision 10-30%. Build chatbot company 1-2 tuần thay vì 6 tháng training model.
Đọc tiếp
- Context Window + Token economics — RAG augment ăn nhiều token, cần optimize
- MCP (Model Context Protocol) là gì — MCP có resource type, một dạng RAG lite
- LLM là gì? Cách 'bộ não' AI dự đoán từ tiếp theo — LLM là backbone của RAG generation
- Database là gì? So sánh dễ hiểu với Excel — vector DB là loại DB chuyên biệt