
LLM STRUCTED OUTPUT: Đảm bảo JSON trả về luôn đúng schema
Structured Outputs (còn gọi là JSON mode) là tính năng của các mô hình ngôn ngữ lớn (LLM) đảm bảo kết quả trả về luôn tuân thủ một JSON Schema được cung cấp. Không cò� phải lo lắng rằng mô hình thiếu key bắt buộc hoặc trả về giá trị enum không hợp lệ nữa. Tính năng này còn phát hiện refusals dựa trên an toàn một cách programmatically, giúp bạn không phải dùng regex để parse hay retry.
Bài viết tham khảo từ OpenAI Structured Outputs guide và Anthropic documentation.
Structured Outputs vs JSON mode truyền thống
Hai tính năng này đều đảm bảo trả về JSON hợp lệ, nhưng chỉ có Structured Outputs mới đảm bảo tuân thủ schema. OpenAI khuyến nghị luôn dùng Structured Outputs thay vì JSON mode truyền thống khi có thể.
| Tính năng | Structured Outputs | JSON mode |
|---|---|---|
| JSON hợp lệ | ✓ | ✓ |
| Tuân thủ schema | ✓ | ✗ |
| Mô hình tương thích | gpt-4o-mini trở lên, gpt-5.6 | gpt-3.5-turbo, gpt-4-* |
| Cách bật | json_schema, strict: true |
json_object |
| Giới hạn schema | Một số constraints không hỗ trợ | Không giới hạn |
Hai cách sử dụng Structured Outputs
- Function calling — dùng khi kết nối mô hình tới các tool, hàm, dữ liệu. Ví dụ: truy vấn database, tương tác UI, chạy code interpreter.
- response_format json_schema — dùng khi muốn cấu trúc output trả về cho người dùng. Ví dụ: tạo giao diện UI từ JSON, sinh kế hoạch học tập có cấu trúc.
Khi kết nối mô hình tới tools, functions, data — dùng function calling. Khi muốn cấu trúc output trả về cho người dùng — dùng response_format json_schema. Đây là nguyên tắc phân biệt quan trọng giúp bạn chọn đúng API cho đúng use case.

Ví dụ Python: trích xuất dữ liệu có cấu trúc
Dùng Pydantic để định nghĩa schema, sau đó sử dụng response_format để ép buộc mô hình tuân thủ. SDK Python của OpenAI cung cấp method parse() tự động parse JSON response thành object:
from pydantic import BaseModel
from openai import OpenAI
client = OpenAI()
class ResearchPaperExtraction(BaseModel):
title: str
authors: list[str]
abstract: str
keywords: list[str]
completion = client.chat.completions.parse(
model="gpt-5.6",
messages=[
{"role": "system",
"content": "You are an expert at structured data extraction."},
{"role": "user",
"content": "Attention Is All You Need by Ashish Vaswani..."}
],
response_format=ResearchPaperExtraction,
)
paper = completion.choices[0].message.parsed
print(paper.title)
Với JavaScript, dùng zodResponseFormat từ openai/helpers/zod. SDK tự động chuyển Pydantic hay Zod schema thành JSON Schema, rồi parse response.
Ví dụ JSON Schema thủ công
Khi không dùng SDK, bạn có thể truyền JSON Schema trực tiếp qua REST API:
curl https://api.openai.com/v1/chat/completions
-H "Authorization: Bearer ***"
-H "Content-Type: application/json"
-d '{
"model": "gpt-5.6",
"messages": [
{"role": "system", "content": "You are a helpful math tutor."},
{"role": "user", "content": "how can I solve 8x + 7 = -23"}
],
"response_format": {
"type": "json_schema",
"json_schema": {
"name": "math_response",
"schema": {
"type": "object",
"properties": {
"steps": {"type": "array", "items": {"type": "object",
"properties": {
"explanation": {"type": "string"},
"output": {"type": "string"}
}, "required": ["explanation", "output"]}},
"final_answer": {"type": "string"}
},
"required": ["steps", "final_answer"],
"additionalProperties": false
},
"strict": true
}
}
}'
Chain-of-thought với Structured Outputs
Structured Outputs không chỉ cho extraction — bạn cũng có thể dùng nó để tạo step-by-step reasoning:
class Step(BaseModel):
explanation: str
output: str
class MathReasoning(BaseModel):
steps: list[Step]
final_answer: str
completion = client.chat.completions.parse(
model="gpt-5.6",
messages=[
{"role": "system",
"content": "You are a helpful math tutor. Guide step by step."},
{"role": "user", "content": "how can I solve 8x + 7 = -23"}
],
response_format=MathReasoning,
)
reasoning = completion.choices[0].message.parsed
Xử lý lỗi và edge cases
Structured Outputs hỗ trợ schema rất rộng nhưng một số tính năng không khả dụng. Luôn xử lý các trường hợp sau:
- Refusal — mô hình từ chối trả lời vì lý do an toàn. Phải kiểm tra
refusaltrường. - Max tokens — kết quả bị cắt do vượt giới hạn token. Kiểm tra
finish_reason. - Content filter — nội dung bị lọc trước khi trả về.
- Schema constraints — một số JSON Schema features không được hỗ trợ bởi Structured Outputs vì lý do performance.
try:
response = client.chat.completions.create(
model="gpt-5.6",
messages=messages,
response_format=response_format,
max_completion_tokens=50,
)
if response.choices[0].finish_reason == "length":
raise Exception("Incomplete response")
math_response = response.choices[0].message
if math_response.refusal:
print(math_response.refusal)
else:
print(math_response.content)
except Exception as e:
print(e)

Best practices thiết lập schema
Theo tài liệu OpenAI, chúng ta nên tuân thủ một số quy tắc để tối ưu chất lượng:
- Đặt tên key rõ ràng, trực quan — tránh tên viết tắt gây hiểu lầm.
- Thêm mô tả chi tiết cho các key quan trọng để hướng dẫn mô hình hoạt động đúng.
- Dùng
additionalProperties: falseđể ngăn thừa properties không mong muốn. - Liệt kê đầy đủ
requiredcho các trường bắt buộc. - Tạo evals để kiểm tra schema hoạt động tốt nhất cho use case của bạn.
- Tránh các schema phức tạp không cần thiết — độ chính xác giảm khi schema quá phức tạp.
Những lĩnh vực ứng dụng
Structured Outputs được dùng rộng rãi trong nhiều lĩnh vực:
- Data extraction — trích xuất thông tin từ văn bản không cấu trúc như research papers, emails, báo cáo.
- Chain of thought — yêu cầu mô hình trả về từng bước lý luận trước khi đưa ra câu trả lời cuối cùng.
- UI generation — sinh cấu trúc UI từ mô tả bằng ngôn ngữ tự nhiên.
- Moderation — phân loại nội dung theo các category được định nghĩa.
Những tips này giúp bạn tối ưu chất lượng output, giảm lỗi parse, và xây dựng pipeline AI đáng tin cậy cho bất kỳ use case nào từ trích xuất dữ liệu đến sinh giao diện UI.
