Zum Hauptinhalt springen
Das Claude Agent SDK bietet detaillierte Token-Nutzungsinformationen für jede Interaktion mit Claude. Dieser Leitfaden erklärt, wie Sie die Nutzung ordnungsgemäß verfolgen und die Kostenberichterstattung verstehen, besonders bei parallelen Tool-Verwendungen und mehrstufigen Gesprächen. Für die vollständige API-Dokumentation siehe die TypeScript SDK-Referenz und Python SDK-Referenz.
Die Felder total_cost_usd und costUSD sind clientseitige Schätzungen, keine verbindlichen Abrechnungsdaten. Das SDK berechnet sie lokal aus einer Preistabelle, die zur Build-Zeit gebündelt wird, daher können sie von dem abweichen, was Sie tatsächlich abgerechnet bekommen, wenn:
  • sich die Preise ändern
  • die installierte SDK-Version ein Modell nicht erkennt
  • Abrechnungsregeln gelten, die der Client nicht modellieren kann
Verwenden Sie diese Felder für Entwicklungseinblicke und ungefähre Budgetierung. Für verbindliche Abrechnung verwenden Sie die Usage and Cost API oder die Seite „Nutzung” in der Claude Console. Berechnen Sie Endbenutzer nicht und treffen Sie keine finanziellen Entscheidungen basierend auf diesen Feldern.

Token-Nutzung verstehen

Die TypeScript- und Python-SDKs stellen die gleichen Nutzungsdaten mit unterschiedlichen Feldnamen bereit:
  • TypeScript bietet Token-Aufschlüsselungen pro Schritt auf jeder Assistenten-Nachricht (message.message.id, message.message.usage), Kosten pro Modell über modelUsage auf der Ergebnis-Nachricht und eine kumulative Summe auf der Ergebnis-Nachricht.
  • Python bietet Token-Aufschlüsselungen pro Schritt auf jeder Assistenten-Nachricht (message.usage, message.message_id), Kosten pro Modell über model_usage auf der Ergebnis-Nachricht und die akkumulierte Summe auf der Ergebnis-Nachricht (total_cost_usd und usage dict).
Beide SDKs verwenden das gleiche zugrunde liegende Kostenmodell und stellen die gleiche Granularität bereit. Der Unterschied liegt in der Feldbennung und wo die Nutzung pro Schritt verschachtelt ist. Die Kostenverfolgung hängt davon ab, zu verstehen, wie das SDK Nutzungsdaten umfasst:
  • query() Aufruf: eine Invokation der query() Funktion des SDK. Ein einzelner Aufruf kann mehrere Schritte beinhalten (Claude antwortet, verwendet Tools, erhält Ergebnisse, antwortet erneut). Jeder Aufruf erzeugt am Ende eine result Nachricht.
  • Schritt: ein einzelner Request/Response-Zyklus innerhalb eines query() Aufrufs. Jeder Schritt erzeugt Assistenten-Nachrichten mit Token-Nutzung.
  • Sitzung: eine Serie von query() Aufrufen, die durch eine Sitzungs-ID verknüpft sind (mit der resume Option). Jeder query() Aufruf innerhalb einer Sitzung meldet seine eigenen Kosten unabhängig.
Das folgende Diagramm zeigt den Nachrichtenstrom aus einem einzelnen query() Aufruf, mit Token-Nutzung, die bei jedem Schritt gemeldet wird, und der kumulativen Schätzung am Ende: Diagramm, das eine Abfrage zeigt, die zwei Schritte von Nachrichten erzeugt. Schritt 1 hat vier Assistenten-Nachrichten, die die gleiche ID und Nutzung teilen (einmal zählen), Schritt 2 hat eine Assistenten-Nachricht mit einer neuen ID, und die endgültige Ergebnis-Nachricht zeigt die geschätzte total_cost_usd.
1

Jeder Schritt erzeugt Assistenten-Nachrichten

Wenn Claude antwortet, sendet es eine oder mehrere Assistenten-Nachrichten. In TypeScript enthält jede Assistenten-Nachricht eine verschachtelte BetaMessage (zugänglich über message.message) mit einer id und einem usage Objekt mit Token-Zählungen (input_tokens, output_tokens). In Python stellt die AssistantMessage Dataclass die gleichen Daten direkt über message.usage und message.message_id bereit. Wenn Claude mehrere Tools in einer Runde verwendet, teilen alle Nachrichten in dieser Runde die gleiche ID, daher deduplizieren Sie nach ID, um Doppelzählungen zu vermeiden.
2

