Structured Outputs
Structured outputs chuyển đổi phản hồi của mô hình từ văn bản tự do thành JSON có định dạng nghiêm ngặt. RouteAPI hỗ trợ hai chế độ structured output: JSON mode (yêu cầu JSON hợp lệ) và JSON Schema (đảm bảo tuân thủ schema cụ thể).
1. Tổng Quan Về Structured Outputs
Phần tiêu đề “1. Tổng Quan Về Structured Outputs”Structured Outputs Là Gì
Phần tiêu đề “Structured Outputs Là Gì”Structured outputs là cơ chế kiểm soát định dạng phản hồi của mô hình. Không giống các cuộc trò chuyện thông thường nơi mô hình tự do tạo văn bản, structured outputs buộc mô hình phải tạo dữ liệu JSON theo định dạng bạn đã xác định. Điều này rất quan trọng cho các tình huống yêu cầu xử lý lập trình đầu ra của mô hình (trích xuất dữ liệu, tạo biểu mẫu, phân tích phản hồi API).
JSON mode so với JSON Schema
Phần tiêu đề “JSON mode so với JSON Schema”RouteAPI cung cấp hai chế độ structured output:
| So sánh | JSON mode | JSON Schema |
|---|---|---|
| Đảm bảo | Đầu ra là JSON hợp lệ | Đầu ra tuân thủ schema đã chỉ định |
| Tham số | response_format: { type: "json_object" } | response_format: { type: "json_schema", json_schema: {...} } |
| Định nghĩa schema | Không bắt buộc, nhưng phải mô tả định dạng trong prompt | Yêu cầu JSON Schema đầy đủ |
| Độ nghiêm ngặt | Chỉ đảm bảo có thể parse, không đảm bảo cấu trúc | Đảm bảo các trường, kiểu dữ liệu và mục bắt buộc khớp chính xác |
| Trường hợp sử dụng | Định dạng đơn giản, mô hình có thể hiểu cấu trúc từ prompt | Cấu trúc lồng ghép phức tạp, cần xác thực kiểu nghiêm ngặt |
Giải thích đơn giản: JSON mode chỉ đảm bảo “có thể được parse thành công bởi JSON.parse” nhưng không quan tâm đến các trường; JSON Schema đảm bảo không chỉ tính hợp lệ mà còn cả cấu trúc, tên trường, kiểu dữ liệu và các mục bắt buộc đều tuân theo định nghĩa của bạn.
Các Trường Hợp Sử Dụng
Phần tiêu đề “Các Trường Hợp Sử Dụng”| Tình huống | Mô tả | Chế độ đề xuất |
|---|---|---|
| Trích xuất dữ liệu | Trích xuất thông tin có cấu trúc từ văn bản không có cấu trúc (tên, địa chỉ, ngày tháng) | JSON Schema |
| Tạo biểu mẫu | Cho mô hình tạo giá trị khởi tạo biểu mẫu hoặc đối tượng cấu hình | JSON Schema |
| Phân tích phản hồi API | Đầu ra mô hình cần giao tiếp với API hệ thống phía sau | JSON Schema |
| Cặp key-value đơn giản | Chỉ cần vài trường, cấu trúc đơn giản và rõ ràng | JSON mode |
| Nhiệm vụ phân loại | Xuất giá trị enum cố định (ví dụ: cảm xúc: tích cực/tiêu cực/trung lập) | JSON Schema + enum |
2. JSON Mode
Phần tiêu đề “2. JSON Mode”JSON mode là phương pháp structured output đơn giản nhất: bạn đặt response_format.type thành "json_object" trong yêu cầu, và mô hình sẽ xuất JSON hợp lệ thay vì văn bản thuần túy.
Định Dạng Yêu Cầu
Phần tiêu đề “Định Dạng Yêu Cầu”{ "model": "gpt-5.5", "messages": [ { "role": "system", "content": "You are a data extraction assistant. Extract name, age, and city fields from user input and return in JSON format." }, { "role": "user", "content": "My name is Li Ming, I'm 28 years old, and I live in Shanghai." } ], "response_format": { "type": "json_object" }}Điểm Chính
Phần tiêu đề “Điểm Chính”-
Phải mô tả định dạng JSON trong prompt: Mô hình không biết bạn muốn trường nào; bạn phải nói rõ qua system message hoặc user message cần xuất trường gì và kiểu của chúng. Trong ví dụ trên,
"Extract name, age, and city fields from user input and return in JSON format"là mô tả định dạng. -
Không đảm bảo tuân thủ schema: Mô hình có thể xuất
{"name": "Li Ming", "age": 28, "city": "Shanghai"}, hoặc{"姓名": "Li Ming", "年龄": 28}, hoặc thậm chí{"person": {"name": "Li Ming"}}. Miễn là JSON hợp lệ thì được chấp nhận. -
Cách sử dụng: Phù hợp cho tình huống có định dạng đơn giản, ít trường, và mô hình có thể hiểu cấu trúc từ ngôn ngữ tự nhiên. Nếu cần xác thực nghiêm ngặt tên trường hoặc kiểu dữ liệu, hãy dùng JSON Schema.
Ví Dụ Đầy Đủ
Phần tiêu đề “Ví Dụ Đầy Đủ”Yêu cầu (curl):
curl https://api.routeapi.ai/v1/chat/completions \ -H "Authorization: Bearer $ROUTEAPI_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "gpt-5.5", "messages": [ { "role": "system", "content": "You are a data extraction assistant. Extract name, age, and city fields from user input and return in JSON format." }, { "role": "user", "content": "My name is Li Ming, I am 28 years old, and I live in Shanghai." } ], "response_format": { "type": "json_object" } }'Phản hồi:
{ "id": "chatcmpl_xxx", "object": "chat.completion", "created": 1730000000, "model": "gpt-5.5", "choices": [ { "index": 0, "message": { "role": "assistant", "content": "{\"name\": \"Li Ming\", \"age\": 28, \"city\": \"Shanghai\"}" }, "finish_reason": "stop" } ], "usage": { "prompt_tokens": 58, "completion_tokens": 18, "total_tokens": 76 }}Lưu ý rằng message.content là một chuỗi JSON, bạn cần tự JSON.parse / json.loads.
3. JSON Schema (Structured Outputs)
Phần tiêu đề “3. JSON Schema (Structured Outputs)”Chế độ JSON Schema cho phép bạn xác định chính xác cấu trúc đầu ra, và mô hình đảm bảo JSON được tạo tuân thủ hoàn toàn định nghĩa schema của bạn.
Định Dạng Yêu Cầu
Phần tiêu đề “Định Dạng Yêu Cầu”{ "model": "gpt-5.5", "messages": [ { "role": "user", "content": "My name is Li Ming, I'm 28 years old, and I live in Shanghai." } ], "response_format": { "type": "json_schema", "json_schema": { "name": "person_extraction", "strict": true, "schema": { "type": "object", "properties": { "name": { "type": "string", "description": "Name" }, "age": { "type": "integer", "description": "Age" }, "city": { "type": "string", "description": "City" } }, "required": ["name", "age", "city"], "additionalProperties": false } } }}Cấu Trúc response_format
Phần tiêu đề “Cấu Trúc response_format”| Trường | Kiểu | Bắt buộc | Mô tả |
|---|---|---|---|
type | string | Có | Cố định là "json_schema" |
json_schema.name | string | Có | Tên schema để nhận dạng, chữ cái, số, gạch dưới, gạch ngang |
json_schema.strict | boolean | Không | Có bật chế độ strict không, mặc định false |
json_schema.schema | object | Có | Định nghĩa JSON Schema chuẩn |
Chế Độ Strict so với Non-strict
Phần tiêu đề “Chế Độ Strict so với Non-strict”| Chế độ | strict | Hành vi |
|---|---|---|
| Chế độ strict | true | Mô hình phải tạo chính xác theo schema, tên trường, kiểu dữ liệu, mục bắt buộc, additionalProperties đều được tuân thủ nghiêm ngặt |
| Chế độ non-strict | false | Mô hình cố gắng tuân thủ schema, nhưng không đảm bảo hoàn toàn nhất quán, có thể thiếu trường hoặc thêm trường |
Đề xuất: Sử dụng strict: true trong production; đây là giá trị cốt lõi của chế độ JSON Schema. Hành vi chế độ non-strict tương tự JSON mode + mô tả prompt, ý nghĩa hạn chế.
Đặc Tả Định Nghĩa Schema
Phần tiêu đề “Đặc Tả Định Nghĩa Schema”Trường schema tuân theo đặc tả JSON Schema chuẩn (Draft 2020-12), các trường phổ biến:
| Trường | Mô tả |
|---|---|
type | Kiểu dữ liệu: "object", "array", "string", "number", "integer", "boolean", "null" |
properties | Định nghĩa trường cho object (dùng khi type là "object") |
required | Mảng tên trường bắt buộc |
additionalProperties | Có cho phép thêm trường không xác định không (đề xuất false ở chế độ strict) |
items | Schema cho phần tử mảng (dùng khi type là "array") |
enum | Danh sách giá trị enum, giới hạn phạm vi giá trị |
description | Mô tả trường, giúp mô hình hiểu ngữ nghĩa |
4. Hướng Dẫn Định Nghĩa Schema
Phần tiêu đề “4. Hướng Dẫn Định Nghĩa Schema”Các Kiểu Cơ Bản
Phần tiêu đề “Các Kiểu Cơ Bản”{ "type": "object", "properties": { "name": { "type": "string" }, "age": { "type": "integer" }, "score": { "type": "number" }, "is_active": { "type": "boolean" }, "notes": { "type": ["string", "null"] } }}Mô tả kiểu:
"string": Chuỗi"integer": Số nguyên"number": Số (bao gồm số nguyên và số thập phân)"boolean": Boolean"null": Giá trị null["string", "null"]: Cho phép chuỗi hoặc null (trường tùy chọn)
Object và Array
Phần tiêu đề “Object và Array”{ "type": "object", "properties": { "user": { "type": "object", "properties": { "name": { "type": "string" }, "email": { "type": "string" } }, "required": ["name"] }, "tags": { "type": "array", "items": { "type": "string" } }, "scores": { "type": "array", "items": { "type": "number" } } }}Các Trường Bắt Buộc
Phần tiêu đề “Các Trường Bắt Buộc”{ "type": "object", "properties": { "name": { "type": "string" }, "age": { "type": "integer" }, "city": { "type": "string" } }, "required": ["name", "age"]}Mảng required liệt kê các trường phải tồn tại. Trong ví dụ trên, name và age là bắt buộc, city là tùy chọn.
Giá Trị Enum
Phần tiêu đề “Giá Trị Enum”{ "type": "object", "properties": { "sentiment": { "type": "string", "enum": ["positive", "negative", "neutral"], "description": "Sentiment classification result" }, "priority": { "type": "integer", "enum": [1, 2, 3], "description": "Priority: 1-low, 2-medium, 3-high" } }, "required": ["sentiment"]}enum giới hạn trường chỉ nhận giá trị trong danh sách; mô hình sẽ không tạo giá trị khác.
Cấu Trúc Lồng Ghép
Phần tiêu đề “Cấu Trúc Lồng Ghép”{ "type": "object", "properties": { "user": { "type": "object", "properties": { "name": { "type": "string" }, "address": { "type": "object", "properties": { "city": { "type": "string" }, "street": { "type": "string" } }, "required": ["city"] } }, "required": ["name", "address"] } }, "required": ["user"]}Object có thể lồng vô hạn, nhưng lồng quá sâu có thể ảnh hưởng chất lượng và hiệu suất tạo của mô hình.
Trường Description
Phần tiêu đề “Trường Description”{ "type": "object", "properties": { "date": { "type": "string", "description": "Date, format YYYY-MM-DD" }, "amount": { "type": "number", "description": "Amount in CNY" } }}description không bắt buộc, nhưng khuyến khích mạnh. Nó giúp mô hình hiểu ngữ nghĩa trường, phạm vi giá trị và quy ước định dạng, cải thiện đáng kể độ chính xác tạo.
5. Ví Dụ Schema
Phần tiêu đề “5. Ví Dụ Schema”Trích Xuất Thông Tin Người Dùng
Phần tiêu đề “Trích Xuất Thông Tin Người Dùng”Trích xuất thông tin người dùng từ văn bản không có cấu trúc:
{ "name": "user_info_extraction", "strict": true, "schema": { "type": "object", "properties": { "name": { "type": "string", "description": "User name" }, "age": { "type": "integer", "description": "Age" }, "email": { "type": ["string", "null"], "description": "Email address, null if not in text" }, "phone": { "type": ["string", "null"], "description": "Phone number, null if not in text" }, "city": { "type": "string", "description": "City" } }, "required": ["name", "age", "city"], "additionalProperties": false }}Tạo Danh Sách Sản Phẩm
Phần tiêu đề “Tạo Danh Sách Sản Phẩm”Cho mô hình tạo mảng sản phẩm:
{ "name": "product_list", "strict": true, "schema": { "type": "object", "properties": { "products": { "type": "array", "items": { "type": "object", "properties": { "name": { "type": "string", "description": "Product name" }, "price": { "type": "number", "description": "Price in CNY" }, "category": { "type": "string", "enum": ["electronics", "clothing", "food", "other"], "description": "Product category" }, "in_stock": { "type": "boolean", "description": "Whether in stock" } }, "required": ["name", "price", "category", "in_stock"], "additionalProperties": false } }, "total_count": { "type": "integer", "description": "Total product count" } }, "required": ["products", "total_count"], "additionalProperties": false }}Object Lồng Phức Tạp
Phần tiêu đề “Object Lồng Phức Tạp”Trích xuất thông tin đơn hàng với lồng nhiều cấp:
{ "name": "order_extraction", "strict": true, "schema": { "type": "object", "properties": { "order_id": { "type": "string", "description": "Order ID" }, "customer": { "type": "object", "properties": { "name": { "type": "string" }, "phone": { "type": "string" }, "address": { "type": "object", "properties": { "province": { "type": "string" }, "city": { "type": "string" }, "street": { "type": "string" } }, "required": ["province", "city", "street"], "additionalProperties": false } }, "required": ["name", "phone", "address"], "additionalProperties": false }, "items": { "type": "array", "items": { "type": "object", "properties": { "product_name": { "type": "string" }, "quantity": { "type": "integer" }, "unit_price": { "type": "number" } }, "required": ["product_name", "quantity", "unit_price"], "additionalProperties": false } }, "total_amount": { "type": "number", "description": "Order total amount" } }, "required": ["order_id", "customer", "items", "total_amount"], "additionalProperties": false }}6. Hỗ Trợ Mô Hình
Phần tiêu đề “6. Hỗ Trợ Mô Hình”Các Mô Hình Hỗ Trợ JSON mode
Phần tiêu đề “Các Mô Hình Hỗ Trợ JSON mode”Hầu hết các mô hình chủ đạo được tích hợp bởi RouteAPI hỗ trợ JSON mode (response_format: { type: "json_object" }), bao gồm:
- OpenAI GPT series (gpt-4o, gpt-4-turbo, gpt-3.5-turbo, v.v.)
- Claude series (claude-3.5-sonnet, claude-3-opus, claude-3-haiku, v.v.)
- Gemini series (gemini-2.0-flash, gemini-1.5-pro, v.v.)
- Các mô hình khác hỗ trợ định dạng OpenAI
Các Mô Hình Hỗ Trợ JSON Schema
Phần tiêu đề “Các Mô Hình Hỗ Trợ JSON Schema”JSON Schema (response_format: { type: "json_schema" }) yêu cầu khả năng mô hình cao hơn; các mô hình hiện hỗ trợ:
- OpenAI: gpt-4o series, gpt-4-turbo series (phiên bản 2024-08-06 và sau)
- Claude: claude-3.5-sonnet series, claude-3-opus series
- Gemini: gemini-2.0-flash-exp, gemini-1.5-pro series
- Khác: một số mô hình thế hệ mới
Cách xác nhận: Truy vấn khả năng mô hình thông qua Models API trước khi gọi, kiểm tra trường supports_response_format.
So Sánh Khả Năng Mô Hình
Phần tiêu đề “So Sánh Khả Năng Mô Hình”| Khả năng | JSON mode | JSON Schema | Ghi chú |
|---|---|---|---|
| Phạm vi hỗ trợ mô hình | Rộng (hầu như tất cả mô hình chủ đạo) | Hạn chế (mô hình thế hệ mới) | JSON mode có hỗ trợ cao hơn |
| Độ phức tạp schema | N/A | Đề xuất không quá 3 cấp lồng | Độ sâu quá mức ảnh hưởng chất lượng tạo |
| Số trường tối đa | N/A | Đề xuất không quá 50 trường cấp cao nhất | Quá nhiều trường ảnh hưởng hiệu suất |
| Đảm bảo nghiêm ngặt | Chỉ đảm bảo JSON hợp lệ | Đảm bảo tuân thủ schema | 100% tuân thủ ở chế độ strict |
| Hiệu suất | Nhanh | Tương đối chậm hơn | Xác thực schema có overhead thêm |
| Tiêu thụ token | Thấp | Cao hơn một chút | Định nghĩa schema chiếm prompt tokens |
Giới Hạn và Lưu Ý
Phần tiêu đề “Giới Hạn và Lưu Ý”-
Giới hạn kích thước schema: Định nghĩa schema đơn đề xuất không vượt quá 10KB; schema quá lớn có thể bị cắt ngắn hoặc từ chối.
-
Giới hạn độ sâu lồng: Đề xuất cấp lồng không vượt quá 3-4 cấp; lồng quá mức làm giảm chất lượng và tốc độ tạo của mô hình.
-
Tác động hiệu suất: Thời gian phản hồi chế độ JSON Schema thường chậm hơn 10%-30% so với yêu cầu thông thường vì mô hình cần xác thực cấu trúc theo thời gian thực trong quá trình tạo.
-
Tính năng schema không được hỗ trợ: Một số tính năng JSON Schema nâng cao (như
$ref,allOf,anyOf,oneOf, regex) có thể không được hỗ trợ bởi tất cả mô hình. -
Đầu ra streaming: Chế độ JSON Schema hỗ trợ đầu ra streaming (
stream: true), nhưngcontentđược trả về theo từng đoạn; JSON hoàn chỉnh cần được nối lại trước khi parse.
7. Ví Dụ Ứng Dụng Đầy Đủ
Phần tiêu đề “7. Ví Dụ Ứng Dụng Đầy Đủ”Ví Dụ 1: Trích Xuất Thông Tin Có Cấu Trúc Từ Văn Bản Không Có Cấu Trúc
Phần tiêu đề “Ví Dụ 1: Trích Xuất Thông Tin Có Cấu Trúc Từ Văn Bản Không Có Cấu Trúc”Tình huống: Trích xuất thông tin khách hàng và phân loại vấn đề từ cuộc trò chuyện dịch vụ khách hàng.
curl:
curl https://api.routeapi.ai/v1/chat/completions \ -H "Authorization: Bearer $ROUTEAPI_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "gpt-4o", "messages": [ { "role": "user", "content": "Customer Li Ming (phone 13800138000) reported that order ORD-2024-001 in Chaoyang District, Beijing has not been shipped and is quite urgent." } ], "response_format": { "type": "json_schema", "json_schema": { "name": "customer_inquiry", "strict": true, "schema": { "type": "object", "properties": { "customer_name": { "type": "string", "description": "Customer name" }, "phone": { "type": ["string", "null"], "description": "Customer phone" }, "location": { "type": ["string", "null"], "description": "Customer location" }, "order_id": { "type": ["string", "null"], "description": "Order ID" }, "issue_category": { "type": "string", "enum": ["delivery", "quality", "refund", "other"], "description": "Issue category: delivery-logistics, quality-quality, refund-refund, other-other" }, "urgency": { "type": "string", "enum": ["low", "medium", "high"], "description": "Urgency level" } }, "required": ["customer_name", "issue_category", "urgency"], "additionalProperties": false } } } }'Phản hồi:
{ "choices": [ { "message": { "role": "assistant", "content": "{\"customer_name\":\"Li Ming\",\"phone\":\"13800138000\",\"location\":\"Chaoyang District, Beijing\",\"order_id\":\"ORD-2024-001\",\"issue_category\":\"delivery\",\"urgency\":\"high\"}" }, "finish_reason": "stop" } ]}Python:
import osimport jsonfrom openai import OpenAI
client = OpenAI( api_key=os.environ["ROUTEAPI_KEY"], base_url="https://api.routeapi.ai/v1",)
response = client.chat.completions.create( model="gpt-4o", messages=[ { "role": "user", "content": "Customer Li Ming (phone 13800138000) reported that order ORD-2024-001 in Chaoyang District, Beijing has not been shipped and is quite urgent.", } ], response_format={ "type": "json_schema", "json_schema": { "name": "customer_inquiry", "strict": True, "schema": { "type": "object", "properties": { "customer_name": {"type": "string", "description": "Customer name"}, "phone": {"type": ["string", "null"], "description": "Customer phone"}, "location": {"type": ["string", "null"], "description": "Customer location"}, "order_id": {"type": ["string", "null"], "description": "Order ID"}, "issue_category": { "type": "string", "enum": ["delivery", "quality", "refund", "other"], "description": "Issue category", }, "urgency": { "type": "string", "enum": ["low", "medium", "high"], "description": "Urgency level", }, }, "required": ["customer_name", "issue_category", "urgency"], "additionalProperties": False, }, }, },)
data = json.loads(response.choices[0].message.content)print(f"Customer: {data['customer_name']}")print(f"Issue type: {data['issue_category']}")print(f"Urgency: {data['urgency']}")Node.js:
import OpenAI from 'openai';
const client = new OpenAI({ apiKey: process.env.ROUTEAPI_KEY, baseURL: 'https://api.routeapi.ai/v1',});
const response = await client.chat.completions.create({ model: 'gpt-4o', messages: [ { role: 'user', content: 'Customer Li Ming (phone 13800138000) reported that order ORD-2024-001 in Chaoyang District, Beijing has not been shipped and is quite urgent.', }, ], response_format: { type: 'json_schema', json_schema: { name: 'customer_inquiry', strict: true, schema: { type: 'object', properties: { customer_name: { type: 'string', description: 'Customer name' }, phone: { type: ['string', 'null'], description: 'Customer phone' }, location: { type: ['string', 'null'], description: 'Customer location' }, order_id: { type: ['string', 'null'], description: 'Order ID' }, issue_category: { type: 'string', enum: ['delivery', 'quality', 'refund', 'other'], description: 'Issue category', }, urgency: { type: 'string', enum: ['low', 'medium', 'high'], description: 'Urgency level', }, }, required: ['customer_name', 'issue_category', 'urgency'], additionalProperties: false, }, }, },});
const data = JSON.parse(response.choices[0].message.content);console.log(`Customer: ${data.customer_name}`);console.log(`Issue type: ${data.issue_category}`);console.log(`Urgency: ${data.urgency}`);Ví Dụ 2: Tạo Dữ Liệu Biểu Mẫu
Phần tiêu đề “Ví Dụ 2: Tạo Dữ Liệu Biểu Mẫu”Tình huống: Cho mô hình tạo giá trị khởi tạo biểu mẫu dựa trên mô tả ngôn ngữ tự nhiên.
Python:
response = client.chat.completions.create( model="gpt-4o", messages=[ { "role": "system", "content": "You are a form filling assistant. Generate form data based on user description.", }, { "role": "user", "content": "Create a new employee onboarding form: Zhang Wei, male, born in 1995, bachelor's degree, software engineer position, monthly salary 15000.", }, ], response_format={ "type": "json_schema", "json_schema": { "name": "employee_form", "strict": True, "schema": { "type": "object", "properties": { "name": {"type": "string"}, "gender": {"type": "string", "enum": ["male", "female"]}, "birth_year": {"type": "integer"}, "education": { "type": "string", "enum": ["high_school", "bachelor", "master", "phd"], }, "position": {"type": "string"}, "salary": {"type": "number", "description": "Monthly salary in CNY"}, }, "required": ["name", "gender", "birth_year", "education", "position", "salary"], "additionalProperties": False, }, }, },)
form_data = json.loads(response.choices[0].message.content)print(json.dumps(form_data, ensure_ascii=False, indent=2))Đầu ra:
{ "name": "Zhang Wei", "gender": "male", "birth_year": 1995, "education": "bachelor", "position": "Software Engineer", "salary": 15000}Ví Dụ 3: Phân Tích Phản Hồi API
Phần tiêu đề “Ví Dụ 3: Phân Tích Phản Hồi API”Tình huống: Cho mô hình trích xuất thông tin quan trọng từ phản hồi API bên thứ ba không có cấu trúc.
Node.js:
const apiResponse = `Order status: ShippedLogistics company: SF ExpressTracking number: SF1234567890Estimated delivery: January 20, 2024Current location: Beijing Distribution Center`;
const response = await client.chat.completions.create({ model: 'gpt-4o', messages: [ { role: 'user', content: `Extract structured data from the following logistics information:\n${apiResponse}`, }, ], response_format: { type: 'json_schema', json_schema: { name: 'logistics_info', strict: true, schema: { type: 'object', properties: { status: { type: 'string', enum: ['pending', 'shipped', 'in_transit', 'delivered'], }, carrier: { type: 'string', description: 'Logistics company' }, tracking_number: { type: 'string', description: 'Tracking number' }, estimated_delivery: { type: ['string', 'null'], description: 'Estimated delivery date, format YYYY-MM-DD', }, current_location: { type: ['string', 'null'], description: 'Current location' }, }, required: ['status', 'carrier', 'tracking_number'], additionalProperties: false, }, }, },});
const data = JSON.parse(response.choices[0].message.content);console.log(data);// Output: { status: 'shipped', carrier: 'SF Express', tracking_number: 'SF1234567890', estimated_delivery: '2024-01-20', current_location: 'Beijing Distribution Center' }8. Xử Lý Lỗi
Phần tiêu đề “8. Xử Lý Lỗi”Xác Thực Schema Thất Bại
Phần tiêu đề “Xác Thực Schema Thất Bại”Nếu định nghĩa schema của bạn có vấn đề (lỗi cú pháp, tính năng không được hỗ trợ), yêu cầu sẽ trả về lỗi 400 trực tiếp:
{ "error": { "message": "Invalid JSON schema: ...", "type": "invalid_request_error", "param": "response_format.json_schema.schema", "code": "invalid_json_schema" }}Giải pháp:
- Kiểm tra xem cú pháp schema có tuân theo đặc tả JSON Schema không
- Loại bỏ các tính năng nâng cao không được hỗ trợ (như
$ref,allOf) - Đơn giản hóa cấu trúc lồng quá mức
Mô Hình Không Thể Tạo Đầu Ra Tuân Thủ Schema
Phần tiêu đề “Mô Hình Không Thể Tạo Đầu Ra Tuân Thủ Schema”Trong trường hợp hiếm gặp, mô hình có thể không thể tạo nội dung tuân thủ schema (ví dụ: đầu vào người dùng hoàn toàn xung đột với yêu cầu schema); trong trường hợp này, một lỗi sẽ được trả về hoặc nó sẽ hạ cấp xuống đầu ra văn bản thuần túy. Ví dụ lỗi:
{ "error": { "message": "Failed to generate valid output matching the provided schema after maximum retries.", "type": "model_error", "code": "schema_generation_failed" }}Giải pháp:
- Kiểm tra xem prompt có nhất quán với yêu cầu schema không
- Đơn giản hóa schema, loại bỏ các ràng buộc quá nghiêm ngặt
- Nêu rõ yêu cầu đầu ra trong prompt
- Đối với trường tùy chọn, sử dụng kiểu
["string", "null"]thay vì chỉ"string"
Chiến Lược Retry
Phần tiêu đề “Chiến Lược Retry”Đối với lỗi tạo thỉnh thoảng, bạn có thể triển khai retry tự động:
import time
def call_with_retry(client, **kwargs): max_retries = 3 for attempt in range(max_retries): try: response = client.chat.completions.create(**kwargs) content = response.choices[0].message.content data = json.loads(content) # Verify it can be parsed return data except (json.JSONDecodeError, Exception) as e: if attempt == max_retries - 1: raise time.sleep(2 ** attempt) # Exponential backoff9. Best Practices
Phần tiêu đề “9. Best Practices”Nguyên Tắc Thiết Kế Schema
Phần tiêu đề “Nguyên Tắc Thiết Kế Schema”-
Bắt đầu đơn giản: Đầu tiên xác minh tính khả thi với JSON mode, sau đó nâng cấp lên JSON Schema sau khi xác nhận cần xác thực nghiêm ngặt.
-
Làm rõ bắt buộc và tùy chọn: Đặt các trường bắt buộc vào mảng
required, sử dụng["type", "null"]cho các trường tùy chọn hoặc đơn giản là không đặt chúng vàorequired. -
Sử dụng enum để giới hạn enum: Đối với các trường có giá trị hạn chế (trạng thái, phân loại, ưu tiên), liệt kê rõ ràng chúng bằng
enum; điều này có thể giảm đáng kể tỷ lệ lỗi. -
Thêm description: Thêm
descriptioncho mỗi trường, giải thích ý nghĩa, định dạng, phạm vi giá trị; mô hình tạo chính xác hơn dựa trên điều này. -
Đặt additionalProperties: false: Ở chế độ strict, thêm điều này ngăn mô hình xuất các trường thêm không xác định.
Tránh Schema Quá Phức Tạp
Phần tiêu đề “Tránh Schema Quá Phức Tạp”| Vấn đề | Mô tả | Đề xuất |
|---|---|---|
| Lồng quá sâu | Hơn 4 cấp lồng làm giảm chất lượng tạo | Chia thành nhiều object phẳng, hoặc trích xuất theo bước bằng cuộc trò chuyện nhiều lượt |
| Quá nhiều trường | Object đơn vượt quá 50 trường | Nhóm theo logic nghiệp vụ, chia thành nhiều sub-object |
| Ràng buộc quá mức | Tất cả trường đều bắt buộc, không có tính linh hoạt | Chỉ đánh dấu các trường cốt lõi là bắt buộc, cho phép null cho các trường khác |
| Không có description | Mô hình không hiểu ngữ nghĩa trường | Thêm description cho mỗi trường, giải thích rõ ràng |
Tối Ưu Hóa Hiệu Suất
Phần tiêu đề “Tối Ưu Hóa Hiệu Suất”-
Giảm kích thước schema: Định nghĩa schema chiếm prompt tokens; schema quá lớn tăng độ trễ và chi phí.
-
Cache định nghĩa schema: Khi cùng một schema được sử dụng lặp lại, định nghĩa nó như một hằng số trong code để tránh xây dựng lại cho mỗi yêu cầu.
-
Chọn mô hình phù hợp: Không phải tất cả nhiệm vụ đều cần mô hình mạnh nhất; trích xuất có cấu trúc đơn giản có thể dùng gpt-3.5-turbo + JSON mode.
-
Xử lý hàng loạt: Nếu có nhiều nhiệm vụ tương tự, thiết kế một array schema để mô hình xử lý nhiều mục dữ liệu cùng lúc.
Cân Nhắc Chi Phí
Phần tiêu đề “Cân Nhắc Chi Phí”| Yếu tố | Tác động | Đề xuất tối ưu |
|---|---|---|
| Kích thước schema | Định nghĩa schema chiếm prompt tokens | Tinh gọn description, loại bỏ trường dư thừa |
| Lựa chọn mô hình | JSON Schema thường yêu cầu mô hình mạnh hơn | Dùng JSON mode + mô hình yếu hơn cho nhiệm vụ đơn giản |
| Độ dài phản hồi | Đầu ra JSON thường dài hơn văn bản (tên key, dấu ngoặc kép, dấu ngoặc) | Rút ngắn tên trường, dùng enum thay vì chuỗi dài |
| Số lần retry | Retry khi tạo thất bại gấp đôi phí | Tối ưu schema và prompt để giảm tỷ lệ thất bại |
Mẹo thực tế: Đối với tình huống gọi tần suất cao, trước tiên hãy thử nghiệm với JSON mode; sau khi xác nhận mô hình có thể xuất định dạng đúng ổn định, hãy nâng cấp lên JSON Schema. JSON mode thường có mức tiêu thụ token và chi phí thấp hơn 10%-20% so với JSON Schema.
Lưu Ý Tương Thích
Phần tiêu đề “Lưu Ý Tương Thích”- Hỗ trợ JSON mode và JSON Schema phụ thuộc vào mô hình được chọn; vui lòng truy vấn trường
supports_response_formatthông qua Models API để xác nhận. response_formatloại trừ lẫn nhau vớitools(tool calling): cùng một yêu cầu không thể sử dụng cả structured outputs và tool calling.- Trong đầu ra streaming (
stream: true),contentđược trả về theo từng đoạn và cần được nối hoàn toàn trước khiJSON.parse. - Các tham số tùy chọn được truyền rõ ràng
0hoặcfalseđược coi là người dùng đặt rõ ràng và sẽ không được coi là bỏ qua mặc định. - Ghi lại request ID, model ID, status code và token usage của mỗi yêu cầu để khắc phục sự cố. Chi tiết cấu trúc lỗi xem Errors and Debugging.