RAG với Claude — Retrieval-Augmented Generation toàn tập
RAG là gì?
Retrieval-Augmented Generation (RAG) là kiến trúc kết hợp giữa hệ thống tìm kiếm thông tin (retrieval) và mô hình ngôn ngữ lớn (generation). Thay vì chỉ dựa vào kiến thức được huấn luyện sẵn, mô hình AI sẽ truy xuất các đoạn văn bản liên quan từ cơ sở dữ liệu của bạn trước khi sinh ra câu trả lời.
Kết quả là Claude có thể trả lời chính xác về tài liệu nội bộ, dữ liệu cập nhật theo thời gian thực, hoặc kiến thức chuyên ngành mà nó chưa được huấn luyện — tất cả mà không cần fine-tuning hay nhét toàn bộ tài liệu vào context window.
Tại sao RAG thay vì fine-tuning hay long context?
So sánh ba phương pháp
| Tiêu chí | RAG | Fine-tuning | Long context |
|---|---|---|---|
| Cập nhật dữ liệu | Dễ — chỉ cần cập nhật vector DB | Khó — phải train lại | Dễ nhưng tốn kém |
| Chi phí | Trung bình | Cao (training) | Cao (nhiều token input) |
| Độ chính xác trích dẫn | Cao | Thấp (hallucination) | Cao nhưng phụ thuộc context |
| Kiểm soát nguồn | Có — biết từ tài liệu nào | Không | Có |
| Scale tài liệu | Tốt — hàng triệu tài liệu | Cần data lớn để hiệu quả | Giới hạn bởi context window |
RAG phù hợp nhất khi dữ liệu thay đổi thường xuyên, tập tài liệu lớn hơn context window, và bạn cần khả năng truy xuất nguồn gốc câu trả lời. Claude với context window 200K token xử lý được nhiều tài liệu, nhưng đối với cơ sở tri thức doanh nghiệp lên đến hàng nghìn tài liệu, RAG vẫn là lựa chọn kinh tế hơn.
Kiến trúc tổng quan của hệ thống RAG
Một pipeline RAG hoàn chỉnh gồm hai giai đoạn chính:
Giai đoạn 1: Indexing (Xử lý tài liệu)
- Load tài liệu (PDF, DOCX, web pages, v.v.)
- Chunk (chia nhỏ) tài liệu thành các đoạn
- Tạo embedding cho mỗi chunk
- Lưu embedding vào vector database
Giai đoạn 2: Retrieval + Generation (Truy vấn)
- Nhận câu hỏi từ người dùng
- Tạo embedding cho câu hỏi
- Tìm kiếm các chunks liên quan nhất trong vector DB (similarity search)
- Đưa chunks + câu hỏi vào prompt của Claude
- Claude sinh ra câu trả lời dựa trên context
Document Processing — Chunking Strategies
Chất lượng chunking ảnh hưởng trực tiếp đến chất lượng retrieval. Ba chiến lược phổ biến:
1. Fixed-size chunking
Chia tài liệu thành các đoạn có kích thước cố định (ví dụ: 512 tokens), với overlap để tránh mất ngữ cảnh tại ranh giới.
def fixed_chunk(text, chunk_size=512, overlap=50):
words = text.split()
chunks = []
for i in range(0, len(words), chunk_size - overlap):
chunk = ' '.join(words[i:i + chunk_size])
chunks.append(chunk)
return chunks
Ưu điểm: đơn giản, dễ triển khai. Nhược điểm: có thể cắt đứt câu hoặc đoạn có nghĩa quan trọng.
2. Semantic chunking
Chia theo ranh giới ngữ nghĩa — đoạn văn, mục, tiêu đề. Phù hợp với tài liệu có cấu trúc rõ ràng như hợp đồng, báo cáo, tài liệu kỹ thuật.
def semantic_chunk(text):
# Chia theo paragraph breaks
paragraphs = text.split('
')
# Gộp các paragraph ngắn
chunks = []
current = ""
for para in paragraphs:
if len(current) + len(para) < 1000:
current += "
" + para
else:
if current:
chunks.append(current.strip())
current = para
if current:
chunks.append(current.strip())
return chunks
3. Recursive chunking
Phương pháp được khuyến nghị bởi LangChain và nhiều framework RAG. Thử chia theo hierarchy: paragraph → sentence → word, đảm bảo không vượt quá kích thước tối đa.
from langchain.text_splitter import RecursiveCharacterTextSplitter
splitter = RecursiveCharacterTextSplitter(
chunk_size=1000,
chunk_overlap=200,
separators=["
", "
", ". ", " ", ""]
)
chunks = splitter.split_text(document_text)
Chọn chiến lược nào?
- Tài liệu có cấu trúc (manual, spec): semantic chunking
- Tài liệu thuần văn bản, liên tục: recursive chunking
- Prototype nhanh: fixed-size với overlap 15-20%
- Chunk size khuyến nghị: 256-512 tokens cho Q&A, 512-1024 cho tóm tắt
Embedding Models
Embedding model chuyển đổi văn bản thành vector số để so sánh độ tương đồng ngữ nghĩa. Các lựa chọn phổ biến:
- text-embedding-3-small (OpenAI): 1536 dimensions, chi phí thấp, chất lượng tốt cho hầu hết use cases
- text-embedding-3-large (OpenAI): 3072 dimensions, chất lượng cao hơn, chi phí cao hơn
- voyage-3 (Voyage AI): Được Anthropic khuyến nghị, tối ưu cho Claude
- bge-m3 (BAAI): Open-source, hỗ trợ đa ngôn ngữ tốt, phù hợp tiếng Việt
- multilingual-e5-large: Open-source, hiệu suất tốt cho tiếng Việt
Lưu ý: embedding model và retrieval model phải nhất quán — bạn phải dùng cùng model để embed câu hỏi và tài liệu.
Vector Databases
Vector database lưu trữ và tìm kiếm embedding nhanh chóng theo độ tương đồng cosine hoặc dot product.
Pinecone
Managed service, không cần tự quản lý infrastructure. Phù hợp cho production với tập dữ liệu lớn. Có free tier (100K vectors).
import pinecone
pc = pinecone.Pinecone(api_key="YOUR_API_KEY")
index = pc.Index("my-rag-index")
# Upsert vectors
index.upsert(vectors=[
("doc-1", embedding_vector, {"text": "...", "source": "manual.pdf"})
])
# Query
results = index.query(vector=query_embedding, top_k=5, include_metadata=True)
Weaviate
Open-source, có thể self-host hoặc dùng managed cloud. Tích hợp sẵn với nhiều embedding model, hỗ trợ hybrid search tốt.
pgvector (PostgreSQL extension)
Lựa chọn tốt nhất nếu bạn đã dùng PostgreSQL. Không cần database mới, chi phí thấp, dễ maintain.
-- Cài extension
CREATE EXTENSION vector;
-- Tạo bảng
CREATE TABLE documents (
id bigserial PRIMARY KEY,
content text,
embedding vector(1536),
metadata jsonb
);
-- Tạo index
CREATE INDEX ON documents USING ivfflat (embedding vector_cosine_ops);
-- Query similarity
SELECT content, metadata,
1 - (embedding <=> $1) AS similarity
FROM documents
ORDER BY embedding <=> $1
LIMIT 5;
Chroma
Open-source, nhẹ, phù hợp cho development và small-scale deployment. API đơn giản, tích hợp tốt với LangChain.
Retrieval Strategies
Dense retrieval (semantic search)
Tìm kiếm theo nghĩa bằng cosine similarity giữa các embedding. Hiệu quả với câu hỏi diễn đạt khác nhau nhưng cùng nghĩa.
Sparse retrieval (keyword search)
BM25 hoặc TF-IDF — tìm kiếm theo từ khóa chính xác. Vẫn hiệu quả cho tên riêng, số hiệu, mã code.
Hybrid search (khuyến nghị)
Kết hợp dense + sparse, sau đó rerank kết quả. Cho kết quả tốt nhất trong hầu hết trường hợp:
def hybrid_search(query, vector_db, bm25_index, top_k=10):
# Dense search
query_embedding = embed(query)
dense_results = vector_db.query(query_embedding, top_k=top_k)
# Sparse search
sparse_results = bm25_index.search(query, top_k=top_k)
# Reciprocal Rank Fusion
return rrf_merge(dense_results, sparse_results)
Prompt Template cho RAG
Cấu trúc prompt hiệu quả khi dùng Claude với RAG:
SYSTEM_PROMPT = """Bạn là trợ lý hỗ trợ kỹ thuật. Trả lời câu hỏi DUY NHẤT dựa trên
tài liệu được cung cấp trong phần CONTEXT. Nếu tài liệu không có thông tin,
hãy nói rõ "Tôi không tìm thấy thông tin này trong tài liệu."
Khi trả lời, hãy trích dẫn nguồn tài liệu cụ thể."""
def build_rag_prompt(question, retrieved_chunks):
context = "
---
".join([
f"[Nguồn: {chunk['source']}]
{chunk['text']}"
for chunk in retrieved_chunks
])
return f"""CONTEXT:
{context}
CÂU HỎI: {question}
Trả lời dựa trên CONTEXT ở trên:"""
Reranking
Sau khi retrieve top-K chunks, reranker chấm điểm lại độ liên quan và chọn top-N thực sự nhất để đưa vào prompt. Giúp lọc ra kết quả giả tương đồng (false positives).
from voyageai import Client as VoyageClient
voyage = VoyageClient(api_key="YOUR_KEY")
def rerank(query, documents, top_n=3):
result = voyage.rerank(
query=query,
documents=[doc['text'] for doc in documents],
model="rerank-2",
top_k=top_n
)
return [documents[r.index] for r in result.results]
Evaluation Metrics
Đánh giá hệ thống RAG cần đo cả retrieval và generation:
- Retrieval Recall@K: Trong K kết quả truy xuất, bao nhiêu phần trăm chứa câu trả lời đúng
- Retrieval Precision@K: Tỉ lệ kết quả truy xuất thực sự liên quan
- Faithfulness: Câu trả lời có trung thực với context không (không hallucinate)
- Answer Relevancy: Câu trả lời có thực sự trả lời câu hỏi không
- Context Relevancy: Context truy xuất có liên quan đến câu hỏi không
Framework RAGAS (Python) giúp tự động đánh giá các metrics trên bằng cách dùng LLM làm judge.
Production Tips và Cost Optimization
Giảm chi phí embedding
- Cache embedding cho các tài liệu không thay đổi
- Dùng text-embedding-3-small thay vì large nếu chất lượng đủ
- Batch embedding requests thay vì gọi từng cái
Tối ưu retrieval
- Tune chunk size: thử 256, 512, 1024 tokens và đánh giá
- Adjust top-K: bắt đầu với K=5, tăng nếu recall thấp
- Metadata filtering: lọc theo ngày, danh mục trước khi similarity search
- Parent document retrieval: retrieve chunk nhỏ nhưng đưa cả section lớn hơn vào context
Prompt Caching với RAG
Dùng Prompt Caching của Claude để cache system prompt và instructions — đặc biệt hữu ích nếu system prompt dài.
import anthropic
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-opus-4",
max_tokens=1024,
system=[
{
"type": "text",
"text": long_system_instructions,
"cache_control": {"type": "ephemeral"} # Cache system prompt
}
],
messages=[
{"role": "user", "content": rag_prompt_with_context}
]
)
Monitoring và debugging
- Log tất cả queries, retrieved chunks, và responses để phân tích
- Track retrieval failures: câu hỏi nào không tìm được context phù hợp
- A/B test chunking strategies và embedding models trên real queries
- Dùng Langfuse hoặc Arize để observability
Kết luận
RAG là nền tảng của hầu hết hệ thống AI production hiện nay. Với Claude, bạn có thể xây dựng RAG pipeline mạnh mẽ nhờ context window lớn (200K tokens), khả năng hiểu tài liệu phức tạp, và API Tool Use để tích hợp retrieval động.
Bắt đầu với recursive chunking, pgvector (nếu đã có Postgres) hoặc Chroma (nếu mới), và voyage-3 embedding. Sau khi có baseline hoạt động, mới tối ưu dần từng thành phần dựa trên evaluation metrics thực tế.
Bai viet co huu ich khong?
Bản quyền thuộc về tác giả. Vui lòng dẫn nguồn khi chia sẻ.



