Lewati ke konten utama

Mulai Menggunakan OpenAI Structured Outputs

Pelajari cara memulai dengan OpenAI Structured Outputs, pahami sintaks barunya, dan jelajahi penerapan utamanya.
Diperbarui 28 Sep 2026  · 9 mnt Baca

Jelajahi bersama AI

ChatGPTClaudePerplexity

Pada Agustus 2024, OpenAI mengumumkan fitur baru yang kuat di API mereka—Structured Outputs. Dengan fitur ini, sebagaimana namanya, Anda dapat memastikan LLM hanya akan menghasilkan respons dalam format yang Anda tentukan. Kapabilitas ini akan membuat pembangunan aplikasi yang memerlukan pemformatan data presisi menjadi jauh lebih mudah. 

Dalam tutorial ini, Anda akan mempelajari cara memulai dengan OpenAI Structured Outputs, memahami sintaks barunya, dan mengeksplorasi penerapan utamanya.

Pentingnya Structured Outputs dalam Aplikasi AI

Respons deterministik, atau dengan kata lain, respons dengan format yang konsisten, sangat penting untuk banyak tugas seperti entri data, pengambilan informasi, tanya jawab, alur kerja multi-langkah, dan seterusnya. Anda mungkin pernah mengalami bagaimana LLM dapat menghasilkan output dalam format yang sangat berbeda, meskipun prompt-nya sama.

Sebagai contoh, pertimbangkan fungsi sederhana classify_sentiment berikut yang ditenagai oleh GPT-4o:

# List of hotel reviews
reviews = [
   "The room was clean and the staff was friendly.",
   "The location was terrible and the service was slow.",
   "The food was amazing but the room was too small.",
]
# Classify sentiment for each review and print the results
for review in reviews:
   sentiment = classify_sentiment(review)
   print(f"Review: {review}\nSentiment: {sentiment}\n")

Output:

Review: The room was clean and the staff was friendly.
Sentiment: Positive
Review: The location was terrible and the service was slow.
Sentiment: Negative
Review: The food was amazing but the room was too small.
Sentiment: The sentiment of the review is neutral.

Meskipun dua respons pertama menggunakan format satu kata yang sama, yang terakhir berupa satu kalimat penuh. Jika ada aplikasi hilir lain yang bergantung pada output kode di atas, aplikasi tersebut bisa gagal karena mengharapkan respons satu kata.

Kita bisa memperbaiki masalah ini dengan prompt engineering, tetapi ini adalah proses yang memakan waktu dan iteratif. Bahkan dengan prompt yang sempurna, kita tidak bisa 100% yakin respons akan mengikuti format kita pada permintaan berikutnya. Kecuali, tentu saja, kita menggunakan Structured Outputs:

def classify_sentiment_with_structured_outputs(review):
   """Sentiment classifier with Structured Outputs"""
   ...
# Classify sentiment for each review with Structured Outputs
for review in reviews:
   sentiment = classify_sentiment_with_structured_outputs(review)
   print(f"Review: {review}\nSentiment: {sentiment}\n")

Output:

Review: The room was clean and the staff was friendly.
Sentiment: {"sentiment":"positive"}
Review: The location was terrible and the service was slow.
Sentiment: {"sentiment":"negative"}
Review: The food was amazing but the room was too small.
Sentiment: {"sentiment":"neutral"}

Dengan fungsi baru classify_sentiment_with_structured_outputs, semua respons berada dalam format yang sama.

Kemampuan memaksa model bahasa menghasilkan format yang kaku ini sangat signifikan, menghemat banyak waktu Anda untuk prompt engineering atau ketergantungan pada alat open-source lainnya.

Mulai Menggunakan OpenAI Structured Outputs

Pada bagian ini, kita akan menguraikan structured outputs menggunakan contoh fungsi penganalisis sentimen.

Menyiapkan Lingkungan Anda

Prasyarat

Sebelum memulai, pastikan Anda memiliki hal-hal berikut:

  • Python 3.7 atau yang lebih baru terpasang pada sistem Anda.
  • Kunci API OpenAI. Anda dapat memperolehnya dengan mendaftar di situs web OpenAI.

Menyiapkan OpenAI API

