AI News Hub Logo

AI News Hub

Como Rastrear Gastos da API OpenAI por Funcionalidade: Guia de Atribuição de Custos

DEV Community
Lucas

Seu extrato do OpenAI diz que você gastou $4.237 no mês passado. Ele não informa que $3.100 vieram de um endpoint de sumarização descontrolado, $700 de um cliente que paga $50/mês e $437 de uma funcionalidade que ninguém usa. Para gerenciar custos de LLM em produção, você precisa atribuir cada requisição a uma funcionalidade, rota, cliente e ambiente — e transformar isso em logs, consultas, alertas e limites operacionais. Experimente o Apidog hoje 💡 O Apidog ajuda a validar requisições em nível de API antes de você ir para produção. Use-o para reproduzir chamadas marcadas, verificar o formato dos logs e confirmar que cada requisição carrega os metadados esperados pelo seu data warehouse. Implemente um wrapper único para chamadas OpenAI. Ele deve: exigir metadados como feature, route, customer_id e environment; capturar response.usage; calcular cost_usd no momento da requisição; emitir uma linha JSON estruturada por chamada; enviar os eventos para seu data warehouse; agregar custo por funcionalidade, rota e cliente; aplicar limites por chave/projeto no painel do OpenAI; validar o fluxo com testes de cenário no Apidog. O painel do OpenAI responde: “Quanto minha organização gastou?” Mas times de produto, engenharia e finanças precisam responder: “Qual funcionalidade, cliente ou rota gerou esse gasto?” Essa diferença importa quando você tem: várias funcionalidades usando o mesmo modelo; clientes B2B com padrões de uso diferentes; jobs assíncronos ou cron jobs; ambientes dev, staging e prod; desenvolvedores testando agentes ou automações; necessidade de calcular margem por cliente. O painel nativo mostra totais diários, modelo e limite de uso. Ele não fornece atribuição por funcionalidade, rota HTTP, cliente ou job interno. A API de uso do OpenAI também retorna dados agregados, não eventos por requisição. Para contexto de precificação, veja a análise de preços do GPT-5.5. Para um problema parecido no lado de ferramentas de desenvolvedor, veja cobrança de uso do GitHub Copilot para equipes de API. A referência oficial da API está em OpenAI API Reference. A unidade de análise deve ser um evento por requisição OpenAI. Um esquema mínimo: Coluna Tipo Exemplo Por que importa request_id uuid 7a91... Idempotência, deduplicação e retentativas timestamp timestamptz 2026-05-06T14:23:01Z Séries temporais e alertas feature text support-chat Funcionalidade do produto route text /api/v1/chat/answer Rota HTTP ou job customer_id text cust_4291 Custo por cliente environment text prod Separar produção de dev/staging model text gpt-5.5 Precificação por modelo prompt_tokens int 15234 Tokens de entrada completion_tokens int 812 Tokens de saída reasoning_tokens int 4500 Tokens de raciocínio cobrados como saída cached_tokens int 12000 Tokens com cache de prompt latency_ms int 2341 Correlação entre custo e UX cost_usd numeric 0.045672 Custo calculado no momento da requisição prompt_cache_key text system-v3 Análise de cache por prompt error_code text 429 Diagnóstico de falhas e retentativas Calcule o custo no momento da gravação, não apenas na consulta. Preços mudam; o evento deve refletir a tarifa aplicada no dia da chamada. Exemplo em Python: PRICING = { # USD por 1M tokens, a partir de maio de 2026 "gpt-5.5": {"input": 5.00, "cached": 2.50, "output": 30.00}, "gpt-5.5-pro": {"input": 30.00, "cached": 15.00, "output": 180.00}, "gpt-5.4": {"input": 2.50, "cached": 1.25, "output": 15.00}, "gpt-5.4-mini": {"input": 0.25, "cached": 0.125, "output": 2.00}, } def compute_cost_usd( model, prompt_tokens, cached_tokens, completion_tokens, reasoning_tokens ): rates = PRICING[model] uncached = max(0, prompt_tokens - cached_tokens) input_cost = (uncached * rates["input"]) / 1_000_000 cache_cost = (cached_tokens * rates["cached"]) / 1_000_000 output_cost = ( (completion_tokens + reasoning_tokens) * rates["output"] ) / 1_000_000 return round(input_cost + cache_cost + output_cost, 6) Tokens de raciocínio aparecem em usage.completion_tokens_details.reasoning_tokens, mas são cobrados como saída. Se você ignorar isso, subestimará o custo de chamadas com modo Thinking. Para a matemática completa, consulte a análise de preços do GPT-5.5. A regra prática: nenhuma funcionalidade deve chamar o SDK diretamente. Todas as chamadas passam por um wrapper. import time import uuid import json import logging from openai import OpenAI client = OpenAI() logger = logging.getLogger("llm.cost") def call_with_attribution( *, feature, route, customer_id, environment, model, messages, **openai_kwargs ): request_id = str(uuid.uuid4()) started = time.time() error_code = None response = None try: response = client.chat.completions.create( model=model, messages=messages, **openai_kwargs ) return response except Exception as e: error_code = getattr(e, "code", "unknown_error") raise finally: latency_ms = int((time.time() - started) * 1000) usage = response.usage if response else None prompt_tokens = getattr(usage, "prompt_tokens", 0) completion_tokens = getattr(usage, "completion_tokens", 0) cached_tokens = getattr( getattr(usage, "prompt_tokens_details", None), "cached_tokens", 0 ) or 0 reasoning_tokens = getattr( getattr(usage, "completion_tokens_details", None), "reasoning_tokens", 0 ) or 0 cost_usd = compute_cost_usd( model, prompt_tokens, cached_tokens, completion_tokens, reasoning_tokens ) logger.info(json.dumps({ "event": "openai.request", "request_id": request_id, "feature": feature, "route": route, "customer_id": customer_id, "environment": environment, "model": model, "prompt_tokens": prompt_tokens, "completion_tokens": completion_tokens, "reasoning_tokens": reasoning_tokens, "cached_tokens": cached_tokens, "latency_ms": latency_ms, "cost_usd": cost_usd, "error_code": error_code, })) Uso: response = call_with_attribution( feature="support-chat", route="/api/v1/chat/answer", customer_id="cust_4291", environment="prod", model="gpt-5.5", messages=[ {"role": "system", "content": "Você é um assistente de suporte."}, {"role": "user", "content": "Como redefino minha senha?"} ] ) Esse wrapper vira a superfície única de governança. A partir dele, envie os logs para BigQuery, ClickHouse, Snowflake, Postgres ou qualquer pipeline existente com Vector, Fluent Bit, Logstash ou coletor OTLP. Em Node.js, o padrão é o mesmo: receba metadados obrigatórios; chame o SDK; leia response.usage; calcule o custo; emita um JSON por requisição. Depois que os eventos chegam ao warehouse, a atribuição vira SQL. SELECT feature, DATE_TRUNC(timestamp, DAY) AS day, COUNT(*) AS requests, SUM(cost_usd) AS spend_usd, SUM(prompt_tokens + completion_tokens + reasoning_tokens) AS total_tokens, AVG(latency_ms) AS avg_latency_ms, SUM(cached_tokens) / NULLIF(SUM(prompt_tokens), 0) AS cache_hit_rate FROM openai_events WHERE environment = 'prod' AND timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY) GROUP BY feature, day ORDER BY day DESC, spend_usd DESC; SELECT customer_id, COUNT(*) AS requests, SUM(cost_usd) AS spend_usd, AVG(cost_usd) AS avg_cost_per_request FROM openai_events WHERE environment = 'prod' AND timestamp >= DATE_TRUNC(CURRENT_TIMESTAMP(), MONTH) GROUP BY customer_id ORDER BY spend_usd DESC LIMIT 20; SELECT route, feature, COUNT(*) AS requests, SUM(cost_usd) AS spend_usd FROM openai_events WHERE environment = 'prod' AND timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 1 DAY) GROUP BY route, feature ORDER BY spend_usd DESC LIMIT 20; Antes de confiar nos dashboards, valide o fluxo de ponta a ponta. Um campo errado no log pode gerar atribuição silenciosamente incorreta. Use o Apidog para criar cenários que executam seus endpoints de IA e verificam se os metadados chegam corretamente. Checklist: Crie uma requisição para seu endpoint de IA. Envie customer_id, feature e demais dados esperados. Execute a chamada em staging. Capture a resposta e o evento de log. Verifique se o log contém: feature; route; customer_id; environment; model; prompt_tokens > 0; cost_usd > 0; request_id. Reexecute o cenário e valide o comportamento de retentativas. Rode o mesmo cenário em produção usando variáveis de ambiente do Apidog. Exemplo de payload esperado no log: { "event": "openai.request", "request_id": "7a91f5c8-7a1e-4c7a-83e0-df56b6b5b111", "feature": "support-chat", "route": "/api/v1/chat/answer", "customer_id": "cust_4291", "environment": "staging", "model": "gpt-5.5", "prompt_tokens": 1234, "completion_tokens": 210, "reasoning_tokens": 0, "cached_tokens": 800, "latency_ms": 1820, "cost_usd": 0.00834, "error_code": null } Para ampliar esse fluxo, veja ferramentas de teste de API para engenheiros de QA e desenvolvimento de API contract-first. A atribuição só fica operacional quando você adiciona limites. Exemplos: prod-support-chat prod-summarization prod-rag-search staging-all dev-sandbox Isso permite aplicar limites no painel do OpenAI e reduzir o impacto de loops descontrolados. Exemplo: alertar quando uma funcionalidade gastar 3x mais que sua média horária dos últimos 7 dias. WITH hourly AS ( SELECT feature, TIMESTAMP_TRUNC(timestamp, HOUR) AS hour, SUM(cost_usd) AS spend_usd FROM openai_events WHERE environment = 'prod' AND timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 7 DAY) GROUP BY feature, hour ), baseline AS ( SELECT feature, AVG(spend_usd) AS avg_hourly_spend FROM hourly WHERE hour = TIMESTAMP_TRUNC(CURRENT_TIMESTAMP(), HOUR) GROUP BY feature ) SELECT c.feature, c.current_spend, b.avg_hourly_spend FROM current_hour c JOIN baseline b USING (feature) WHERE c.current_spend > b.avg_hourly_spend * 3; Envie o resultado para Slack, PagerDuty, Opsgenie ou outro canal de incidentes. O GPT-5.5 cobra 50% da taxa de entrada para tokens em cache. Para melhorar a taxa de acerto: mantenha o prompt de sistema estável; coloque variáveis no fim do prompt; evite alterar instruções globais sem necessidade; monitore cache_hit_rate por funcionalidade. A documentação oficial está em Prompt Caching. Use Batch para cargas que não precisam de resposta síncrona: sumarização noturna; avaliações; reprocessamento de documentos; geração de embeddings; rotinas de backfill. Marque os eventos com batch_job_id para manter a atribuição. Se você usa modelos com configuração de raciocínio, audite o nível aplicado por funcionalidade. Perguntas úteis: medium é realmente necessário? low passa nos critérios de qualidade? qual é o custo por resposta aceita? o ganho de qualidade justifica o aumento de tokens? Para mais detalhes, veja como usar a API GPT-5.5. Prompts longos são caros. Monitore: média de prompt_tokens por funcionalidade; crescimento semanal; rotas com prompts fora do padrão; requisições próximas do limite. Se uma funcionalidade cresce em tokens sem mudança de produto, o prompt provavelmente está acumulando contexto desnecessário. O OpenAI aplica multiplicadores em requisições acima de 272K tokens: entrada 2x e saída 1.5x. Adicione um guardrail no wrapper: if prompt_tokens > 250_000: logger.warning(json.dumps({ "event": "openai.prompt_near_large_context_threshold", "request_id": request_id, "feature": feature, "route": route, "customer_id": customer_id, "prompt_tokens": prompt_tokens })) Veja os detalhes no post sobre precificação do GPT-5.5. Evite estes padrões: contar tokens de raciocínio como entrada; confiar no painel do OpenAI para alertas em tempo real; deixar feature ou customer_id como null; marcar apenas endpoints HTTP e esquecer workers, filas e cron jobs; usar unknown como valor padrão silencioso; amostrar logs de custo; calcular custo apenas no dashboard, sem persistir cost_usd; não deduplicar retentativas; misturar ambientes dev, staging e prod na mesma análise. Para jobs assíncronos, use rotas sintéticas: cron:nightly-summarize queue:document-classification worker:embedding-backfill webhook:ticket-created Abordagem O que faz bem Custo Quando usar API de uso do OpenAI Nativa, sem configuração, precisa ao centavo Grátis Um projeto, uma funcionalidade, sem atribuição por cliente Helicone Proxy drop-in, painéis, cache, custos por usuário Camada gratuita; pago a partir de $20/mês Você quer um painel rápido e aceita proxy no caminho Langfuse Código aberto, self-hosted ou nuvem, traces + custo Self-host gratuito; nuvem a partir de $29/mês Você quer rastreamento e custo em uma ferramenta open source LangSmith Integração com LangChain, avaliação + custo Pago a partir de $39/usuário/mês Você já usa LangChain Data warehouse próprio Controle total e integração com sua stack Tempo de engenharia Cargas grandes, dimensões customizadas e requisitos de dados Trade-offs: Proxy adiciona um salto no caminho crítico. Observabilidade self-hosted exige operação. Data warehouse próprio exige consultas, alertas e manutenção. API de uso nativa é simples, mas limitada para atribuição detalhada. Leituras úteis: Guia da Helicone sobre rastreamento de custos de LLM Documentação da Langfuse sobre rastreamento de custos Plataformas de API para arquitetura de microsserviços Uma empresa de inteligência de vendas gasta $80.000/mês com OpenAI. Sem atribuição, esse número é apenas uma linha de custo. Com customer_id, ela descobre que 12% dos clientes geram 71% do gasto. A partir disso, pode: criar cotas por plano; cobrar excedente; limitar abuso; medir margem por cliente; ajustar preços com dados reais. Uma organização oferece um assistente GPT-5.5 interno para devs. Ao usar customer_id = dev_email, a equipe de plataforma identifica que três pessoas geram 50% do gasto. Duas estão executando loops de agentes esquecidos. Uma está usando legitimamente para trabalho crítico. Resultado: corte de desperdício e cota maior para o uso legítimo. Antes de lançar uma sumarização com IA, o time estima: tokens médios de entrada; tokens médios de saída; chamadas por usuário ativo; usuários ativos esperados; custo por usuário/dia. Com histórico por funcionalidade, a previsão deixa de ser chute e vira modelo financeiro. O painel do OpenAI mostra quanto você gastou. Ele não mostra por que você gastou. Para tratar IA como custo de produto, implemente: wrapper obrigatório para chamadas OpenAI; metadados por requisição; cálculo de custo no momento da gravação; logs estruturados; agregação no data warehouse; limites por chave/projeto; alertas por anomalia; testes de ponta a ponta com Apidog. Checklist final: Marque toda requisição com feature, route, customer_id e environment. Calcule cost_usd no momento da chamada. Registre uma linha JSON por requisição. Não amostre eventos de custo. Use chaves separadas por ambiente ou funcionalidade. Crie alertas por gasto anômalo. Audite prompts, cache e esforço de raciocínio regularmente. Valide o wrapper com Apidog antes de confiar nos dashboards. Baixe o Apidog e use-o para verificar seu wrapper de atribuição de custos de ponta a ponta: envie requisições marcadas, valide o payload de log e reproduza cenários em diferentes ambientes. Para leitura relacionada, veja a análise de preços do GPT-5.5 e cobrança de uso do GitHub Copilot para equipes de API. Saída. Eles aparecem em usage.completion_tokens_details.reasoning_tokens e devem ser somados a completion_tokens no cálculo de custo. Veja a análise de preços do GPT-5.5. response.usage bate com o painel do OpenAI? As contagens de tokens devem corresponder. Diferenças de custo geralmente vêm de tabelas de preço desatualizadas ou arredondamento. Parcialmente. Chaves de projeto ajudam a separar ambientes ou grandes áreas, mas não resolvem atribuição por funcionalidade, cliente ou rota. Para isso, use metadados no nível da aplicação. Se a requisição falhar antes da execução do modelo, normalmente não há usage. Se uma chamada bem-sucedida for repetida pela aplicação, você pode contar duas vezes. Use request_id idempotente e deduplicação na gravação. Não para tempo real. Ela tem atraso. Use seu próprio pipeline de eventos para alertas e a API de uso para reconciliação. Não. O volume é pequeno e a amostragem quebra a atribuição por cliente e rota. Sim. Adicione uma coluna provider e uma tabela de preços por provedor. O wrapper muda; o modelo de dados e os dashboards continuam. Para comparação, veja precificação da API DeepSeek V4. Sim, mas a matemática muda. Embeddings geralmente são cobrados por token de entrada. Imagens são cobradas por imagem e resolução. Adicione uma coluna endpoint, como chat, embeddings ou image, e calcule o custo conforme o tipo de chamada.