Structured Outputs dengan API OpenAI-compatible: panduan JSON Schema
Panduan praktis JSON Schema strict untuk Responses dan Chat Completions, validasi berlapis, penanganan kegagalan, dan pengujian route.
Structured Outputs memungkinkan aplikasi meminta JSON yang mengikuti Schema tertentu, bukan sekadar menyuruh model “mengembalikan JSON”. Pada API OpenAI-compatible, JSON Schema yang sama dapat dipakai melalui Responses atau Chat Completions, tetapi wrapper field berbeda dan dukungan harus diverifikasi pada model serta route yang sebenarnya.
Pola production yang aman memiliki tiga lapisan: gunakan strict jika didukung, parse dan validasi ulang JSON di aplikasi, lalu terapkan business rule deterministik. Kepatuhan terhadap Schema mengurangi kegagalan format, tetapi tidak membuktikan kebenaran faktual atau semantik.
Structured Outputs berbeda dari JSON mode
| Metode | JSON valid | Memaksa Schema | Penggunaan umum |
|---|---|---|---|
| Prompt saja | Tidak dijamin | Tidak | Prototype yang menerima kegagalan parsing |
| JSON mode | Ya jika didukung dan selesai | Tidak | JSON fleksibel yang divalidasi aplikasi |
Structured Outputs dengan strict: true |
Ya, dengan penanganan completion dan refusal | Ya dalam subset yang didukung | Ekstraksi typed dan application workflow |
Panduan OpenAI Structured Outputs merekomendasikannya dibanding JSON mode ketika model dan endpoint mendukung. Structured response format menghasilkan data object yang dapat diprediksi; Function Calling meminta aplikasi melakukan tindakan. Schema dapat serupa, tetapi Call ID dan result message mengikuti kontrak berbeda.
Definisikan Schema sebelum memilih endpoint
Workflow triase dukungan membutuhkan empat 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
}
Semua property dibuat required dan additionalProperties: false menghasilkan object stabil. Namun, tidak semua keyword JSON Schema menjadi portable. OpenAI mendokumentasikan subset tertentu; penyedia lain dapat mendukung subset berbeda atau tidak memiliki Strict Schema Mode.
Kirim Schema dengan Responses API
Responses menempatkan Schema di 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
}
}
}
Kirim ke POST https://modelflare.dev/v1/responses dengan Authorization: Bearer <YOUR_API_KEY>. Konten berada dalam typed output items. SDK dapat menawarkan helper, tetapi HTTP client harus menemukan text output yang selesai dan melakukan JSON parsing secara eksplisit.
Kirim Schema yang sama dengan Chat Completions
Chat Completions memakai 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 biasanya berupa string di choices[0].message.content dan perlu di-parse.
| Tujuan | 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 |
Lapisan kompatibilitas Modelflare mengonversi kedua wrapper pada route OpenAI/Codex yang didukung, tetapi tidak menciptakan Structured Outputs pada model upstream yang tidak mendukungnya. Untuk Raw Chat Completions Pass-through, kontrak penyedia tetap menjadi Source of Truth.
Validasi struktur dan makna secara terpisah
{
"category": "billing",
"priority": 2,
"requires_human": true,
"summary": "Customer reports a duplicate charge and requests a refund."
}
Validasi struktural
JSON Schema validator memeriksa required property, property tak terduga, type, enum, dan range. Walaupun provider menjanjikan Strict Adherence, validasi aplikasi melindungi dari route tak didukung, kesalahan integrasi, truncation, dan perubahan kontrak.
Validasi semantik dan bisnis
Schema tidak mengetahui apakah duplikasi pembayaran benar terjadi, apakah priority: 2 tepat, atau siapa yang boleh menyetujui refund. Perlakukan object sebagai klasifikasi usulan, bandingkan dengan data otoritatif, dan terapkan izin serta financial limit dalam kode deterministik. JSON valid tidak boleh melewati authorization, billing, atau security boundary.
Tangani output tidak lengkap dan pengecualian
Refusal
Periksa Status dan refusal representation sebelum mencari JSON. Penolakan keamanan bukan parsing error.
Truncation dan Output Limit
Jika generation berhenti sebelum object ditutup, Schema tidak dapat memperbaiki bagian yang hilang. Periksa Completion Status dan Stop Reason serta berikan Output Limit yang cukup tetapi terbatas.
Keyword yang tidak didukung
Mulai dari Objects, Arrays, Primitive Types, Enums, Required, dan Additional Properties eksplisit. Periksa dokumentasi sebelum memakai References, recursion, Union kompleks, atau advanced validation.
Latency penggunaan Schema pertama
Sebagian provider memproses dan menyimpan Schema baru di cache. Gunakan kembali Schema stabil dan berversi serta pisahkan pengukuran First Use dari Steady State.
Model atau route tidak kompatibel
Endpoint dapat menerima Chat Completions biasa tetapi menolak json_schema atau mengabaikan strict. Response 200 dengan JSON bukan bukti Strict Adherence. Sertakan input invalid dan edge case.
Jalankan matriks kompatibilitas
| Pengujian | Bukti yang disimpan |
|---|---|
| Required Object minimal | Status, model, route, parsed object, validation result |
| Semua Enum | Pembuatan dan parsing setiap nilai |
| Informasi hilang | Nilai fallback terbatas atau clarification |
| Safety Input | Format refusal dan penanganan aplikasi |
| Output Limit rendah | Completion Status dan truncation |
| Feature tak didukung | Error eksplisit atau constraint diabaikan |
| Wrapper Responses dan Chat | Object aplikasi yang setara |
| Stable Schema berulang | First Use dibanding Steady State |
Pertahankan Schema, Prompt, Region, Streaming Mode, dan Output Limit yang sama dan catat tanggal pengujian.
Pilih endpoint setelah menguji workflow
Gunakan Responses untuk typed output items, streaming events, atau Tool workflow yang lebih luas. Gunakan Chat Completions untuk integrasi berbasis messages jika route mendukung response_format. Lihat Responses API vs Chat Completions.
Apa pun endpoint-nya:
- simpan satu Source of Truth JSON Schema yang berversi;
- ubah wrapper tanpa mengubah makna;
- validasi response yang selesai;
- terapkan business rule deterministik setelah validasi struktur;
- monitor parsing, refusal, truncation, dan compatibility failure secara terpisah.
Mulai migrasi dengan Panduan OpenAI-Compatible API, dan gunakan Panduan AI API Streaming untuk stream tak lengkap. Periksa Models & Pricing, lalu uji Structured Outputs pada route sebenarnya dari API Key.
Structured Outputs mempersempit respons model menjadi interface aplikasi yang lebih andal. Namun, ini tidak menggantikan verifikasi fakta, authorization, atau billing logic. “OpenAI-compatible” tetap harus diuji per fitur.