1. Instal paket Python OpenAI: Buka terminal Anda dan jalankan perintah berikut untuk memasang atau memperbarui paket Python OpenAI ke versi terbaru:

$ pip install -U openai

2. Atur kunci API Anda: Anda dapat mengatur kunci API sebagai variabel lingkungan atau langsung di kode Anda. Untuk mengaturnya sebagai variabel lingkungan, jalankan:

$ export OPENAI_API_KEY='your-api-key'

3. Verifikasi instalasi: Buat skrip Python sederhana untuk memverifikasi instalasi:

from openai import OpenAI
client = OpenAI()
response = client.chat.completions.create(
   model="gpt-4o-mini",
   messages=[
       {"role": "system", "content": "You are a helpful assistant."},
       {"role": "user", "content": "Say hello!"}
   ],
   max_tokens=5
)
>>> print(response.choices[0].message.content.strip())
Hello! How can I

Jalankan skrip untuk memastikan semuanya sudah disiapkan dengan benar. Anda akan melihat respons model tercetak di terminal.

Selain paket OpenAI, Anda memerlukan pustaka Pydantic untuk mendefinisikan dan memvalidasi skema JSON bagi Structured Outputs. Pasang menggunakan pip:

$ pip install pydantic

Dengan langkah-langkah ini, lingkungan Anda kini siap menggunakan fitur Structured Outputs dari OpenAI.

Mendefinisikan Skema Output Menggunakan Pydantic

Untuk menggunakan Structured Outputs, Anda perlu mendefinisikan struktur output yang diharapkan menggunakan model Pydantic. Pydantic adalah pustaka validasi data dan manajemen pengaturan untuk Python, yang memungkinkan Anda mendefinisikan model data menggunakan anotasi tipe Python. Model-model ini kemudian dapat digunakan untuk menegakkan struktur output yang dihasilkan oleh model OpenAI.

Berikut contoh model Pydantic untuk menentukan format bagi pengklasifikasi sentimen ulasan kita:

from pydantic import BaseModel
from typing import Literal
class SentimentResponse(BaseModel):
   sentiment: Literal["positive", "negative", "neutral"]

Dalam contoh ini:

  • SentimentResponse adalah model Pydantic yang mendefinisikan struktur output yang diharapkan.
  • Model ini memiliki satu field sentiment, yang hanya dapat berisi salah satu dari tiga nilai literal: "positive", "negative", atau "neutral".

Saat kita meneruskan model ini sebagai bagian dari permintaan API OpenAI, outputnya hanya akan berupa salah satu dari kata yang kita sediakan.

Mari lihat caranya.

Menggunakan Helper parse

Untuk menerapkan skema Pydantic kita dalam permintaan OpenAI, yang perlu kita lakukan hanyalah meneruskannya ke parameter response_format dari API chat completions. Secara garis besar, tampilannya seperti ini:

response = client.beta.chat.completions.parse(
   model=MODEL,
   messages=[...],
   response_format=SentimentResponse
)

Perhatikan, alih-alih menggunakan client.chat.completions.create, kita menggunakan metode client.beta.chat.completions.parse. .parse() adalah metode baru di Chat Completions API yang ditulis khusus untuk Structured Outputs.

Sekarang, mari kita satukan semuanya dengan menulis ulang pengklasifikasi sentimen ulasan menggunakan Structured Outputs. Pertama, kita lakukan impor yang diperlukan, mendefinisikan model Pydantic, system prompt, dan templat prompt:

from openai import OpenAI
from pydantic import BaseModel
from typing import Literal
class SentimentResponse(BaseModel):
   sentiment: Literal["positive", "negative", "neutral"]
client = OpenAI()
MODEL = "gpt-4o-mini"
SYSTEM_PROMPT = "You are a sentiment classifier assistant."
PROMPT_TEMPLATE = """
   Classify the sentiment of the following hotel review as positive, negative, or neutral:\n\n{review}
"""

Lalu, kita tulis fungsi baru yang menggunakan metode helper .parse():

