Sau OCR, bạn có một khối text hỗn độn. Bước này biến nó thành dữ liệu máy dùng được: một JSON với các trường chuẩn. Đây là trái tim của agent.
Hai trường phái trích xuất
- Regex/luật (rule-based) — dùng biểu thức chính quy tìm mẫu cố định (mã số thuế 10-13 số, ngày dd/mm/yyyy). Nhanh, rẻ, chính xác tuyệt đối khi mẫu ổn định. Nhưng giòn: nhà cung cấp đổi bố cục là gãy.
- LLM trích xuất theo schema — mô tả các trường cần lấy, để model đọc hiểu và điền. Linh hoạt với bố cục lạ, nhưng có thể "bịa" (hallucinate) và chậm/tốn hơn.
Định nghĩa schema trước — luôn luôn
Đừng để model tự do trả về. Ép nó theo một khuôn (JSON Schema):
{
"so_hoa_don": "string | null",
"ngay": "YYYY-MM-DD | null",
"mst_nguoi_ban": "string | null",
"tien_hang": "number | null",
"thue_vat": "number | null",
"tong_tien": "number | null",
"do_tin_cay": "0..1"
}
Trường null khi không tìm thấy — cấm bịa. Trường do_tin_cay để dùng cho việc phân làn ở bài sau.
Prompt trích xuất mẫu (dùng cho LLM)
Bạn là bộ trích xuất hóa đơn. Chỉ dùng thông tin có trong VĂN BẢN dưới đây.
Nếu không tìm thấy một trường, trả về null — TUYỆT ĐỐI không suy đoán.
Số tiền trả về dạng số, bỏ dấu chấm phân cách nghìn.
Trả về đúng JSON theo schema, không thêm chữ nào ngoài JSON.
SCHEMA: {...}
VĂN BẢN:
"""
<text OCR>
"""
Ba câu lệnh vàng: "chỉ dùng thông tin có trong văn bản", "không tìm thấy → null", "trả về đúng JSON". Thiếu chúng, model sẽ bịa số đẹp.
Trích trường cứng bằng regex (đáng tin hơn LLM cho con số)
import re
def extract_mst(text):
m = re.search(r"\b(\d{10}(?:-\d{3})?)\b", text) # 10 hoặc 13 số
return m.group(1) if m else None
def extract_amounts(text):
# 12.500.000 hoặc 12,500,000
return [int(x.replace(".", "").replace(",", ""))
for x in re.findall(r"\d{1,3}(?:[.,]\d{3})+", text)]
Với con số tiền và MST, regex đáng tin hơn LLM vì không có chỗ cho "sáng tạo".
Khung tư duy: mỗi trường một mức tin cậy
Gắn cho mỗi trường một cờ nguồn gốc:
| Nguồn | Độ tin cậy | Xử lý |
|---|---|---|
| Regex khớp duy nhất | Cao | Chấp nhận |
| LLM + có trong text | Trung bình | Đối chiếu chéo |
| LLM nhưng text mờ | Thấp | Gắn cờ người duyệt |
Các bước triển khai
- Viết schema JSON cho loại tài liệu.
- Trích trường cứng bằng regex trước (MST, ngày, số tiền).
- Trích trường mềm bằng LLM theo schema, ép trả
nullkhi thiếu. - Đối chiếu chéo những trường cả hai cùng lấy được.
- Chuẩn hóa định dạng: ngày về
YYYY-MM-DD, tiền về số nguyên đồng. - Sinh
do_tin_caytổng hợp từ mức tin cậy từng trường.
Checklist trích xuất
- [ ] Có schema JSON cố định
- [ ] Regex phủ hết trường có mẫu cứng
- [ ] Prompt ép "null khi không thấy"
- [ ] Có bước đối chiếu chéo regex vs LLM
- [ ] Ngày và tiền đã chuẩn hóa định dạng
Sai lầm thường gặp
- Để LLM trả tự do dạng văn xuôi — không parse nổi. Luôn ép JSON schema.
- Tin LLM tuyệt đối với con số — nó bịa số "hợp lý". Dùng regex cho tiền.
- Quên chuẩn hóa định dạng —
1.500.000và1500000lẫn lộn phá vỡ mọi phép tính sau. - Không lưu vị trí trường — khi cần người duyệt, họ không biết số đó lấy từ đâu trên trang. Lưu tọa độ nếu OCR hỗ trợ.
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