Passer au contenu principal
Le Claude Agent SDK fournit des informations détaillées sur l’utilisation des tokens pour chaque interaction avec Claude. Ce guide explique comment suivre correctement l’utilisation et comprendre les rapports de coûts, en particulier lorsqu’il s’agit d’utiliser des outils en parallèle et de conversations multi-étapes. Pour la documentation complète de l’API, consultez la référence du SDK TypeScript et la référence du SDK Python.
Les champs total_cost_usd et costUSD sont des estimations côté client, pas des données de facturation faisant autorité. Le SDK les calcule localement à partir d’une table de prix intégrée au moment de la compilation, ils peuvent donc diverger de ce que vous êtes réellement facturé lorsque :
  • les prix changent
  • la version du SDK installée ne reconnaît pas un modèle
  • des règles de facturation s’appliquent que le client ne peut pas modéliser
Utilisez ces champs pour obtenir des informations de développement et un budget approximatif. Pour une facturation faisant autorité, utilisez l’API d’utilisation et de coûts ou la page Utilisation dans la Console Claude. Ne facturez pas les utilisateurs finaux et ne déclenchez pas de décisions financières à partir de ces champs.

Comprendre l’utilisation des tokens

Les SDK TypeScript et Python exposent les mêmes données d’utilisation avec des noms de champs différents :
  • TypeScript fournit des ventilations de tokens par étape sur chaque message d’assistant (message.message.id, message.message.usage), le coût par modèle via modelUsage sur le message de résultat, et un total cumulatif sur le message de résultat.
  • Python fournit des ventilations de tokens par étape sur chaque message d’assistant (message.usage, message.message_id), le coût par modèle via model_usage sur le message de résultat, et le total accumulé sur le message de résultat (total_cost_usd et dictionnaire usage).
Les deux SDK utilisent le même modèle de coûts sous-jacent et exposent la même granularité. La différence réside dans la dénomination des champs et dans l’endroit où l’utilisation par étape est imbriquée. Le suivi des coûts dépend de la compréhension de la façon dont le SDK délimite les données d’utilisation :
  • Appel query() : une invocation de la fonction query() du SDK. Un seul appel peut impliquer plusieurs étapes (Claude répond, utilise des outils, obtient des résultats, répond à nouveau). Chaque appel produit un message result à la fin.
  • Étape : un seul cycle requête/réponse dans un appel query(). Chaque étape produit des messages d’assistant avec l’utilisation des tokens.
  • Session : une série d’appels query() liés par un ID de session (en utilisant l’option resume). Chaque appel query() dans une session rapporte son propre coût indépendamment.
Le diagramme suivant montre le flux de messages d’un seul appel query(), avec l’utilisation des tokens rapportée à chaque étape et l’estimation cumulative à la fin : Diagramme montrant une requête produisant deux étapes de messages. L'étape 1 a quatre messages d'assistant partageant le même ID et l'utilisation (compter une fois), l'étape 2 a un message d'assistant avec un nouvel ID, et le message de résultat final affiche le total_cost_usd estimé.
1

Chaque étape produit des messages d'assistant

Lorsque Claude répond, il envoie un ou plusieurs messages d’assistant. Dans TypeScript, chaque message d’assistant contient un BetaMessage imbriqué (accessible via message.message) avec un id et un objet usage avec des comptages de tokens (input_tokens, output_tokens). En Python, la classe de données AssistantMessage expose les mêmes données directement via message.usage et message.message_id. Lorsque Claude utilise plusieurs outils en un seul tour, tous les messages de ce tour partagent le même ID, donc dédupliquez par ID pour éviter le double comptage.
2

Le message de résultat fournit l'estimation cumulative

Lorsque l’appel query() se termine, le SDK émet un message de résultat avec total_cost_usd et usage cumulatif. Ceci est disponible à la fois dans TypeScript (SDKResultMessage) et Python (ResultMessage). Si vous effectuez plusieurs appels query() (par exemple, dans une session multi-tours), chaque résultat ne reflète que le coût de cet appel individuel. Si vous avez seulement besoin du total estimé, vous pouvez ignorer l’utilisation par étape et lire cette valeur unique.

Obtenir le coût total d’une requête

Le message de résultat (TypeScript, Python) marque la fin de la boucle d’agent pour un appel query(). Il inclut total_cost_usd, le coût estimé cumulatif sur toutes les étapes de cet appel. Cela fonctionne à la fois pour les résultats de succès et d’erreur. Si vous utilisez des sessions pour effectuer plusieurs appels query(), chaque résultat ne reflète que le coût de cet appel individuel. Les exemples suivants itèrent sur le flux de messages d’un appel query() et impriment le coût total lorsque le message result arrive :
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}`);
  }
}

Suivre l’utilisation par étape et par modèle

Les exemples de cette section utilisent les noms de champs TypeScript. En Python, les champs équivalents sont AssistantMessage.usage et AssistantMessage.message_id pour l’utilisation par étape, et ResultMessage.model_usage pour les ventilations par modèle.

Suivre l’utilisation par étape

Chaque message d’assistant contient un BetaMessage imbriqué (accessible via message.message) avec un id et un objet usage avec des comptages de tokens. Lorsque Claude utilise des outils en parallèle, plusieurs messages partagent le même id avec des données d’utilisation identiques. Suivez les ID que vous avez déjà comptés et ignorez les doublons pour éviter des totaux gonflés.
Les appels d’outils parallèles produisent plusieurs messages d’assistant dont le BetaMessage imbriqué partage le même id et l’utilisation identique. Dédupliquez toujours par ID pour obtenir des comptages de tokens précis par étape.
L’exemple suivant accumule les tokens d’entrée et de sortie sur toutes les étapes, en comptant chaque ID de message unique une seule fois :
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}`);