# Function to classify sentiment using OpenAI's chat completions API with structured outputs
def classify_sentiment_with_structured_outputs(review):
   response = client.beta.chat.completions.parse(
       model=MODEL,
       messages=[
           {"role": "system", "content": SYSTEM_PROMPT},
           {"role": "user", "content": PROMPT_TEMPLATE.format(review=review)},
       ],
       response_format=SentimentResponse
   )
   return response.choices[0].message

Baris penting dalam fungsi tersebut adalah response_format=SentimentResponse, yang benar-benar mengaktifkan Structured Outputs.

Mari kita uji pada salah satu ulasan:

# List of hotel reviews
reviews = [
   "The room was clean and the staff was friendly.",
   "The location was terrible and the service was slow.",
   "The food was amazing but the room was too small.",
]
result = classify_sentiment_with_structured_outputs(reviews[0])
>>> print(result.content)
{"sentiment":"positive"}

Di sini, result adalah objek pesan:

>>> type(result)
openai.types.chat.parsed_chat_completion.ParsedChatCompletionMessage[SentimentResponse]

Selain atribut .content, yang mengambil respons, objek ini memiliki atribut .parsed yang mengembalikan informasi terurai sebagai sebuah kelas:

>>> result.parsed
SentimentResponse(sentiment='positive')

Seperti yang terlihat, kita mendapatkan instance dari kelas SentimentResponse. Artinya, kita dapat mengakses sentimen sebagai string alih-alih kamus menggunakan atribut .sentiment:

>>> result.parsed.sentiment
'positive'

Menyusun Model Pydantic untuk Mendefinisikan Skema Kompleks

Dalam beberapa kasus, Anda mungkin perlu mendefinisikan struktur output yang lebih kompleks yang melibatkan data bertingkat. Pydantic memungkinkan Anda untuk menumpuk model satu sama lain, sehingga Anda dapat membuat skema rumit yang mampu menangani berbagai kasus penggunaan. Ini sangat berguna saat menangani data hierarkis atau ketika Anda perlu menegakkan struktur tertentu untuk output yang kompleks.

Mari pertimbangkan contoh di mana kita perlu mengekstrak informasi pengguna secara rinci, termasuk nama, detail kontak, dan daftar alamat. Setiap alamat harus mencakup field untuk jalan, kota, negara bagian, dan kode pos. Ini memerlukan lebih dari satu model Pydantic untuk membangun skema yang benar.

Langkah 1: Definisikan model Pydantic

Pertama, kita definisikan model Pydantic untuk alamat dan informasi pengguna:

from pydantic import BaseModel
from typing import List
# Define the Pydantic model for an address
class Address(BaseModel):
   street: str
   city: str
   state: str
   zip_code: str
# Define the Pydantic model for user information
class UserInfo(BaseModel):
   name: str
   email: str
   phone: str
   addresses: List[Address]

Dalam contoh ini:

  • Address adalah model Pydantic yang mendefinisikan struktur sebuah alamat.
  • UserInfo adalah model Pydantic yang mencakup daftar objek Address, beserta field untuk nama, email, dan nomor telepon pengguna.

Langkah 2: Gunakan model Pydantic bertingkat dalam panggilan API

Selanjutnya, kita gunakan model Pydantic bertingkat ini untuk menegakkan struktur output dalam panggilan OpenAI API:

SYSTEM_PROMPT = "You are a user information extraction assistant."
PROMPT_TEMPLATE = """ Extract the user information from the following text:\n\n{text}"""
# Function to extract user information using OpenAI's chat completions API with structured outputs
def extract_user_info(text):
   response = client.beta.chat.completions.parse(
       model=MODEL,
       messages=[
           {"role": "system", "content": SYSTEM_PROMPT},
           {"role": "user", "content": PROMPT_TEMPLATE.format(text=text)},
       ],
       response_format=UserInfo
   )
   return response.choices[0].message
# Example text containing user information
text = """John DoeEmail: john.doe@example.comPhone: 123-456-7890Addresses:- 123 Main St, Springfield, IL, 62701- 456 Elm St, Shelbyville, IL, 62702"""
# Extract user information and print the results
user_info = extract_user_info(text)

Teks contoh benar-benar sulit dibaca dan tidak memiliki spasi antar bagian informasi kunci. Mari kita lihat apakah model berhasil. Kita akan menggunakan pustaka json untuk mempercantik respons:

import json
data = json.loads(user_info.content)
pretty_response = json.dumps(data, indent=2)
print(pretty_response)
{
 "name": "John Doe",
 "email": "john.doe@example.com",
 "phone": "123-456-7890",
 "addresses": [
   {
     "street": "123 Main St",
     "city": "Springfield",
     "state": "IL",
     "zip_code": "62701"
   },
   {
     "street": "456 Elm St",
     "city": "Shelbyville",
     "state": "IL",
     "zip_code": "62702"
   }
 ]
}

Seperti terlihat, model berhasil menangkap informasi satu pengguna beserta dua alamat terpisahnya berdasarkan skema yang kita sediakan.

Singkatnya, dengan menyusun model Pydantic, Anda dapat mendefinisikan skema kompleks yang menangani data hierarkis dan menegakkan struktur khusus untuk output yang rumit.

Function Calling dengan Structured Outputs

Salah satu fitur yang luas digunakan pada model bahasa yang lebih baru adalah function calling (juga disebut tool calling). Kapabilitas ini memungkinkan Anda menghubungkan model bahasa ke fungsi yang didefinisikan pengguna, sehingga secara efektif memberi model akses ke dunia luar.

Beberapa contoh umum:

  • Mengambil data real-time (misalnya, cuaca, harga saham, skor olahraga)
  • Melakukan perhitungan atau analisis data
  • Melakukan kueri ke basis data atau API
  • Menghasilkan gambar atau media lainnya
  • Menerjemahkan teks antar bahasa
  • Mengendalikan perangkat rumah pintar atau sistem IoT
  • Mengeksekusi logika bisnis atau alur kerja kustom

Kita tidak akan membahas detail cara kerja function calling di sini, namun Anda dapat membaca tutorial OpenAI Function Calling kami.

Yang penting untuk diketahui adalah dengan Structured Outputs, penggunaan function calling dengan model OpenAI menjadi jauh lebih mudah. Di masa lalu, fungsi yang Anda teruskan ke model OpenAI memerlukan penulisan skema JSON yang kompleks, merinci setiap parameter fungsi dengan petunjuk tipe. Berikut contohnya:

{
   "type": "function",
   "function": {
       "name": "get_current_weather",
       "description": "Get the current weather",
       "parameters": {
           "type": "object",
           "properties": {
               "location": {
                   "type": "string",
                   "description": "The city and state, e.g. San Francisco, CA",
               },
               "format": {
                   "type": "string",
                   "enum": ["celsius", "fahrenheit"],
                   "description": "The temperature unit to use. Infer this from the users location.",
               },
           },
           "required": ["location", "format"],
       },
   }
}

Meskipun fungsi get_current_weather hanya memiliki dua parameter, skema JSON-nya menjadi sangat besar dan rawan kesalahan bila ditulis manual.

Hal ini diatasi dalam Structured Outputs dengan kembali menggunakan model Pydantic:

from pydantic import BaseModel
from typing import Literal
def get_weather(location: str, unit: str, condition: str):
   # Implementation details...
   pass
class WeatherData(BaseModel):
   location: str
   unit: Literal["celsius", "fahrenheit"]
   condition: Literal["sunny", "cloudy", "rainy", "snowy"]

Pertama, Anda menulis fungsinya dan logiknya. Lalu, Anda mendefinisikannya kembali dengan model Pydantic yang menentukan parameter input yang diharapkan.

Kemudian, untuk mengonversi model Pydantic ke skema JSON yang kompatibel, Anda memanggil pydantic_function_tool:

>>> import openai
>>> openai.pydantic_function_tool(WeatherData)
{'type': 'function',
'function': {'name': 'WeatherData',
 'strict': True,
 'parameters': {'properties': {'location': {'title': 'Location',
    'type': 'string'},
   'unit': {'enum': ['celsius', 'fahrenheit'],
    'title': 'Unit',
    'type': 'string'},
   'condition': {'enum': ['sunny', 'cloudy', 'rainy', 'snowy'],
    'title': 'Condition',
    'type': 'string'}},
  'required': ['location', 'unit', 'condition'],
  'title': 'WeatherData',
  'type': 'object',
  'additionalProperties': False}}}

