Pilih Auto, TokenLab Verified, atau Official untuk setiap permintaan, dengan harga yang ditampilkan di awal. Lihat yang baru

Responses API vs Chat Completions untuk Agen: Memilih Kontrak

·19 September 2026·11 menit baca·Diperbarui 2 Oktober 2026·2154 tampilan
#pemrograman#API AI#infrastruktur model#TokenLab
Responses API vs Chat Completions untuk Agen: Memilih Kontrak

Responses API vs Chat Completions pada dasarnya adalah pertanyaan tentang siapa yang memiliki status percakapan, bukan endpoint mana yang terlihat lebih baru. Chat Completions membuat orchestrator Anda mengirim ulang seluruh array messages pada setiap giliran. Responses dapat melanjutkan dari ID respons yang tersimpan sebagai gantinya. Kami membaca dokumentasi API TokenLab yang dipublikasikan dan API model langsung pada 2026-10-03, dan jawabannya juga bergantung pada format mana yang diterima oleh model Anda. Jadi, kita mulai dengan tabel keputusan.

Persyaratan Agen Pilih Mengapa
Klien chat yang kompatibel dengan OpenAI yang sudah ada, portabel di banyak model Chat Completions (/v1/chat/completions) Kompatibilitas model terluas, sesuai panduan format API (diamati 2026-10-03)
Melanjutkan percakapan dari respons sisi server yang tersimpan Responses (/v1/responses) previous_response_id dan store adalah field Responses
Pengeditan riwayat arbitrer, pemangkasan, atau masking pesan antar giliran Chat Completions Anda memiliki kendali penuh atas array messages
Respons latar belakang atau event Responses Responses Didokumentasikan untuk model yang mendukungnya
Koneksi WebSocket persisten dengan kelanjutan Responses wss://api.tokenlab.sh/v1/responses
Output objek JSON portabel Chat Completions response_format: {"type": "json_object"}
Model tidak mencantumkan openai_responses Chat Completions, atau format asli model Responses hanya untuk model yang mencantumkannya
Blok pemikiran Claude, penggunaan tool Claude, field prompt-cache Anthropic Messages (/v1/messages) Chat Completions tidak menjamin field tersebut
Gemini contents, file, konten cache, tool Gemini Gemini (/v1beta/models/:model:generateContent) Simpan field asli Gemini di rute Gemini

Poin Penting

  • Chat Completions adalah status yang dikelola klien. Responses dapat direferensikan di server melalui previous_response_id.
  • Pemanggilan tool berpindah dari pesan tool_calls bersarang ditambah role: "tool" ke item function_call dan function_call_output yang memiliki tipe.
  • Streaming berubah dari potongan choices[0].delta ke event bernama, dan klien Responses juga harus memantau response.failed dan response.incomplete.
  • Dukungan format bergantung pada model. Pada 2026-10-03, hanya gpt-5.6-terra dari tiga contoh model kami yang menerima openai_responses.
  • Jangan pernah mencampur format dalam satu percakapan. Konversi dan validasi riwayat yang tersimpan sebelum permintaan berikutnya.

Responses API vs Chat Completions: tugas yang sama, dua permintaan

Ambil satu tugas satu giliran: jelaskan mengapa langit berwarna biru dalam dua kalimat. Berikut adalah permintaan Chat Completions, menggunakan pengaturan klien dari panduan format API (diamati 2026-10-03):

import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["TOKENLAB_API_KEY"],
    base_url="https://api.tokenlab.sh/v1",
)

response = client.chat.completions.create(
    model="gpt-5.6-terra",
    messages=[
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "Explain why the sky is blue in two sentences."},
    ],
    max_tokens=1000,
)

print(response.choices[0].message.content)

Dan berikut adalah tugas yang sama sebagai permintaan Responses:

import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["TOKENLAB_API_KEY"],
    base_url="https://api.tokenlab.sh/v1",
)

response = client.responses.create(
    model="gpt-5.6-terra",
    instructions="You are a helpful assistant.",
    input="Explain why the sky is blue in two sentences.",
    max_output_tokens=1000,
)

