
Ép AI trả JSON đúng schema: JSON mode vẫn có thể sai cấu trúc

Để AI trả JSON đúng schema, hãy khai báo schema bằng tính năng đầu ra có cấu trúc của API. Hướng dẫn Structured Outputs của OpenAI phân biệt rõ hai mức: JSON mode tạo JSON hợp lệ, còn Structured Outputs ràng buộc kết quả theo schema được khai báo. Một đối tượng phân tích cú pháp được vẫn có thể thiếu trường, sai kiểu hoặc chứa giá trị ngoài enum mà ứng dụng chấp nhận.
Khi dùng Gemini, hãy đưa schema vào cấu hình đầu ra JSON và đối chiếu những từ khóa được hỗ trợ trước khi chuyển cấu hình từ OpenAI. Hướng dẫn đầu ra có cấu trúc của Gemini liệt kê một tập con của JSON Schema, thay vì toàn bộ đặc tả. Vì thế, cùng một hợp đồng dữ liệu có thể dùng làm điểm xuất phát cho hai API, nhưng từng ràng buộc cần được kiểm tra theo endpoint.
JSON hợp lệ khác gì dữ liệu đúng schema?
Chuỗi {"status":"done"} là JSON hợp lệ: trình phân tích cú pháp có thể đọc nó. Nhưng nếu ứng dụng yêu cầu thêm title và chỉ nhận trạng thái new hoặc approved, chuỗi đó không đạt hợp đồng dữ liệu. Việc ghi “trả đúng mẫu” trong câu nhắc không tạo ra ràng buộc schema tại API.
Chọn đầu ra có cấu trúc khi kết quả sẽ đi vào biểu mẫu, cơ sở dữ liệu hoặc một bước tự động hóa phụ thuộc vào tên trường và kiểu dữ liệu cố định. Nếu chỉ dùng JSON mode, ứng dụng phải tự xác thực cấu trúc và xử lý phản hồi sai. Cũng cần phân biệt schema cho câu trả lời cuối cùng với schema tham số của lệnh gọi công cụ: một bên định dạng dữ liệu trả về, bên kia định dạng yêu cầu mô hình gửi tới công cụ.
Một schema để đối chiếu giữa hai API
Ví dụ giả định: ứng dụng trích xuất yêu cầu công việc với tiêu đề, trạng thái và hạn chót. Trạng thái chỉ nhận new hoặc approved; nếu chưa có hạn chót, trường đó nhận null. Hợp đồng dữ liệu tối giản là:
{"type":"object","properties":{"title":{"type":"string"},"status":{"type":"string","enum":["new","approved"]},"deadline":{"type":["string","null"]}},"required":["title","status","deadline"],"additionalProperties":false}
required buộc cả ba khóa xuất hiện, kể cả khi deadline bằng null. Khóa bị thiếu và khóa có giá trị null là hai trạng thái khác nhau: trường hợp thứ nhất sai schema mẫu, trường hợp thứ hai đúng về cấu trúc. additionalProperties:false loại khóa phát sinh; enum giới hạn chính xác hai giá trị trạng thái.
Một bản ghi phù hợp về cấu trúc là {"title":"Duyệt bản thảo","status":"new","deadline":null}. Đây là dữ liệu minh họa, không phải kết quả thử API. Schema cố ý chỉ khai báo deadline là chuỗi hoặc null: nó chưa quy định định dạng ngày, nên một chuỗi bất kỳ vẫn có thể vượt qua bước kiểm tra cấu trúc này.
Đặt schema vào OpenAI Responses API
Trong Responses API, đặt đối tượng mẫu vào text.format.schema; cùng cấp với schema là type:"json_schema", một name và strict:true. Phần cấu hình rút gọn có dạng {"text":{"format":{"type":"json_schema","name":"work_request","strict":true,"schema":SCHEMA}}}, trong đó SCHEMA là ký hiệu thay cho toàn bộ đối tượng schema ở trên, không phải chuỗi gửi nguyên vào API. Với Chat Completions, cấu hình tương ứng nằm trong response_format.json_schema.
Ở chế độ strict, mọi khóa trong properties phải có mặt trong required, và mỗi object phải đặt additionalProperties:false. Nếu một giá trị có thể chưa xác định về mặt nghiệp vụ, cách biểu diễn trong ví dụ là giữ khóa bắt buộc nhưng cho phép null. Một schema dùng từ khóa ngoài phạm vi hỗ trợ có thể khiến lệnh gọi bị lỗi trước khi có phản hồi, nên cần kiểm tra cấu hình khi thêm ràng buộc mới.
Chuyển cấu hình sang Gemini
Với Gemini Interactions API, đặt schema trong response_format.schema, cùng với type:"text" và mime_type:"application/json". Dạng rút gọn là {"response_format":{"type":"text","mime_type":"application/json","schema":SCHEMA}}. Đường dẫn tham số khác OpenAI; phần SCHEMA vẫn đại diện cho đối tượng dữ liệu mẫu, không phải toàn bộ cấu hình của nhà cung cấp kia.
Tập con schema được Gemini liệt kê có properties, required và additionalProperties cho object; enum cho chuỗi; và kiểu null trong mảng type. Đó là những thành phần mà ví dụ sử dụng. Khi mở rộng schema, đừng mặc định các từ khóa như điều kiện, tham chiếu hay ràng buộc chuỗi hoạt động giống nhau ở hai API. Hãy đối chiếu từ khóa với tài liệu của đúng endpoint và xử lý lỗi cấu hình trước khi đưa dữ liệu vào quy trình chính.
Kiểm tra gì trước khi ghi dữ liệu?
- Enum: Giữ nguyên từng giá trị và cách viết hoa, viết thường. "done" là chuỗi JSON hợp lệ nhưng nằm ngoài danh sách trạng thái của ví dụ.
- Trường bắt buộc: So required với properties ở từng object, kể cả object lồng nhau. Thiếu tên trường trong danh sách có thể làm thay đổi hợp đồng dữ liệu.
- Null: Quyết định rõ lúc nào giá trị chưa có được ghi bằng null. Đừng để mã ứng dụng đồng nhất null với khóa bị thiếu.
- Khóa ngoài schema: Giữ additionalProperties:false khi ứng dụng chỉ tiếp nhận các khóa đã định, thay vì chỉ sao chép danh sách trường.
- Trạng thái phản hồi: Kiểm tra phản hồi đã hoàn tất và có nội dung JSON trước khi phân tích. Lời từ chối vì an toàn có thể nằm ngoài schema; đầu ra bị ngắt cũng có thể chưa tạo thành bản ghi hoàn chỉnh.
Sau bước kiểm tra trạng thái, hãy phân tích JSON và xác thực đối tượng bằng hợp đồng dữ liệu của ứng dụng trước khi ghi cơ sở dữ liệu hoặc kích hoạt tác vụ tiếp theo. Bước này còn xử lý các quy tắc nghiệp vụ mà schema mẫu chưa diễn đạt, chẳng hạn tiêu đề rỗng hoặc chuỗi hạn chót không phải ngày hợp lệ. Nếu xác thực thất bại, trả lỗi có kiểm soát hoặc tạo lại kết quả theo quy trình của ứng dụng; việc tự sửa thầm một giá trị sẽ làm mất dấu dữ liệu mà mô hình thực sự đã trả về.
Đọc thêm:
Bài viết liên quan


IonQ chi tới 1,3 tỷ USD cho Elisity: thương vụ vẫn chưa hoàn tất

Claude Fable 5.1 giảm 75% giá đọc cache, nhưng có ba thay đổi phá vỡ

Nhãn Verified trên GitHub vẫn còn sau khi khóa ký bị thu hồi

Gọi GPT-6 Astra qua Bedrock: chọn sai endpoint có thể phá yêu cầu vùng

Gemini 3.8 Flash giữ giá cũ, nhưng an toàn đa ngôn ngữ lại giảm
Đăng ký bản tin
Nhận tin Web3, AI và tiền mã hóa mới nhất ngay trong hộp thư.