Skip to main content
Setiap respons LLM membawa objek usage yang melaporkan token yang dikonsumsi oleh permintaan tersebut. Sunra melaporkan penggunaan dalam semantik endpoint yang Anda panggil: respons Messages mengikuti kontrak Anthropic, dan respons Chat Completions atau Responses mengikuti kontrak OpenAI. Bentuk-bentuk ini berbeda, dan itu disengaja. SDK OpenAI yang membaca respons Chat Completions mengasumsikan semantik OpenAI, dan SDK Anthropic yang membaca respons Messages mengasumsikan semantik Anthropic. Setiap endpoint menghormati apa yang dijanjikan oleh spesifikasinya sendiri alih-alih dipaksa masuk ke dalam satu bentuk bersama.
/v1/messages dan /v1/responses sama-sama menggunakan nama field input_tokens, dan artinya tidak sama pada keduanya. Pada Messages, itu hanya input baru. Pada Responses, itu adalah keseluruhan prompt, termasuk token cache.

Messages

Pada /v1/messages, ketiga bucket input saling eksklusif. Tidak ada token yang dihitung dua kali, sehingga total prompt adalah jumlah dari ketiganya:
integer
Hanya token input baru. Tidak termasuk kedua bucket cache.
integer
Token yang ditulis ke cache oleh permintaan ini.
integer
Token yang disajikan ke permintaan ini dari cache.
integer
Token yang dihasilkan oleh model.
integer
Ketiga bucket input ditambah output_tokens. Ada pada respons non-streaming.
Bucket yang tidak ada atau bernilai null dihitung sebagai nol.

Contoh perhitungan

Prefix 19.000 token yang sama dikirim dua kali ke claude-opus-4-8. Permintaan pertama menulis cache; permintaan kedua membacanya.
Permintaan dingin (penulisan cache)
Permintaan hangat (pembacaan cache)
input_tokens tetap 8 pada kedua permintaan, karena 8 adalah input yang benar-benar baru setiap kali. Prefix 19.349 token berpindah dari bucket pembuatan cache ke bucket pembacaan cache. Kedua permintaan sama-sama berjumlah total 19.359 token tetapi biayanya tidak sama: penulisan cache dan pembacaan cache dikenakan tarif per-token masing-masing, itulah sebabnya keduanya dilaporkan sebagai bucket terpisah.

Chat Completions dan Responses

Endpoint-endpoint ini melaporkan semantik OpenAI, tanpa perubahan. Jumlah prompt adalah keseluruhan prompt, dan token cache adalah subset darinya yang dilaporkan secara terpisah.
/v1/chat/completions
Menjumlahkan prompt_tokens dan cached_tokens menghasilkan penghitungan ganda. Untuk mendapatkan input baru pada endpoint ini, kurangkan:
Aturan yang sama berlaku untuk /v1/responses dengan input_tokens dan input_tokens_details.cached_tokens.

Penanda sunra_usage_semantics

Respons yang telah dinormalisasi oleh Sunra membawa sebuah penanda di dalam usage:
Penanda ini adalah sebuah janji tentang respons, bukan tentang event atau field mana pun secara individual. Pada respons tanpa streaming, penanda muncul di objek usage root; pada respons yang di-stream, penanda muncul di message_start, yaitu event yang membawa bucket input. Ketika penanda hadir dengan nilai ini, jaminan pada halaman ini berlaku: ketiga bucket input saling eksklusif, dan total_tokens — jika ada — adalah jumlah ketiganya ditambah output_tokens. Ketiadaannya juga merupakan sebuah janji. Sunra hanya menormalisasi bentuk respons yang telah diukurnya. Selain itu, respons diteruskan dari provider upstream tanpa disentuh dan dibiarkan tanpa penanda, dan respons tanpa penanda adalah respons yang bucket-bucketnya tidak dijamin oleh Sunra. Lakukan pemeriksaan terhadap penanda alih-alih memeriksa angka-angkanya untuk menebak konvensi mana yang diikuti sebuah respons. Menebak dari bentuk respons adalah hal yang ingin digantikan oleh field ini — heuristik seperti “bucket-bucket ini pasti eksklusif karena jumlahnya lebih besar dari jumlah prompt” dipenuhi oleh lebih dari satu konvensi dan pada akhirnya akan membaca sebuah respons secara keliru.
Hanya respons /v1/messages yang pernah membawa penanda ini. Chat Completions dan Responses mengikuti spesifikasi OpenAI dan tidak diberi penanda. Nilainya memiliki versi. Perubahan yang merusak pada makna field-field ini akan dirilis dengan nilai baru, sehingga pemeriksaan kesamaan terhadap anthropic.exclusive.v1 tidak akan diam-diam mulai membaca kontrak yang berbeda.

Streaming

Pada permintaan Messages yang di-stream, penggunaan tiba melalui dua event. message_start membawa sisi input dan penanda. message_delta terakhir hanya membawa output_tokens. Lakukan pemeriksaan terhadap penanda di message_start, lalu gabungkan kedua event seperti biasa — menerapkan usage dari event yang lebih akhir di atas event yang lebih awal — untuk memperoleh nilai-nilai yang didokumentasikan di atas. total_tokens dihilangkan dari respons yang di-stream. Tidak ada satu event pun yang mengetahui sisi input dan sisi output sekaligus, sehingga total apa pun yang dihitung di tengah stream akan salah. Jumlahkan sendiri bucket-bucket tersebut setelah stream selesai.

Migrasi dari perilaku sebelumnya

Sebelumnya Sunra meneruskan objek usage dari upstream secara verbatim pada /v1/messages. Lapisan penerjemahan di depan sebagian provider melipat token pembuatan cache ke dalam input_tokens, sehingga pemanggil yang mengikuti kontrak Anthropic dan menjumlahkan ketiga bucket menghitung token pembuatan cache dua kali.
  • Jika Anda menjumlahkan ketiga bucket, seperti yang dijelaskan oleh kontrak Anthropic, sekarang Anda sudah benar. Tidak ada perubahan yang diperlukan di sisi Anda.
  • Jika Anda melakukan kompensasi untuk perilaku lama — mengurangkan sendiri cache_creation_input_tokens dari input_tokens, atau merekayasa balik pelipatan itu dengan cara lain — hentikan. Koreksi tersebut kini mengurangkan token yang memang sudah dikecualikan dan akan membuat input Anda terlaporkan lebih rendah dari yang sebenarnya.
  • Jika Anda membaca total_tokens, field ini tetap melaporkan hitungan penuh: input baru, kedua bucket cache, dan output.
Kendalikan perubahan ini berdasarkan penanda, bukan berdasarkan tanggal deploy, sehingga jalur kode yang sama tetap benar baik untuk respons yang bertanda maupun yang tidak bertanda.