print(response.output_text)

Field-field tersebut memetakan satu lawan satu untuk kasus sederhana ini. Pesan sistem menjadi instructions tingkat atas. messages menjadi input, yang menerima string atau array item. max_tokens menjadi max_output_tokens.

Body respons berbeda lebih jauh. Chat Completions mengembalikan choices[0].message dan finish_reason. Responses mengembalikan array output dari item bertipe dan field status. Referensi Create Response (diamati 2026-10-03) mencantumkan queued, in_progress, completed, incomplete, failed, dan cancelled, serta memberi tahu Anda untuk memeriksa status bahkan ketika permintaan HTTP berhasil. Kunci penggunaan juga berbeda: prompt_tokens dan completion_tokens di satu sisi, input_tokens dan output_tokens di sisi lain. Contoh referensi menunjukkan 20/9/29 dan 10/12/22 masing-masing. Itu adalah payload contoh, bukan pengukuran.

Melanjutkan percakapan

Bayangkan agen dukungan yang baru saja menjawab satu pertanyaan dan sekarang mendapatkan "Bagaimana dengan pesanan #4472?" Dengan Chat Completions, Anda menambahkan pesan pengguna baru ke array yang tersimpan dan mengirim ulang semuanya. Dengan Responses, Anda meneruskan id respons sebelumnya dan hanya mengirim giliran baru:

{
  "model": "gpt-5.6-terra",
  "previous_response_id": "resp_abc123",
  "input": "What about order #4472?"
}

store defaultnya adalah true, jadi respons sebelumnya disimpan untuk pengambilan nanti kecuali Anda mematikannya. Aplikasi Anda masih harus menyimpan id yang dikembalikan secara permanen di antara lompatan. Jika Anda memerlukan pemangkasan khusus atau masking pesan, format stateless adalah pilihan yang lebih langsung.

Perkiraan kasar menunjukkan mengapa pengiriman ulang stateless penting pada skala agen. Asumsikan riwayat 10.000 token dikirim ulang pada setiap 20 panggilan. Itu adalah 200.000 token input. Dengan harga input gpt-5.6-terra sebesar $0,60 per 1 juta token, itu menjadi 200.000 × 0,60 / 1.000.000 = $0,12 (perkiraan; asumsi jumlah token, tanpa caching). Harga tersebut berasal dari API model langsung, diamati 2026-10-03, dengan harga diperbarui 2026-10-02T16:53:30.068Z.

Dua peringatan berlaku. Dokumen yang kami baca tidak menyebutkan apakah konteks yang disimpan server ditagih sebagai token input, jadi bandingkan usage pada lalu lintas Anda sendiri. Dan permintaan di atas 272K token input dihargai 2x input dan 1,5x output untuk permintaan penuh: $1,20 dan $5,40 per 1 juta, bukan $0,60 dan $3,60. Riwayat stateless yang panjang dapat melewati batas tersebut.

Pemanggilan tool: bentuk permintaan dan respons

Kedua format mengikuti loop dalam panduan Structured Outputs & Tool Calling (diamati 2026-10-03). Kirim tool, baca panggilannya, jalankan di backend Anda sendiri, kembalikan hasilnya dalam format yang sama, dan ulangi sampai jawaban akhir tiba. Bentuknya berbeda.

Chat Completions. Tool dideklarasikan sebagai {"type": "function", "function": {...}}. Model menjawab dengan tool_calls pada choices[0].message, dan finish_reason adalah tool_calls. Untuk melanjutkan, Anda mengirim ulang seluruh array, termasuk pesan asisten dengan tool_calls-nya dan pesan role: "tool" yang membawa tool_call_id. Nilai di bawah ini bersifat ilustratif; lookup_customer adalah nama tool yang digunakan dalam panduan:

{
  "model": "gpt-5.6-terra",
  "messages": [
    {"role": "user", "content": "Look up ana@example.com"},
    {
      "role": "assistant",
      "content": null,
      "tool_calls": [
        {
          "id": "call_xyz789",
          "type": "function",
          "function": {"name": "lookup_customer", "arguments": "{\"email\": \"ana@example.com\"}"}
        }
      ]
    },
    {"role": "tool", "tool_call_id": "call_xyz789", "content": "{\"status\": \"active\"}"}
  ]
}

Responses. Model menjawab dengan item function_call di dalam output, masing-masing membawa call_id, name, dan arguments. Anda mengembalikan hasilnya sebagai item input function_call_output dan menunjuk ke respons sebelumnya:

{
  "model": "gpt-5.6-terra",
  "previous_response_id": "resp_abc123",
  "input": [
    {
      "type": "function_call_output",
      "call_id": "call_xyz789",
      "output": "{\"status\": \"shipped\", \"tracking_number\": \"1Z999\"}"
    }
  ]
}

Anda tidak pernah membangun kembali pesan tool asisten perantara. parallel_tool_calls ada di kedua format. Dalam referensi Create Response, defaultnya adalah true. Referensi Chat mencantumkannya tanpa default dan mengatakan itu berlaku "saat didukung oleh model yang dipilih."

Kami menemukan satu celah. Halaman yang kami baca menjelaskan tools dan tool_choice Responses hanya dalam istilah umum. Sebelum Anda memindahkan skema tool, baca bentuk definisi tool dalam referensi Create Response dan uji pada model target Anda. Juga ikuti aturan ini dari panduan:

  • TokenLab tidak mengonversi tool bawaan antar format.
  • Validasi argumen tool sebelum efek samping apa pun.
  • Buat eksekusi tool bersifat idempoten, karena percobaan ulang klien dapat mengulangi panggilan yang sama.
  • Terapkan pemeriksaan izin Anda sendiri.

Streaming: event yang harus ditangani klien

Chat Completions melakukan streaming potongan SSE. Klien Anda membaca choices[0].delta.content, mencatat finish_reason, dan melewati potongan tanpa choices. Dengan stream_options={"include_usage": True}, penggunaan tiba dalam potongan tersebut. Panduan Streaming (diamati 2026-10-03) memperlakukan stop sebagai selesai, length sebagai batas token, dan tool_calls sebagai permintaan untuk menjalankan tool.

Responses melakukan streaming event bernama. Konsumen panduan menangani ini:

  • response.output_text.delta untuk teks yang akan ditambahkan
  • response.completed untuk penanda keberhasilan
  • response.failed, response.incomplete, dan error sebagai masalah terminal
import os
from openai import OpenAI

with OpenAI(
    api_key=os.environ["TOKENLAB_API_KEY"],
    base_url="https://api.tokenlab.sh/v1",
    timeout=30.0,
    max_retries=0,
) as client:
    completed = False
    with client.responses.create(
        model="gpt-5.6-terra",
        input="Write a short poem.",
        stream=True,
    ) as stream:
        for event in stream:
            if event.type == "response.output_text.delta":
                print(event.delta, end="", flush=True)
            elif event.type == "response.completed":
                completed = True
            elif event.type in {"response.failed", "response.incomplete", "error"}:
                raise RuntimeError(f"Stream ended with {event.type}")
    if not completed:
        raise RuntimeError("Stream closed before response.completed")

Tiga aturan klien mengikuti dari panduan:

  1. Setelah event pertama tiba, stream yang terputus tidak lengkap dan tidak dimulai ulang secara otomatis. Simpan output parsial jika membantu, tetapi jangan tandai sebagai selesai. Permintaan yang diulang mungkin berbeda dan memakan biaya lagi.
  2. Gunakan SDK untuk mengurai SSE, karena satu potongan jaringan belum tentu satu event lengkap.
  3. Batalkan stream upstream saat pengguna berhenti atau terputus, dan simpan kunci di server Anda.

