Chuyển đến nội dung chính

Bài 1: RAG là gì? — Kiến trúc, Use Cases & Tại sao cần RAG

RAG giải quyết vấn đề gì: hallucination, knowledge cutoff, domain-specific. Kiến trúc Retrieve → Augment → Generate. So sánh RAG vs Fine-tuning. Demo "Chat with PDF" đơn giản nhất trong 50 dòng code.

🧠 AI & ML — Bài 0 Bài 1: RAG là gì? — Kiến trúc, Use Cases & Tại sao cần RAG

RAG Thực Chiến: Từ Basic đến Advanced

Phần 1: Nền tảng RAG

xdev.asia

Kiến trúc RAG: Documents → Chunking → Embedding → Vector DB → Retrieval → LLM → Answer

Giới thiệu

Bạn có bao giờ hỏi ChatGPT về nội quy công ty bạn và nhận được câu trả lời... bịa? Hoặc hỏi về sự kiện tuần trước nhưng AI nói "Tôi không có thông tin sau tháng 4/2024"?

Đó là 2 vấn đề lớn nhất của LLM:

Vấn đềGiải thíchVí dụ
HallucinationAI "bịa" thông tin khi không biếtHỏi về nội quy → AI bịa nội quy
Knowledge CutoffAI chỉ biết dữ liệu đến thời điểm trainingHỏi tin tức tuần này → "Tôi không biết"
No Domain KnowledgeAI không biết dữ liệu riêng của bạnHỏi về sản phẩm công ty → trả lời chung chung

RAG (Retrieval-Augmented Generation) giải quyết cả 3 vấn đề bằng cách cho LLM "đọc" tài liệu của bạn trước khi trả lời.


1. RAG là gì?

1.1 Ý tưởng chính

Ví dụ đời thường: Hãy tưởng tượng bạn đi thi vấn đáp:

  • Không có RAG = Thi đóng sách → chỉ dùng kiến thức trong đầu → dễ sai, dễ quên
  • Có RAG = Thi mở sách → được tra tài liệu trước khi trả lời → chính xác hơn nhiều!

RAG = Cho AI "mở sách" trước khi trả lời.

1.2 Ba bước của RAG

User hỏi: "Chính sách nghỉ phép 2026 là gì?"
                                          │
                                          ▼
                    ┌─────────────────────────┐
Step 1: RETRIEVE    │ Tìm tài liệu liên quan  │
(Tìm kiếm)         │ trong knowledge base     │
                    │ → "HR_Policy_2026.pdf"   │
                    │    trang 15-17            │
                    └──────────┬──────────────┘
                               ▼
                    ┌─────────────────────────┐
Step 2: AUGMENT     │ Ghép tài liệu tìm được  │
(Bổ sung)           │ vào prompt cho LLM       │
                    │ → "Dựa trên tài liệu    │
                    │    sau, trả lời câu hỏi" │
                    └──────────┬──────────────┘
                               ▼
                    ┌─────────────────────────┐
Step 3: GENERATE    │ LLM đọc tài liệu        │
(Trả lời)          │ + tạo câu trả lời        │
                    │ → "Theo chính sách 2026, │
                    │    nhân viên được 15 ngày │
                    │    phép/năm..."           │
                    └─────────────────────────┘

1.3 Tại sao RAG hiệu quả?

Không có RAGCó RAG
AI trả lời từ "trí nhớ" (training data)AI trả lời từ tài liệu thực
Có thể bịa nếu không biếtTrích dẫn từ nguồn cụ thể
Kiến thức cũ (cutoff)Tài liệu cập nhật real-time
Không biết data riêngĐọc data riêng của bạn

2. Kiến trúc RAG chi tiết

2.1 Hai giai đoạn: Indexing & Querying

=== GIAI ĐOẠN 1: INDEXING (làm 1 lần, offline) ===

Tài liệu gốc     →    Chunking    →    Embedding    →    Vector DB
[PDF, DOCX, Web]     [Chia nhỏ]      [Text → Vector]    [Lưu trữ]

company_policy.pdf → Chunk 1: 300 từ → [0.23, -0.15, ...] → ChromaDB
                     Chunk 2: 300 từ → [0.45, 0.22, ...]
                     Chunk 3: 300 từ → [-0.11, 0.67, ...]


=== GIAI ĐOẠN 2: QUERYING (mỗi câu hỏi, real-time) ===

Câu hỏi user → Embedding → Similarity Search → Top-K chunks → LLM → Answer
"Nghỉ phép              tìm chunks               ghép vào      trả lời
 bao nhiêu?"            gần nhất                  prompt        từ tài liệu

2.2 Giải thích từng bước

Bước 1 — Chunking: Chia tài liệu thành các đoạn nhỏ (~300-500 từ). Tại sao? Vì LLM có giới hạn context window, và đoạn nhỏ dễ tìm kiếm chính xác hơn.

