AILapTrinh.comAI Lập Trình
Đưa tính năng AI vào sản phẩm

Bắt AI trả về JSON đúng cấu trúc: lược đồ, kiểm hợp lệ và thử lại khi hỏng

Cách lấy đầu ra JSON ổn định từ mô hình ngôn ngữ: ba mức kiểm soát, thiết kế lược đồ dễ điền, kiểm hợp lệ ở máy chủ và thử lại có giới hạn.

Small online shop office in Can Tho, a staff member seen from behind sorting parcels on a shelf while a laptop with a blank screen sits on a packing table

Muốn mô hình ngôn ngữ trả về JSON mà mã của bạn đọc được mọi lần, bạn cần ba lớp: mô tả cấu trúc mong muốn bằng một lược đồ rõ ràng, dùng chế độ đầu ra có cấu trúc nếu nhà cung cấp hỗ trợ, và luôn kiểm hợp lệ ở máy chủ trước khi dùng, hỏng thì thử lại có giới hạn hoặc báo lỗi. Thiếu lớp cuối cùng, sớm muộn một câu trả lời lệch định dạng sẽ làm sập một trang hay ghi dữ liệu rác vào cơ sở dữ liệu.

Bài này dành cho lập trình viên muốn dùng AI để trích xuất, phân loại, chấm nhãn hay sinh dữ liệu cho phần mềm xử lý tiếp, chứ không phải để hiện chữ cho người đọc. Ví dụ xuyên suốt là ví dụ giả định: một cửa hàng online nhận đơn qua tin nhắn và muốn tự tách tên hàng, số lượng, địa chỉ giao.

Vì sao đầu ra cho máy đọc khó hơn đầu ra cho người đọc

Người đọc tha thứ được nhiều thứ: một câu mở đầu thừa, một dấu chấm lạc chỗ, số viết “hai cái” thay vì 2. Trình phân tích JSON thì không. Thiếu một dấu ngoặc, dư một dấu phẩy cuối, hay mô hình mở đầu bằng câu “Đây là kết quả của bạn:” là hàm phân tích ném lỗi ngay. Với tính năng chạy hàng nghìn lần mỗi ngày, tỉ lệ hỏng dù rất nhỏ cũng thành vài chục lỗi thật.

Khó hơn nữa là lỗi không nằm ở cú pháp mà ở nội dung: JSON hợp lệ nhưng trường số lượng là chuỗi “3 hộp”, trường ngày giao là “thứ bảy tuần sau”, hoặc trường số điện thoại bị mô hình tự điền một dãy số bịa khi tin nhắn không có. Những lỗi này đi qua trình phân tích êm ru và chỉ lộ ra ở bước sau, khi đơn hàng giao sai hay báo cáo cộng sai.

Vì vậy cần nghĩ về đầu ra JSON như dữ liệu từ một nguồn bên ngoài không đáng tin, giống dữ liệu người dùng gửi qua biểu mẫu. Mô hình là một nguồn rất giỏi nhưng không có cam kết. Mã của bạn phải là bên quyết định cuối cùng điều gì được chấp nhận.

Ba mức kiểm soát định dạng đầu ra

Các nhà cung cấp lớn hiện có những cơ chế khác nhau để ép định dạng, và chúng thay đổi theo phiên bản. Bảng dưới mô tả theo loại cơ chế; tên tham số cụ thể bạn tra trong tài liệu chính thức của hãng mình dùng.

MứcCách làmĐảm bảo được gìVẫn phải lo
1. Dặn trong câu lệnhMô tả cấu trúc và đưa ví dụ JSON trong câu lệnh, yêu cầu chỉ trả JSONĐúng phần lớn thời gian với mô hình tốtLời dẫn thừa, khối bọc ba dấu huyền, thiếu trường, sai kiểu
2. Chế độ JSONBật tuỳ chọn yêu cầu đầu ra là JSON hợp lệ, nếu hãng cóCú pháp JSON hợp lệThiếu trường, thừa trường, sai kiểu, sai giá trị
3. Lược đồ bắt buộcGửi kèm lược đồ JSON và bật chế độ tuân thủ lược đồ, nếu hãng có; hoặc dùng cơ chế gọi công cụ với tham số theo lược đồĐúng tên trường, đúng kiểu cơ bảnGiá trị sai về nghĩa, giá trị bịa khi dữ liệu không có