Berikut cara menggunakan tool ini sebagai bagian dari permintaan:

import openai
client = OpenAI()
tools = [openai.pydantic_function_tool(WeatherData)]
messages = [
   {
       "role": "system",
       "content": "You are a helpful customer support assistant. Use the supplied tools to assist the user.",
   },
   {
       "role": "user",
       "content": "What is the weather in Tokyo?",
   }
]
response = client.chat.completions.create(
   model=MODEL, messages=messages, tools=tools
)
tool_call = response.choices[0].message.tool_calls[0]
>>> tool_call
ChatCompletionMessageToolCall(id='call_QnZZ0DmNN2cxw3bN433JQNIC', function=Function(arguments='{"location":"Tokyo","unit":"celsius","condition":"sunny"}', name='WeatherData'), type='function')

Kita meneruskan model Pydantic dalam format JSON yang kompatibel ke parameter tools dari Chat Completions API. Lalu, bergantung pada kueri kita, model memutuskan apakah akan memanggil tool tersebut atau tidak.

Karena kueri kita pada contoh di atas adalah “What is the weather in Tokyo?”, kita melihat sebuah panggilan pada tool_calls dari objek pesan yang dikembalikan.

Ingat, model tidak memanggil fungsi get_weather, melainkan menghasilkan argumen untuknya berdasarkan skema Pydantic yang kita berikan:

arguments = json.loads(tool_call.function.arguments)
>>> arguments
{'location': 'Tokyo', 'unit': 'celsius', 'condition': 'sunny'}

Terserah kita untuk memanggil fungsi dengan argumen yang disediakan:

some_result = get_weather(**arguments)

Jika Anda ingin model menghasilkan argumen untuk fungsi dan memanggilnya sekaligus, Anda memerlukan agen AI. 

Kami memiliki tutorial LangChain Agents terpisah jika Anda tertarik.

Praktik Terbaik Saat Menggunakan OpenAI Structured Outputs

Saat menggunakan Structured Outputs, ada sejumlah praktik terbaik dan rekomendasi yang perlu diingat. Pada bagian ini, kami akan menguraikan beberapa di antaranya.

  1. Gunakan model Pydantic untuk mendefinisikan skema output, karena memberikan cara yang rapi dan aman tipe untuk mendefinisikan struktur output yang diharapkan.
  2. Jaga skema tetap sederhana dan spesifik untuk mendapatkan hasil yang paling akurat.
  3. Gunakan tipe data yang sesuai (str, int, float, bool, List, Dict) untuk merepresentasikan data Anda secara akurat.
  4. Gunakan tipe Literal untuk enum guna mendefinisikan nilai yang diizinkan secara spesifik untuk field.
  5. Tangani penolakan model. Saat menggunakan metode baru .parse(), objek pesan memiliki atribut baru .refusal untuk menunjukkan penolakan:
text = """John DoeEmail: john.doe@example.comPhone: 123-456-7890Addresses:- 123 Main St, Springfield, IL, 62701- 456 Elm St, Shelbyville, IL, 62702"""
user_info = extract_user_info(text)
if user_info.refusal:
   print(user_info.refusal)
else:
   print(user_info.content)

Output:

{"name":"John Doe","email":"john.doe@example.com","phone":"123-456-7890","addresses":[{"street":"123 Main St","city":"Springfield","state":"IL","zip_code":"62701"},{"street":"456 Elm St","city":"Shelbyville","state":"IL","zip_code":"62702"}]}

6. Berikan deskripsi yang jelas dan ringkas untuk setiap field dalam model Pydantic Anda guna meningkatkan ketepatan output model:

from pydantic import BaseModel, Field
class Person(BaseModel):
   name: str = Field(..., description="The person's full name")
   age: int = Field(..., description="The person's age in years")
   occupation: str = Field(..., description="The person's current job or profession")

Praktik-praktik ini akan sangat membantu memaksimalkan pemanfaatan Structured Outputs dalam aplikasi Anda.

Penutup