Bước 2 — Embedding: Biến text thành vector (dãy số). Các đoạn text có ý nghĩa tương tự sẽ có vector gần nhau trong không gian nhiều chiều.

# "Chính sách nghỉ phép" → [0.23, -0.15, 0.87, ...]
# "Quy định ngày phép"   → [0.25, -0.12, 0.85, ...]  ← rất gần!
# "Lương thưởng"         → [-0.45, 0.55, 0.12, ...]  ← rất xa

Bước 3 — Similarity Search: Khi user hỏi, embedding câu hỏi → tìm chunks có vector gần nhất → trả về top-K chunks liên quan nhất (thường K=3-5).

Bước 4 — Generate: Ghép chunks vào prompt, gửi cho LLM:

System: Trả lời câu hỏi dựa trên context được cung cấp.
        Nếu context không chứa câu trả lời, nói "Tôi không
        tìm thấy thông tin trong tài liệu."

Context:
---
[Chunk 1: "Theo chính sách 2026, nhân viên full-time được
15 ngày phép/năm. Nhân viên trên 5 năm được 18 ngày..."]
[Chunk 2: "Quy trình xin phép: gửi đơn trước 3 ngày..."]
---

User: Nhân viên mới được bao nhiêu ngày nghỉ phép?

💡 Bài tập 2: Giải thích RAG cho đồng nghiệp non-tech bằng ví dụ "thư viện": thủ thư (retriever), sách liên quan (context), sinh viên (LLM tự tổng hợp câu trả lời). Thử viết 3-4 câu.


3. Demo: "Chat with PDF" trong 50 dòng

Đây là RAG pipeline đơn giản nhất — chỉ cần Python + OpenAI + ChromaDB:

3.1 Cài đặt

pip install openai chromadb langchain langchain-openai \
            langchain-community pypdf

3.2 Code hoàn chỉnh

"""
RAG đơn giản nhất: Chat with PDF
50 dòng code — hiểu toàn bộ flow!
"""
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.prompts import ChatPromptTemplate
from langchain.schema.runnable import RunnablePassthrough

# === Bước 1: Load PDF ===
loader = PyPDFLoader("company_policy.pdf")
pages = loader.load()
print(f"Loaded {len(pages)} pages")

# === Bước 2: Chunking ===
splitter = RecursiveCharacterTextSplitter(
    chunk_size=500,     # Mỗi chunk ~500 ký tự
    chunk_overlap=50    # Overlap 50 ký tự (tránh cắt giữa câu)
)
chunks = splitter.split_documents(pages)
print(f"Split into {len(chunks)} chunks")

# === Bước 3: Embedding + Store vào Vector DB ===
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
vectorstore = Chroma.from_documents(chunks, embeddings)
retriever = vectorstore.as_retriever(search_kwargs={"k": 3})

# === Bước 4: RAG Chain ===
template = """Trả lời câu hỏi dựa trên context sau.
Nếu không tìm thấy, nói "Tôi không tìm thấy trong tài liệu."
Trích dẫn nguồn (trang số) nếu có thể.

Context:
{context}

Câu hỏi: {question}
"""
prompt = ChatPromptTemplate.from_template(template)
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)

rag_chain = (
    {"context": retriever, "question": RunnablePassthrough()}
    | prompt
    | llm
)

# === Bước 5: Hỏi! ===
while True:
    question = input("\n❓ Hỏi: ")
    if question.lower() in ["quit", "exit"]:
        break
    answer = rag_chain.invoke(question)
    print(f"\n💬 {answer.content}")

3.3 Giải thích flow

User: "Nhân viên mới được bao nhiêu ngày phép?"
  ↓
1. Embedding câu hỏi → vector [0.3, -0.1, ...]
  ↓
2. Tìm 3 chunks gần nhất trong ChromaDB
  ↓
3. Ghép chunks vào template prompt
  ↓
4. Gửi cho GPT-4o-mini
  ↓
5. AI đọc chunks + trả lời: "Theo tài liệu trang 15,
   nhân viên mới được 15 ngày phép/năm..."

Quan trọng: AI trả lời dựa trên tài liệu, không phải tự bịa! Đây là sức mạnh cốt lõi của RAG.

💡 Bài tập 3:

  1. Chạy code trên với 1 file PDF bất kỳ (CV, tài liệu học, docs).
  2. Hỏi 5 câu: 3 câu có đáp án trong PDF, 2 câu không có → AI xử lý thế nào?
  3. Thử thay chunk_size=500 thành 200 và 1000 — chất lượng thay đổi ra sao?

4. RAG vs Fine-tuning — Khi nào dùng gì?

Đây là câu hỏi phổ biến nhất: "Tôi nên dùng RAG hay fine-tune model?"

4.1 Bảng so sánh chi tiết