Die Ergebnis-Nachricht bietet die kumulative Schätzung

Wenn der query() Aufruf abgeschlossen ist, gibt das SDK eine Ergebnis-Nachricht mit total_cost_usd und kumulativer usage aus. Dies ist in TypeScript (SDKResultMessage) und Python (ResultMessage) verfügbar. Wenn Sie mehrere query() Aufrufe tätigen (zum Beispiel in einer mehrstufigen Sitzung), spiegelt jedes Ergebnis nur die Kosten dieses einzelnen Aufrufs wider. Wenn Sie nur die geschätzte Summe benötigen, können Sie die Nutzung pro Schritt ignorieren und diesen einzelnen Wert lesen.

Gesamtkosten einer Abfrage abrufen

Die Ergebnis-Nachricht (TypeScript, Python) markiert das Ende der Agent-Schleife für einen query()-Aufruf. Sie enthält total_cost_usd, die geschätzte kumulative Kosten über alle Schritte in diesem Aufruf. Dies funktioniert sowohl für erfolgreiche als auch für Fehler-Ergebnisse. Wenn Sie Sitzungen verwenden, um mehrere query()-Aufrufe zu tätigen, spiegelt jedes Ergebnis nur die Kosten dieses einzelnen Aufrufs wider. Die folgenden Beispiele durchlaufen den Nachrichtenstrom aus einem query()-Aufruf und geben die Gesamtkosten aus, wenn die result-Nachricht ankommt:
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}`);
  }
}

Nutzung pro Schritt und pro Modell verfolgen

Die Beispiele in diesem Abschnitt verwenden TypeScript-Feldnamen. In Python sind die entsprechenden Felder AssistantMessage.usage und AssistantMessage.message_id für die Nutzung pro Schritt, und ResultMessage.model_usage für Aufschlüsselungen pro Modell.

Nutzung pro Schritt verfolgen

Jede Assistenten-Nachricht enthält eine verschachtelte BetaMessage (zugänglich über message.message) mit einer id und einem usage Objekt mit Token-Zählungen. Wenn Claude Tools parallel verwendet, teilen mehrere Nachrichten die gleiche id mit identischen Nutzungsdaten. Verfolgen Sie, welche IDs Sie bereits gezählt haben, und überspringen Sie Duplikate, um aufgeblähte Summen zu vermeiden.
Parallele Tool-Aufrufe erzeugen mehrere Assistenten-Nachrichten, deren verschachtelte BetaMessage die gleiche id und identische Nutzung teilt. Deduplizieren Sie immer nach ID, um genaue Token-Zählungen pro Schritt zu erhalten.
Das folgende Beispiel akkumuliert Input- und Output-Tokens über alle Schritte, zählt jede eindeutige Nachrichten-ID nur einmal:
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}`);

Nutzung pro Modell aufschlüsseln

Die Ergebnis-Nachricht enthält modelUsage, eine Zuordnung von Modellname zu Token-Zählungen und Kosten pro Modell. Dies ist nützlich, wenn Sie mehrere Modelle ausführen (zum Beispiel Haiku für Sub-Agenten und Opus für den Haupt-Agenten) und sehen möchten, wohin die Tokens gehen. Das folgende Beispiel führt eine Abfrage aus und gibt die Kosten und Token-Aufschlüsselung für jedes verwendete Modell aus:
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}`);
  }
}

Kosten über mehrere Aufrufe akkumulieren

Jeder query() Aufruf gibt seinen eigenen total_cost_usd zurück. Das SDK bietet keine Sitzungs-Ebenen-Summe, daher müssen Sie, wenn Ihre Anwendung mehrere query() Aufrufe tätigt (zum Beispiel in einer mehrstufigen Sitzung oder über verschiedene Benutzer), die Summen selbst akkumulieren. Die folgenden Beispiele führen zwei query() Aufrufe nacheinander aus, addieren den total_cost_usd jedes Aufrufs zu einer laufenden Summe und geben sowohl die Kosten pro Aufruf als auch die kombinierten Kosten aus:
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)}`);

