Retrieval-Augmented Generation (RAG)
Khái niệm cơ bản
Tưởng tượng bạn đang thi Open Book…
Hai tình huống:
- Thi Closed Book (LLM thuần): Chỉ dựa vào những gì bạn nhớ. Nếu câu hỏi nằm ngoài phạm vi học, bạn phải… đoán (hallucinate).
- Thi Open Book (RAG): Được mang tài liệu vào phòng thi. Gặp câu khó → Lật sách tra cứu → Trả lời chính xác.
RAG = Cho AI mang “sách giáo khoa” vào phòng thi.

Tại sao cần RAG?
| Vấn đề | LLM Thuần | LLM + RAG |
|---|---|---|
| Private Data | Không biết gì về công ty bạn | Truy cập được docs, wiki, database |
| Outdated Info | Knowledge cutoff (vd: 2023) | Cập nhật realtime |
| Hallucination | Bịa khi không biết | Trích dẫn nguồn (citation) |
| Cost | Phải fine-tune (đắt đỏ) | Chỉ cần inject context |
💡 Key Insight: RAG là cách RẺ NHẤT để “dạy” AI kiến thức mới mà không cần training lại.
Kiến trúc RAG (6 Bước)
Bước 1: Indexing (Chuẩn bị - chạy 1 lần)
Documents → Chunking → Embedding → Store in Vector DBBước 2-6: Query Time (Mỗi lần user hỏi)
- Embed Query: Biến câu hỏi thành vector
- Search: Tìm top-K documents tương đồng nhất
- Rerank (Optional): Xếp hạng lại kết quả
- Augment: Ghép query + retrieved docs vào prompt
- Generate: LLM đọc và trả lời
# Pseudo-code RAG Pipeline
def rag_answer(user_query: str) -> str:
# Step 1: Embed query
query_vector = embed(user_query)
# Step 2: Search
relevant_docs = vector_db.search(query_vector, top_k=5)
# Step 3: Augment
context = "\n".join([doc.content for doc in relevant_docs])
prompt = f"""
Dựa trên tài liệu sau đây, trả lời câu hỏi của user.
DOCUMENTS:
{context}
QUESTION: {user_query}
"""
# Step 4: Generate
return llm.generate(prompt)So sánh: RAG vs Fine-tuning vs Long Context
| Phương pháp | Chi phí | Độ chính xác | Cập nhật | Use case |
|---|---|---|---|---|
| RAG | Thấp | Cao (có citation) | Realtime | Q&A, Search, Support |
| Fine-tuning | Cao (~$1000+) | Cao (phong cách) | Cần re-train | Tone, Format cố định |
| Long Context | Trung bình | Trung bình | Mỗi request | Ad-hoc analysis |
Khuyến nghị:
- Bắt đầu với RAG (rẻ, nhanh)
- Kết hợp Long Context cho documents đơn lẻ lớn
- Chỉ Fine-tune khi cần thay đổi phong cách output
Các thành phần của RAG Pipeline
- Embeddings - Biến text thành vectors
- Vector Database - Lưu trữ và tìm kiếm vectors
- Chunking - Cắt documents thành đoạn nhỏ
Advanced Techniques
- Hybrid Search - Kết hợp keyword + semantic
- Reranking - Xếp hạng lại kết quả
- Modular RAG - Kiến trúc nâng cao
Bài tập thực hành: Q&A over PDF
Mục tiêu
Xây dựng chatbot trả lời câu hỏi từ file PDF bằng RAG.
Tools cần thiết
- Python 3.10+
- OpenAI API key
- Chroma (local vector DB)
Code mẫu
# pip install langchain chromadb openai pypdf
from langchain_community.document_loaders import PyPDFLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_openai import OpenAIEmbeddings, ChatOpenAI
from langchain_community.vectorstores import Chroma
from langchain.chains import RetrievalQA
# 1. Load PDF
loader = PyPDFLoader("company_handbook.pdf")
pages = loader.load()
# 2. Chunking
splitter = RecursiveCharacterTextSplitter(
chunk_size=1000,
chunk_overlap=200
)
chunks = splitter.split_documents(pages)
# 3. Embed & Store
embeddings = OpenAIEmbeddings()
vectordb = Chroma.from_documents(chunks, embeddings)
# 4. Create RAG Chain
llm = ChatOpenAI(model="gpt-4o-mini")
qa_chain = RetrievalQA.from_chain_type(
llm=llm,
retriever=vectordb.as_retriever(search_kwargs={"k": 3})
)
# 5. Query
answer = qa_chain.invoke("Chính sách nghỉ phép như thế nào?")
print(answer["result"])Thử thách nâng cao
- Thêm Reranker để cải thiện độ chính xác
- Cho phép user upload PDF qua Streamlit UI
- Thêm citation (hiển thị trang PDF nguồn)
Tóm tắt
| Khái niệm | Ý nghĩa |
|---|---|
| RAG | Cho LLM “mang sách vào phòng thi” |
| Indexing | Chuẩn bị data 1 lần |
| Retrieval | Tìm docs liên quan mỗi query |
| Augmentation | Ghép vào prompt |
| Generation | LLM trả lời |
Bài tiếp theo: Embeddings - Cách biến text thành numbers.
Last updated on