Le Claude Agent SDK fournit des informations détaillées sur l'utilisation des jetons pour chaque interaction avec Claude. Ce guide explique comment suivre correctement les coûts et comprendre les rapports d'utilisation, en particulier lorsqu'il s'agit 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 demandes, il signale l'utilisation des jetons 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, le rapport d'utilisation diffère 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: "Analyze this codebase and run tests",
options: {
onMessage: (message) => {
if (message.type === 'assistant' && message.usage) {
console.log(`Message ID: ${message.id}`);
console.log(`Usage:`, message.usage);
}
}
}
});Voici comment les messages et l'utilisation sont signalés dans une conversation typique multi-étapes :
<!-- Étape 1 : Demande 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 signalent 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 une seule fois par ID de message unique
const uniqueUsage = messages[0].usage; // Identique pour tous les messages avec cet IDVous ne devez facturer les utilisateurs qu'une seule fois par étape, pas pour chaque message individuel. Lorsque vous voyez plusieurs messages d'assistant avec le même ID, utilisez l'utilisation de l'un d'entre eux.
Le message result final 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: "Multi-step task",
options: { /* ... */ }
});
console.log("Total usage:", result.usage);
console.log("Total cost:", result.usage.total_cost_usd);Le message de résultat inclut également modelUsage, qui fournit des données d'utilisation par modèle faisant autorité. Comme total_cost_usd, ce champ est exact et convient à des fins de facturation. Ceci est particulièrement utile lors de l'utilisation de plusieurs modèles (par exemple, Haiku pour les sous-agents, Opus pour l'agent principal).
// modelUsage fournit une ventilation par modèle
type ModelUsage = {
inputTokens: number
outputTokens: number
cacheReadInputTokens: number
cacheCreationInputTokens: number
webSearchRequests: number
costUSD: number
contextWindow: number
}
// Accès à partir du message de résultat
const result = await query({ prompt: "..." });
// result.modelUsage est une carte du nom du modèle à ModelUsage
for (const [modelName, usage] of Object.entries(result.modelUsage)) {
console.log(`${modelName}: $${usage.costUSD.toFixed(4)}`);
console.log(` Input tokens: ${usage.inputTokens}`);
console.log(` Output tokens: ${usage.outputTokens}`);
}Pour les définitions de type complètes, consultez la référence du SDK TypeScript.
Voici un exemple complet d'implémentation d'un système de suivi des coûts :
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 uniquement 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 tarification 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(
"Analyze and refactor this code"
);
console.log(`Steps processed: ${stepUsages.length}`);
console.log(`Total cost: $${totalCost.toFixed(4)}`);Dans de rares cas, vous pourriez observer des valeurs output_tokens différentes pour les 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 invites, suivez ces types de jetons 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 : Jetons d'entrée de base traitésoutput_tokens : Jetons générés dans la réponsecache_creation_input_tokens : Jetons utilisés pour créer des entrées de cachecache_read_input_tokens : Jetons lus à partir du cacheservice_tier : Le niveau de service utilisé (par exemple, « standard »)total_cost_usd : Coût total en USD (uniquement 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 de l'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
};
}
}Was this page helpful?