Le SDK Claude Agent fournit des informations détaillées sur l'utilisation des tokens pour chaque interaction avec Claude. Ce guide explique comment suivre correctement les coûts et comprendre les rapports d'utilisation, en particulier lors du traitement d'utilisations d'outils parallèles et de conversations multi-étapes.
Pour la documentation complète de l'API, consultez la référence du SDK TypeScript.
Lorsque Claude traite les requêtes, il rapporte l'utilisation des tokens au niveau du message. Ces données d'utilisation sont essentielles pour suivre les coûts et facturer les utilisateurs de manière appropriée.
Lorsque Claude exécute des outils, les rapports d'utilisation diffèrent selon que les outils sont exécutés séquentiellement ou en parallèle :
import { query } from "@anthropic-ai/claude-agent-sdk";
// Exemple : Suivi de l'utilisation dans une conversation
const result = await query({
prompt: "Analysez cette base de code et exécutez les tests",
options: {
onMessage: (message) => {
if (message.type === 'assistant' && message.usage) {
console.log(`ID du Message : ${message.id}`);
console.log(`Utilisation :`, message.usage);
}
}
}
});Voici comment les messages et l'utilisation sont rapportés dans une conversation multi-étapes typique :
<!-- Étape 1 : Requête initiale avec utilisations d'outils parallèles -->
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)
<!-- Étape 2 : Réponse de suivi -->
assistant (text) { id: "msg_2", usage: { output_tokens: 98, ... } }Tous les messages avec le même champ id rapportent une utilisation identique. Lorsque Claude envoie plusieurs messages dans le même tour (par exemple, texte + utilisations d'outils), ils partagent le même ID de message et les mêmes données d'utilisation.
// Tous ces messages ont le même ID et la même utilisation
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 } }
];
// Facturer seulement une fois par ID de message unique
const uniqueUsage = messages[0].usage; // Identique pour tous les messages avec cet IDVous ne devriez facturer les utilisateurs qu'une fois par étape, pas pour chaque message individuel. Lorsque vous voyez plusieurs messages d'assistant avec le même ID, utilisez l'utilisation de n'importe lequel d'entre eux.
Le message final result contient l'utilisation cumulative totale de toutes les étapes de la conversation :
// Le résultat final inclut l'utilisation totale
const result = await query({
prompt: "Tâche multi-étapes",
options: { /* ... */ }
});
console.log("Utilisation totale :", result.usage);
console.log("Coût total :", result.usage.total_cost_usd);Voici un exemple complet d'implémentation d'un système de suivi des coûts :
Dans de rares cas, vous pourriez observer différentes valeurs output_tokens pour des messages avec le même ID. Lorsque cela se produit :
total_cost_usd dans le message de résultat fait autoritéLors de l'utilisation de la mise en cache des prompts, suivez ces types de tokens séparément :
interface CacheUsage {
cache_creation_input_tokens: number;
cache_read_input_tokens: number;
cache_creation: {
ephemeral_5m_input_tokens: number;
ephemeral_1h_input_tokens: number;
};
}Chaque objet d'utilisation contient :
input_tokens : Tokens d'entrée de base traitésoutput_tokens : Tokens générés dans la réponsecache_creation_input_tokens : Tokens utilisés pour créer des entrées de cachecache_read_input_tokens : Tokens lus depuis le cacheservice_tier : Le niveau de service utilisé (par exemple, "standard")total_cost_usd : Coût total en USD (seulement dans le message de résultat)Voici comment agréger les données d'utilisation pour un tableau de bord de facturation :
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);
// Mettre à jour les totaux utilisateur
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) {
// Traiter seulement les messages d'assistant avec utilisation
if (message.type !== 'assistant' || !message.usage) {
return;
}
// Ignorer si nous avons déjà traité cet ID de message
if (this.processedMessageIds.has(message.id)) {
return;
}
// Marquer comme traité et enregistrer l'utilisation
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 {
// Implémentez votre calcul de prix ici
// Ceci est un exemple simplifié
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;
}
}
// Utilisation
const tracker = new CostTracker();
const { result, stepUsages, totalCost } = await tracker.trackConversation(
"Analysez et refactorisez ce code"
);
console.log(`Étapes traitées : ${stepUsages.length}`);
console.log(`Coût total : $${totalCost.toFixed(4)}`);