Responses API vs Chat Completions: Perbedaan dan Panduan Migrasi Praktis (2026)
Responses API vs Chat Completions: Perbedaan dan Panduan Migrasi Praktis (2026)
OpenAI merekomendasikan Responses API untuk semua proyek baru sembari menyatakan Chat Completions tetap didukung. Kedua endpoint akan berdampingan lama, tapi struktur field, manajemen state, dan sistem tool-nya berbeda. Panduan ini memecah perbedaan menjadi empat dimensi, menunjukkan kode yang tepat diubah saat migrasi, dan ditutup tabel keputusan per skenario — semua contoh berjalan langsung di endpoint EXAIV
Definisi: Responses API adalah antarmuka terpadu OpenAI yang diperkenalkan setelah Chat Completions: input berupa array input, output berupa daftar item output bertipe, status percakapan disimpan sisi server secara bawaan (store), dan hosted tools seperti web search, file search, serta code interpreter sudah tertanam. Chat Completions adalah protokol tanpa status: setiap request membawa seluruh riwayat messages dan klien mengelola konteksnya sendiri.
Satu tabel untuk semua perbedaan inti
| Dimensi | Chat Completions | Responses API |
|---|---|---|
| Endpoint | /v1/chat/completions | /v1/responses |
| Field input | Array messages | input (string atau array pesan) |
| Bentuk output | choices[0].message.content | Daftar output bertipe, baca output_text |
| Manajemen state | Tanpa status; klien kirim ulang seluruh riwayat | store: true bawaan; previous_response_id merangkai giliran |
| Hosted tools | Tidak ada | web search, file search, code interpreter, computer use, remote MCP |
| Definisi function | Format tools lama | Format baru — mirip tapi tidak identik |
| Beberapa kandidat | Mendukung n > 1 | Dihapus; satu hasil saja |
Posisi resmi
Ketegasan OpenAI: "Chat Completions tetap didukung; Responses direkomendasikan untuk semua proyek baru." Tidak ada tenggat migrasi paksa, tapi kemampuan baru — hosted tools, kelanjutan reasoning — hanya hadir di sisi Responses. Titik referensi: Assistants API dimatikan 26 Agustus 2026, jadi arah konvergensi ke Responses jelas.
Perbandingan kode: tugas sama, dua bentuk
Chat Completions (endpoint EXAIV /api/ai/v1/chat/completions):
curl https://exaiv.com/api/ai/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
-d '{
"model": "gpt-6-sol",
"messages": [
{ "role": "user", "content": "Jelaskan apa itu AI gateway dalam satu kalimat." }
]
}'
Responses API (endpoint EXAIV /api/ai/v1/responses):
curl https://exaiv.com/api/ai/v1/responses \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
-d '{
"model": "gpt-6-sol",
"input": "Jelaskan apa itu AI gateway dalam satu kalimat."
}'
Di lapisan SDK: client.chat.completions.create(...) menjadi client.responses.create(...); pembacaan hasil berubah dari completion.choices[0].message.content menjadi response.output_text. Referensi lengkap: Chat Completions dan Responses
Migrasi empat langkah
messages→input: request teks polos langsung kirim string; request bersejarah ganti nama arraymessagesmenjadiinput, struktur role/content tetap- Ubah jalur hasil:
choices[0].message.content→ iterasioutputsaringtype === "message", atau pakai field praktisoutput_text - Pindahkan system prompt ke
instructions: pesanrole: "system"di Chat punya parameter level atas tersendiri di Responses - Tulis ulang definisi tool: kedua format serupa tapi tidak identik — periksa field per field. Hosted tools Responses (web_search dll.) diaktifkan dengan nama, tanpa orkestrasi sendiri
Event streaming berbeda
Kedua endpoint streaming via SSE, tetapi jenis event-nya sama sekali berbeda (Chat memancarkan delta generik; Responses memancarkan event bernama seperti response.output_text.delta). Parser SSE perlu perubahan tersendiri saat migrasi.
Memilih mana, per skenario
| Skenario | Rekomendasi | Alasan |
|---|---|---|
| Kode lama masih berjalan baik | Tetap Chat Completions | Tidak ada tanggal penghentian; migrasi alur demi alur |
| Proyek baru, agen multi-langkah, butuh hosted tools | Responses | Hosted tools + status sisi server memangkas satu lapis orkestrasi |
| Kode harus jalan di banyak penyedia model | Chat Completions | Standar de facto industri, kompatibilitas terluas |
| Banyak kandidat per request (n > 1) | Chat Completions | Responses sudah menghapus parameter ini |
EXAIV menyediakan kedua endpoint dengan API key yang sama, jadi tidak perlu memilih pihak selamanya: trafik lama tetap Chat Completions, fitur baru pakai Responses, dan ganti model dasar dari halaman model
Mengapa ada dua interface
Konteks evolusi membantu pengambilan keputusan. Chat Completions adalah interface awal OpenAI; karena bentuknya sederhana dan lintas penyedia, ia menjadi standar de facto yang ditiru seluruh industri — hampir semua vendor model hari ini menyediakan endpoint bergaya messages. Responses API adalah desain ulang OpenAI untuk era agen: "model mungkin perlu melakukan beberapa hal" (memanggil tool, mencari, menjalankan kode) menjadi warga kelas satu di lapisan interface, dengan manajemen state dan eksekusi tool kembali ke sisi server. Keduanya menyasar skenario berbeda — itulah mengapa mereka berdampingan.
Tabel peta parameter siap pakai
Korespondensi yang paling sering dipakai saat migrasi:
| Chat Completions | Responses API | Catatan |
|---|---|---|
messages | input | Teks polos bisa langsung string |
role: "system" | instructions | System prompt punya parameter sendiri |
choices[0].message.content | output_text / iterasi output | Jalur baca hasil berbeda |
max_tokens | max_output_tokens | Nama baru, makna serupa |
response_format | text.format | Structured output, bentuknya berubah |
tools + tool_choice | tools format baru | Peran mirip, periksa field per field |
n (banyak kandidat) | Dihapus | Kalau perlu, tetap di Chat Completions |
| — | store / previous_response_id | Kemampuan state khas Responses |
Field yang presisi ada di dokumen referensi; periksa satu per satu saat migrasi.
Manajemen state mendalam: store dan previous_response_id
Inilah perbedaan filosofi terdalam antara dua generasi. Chat Completions berasumsi "server tidak mengingat apa pun": setiap giliran Anda mengirim ulang seluruh riwayat, dan pengelolaan context window serta kendali biaya ada di klien. Responses API menyimpan percakapan di sisi server secara bawaan (store: true); giliran berikutnya cukup merujuk previous_response_id, dan server melanjutkan dengan percakapan serta tool context yang utuh.
Konsekuensi praktis bagi developer:
- Kode berkurang: modul yang merawat array messages, memangkas riwayat, dan memadatkan context bisa dihapus
- Token berkurang: server memakai ulang context yang ada; biaya kirim ulang lenyap
- Perhatikan kepatuhan: data percakapan tersimpan di sisi server; tim dengan syarat data-residency bisa memakai
store: false, dengan konsekuensi kembali ke mode kirim penuh tiap giliran
Lima jebakan migrasi yang sering terjadi
- Hasil kosong: jalur baca belum diubah — konten sekarang ada di
output, bukanchoices[0].message.content - Tool call gagal diam-diam: format definisi tools kedua generasi berbeda; menyalin field mentah gagal tanpa suara — periksa satu per satu
- Parser SSE rusak: jenis event benar-benar berbeda; logika
deltatidak bisa dipakai untukresponse.output_text.delta - Error multi-kandidat: parameter
ndihapus di Responses; logika yang bergantung padanya perlu ditulis ulang atau tetap di Chat - Kebocoran state:
storeaktif secara bawaan, data uji ikut tersimpan — skenario sensitif data matikan secara eksplisit
FAQ
Migrasi streaming, event demi event
Nama event adalah tempat sebagian besar waktu migrasi benar-benar habis. Peta singkatnya:
| Kejadian | Event Chat Completions | Event Responses |
|---|---|---|
| Sepotong jawaban tiba | chat.completion.chunk (delta) | response.output_text.delta |
| Model ingin memanggil tool | delta tool_calls di dalam chunk | response.output_item.added (type: function_call) |
| Tool mengembalikan hasil | Anda append message dan request ulang | item function_call_output, lanjut dalam panggilan yang sama |
| Stream berakhir | data: [DONE] | response.completed |
Dua perbedaan struktural untuk dicerna: delta sisi Chat adalah fragmen anonim yang Anda rakit sendiri, sementara event Responses menyebutkan apa yang dibawanya; dan di Responses, satu giliran multi-tool adalah satu siklus request, bukan beberapa putaran request/response. Parser SSE, logika retry, dan penanganan timeout semuanya perlu ditulis ulang terhadap nama event baru — bagian inilah yang selalu lebih mahal dari perkiraan.
Memakai Responses lewat gateway
Tiga hal yang layak diketahui ketika endpoint diproxy:
- Hosted tools dieksekusi di hulu: web search, code interpreter dan kawan-kawan berjalan di sisi OpenAI; gateway meneruskan request dan mengalirkan hasilnya kembali tanpa disentuh
- State sisi server tetap di hulu:
previous_response_idmerujuk state yang tersimpan di sisi OpenAI; gateway meneruskannya secara transparan - Key dan penagihan milik gateway: satu key EXAIV berlaku untuk kedua endpoint, ditagih per model dan token tanpa memandang endpoint — harga live di halaman harga
Checklist pra-migrasi
Lima pertanyaan berurutan — berhenti di jawaban "belum" pertama dan perbaiki lapisan itu lebih dulu:
- Apakah panggilan teks polos berhasil di endpoint baru (tanpa tool, tanpa streaming)?
- Apakah jalur pembacaan hasil mengembalikan teks sungguhan (bukan
undefined)? - Apakah definisi tool ter-parse tanpa error skema?
- Apakah satu putaran tool penuh selesai (panggil → jalankan → lanjut)?
- Apakah streaming merender penuh dari awal sampai akhir dengan nama event baru?
Garis waktu migrasi yang realistis
Untuk codebase menengah dengan tools dan streaming, begini wujudnya migrasi tenang selama tiga hari:
Hari pertama — teks saja. Arahkan salinan satu alur ke endpoint baru. messages menjadi input, jalur hasil menjadi output_text. Jalankan test suite yang sudah ada. Kebanyakan tim menemukan panggilan teks polos lolos tanpa kejutan; tujuan hari ini hanya membuktikan transportnya berfungsi.
Hari kedua — tools. Tulis ulang satu definisi tool dalam format baru dan jalankan satu putaran penuh: model meminta panggilan, Anda mengeksekusinya, Anda melanjutkan giliran yang sama. Siapkan diri menghabiskan sebagian besar hari di sini — inilah pekerjaan pemetaan field yang diperingatkan tabel-tabel di atas. Pastikan error tool muncul dengan benar, bukan senyap.
Hari ketiga — streaming. Ganti parser SSE ke event bernama. Render end-to-end di UI asli Anda. Retry dan timeout disetel mengikuti perilaku nyata, bukan asumsi.
Apa yang sengaja dihindari garis waktu ini: memigrasi semua alur sekaligus, menulis ulang orkestrasi yang bisa tetap di Chat Completions kuartal depan, dan menguji streaming terakhir di hari Jumat. Trafik bisa bergeser alur demi alur — lewat gateway, per request — selama kedua endpoint berjalan paralel.
FAQ
Skala upaya: kapan menahan diri untuk tidak migrasi
Tidak semua kode layak dimigrasi bulan ini, dan mengakuinya juga bagian dari rencana yang baik. Tiga sinyal untuk menahan diri:
- Tidak ada kebutuhan hosted tools: jika alur Anda murni teks masuk-teks keluar dengan orkestrasi sendiri yang stabil, nilai migrasinya murni masa depan — nyata tapi tidak mendesak
- Bergantung pada
n > 1: parameter itu tidak ada di Responses; menulis ulang logika pemilihan kandidat adalah proyek tersendiri - Kontrak keluaran ketat: jika parser Anda mengharapkan bentuk
choicesdi banyak tempat, biaya sentuhan luas melebihi manfaat hari ini
Catatkan alur-alur itu, kunci ujiannya, dan tinjau kembali per kuartal. Kedua endpoint tidak akan pergi ke mana-mana.