Mức càng cao thì việc kiểm ở máy chủ càng nhẹ, nhưng không bao giờ bằng không. Kể cả ở mức ba, mô hình vẫn có thể điền một địa chỉ đúng kiểu chuỗi nhưng sai hoàn toàn. Ngoài ra, cơ chế lược đồ của mỗi hãng thường chỉ hỗ trợ một phần đặc tả JSON Schema, nên lược đồ phức tạp có thể bị từ chối; đọc phần giới hạn trong tài liệu trước khi thiết kế.

Thiết kế lược đồ sao cho mô hình dễ điền đúng

Tên trường nói lên nghĩa. Trường tên so_luong rõ hơn sl, dia_chi_giao rõ hơn addr2. Mô hình đọc tên trường như đọc chỉ dẫn, nên tên tốt giảm hẳn lỗi điền nhầm. Thêm mô tả ngắn cho từng trường nếu lược đồ cho phép.

Giới hạn giá trị bằng danh sách liệt kê. Trường trạng thái chỉ nhận ba giá trị moi, can_hoi_lai, huy thì khai báo enum đúng ba giá trị đó. Để chuỗi tự do là sẽ nhận về cả “mới”, “Mới tạo”, “new”.

Cho phép rỗng một cách tường minh. Đây là chỗ quan trọng nhất để chống bịa. Nếu trường số điện thoại bắt buộc phải có chuỗi, mô hình sẽ cố điền một thứ gì đó. Cho phép null và dặn rõ: không thấy trong tin nhắn thì để null.

Dùng kiểu số cho số. Số lượng là integer, đơn giá là number không có dấu phân cách nghìn. Dặn rõ đơn vị, ví dụ đơn giá tính bằng đồng, không ghi chữ “k” hay “nghìn”.

Tránh lồng quá sâu. Ba bốn tầng lồng nhau làm tăng lỗi. Nếu có danh sách mặt hàng, một mảng các đối tượng phẳng là đủ: ten_hang, so_luong, ghi_chu.

Thêm trường để mô hình tự báo không chắc. Một trường can_xac_nhan kiểu boolean, kèm trường ly_do ngắn, giúp bạn đẩy những đơn mập mờ sang người duyệt thay vì tin mù quáng.

Kiểm hợp lệ ở máy chủ: đoạn mã mẫu bằng Python

Với Python, thư viện pydantic phiên bản 2 là cách gọn để vừa khai báo cấu trúc vừa kiểm. Bạn khai báo lớp mặt hàng: class MatHang(BaseModel): với các trường ten_hang: str, so_luong: int = Field(ge=1, le=500). Lớp đơn hàng chứa mat_hang: list[MatHang], dia_chi_giao: str | None = None, can_xac_nhan: bool. Cú pháp str | None cần Python 3.10 trở lên; bản cũ hơn dùng Optional[str] từ typing.

Khi nhận chuỗi từ mô hình, bạn gọi don = DonHang.model_validate_json(chuoi_tra_ve) trong một khối try, bắt ValidationError. Hàm này vừa phân tích JSON vừa kiểm kiểu, kiểm khoảng giá trị. Lỗi trả về liệt kê đúng trường nào sai và vì sao, đủ chi tiết để đưa lại cho mô hình khi thử lại. Lớp DonHang cũng xuất được lược đồ JSON bằng DonHang.model_json_schema(), nên bạn có một nguồn sự thật duy nhất cho cả lược đồ gửi đi lẫn bước kiểm.

Với JavaScript hay TypeScript, thư viện zod làm vai trò tương tự; với PHP, bạn có thể dùng json_decode với cờ JSON_THROW_ON_ERROR rồi kiểm từng trường bằng tay hoặc dùng một thư viện kiểm JSON Schema. Dù ngôn ngữ nào, sau bước kiểm kiểu còn một bước kiểm nghiệp vụ: tên hàng có trong danh mục của cửa hàng không, số lượng có vượt tồn kho không. Bước này mô hình không làm thay được.

