Trong Retrieval-Augmented Generation (RAG), tài liệu thường không được đưa nguyên vẹn vào hệ thống truy xuất mà được chia thành các đoạn nhỏ gọi là chunk. Cách chia này ảnh hưởng trực tiếp đến embedding, kết quả tìm kiếm và lượng ngữ cảnh mà mô hình ngôn ngữ nhận được.
Chunk quá lớn có thể chứa nhiều thông tin không liên quan, còn chunk quá nhỏ dễ làm mất ngữ cảnh. Vì vậy, chunking không chỉ là thao tác tiền xử lý mà là một trong những quyết định thiết kế quan trọng của pipeline RAG.
Chunking nằm ở đâu trong pipeline RAG?
Một pipeline RAG cơ bản có thể được hình dung theo luồng sau:
Sau khi tài liệu được chia nhỏ, mỗi chunk được chuyển thành một embedding, tức vector số biểu diễn nội dung ngữ nghĩa. Khi người dùng đặt câu hỏi, hệ thống cũng tạo embedding cho truy vấn rồi tìm những vector gần nhất trong vector database.
Ví dụ, một tài liệu hướng dẫn sản phẩm dài 20 trang có thể chứa thông tin về cài đặt, thanh toán, bảo mật và xử lý lỗi. Nếu đưa cả tài liệu thành một vector duy nhất, embedding phải đại diện cho quá nhiều chủ đề. Chia tài liệu thành các chunk nhỏ giúp truy vấn về “đổi mật khẩu” tìm đúng phần liên quan đến bảo mật thay vì toàn bộ tài liệu.
Chunk size ảnh hưởng đến truy xuất như thế nào?
Chunk size là lượng nội dung trong mỗi đoạn. Có thể đo bằng ký tự, từ hoặc token; với ứng dụng LLM, token thường là đơn vị có ý nghĩa thực tế hơn vì context window của mô hình cũng được tính theo token.
Giả sử tài liệu có đoạn sau:
Nếu mỗi câu trở thành một chunk riêng, truy vấn “Làm thế nào để đặt lại mật khẩu?” có thể lấy được câu đầu nhưng bỏ mất bước xác nhận qua email. Ngược lại, nếu chunk chứa cả vài trang hướng dẫn, kết quả vẫn có thông tin đúng nhưng kèm rất nhiều nội dung không cần thiết.
Có thể xem đây là sự cân bằng giữa hai yếu tố:
- Chunk nhỏ: tập trung hơn, thường thuận lợi cho tìm kiếm chính xác nhưng dễ thiếu ngữ cảnh.
- Chunk lớn: giữ được nhiều ngữ cảnh hơn nhưng có thể làm embedding kém đặc trưng và tăng số token gửi vào LLM.
Không tồn tại một kích thước chunk tối ưu cho mọi hệ thống. Tài liệu FAQ, hợp đồng, tài liệu kỹ thuật và transcript hội thoại có cấu trúc khác nhau nên cần được đánh giá riêng.
Vì sao cần chunk overlap?
Chunk overlap là phần nội dung được lặp lại giữa hai chunk liên tiếp. Mục tiêu chính là giảm nguy cơ cắt mất thông tin nằm ngay tại ranh giới.
Giả sử một tài liệu được chia như sau:
Chunk 2: “...hệ thống tìm các đoạn liên quan rồi bổ sung chúng vào prompt trước khi gọi LLM.”
Nếu cắt đúng tại cụm “khi có truy vấn”, hai phần thông tin liên quan chặt chẽ lại nằm ở hai vector khác nhau. Một vùng overlap nhỏ có thể giữ phần chuyển tiếp trong cả hai chunk, giúp mỗi chunk độc lập hơn về ngữ nghĩa.
Tuy nhiên, overlap càng lớn thì càng tạo nhiều dữ liệu trùng lặp. Điều này làm tăng số embedding, dung lượng vector database và khả năng hệ thống truy xuất nhiều đoạn gần như giống nhau. Vì vậy overlap nên được xem như cơ chế bảo vệ ranh giới, không phải càng lớn càng tốt.
Các chiến lược chunking thường dùng trong NLP và RAG
Fixed-size chunking
Cách đơn giản nhất là chia tài liệu thành các đoạn có độ dài cố định, chẳng hạn theo số ký tự hoặc token. Phương pháp này dễ triển khai, nhanh và phù hợp làm baseline.
Nhược điểm là ranh giới chunk không quan tâm đến cấu trúc ngôn ngữ. Một câu hoặc một đoạn giải thích có thể bị cắt ở giữa.
Recursive chunking
Recursive chunking ưu tiên chia theo các ranh giới tự nhiên như đoạn văn, xuống dòng, câu rồi mới đến ký tự nếu phần nội dung vẫn quá dài. Đây thường là lựa chọn thực dụng cho tài liệu văn bản thông thường vì giữ cấu trúc tốt hơn fixed-size chunking.
Structure-aware chunking
Với Markdown, HTML, tài liệu kỹ thuật hoặc báo cáo có heading rõ ràng, có thể chia theo cấu trúc như tiêu đề, section hoặc subsection. Ví dụ, một section “Authentication” nên được giữ riêng thay vì ghép một nửa với phần “Billing”.
Cách này đặc biệt hữu ích khi heading cũng được lưu vào metadata hoặc ghép vào nội dung chunk, vì nó bổ sung tín hiệu ngữ nghĩa cho quá trình truy xuất.
Semantic chunking
Semantic chunking cố gắng phát hiện điểm thay đổi chủ đề dựa trên biểu diễn ngữ nghĩa, thường thông qua embedding của câu hoặc đoạn. Thay vì cắt ở một số token cố định, hệ thống tạo chunk khi nội dung chuyển sang một chủ đề khác.
Phương pháp này có thể tạo chunk nhất quán về ý nghĩa hơn nhưng phức tạp và tốn chi phí xử lý hơn. Không nên mặc định rằng semantic chunking luôn tốt hơn nếu chưa đánh giá trên dữ liệu và truy vấn thực tế.
Ví dụ chunking bằng Python
Ví dụ dưới đây triển khai fixed-size chunking theo từ với overlap. Cách viết đơn giản này phù hợp để hiểu cơ chế trước khi chuyển sang tokenizer hoặc thư viện chuyên dụng.
def split_text(text, chunk_size=50, overlap=10):
words = text.split()
if overlap >= chunk_size:
raise ValueError("overlap must be smaller than chunk_size")
chunks = []
step = chunk_size - overlap
for start in range(0, len(words), step):
chunk = words[start:start + chunk_size]
if chunk:
chunks.append(" ".join(chunk))
return chunks
text = """RAG sử dụng truy xuất để bổ sung thông tin cho mô hình ngôn ngữ.
Chunking chia tài liệu thành các phần nhỏ trước khi tạo embedding.
Kích thước chunk ảnh hưởng trực tiếp đến chất lượng truy xuất."""
chunks = split_text(text, chunk_size=12, overlap=3)
for i, chunk in enumerate(chunks, start=1):
print(f"Chunk {i}: {chunk}")
Ở đây, mỗi chunk chứa tối đa 12 từ và ba từ cuối của chunk trước được giữ lại trong chunk tiếp theo. Trong hệ thống thực tế, nên cân nhắc đếm theo token thay vì từ để kiểm soát chính xác hơn lượng dữ liệu đưa vào embedding model và LLM.
Chọn chunk size dựa trên dữ liệu thay vì một con số cố định
Thay vì hỏi “chunk size tốt nhất là bao nhiêu?”, nên bắt đầu từ đặc điểm của câu hỏi mà hệ thống cần trả lời. Nếu câu trả lời thường nằm trong một đoạn ngắn, chunk nhỏ có thể phù hợp. Nếu người dùng thường hỏi về quy trình gồm nhiều bước hoặc cần tổng hợp một section, chunk lớn hơn có thể giữ ngữ cảnh tốt hơn.
Một quy trình đánh giá thực tế có thể gồm:
- Thu thập một tập câu hỏi đại diện cho truy vấn thật.
- Xác định đoạn tài liệu nào chứa thông tin cần thiết cho từng câu hỏi.
- Thử một vài cấu hình chunk size và overlap.
- Đo xem các chunk đúng có xuất hiện trong top-k kết quả truy xuất hay không.
- Kiểm tra thêm chất lượng câu trả lời cuối cùng của LLM.
Điểm quan trọng là đánh giá cả retrieval lẫn generation. Một cấu hình tìm được nhiều đoạn liên quan nhưng đưa quá nhiều nội dung dư thừa vào prompt chưa chắc tạo câu trả lời tốt hơn.
Ngoài nội dung chunk, nên lưu metadata như tên tài liệu, heading, section, loại tài liệu hoặc thời gian cập nhật khi chúng hữu ích cho truy vấn. Metadata có thể được dùng để lọc dữ liệu trước khi thực hiện vector search và giúp hệ thống tránh tìm kiếm trên những tài liệu không phù hợp.
Khi nào cần thay đổi chiến lược chunking?
Chunking nên được xem xét lại khi hệ thống thường xuyên truy xuất đoạn có từ khóa đúng nhưng thiếu câu trả lời, hoặc khi câu trả lời cần ghép nhiều chunk chỉ để hiểu một ý hoàn chỉnh. Đây có thể là dấu hiệu chunk đang quá nhỏ hoặc ranh giới chia không phù hợp.
Ngược lại, nếu các kết quả retrieval chứa những đoạn rất dài với phần lớn nội dung không liên quan, chunk có thể đang quá lớn. Với tài liệu có cấu trúc rõ ràng, chuyển từ fixed-size sang structure-aware hoặc recursive chunking thường hợp lý hơn việc chỉ điều chỉnh một con số.
Semantic chunking đáng cân nhắc khi ranh giới chủ đề không trùng với paragraph hoặc heading, nhưng cần kiểm chứng lợi ích so với chi phí bổ sung. Một pipeline đơn giản, dễ đo lường thường là điểm khởi đầu tốt hơn một chiến lược phức tạp chưa được đánh giá.
Kết luận
Chunking trong RAG quyết định đơn vị thông tin mà hệ thống embedding và truy xuất, vì vậy nó tác động trực tiếp đến chất lượng context cung cấp cho LLM. Chunk size, overlap và ranh giới ngữ nghĩa cần được chọn theo cấu trúc tài liệu và loại câu hỏi thực tế.
Thay vì tìm một cấu hình áp dụng cho mọi bài toán, hãy bắt đầu bằng chiến lược đơn giản, xây dựng tập truy vấn đánh giá và điều chỉnh dựa trên kết quả retrieval lẫn câu trả lời cuối cùng.
Nội dung gốc thuộc tác giả. Vui lòng không đăng lại toàn văn khi chưa được phép, trừ trường hợp pháp luật hoặc giấy phép áp dụng cho phép. Nội dung của bên thứ ba tuân theo quyền và giấy phép tương ứng.
Nguồn gốc: Chunking trong RAG: Cách chia văn bản để truy xuất tốt hơn