Nguyên tắc: cắt theo cấu trúc của tài liệu trước, cắt theo độ dài sau. Cắt cứng theo số ký tự sẽ chia đôi một bảng hoặc một khối code, và cả hai mảnh đều trở nên vô nghĩa khi truy xuất.
Thứ tự ưu tiên khi tách:
- Theo heading (Markdown #, thẻ <h1>/<h2> của HTML): mỗi mục thành một nhóm, giữ đường dẫn heading cha trong metadata.
- Theo khối nguyên vẹn: bảng, code fence, danh sách đánh số không được cắt giữa chừng.
- Cuối cùng mới theo độ dài với bộ tách đệ quy (thử ngắt ở đoạn văn, rồi câu, rồi từ).
python
from langchain_text_splitters import MarkdownHeaderTextSplitter, RecursiveCharacterTextSplitter
header_splitter = MarkdownHeaderTextSplitter(
headers_to_split_on=[("#", "h1"), ("##", "h2")]
)
sections = header_splitter.split_text(doc)
# chỉ section nào vẫn còn quá dài mới cắt tiếp theo độ dài
splitter = RecursiveCharacterTextSplitter(chunk_size=800, chunk_overlap=120)
chunks = splitter.split_documents(sections)Hai điểm hay bị bỏ sót: overlap khoảng 10-15% để câu bị cắt ở biên vẫn xuất hiện đủ ở một chunk, và prepend tiêu đề mục vào nội dung chunk để chunk vẫn đủ nghĩa khi bị tách khỏi ngữ cảnh.