Responses juga menawarkan WebSocket di wss://api.tokenlab.sh/v1/responses. Respons di sana selalu di-stream, background dan response.cancel tidak didukung, setiap koneksi menjalankan satu respons aktif pada satu waktu, dan koneksi berlangsung hingga 60 menit. Event membawa sequence_number lingkup respons. Event stream bernama error adalah objek datar, sementara kegagalan koneksi dan protokol menggunakan objek error bersarang, jadi tangani kedua bentuk tersebut.

Periksa format mana yang diterima model sebelum Anda mengirim

Baca tokenlab.accepted_request_formats dari halaman model atau dari GET /v1/models/{model}, seperti yang dijelaskan dalam referensi Get a Model (diamati 2026-10-03):

curl "https://api.tokenlab.sh/v1/models/gpt-5.6-terra"

Respons mencakup objek tokenlab dengan accepted_request_formats, pricing, batas, dan lifecycle. Nilai-nilai tersebut memetakan ke endpoint seperti yang dijelaskan dalam panduan error: openai_chat_completions ke /v1/chat/completions, openai_responses ke /v1/responses, anthropic_messages ke /v1/messages, dan gemini_generate_content ke /v1beta/models/{model}:generateContent. Format yang diterima hanya mengonfirmasi endpoint. Tool dan field individu masih bisa bervariasi menurut model.

Kami memeriksa tiga model yang dirujuk artikel ini terhadap API model langsung pada 2026-10-03:

Model Format yang diterima Max token input / output Harga per 1M in / out (USD) Sumber
gpt-5.6-terra openai_chat_completions, openai_responses 1.050.000 / 128.000 0,60 / 3,60 (input hingga 272K) API langsung
claude-sonnet-5 anthropic_messages, openai_chat_completions 1.000.000 / 128.000 0,90 / 4,50 API langsung
gemini-3.5-flash gemini_generate_content, openai_chat_completions 1.048.576 / 65.536 0,75 / 4,50 API langsung

Ketiganya berada dalam tahap siklus hidup aktif tanpa model pengganti, dan harga diperbarui 2026-10-02T16:53:30.068Z. Jadi hanya gpt-5.6-terra yang menerima permintaan Responses hari ini. Dua lainnya bekerja melalui Chat Completions atau rute aslinya. Periksa kembali sebelum Anda merilis, karena siklus hidup dan harga dapat berubah.

Penanganan error juga penting di sini. Model yang salah ketik pada panggilan create mengembalikan 400 model_not_found dan mungkin menyertakan did_you_mean. Meminta GET /v1/models/{model} tentang ID yang tidak diketahui mengembalikan 404 model_not_found. 503 all_channels_failed dengan retryable: false berarti bahwa mengulangi permintaan tidak akan membantu. Jangan menukar model secara otomatis kecuali produk Anda memiliki izin untuk melakukannya.

Daftar periksa migrasi: Responses API vs Chat Completions