Thử lại khi hỏng, nhưng có giới hạn

Khi kiểm hợp lệ thất bại, phản xạ tự nhiên là gọi lại. Làm đúng cách thì một lần thử lại sửa được phần lớn lỗi định dạng; làm sai cách thì bạn đốt tiền vào vòng lặp vô ích.

  1. Đặt số lần thử tối đa nhỏ, thường một hoặc hai lần. Vượt quá thì dừng và xử lý như lỗi.
  2. Khi thử lại, gửi kèm câu trả lời hỏng và thông báo lỗi kiểm hợp lệ, yêu cầu mô hình sửa đúng trường đó. Gọi lại y nguyên câu lệnh cũ thì dễ nhận lại lỗi cũ.
  3. Ghi nhật ký mọi lần hỏng: câu trả lời gốc, lỗi, đã thử lại mấy lần. Đây là nguồn để sửa câu lệnh và lược đồ về sau.
  4. Hết số lần thử thì không đoán: đánh dấu bản ghi là cần người xem, hoặc báo người dùng nhập tay. Đừng tự điền giá trị mặc định cho trường quan trọng.
  5. Theo dõi tỉ lệ hỏng theo ngày. Tỉ lệ tăng đột ngột thường báo hiệu nhà cung cấp vừa đổi mô hình hoặc dữ liệu đầu vào vừa đổi dạng.

Với tính năng xử lý theo lô, ví dụ trích thông tin từ một nghìn tin nhắn cũ, hãy chạy thử trên năm mươi tin trước và đọc tay kết quả, rồi mới chạy cả lô. Nhớ che số điện thoại, số tài khoản và thông tin cá nhân không cần cho việc trích xuất trước khi gửi tin nhắn của khách đi.

Những lỗi định dạng hay gặp và cách xử lý

Dù đã dùng lược đồ, các lỗi dưới đây vẫn xuất hiện, nhất là khi bạn đổi mô hình hay dùng mô hình nhỏ để tiết kiệm.

  • JSON bọc trong khối ba dấu huyền kèm chữ json ở đầu: nếu không dùng được chế độ JSON, bóc phần nằm giữa dấu ngoặc nhọn đầu và cuối trước khi phân tích, nhưng vẫn ghi nhật ký để biết tần suất.
  • Số viết theo kiểu Việt, như 120.000 hay 1,5: dặn rõ trong mô tả trường, và ở bước kiểm từ chối chuỗi có dấu chấm phân cách nghìn thay vì tự đoán.
  • Ngày tháng tương đối như “mai”, “cuối tuần”: mô hình không biết hôm nay là ngày nào trừ khi bạn ghi ngày hiện tại vào câu lệnh. Tốt hơn là yêu cầu trả nguyên văn cụm từ chỉ thời gian và để mã của bạn quy đổi.
  • Giá trị bịa khi dữ liệu thiếu: cho phép null, dặn rõ, và trong bộ kiểm thêm những tin nhắn cố tình thiếu thông tin để xem mô hình có giữ đúng null không.
  • Câu trả lời bị cắt giữa chừng vì chạm giới hạn độ dài đầu ra: kiểm lý do dừng trong phản hồi; nếu là do hết độ dài thì tăng giới hạn hoặc chia nhỏ đầu vào, đừng cố phân tích phần dở.
  • Trường thừa mô hình tự thêm vào: cấu hình bộ kiểm để bỏ qua hoặc từ chối trường lạ, tuỳ mức chặt bạn cần, nhưng chọn một cách và giữ nhất quán.

Phần lớn các lỗi này lặp lại theo mẫu. Sau một tuần chạy thật, đọc nhật ký lỗi sẽ cho bạn thấy hai ba nguyên nhân chiếm gần hết, và sửa đúng hai ba chỗ đó trong lược đồ hoặc câu lệnh là đủ.

Ví dụ giả định từ đầu tới cuối: tách đơn từ tin nhắn khách