Ventiler l’utilisation par modèle

Le message de résultat inclut modelUsage, une carte du nom du modèle aux comptages de tokens et coûts par modèle. Ceci est utile lorsque vous exécutez plusieurs modèles (par exemple, Haiku pour les sous-agents et Opus pour l’agent principal) et que vous souhaitez voir où vont les tokens. L’exemple suivant exécute une requête et imprime le coût et la ventilation des tokens pour chaque modèle utilisé :
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}`);
  }
}

Accumuler les coûts sur plusieurs appels

Chaque appel query() retourne son propre total_cost_usd. Le SDK ne fournit pas de total au niveau de la session, donc si votre application effectue plusieurs appels query() (par exemple, dans une session multi-tours ou entre différents utilisateurs), accumulez les totaux vous-même. Les exemples suivants exécutent deux appels query() séquentiellement, ajoutent le total_cost_usd de chaque appel à un total cumulatif, et impriment à la fois le coût par appel et le coût combiné :
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)}`);

Gérer les erreurs, la mise en cache et les divergences de tokens

Pour un suivi précis des coûts, tenez compte des conversations échouées, de la tarification des tokens en cache et des incohérences occasionnelles de rapports.

Résoudre les divergences de tokens de sortie

Dans de rares cas, vous pourriez observer différentes valeurs output_tokens pour les messages avec le même ID. Lorsque cela se produit :
  1. Utilisez la valeur la plus élevée : le message final d’un groupe contient généralement le total exact.
  2. Préférez le message de résultat : le total_cost_usd dans le message de résultat reflète l’estimation accumulée du SDK sur toutes les étapes, il est donc plus fiable que de sommer les valeurs par étape vous-même. C’est toujours une estimation et peut différer de votre facture réelle.
  3. Signalez les incohérences : déposez des problèmes sur le référentiel GitHub Claude Code.

Suivre les coûts sur les conversations échouées

Les messages de résultat de succès et d’erreur incluent usage et total_cost_usd. Si une conversation échoue à mi-chemin, vous avez toujours consommé des tokens jusqu’au point d’échec. Lisez toujours les données de coûts du message de résultat quel que soit son subtype.

Suivre les tokens en cache

Le Agent SDK utilise automatiquement la mise en cache des invites pour réduire les coûts sur le contenu répété. Vous n’avez pas besoin de configurer la mise en cache vous-même. L’objet d’utilisation inclut deux champs supplémentaires pour le suivi du cache :
  • cache_creation_input_tokens : tokens utilisés pour créer de nouvelles entrées de cache (facturés à un taux plus élevé que les tokens d’entrée standard).
  • cache_read_input_tokens : tokens lus à partir des entrées de cache existantes (facturés à un taux réduit).
Suivez-les séparément de input_tokens pour comprendre les économies de mise en cache. Dans TypeScript, ces champs sont typés sur l’objet Usage. En Python, ils apparaissent comme des clés dans le dictionnaire ResultMessage.usage (par exemple, message.usage.get("cache_read_input_tokens", 0)).

Prolonger le TTL du cache d’invite à une heure

Les entrées de cache écrites par le SDK utilisent un TTL de 5 minutes par défaut lorsque vous vous authentifiez avec une clé API ou que vous exécutez sur Amazon Bedrock, Google Cloud Vertex AI ou Microsoft Foundry. Si votre charge de travail exécute de nombreuses sessions courtes contre le même système d’invite et le même contexte avec des écarts plus longs que 5 minutes entre elles, le cache expire entre les sessions et chaque nouvelle session paie le prix d’entrée complet. Pour demander un TTL d’une heure sur les écritures de cache, définissez la variable d’environnement ENABLE_PROMPT_CACHING_1H. Vous pouvez l’exporter dans votre environnement shell ou conteneur, ou la transmettre via options.env. L’exemple suivant active le TTL d’une heure pour un agent s’exécutant sur Bedrock :
options = ClaudeAgentOptions(
    env={
        "CLAUDE_CODE_USE_BEDROCK": "1",
        "ENABLE_PROMPT_CACHING_1H": "1",
    },
)
Les écritures de cache avec un TTL d’une heure sont facturées à un taux plus élevé que les écritures de 5 minutes, donc l’activation de ceci échange un coût d’écriture plus élevé pour plus de lectures de cache. Consultez la tarification de la mise en cache des invites pour plus de détails. Les utilisateurs d’abonnement Claude reçoivent déjà automatiquement un TTL d’une heure et n’ont pas besoin de définir cette variable.

Documentation connexe