Khi bắt đầu dự án, tôi nghĩ phần khó là chọn mô hình embedding và tinh chỉnh prompt. Sau ba tháng, nhật ký công việc cho thấy một bức tranh khác: gần như toàn bộ thời gian nằm ở việc làm cho 180.000 trang tài liệu trở nên đọc được bằng máy một cách nhất quán.
Bài viết này ghi lại những gì đã hỏng, cách phát hiện, và những thay đổi giữ lại sau cùng.
01Triệu chứng: câu trả lời đúng ngữ pháp, sai sự thật
Bản demo đầu tiên chạy tốt trên 40 câu hỏi mẫu. Khi mở cho phòng vận hành, tỷ lệ câu trả lời được đánh dấu sai tăng lên 31%. Điểm chung của các lỗi: hệ thống trích đúng tài liệu nhưng lấy nhầm phiên bản, hoặc lấy đúng phiên bản nhưng cắt mất bảng điều kiện ở trang kế tiếp.
- 34% lỗi đến từ tài liệu trùng lặp nhiều phiên bản, không có trường ngày hiệu lực.
- 28% từ bảng bị vỡ khi trích xuất PDF, biến thành chuỗi số không có tiêu đề cột.
- 18% từ việc chia đoạn cắt ngang một điều khoản.
- Phần còn lại là lỗi mô hình thật sự.
02Chuẩn hoá trước, chia đoạn sau
Thay vì chia đoạn theo số ký tự, chúng tôi dựng một bước trung gian: mỗi tài liệu được đưa về một cấu trúc chung gồm tiêu đề, ngày hiệu lực, phòng ban sở hữu và danh sách khối nội dung có kiểu. Bảng giữ nguyên là bảng, điều khoản giữ nguyên là một khối.
@dataclass
class Block:
doc_id: str
kind: Literal["heading", "clause", "table", "para"]
text: str
effective_from: date
department: str
def normalize(doc: RawDoc) -> list[Block]:
meta = extract_header(doc) # ngày hiệu lực, phòng ban
blocks = layout_parse(doc) # giữ bảng nguyên khối
return [b.with_meta(meta) for b in blocks if b.text.strip()]
Mỗi khối giữ lại metadata của tài liệu gốc, nên bộ lọc theo phòng ban và ngày hiệu lực chạy được ngay ở tầng truy hồi.
03Kết quả đo được
Cùng một mô hình, cùng một prompt, chỉ khác tầng dữ liệu. Đo trên bộ 320 câu hỏi do phòng vận hành viết.
| chỉ số | trước | sau |
|---|---|---|
| trả lời sai (người chấm) | 31% | 7% |
| recall@5 | 0,61 | 0,89 |
| trích dẫn sai phiên bản | 22% | 1,5% |
| độ trễ p95 | 2,4s | 1,9s |
“Mô hình chỉ tốt ngang với đoạn văn bản tệ nhất mà nó được đưa cho.”
04Những gì tôi sẽ làm khác lần sau
- Viết bộ eval trong tuần đầu. Không có nó, mọi tranh luận về chất lượng đều là cảm tính.
- Kiểm kê dữ liệu trước khi hứa tiến độ. Lấy mẫu 200 tài liệu và đọc bằng mắt.
- Đưa trích dẫn ra giao diện từ ngày đầu. Người dùng phát hiện lỗi dữ liệu nhanh hơn bất kỳ dashboard nào.