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.
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.
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);
}
}
}
});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, ... } }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 IDSie 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.
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);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)}`);In seltenen Fällen könnten Sie unterschiedliche output_tokens-Werte für Nachrichten mit derselben ID beobachten. Wenn dies auftritt:
total_cost_usd in der Ergebnisnachricht ist maßgebendBei 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;
};
}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)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
};
}
}