Chất lượng Agent Q&A phụ thuộc trực tiếp vào chất lượng nguồn. Bài này xây kho nguồn (source of truth) sạch, có metadata, sẵn sàng đưa vào pipeline RAG.
Bước 1: Kiểm kê nguồn (source inventory)
Lập bảng liệt kê mọi nguồn tài liệu. Với mỗi nguồn ghi: định dạng, chủ sở hữu, tần suất cập nhật, độ nhạy cảm.
| Nguồn | Định dạng | Owner | Cập nhật | Nhạy cảm |
|---|---|---|---|---|
| Sổ tay nhân viên | HR | Quý | Nội bộ | |
| Bảng giá dịch vụ | Google Sheet | Sales | Tuần | Nội bộ |
| Wiki kỹ thuật | Confluence | Eng | Liên tục | Nội bộ |
Bước 2: Trích xuất text theo định dạng
Mỗi định dạng cần cách xử lý riêng:
- PDF text-based: dùng
pdfplumber/PyMuPDFđể lấy text kèm số trang. - PDF scan (ảnh): cần OCR (Tesseract) — chất lượng thấp hơn, cần kiểm tra.
- DOCX:
python-docx. - HTML/Wiki: bóc tag, giữ heading làm cấu trúc.
- Bảng tính: chuyển mỗi dòng thành câu có nghĩa, đừng để nguyên ô rời rạc.
import pdfplumber
def extract_pdf(path):
pages = []
with pdfplumber.open(path) as pdf:
for i, page in enumerate(pdf.pages, start=1):
text = page.extract_text() or ""
pages.append({"page": i, "text": text})
return pages
Bước 3: Làm sạch (cleaning)
- Bỏ header/footer lặp ("Trang X", tên công ty in mỗi trang) — chúng gây nhiễu retrieval.
- Bỏ mục lục, trang bìa — không mang thông tin trả lời được.
- Chuẩn hóa khoảng trắng, gộp dòng bị ngắt giữa câu.
- Giữ lại heading và cấu trúc — sẽ dùng cho metadata và chunking ở bài sau.
- Với bảng, viết lại thành câu:
"Gói Basic: 200.000đ/tháng, 5 người dùng"thay vìBasic | 200000 | 5.
Bước 4: Gắn metadata cho mỗi tài liệu
Metadata là chìa khóa để trích dẫn và lọc quyền sau này.
{
"doc_id": "hr-handbook-2026",
"title": "Sổ tay nhân viên 2026",
"source_url": "https://drive.company/hr-handbook",
"owner": "hr@company.vn",
"version": "2026.1",
"effective_date": "2026-01-01",
"access": ["all-staff"]
}
Khung tư duy: 4C của một nguồn tốt
- Current (hiện hành) — bản mới nhất, ghi rõ ngày hiệu lực.
- Complete (đầy đủ) — không thiếu phần quan trọng.
- Clean (sạch) — không rác, không header/footer lặp.
- Credited (ghi nguồn) — có metadata để trích dẫn ngược lại.
Ví dụ: xử lý xung đột phiên bản
Bạn tìm thấy hai file: chinh-sach-phep-2024.pdf và chinh-sach-phep-2026.pdf, nội dung khác nhau về số ngày phép. Nếu nạp cả hai, agent sẽ trả lời lẫn lộn. Cách xử lý:
- Xác định bản hiện hành (2026) qua
effective_date. - Loại hoặc đánh dấu deprecated bản cũ.
- Nếu cần giữ lịch sử, thêm metadata
status: archivedvà lọc bỏ khi retrieve mặc định.
Checklist trước khi sang bước embedding
- [ ] Mỗi tài liệu có
doc_id,title,source_url,version,owner. - [ ] Đã loại bản trùng/cũ, chỉ giữ bản hiện hành.
- [ ] Text đã bỏ header/footer/mục lục.
- [ ] Bảng đã chuyển thành câu có nghĩa.
- [ ] Đã ghi lại số trang/heading để trích dẫn.
Sai lầm thường gặp
- Nạp file scan mà không OCR. Kết quả là chunk rỗng, agent "không tìm thấy" dù tài liệu có.
- Giữ nhiều phiên bản cùng lúc. Agent trả lời mâu thuẫn, mất niềm tin ngay lần đầu.
- Mất số trang khi trích xuất. Sau này không trích dẫn được, không debug được.
- Để nguyên bảng thô. Ô rời rạc làm embedding vô nghĩa, retrieval trượt.
- Không ghi owner. Khi tài liệu sai, không biết hỏi ai để sửa.
Mẹo thực chiến: bắt đầu nhỏ
Đừng cố nạp toàn bộ kho tài liệu công ty ngay lần đầu. Chọn một nhóm hẹp (ví dụ chỉ tài liệu HR) với 20–30 câu hỏi thật, làm sạch thật kỹ, chạy thử. Khi pipeline đã ổn định và bạn tin vào chất lượng, mới mở rộng sang phòng ban khác. Cách này giúp phát hiện lỗi làm sạch sớm, chi phí thấp, và có sản phẩm chạy được để lấy phản hồi thay vì một dự án khổng lồ chưa dùng được.
Nguồn đã sạch. Bài 3 sẽ cắt chúng thành chunk và tạo embedding.