Il Claude Agent SDK fornisce informazioni dettagliate sull'utilizzo dei token per ogni interazione con Claude. Questa guida spiega come tracciare correttamente i costi e comprendere il reporting dell'utilizzo, specialmente quando si gestiscono utilizzi di strumenti paralleli e conversazioni multi-step.
Per la documentazione API completa, consulta il riferimento TypeScript SDK.
Quando Claude elabora le richieste, riporta l'utilizzo dei token a livello di messaggio. Questi dati di utilizzo sono essenziali per tracciare i costi e fatturare gli utenti in modo appropriato.
Quando Claude esegue strumenti, il reporting dell'utilizzo differisce in base al fatto che gli strumenti vengano eseguiti sequenzialmente o in parallelo:
import { query } from "@anthropic-ai/claude-agent-sdk";
// Esempio: Tracciamento dell'utilizzo in una conversazione
const result = await query({
prompt: "Analizza questo codebase ed esegui i test",
options: {
onMessage: (message) => {
if (message.type === 'assistant' && message.usage) {
console.log(`ID Messaggio: ${message.id}`);
console.log(`Utilizzo:`, message.usage);
}
}
}
});Ecco come vengono riportati i messaggi e l'utilizzo in una tipica conversazione multi-step:
<!-- Step 1: Richiesta iniziale con utilizzi di strumenti paralleli -->
assistant (text) { id: "msg_1", usage: { output_tokens: 100, ... } }
assistant (tool_use) { id: "msg_1", usage: { output_tokens: 100, ... } }
assistant (tool_use) { id: "msg_1", usage: { output_tokens: 100, ... } }
assistant (tool_use) { id: "msg_1", usage: { output_tokens: 100, ... } }
user (tool_result)
user (tool_result)
user (tool_result)
<!-- Step 2: Risposta di follow-up -->
assistant (text) { id: "msg_2", usage: { output_tokens: 98, ... } }Tutti i messaggi con lo stesso campo id riportano utilizzo identico. Quando Claude invia più messaggi nello stesso turno (ad es., testo + utilizzi di strumenti), condividono lo stesso ID messaggio e dati di utilizzo.
// Tutti questi messaggi hanno lo stesso ID e utilizzo
const messages = [
{ type: 'assistant', id: 'msg_123', usage: { output_tokens: 100 } },
{ type: 'assistant', id: 'msg_123', usage: { output_tokens: 100 } },
{ type: 'assistant', id: 'msg_123', usage: { output_tokens: 100 } }
];
// Addebita solo una volta per ID messaggio unico
const uniqueUsage = messages[0].usage; // Uguale per tutti i messaggi con questo IDDovresti addebitare agli utenti solo una volta per step, non per ogni singolo messaggio. Quando vedi più messaggi dell'assistente con lo stesso ID, usa l'utilizzo da uno qualsiasi di essi.
Il messaggio finale result contiene l'utilizzo cumulativo totale da tutti gli step nella conversazione:
// Il risultato finale include l'utilizzo totale
const result = await query({
prompt: "Attività multi-step",
options: { /* ... */ }
});
console.log("Utilizzo totale:", result.usage);
console.log("Costo totale:", result.usage.total_cost_usd);Ecco un esempio completo di implementazione di un sistema di tracciamento dei costi:
In rari casi, potresti osservare valori diversi di output_tokens per messaggi con lo stesso ID. Quando questo accade:
total_cost_usd nel messaggio risultato è autorevoleQuando usi il prompt caching, traccia questi tipi di token separatamente:
interface CacheUsage {
cache_creation_input_tokens: number;
cache_read_input_tokens: number;
cache_creation: {
ephemeral_5m_input_tokens: number;
ephemeral_1h_input_tokens: number;
};
}Ogni oggetto utilizzo contiene:
input_tokens: Token di input base elaboratioutput_tokens: Token generati nella rispostacache_creation_input_tokens: Token usati per creare voci di cachecache_read_input_tokens: Token letti dalla cacheservice_tier: Il livello di servizio usato (ad es., "standard")total_cost_usd: Costo totale in USD (solo nel messaggio risultato)Ecco come aggregare i dati di utilizzo per una dashboard di fatturazione:
class BillingAggregator {
private userUsage = new Map<string, {
totalTokens: number;
totalCost: number;
conversations: number;
}>();
async processUserRequest(userId: string, prompt: string) {
const tracker = new CostTracker();
const { result, stepUsages, totalCost } = await tracker.trackConversation(prompt);
// Aggiorna i totali utente
const current = this.userUsage.get(userId) || {
totalTokens: 0,
totalCost: 0,
conversations: 0
};
const totalTokens = stepUsages.reduce((sum, step) =>
sum + step.usage.input_tokens + step.usage.output_tokens, 0
);
this.userUsage.set(userId, {
totalTokens: current.totalTokens + totalTokens,
totalCost: current.totalCost + totalCost,
conversations: current.conversations + 1
});
return result;
}
getUserBilling(userId: string) {
return this.userUsage.get(userId) || {
totalTokens: 0,
totalCost: 0,
conversations: 0
};
}
}import { query } from "@anthropic-ai/claude-agent-sdk";
class CostTracker {
private processedMessageIds = new Set<string>();
private stepUsages: Array<any> = [];
async trackConversation(prompt: string) {
const result = await query({
prompt,
options: {
onMessage: (message) => {
this.processMessage(message);
}
}
});
return {
result,
stepUsages: this.stepUsages,
totalCost: result.usage?.total_cost_usd || 0
};
}
private processMessage(message: any) {
// Elabora solo messaggi dell'assistente con utilizzo
if (message.type !== 'assistant' || !message.usage) {
return;
}
// Salta se abbiamo già elaborato questo ID messaggio
if (this.processedMessageIds.has(message.id)) {
return;
}
// Segna come elaborato e registra l'utilizzo
this.processedMessageIds.add(message.id);
this.stepUsages.push({
messageId: message.id,
timestamp: new Date().toISOString(),
usage: message.usage,
costUSD: this.calculateCost(message.usage)
});
}
private calculateCost(usage: any): number {
// Implementa qui il tuo calcolo dei prezzi
// Questo è un esempio semplificato
const inputCost = usage.input_tokens * 0.00003;
const outputCost = usage.output_tokens * 0.00015;
const cacheReadCost = (usage.cache_read_input_tokens || 0) * 0.0000075;
return inputCost + outputCost + cacheReadCost;
}
}
// Utilizzo
const tracker = new CostTracker();
const { result, stepUsages, totalCost } = await tracker.trackConversation(
"Analizza e refactorizza questo codice"
);
console.log(`Step elaborati: ${stepUsages.length}`);
console.log(`Costo totale: $${totalCost.toFixed(4)}`);