Langsung ke konten utama
Claude Agent SDK menyediakan informasi penggunaan token yang terperinci untuk setiap interaksi dengan Claude. Panduan ini menjelaskan cara melacak penggunaan dengan benar dan memahami pelaporan biaya, terutama ketika menangani penggunaan alat paralel dan percakapan multi-langkah. Untuk dokumentasi API lengkap, lihat referensi SDK TypeScript dan referensi SDK Python.
Bidang total_cost_usd dan costUSD adalah perkiraan sisi klien, bukan data penagihan yang berwenang. SDK menghitungnya secara lokal dari tabel harga yang disertakan pada waktu pembuatan, sehingga dapat menyimpang dari apa yang sebenarnya Anda ditagih ketika:
  • harga berubah
  • versi SDK yang diinstal tidak mengenali model
  • aturan penagihan berlaku yang tidak dapat dimodelkan oleh klien
Gunakan bidang ini untuk wawasan pengembangan dan anggaran perkiraan. Untuk penagihan yang berwenang, gunakan Usage and Cost API atau halaman Penggunaan di Claude Console. Jangan menagih pengguna akhir atau memicu keputusan keuangan dari bidang ini.

Pahami penggunaan token

SDK TypeScript dan Python mengekspos data penggunaan yang sama dengan nama bidang yang berbeda:
  • TypeScript menyediakan rincian token per-langkah pada setiap pesan asisten (message.message.id, message.message.usage), biaya per-model melalui modelUsage pada pesan hasil, dan total kumulatif pada pesan hasil.
  • Python menyediakan rincian token per-langkah pada setiap pesan asisten (message.usage, message.message_id), biaya per-model melalui model_usage pada pesan hasil, dan total yang terakumulasi pada pesan hasil (total_cost_usd dan dict usage).
Kedua SDK menggunakan model biaya yang sama dan mengekspos granularitas yang sama. Perbedaannya adalah dalam penamaan bidang dan di mana penggunaan per-langkah bersarang. Pelacakan biaya bergantung pada pemahaman tentang bagaimana SDK membatasi data penggunaan:
  • Panggilan query(): satu invokasi fungsi query() SDK. Satu panggilan dapat melibatkan beberapa langkah (Claude merespons, menggunakan alat, mendapatkan hasil, merespons lagi). Setiap panggilan menghasilkan satu pesan result di akhir.
  • Langkah: satu siklus permintaan/respons dalam panggilan query(). Setiap langkah menghasilkan pesan asisten dengan penggunaan token.
  • Sesi: serangkaian panggilan query() yang ditautkan oleh ID sesi (menggunakan opsi resume). Setiap panggilan query() dalam sesi melaporkan biayanya sendiri secara independen.
Diagram berikut menunjukkan aliran pesan dari satu panggilan query(), dengan penggunaan token dilaporkan pada setiap langkah dan perkiraan kumulatif di akhir: Diagram menunjukkan query menghasilkan dua langkah pesan. Langkah 1 memiliki empat pesan asisten yang berbagi ID dan penggunaan yang sama (hitung sekali), Langkah 2 memiliki satu pesan asisten dengan ID baru, dan pesan hasil akhir menunjukkan total_cost_usd yang diperkirakan.
1

Setiap langkah menghasilkan pesan asisten

Ketika Claude merespons, ia mengirim satu atau lebih pesan asisten. Di TypeScript, setiap pesan asisten berisi BetaMessage bersarang (diakses melalui message.message) dengan id dan objek usage dengan hitungan token (input_tokens, output_tokens). Di Python, dataclass AssistantMessage mengekspos data yang sama secara langsung melalui message.usage dan message.message_id. Ketika Claude menggunakan beberapa alat dalam satu giliran, semua pesan dalam giliran itu berbagi ID yang sama, jadi deduplikasi berdasarkan ID untuk menghindari penghitungan ganda.
2

Pesan hasil memberikan perkiraan kumulatif

Ketika panggilan query() selesai, SDK memancarkan pesan hasil dengan total_cost_usd dan usage kumulatif. Ini tersedia di TypeScript (SDKResultMessage) dan Python (ResultMessage). Jika Anda membuat beberapa panggilan query() (misalnya, dalam sesi multi-giliran), setiap hasil hanya mencerminkan biaya panggilan individual itu. Jika Anda hanya membutuhkan total yang diperkirakan, Anda dapat mengabaikan penggunaan per-langkah dan membaca nilai tunggal ini.

