Kosten und Nutzung verfolgen
SDK-Kostenverfolgung
Das Claude Agent SDK bietet detaillierte Token-Nutzungsinformationen für jede Interaktion mit Claude. Dieser Leitfaden erklärt, wie Sie Kosten ordnungsgemäß verfolgen und die Nutzungsberichterstattung verstehen, insbesondere beim Umgang mit parallelen Tool-Verwendungen und mehrstufigen Unterhaltungen.
Für die vollständige API-Dokumentation siehe die TypeScript SDK-Referenz.
Token-Nutzung verstehen
Wenn Claude Anfragen verarbeitet, meldet es die Token-Nutzung auf Nachrichtenebene. Diese Nutzungsdaten sind wesentlich für die Kostenverfolgung und die angemessene Abrechnung von Benutzern.
Schlüsselkonzepte
- Schritte: Ein Schritt ist ein einzelnes Anfrage/Antwort-Paar zwischen Ihrer Anwendung und Claude
- Nachrichten: Einzelne Nachrichten innerhalb eines Schritts (Text, Tool-Verwendungen, Tool-Ergebnisse)
- Nutzung: Token-Verbrauchsdaten, die an Assistenten-Nachrichten angehängt sind
Struktur der Nutzungsberichterstattung
Einzelne vs. parallele Tool-Verwendung
Wenn Claude Tools ausführt, unterscheidet sich die Nutzungsberichterstattung je nachdem, ob Tools sequenziell oder parallel ausgeführt werden:
import { query } from "@anthropic-ai/claude-agent-sdk";
// Beispiel: Nutzung in einer Unterhaltung verfolgen
const result = await query({
prompt: "Analysiere diese Codebasis und führe Tests aus",
options: {
onMessage: (message) => {
if (message.type === 'assistant' && message.usage) {
console.log(`Nachrichten-ID: ${message.id}`);
console.log(`Nutzung:`, message.usage);
}
}
}
});from claude_agent_sdk import query, ClaudeAgentOptions, AssistantMessage
import asyncio
# Beispiel: Nutzung in einer Unterhaltung verfolgen
async def track_usage():
# Nachrichten verarbeiten, während sie eintreffen
async for message in query(
prompt="Analysiere diese Codebasis und führe Tests aus"
):
if isinstance(message, AssistantMessage) and hasattr(message, 'usage'):
print(f"Nachrichten-ID: {message.id}")
print(f"Nutzung: {message.usage}")
asyncio.run(track_usage())Beispiel für Nachrichtenfluss
So werden Nachrichten und Nutzung in einer typischen mehrstufigen Unterhaltung gemeldet:
<!-- Schritt 1: Erste Anfrage mit parallelen Tool-Verwendungen -->
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)
<!-- Schritt 2: Folge-Antwort -->
assistant (text) { id: "msg_2", usage: { output_tokens: 98, ... } }Wichtige Nutzungsregeln
1. Gleiche ID = Gleiche Nutzung
Alle Nachrichten mit demselben id-Feld melden identische Nutzung. Wenn Claude mehrere Nachrichten im selben Zug sendet (z.B. Text + Tool-Verwendungen), teilen sie dieselbe Nachrichten-ID und Nutzungsdaten.
// Alle diese Nachrichten haben dieselbe ID und Nutzung
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 } }
];
// Nur einmal pro eindeutiger Nachrichten-ID berechnen
const uniqueUsage = messages[0].usage; // Gleich für alle Nachrichten mit dieser ID2. Einmal pro Schritt berechnen
Sie sollten Benutzer nur einmal pro Schritt berechnen, nicht für jede einzelne Nachricht. Wenn Sie mehrere Assistenten-Nachrichten mit derselben ID sehen, verwenden Sie die Nutzung von einer beliebigen davon.
3. Ergebnisnachricht enthält kumulative Nutzung
Die finale result-Nachricht enthält die gesamte kumulative Nutzung aller Schritte in der Unterhaltung:
// Finales Ergebnis enthält Gesamtnutzung
const result = await query({
prompt: "Mehrstufige Aufgabe",
options: { /* ... */ }
});
console.log("Gesamtnutzung:", result.usage);
console.log("Gesamtkosten:", result.usage.total_cost_usd);Implementierung: Kostenverfolgungssystem
Hier ist ein vollständiges Beispiel für die Implementierung eines Kostenverfolgungssystems:
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) {
// Nur Assistenten-Nachrichten mit Nutzung verarbeiten
if (message.type !== 'assistant' || !message.usage) {
return;
}
// Überspringen, wenn wir diese Nachrichten-ID bereits verarbeitet haben
if (this.processedMessageIds.has(message.id)) {
return;
}
// Als verarbeitet markieren und Nutzung aufzeichnen
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 {
// Implementieren Sie hier Ihre Preisberechnung
// Dies ist ein vereinfachtes Beispiel
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;
}
}
// Verwendung
const tracker = new CostTracker();
const { result, stepUsages, totalCost } = await tracker.trackConversation(
"Analysiere und refaktoriere diesen Code"
);
console.log(`Verarbeitete Schritte: ${stepUsages.length}`);
console.log(`Gesamtkosten: $${totalCost.toFixed(4)}`);Umgang mit Sonderfällen
Diskrepanzen bei Output-Token
In seltenen Fällen könnten Sie unterschiedliche output_tokens-Werte für Nachrichten mit derselben ID beobachten. Wenn dies auftritt:
- Verwenden Sie den höchsten Wert - Die letzte Nachricht in einer Gruppe enthält typischerweise die genaue Gesamtsumme
- Gegen Gesamtkosten verifizieren - Die
total_cost_usdin der Ergebnisnachricht ist maßgebend - Inkonsistenzen melden - Reichen Sie Probleme im Claude Code GitHub-Repository ein
Cache-Token-Verfolgung
Bei Verwendung von Prompt-Caching verfolgen Sie diese Token-Typen separat:
interface CacheUsage {
cache_creation_input_tokens: number;
cache_read_input_tokens: number;
cache_creation: {
ephemeral_5m_input_tokens: number;
ephemeral_1h_input_tokens: number;
};
}Best Practices
- Nachrichten-IDs für Deduplizierung verwenden: Verfolgen Sie immer verarbeitete Nachrichten-IDs, um Doppelberechnungen zu vermeiden
- Die Ergebnisnachricht überwachen: Das finale Ergebnis enthält maßgebende kumulative Nutzung
- Protokollierung implementieren: Protokollieren Sie alle Nutzungsdaten für Auditing und Debugging
- Fehler elegant behandeln: Verfolgen Sie partielle Nutzung auch wenn eine Unterhaltung fehlschlägt
- Streaming berücksichtigen: Für Streaming-Antworten akkumulieren Sie Nutzung während Nachrichten eintreffen
Referenz für Nutzungsfelder
Jedes Nutzungsobjekt enthält:
input_tokens: Verarbeitete Basis-Input-Tokenoutput_tokens: In der Antwort generierte Tokencache_creation_input_tokens: Token, die zur Erstellung von Cache-Einträgen verwendet wurdencache_read_input_tokens: Aus dem Cache gelesene Tokenservice_tier: Die verwendete Service-Stufe (z.B. "standard")total_cost_usd: Gesamtkosten in USD (nur in Ergebnisnachricht)
Beispiel: Aufbau eines Abrechnungs-Dashboards
So aggregieren Sie Nutzungsdaten für ein Abrechnungs-Dashboard:
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);
// Benutzer-Gesamtsummen aktualisieren
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
};
}
}Verwandte Dokumentation
- TypeScript SDK-Referenz - Vollständige API-Dokumentation
- SDK-Übersicht - Erste Schritte mit dem SDK
- SDK-Berechtigungen - Tool-Berechtigungen verwalten