Das Claude Agent SDK bietet detaillierte Token-Nutzungsinformationen für jede Interaktion mit Claude. Dieser Leitfaden erklärt, wie Sie Kosten ordnungsgemäß verfolgen und Nutzungsberichte verstehen, besonders wenn Sie mit parallelen Tool-Verwendungen und mehrstufigen Gesprächen umgehen.
Für die vollständige API-Dokumentation siehe die TypeScript SDK-Referenz.
Wenn Claude Anfragen verarbeitet, meldet es Token-Nutzung auf Nachrichtenebene. Diese Nutzungsdaten sind essentiell für die Verfolgung von Kosten und die angemessene Abrechnung von Benutzern.
Wenn Claude Tools ausführt, unterscheidet sich die Nutzungsberichterstellung je nachdem, ob Tools sequenziell oder parallel ausgeführt werden:
import { query } from "@anthropic-ai/claude-agent-sdk";
// Beispiel: Nutzungsverfolgung in einem Gespräch
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);
}
}
}
});So werden Nachrichten und Nutzung in einem typischen mehrstufigen Gespräch gemeldet:
<!-- Schritt 1: Anfängliche 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: Nachfolgende Antwort -->
assistant (text) { id: "msg_2", usage: { output_tokens: 98, ... } }Alle Nachrichten mit dem gleichen id-Feld melden identische Nutzung. Wenn Claude mehrere Nachrichten in derselben Runde sendet (z.B. Text + Tool-Verwendungen), teilen sie sich die gleiche Nachrichten-ID und Nutzungsdaten.
// Alle diese Nachrichten haben die gleiche 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 } }
];
// Berechne nur einmal pro eindeutiger Nachrichten-ID
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 Assistent-Nachrichten mit der gleichen ID sehen, verwenden Sie die Nutzung von einer beliebigen davon.
Die finale result-Nachricht enthält die gesamte kumulative Nutzung aus allen Schritten im Gespräch:
// Finales Ergebnis enthält Gesamtnutzung
const result = await query({
prompt: "Multi-step task",
options: { /* ... */ }
});
console.log("Total usage:", result.usage);
console.log("Total cost:", result.usage.total_cost_usd);Die Ergebnis-Nachricht enthält auch modelUsage, das autorisierte Pro-Modell-Nutzungsdaten bereitstellt. Wie total_cost_usd ist dieses Feld genau und geeignet für Abrechnungszwecke. Dies ist besonders nützlich, wenn mehrere Modelle verwendet werden (z.B. Haiku für Sub-Agenten, Opus für den Haupt-Agenten).
// modelUsage bietet Pro-Modell-Aufschlüsselung
type ModelUsage = {
inputTokens: number
outputTokens: number
cacheReadInputTokens: number
cacheCreationInputTokens: number
webSearchRequests: number
costUSD: number
contextWindow: number
}
// Zugriff aus Ergebnis-Nachricht
const result = await query({ prompt: "..." });
// result.modelUsage ist eine Zuordnung von Modellname zu 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}`);
}Für die vollständigen Typ-Definitionen siehe die TypeScript SDK-Referenz.
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) {
// Verarbeite nur Assistent-Nachrichten mit Nutzung
if (message.type !== 'assistant' || !message.usage) {
return;
}
// Überspringe, wenn wir diese Nachrichten-ID bereits verarbeitet haben
if (this.processedMessageIds.has(message.id)) {
return;
}
// Markiere als verarbeitet und erfasse Nutzung
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 {
// Implementiere deine Preisberechnung hier
// 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;
}
}
// Nutzung
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)}`);In seltenen Fällen können Sie unterschiedliche output_tokens-Werte für Nachrichten mit der gleichen ID beobachten. Wenn dies auftritt:
total_cost_usd in der Ergebnis-Nachricht ist maßgeblichBei 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: Basis-Input-Tokens verarbeitetoutput_tokens: Tokens generiert in der Antwortcache_creation_input_tokens: Tokens verwendet zum Erstellen von Cache-Einträgencache_read_input_tokens: Tokens gelesen aus Cacheservice_tier: Die verwendete Service-Stufe (z.B. "standard")total_cost_usd: Gesamtkosten in USD (nur in Ergebnis-Nachricht)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);
// Aktualisiere Benutzer-Gesamtwerte
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?