Tracciamento di Costi e Utilizzo
Tracciamento dei Costi SDK
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.
Comprensione dell'Utilizzo dei Token
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.
Concetti Chiave
- Steps: Uno step è una singola coppia richiesta/risposta tra la tua applicazione e Claude
- Messaggi: Messaggi individuali all'interno di uno step (testo, utilizzi di strumenti, risultati di strumenti)
- Utilizzo: Dati di consumo dei token allegati ai messaggi dell'assistente
Struttura del Reporting dell'Utilizzo
Utilizzo di Strumenti Singolo vs Parallelo
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);
}
}
}
});from claude_agent_sdk import query, ClaudeAgentOptions, AssistantMessage
import asyncio
# Esempio: Tracciamento dell'utilizzo in una conversazione
async def track_usage():
# Elabora i messaggi man mano che arrivano
async for message in query(
prompt="Analizza questo codebase ed esegui i test"
):
if isinstance(message, AssistantMessage) and hasattr(message, 'usage'):
print(f"ID Messaggio: {message.id}")
print(f"Utilizzo: {message.usage}")
asyncio.run(track_usage())Esempio di Flusso di Messaggi
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, ... } }Regole Importanti per l'Utilizzo
1. Stesso ID = Stesso Utilizzo
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 ID2. Addebita Una Volta Per Step
Dovresti 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.
3. Il Messaggio Risultato Contiene l'Utilizzo Cumulativo
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);Implementazione: Sistema di Tracciamento dei Costi
Ecco un esempio completo di implementazione di un sistema di tracciamento dei costi:
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)}`);Gestione dei Casi Limite
Discrepanze nei Token di Output
In rari casi, potresti osservare valori diversi di output_tokens per messaggi con lo stesso ID. Quando questo accade:
- Usa il valore più alto - L'ultimo messaggio in un gruppo tipicamente contiene il totale accurato
- Verifica contro il costo totale - Il
total_cost_usdnel messaggio risultato è autorevole - Segnala inconsistenze - Segnala problemi al repository GitHub di Claude Code
Tracciamento dei Token di Cache
Quando 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;
};
}Migliori Pratiche
- Usa gli ID Messaggio per la Deduplicazione: Traccia sempre gli ID messaggio elaborati per evitare doppi addebiti
- Monitora il Messaggio Risultato: Il risultato finale contiene l'utilizzo cumulativo autorevole
- Implementa il Logging: Registra tutti i dati di utilizzo per audit e debug
- Gestisci i Fallimenti con Grazia: Traccia l'utilizzo parziale anche se una conversazione fallisce
- Considera lo Streaming: Per risposte in streaming, accumula l'utilizzo man mano che arrivano i messaggi
Riferimento dei Campi di Utilizzo
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)
Esempio: Costruzione di una Dashboard di Fatturazione
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
};
}
}Documentazione Correlata
- Riferimento TypeScript SDK - Documentazione API completa
- Panoramica SDK - Iniziare con l'SDK
- Permessi SDK - Gestione dei permessi degli strumenti