Retrieval không tìm nguyên tài liệu — nó tìm chunk (đoạn nhỏ). Cách bạn cắt quyết định agent tìm đúng hay trượt. Bài này bàn về chunking và embedding.
Vì sao phải cắt nhỏ?
- Giới hạn context: prompt chỉ chứa được một lượng token, không thể nhét cả tài liệu.
- Độ chính xác retrieval: chunk nhỏ, tập trung một ý → embedding "đậm nghĩa", dễ khớp câu hỏi. Chunk quá to pha loãng nhiều ý → khó khớp.
- Trích dẫn gọn: trích dẫn một đoạn 200 từ dễ kiểm chứng hơn cả trang.
Ba chiến lược chunking
- Cắt cố định (fixed-size): ví dụ 500 token, overlap 50. Đơn giản nhưng dễ cắt ngang câu/ý.
- Cắt theo cấu trúc (structure-aware): cắt theo heading, đoạn văn, mục. Giữ trọn ý — ưu tiên cho tài liệu có heading rõ (sổ tay, wiki).
- Cắt theo ngữ nghĩa (semantic): gộp các câu cùng chủ đề. Chất lượng cao nhưng tốn xử lý.
def chunk_by_heading(sections, max_tokens=500, overlap=60):
chunks = []
for sec in sections: # sec = {heading, text, page}
for piece in split_tokens(sec["text"], max_tokens, overlap):
chunks.append({
"text": f"{sec['heading']}\n{piece}", # nhồi heading vào chunk
"heading": sec["heading"],
"page": sec["page"],
})
return chunks
Mẹo quan trọng: nhồi heading (và tiêu đề tài liệu) vào đầu mỗi chunk. Chunk "Chính sách nghỉ phép\nNhân viên được 14 ngày..." khớp câu hỏi tốt hơn nhiều so với chỉ "Nhân viên được 14 ngày...".
Embedding là gì?
Embedding là vector số biểu diễn nghĩa của đoạn text. Hai đoạn cùng nghĩa có vector gần nhau (đo bằng cosine similarity). Nhờ vậy "bao nhiêu ngày phép" khớp được với "nhân viên được nghỉ 14 ngày" dù không trùng từ.
Lưu ý chọn model embedding:
- Hỗ trợ tiếng Việt tốt (đa ngôn ngữ) — bắt buộc với tài liệu tiếng Việt.
- Cùng một model cho cả ingest và query — nếu đổi model, phải tạo lại toàn bộ embedding.
- Kích thước vector ảnh hưởng chi phí lưu trữ và tốc độ.
def build_embeddings(chunks):
for c in chunks:
c["vector"] = embed_model.encode(c["text"]) # cùng model với query
return chunks
Khung tư duy: chọn kích thước chunk
- Câu hỏi factoid ("số ngày phép?") → chunk nhỏ (200–400 token), retrieval sắc.
- Câu hỏi giải thích quy trình → chunk vừa (500–800 token) để giữ đủ các bước.
- Nghi ngờ? Chọn vừa + overlap, rồi đo bằng câu hỏi thật (bài 6).
Ví dụ so sánh
Tài liệu: mục "Quy trình xin công tác phí" có 6 bước.
- Chunk quá nhỏ (100 token): mỗi bước một chunk → hỏi "quy trình đầy đủ?" chỉ lấy được vài bước, trả lời thiếu.
- Chunk vừa (500 token): trọn 6 bước trong 1 chunk → trả lời đủ.
- Chunk quá to (cả chương): lẫn cả công tác phí, tạm ứng, hoàn ứng → retrieval kém sắc.
Checklist chunking
- [ ] Ưu tiên cắt theo heading/đoạn, không cắt ngang câu.
- [ ] Nhồi heading + tiêu đề tài liệu vào chunk.
- [ ] Overlap 10–15% giữa các chunk.
- [ ] Mỗi chunk giữ metadata:
doc_id,page,heading. - [ ] Dùng cùng một embedding model cho ingest và query.
Sai lầm thường gặp
- Cắt cố định thô cắt ngang bảng/danh sách → chunk vô nghĩa.
- Quên nhồi heading → chunk mất ngữ cảnh, retrieval trượt câu hỏi tổng quát.
- Đổi embedding model giữa ingest và query → vector không so sánh được, kết quả rác.
- Chunk quá to vì "cho chắc" → pha loãng nghĩa, tốn token, giảm độ chính xác.
- Bỏ metadata khỏi chunk → không trích dẫn được ở bài sau.
Học xong bài này rồi?
Tạo tài khoản miễn phí để lưu lại — lần sau vào là biết ngay đang dở ở đâu,
và học hết khóa thì có chứng chỉ.
Lưu tiến độ của tôi