Tiêu chíRAGFine-tuning
Mục đíchThêm knowledge (kiến thức)Thay đổi behavior (hành vi)
Ví dụTrả lời từ docs công tyViết theo brand voice
Chi phí setupThấp (~$5-50)Cao (~$50-500+)
Thời gianVài phútVài giờ → ngày
Update data✅ Cập nhật real-time❌ Phải re-train
AccuracyCao (trích dẫn nguồn)Trung bình (có thể hallucinate)
Scalable✅ Thêm docs dễ❌ Khó scale

4.2 Decision Framework

Câu hỏi quyết định:
                        ┌─ Cần AI biết data MỚI/RIÊNG? → RAG
                        │
Bạn cần gì? ────────── ├─ Cần AI thay đổi PHONG CÁCH/FORMAT? → Fine-tuning
                        │
                        ├─ Cần CẢ HAI? → RAG + Fine-tuning (Hybrid)
                        │
                        └─ Không chắc? → Thử RAG trước (rẻ, nhanh)

4.3 Ví dụ thực tế

Bài toánChọnLý do
Chatbot trả lời FAQ từ 100 bài blogRAGKnowledge gap — cần data riêng
AI viết email theo giọng CEOFine-tuningBehavior gap — cần thay đổi style
AI hỗ trợ bác sĩ tra cứu thuốcRAGCần data cập nhật + trích dẫn nguồn
AI phân loại ticket supportFine-tuningTask-specific behavior
Chatbot nội bộ + brand voiceHybridCần cả knowledge + style riêng

Quy tắc ngón cái: Nếu không chắc, bắt đầu bằng RAG. RAG rẻ, nhanh, dễ iterate. Fine-tuning chỉ khi RAG không đủ.


5. Use Cases phổ biến nhất

5.1 Doanh nghiệp

Use CaseMô tảNguồn data
Internal Knowledge BotNhân viên hỏi về quy trình, chính sáchHR docs, SOPs, wiki
Customer SupportBot trả lời từ FAQ + docs sản phẩmHelp center, manuals
Legal AssistantTra cứu luật, hợp đồngVăn bản pháp luật, contracts
Sales EnablementTìm case studies, competitive intelCRM data, reports

5.2 Cá nhân / Giáo dục

Use CaseMô tảNguồn data
Study Assistant"Chat with textbook" — hỏi bài giáo khoaPDF sách, slides
Research HelperTổng hợp insights từ 50+ papersArxiv papers
Personal WikiNote-taking + Q&A từ notesObsidian, Notion
Code DocumentationHỏi về codebase 100K+ dòngSource code, docs

5.3 Sản phẩm AI

Use CaseVí dụ thực tế
Perplexity AISearch engine + RAG (search web → trả lời)
Notion AIRAG từ workspace Notion của bạn
GitHub CopilotRAG từ codebase hiện tại
ChatGPT + BrowseRAG từ web real-time

💡 Bài tập 5: Liệt kê 3 use cases RAG cho công ty / dự án / trường học của bạn. Với mỗi use case, xác định: nguồn data, ai là user, và metric thành công.


6. Limitations — RAG không phải "silver bullet"

LimitationGiải thíchGiải pháp (học ở bài sau)
Garbage in, garbage outData xấu → RAG xấuData cleaning (Bài 5)
Chunk quá nhỏ/lớnMất context hoặc quá nhiều noiseChunking strategies (Bài 5)
Query mơ hồRetriever không tìm đúngQuery transformation (Bài 7)
Lost in the middleLLM bỏ qua context ở giữaRe-ranking (Bài 8)
MultimodalẢnh/bảng trong PDF bị bỏMultimodal RAG (Bài 10)

Tóm tắt

ConceptGhi nhớ
RAGRetrieve → Augment → Generate (thi "mở sách")
Giải quyếtHallucination, knowledge cutoff, domain knowledge
IndexingChunk → Embed → Store (offline, 1 lần)
QueryingEmbed query → Search → Augment → Generate (real-time)
vs Fine-tuningRAG = thêm knowledge, Fine-tuning = thay đổi behavior
Bắt đầu bằngRAG trước (rẻ, nhanh, dễ iterate)

Bài tập tổng hợp

  1. ✅ Hoàn thành bài tập nhỏ (2, 3, 5)
  2. Hands-on: Chạy demo "Chat with PDF" ở phần 3 với tài liệu thật. Chụp screenshot kết quả.
  3. Architecture Diagram: Vẽ lại kiến trúc RAG cho 1 use case cụ thể ở phần 5 (dùng draw.io hoặc Mermaid).
  4. Research: Tìm 3 tools/sản phẩm RAG đang được dùng nhiều nhất 2026 (hint: LangChain, LlamaIndex, Vercel AI SDK). So sánh ưu/nhược.

Bài tiếp theo: Embedding Models — cách biến text thành vector, so sánh OpenAI vs Cohere vs Open-source, và embedding tiếng Việt.