Dapatkan biaya total dari query

Pesan hasil (TypeScript, Python) menandai akhir dari loop agen untuk panggilan query(). Ini mencakup total_cost_usd, biaya perkiraan kumulatif di semua langkah dalam panggilan itu. Ini berfungsi untuk hasil sukses dan kesalahan. Jika Anda menggunakan sesi untuk membuat beberapa panggilan query(), setiap hasil hanya mencerminkan biaya panggilan individual itu. Contoh berikut mengulangi aliran pesan dari panggilan query() dan mencetak biaya total ketika pesan result tiba:
import { query } from "@anthropic-ai/claude-agent-sdk";

for await (const message of query({ prompt: "Summarize this project" })) {
  if (message.type === "result") {
    console.log(`Total cost: $${message.total_cost_usd}`);
  }
}

Lacak penggunaan per-langkah dan per-model

Contoh di bagian ini menggunakan nama bidang TypeScript. Di Python, bidang yang setara adalah AssistantMessage.usage dan AssistantMessage.message_id untuk penggunaan per-langkah, dan ResultMessage.model_usage untuk rincian per-model.

Lacak penggunaan per-langkah

Setiap pesan asisten berisi BetaMessage bersarang (diakses melalui message.message) dengan id dan objek usage dengan hitungan token. Ketika Claude menggunakan alat secara paralel, beberapa pesan berbagi id yang sama dengan data penggunaan yang identik. Lacak ID mana yang sudah Anda hitung dan lewati duplikat untuk menghindari total yang meningkat.
Panggilan alat paralel menghasilkan beberapa pesan asisten yang BetaMessage bersarangnya berbagi id yang sama dan penggunaan yang identik. Selalu deduplikasi berdasarkan ID untuk mendapatkan hitungan token per-langkah yang akurat.
Contoh berikut mengakumulasi token input dan output di semua langkah, menghitung setiap ID pesan unik hanya sekali:
import { query } from "@anthropic-ai/claude-agent-sdk";

const seenIds = new Set<string>();
let totalInputTokens = 0;
let totalOutputTokens = 0;

for await (const message of query({ prompt: "Summarize this project" })) {
  if (message.type === "assistant") {
    const msgId = message.message.id;

    // Parallel tool calls share the same ID, only count once
    if (!seenIds.has(msgId)) {
      seenIds.add(msgId);
      totalInputTokens += message.message.usage.input_tokens;
      totalOutputTokens += message.message.usage.output_tokens;
    }
  }
}

console.log(`Steps: ${seenIds.size}`);
console.log(`Input tokens: ${totalInputTokens}`);
console.log(`Output tokens: ${totalOutputTokens}`);

Rincian penggunaan per model

Pesan hasil mencakup modelUsage, peta nama model ke hitungan token per-model dan biaya. Ini berguna ketika Anda menjalankan beberapa model (misalnya, Haiku untuk subagen dan Opus untuk agen utama) dan ingin melihat ke mana token pergi. Contoh berikut menjalankan query dan mencetak rincian biaya dan token untuk setiap model yang digunakan:
import { query } from "@anthropic-ai/claude-agent-sdk";

for await (const message of query({ prompt: "Summarize this project" })) {
  if (message.type !== "result") continue;

  for (const [modelName, usage] of Object.entries(message.modelUsage)) {
    console.log(`${modelName}: $${usage.costUSD.toFixed(4)}`);
    console.log(`  Input tokens: ${usage.inputTokens}`);
    console.log(`  Output tokens: ${usage.outputTokens}`);
    console.log(`  Cache read: ${usage.cacheReadInputTokens}`);
    console.log(`  Cache creation: ${usage.cacheCreationInputTokens}`);
  }
}

Akumulasi biaya di beberapa panggilan

Setiap panggilan query() mengembalikan total_cost_usd-nya sendiri. SDK tidak menyediakan total tingkat sesi, jadi jika aplikasi Anda membuat beberapa panggilan query() (misalnya, dalam sesi multi-giliran atau di seluruh pengguna yang berbeda), akumulasi total sendiri. Contoh berikut menjalankan dua panggilan query() secara berurutan, menambahkan total_cost_usd setiap panggilan ke total yang berjalan, dan mencetak biaya per-panggilan dan gabungan:
import { query } from "@anthropic-ai/claude-agent-sdk";