Dalam tutorial ini, kita telah mempelajari cara memulai dengan fitur baru OpenAI API: Structured Outputs. Kita telah melihat bagaimana fitur ini memaksa model bahasa untuk menghasilkan output dalam format yang kita tentukan. Kita telah mempelajari cara menggunakannya bersama function calling dan mengeksplorasi beberapa praktik terbaik untuk memaksimalkan fitur ini.

Berikut beberapa sumber terkait untuk menambah pemahaman Anda:

Structured Outputs FAQs

Bagaimana model Pydantic bekerja dengan Structured Outputs?

Model Pydantic digunakan untuk mendefinisikan skema struktur output yang diinginkan, yang kemudian diteruskan ke OpenAI API untuk menegakkan format respons.

Apakah Structured Outputs dapat digunakan dengan function calling?

Ya, Structured Outputs dapat digunakan dengan function calling untuk menyederhanakan proses pendefinisian parameter fungsi dan output yang diharapkan.

Apa manfaat menggunakan Structured Outputs?

Manfaatnya mencakup format respons yang konsisten, kebutuhan pasca-pemrosesan yang lebih sedikit, keandalan yang meningkat dalam aplikasi AI, dan integrasi yang lebih mudah dengan sistem yang ada.

Apakah ada keterbatasan dalam menggunakan Structured Outputs?

Meskipun kuat, Structured Outputs dapat membatasi fleksibilitas respons AI dan memerlukan perancangan skema yang cermat untuk menyeimbangkan struktur dengan tingkat detail yang diinginkan pada output.


Bexruz (Bex) Tuychiev's photo
Author
Bexruz (Bex) Tuychiev
LinkedIn

Saya adalah kreator konten data science dengan pengalaman lebih dari 2 tahun dan salah satu dengan jumlah pengikut terbesar di Medium. Saya suka menulis artikel mendalam tentang AI dan ML dengan sedikit gaya sarkastik—karena harus ada sesuatu untuk membuatnya tidak terlalu membosankan. Saya telah menghasilkan lebih dari 130 artikel dan satu kursus di DataCamp, dengan satu lagi sedang dalam proses. Konten saya telah dilihat oleh lebih dari 5 juta pasang mata, dan 20 ribu di antaranya menjadi pengikut di Medium dan LinkedIn. 

Topik
Kecerdasan Buatan
OpenAI

Kursus OpenAI Teratas

{count, plural, one {Kursus} other {Kursus}}

Bekerja dengan OpenAI API

{hours} jam
181.3K
Mulai perjalanan Anda mengembangkan aplikasi berbasis AI dengan OpenAI API. Pelajari fungsionalitas yang menjadi dasar aplikasi AI populer seperti ChatGPT.
Lihat DetailRight Arrow
Mulai Kursus
Lihat SelengkapnyaRight Arrow
Terkait

{count, plural, one {blog} other {blogs}}

12 Alternatif ChatGPT Terbaik yang Bisa Anda Coba pada 2026

Artikel ini menyajikan daftar alternatif ChatGPT yang akan meningkatkan produktivitas Anda.
Javier Canales Luna's photo

Javier Canales Luna

14 mnt

{count, plural, one {blog} other {blogs}}

Tutorial Korelasi di R

Dapatkan pengenalan dasar-dasar korelasi di R: pelajari lebih lanjut tentang koefisien korelasi, matriks korelasi, plotting korelasi, dan sebagainya.
David Woods's photo

David Woods

13 mnt

{count, plural, one {blog} other {blogs}}

40 Pertanyaan Wawancara DBMS Teratas di 2026

Kuasai pertanyaan wawancara basis data, dari konsep SQL dasar hingga skenario desain sistem tingkat lanjut. Panduan mendalam ini mencakup semua yang Anda perlukan untuk sukses di wawancara DBMS dan meraih peran berikutnya.
Dario Radečić's photo

Dario Radečić

15 mnt

{count, plural, one {blog} other {blogs}}

Spaghetti Plot dan Jalur Badai

Temukan alasan mengapa Anda sebaiknya (tidak) menggunakan spaghetti plot untuk menyampaikan ketidakpastian jalur prediksi badai serta dampaknya terhadap interpretasi.
Hugo Bowne-Anderson's photo

Hugo Bowne-Anderson

13 mnt

Lihat SelengkapnyaLihat Selengkapnya