Bài toán: rút dữ liệu có cấu trúc (trường, bảng, quan hệ) từ hoá đơn, hợp đồng, báo cáo — nơi layout mang thông tin, không chỉ có chữ.
Vì sao OCR thuần không đủ: OCR trả về chữ nhưng mất cấu trúc. Một hoá đơn có nhiều con số; phải biết "1.250.000" nằm ở ô nào mới biết đó là tổng tiền hay tiền thuế. Thế hệ trước giải bằng model hiểu layout (LayoutLM, Donut — học trên bộ ba chữ + toạ độ + ảnh), nhưng phải fine-tune riêng cho từng loại tài liệu và cần dữ liệu gán nhãn.
Cách làm hiện nay: cho VLM đọc thẳng ảnh trang và ép trả về theo schema. Không cần fine-tune, chịu được layout thay đổi, và schema đóng luôn vai trò đặc tả.
class LineItem(BaseModel):
description: str
quantity: int
unit_price: float
class Invoice(BaseModel):
invoice_number: str
issue_date: str # mô tả rõ định dạng: YYYY-MM-DD
vendor_name: str
line_items: list[LineItem]
subtotal: float
tax: float
total: float
low_confidence_fields: list[str] # buộc model tự khai chỗ nó không chắc
resp = client.beta.chat.completions.parse(
model="gpt-4o",
messages=[
{"role": "system", "content": "Chi trich xuat tu anh. Truong nao khong doc duoc thi de trong va ghi vao low_confidence_fields. Tuyet doi khong bia."},
{"role": "user", "content": [{"type": "image_url",
"image_url": {"url": f"data:image/png;base64,{img_b64}"}}]},
],
response_format=Invoice,
temperature=0,
)Ba thứ quyết định hệ có dùng được hay không:
- Bắt model tự khai chỗ không chắc. Thiếu trường này thì model sẽ điền một giá trị trông rất hợp lý, và đó là dạng lỗi tệ nhất vì không ai phát hiện ra.
- Kiểm bằng ràng buộc nghiệp vụ, không chỉ kiểm schema.
tổng các dòng = subtotal,subtotal + thuế = total. Sai thì cho chạy lại hoặc đẩy sang người. Đây là lớp bắt lỗi rẻ và hiệu quả nhất. - Có đường đưa sang người duyệt. Với tài liệu dính tiền bạc hay pháp lý, mục tiêu không phải tự động 100%, mà là tự động phần chắc chắn và định tuyến phần còn lại.
Khó ở đâu trong thực tế: ảnh scan mờ hoặc lệch (phải tiền xử lý), chữ viết tay (model đa dụng yếu, cần dịch vụ chuyên), bảng tràn qua nhiều trang phải ghép lại, và ô tick cùng chữ ký rất hay bị bỏ sót.
Chi phí: mỗi trang tốn cỡ 1.500–2.000 token ảnh. Khi khối lượng lớn, dùng parser hiểu layout (LlamaParse, Azure Document Intelligence, Amazon Textract) chuyển sang văn bản có cấu trúc rồi cho một model rẻ đọc thường tiết kiệm hơn hẳn so với cho VLM đọc ảnh mọi trang.