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.
💡 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.
TL;DR
Implemente um wrapper único para chamadas OpenAI. Ele deve:
- exigir metadados como
feature,route,customer_ideenvironment; - capturar
response.usage; - calcular
cost_usdno 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 problema: o painel de cobrança não responde à pergunta certa
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,stagingeprod; - 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.
Modelo de dados para atribuição de custos
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.
Wrapper OpenAI com atribuição de custos
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.
Consultas úteis no data warehouse
Depois que os eventos chegam ao warehouse, a atribuição vira SQL.
Gasto diário por funcionalidade
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;
Top clientes por gasto no mês
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;
Rotas que mais gastaram ontem
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;
Como validar o wrapper com Apidog
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,featuree 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.
Limites e alertas
A atribuição só fica operacional quando você adiciona limites.
1. Use chaves por ambiente ou funcionalidade
Exemplos:
prod-support-chatprod-summarizationprod-rag-searchstaging-alldev-sandbox
Isso permite aplicar limites no painel do OpenAI e reduzir o impacto de loops descontrolados.
2. Crie alertas por desvio
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
),
current_hour AS (
SELECT
feature,
SUM(cost_usd) AS current_spend
FROM openai_events
WHERE environment = 'prod'
AND timestamp >= 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.
Otimizações práticas de custo
Cache de prompt
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_ratepor funcionalidade.
A documentação oficial está em Prompt Caching.
API Batch para trabalho offline
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.
Esforço de raciocínio
Se você usa modelos com configuração de raciocínio, audite o nível aplicado por funcionalidade.
Perguntas úteis:
-
mediumé realmente necessário? -
lowpassa 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.
Janela de contexto
Prompts longos são caros. Monitore:
- média de
prompt_tokenspor 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.
Limite de 272K tokens do GPT-5.5
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.
Erros comuns
Evite estes padrões:
- contar tokens de raciocínio como entrada;
- confiar no painel do OpenAI para alertas em tempo real;
- deixar
featureoucustomer_idcomonull; - marcar apenas endpoints HTTP e esquecer workers, filas e cron jobs;
- usar
unknowncomo valor padrão silencioso; - amostrar logs de custo;
- calcular custo apenas no dashboard, sem persistir
cost_usd; - não deduplicar retentativas;
- misturar ambientes
dev,stagingeprodna mesma análise.
Para jobs assíncronos, use rotas sintéticas:
cron:nightly-summarize
queue:document-classification
worker:embedding-backfill
webhook:ticket-created
Alternativas e ferramentas
| 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
Casos de uso
SaaS B2B com IA por cliente
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.
Ferramenta interna para desenvolvedores
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.
Previsão de custo de nova funcionalidade
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.
Conclusão
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_ideenvironment. - Calcule
cost_usdno 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.
FAQ
Os tokens de raciocínio contam como entrada ou saída?
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.
Posso fazer atribuição apenas com chaves de projeto?
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.
Retentativas contam custo duas vezes?
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.
A API de uso do OpenAI é suficiente para alertas?
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.
Devo amostrar logs?
Não. O volume é pequeno e a amostragem quebra a atribuição por cliente e rota.
Isso funciona para outros provedores de LLM?
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.
Isso também funciona para embeddings e geração de imagem?
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.
Top comments (0)