Cửa hàng bán đồ khô ở Huế nhận tin nhắn kiểu: “Cho chị 2 hũ ruốc với 1 túi mè xửng, giao về nhà chị ở phường Thuận Hoá, chiều mai nha”. Máy chủ trước hết thay số điện thoại và tên người trong tin bằng ký hiệu, rồi gửi cho mô hình câu lệnh gồm: vai trò trích xuất đơn hàng, danh sách tên hàng cửa hàng đang bán, ngày hiện tại, và lược đồ DonHang với các trường đã nêu.

Kết quả mong đợi là mảng hai mặt hàng với số lượng 2 và 1, địa chỉ giao là chuỗi phường đã nêu, trường thời gian giữ nguyên văn “chiều mai” để mã quy đổi, và can_xac_nhan bằng true vì địa chỉ chưa có số nhà. Bước kiểm nghiệp vụ đối chiếu tên hàng với danh mục: “mè xửng” khớp, “ruốc” khớp với “ruốc tôm” sau khi so gần đúng, và vì phải so gần đúng nên đơn được đẩy vào hàng chờ cho nhân viên bấm xác nhận.

Nhân viên thấy một thẻ đơn đã điền sẵn, chỉ cần sửa số nhà và bấm lưu. Việc mất ba mươi giây thay vì hai phút gõ tay, mà không có đơn nào tự đi khi còn mập mờ. Đó là hình dạng hợp lý cho phần lớn tính năng trích xuất ở bản đầu: AI làm phần đọc, người làm phần quyết.

Câu hỏi thường gặp

Có nên yêu cầu mô hình giải thích trước rồi mới đưa JSON không?

Với việc cần suy luận, cho mô hình một trường lý do hoặc một bước suy nghĩ trước có thể cải thiện kết quả. Nhưng nếu đầu ra phải là JSON thuần, hãy đặt phần giải thích thành một trường trong chính JSON, thay vì để văn bản tự do đứng trước làm hỏng bước phân tích.

Mô hình nhỏ có trả JSON ổn định không?

Mô hình nhỏ thường làm tốt với lược đồ đơn giản và đầu vào rõ ràng, kém hơn với lược đồ nhiều tầng hay đầu vào lộn xộn. Hãy chạy cùng bộ kiểm trên mô hình nhỏ và lớn, so tỉ lệ đạt, rồi quyết định theo số liệu thay vì mặc định chọn mô hình lớn.

Lược đồ nên đặt trong câu lệnh hay trong tham số riêng?

Nếu hãng có tham số riêng cho lược đồ, dùng tham số đó vì nó thường được ép chặt hơn. Vẫn nên giữ một câu mô tả ngắn trong câu lệnh về ý nghĩa của từng trường quan trọng, vì lược đồ chỉ nói kiểu chứ không nói nghĩa.

Có thể tin JSON mô hình trả về để ghi thẳng vào cơ sở dữ liệu không?

Không nên ghi thẳng. Luôn qua bước kiểm kiểu và kiểm nghiệp vụ, dùng câu truy vấn có tham số khi ghi. Với dữ liệu quan trọng như đơn hàng hay hồ sơ khách, bản đầu nên để người duyệt trước khi lưu chính thức.

Làm sao đo được chất lượng trích xuất?

Lấy một mẫu đầu vào thật, che thông tin cá nhân, nhờ người trong nghề điền đáp án đúng bằng tay. Chạy mô hình trên mẫu đó và so từng trường, đếm tỉ lệ đúng theo trường. Trường nào thấp nhất là chỗ cần sửa lược đồ hay câu lệnh trước.

Đầu ra có cấu trúc có chậm hơn không?

Tuỳ hãng và cơ chế. Có hệ thống cần xử lý lược đồ ở lần gọi đầu nên lần đầu chậm hơn một chút, các lần sau bình thường. Độ dài JSON đầu ra cũng ảnh hưởng thời gian, nên chỉ yêu cầu những trường thật sự cần.

Cần tư vấn cụ thể cho trường hợp của bạn?

Chúng tôi sẽ liên hệ trong vòng 24 giờ.

Đăng ký tư vấn ngay

Bài viết liên quan

Bạn cần hỗ trợ thêm?

Để lại thông tin, chúng tôi sẽ liên hệ trong 24 giờ.

hoặc
Gọi ngay 0926 138 138