Structured Outputs với API OpenAI-compatible: hướng dẫn JSON Schema

Hướng dẫn thực tế về JSON Schema strict trong Responses và Chat Completions, validation nhiều lớp, xử lý lỗi và kiểm thử route.

Structured Outputs cho phép ứng dụng yêu cầu JSON tuân theo một Schema xác định, thay vì chỉ bảo mô hình “trả về JSON”. Với API OpenAI-compatible, cùng một JSON Schema có thể dùng qua Responses hoặc Chat Completions, nhưng wrapper field khác nhau và phải xác minh trên model cùng route thực tế.

Mẫu production an toàn có ba lớp: dùng strict khi mô hình hỗ trợ, parse và validate lại JSON trong ứng dụng, sau đó áp dụng business rule xác định. Tuân thủ Schema giảm lỗi định dạng nhưng không chứng minh câu trả lời đúng về mặt sự thật hoặc ngữ nghĩa.

Structured Outputs không phải JSON mode

Phương pháp JSON hợp lệ Bắt buộc theo Schema Trường hợp sử dụng
Chỉ Prompt Không được bảo đảm Không Prototype chấp nhận lỗi parsing
JSON mode Có nếu được hỗ trợ và hoàn tất Không JSON linh hoạt do ứng dụng validate
Structured Outputs với strict: true Có, nếu xử lý completion và refusal Có trong subset được hỗ trợ Trích xuất typed và application workflow

Hướng dẫn OpenAI Structured Outputs khuyến nghị cách này thay cho JSON mode khi model và endpoint hỗ trợ. Structured response format trả về một data object có thể dự đoán; Function Calling yêu cầu ứng dụng thực hiện hành động. Schema có thể tương tự, nhưng Call ID và result message thuộc contract khác.

Định nghĩa Schema trước khi chọn endpoint

Workflow phân loại hỗ trợ cần bốn field:

{
  "type": "object",
  "properties": {
    "category": { "type": "string", "enum": ["billing", "technical", "account"] },
    "priority": { "type": "integer", "minimum": 1, "maximum": 3 },
    "requires_human": { "type": "boolean" },
    "summary": { "type": "string" }
  },
  "required": ["category", "priority", "requires_human", "summary"],
  "additionalProperties": false
}

Đặt mọi property là required và additionalProperties: false tạo object ổn định. Điều đó không làm mọi JSON Schema keyword trở nên portable. OpenAI hỗ trợ subset được ghi rõ; provider khác có thể hỗ trợ subset khác hoặc không có Strict Schema Mode.

Gửi Schema bằng Responses API

Responses đặt Schema dưới text.format:

{
  "model": "<MODEL_WITH_VERIFIED_STRUCTURED_OUTPUT_SUPPORT>",
  "input": "The customer was charged twice and wants a refund.",
  "text": {
    "format": {
      "type": "json_schema",
      "name": "support_ticket",
      "schema": {
        "type": "object",
        "properties": {
          "category": { "type": "string", "enum": ["billing", "technical", "account"] },
          "priority": { "type": "integer", "minimum": 1, "maximum": 3 },
          "requires_human": { "type": "boolean" },
          "summary": { "type": "string" }
        },
        "required": ["category", "priority", "requires_human", "summary"],
        "additionalProperties": false
      },
      "strict": true
    }
  }
}

Gửi tới POST https://modelflare.dev/v1/responses với Authorization: Bearer <YOUR_API_KEY>. Nội dung sinh ra nằm trong typed output items. SDK có thể cung cấp helper, nhưng HTTP client phải tìm text output hoàn tất và parse JSON rõ ràng.

Gửi cùng Schema bằng Chat Completions

Chat Completions dùng response_format.json_schema:

{
  "model": "<MODEL_WITH_VERIFIED_STRUCTURED_OUTPUT_SUPPORT>",
  "messages": [
    { "role": "user", "content": "The customer was charged twice and wants a refund." }
  ],
  "response_format": {
    "type": "json_schema",
    "json_schema": {
      "name": "support_ticket",
      "schema": {
        "type": "object",
        "properties": {
          "category": { "type": "string", "enum": ["billing", "technical", "account"] },
          "priority": { "type": "integer", "minimum": 1, "maximum": 3 },
          "requires_human": { "type": "boolean" },
          "summary": { "type": "string" }
        },
        "required": ["category", "priority", "requires_human", "summary"],
        "additionalProperties": false
      },
      "strict": true
    }
  }
}

