Chunking tài liệu khách hàng: đo trước khi cắt, rồi gắn ngữ cảnh cho từng chunk
Bị cắt khỏi tài liệu gốc, một đoạn văn có thể mất cả tên công ty lẫn mốc thời gian. Chỉ cần gắn lại vài chục token ngữ cảnh, số lần truy xuất thất bại đã giảm 49%, và giảm 67% nếu thêm reranking.
- 1Đếm token của corpusDưới khoảng 200.000 token thì có thể đưa thẳng vào prompt, không cần chunking.
- 2Phân tích tài liệuXác định văn bản trơn, hợp đồng có cấu trúc hay báo cáo có bảng biểu, hình ảnh.
- 3Dựng bộ câu hỏi thửGom câu hỏi từ người dùng thật, mỗi câu kèm đoạn văn chứa câu trả lời.
- 4So sánh cấu hình chunkĐo hit rate cho từng kích thước và overlap, rồi ghi lại cái giá của lựa chọn.
- 5Gắn ngữ cảnh cho chunkThêm 50-100 token ngữ cảnh và metadata nguồn vào đầu chunk trước khi embed.
- 6Đo lạiChạy lại đúng bộ câu hỏi cũ để thấy thay đổi thực sự.
Chỉ cắt sau khi đã đo, và luôn đo lại sau khi gắn ngữ cảnh cho từng chunk.
Đồ hoạ: FDE Times
Tóm tắt nhanh
- Corpus dưới khoảng 200.000 token (chừng 500 trang) có thể đưa thẳng vào prompt, không cần chunking.
- Chọn kích thước chunk và overlap dựa trên kết quả đo với câu hỏi thật, đừng tin cấu hình mặc định.
- Gắn 50-100 token ngữ cảnh vào đầu mỗi chunk giúp giảm 49% số lần truy xuất thất bại, và 67% khi kết hợp reranking.
Thử hình dung đây là tuần thứ hai bạn ở chỗ khách hàng. Bản demo RAG trả lời trơn tru mười câu hỏi bạn tự soạn. Rồi trưởng phòng tài chính gõ một câu thật: doanh thu quý hai của công ty con phía Bắc tăng bao nhiêu?
Hệ thống trả về một đoạn ghi “doanh thu tăng 3% so với quý trước”. Đoạn này có thật trong tài liệu, nhưng thuộc báo cáo của một công ty con khác, ở một quý khác. Model không bịa gì cả. Nó chỉ nhận về một đoạn văn đã bị cắt mất tên và ngày tháng.
Anthropic mô tả đúng hiện tượng này: khi đứng một mình, chunk không còn cho biết nó nói về công ty nào hay giai đoạn nào.
Với một FDE, đây là thứ bạn sẽ gặp ở gần như mọi dự án RAG, vì tài liệu doanh nghiệp đầy những câu như “như đã nêu ở trên” hay “trong kỳ này”.
Bài này đi qua ba việc theo đúng thứ tự: đo trước, cắt sau, và gắn ngữ cảnh cho từng chunk.
Vì sao không nên cắt theo mặc định?
Hướng dẫn kiến trúc RAG của Microsoft gọi cách chunking là một lựa chọn gần như cố định trong thiết kế hệ thống. Lý do rất thực tế: đổi cách cắt nghĩa là embed lại, index lại, và đo lại mọi thứ phía sau. Quyết định sai ở tuần thứ hai sẽ còn đi theo bạn đến lúc bàn giao.
Trong khi đó, báo cáo kỹ thuật của Chroma cho thấy cấu hình mặc định của một số chiến lược chunking phổ biến cho kết quả khá kém. Thư viện cho bạn một con số chunk size sẵn có. Con số đó chưa từng nhìn thấy tài liệu của khách hàng.
Câu hỏi đầu tiên: có cần cắt không?
Trước khi bàn chuyện cắt thế nào, hãy hỏi có cần cắt hay không. Anthropic lưu ý rằng nếu knowledge base nhỏ hơn 200.000 token, tức khoảng 500 trang, bạn có thể đưa toàn bộ vào prompt mà không cần RAG.
Ở nhiều khách hàng, bộ tài liệu cho một use case đầu tiên chỉ là vài chục quy trình nội bộ. Đếm token trong buổi đầu tiên có thể tiết kiệm cho bạn cả tuần dựng pipeline. Nếu corpus lớn hơn ngưỡng đó, hoặc sẽ còn phình ra nhanh, thì mới chuyển sang bước tiếp theo.
Đo bằng câu hỏi thật, không bằng cảm giác
Microsoft khuyên làm phân tích tài liệu trước, rồi thử nhiều cách chunking trên một bộ test gồm tài liệu và câu hỏi đã thu thập sẵn. Phân tích tài liệu nghĩa là nhìn xem khách hàng đang có loại gì: văn bản trơn, hợp đồng có điều khoản đánh số, hay báo cáo có bảng biểu và hình ảnh.
Cấu trúc tài liệu quyết định nên cắt kiểu gì. Theo Microsoft, văn bản ít cấu trúc hợp với cắt theo câu hoặc cắt kích thước cố định có overlap. Tài liệu bán cấu trúc thì hợp với phân tích layout hoặc code tự viết theo đúng định dạng.
Pinecone bổ sung thêm vài câu hỏi cần trả lời trước khi chọn: nội dung thuộc loại gì, dùng embedding model nào, và câu hỏi của người dùng dài, phức tạp đến đâu. Câu hỏi cuối chỉ trả lời được bằng cách ngồi với người dùng thật. Vì vậy bộ test nên đến từ họ, không phải từ bạn.
Về thước đo, cách đơn giản nhất là hit rate: với mỗi câu hỏi, đoạn văn chứa câu trả lời có nằm trong top-k kết quả hay không. Chroma đi xa hơn với Intersection over Union (IoU) ở mức token, một cách chấm chunking tách biệt khỏi cả pipeline RAG. IoU phạt những token thừa do các chunk chồng lên nhau.
Một ví dụ đo từ đầu đến cuối
Giả sử khách hàng là một công ty bảo hiểm với vài nghìn hợp đồng. Bạn ngồi với nhóm chăm sóc khách hàng và gom được 40 câu hỏi họ thực sự hay tra cứu, mỗi câu kèm đoạn điều khoản chứa câu trả lời.
Rồi bạn chạy ba cấu hình và đo hit rate ở top-5. Các con số dưới đây chỉ là minh hoạ cho cách đọc kết quả.
| Cấu hình | Tìm đúng đoạn trong top-5 | Hit rate |
|---|---|---|
| 200 token, không overlap | 24/40 | 60% |
| 200 token, overlap 50 token | 31/40 | 77,5% |
| 800 token, không overlap | 28/40 | 70% |
Nhìn vào bảng, chunk nhỏ không overlap kém hẳn hai cấu hình còn lại, vì câu trả lời hay rơi đúng vào chỗ bị cắt. Kết quả này khớp với quan sát của Chroma rằng với context nhỏ, overlap là cần thiết để đạt recall cao, và với cảnh báo của Microsoft rằng ngữ cảnh liên quan có thể trải qua nhiều chunk.
Chunk 800 token cũng không phải lời giải. Pinecone nhắc rằng chunk quá nhỏ hay quá lớn đều làm kết quả tìm kiếm kém chính xác. Lý do với chunk lớn khá dễ hình dung: một đoạn dài gom nhiều ý khác nhau, nên embedding của nó khó khớp sắc nét với một câu hỏi cụ thể.
Còn overlap thì có giá của nó: thêm token trùng lặp, nghĩa là IoU giảm và index phình to. Bạn chọn cấu hình thứ hai, nhưng ghi rõ lý do và cái giá phải trả.
Gắn ngữ cảnh vào từng chunk
Chọn đúng kích thước vẫn chưa sửa được lỗi ở đầu bài. Đoạn “doanh thu tăng 3%” dù dài 200 hay 800 token vẫn không nói nó thuộc công ty nào. Contextual Retrieval, kỹ thuật Anthropic giới thiệu, nhắm đúng vào lỗi này.
Ý tưởng rất gọn: mỗi chunk được gắn thêm một đoạn ngữ cảnh ngắn viết riêng cho nó, thường 50-100 token, đặt ở đầu chunk trước khi embed và trước khi đánh index BM25. Theo Anthropic, cách này giảm 49% số lần truy xuất thất bại, và 67% khi kết hợp thêm reranking.
Đoạn phác thảo dưới đây là một cách làm: nhờ LLM đọc tài liệu chứa chunk và viết phần ngữ cảnh đó.
# Phác thảo: llm() và search() là hàm giả định, thay bằng client bạn đang dùng
def contextualize(doc_text, chunk_text, llm):
prompt = (
"TÀI LIỆU:\n" + doc_text + "\n\n"
"ĐOẠN CẦN ĐẶT NGỮ CẢNH:\n" + chunk_text + "\n\n"
"Viết 1-2 câu ngắn nêu đoạn này thuộc tài liệu nào, "
"nói về đơn vị nào, giai đoạn nào. Chỉ trả về phần ngữ cảnh."
)
context = llm(prompt) # thường khoảng 50-100 token
return context + "\n\n" + chunk_text # embed và index BM25 chuỗi này
def hit_rate(test_set, search, k=5):
hits = 0
for q in test_set: # mỗi q gồm "question" và "gold_span"
results = search(q["question"], k=k)
hits += any(q["gold_span"] in r.text for r in results)
return hits / len(test_set)
Lưu ý hàm hit_rate kiểm tra đoạn văn đúng có nằm trong kết quả hay không, thay vì so ID chunk. Nhờ vậy cùng một bộ test dùng được cho mọi cấu hình cắt. Chi phí cũng không đáng ngại: nhờ prompt caching, Anthropic ước tính khoảng 1,02 USD cho mỗi triệu token tài liệu, với giả định chunk 800 token và tài liệu 8.000 token.
Ngữ cảnh không chỉ là câu chữ. Microsoft khuyên khi mô tả một bảng hay hình ảnh bị chia ra nhiều chunk, hãy gắn URL của hình vào từng chunk để metadata luôn đi kèm mọi câu trả lời dùng đến nó. Tên file, số trang, mục lục cũng nên đi theo từng chunk như vậy.
Đo lại: vòng cuối của ví dụ
Quay lại công ty bảo hiểm. Bạn giữ cấu hình 200 token, overlap 50 token, gắn ngữ cảnh cho từng chunk, rồi chạy lại đúng 40 câu hỏi cũ. Vẫn là số minh hoạ: giả sử kết quả lên 35/40, tức hit rate 87,5%, so với 31/40 trước đó.
Điều quan trọng là bạn so trên cùng một bộ câu hỏi và cùng một thước đo. Nếu đổi bộ test giữa chừng, bạn không còn biết phần cải thiện đến từ ngữ cảnh hay từ câu hỏi dễ hơn. Bảng hai dòng “trước” và “sau” này cũng là thứ bạn đưa cho khách hàng khi đề xuất bật tính năng.
Những lỗi hay gặp
Lỗi phổ biến nhất là tự soạn câu hỏi test. Câu hỏi của kỹ sư thường dùng đúng từ trong tài liệu, nên hit rate cao giả tạo. Câu hỏi của người dùng thật ngắn hơn, mơ hồ hơn, và hay dùng từ nội bộ.
Lỗi thứ hai là đo một lần rồi thôi. Mỗi khi khách hàng thêm loại tài liệu mới, ví dụ chuyển từ hợp đồng sang biên bản họp, bộ test cần thêm câu hỏi cho loại đó. Lỗi thứ ba là cắt bảng biểu như văn bản trơn: một hàng số liệu tách khỏi tiêu đề cột thì gần như vô nghĩa.
Lỗi cuối cùng là bỏ qua bước kiểm tra kích thước corpus. Không ít pipeline phức tạp được dựng cho một bộ tài liệu vừa vặn trong một prompt.
Nhà tuyển dụng thấy kỹ năng này ở đâu?
Trong JD của các vị trí FDE hay AI engineer, hãy để ý những cụm như “retrieval quality”, “evaluation”, “RAG pipeline” hay “document ingestion”. Đó là tín hiệu công việc sẽ cần đúng những gì bài này mô tả.
Trên CV, một dòng có số đo thuyết phục hơn nhiều so với “xây dựng hệ thống RAG”. Ví dụ: “Dựng bộ 40 câu hỏi từ người dùng, so sánh 3 cấu hình chunking, nâng hit rate@5 từ X lên Y bằng overlap và gắn ngữ cảnh cho từng chunk”.
Khi phỏng vấn, hãy chuẩn bị nói rõ sự đánh đổi phía sau cấu hình bạn chọn: overlap giúp tăng recall nhưng làm giảm IoU và làm index phình to, còn chunk 800 token tuy ít bị cắt ngang câu trả lời nhưng lại kém chính xác khi tìm kiếm. Người phỏng vấn muốn nghe bạn biết mình đã trả giá gì để đổi lấy con số đó.
Khách hàng sẽ không bao giờ hỏi bạn chunk size là bao nhiêu. Họ chỉ nhớ lần hệ thống trả lời nhầm doanh thu của một công ty con khác, và người hiểu vì sao lỗi đó xảy ra là người họ muốn giữ lại.