Chunking Strategies: Chia tài liệu thế nào cho AI đọc tốt?
Cách chia nhỏ tài liệu để RAG hiệu quả: từ fixed-size đến semantic chunking, chiến lược overlap và bảo toàn ngữ cảnh cho tiếng Việt.
Định nghĩa
Chunking là kỹ thuật chia nhỏ tài liệu dài thành các đoạn văn bản (chunks) có tính ngữ nghĩa hoàn chỉnh, để đưa vào vector database phục vụ cho retrieval trong hệ thống RAG. Mục tiêu là đảm bảo mỗi chunk chứa đủ thông tin để AI hiểu ngữ cảnh, nhưng đủ nhỏ để embedding model xử lý hiệu quả và vừa vặn trong context window khi retrieval.
Giải thích chi tiết
Tại sao không đưa nguyên tài liệu vào? Bài toán "Thông tin nhiễu"
Khi bạn đưa cả cuốn sách 500 trang vào embedding model, hai vấn đề xảy ra:
- Embedding dilution: Vector đại diện cho cả tài liệu sẽ bị "loãng" — nó phải gói gọn quá nhiều ý, khiến việc similarity search kém chính xác.
- Context overflow: Khi retrieval trả về 10 "đoạn liên quan nhất", nếu mỗi đoạn là 50 trang, bạn sẽ quá tải context window của LLM.
Chunking giải quyết bằng cách tạo các đơn vị thông tin có độ phân giải cao — giống như pixel trong ảnh: đủ nhỏ để tinh chỉnh, đủ lớn để có nghĩa.
Fixed-size Chunking: Phương án đơn giản nhất
Cắt theo số ký tự hoặc token cố định (ví dụ 500 token mỗi chunk). Đơn giản, nhanh, nhưng có nguy cơ cắt giữa câu: "Hà Nội là thủ đô của Việt Nam. Năm 2024..." có thể bị cắt thành "Hà Nội là thủ đô của Việ" và " Nam. Năm 2024...".
Best practice: Luôn cắt theo ranh giới từ (word boundaries) và thêm overlap (chồng lấp) 10-20% giữa các chunks để giữ ngữ cảnh.
Semantic Chunking: Cắt theo ý, không theo số
Dùng thư viện NLP (spaCy, NLTK) để phát hiện ranh giới câu và đoạn văn. Chunk sẽ kết thúc ở cuối câu hoặc đoạn, đảm bảo tính ngữ nghĩa.
Với tiếng Việt, cần lưu ý:
- Từ ghép (compound words) như "trí tuệ nhân tạo" không nên bị cắt giữa chừng.
- Câu tiếng Việt dùng dấu câu (. ! ?) rõ ràng, nhưng cũng có nhiều mệnh đề phức tạp nên việc giữ nguyên câu trọn vẹn quan trọng hơn là đạt đúng số token.
Chiến lược Overlap: Không để mất ngữ cảnh
Khi một ý nằm giữa hai câu cuối đoạn A và đầu đoạn B, cắt tách sẽ mất ngữ cảnh. Overlap 1-2 câu giữa các chunks giúp retrieval bắt được ý dù nó nằm ở ranh giới.
Hierarchical Chunking: Nhiều tầng độ phân giải
Tài liệu được chunk ở nhiều level:
- Level 1: Section (to)
- Level 2: Paragraph (vừa)
- Level 3: Sentence (nhỏ)
Khi retrieval, thử tìm ở level to trước, nếu không đủ chi tiết thì drill down xuống level nhỏ hơn.
Metadata và Context Enrichment
Mỗi chunk nên mang metadata: tên file, page number, section header, ngày cập nhật. Khi retrieval, bạn không chỉ trả về nội dung chunk mà còn trả về "chunk này từ đâu đến", giúp LLM đánh giá độ tin cậy.
Ví dụ thực tế
Chunking cho tài liệu pháp lý tiếng Việt
Với hợp đồng lao động, không thể cắt giữa điều khoản:
def semantic_chunk_legal(text, max_tokens=512):
# Tách theo điều khoản (Điều 1, Điều 2...)
import re
articles = re.split(r'(Điều \d+[:.])', text)
chunks = []
current_chunk = ""
for i in range(1, len(articles), 2):
article_header = articles[i]
article_content = articles[i+1] if i+1 < len(articles) else ""
article_text = article_header + article_content
if len(current_chunk) + len(article_text) < max_tokens:
current_chunk += article_text
else:
if current_chunk:
chunks.append({
"text": current_chunk,
"metadata": {"type": "legal_article", "source": "labor_contract"}
})
current_chunk = article_text
return chunksRAG Pipeline với Parent Document Retrieval
Thay vì embedding từng câu nhỏ, bạn embed đoạn vừa (child chunk) nhưng retrieval trả về đoạn to hơn (parent chunk) chứa nó:
# Child chunks: 200 tokens (for precise search)
# Parent chunks: 2000 tokens (for context)
child_vectorstore.add_documents(child_chunks)
parent_docstore.add_documents(parent_chunks)
# Search trên child, nhưng truy vấn parent để đưa vào LLM
relevant_child = child_vectorstore.similarity_search(query, k=3)
parents = [parent_docstore.find(child.metadata["parent_id"])
for child in relevant_child]Chunking code với cú pháp
Với Python code, cắt theo hàm/class:
import ast
def chunk_by_function(code):
tree = ast.parse(code)
chunks = []
for node in ast.walk(tree):
if isinstance(node, (ast.FunctionDef, ast.ClassDef)):
chunk_text = ast.unparse(node)
chunks.append({
"text": chunk_text,
"metadata": {
"type": "function" if isinstance(node, ast.FunctionDef) else "class",
"name": node.name,
"line_start": node.lineno
}
})
return chunksỨng dụng
Cho Data Engineer xây dựng RAG pipeline
Xây dựng hệ thống chunking không chỉ là cắt chuỗi — bạn cần thiết kế schema metadata để có thể filter theo ngày tháng, loại tài liệu, hoặc permission trước khi retrieval. Kết hợp vector search với metadata filtering giúp giảm 80% noise.
Cho Legal/Compliance team
Xử lý văn bản pháp luật Việt Nam yêu cầu bảo toàn cấu trúc điều khoản. Dùng semantic chunking với regex nhận diện "Điều", "Khoản", "Mục" để không bao giờ cắt giữa điều luật.
Cho Content Creator xây dựng Knowledge Base
Khi upload 100 bài blog cá nhân vào Notion AI hay Obsidian AI, chunking theo heading (Markdown headers) giúp AI hiểu đây là phần nào của bài viết, tránh trả lời lung tung.
So sánh
| Chiến lược | Ưu điểm | Nhược điểm | Khi nào dùng |
|---|---|---|---|
| Fixed-size | Nhanh, đơn giản, dễ parallelize | Có thể cắt giữa câu, mất ngữ cảnh | Dữ liệu không cấu trúc, log files, xử lý batch lớn |
| Semantic (Sentence/Paragraph) | Giữ nguyên ý nghĩa câu/văn bản | Khó kiểm soát độ dài chính xác | Văn bản thông thường, articles, books |
| Recursive | Cân bằng độ dài và ngữ nghĩa | Phức tạp, cần nhiều pass | Tài liệu có hierarchy rõ (chương → mục → đoạn) |
| Agentic (LLM-based) | Chunk "thông minh" nhất, hiểu nội dung | Chậm, expensive, rate limit | Tài liệu cực quan trọng, ít volume (hợp đồng, báo cáo tài chính) |
| Content-specific | Tôn trọng cấu trúc gốc (Markdown, JSON, Code) | Cần parser riêng cho mỗi format | Code repositories, API docs, structured data |
Kết luận: 90% use case bắt đầu với Recursive Character Text Splitting (kết hợp fixed-size + semantic boundaries) rồi tinh chỉnh overlap. Chỉ dùng LLM-based chunking khi bạn có ít hơn 1000 documents đắt giá và cần perfection.
Bài viết liên quan
Cùng cụm Retrieval & Knowledge
RAG là gì? Retrieval-Augmented Generation giải thích đơn giản
Hiểu cơ chế tổng thể của RAG trước khi đi sâu vào chunking chi tiết
Embedding và Vector Search
Sau khi chunk xong, làm sao để AI tìm được chunk đúng? Tìm hiểu embedding và similarity search
Knowledge Graph cho Context
Khi chunking không đủ để nắm bắt relationships phức tạp, dùng Knowledge Graph để bổ sung structured context
Reranking & Filtering
Thuật toán để chọn ra đúng chunks từ kết quả retrieval, loại bỏ nhiễu trước khi đưa vào LLM
Đọc tiếp
Context Management: Quản lý Context Window hiệu quả
Đã có chunks rồi, làm sao đưa vừa vào context window? Chiến lược sắp xếp và ưu tiên thông tin
Conversation Memory trong AI
Chunking không chỉ cho tài liệu tĩnh — còn áp dụng cho lịch sử hội thoại dài để AI nhớ ngữ cảnh
Tool Use & MCP Protocol
Kết hợp RAG với Tool Use: dùng chunking để chuẩn bị context trước khi AI gọi external tools
Embedding và Vector Search: Cách AI tìm thông tin liên quan
Khám phá cách AI chuyển văn bản thành số để hiểu ngữ nghĩa và tìm kiếm thông tin chính xác bằng Vector Search — nền tảng cốt lõi của hệ thống RAG hiện đại.
Knowledge Graph: Tổ chức kiến thức có cấu trúc cho AI
Knowledge Graph giúp AI hiểu mối quan hệ giữa các thực thể thay vì chỉ tìm kiếm từ khóa. Khám phá cách tổ chức dữ liệu có cấu trúc để RAG thông minh hơn.