JSON hợp lệ mới là bước kiểm tra đầu tiên của đầu ra LLM
Kiểm tra kết quả trích xuất theo cấu trúc, số học và bằng chứng nguồn; phân biệt thuế chưa biết với thuế bằng không qua ví dụ chạy được.

Khi dùng câu trả lời của mô hình ngôn ngữ làm dữ liệu ứng dụng, phân tích JSON thành công mới là bước kiểm tra đầu tiên. Một đối tượng đúng cú pháp vẫn có thể chứa sai tiền tệ, tổng tiền vô lý hoặc giá trị chưa từng xuất hiện trong nguồn. Việc xác thực phải theo sát ý nghĩa của trường dữ liệu tới tận hành động sử dụng trường đó.
Bài này dành cho lập trình viên đã đọc được JSON và muốn thiết kế luồng trích xuất có thể kiểm tra. Giả sử model nhận một hóa đơn rồi trả về nhà cung cấp, tiền tệ, các dòng hàng và tổng tiền. Ứng dụng chỉ tạo bản nháp để người dùng rà soát, chưa thực hiện thanh toán. Phạm vi hành động nhỏ vẫn cần dữ liệu chính xác, vì một bản nháp sai có thể làm tốn thời gian hoặc chuyển lỗi sang hệ thống khác.
Tách các lớp xác thực
Bắt đầu từ cú pháp: bộ phân tích JSON có đọc được phản hồi không? Tiếp theo là schema, tức hợp đồng về cấu trúc dữ liệu: các trường bắt buộc đã có chưa, số có được biểu diễn bằng kiểu số không, mã tiền tệ có đúng định dạng cho phép không? Sau đó kiểm tra quy tắc nghiệp vụ, chẳng hạn miền hợp lệ của số lượng và tổng tiền phải khớp các dòng hàng cùng khoản điều chỉnh được ghi nhận.
Cuối cùng là bằng chứng. Tổng tiền có thể khớp phép tính nhưng vẫn do model tự tạo. Tài liệu nguồn phải hỗ trợ các giá trị được trích xuất. Nếu model điền một khoản thuế thiếu căn cứ để tổng tiền cân bằng, kiểm tra số học không phát hiện được việc bịa dữ liệu đó.
{
"currency": "USD",
"items": [
{"description": "Notebook", "quantity": 2, "unitPriceMinor": 500}
],
"taxMinor": 100,
"totalMinor": 1100,
"evidence": {"totalMinor": "page-1-total"}
}
Đây là các giá trị giả định, dùng số nguyên theo đơn vị tiền tệ nhỏ nhất trong ví dụ USD có hai chữ số thập phân. Thành tiền của dòng hàng là 2 × 500 = 1000; cộng 100 thành 1100. Mô hình tiền tệ trong hệ thống thực tế phải tuân theo đơn vị nhỏ nhất của từng loại tiền và quy tắc làm tròn đã chọn.
Mỗi lớp loại một nhóm lỗi khác nhau. Cấu trúc hợp lệ không kéo theo tổng tiền hợp lệ; tổng tiền hợp lệ cũng không kéo theo nguồn hỗ trợ. Tách các nhãn lỗi giúp hàng đợi rà soát hữu ích hơn việc gộp tất cả thành “phản hồi không hợp lệ”.
Dùng structured output đúng phạm vi bảo đảm
Hướng dẫn structured outputs của OpenAI, được đọc ngày 20 tháng 9 năm 2026, mô tả cách ràng buộc đầu ra theo các JSON Schema được hỗ trợ. Tính năng này có thể giảm lỗi định dạng trên model và schema phù hợp. Nó không quyết định model đã đọc đúng hóa đơn hay bản thân hóa đơn có xác thực hay không.
Xử lý trường hợp từ chối và sinh chưa hoàn tất thành các kết quả riêng theo hợp đồng API. Đừng coi mọi nhánh phản hồi đều chứa một đối tượng hóa đơn thành công để đem đi phân tích. Yêu cầu vượt ngân sách đầu ra có thể cần thử lại có kiểm soát hoặc rà soát thủ công; phản hồi từ chối có thể cần lời giải thích khác cho người dùng.
Ngay cả khi nhà cung cấp ràng buộc cấu trúc đầu ra, ứng dụng vẫn nên xác thực tại ranh giới nhận dữ liệu. Dữ liệu còn có thể đến từ bản ghi đã lưu, fixture kiểm thử, model thay thế hoặc phiên bản tích hợp mới. Một nơi xác thực tập trung giúp các đường vào tuân cùng hợp đồng và báo lỗi nhất quán khi schema thay đổi ngoài dự kiến.
Giữ rõ thông tin đang thiếu
Không có số tiền thuế khác với số tiền thuế bằng không. Nếu nguồn không nêu thuế, kết quả trích xuất phải giữ sự chưa biết ấy. Trường cho phép null có thể biểu diễn giá trị thiếu; một trạng thái bằng chứng riêng còn giúp phân biệt văn bản không đọc được với trường thực sự không xuất hiện.
Chẳng hạn, taxMinor: null kèm taxStatus: "not_found" cung cấp thông tin khác với taxMinor: 0 có trích dẫn dòng “Tax 0.00”. Tránh giá trị mặc định trong schema âm thầm thay mọi khoản thiếu bằng không. Giá trị mặc định là quyết định của ứng dụng và không nên xóa mất bằng chứng về đầu vào.
Vấn đề tương tự xảy ra với ngày tháng. Nguồn có thể chỉ nêu tháng, hoặc ghi ngày theo cách chưa rõ thứ tự ngày và tháng. Schema bắt buộc một ngày ISO đầy đủ có thể thúc đẩy model chọn cách hiểu thiếu căn cứ. Hợp đồng nên cho phép giữ trạng thái ngày chưa xác định khi đó mới là kết quả trung thực.
Chạy một kiểm tra tổng tiền có phạm vi hẹp
Hàm thuần dưới đây chạy sau khi lớp xác thực cấu trúc đã bảo đảm các khóa, dạng đối tượng và trường chuỗi trong ví dụ. Nó chỉ kiểm tra nghiệp vụ và bằng chứng cho tổng tiền, không thay thế bộ xác thực JSON Schema. Hóa đơn minh họa chỉ cho phép USD, số lượng nguyên dương và số tiền nguyên không âm; không có chiết khấu, khoản ghi có, số lượng phân số hoặc chuyển đổi tiền tệ.
def check_total(invoice, source_totals):
if invoice["currency"] != "USD":
return "unsupported_currency"
if not invoice["items"]:
return "invalid_items"
subtotal = 0
for item in invoice["items"]:
quantity, price = item["quantity"], item["unitPriceMinor"]
if type(quantity) is not int or quantity <= 0:
return "invalid_quantity"
if type(price) is not int or price < 0:
return "invalid_price"
subtotal += quantity * price
tax, total = invoice["taxMinor"], invoice["totalMinor"]
if tax is None:
return "tax_unknown"
if any(type(x) is not int or x < 0 for x in (tax, total)):
return "invalid_amount"
if subtotal + tax != total:
return "total_mismatch"
reference = invoice["evidence"]["totalMinor"]
if reference not in source_totals:
return "unknown_reference"
if source_totals[reference] != total:
return "source_total_mismatch"
return "total_supported"
Dùng đối tượng JSON ở trên làm hóa đơn và một bảng giá trị nguồn đáng tin cậy chứa {"page-1-total": 1100}. Kết quả kỳ vọng là tổng tiền có nguồn hỗ trợ. Nếu chỉ đổi tổng thành 1200, kiểm tra số học thất bại. Nếu đổi cả thuế thành 200 và tổng thành 1200, phép tính khớp lại nhưng giá trị không khớp nguồn. Biến thể thứ hai cho thấy vì sao chỉ kiểm tra mã trích dẫn có tồn tại là chưa đủ.
Bảng giá trị nguồn ở đây do người viết kiểm thử gán nhãn trên một phiên bản tài liệu cụ thể. Trong ứng dụng thật, lấy giá trị độc lập ấy có thể cần bộ phân tích tài liệu đáng tin cậy hoặc người rà soát. Yêu cầu cùng model nhắc lại tổng tiền nó đã tự tạo không sinh ra bằng chứng độc lập. Tổng có căn cứ cũng không chứng minh nhà cung cấp, mô tả hàng, thuế hay từng số lượng đều đúng. Các trường ấy cần kiểm tra riêng trước khi chấp nhận toàn bộ bản nháp.
Để kiểm tra thuế bằng không, đặt thuế là 0, tổng là 1000 và dùng fixture riêng có nguồn ghi rõ tổng đó. Hàm chấp nhận trường hợp này. Nếu thay thuế bằng null, kết quả chuyển sang chưa biết thuế; hàm không tự thay bằng không. Python còn có trường hợp biên đáng chú ý vì Boolean thuộc lớp con của số nguyên: kiểm tra kiểu chính xác trong mã sẽ loại số lượng true. Hàm vẫn giả định cấu trúc đầu vào hợp lệ và bảng nguồn chứa số nguyên đáng tin cậy, nên đối tượng sai hình dạng phải được kiểm tra ở lớp trước.
Bài trích xuất dữ liệu bằng LLM schemas của Simon Willison, xuất bản ngày 28 tháng 2 năm 2025, minh họa cách lấy cấu trúc bản ghi nhất quán từ nội dung phi cấu trúc. Phần thảo luận về cơ chế khác nhau giữa nhà cung cấp cũng là lý do giữ rõ các kiểm tra phía ứng dụng. Schema tái sử dụng giúp tích hợp có hợp đồng ổn định; đối chiếu nguồn theo nghiệp vụ cung cấp một bảo đảm khác. Hàm hóa đơn minh họa trách nhiệm thứ hai, không tuyên bố đã đo được tỷ lệ trích xuất thành công.
Đặt hành động sau các bước kiểm tra
Hướng dẫn function calling mô tả cách model yêu cầu ứng dụng thực hiện một thao tác. Nếu dữ liệu trích xuất sau này trở thành tham số của công cụ tạo bản nháp, bộ thực thi phải áp dụng cùng các kiểm tra cấu trúc và nghiệp vụ trước khi ghi dữ liệu. Mức tự tin mà model thể hiện không phải quy tắc cấp quyền.
Gắn mã bằng chứng với các bản ghi ứng dụng thực sự đã cung cấp. Mã do model sinh như page-1-total chỉ hữu ích khi ánh xạ được tới đoạn nguồn có thật. Loại tham chiếu nằm ngoài tập đó và giữ phiên bản tài liệu để người rà soát nhìn thấy đúng nguồn đã dùng khi trích xuất.
Bộ kiểm thử nên có JSON hỏng cú pháp, thuộc tính dư, số lượng âm, tổng không khớp, thiếu trường thuế và mã bằng chứng tự tạo. Thêm một trường hợp hợp lệ có thuế bằng không được ghi rõ để bảo đảm bộ xác thực không loại nó chỉ vì trường hợp khác dùng null. Với trường thuế bị thiếu hẳn, lớp schema phải phát hiện trước khi chạy hàm tổng tiền.
Kết quả chấp nhận nên nêu lớp nào thất bại và việc thử lại có thể giúp gì. Gọi lại cùng model có thể sửa lỗi định dạng, nhưng không tạo ra trang tài liệu đang thiếu. Khi thiếu bằng chứng, yêu cầu bổ sung nguồn hoặc chuyển sang rà soát. Bản nháp cuối cùng chỉ nên giữ những giá trị mà ứng dụng giải thích được cả ý nghĩa lẫn nguồn gốc.