Sebuah pipeline meminta model mengekstrak status peluncuran. Jawabannya JSON yang valid, tetapi field status berisi available ketika dokumen mengatakan “akan tersedia”. Parser tidak menemukan kesalahan. Aplikasi tetap bisa mengambil keputusan yang salah.
Structured Outputs membantu membatasi bentuk keluaran terhadap skema yang didukung. Ia berguna untuk integrasi, tetapi tidak menggantikan validasi fakta dan aturan bisnis. Kita akan merancang kontrak ekstraksi editorial dengan tiga lapisan pemeriksaan: sintaks, struktur, dan makna. Skema serta data di artikel ini merupakan contoh rancangan Nalarku.
Mulai dari konsumen data
Tanyakan apa yang benar-benar dibutuhkan aplikasi berikutnya. Jika tugasnya mengisi kartu produk, konsumen mungkin memerlukan nama, status akses, tanggal sumber, serta daftar bukti. Jangan meminta “semua informasi penting” tanpa mendefinisikan bentuknya.
Bedakan tidak diketahui dari tidak berlaku. String kosong, field hilang, dan null tidak otomatis berarti hal yang sama. Ketika sumber tidak menyebut tanggal ketersediaan, null yang didefinisikan jelas lebih aman daripada model mengisi tanggal penerbitan artikel sebagai tebakan.
Simpan versi kontrak di luar atau di dalam objek. Perubahan arti sebuah field dapat mematahkan integrasi walaupun tipe datanya tetap string. Misalnya, available yang awalnya berarti dapat mendaftar waitlist tidak boleh diam-diam diubah menjadi dapat langsung memakai produk.
Skema membatasi struktur, bukan pengetahuan
Referensi JSON Schema membedakan properties, required, dan additionalProperties. Mendefinisikan properti tidak otomatis mewajibkan keberadaannya. Dukungan provider dapat berupa subset JSON Schema, sehingga skema harus dicocokkan dengan dokumentasi endpoint yang digunakan.
{
"type": "object",
"properties": {
"schema_version": {"type": "string", "enum": ["1"]},
"product": {"type": "string"},
"access": {
"type": "string",
"enum": ["announced", "private_preview", "public", "unknown"]
},
"availability_date": {"type": ["string", "null"]},
"evidence_ids": {"type": "array", "items": {"type": "string"}}
},
"required": [
"schema_version", "product", "access",
"availability_date", "evidence_ids"
],
"additionalProperties": false
}
Contoh ini adalah objek skema, bukan permintaan HTTP lengkap. Aplikasi masih perlu meletakkannya pada field yang sesuai untuk API dan model yang didukung. Tidak ada panggilan layanan berbayar yang diperlukan untuk mempelajari validator lokalnya.
Tambahkan pemeriksaan semantik
Tanggal dengan bentuk 2026-02-31 terlihat seperti pola ISO, tetapi tidak valid. Bukti S99 terlihat seperti ID, tetapi mungkin tidak ada. Keluaran terstruktur perlu diperiksa terhadap konteks aplikasi.
from datetime import date
def validate_release(data, known_evidence):
errors = []
if not data["product"].strip():
errors.append("Nama produk kosong")
if data["availability_date"] is not None:
try:
parsed = date.fromisoformat(data["availability_date"])
if parsed.isoformat() != data["availability_date"]:
errors.append("Gunakan tanggal YYYY-MM-DD")
except ValueError:
errors.append("Tanggal tidak valid")
refs = data["evidence_ids"]
if len(refs) != len(set(refs)):
errors.append("ID bukti berulang")
if any(ref not in known_evidence for ref in refs):
errors.append("Ada bukti yang tidak ditemukan")
if data["access"] != "unknown" and not refs:
errors.append("Status pasti memerlukan bukti")
return errors
Fungsi ini mengasumsikan validasi struktur sudah dilakukan. Ia belum membaca isi bukti. Status public dengan tautan sumber yang hanya mengatakan private_preview tetap memerlukan pemeriksaan entailment atau review manusia. Pisahkan pesan error teknis dari alasan editorial agar pengguna tahu apa yang perlu diperbaiki.
Refusal dan keluaran terpotong adalah cabang normal
Dokumentasi OpenAI menjelaskan bahwa refusal dapat muncul di luar bentuk jawaban yang diminta. Respons yang berhenti karena batas keluaran juga tidak boleh diperlakukan sebagai objek selesai. Penanganan tepat bergantung pada envelope endpoint yang dipakai.
Rancang adapter yang menghasilkan status aplikasi seperti completed, refused, incomplete, atau failed. Baru setelah completed, jalankan parsing dan validasi. Jangan membuat fallback berupa objek kosong hanya supaya langkah berikutnya terus berjalan.
Jika hasil tidak lengkap, simpan alasan dan putuskan apakah perlu retry dengan input lebih terfokus atau batas keluaran yang sesuai. Retry yang sekadar meminta “hasilkan JSON yang benar” dapat memperbaiki bentuk sambil mengarang isi. Pertahankan sumber awal dan catat setiap percobaan.
Kontrak keluaran bukan kontrak tindakan
Objek {"action":"publish"} tetap merupakan data. Otorisasi publikasi berada pada aplikasi yang menjalankan tindakan. Daftar enum memperkecil variasi nilai, tetapi tidak memberi wewenang kepada model untuk melakukan salah satunya.
| Lapisan | Yang diperiksa | Yang belum dijamin |
|---|---|---|
| Parser JSON | Dokumen dapat dibaca | Struktur sesuai kebutuhan |
| Validator skema | Field dan tipe sesuai | Nilai didukung sumber |
| Validator semantik | Aturan lintas field dan referensi | Interpretasi semua bukti benar |
| Review editorial | Klaim dan konteks | Izin melakukan tindakan eksternal |
| Pelaksana tindakan | Izin, versi, idempotensi | Kualitas keseluruhan isi |
Dengan pemisahan ini, kegagalan satu lapisan bisa ditangani tanpa menyamarkan lapisan lain. Kesalahan bukti tidak perlu dilaporkan sebagai “JSON error”.
Migrasi skema tanpa merusak arsip
Saat menambah status baru seperti regional_preview, jangan langsung mengubah arti data lama. Tambahkan versi kontrak, adapter pembaca, dan fixture yang mencakup kedua versi. Konsumen lama perlu keputusan eksplisit: menolak versi baru atau memetakannya ke kategori yang aman.
Buat kasus uji untuk field tambahan, ID bukti hilang, tanggal mustahil, status tanpa sumber, refusal, dan keluaran terpotong. Bandingkan tingkat validitas struktur dengan tingkat ketepatan fakta. Keduanya dapat bergerak ke arah berbeda saat prompt atau model berubah.
Latihan yang berguna adalah mengambil sepuluh dokumen pengumuman dan menyusun label rujukan sebelum menjalankan model. Simpan kesalahan per field agar terlihat apakah sistem lemah pada tanggal, syarat akses, atau atribusi. Lanjutkan dengan panduan evaluasi dan regresi untuk menentukan apakah kontrak tersebut sudah cukup baik untuk dipakai dalam alur kerja nyata.