O Claude Agent SDK fornece informações detalhadas sobre o uso de tokens para cada interação com Claude. Este guia explica como rastrear adequadamente os custos e entender os relatórios de uso, especialmente ao lidar com usos paralelos de ferramentas e conversas de múltiplas etapas.
Para documentação completa da API, consulte a referência do SDK TypeScript.
Quando Claude processa solicitações, ele relata o uso de tokens no nível da mensagem. Esses dados de uso são essenciais para rastrear custos e faturar usuários adequadamente.
Quando Claude executa ferramentas, os relatórios de uso diferem com base em se as ferramentas são executadas sequencialmente ou em paralelo:
import { query } from "@anthropic-ai/claude-agent-sdk";
// Exemplo: Rastreando uso em uma conversa
const result = await query({
prompt: "Analise esta base de código e execute testes",
options: {
onMessage: (message) => {
if (message.type === 'assistant' && message.usage) {
console.log(`ID da Mensagem: ${message.id}`);
console.log(`Uso:`, message.usage);
}
}
}
});Aqui está como as mensagens e o uso são relatados em uma conversa típica de múltiplas etapas:
<!-- Etapa 1: Solicitação inicial com usos paralelos de ferramentas -->
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)
<!-- Etapa 2: Resposta de acompanhamento -->
assistant (text) { id: "msg_2", usage: { output_tokens: 98, ... } }Todas as mensagens com o mesmo campo id relatam uso idêntico. Quando Claude envia múltiplas mensagens no mesmo turno (por exemplo, texto + usos de ferramentas), elas compartilham o mesmo ID de mensagem e dados de uso.
// Todas essas mensagens têm o mesmo ID e uso
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 } }
];
// Cobre apenas uma vez por ID de mensagem único
const uniqueUsage = messages[0].usage; // Mesmo para todas as mensagens com este IDVocê deve cobrar dos usuários apenas uma vez por etapa, não para cada mensagem individual. Quando você vê múltiplas mensagens do assistente com o mesmo ID, use o uso de qualquer uma delas.
A mensagem final result contém o uso cumulativo total de todas as etapas na conversa:
// Resultado final inclui uso total
const result = await query({
prompt: "Tarefa de múltiplas etapas",
options: { /* ... */ }
});
console.log("Uso total:", result.usage);
console.log("Custo total:", result.usage.total_cost_usd);Aqui está um exemplo completo de implementação de um sistema de rastreamento de custos:
Em casos raros, você pode observar valores diferentes de output_tokens para mensagens com o mesmo ID. Quando isso ocorre:
total_cost_usd na mensagem de resultado é autoritativoAo usar cache de prompt, rastreie esses tipos de tokens separadamente:
interface CacheUsage {
cache_creation_input_tokens: number;
cache_read_input_tokens: number;
cache_creation: {
ephemeral_5m_input_tokens: number;
ephemeral_1h_input_tokens: number;
};
}Cada objeto de uso contém:
input_tokens: Tokens de entrada base processadosoutput_tokens: Tokens gerados na respostacache_creation_input_tokens: Tokens usados para criar entradas de cachecache_read_input_tokens: Tokens lidos do cacheservice_tier: O nível de serviço usado (por exemplo, "standard")total_cost_usd: Custo total em USD (apenas na mensagem de resultado)Aqui está como agregar dados de uso para um painel de faturamento:
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);
// Atualiza totais do usuário
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
};
}
}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) {
// Processa apenas mensagens do assistente com uso
if (message.type !== 'assistant' || !message.usage) {
return;
}
// Pula se já processamos este ID de mensagem
if (this.processedMessageIds.has(message.id)) {
return;
}
// Marca como processado e registra uso
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 {
// Implemente seu cálculo de preços aqui
// Este é um exemplo simplificado
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;
}
}
// Uso
const tracker = new CostTracker();
const { result, stepUsages, totalCost } = await tracker.trackConversation(
"Analise e refatore este código"
);
console.log(`Etapas processadas: ${stepUsages.length}`);
console.log(`Custo total: $${totalCost.toFixed(4)}`);