Fehler, Caching und Token-Diskrepanzen behandeln

Für genaue Kostenverfolgung müssen Sie fehlgeschlagene Gespräche, Cache-Token-Preisgestaltung und gelegentliche Berichterstattungsinkonsistenzen berücksichtigen.

Output-Token-Diskrepanzen auflösen

In seltenen Fällen können Sie unterschiedliche output_tokens Werte für Nachrichten mit der gleichen ID beobachten. Wenn dies auftritt:
  1. Verwenden Sie den höchsten Wert: die letzte Nachricht in einer Gruppe enthält typischerweise die genaue Summe.
  2. Bevorzugen Sie die Ergebnis-Nachricht: die total_cost_usd in der Ergebnis-Nachricht spiegelt die akkumulierte Schätzung des SDK über alle Schritte wider, daher ist sie zuverlässiger als die Summe der Werte pro Schritt selbst. Es ist immer noch eine Schätzung und kann von Ihrer tatsächlichen Rechnung abweichen.
  3. Melden Sie Inkonsistenzen: reichen Sie Probleme im Claude Code GitHub Repository ein.

Kosten bei fehlgeschlagenen Gesprächen verfolgen

Sowohl erfolgreiche als auch Fehler-Ergebnis-Nachrichten enthalten usage und total_cost_usd. Wenn ein Gespräch in der Mitte fehlschlägt, haben Sie immer noch Tokens bis zum Punkt des Fehlers verbraucht. Lesen Sie Kostendaten immer aus der Ergebnis-Nachricht, unabhängig von ihrem subtype.

Cache-Tokens verfolgen

Das Agent SDK verwendet automatisch prompt caching, um Kosten bei wiederholtem Inhalt zu reduzieren. Sie müssen Caching nicht selbst konfigurieren. Das Nutzungs-Objekt enthält zwei zusätzliche Felder für Cache-Verfolgung:
  • cache_creation_input_tokens: Tokens, die zum Erstellen neuer Cache-Einträge verwendet werden (berechnet zu einem höheren Satz als Standard-Input-Tokens).
  • cache_read_input_tokens: Tokens, die aus vorhandenen Cache-Einträgen gelesen werden (berechnet zu einem reduzierten Satz).
Verfolgen Sie diese separat von input_tokens, um Cache-Einsparungen zu verstehen. In TypeScript sind diese Felder auf dem Usage Objekt typisiert. In Python erscheinen sie als Schlüssel im ResultMessage.usage dict (zum Beispiel, message.usage.get("cache_read_input_tokens", 0)).

Prompt-Cache-TTL auf eine Stunde verlängern

Cache-Einträge, die vom SDK geschrieben werden, verwenden standardmäßig eine 5-Minuten-TTL, wenn Sie sich mit einem API-Schlüssel authentifizieren oder auf Amazon Bedrock, Google Cloud Vertex AI oder Microsoft Foundry ausführen. Wenn Ihre Workload viele kurze Sitzungen gegen das gleiche System-Prompt und den gleichen Kontext mit Lücken länger als 5 Minuten zwischen ihnen ausführt, läuft der Cache zwischen Sitzungen ab und jede neue Sitzung zahlt den vollen Input-Preis. Um eine 1-Stunden-TTL bei Cache-Schreibvorgängen anzufordern, setzen Sie die ENABLE_PROMPT_CACHING_1H Umgebungsvariable. Sie können sie in Ihrer Shell- oder Container-Umgebung exportieren oder sie durch options.env übergeben. Das folgende Beispiel aktiviert 1-Stunden-TTL für einen Agenten, der auf Bedrock ausgeführt wird:
options = ClaudeAgentOptions(
    env={
        "CLAUDE_CODE_USE_BEDROCK": "1",
        "ENABLE_PROMPT_CACHING_1H": "1",
    },
)
Cache-Schreibvorgänge mit einer 1-Stunden-TTL werden zu einem höheren Satz als 5-Minuten-Schreibvorgänge berechnet, daher aktiviert dies einen Austausch von höheren Schreibkosten für mehr Cache-Lesevorgänge. Siehe prompt caching Preisgestaltung für Details. Claude-Abonnement-Benutzer erhalten bereits automatisch 1-Stunden-TTL und müssen diese Variable nicht setzen.

Verwandte Dokumentation