Você está crescendo. Isso é bom. Mas os custos estão crescendo 2,5x mais rápido que o uso. Isso é ruim.

Recursos selecionados para complementar sua leitura
Sua fatura de LLM chegou esta manhã: R$236.710.
Mês passado foi R$156.075. O mês anterior, R$94.700.
Você está crescendo. Isso é bom. Mas os custos estão crescendo 2,5x mais rápido que o uso. Isso é ruim.
Seu CFO está fazendo perguntas. Seu CEO quer saber por que a IA custa mais que toda sua infraestrutura AWS. Seu time de engenharia está apagando incêndios em produção e não consegue focar em otimização.
Enquanto isso, seu concorrente roda um produto similar por um décimo do custo.
Esta é a crise de custo de LLM. E é solucionável.
Os times rodando sistemas de IA eficientes não são mais inteligentes. Não estão usando modelos secretos. Eles apenas conhecem os padrões—os 20% de otimizações que entregam 80% da economia.
Este artigo é esse 20%.
Antes de otimizar, você precisa entender onde o dinheiro realmente vai.
A maioria dos times chuta errado.
"Fazemos X requisições por dia. Cada requisição custa Y tokens. Custo total = X × Y × preço_por_token."
Esse modelo é simples demais. Perde três fatores críticos:
1. Distribuição de Tokens Não É Uniforme
# O que times pensam que o uso de tokens parece
average_tokens_per_request = 2000
# Como realmente é
percentile_distribution = {
"p50": 800, # Requisição mediana
"p90": 3500, # 90º percentil
"p95": 8000, # 95º percentil
"p99": 25000, # 99º percentil
}
# As requisições p99 custam 30x mais que a mediana
# E estão dirigindo sua fatura
Seu top 1% de requisições está consumindo 40% do seu orçamento.
A maioria dos esforços de otimização foca na mediana. Isso é otimizar a coisa errada.
2. Seleção de Modelo Varia Drasticamente em Custo
# Custo por 1M de tokens (input + output, pricing Jan 2024)
model_costs = {
"gpt-4-turbo": 30.00,
"gpt-3.5-turbo": 2.00,
"claude-3-haiku": 1.00,
"local-llama-7b": 0.10, # Self-hosted
}
# Se você rotear 50% do tráfego de gpt-4-turbo para gpt-3.5-turbo
# Economia: 50% × ($30 - $2) = $14 por 1M tokens
# Em 100M tokens/mês: $1.400 de economia
# Se 30% do tráfego pode usar haiku
# Economia adicional: 30% × ($2 - $1) = $0.30 por 1M tokens
# Em 100M tokens/mês: $30 + $420 = $450 de economia total do roteamento
Roteamento de modelo sozinho pode cortar custos em 40-60% sem perda zero de qualidade se feito inteligentemente.
3. Caching É Massivamente Subutilizado
# Taxas de cache hit reais de sistemas em produção
cache_scenarios = {
"no_cache": 0,
"naive_exact_match": 0.12, # 12% hit rate
"semantic_similarity": 0.35, # 35% hit rate
"prompt_normalized": 0.48, # 48% hit rate
}
# Em 100M tokens/mês, $2 por 1M tokens
without_cache = 100 × 2 = $200
with_48_cache = 52 × 2 = $104
# Economia: $96/mês (48%)
Quase metade das suas requisições poderiam ser servidas do cache se você projetar para isso.
A única otimização de maior alavancagem: rotear requisições para o modelo mais barato capaz de lidar com elas.
Nem todas as requisições precisam de GPT-4.
class RequestComplexity:
SIMPLE = "simple" # QA extrativo, classificação
MODERATE = "moderate" # Sumarização, geração simples
COMPLEX = "complex" # Raciocínio, geração de código
EXPERT = "expert" # Tarefas multi-passo, pesquisa
# Capacidades dos modelos
model_tiers = {
"expert": ["gpt-4-turbo", "claude-3-opus"], # $30/1M tokens
"complex": ["gpt-4", "claude-3-sonnet"], # $15/1M tokens
"moderate": ["gpt-3.5-turbo", "claude-3-haiku"], # $1-2/1M tokens
"simple": ["local-llama-7b", "cached-results"], # $0.10/1M tokens
}
class IntelligentRouter:
def __init__(self):
self.complexity_classifier = self._train_classifier()
self.fallback_chain = [
"claude-3-haiku",
"gpt-3.5-turbo",
"gpt-4-turbo"
]
def route_request(self, query, user_context):
# Passo 1: Classifica complexidade da requisição
complexity = self._classify_complexity(query, user_context)
# Passo 2: Seleciona modelo mais barato capaz
if complexity == "simple":
# Tenta cache primeiro
cached = self.cache.get(query)
if cached:
return cached, "cache", 0
# Usa modelo menor
return self._call_model("claude-3-haiku", query), "haiku", 1.00
elif complexity == "moderate":
return self._call_model("gpt-3.5-turbo", query), "gpt-3.5", 2.00
elif complexity == "complex":
return self._call_model("gpt-4", query), "gpt-4", 15.00
else: # expert
return self._call_model("gpt-4-turbo", query), "gpt-4-turbo", 30.00
Antes do roteamento:
Depois do roteamento:
routing_breakdown = {
"cache": 0.20, # 20% cache hits
"haiku": 0.40, # 40% queries simples
"gpt-3.5": 0.30, # 30% moderado
"gpt-4": 0.10, # 10% complexo
}
new_cost = (
0.20 × 0 + # Cache: grátis
0.40 × 1.00 + # Haiku: $1/1M
0.30 × 2.00 + # GPT-3.5: $2/1M
0.10 × 15.00 # GPT-4: $15/1M
) × 2000
new_cost = (0 + 0.40 + 0.60 + 1.50) × 2000 = $5.000/mês
Economia: $25.000/mês (83%)
Impacto na qualidade: Nenhum. Cada query vai para um modelo capaz de lidar com ela.
A maioria dos times tenta caching. A maioria desiste porque a taxa de hit é 5%.
Aqui está como obter 40-60% de taxa de hit.
import hashlib
class ExactMatchCache:
def __init__(self, redis_client):
self.redis = redis_client
self.ttl = 86400 # 24 horas
def get(self, query, system_prompt):
cache_key = self._make_key(query, system_prompt)
return self.redis.get(cache_key)
def set(self, query, system_prompt, response):
cache_key = self._make_key(query, system_prompt)
self.redis.setex(cache_key, self.ttl, response)
def _make_key(self, query, system_prompt):
combined = f"{system_prompt}|||{query}"
return hashlib.sha256(combined.encode()).hexdigest()
Hit rate: 8-12% (apenas queries idênticas)
from sentence_transformers import SentenceTransformer
import numpy as np
class SemanticCache:
def __init__(self, redis_client, similarity_threshold=0.95):
self.redis = redis_client
self.encoder = SentenceTransformer('all-MiniLM-L6-v2')
self.threshold = similarity_threshold
self.index = self._build_vector_index()
def get(self, query):
# Codifica query
query_embedding = self.encoder.encode(query)
# Encontra queries cached similares
similar_queries = self.index.search(
query_embedding,
k=5,
threshold=self.threshold
)
if similar_queries:
# Retorna resposta cached da query mais similar
best_match = similar_queries[0]
cached_response = self.redis.get(best_match.cache_key)
return cached_response
return None
Hit rate: 30-40% (queries semanticamente similares)
Exemplos de hits:
Trade-off: Adiciona 20-50ms de latência para embedding + busca. Ainda mais rápido que chamada de LLM (500-2000ms).
Muitas queries "diferentes" são na verdade idênticas depois de normalização.
class NormalizedCache:
def __init__(self, base_cache):
self.cache = base_cache
def _normalize(self, query):
# Lowercase
text = query.lower()
# Remove espaço extra
text = ' '.join(text.split())
# Remove variações de pontuação
text = text.rstrip('?.!')
# Expande contrações
contractions = {
"o que é": "o que eh",
"pq": "porque",
# ... mais
}
for contraction, expansion in contractions.items():
text = text.replace(contraction, expansion)
return text.strip()
Boost de hit rate: +10-15% quando combinado com caching semântico.
caching_comparison = {
"exact_match": {
"hit_rate": 0.12,
"latency_overhead": "0ms",
"implementation": "simple",
"cost_per_lookup": "$0.0001"
},
"semantic": {
"hit_rate": 0.35,
"latency_overhead": "30ms",
"implementation": "moderate",
"cost_per_lookup": "$0.001"
},
"normalized": {
"hit_rate": 0.48,
"latency_overhead": "40ms",
"implementation": "moderate",
"cost_per_lookup": "$0.001"
}
}
# Em 1M requisições/mês, $15 por 1M tokens médio
savings = {
"exact": 1M × 0.12 × $15 = $1.800,
"semantic": 1M × 0.35 × $15 = $5.250,
"normalized": 1M × 0.48 × $15 = $7.200,
}
Seus prompts provavelmente são muito longos.
# Estrutura de prompt típica
system_prompt = """
Você é um assistente útil de suporte ao cliente para AcmeCorp.
Diretrizes:
- Sempre seja educado e profissional
- Se não souber a resposta, diga
- Nunca revele informações confidenciais
- ... (15 mais diretrizes)
Conhecimento da empresa:
- Oferecemos garantia de 30 dias
- Envio leva 3-5 dias úteis
- ... (30 mais fatos)
Exemplos:
P: Como devolver um produto?
R: Para devolver...
... (10 mais exemplos)
"""
# Contagem de tokens: 1.847 tokens
# Query do usuário: "Como reseto minha senha?"
# Contagem de tokens: 8 tokens
# Total de tokens de input: 1.855
# Você está pagando por 1.847 tokens de contexto em toda requisição
Em 1M requisições/mês, $15 por 1M tokens:
1. Remova Redundância
# Antes (348 tokens)
"""
Você é um assistente útil. Você deve ser útil, amigável e profissional.
Sempre forneça respostas úteis. Seja muito útil.
"""
# Depois (12 tokens)
"""
Você é um assistente útil, amigável e profissional.
"""
# Economia: 336 tokens por requisição
# Em 1M requisições: 336M tokens × $15 = $5.040/mês
2. Use Retrieval para Exemplos
# Antes: Inclui todos os 10 exemplos em todo prompt
all_examples_tokens = 1200
# Depois: Recupera exemplos relevantes por query
@cached
def get_relevant_examples(query, k=2):
# Busca semântica para exemplos mais relevantes
examples = vector_index.search(query, k=k)
return examples
# Tokens médios com 2 exemplos: 240 tokens
# Economia: 960 tokens por requisição
# Em 1M requisições: 960M tokens × $15 = $14.400/mês
3. Abreviação e Shorthand
LLMs entendem abreviações perfeitamente.
# Antes (125 tokens)
"""
Por favor analise o código a seguir e identifique quaisquer bugs potenciais,
vulnerabilidades de segurança ou problemas de performance. Forneça
recomendações específicas para melhoria.
"""
# Depois (45 tokens)
"""
Analise código. Identifique: bugs, issues de segurança, problemas de performance.
Recomende fixes.
"""
# Impacto na qualidade: Nenhum. Output é idêntico.
# Economia: 80 tokens por requisição
Nem todas as requisições precisam de respostas instantâneas.
# Síncrono (usuário esperando)
@app.post("/api/chat")
async def chat(query: str):
response = await llm.generate(query) # 500-2000ms
return {"response": response}
# Usuário espera por LLM. Deve usar modelo caro e rápido.
model_choice = "gpt-4-turbo" # $30/1M tokens
# Assíncrono (usuário pode esperar)
@app.post("/api/analyze")
async def analyze(document: str):
task_id = queue.enqueue(llm_task, document)
return {"task_id": task_id, "status": "processing"}
# Usuário faz polling do resultado. Pode usar modelo mais barato e lento ou batch.
model_choice = "gpt-3.5-turbo" # $2/1M tokens
class BatchProcessor:
def __init__(self, batch_size=10, max_wait_seconds=2):
self.batch_size = batch_size
self.max_wait = max_wait_seconds
self.pending = []
async def add_request(self, request):
self.pending.append(request)
# Inicia timer na primeira requisição
if len(self.pending) == 1:
self.timer = asyncio.create_task(
self._wait_and_process()
)
# Processa imediatamente se batch está cheio
if len(self.pending) >= self.batch_size:
await self._process_batch()
async def _process_batch(self):
if not self.pending:
return
batch = self.pending[:self.batch_size]
self.pending = self.pending[self.batch_size:]
# Cria prompt em batch
batched_prompt = self._create_batch_prompt(batch)
# Chamada única de LLM para múltiplas requisições
response = await llm.generate(batched_prompt)
# Parse e distribui respostas
individual_responses = self._parse_batch_response(response)
for request, response in zip(batch, individual_responses):
request.future.set_result(response)
Economia de custo:
# Sem batching: 10 requisições
individual_costs = 10 × 2000_tokens × $2/1M = $0.04
# Com batching: 1 requisição com 10 sub-queries
batched_cost = 12000_tokens × $2/1M = $0.024
# Economia: 40% em overhead fixo
Você não pode otimizar o que não mede.
class CostMonitor:
def __init__(self, metrics_client):
self.metrics = metrics_client
def record_request(self, model, input_tokens, output_tokens, user_id, endpoint):
# Registra métricas brutas
self.metrics.counter("llm.requests", {
"model": model,
"endpoint": endpoint
})
self.metrics.counter("llm.tokens.input", input_tokens, {
"model": model,
"endpoint": endpoint,
"user_id": user_id
})
# Calcula custo
cost = self._calculate_cost(model, input_tokens, output_tokens)
self.metrics.counter("llm.cost.dollars", cost, {
"model": model,
"endpoint": endpoint,
"user_id": user_id
})
class BudgetAlertSystem:
def __init__(self, monthly_budget=10000):
self.monthly_budget = monthly_budget
self.alert_thresholds = [0.5, 0.75, 0.9, 1.0]
def check_budget(self):
# Obtém gasto month-to-date
mtd_spend = metrics.sum("llm.cost.dollars", since=start_of_month())
budget_used = mtd_spend / self.monthly_budget
# Alerta nos thresholds
for threshold in self.alert_thresholds:
if budget_used >= threshold and not self.alerted_at(threshold):
self.alert(
level="high" if threshold >= 0.9 else "medium",
message=f"Orçamento de LLM em {budget_used:.0%}"
)
# Throttle se acima do orçamento
if budget_used >= 1.0:
self.enable_emergency_throttle()
# 1. Instrumente tudo
monitor = CostMonitor()
# 2. Analise gasto atual
report = analyzer.analyze_last_30_days()
# 1. Implemente exact-match caching (2-4 horas)
cache = ExactMatchCache(redis_client)
# Impacto esperado: 8-12% redução de custo
# 2. Adicione roteamento básico de requisições (4-8 horas)
router = BasicRouter()
# Impacto esperado: 30-40% redução de custo
# Combinado: ~45% redução total
# 1. Caching semântico (1-2 dias)
semantic_cache = SemanticCache(redis_client, threshold=0.95)
# Impacto adicional esperado: +20-25% redução
# 2. Compressão de prompt (2-3 dias)
compressed_prompts = compress_all_prompts()
# Impacto adicional esperado: +10-15% redução
# Combinado com semana 2: ~70-75% redução total
# 1. Configure dashboards
dashboard.add_panel("Cost over time")
dashboard.add_panel("Cost by model")
dashboard.add_panel("Cache hit rate")
# 2. Configure alertas
alert_config = {
"daily_budget_exceeded": 1000,
"unusual_spike_threshold": 2.0,
"cache_hit_rate_drop": 0.10,
}
Empresa: SaaS B2B com assistente de pesquisa powered by AI Custo original: $52.340/mês Depois da otimização: $6.180/mês Redução: 88%
Mês 1 - Medição:
Mês 2 - Quick Wins:
Mês 3 - Otimizações Avançadas:
Mês 4 - Fine-tuning:
Impacto na qualidade: Satisfação do usuário na verdade aumentou 4% devido a tempos de resposta mais rápidos do caching.
Entendimento:
Roteamento:
Caching:
Otimização de Prompt:
Monitoramento:
A maioria dos times ataca redução de custo assim:
Isso não funciona.
Os times rodando sistemas de IA cost-efficient focam nos 20%:
Esses três padrões sozinhos entregam 70-80% de redução de custo.
Todo o resto—batching, processamento async, fine-tuning para eficiência—adiciona outros 10-15%.
A matemática é simples:
original_cost = 100
# Depois de roteamento (40% para modelos baratos)
after_routing = 100 × 0.6 + (100 × 0.4 × 0.1) = 64
# Depois de caching (40% hit rate)
after_caching = 64 × 0.6 = 38
# Depois de compressão de prompt (30% redução)
after_compression = 38 × 0.7 = 27
# Custo final: $27 (73% redução)
# Tempo para implementar: 2-3 semanas
# Complexidade: Moderada
Sua fatura de $50K/mês pode se tornar $5K/mês.
Você não precisa de modelos secretos. Você não precisa de otimizações nível PhD.
Você precisa de roteamento, caching e compressão.
Comece por aí.
Este framework é usado em produção por times gastando $10K-$500K/mês em inferência de LLM. As estratégias de roteamento são adaptadas de plataformas de serving multi-modelo. Os padrões de caching combinam pesquisa de busca semântica com melhores práticas de CDN de produção. As abordagens de monitoramento de custo vêm de disciplinas de FinOps e otimização de custo de cloud.
AI Engineer
Construindo meu pedaço da internet.
Checklist de 47 pontos para encontrar bugs, riscos de segurança e problemas de performance antes do lançamento.
Templates testados em produção, usados por desenvolvedores. Economize semanas de setup no seu próximo projeto.
Consultorias modulares para founders e CTOs fracionados. Você recebe diagnóstico acionável e acompanhamento direto comigo.
2 vagas para consultorias no Q2