JSON thường là string tại choices[0].message.content và vẫn cần parse.

Mục đích Responses API Chat Completions
Container text.format response_format.json_schema
Type text.format.type response_format.type
Name text.format.name response_format.json_schema.name
Schema text.format.schema response_format.json_schema.schema
Strict text.format.strict response_format.json_schema.strict
Result Output items / helper choices[0].message.content

Lớp tương thích của Modelflare chuyển đổi hai wrapper trên route OpenAI/Codex được hỗ trợ, nhưng không thể tạo Structured Outputs trong upstream model không có tính năng này. Với Raw Chat Completions Pass-through, contract của provider là Source of Truth.

Validate cấu trúc và ý nghĩa riêng biệt

{
  "category": "billing",
  "priority": 2,
  "requires_human": true,
  "summary": "Customer reports a duplicate charge and requests a refund."
}

Validate cấu trúc

JSON Schema validator kiểm tra required property, property ngoài dự kiến, type, enum và range. Ngay cả khi có Strict Adherence, validation trong ứng dụng vẫn bảo vệ trước route không hỗ trợ, lỗi tích hợp, truncation và thay đổi contract.

Validate ngữ nghĩa và nghiệp vụ

Schema không biết khách hàng có thật sự bị tính phí hai lần, priority: 2 có đúng hay ai được duyệt hoàn tiền. Hãy xem object là phân loại đề xuất, so sánh với dữ liệu có thẩm quyền, và thực thi quyền cùng financial limit bằng code xác định. JSON hợp lệ không được vượt qua authorization, billing hoặc security boundary.

Xử lý output không đầy đủ và ngoại lệ

Refusal

Kiểm tra Status và refusal representation trước khi tìm JSON. Từ chối vì an toàn không phải parsing error.

Truncation và Output Limit

Nếu generation dừng trước khi object đóng, Schema không thể khôi phục phần thiếu. Kiểm tra Completion Status và Stop Reason, đặt Output Limit đủ nhưng có giới hạn.

Keyword không được hỗ trợ

Bắt đầu với Objects, Arrays, Primitive Types, Enums, Required và Additional Properties rõ ràng. Xem tài liệu provider trước khi dùng References, recursion, Union phức tạp hoặc advanced validation.

Latency khi dùng Schema lần đầu

Một số provider preprocess và cache Schema mới. Tái sử dụng Schema ổn định, có version và đo First Use riêng với Steady State.

Model hoặc route không tương thích

Endpoint có thể nhận Chat Completions thường nhưng từ chối json_schema hoặc bỏ qua strict. Response 200 có JSON không chứng minh Strict Adherence. Phải thử input invalid và edge case.

Chạy ma trận tương thích

Kiểm thử Bằng chứng cần lưu
Required Object tối thiểu Status, model, route, parsed object, validation result
Mọi Enum Sinh và parse từng giá trị
Thiếu thông tin Giá trị giới hạn hoặc yêu cầu làm rõ
Safety Input Refusal format và xử lý ứng dụng
Output Limit thấp Completion Status và truncation
Feature không hỗ trợ Error rõ ràng hoặc constraint bị bỏ qua
Wrapper Responses và Chat Object ứng dụng tương đương
Stable Schema lặp lại First Use so với Steady State

Giữ nguyên Schema, Prompt, Region, Streaming Mode và Output Limit, đồng thời ghi ngày kiểm thử.

Chọn endpoint sau khi thử workflow

Dùng Responses cho typed output items, streaming events hoặc Tool workflow rộng hơn. Dùng Chat Completions cho tích hợp dựa trên messages khi route hỗ trợ response_format. Xem Responses API và Chat Completions.

Dù chọn cách nào:

  1. giữ một Source of Truth JSON Schema có version;
  2. chỉ thay wrapper, không thay ý nghĩa;
  3. validate response hoàn tất;
  4. áp dụng business rule xác định sau cấu trúc;
  5. theo dõi parsing, refusal, truncation và compatibility failure riêng.

Bắt đầu migration với Hướng dẫn OpenAI-Compatible API, và dùng Hướng dẫn AI API Streaming cho stream không đầy đủ. Kiểm tra Models & Pricing, sau đó thử Structured Outputs trên route thực tế của API Key.

Structured Outputs thu hẹp phản hồi mô hình thành interface đáng tin cậy hơn, nhưng không thay thế xác minh sự thật, authorization hay billing logic. “OpenAI-compatible” vẫn là tuyên bố cần kiểm thử theo từng tính năng.