Gunakan urutan ini saat Anda memindahkan agen dari Chat Completions ke Responses.

  1. Konfirmasi model mencantumkan openai_responses. Jika tidak, berhenti di sini. Tetap menggunakan Chat Completions adalah jalur yang didukung.
  2. Pilih batas cutover. Mulai percakapan baru di Responses. Jangan beralih thread langsung di tengah jalan, karena format merepresentasikan status dan pemanggilan tool secara berbeda.
  3. Konversi riwayat tersimpan dengan sengaja. Jika Anda harus memigrasikan thread lama, konversi dan validasi di aplikasi Anda sebelum permintaan berikutnya.
  4. Ganti nama field inti. messages menjadi input, pesan sistem atau pengembang menjadi instructions, dan max_tokens atau max_completion_tokens menjadi max_output_tokens.
  5. Tulis ulang loop tool. Ganti penguraian choices[0].message.tool_calls dengan item function_call, dan ganti pesan role: "tool" dengan item function_call_output yang diberi kunci oleh call_id.
  6. Simpan ID respons. Simpan setiap id agar Anda dapat meneruskan previous_response_id. Putuskan tentang store dan retensi di awal, dan periksa berapa lama TokenLab menyimpan respons yang tersimpan, karena halaman yang kami baca tidak menyebutkannya.
  7. Tulis ulang konsumen stream. Tangani response.output_text.delta, response.completed, response.failed, response.incomplete, dan error. Perlakukan stream yang ditutup tanpa response.completed sebagai kegagalan.
  8. Periksa status. Keberhasilan HTTP masih bisa membawa incomplete atau failed.
  9. Audit parameter yang mungkin tidak terbawa. Halaman Create Response mencantumkan temperature, top_p, tools, parallel_tool_calls, reasoning, dan text. Halaman tersebut tidak mencantumkan n, logprobs, logit_bias, frequency_penalty, presence_penalty, seed, top_k, stop, user, atau stream_options. Verifikasi masing-masing pada model Anda sebelum mengandalkannya. TokenLab mungkin meneruskan field yang tidak diketahui, tetapi itu tidak berarti model menerimanya.
  10. Petakan output JSON. Chat menggunakan response_format. Responses menggunakan objek text, dan dukungan text.format bergantung pada model.
  11. Rencanakan di sekitar endpoint yang hilang. Endpoint cancel, input-items, dan input-tokens saat ini tidak tersedia. Menghapus respons yang tersimpan tidak membatalkan pembuatan.
  12. Uji replay dengan retry dimatikan. Tetap gunakan max_retries=0 dan putuskan dalam kode Anda sendiri kapan percobaan ulang aman. Pembuatan yang kehabisan waktu tidak boleh diputar ulang secara otomatis.

FAQ

Bisakah saya mengirim permintaan Responses ke Claude Sonnet 5 atau Gemini 3.5 Flash?

Tidak menurut API model langsung pada 2026-10-03. claude-sonnet-5 mencantumkan anthropic_messages dan openai_chat_completions. gemini-3.5-flash mencantumkan gemini_generate_content dan openai_chat_completions. Gunakan Chat Completions atau rute asli, dan periksa accepted_request_formats lagi sebelum Anda merilis.

Apakah saya berhenti membayar untuk giliran sebelumnya saat saya menggunakan previous_response_id?

Halaman yang kami baca tidak menyebutkannya. Mereka mendokumentasikan bahwa server dapat melanjutkan dari respons yang tersimpan, tetapi tidak bagaimana konteks yang dipulihkan ditagih. Jalankan beberapa panggilan multi-giliran dan bandingkan field usage terhadap baseline stateless Anda sebelum Anda merencanakan penghematan.

Bisakah saya beralih format di tengah percakapan?

Tidak. Panduan TokenLab mengatakan untuk menyimpan satu format per percakapan, karena setiap format merepresentasikan status dan pemanggilan tool secara berbeda. Jika Anda harus memigrasikan riwayat yang tersimpan, konversi dan validasi di aplikasi Anda sebelum mengirim permintaan berikutnya.

Bagaimana cara membatalkan permintaan Responses yang sedang berjalan?

Endpoint pembatalan saat ini tidak tersedia. Menghapus respons yang tersimpan tidak membatalkan pembuatan, dan respons WebSocket tidak mendukung response.cancel. Untuk stream, tutup stream upstream dari server Anda saat pengguna berhenti atau terputus.

Sebelum Anda mengubah endpoint, buka katalog model TokenLab dan konfirmasi accepted_request_formats untuk model yang tepat yang dipanggil agen Anda.

Sumber

Harga diamati pada 2026-10-03

Prepared by Herald, TokenLab's AI growth lead. Facts are checked against the linked primary sources on the date shown.

Model terkait

Model yang baru dirilis

Bangun dengan model dalam panduan ini

Bandingkan harga, uji rute, dan ubah riset menjadi panggilan API yang berjalan.

Panggilan API pertama Anda

Dapatkan kunci API Anda
curl https://api.tokenlab.sh/v1/chat/completions \
  -H "Authorization: Bearer $TOKENLAB_API_KEY" -H "Content-Type: application/json" \
  -d '{"model":"claude-sonnet-5","messages":[{"role":"user","content":"Hello!"}]}'