// Track cumulative cost across multiple query() calls
let totalSpend = 0;

const prompts = [
  "Read the files in src/ and summarize the architecture",
  "List all exported functions in src/auth.ts"
];

for (const prompt of prompts) {
  for await (const message of query({ prompt })) {
    if (message.type === "result") {
      totalSpend += message.total_cost_usd;
      console.log(`This call: $${message.total_cost_usd}`);
    }
  }
}

console.log(`Total spend: $${totalSpend.toFixed(4)}`);

Tangani kesalahan, caching, dan perbedaan token

Untuk pelacakan biaya yang akurat, pertimbangkan percakapan yang gagal, harga token cache, dan ketidakkonsistenan pelaporan yang sesekali.

Selesaikan perbedaan token output

Dalam kasus yang jarang terjadi, Anda mungkin mengamati nilai output_tokens yang berbeda untuk pesan dengan ID yang sama. Ketika ini terjadi:
  1. Gunakan nilai tertinggi: pesan terakhir dalam grup biasanya berisi total yang akurat.
  2. Lebih suka pesan hasil: total_cost_usd dalam pesan hasil mencerminkan perkiraan terakumulasi SDK di semua langkah, sehingga lebih dapat diandalkan daripada menjumlahkan nilai per-langkah sendiri. Ini masih merupakan perkiraan dan mungkin berbeda dari tagihan aktual Anda.
  3. Laporkan ketidakkonsistenan: ajukan masalah di repositori GitHub Claude Code.

Lacak biaya pada percakapan yang gagal

Pesan hasil sukses dan kesalahan keduanya mencakup usage dan total_cost_usd. Jika percakapan gagal di tengah jalan, Anda masih mengonsumsi token hingga titik kegagalan. Selalu baca data biaya dari pesan hasil terlepas dari subtype-nya.

Lacak token cache

Agent SDK secara otomatis menggunakan prompt caching untuk mengurangi biaya pada konten berulang. Anda tidak perlu mengonfigurasi caching sendiri. Objek penggunaan mencakup dua bidang tambahan untuk pelacakan cache:
  • cache_creation_input_tokens: token yang digunakan untuk membuat entri cache baru (ditagih dengan tarif lebih tinggi daripada token input standar).
  • cache_read_input_tokens: token yang dibaca dari entri cache yang ada (ditagih dengan tarif yang dikurangi).
Lacak ini secara terpisah dari input_tokens untuk memahami penghematan caching. Di TypeScript, bidang ini diketik pada objek Usage. Di Python, mereka muncul sebagai kunci dalam dict ResultMessage.usage (misalnya, message.usage.get("cache_read_input_tokens", 0)).

Perpanjang TTL cache prompt ke satu jam

Entri cache yang ditulis oleh SDK menggunakan TTL 5 menit secara default ketika Anda mengautentikasi dengan kunci API atau menjalankan di Amazon Bedrock, Google Cloud Vertex AI, atau Microsoft Foundry. Jika beban kerja Anda menjalankan banyak sesi pendek terhadap prompt sistem dan konteks yang sama dengan celah lebih lama dari 5 menit di antara mereka, cache kedaluwarsa di antara sesi dan setiap sesi baru membayar harga input penuh. Untuk meminta TTL 1 jam pada penulisan cache, atur variabel lingkungan ENABLE_PROMPT_CACHING_1H. Anda dapat mengekspornya di lingkungan shell atau kontainer Anda, atau meneruskannya melalui options.env. Contoh berikut mengaktifkan TTL 1 jam untuk agen yang berjalan di Bedrock:
options = ClaudeAgentOptions(
    env={
        "CLAUDE_CODE_USE_BEDROCK": "1",
        "ENABLE_PROMPT_CACHING_1H": "1",
    },
)
Penulisan cache dengan TTL 1 jam ditagih dengan tarif lebih tinggi daripada penulisan 5 menit, jadi mengaktifkan ini menukar biaya penulisan lebih tinggi untuk lebih banyak pembacaan cache. Lihat harga prompt caching untuk detail. Pengguna langganan Claude sudah menerima TTL 1 jam secara otomatis dan tidak perlu mengatur variabel ini.

Dokumentasi terkait