Bỏ qua điều hướng
~/minhquan
Esc

Đang tải chỉ mục…

↑↓ chọn · Enter mở · Esc đóng · trang tìm kiếm

Tất cả bài viết

3 phút đọc

RAG là gì? Tự xây pipeline hỏi đáp tài liệu từ con số 0

Ghi chú về Retrieval-Augmented Generation: tại sao cần RAG, các bước chunking → embedding → retrieval → generation, và code minh hoạ bằng Python thuần.

Mục lục
  1. Pipeline tổng quan
  2. Bước 1: Chunking
  3. Bước 2 & 3: Embedding và tìm kiếm
  4. Bước 4: Generation
  5. Điều mình rút ra

LLM rất giỏi ngôn ngữ nhưng không biết gì về tài liệu riêng của bạn và kiến thức của nó dừng lại ở thời điểm train. RAG (Retrieval-Augmented Generation) giải quyết chuyện đó: trước khi hỏi model, ta tìm những đoạn tài liệu liên quan rồi nhét chúng vào prompt.

Pipeline tổng quan

  1. Chunking — chia tài liệu thành các đoạn nhỏ.
  2. Embedding — biến mỗi đoạn thành một vector.
  3. Retrieval — khi có câu hỏi, tìm các vector gần nhất.
  4. Generation — đưa các đoạn tìm được + câu hỏi cho LLM trả lời.

Bước 1: Chunking

Chunk quá dài thì nhiễu, quá ngắn thì mất ngữ cảnh. Cách đơn giản nhất là cắt theo số từ và cho các chunk chồng lên nhau một chút:

chunking.py
def chunk_text(text: str, size: int = 200, overlap: int = 40) -> list[str]:
    words = text.split()
    chunks = []
    step = size - overlap
    for start in range(0, len(words), step):
        chunks.append(" ".join(words[start : start + size]))
    return chunks

Bước 2 & 3: Embedding và tìm kiếm

Embedding model biến văn bản thành vector sao cho các câu cùng nghĩa nằm gần nhau. Độ "gần" thường đo bằng cosine similarity:

retrieval.py
import numpy as np
 
def cosine_similarity(a: np.ndarray, b: np.ndarray) -> float:
    return float(a @ b / (np.linalg.norm(a) * np.linalg.norm(b)))
 
def top_k(query_vec, chunk_vecs, k: int = 3) -> list[int]:
    scores = [cosine_similarity(query_vec, v) for v in chunk_vecs]
    return sorted(range(len(scores)), key=lambda i: scores[i], reverse=True)[:k]

Khi dữ liệu lớn, ta dùng vector database (pgvector, Qdrant, Chroma…) thay cho vòng lặp này.

Bước 4: Generation

Thành phầnVai trò
System promptDặn model chỉ trả lời dựa trên ngữ cảnh
ContextCác chunk tìm được, kèm nguồn
Câu hỏiCâu hỏi gốc của người dùng

Điều mình rút ra

  • RAG tốt hay dở phụ thuộc 70% vào retrieval, không phải model.
  • Luôn trả kèm nguồn trích dẫn để người dùng kiểm chứng.
  • Bước tiếp theo mình muốn thử: reranking và hybrid search (BM25 + vector).

Bài liên quan