Tracciare costi e utilizzo
Scopri come tracciare l'utilizzo dei token, stimare i costi e configurare la memorizzazione nella cache dei prompt con Claude Agent SDK.
Claude Agent SDK fornisce informazioni dettagliate sull'utilizzo dei token per ogni interazione con Claude. Questa guida spiega come tracciare correttamente l'utilizzo e comprendere la segnalazione dei costi, soprattutto quando si affrontano utilizzi di strumenti paralleli e conversazioni multi-step.
Per la documentazione API completa, consulta il riferimento TypeScript SDK e il riferimento Python SDK.
I campi total_cost_usd e costUSD sono stime lato client, non dati di fatturazione autorevoli. L'SDK li calcola localmente da una tabella dei prezzi inclusa al momento della compilazione, quindi possono divergere da ciò che viene effettivamente fatturato quando:
- i prezzi cambiano
- la versione dell'SDK installata non riconosce un modello
- si applicano regole di fatturazione che il client non può modellare
Utilizza questi campi per approfondimenti di sviluppo e budget approssimativi. Per la fatturazione autorevole, utilizza l'API di utilizzo e costi o la pagina Utilizzo nella Console Claude. Non fatturare gli utenti finali o attivare decisioni finanziarie da questi campi.
Comprendere l'utilizzo dei token
Gli SDK TypeScript e Python espongono gli stessi dati di utilizzo con nomi di campi diversi:
- TypeScript fornisce scomposizioni di token per step su ogni messaggio dell'assistente (
message.message.id,message.message.usage), costi per modello tramitemodelUsagesul messaggio risultato e un totale cumulativo sul messaggio risultato. - Python fornisce scomposizioni di token per step su ogni messaggio dell'assistente (
message.usage,message.message_id), costi per modello tramitemodel_usagesul messaggio risultato e il totale accumulato sul messaggio risultato (total_cost_usde dizionariousage).
Entrambi gli SDK utilizzano lo stesso modello di costo sottostante ed espongono la stessa granularità. La differenza è nella denominazione dei campi e nel punto in cui l'utilizzo per step è annidato.
Il tracciamento dei costi dipende dalla comprensione di come l'SDK delimita i dati di utilizzo:
- Chiamata
query(): una singola invocazione della funzionequery()dell'SDK. Una singola chiamata può coinvolgere più step (Claude risponde, utilizza strumenti, ottiene risultati, risponde di nuovo). Ogni chiamata produce un messaggioresultalla fine. - Step: un singolo ciclo di richiesta/risposta all'interno di una chiamata
query(). Ogni step produce messaggi dell'assistente con utilizzo dei token. - Sessione: una serie di chiamate
query()collegate da un ID di sessione (utilizzando l'opzioneresume). Ogni chiamataquery()all'interno di una sessione segnala il proprio costo in modo indipendente.
Il diagramma seguente mostra il flusso di messaggi da una singola chiamata query(), con utilizzo dei token segnalato ad ogni step e la stima cumulativa alla fine:
Ogni step produce messaggi dell'assistente
Quando Claude risponde, invia uno o più messaggi dell'assistente. In TypeScript, ogni messaggio dell'assistente contiene un BetaMessage annidato (accessibile tramite message.message) con un id e un oggetto usage con conteggi di token (input_tokens, output_tokens). In Python, la classe dataclass AssistantMessage espone gli stessi dati direttamente tramite message.usage e message.message_id. Quando Claude utilizza più strumenti in un turno, tutti i messaggi in quel turno condividono lo stesso ID, quindi deduplicare per ID per evitare il doppio conteggio.
Il messaggio risultato fornisce la stima cumulativa
Quando la chiamata query() si completa, l'SDK emette un messaggio risultato con total_cost_usd e usage cumulativo. Questo è disponibile sia in TypeScript (SDKResultMessage) che in Python (ResultMessage). Se effettui più chiamate query() (ad esempio, in una sessione multi-turno), ogni risultato riflette solo il costo di quella singola chiamata. Se hai bisogno solo della stima totale, puoi ignorare l'utilizzo per step e leggere questo singolo valore.
Ottenere il costo totale di una query
Il messaggio risultato (TypeScript, Python) segna la fine del ciclo dell'agente per una chiamata query(). Include total_cost_usd, il costo stimato cumulativo su tutti gli step in quella chiamata. Questo funziona sia per risultati di successo che di errore. Se utilizzi sessioni per effettuare più chiamate query(), ogni risultato riflette solo il costo di quella singola chiamata.
Gli esempi seguenti iterano sul flusso di messaggi da una chiamata query() e stampano il costo totale quando arriva il messaggio result:
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}`);
}
}
from claude_agent_sdk import query, ResultMessage
import asyncio
async def main():
async for message in query(prompt="Summarize this project"):
if isinstance(message, ResultMessage):
print(f"Total cost: ${message.total_cost_usd or 0}")
asyncio.run(main())
Tracciare l'utilizzo per step e per modello
Gli esempi in questa sezione utilizzano nomi di campi TypeScript. In Python, i campi equivalenti sono AssistantMessage.usage e AssistantMessage.message_id per l'utilizzo per step, e ResultMessage.model_usage per le scomposizioni per modello.
Tracciare l'utilizzo per step
Ogni messaggio dell'assistente contiene un BetaMessage annidato (accessibile tramite message.message) con un id e un oggetto usage con conteggi di token. Quando Claude utilizza strumenti in parallelo, più messaggi condividono lo stesso id con dati di utilizzo identici. Traccia quali ID hai già contato e salta i duplicati per evitare totali gonfiati.
Le chiamate di strumenti paralleli producono più messaggi dell'assistente il cui BetaMessage annidato condivide lo stesso id e utilizzo identico. Deduplicare sempre per ID per ottenere conteggi di token per step accurati.
L'esempio seguente accumula token di input e output su tutti gli step, contando ogni ID di messaggio univoco una sola volta:
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}`);
Scomporre l'utilizzo per modello
Il messaggio risultato include modelUsage, una mappa del nome del modello ai conteggi di token e costi per modello. Questo è utile quando esegui più modelli (ad esempio, Haiku per subagenti e Opus per l'agente principale) e vuoi vedere dove vanno i token.
L'esempio seguente esegue una query e stampa il costo e la scomposizione dei token per ogni modello utilizzato:
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}`);
}
}
Accumulare costi su più chiamate
Ogni chiamata query() restituisce il suo total_cost_usd. L'SDK non fornisce un totale a livello di sessione, quindi se la tua applicazione effettua più chiamate query() (ad esempio, in una sessione multi-turno o tra diversi utenti), accumula i totali tu stesso.
Gli esempi seguenti eseguono due chiamate query() in sequenza, aggiungono il total_cost_usd di ogni chiamata a un totale in esecuzione e stampano sia il costo per chiamata che quello combinato:
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)}`);
from claude_agent_sdk import query, ResultMessage
import asyncio
async def main():
# Track cumulative cost across multiple query() calls
total_spend = 0.0
prompts = [
"Read the files in src/ and summarize the architecture",
"List all exported functions in src/auth.ts",
]
for prompt in prompts:
async for message in query(prompt=prompt):
if isinstance(message, ResultMessage):
cost = message.total_cost_usd or 0
total_spend += cost
print(f"This call: ${cost}")
print(f"Total spend: ${total_spend:.4f}")
asyncio.run(main())
Gestire errori, caching e discrepanze di token
Per un tracciamento accurato dei costi, tieni conto di conversazioni non riuscite, prezzi dei token in cache e occasionali incoerenze di segnalazione.
Risolvere discrepanze di token di output
In rari casi, potresti osservare valori output_tokens diversi per messaggi con lo stesso ID. Quando ciò accade:
- Utilizza il valore più alto: il messaggio finale in un gruppo contiene in genere il totale accurato.
- Preferisci il messaggio risultato: il
total_cost_usdnel messaggio risultato riflette la stima accumulata dell'SDK su tutti gli step, quindi è più affidabile che sommare i valori per step tu stesso. È comunque una stima e può differire dalla tua fattura effettiva. - Segnala incoerenze: archivia i problemi nel repository GitHub Claude Code.
Tracciare i costi su conversazioni non riuscite
Sia i messaggi risultato di successo che di errore includono usage e total_cost_usd. Se una conversazione fallisce a metà, hai comunque consumato token fino al punto di errore. Leggi sempre i dati di costo dal messaggio risultato indipendentemente dal suo subtype.
Tracciare i token in cache
Agent SDK utilizza automaticamente la memorizzazione nella cache dei prompt per ridurre i costi su contenuti ripetuti. Non è necessario configurare il caching tu stesso. L'oggetto di utilizzo include due campi aggiuntivi per il tracciamento della cache:
cache_creation_input_tokens: token utilizzati per creare nuove voci di cache (addebitati a una tariffa più alta rispetto ai token di input standard).cache_read_input_tokens: token letti da voci di cache esistenti (addebitati a una tariffa ridotta).
Traccia questi separatamente da input_tokens per comprendere i risparmi di caching. In TypeScript, questi campi sono tipizzati sull'oggetto Usage. In Python, appaiono come chiavi nel dizionario ResultMessage.usage (ad esempio, message.usage.get("cache_read_input_tokens", 0)).
Estendere il TTL della cache dei prompt a un'ora
Le voci di cache scritte dall'SDK utilizzano un TTL di 5 minuti per impostazione predefinita quando ti autentichi con una chiave API o esegui su Amazon Bedrock, Google Cloud Vertex AI o Microsoft Foundry. Se il tuo carico di lavoro esegue molte sessioni brevi rispetto allo stesso prompt di sistema e contesto con gap più lunghi di 5 minuti tra loro, la cache scade tra le sessioni e ogni nuova sessione paga il prezzo di input completo.
Per richiedere un TTL di 1 ora sulle scritture della cache, imposta la variabile di ambiente ENABLE_PROMPT_CACHING_1H. Puoi esportarla nel tuo ambiente shell o container, oppure passarla tramite options.env.
L'esempio seguente abilita il TTL di 1 ora per un agente in esecuzione su Bedrock:
from claude_agent_sdk import ClaudeAgentOptions, query
import asyncio
async def main():
options = ClaudeAgentOptions(
env={
"CLAUDE_CODE_USE_BEDROCK": "1",
"ENABLE_PROMPT_CACHING_1H": "1",
},
)
async for message in query(prompt="Summarize this project", options=options):
print(message)
asyncio.run(main())
import { query } from "@anthropic-ai/claude-agent-sdk";
const options = {
env: {
...process.env,
CLAUDE_CODE_USE_BEDROCK: "1",
ENABLE_PROMPT_CACHING_1H: "1",
},
};
for await (const message of query({ prompt: "Summarize this project", options })) {
console.log(message);
}
Le scritture della cache con un TTL di 1 ora sono fatturate a una tariffa più alta rispetto alle scritture di 5 minuti, quindi abilitare questa opzione scambia un costo di scrittura più elevato per più letture della cache. Consulta i prezzi della memorizzazione nella cache dei prompt per i dettagli. Gli utenti con abbonamento Claude ricevono già automaticamente il TTL di 1 ora e non hanno bisogno di impostare questa variabile.
Documentazione correlata
- Riferimento TypeScript SDK - Documentazione API completa
- Panoramica SDK - Introduzione all'SDK
- Autorizzazioni SDK - Gestione delle autorizzazioni degli strumenti