Playbook de redução de custo: 14 alavancas em ordem de aplicação
- ⬜🧪 Evals: como saber se está bom (e como trocar de modelo sem medo)(AWS Bedrock — GenAI em Produção)
Recomendamos completar os pré-requisitos antes de seguir, mas nada te impede de continuar.
Toda conta de IA que assusta é resultado de um punhado de decisões pequenas tomadas por omissão: ninguém marcou o ponto de cache, ninguém limitou a saída, ninguém mediu se o modelo barato resolvia, ninguém revisou o índice que cobra parado. A boa notícia é que o inverso também é verdade — as alavancas são conhecidas, ordenáveis e a maioria não custa nada para aplicar. Este é o manual operacional: 14 alavancas com economia típica, esforço, risco e a ordem certa. A ordem importa tanto quanto a lista, porque as primeiras são gratuitas e as últimas são projeto.
Os quatro sumidouros: onde o dinheiro realmente está
Antes de otimizar, descubra onde o dinheiro vai — porque a intuição erra. Em quase toda arquitetura, a conta se concentra em quatro lugares, e o primeiro passo é medir qual deles domina no seu caso. Otimizar o sumidouro errado é o motivo mais comum de um esforço de FinOps não mover a fatura.
| Sumidouro | Sinal de que é ele | Alavancas que atacam |
|---|---|---|
| Prefixo repetido | Prompt de sistema grande e taxa de leitura de cache baixa ou zerada | Cache de prefixo, estabilidade de tools, ordem determinística |
| Contexto injetado | Top-k alto, documentos longos, histórico crescente por turno | Rerank com top-k pequeno, truncar resultado de tool, limpeza e compactação |
| Tokens de saída | Respostas longas, max_tokens generoso, agent tagarela | Limite de saída, prompt de concisão, esforço menor onde couber |
| Infraestrutura ociosa | Conta alta com tráfego baixo; custo por consulta absurdo no piloto | Right-sizing de vector store, retenção de log, provisionamento sob demanda |
Saída custa múltiplos da entrada
Nas famílias usadas em produção corporativa, o token de saída costuma custar algumas vezes o de entrada. Isso inverte a intuição de otimização: encurtar o prompt de sistema em 30% muitas vezes vale menos que encurtar a resposta em 30%. Antes de refatorar prompt, olhe a razão entre tokens de entrada e de saída no seu tráfego — ela diz por onde começar.
- → volátil DEPOIS do ponto de cache
- → primeiro: a regra resolve?
- → buscar largo e entregar estreito
- → pergunta repetida não vira chamada
- → custo por app é o que permite achar o vazamento
- Gestão e governança
- IA e machine learning
- Compute
- Banco de dados
- Analytics
Otimizar o sumidouro errado é o motivo mais comum de um esforço de FinOps não mover a fatura. Percorra os passos na ordem: as três primeiras alavancas não têm risco de qualidade.
- Descobrir qual sumidouro domina. Sem inference profile por app não há diagnóstico: a fatura é uma linha só. É o pré-requisito de tudo.
- Alavanca 1 — a chamada que não acontece. Validação de documento, extração de código, roteamento por palavra inequívoca: o que a regra resolve não vira token.
- Alavanca 2 — cache de prefixo. Estável primeiro, volátil depois do ponto de cache. Se a leitura de cache vem zerada, procure timestamp, id ou conjunto de tools variando.
- Alavanca 3 — disciplina de saída. Saída custa múltiplos da entrada. Limite por tipo de tarefa, concisão no prompt e saída estruturada onde o destino é um sistema.
- Alavanca 4 — o que cobra parado. Vector store com capacidade mínima e log sem retenção cobram 24 horas por dia. Em piloto, costumam ser a maior linha da conta.
- Alavancas 6 e 9 — cortar o contexto. Reranking entrega top-k pequeno; resultado de ferramenta truncado não é reenviado inteiro em todos os turnos seguintes; janela deslizante no histórico.
- Alavanca 7 — a maior de todas. Cascata por tier, com as categorias que descem definidas por eval segmentada — não por palpite. Acompanhe a taxa de escalada semanalmente.
As 14 alavancas, na ordem de aplicação
| # | Alavanca | Economia típica | Esforço | Risco de qualidade |
|---|---|---|---|---|
| 1 | Não usar LLM onde regra resolve | Elimina a chamada inteira nesse fatia | Baixo | Nenhum — fica mais determinístico |
| 2 | Cache de prefixo bem marcado | Grande parte do custo do prefixo repetido | Baixo | Nenhum |
| 3 | Disciplina de saída (limite + prompt) | Alta, porque saída é o lado caro | Baixo | Baixo, se validado por eval |
| 4 | Right-sizing de vector store e logs | Elimina a linha ociosa; decisiva em baixo volume | Baixo | Nenhum |
| 5 | Remover tools e contexto mortos | Proporcional ao peso do prefixo | Baixo | Nenhum |
| 6 | Rerank com top-k pequeno | Grande fatia do contexto injetado | Médio | Negativo — costuma melhorar |
| 7 | Roteamento em cascata por tier | A maior de todas em tráfego heterogêneo | Médio | Médio — exige eval segmentada |
| 8 | Batch no que não é interativo | Cerca de metade nessa fatia | Médio | Nenhum — muda só a latência |
| 9 | Truncar e resumir resultado de tool | Alta em agents com laço longo | Médio | Baixo |
| 10 | Cache semântico de perguntas repetidas | Proporcional à repetição do tráfego | Médio | Médio — exige invalidação correta |
| 11 | Limpeza e compactação de contexto | Alta em conversas longas | Alto | Médio — pode perder o fio |
| 12 | Materializar respostas frequentes | Elimina a chamada nas repetidas | Médio | Médio — precisa invalidar quando muda |
| 13 | Distillation para tarefa de alto volume | Grande, se o volume justificar o projeto | Alto | Médio — exige eval forte |
| 14 | Provisioned throughput | Só ganha com saturação quase contínua | Alto | Nenhum — mas dinheiro parado se errar |
Pare depois da alavanca 8 na primeira rodada
As oito primeiras cobrem a maior parte do que dá para economizar sem projeto, e a maioria delas não tem risco de qualidade. Aplicar as seis últimas antes das oito primeiras é o erro clássico: o time monta distillation enquanto o cache está desligado e o vector store cobra ocioso. Faça a rodada barata inteira, meça de novo, e só então avalie se as caras ainda fazem sentido.
Bloco 1 — as gratuitas (aplique esta semana)
Alavanca 1: não usar LLM onde a regra resolve. A economia perfeita é a chamada que não acontece. Antes de qualquer otimização de token, revise o fluxo procurando por decisões determinísticas que estão passando pelo modelo por preguiça de escrever a regra.
| Passando pelo modelo | O que resolve sem LLM | Efeito |
|---|---|---|
| Validar CPF, CNPJ, data, e-mail, total | Regra e dígito verificador | Mais barato, mais rápido e mais correto |
| Detectar idioma, extrair CEP, achar código | Regex e biblioteca | Elimina a chamada |
| Rotear por palavra-chave inequívoca | Tabela de correspondência com fallback para o modelo | Corta a fatia trivial do volume |
| Classificar em duas classes com muito exemplo | Classificador clássico treinado nos seus dados | Ordens de grandeza mais barato por inferência |
| Responder a pergunta idêntica repetida | Resposta materializada com invalidação | Elimina a chamada nas repetições |
| Reprocessar item já processado | Chave de idempotência | Evita pagar duas vezes pelo mesmo trabalho |
Alavanca 2: cache de prefixo. É a de maior impacto imediato em qualquer sistema com instrução grande e repetida. A mecânica é simples e implacável: o cache é casamento de prefixo — vale do começo até o ponto marcado, e qualquer byte diferente antes desse ponto invalida tudo depois.
# ERRADO — o prefixo muda a cada request e o cache nunca acerta.
system_ruim = [{
"text": f"Voce e um assistente. Data e hora: {datetime.now()}. "
f"Usuario: {usuario.nome} (id {usuario.id}).\n{MANUAL_GRANDE}"
}]
# datetime e nome do usuario ficam ANTES do manual: cada request e um prefixo
# novo, o manual inteiro e reprocessado a preco cheio, e cacheReadInputTokens = 0.
# CERTO — estavel primeiro, volatil depois do ponto de cache.
system_bom = [
{"text": MANUAL_GRANDE}, # identico em todo request
{"text": POLITICA_DE_RESPOSTA}, # identico em todo request
{"cachePoint": {"type": "default"}},
]
mensagens = [{
"role": "user",
"content": [
# O que varia entra DEPOIS do ponto de cache.
{"text": f"[contexto: {datetime.now():%Y-%m-%d}, usuario {usuario.id}]"},
{"text": pergunta},
],
}]
resp = br.converse(modelId=MODEL_ID, system=system_bom, messages=mensagens)
# VERIFIQUE — sem isto voce nao sabe se o cache funciona.
u = resp["usage"]
lidos = u.get("cacheReadInputTokens", 0)
if lidos == 0:
log.warning("cache nao acertou: procure um invalidador no prefixo")
Os cinco invalidadores silenciosos
Se a leitura de cache vem sempre zerada, procure por: (1) timestamp ou id gerado dentro do prefixo; (2) serialização não determinística — dicionário ou conjunto sem ordenação estável; (3) conjunto ou ordem de ferramentas mudando entre requests; (4) trocar de modelo no meio da conversa, porque o cache é por modelo; (5) prefixo abaixo do mínimo cacheável, que varia por modelo e faz o cache não se formar em silêncio. Nenhum deles dá erro — só uma fatura mais alta.
Alavanca 3: disciplina de saída. Como a saída custa múltiplos da entrada, é o lugar com melhor retorno por linha de código alterada — e o mais negligenciado, porque "deixa o max_tokens alto por segurança" parece prudente e é caro.
- Defina o limite de saída por tipo de tarefa, não um valor global generoso: classificação precisa de dezenas de tokens, não de milhares.
- Peça concisão no prompt e dê um exemplo do formato desejado — exemplo positivo funciona melhor que proibição.
- Prefira saída estruturada a texto livre quando a resposta vai para um sistema: schema corta preâmbulo e explicação.
- Corte o preâmbulo ("Claro! Vou ajudar...") com instrução explícita de responder direto.
- Onde houver controle de esforço de raciocínio, calibre por rota: nem toda tarefa merece o nível alto.
- Meça o percentil 95 de tokens de saída por rota — a cauda é onde mora o desperdício, e a média a esconde.
Alavanca 4: o custo que existe mesmo sem tráfego
Vector store com capacidade mínima, endpoint provisionado e log sem política de retenção cobram 24 horas por dia, com ou sem uso. Em piloto, essa linha costuma ser a maior da conta — maior que toda a inferência. Revise trimestralmente: dimensione pelo pico real medido, não pelo pico imaginado, e defina retenção de log no dia em que ligar o logging, não depois que a fatura chamar atenção.
Bloco 2 — engenharia leve, ganho grande
Alavanca 7, a maior de todas em tráfego heterogêneo: roteamento em cascata. A regra de decisão já apareceu nos padrões agênticos — só vale se a maior parte do volume terminar no tier barato. O que muda aqui é que agora você tem eval para definir quais categorias podem descer, em vez de chutar um limiar de confiança.
# As categorias que descem de tier NAO sao palpite: saem do protocolo de
# rebaixamento (eval par a par, segmentada por tipo de tarefa).
CATEGORIAS_TIER_VOLUME = {
"saudacao", "status_pedido", "rastreio", "segunda_via",
"horario_funcionamento", "politica_troca",
}
def responder(pergunta, contexto, metrica):
# Passo 0: a alavanca 1. Sem LLM quando a regra resolve.
if resposta := resposta_deterministica(pergunta):
metrica.incr("rota.sem_llm")
return resposta
# Passo 1: classificacao barata, saida curtissima.
categoria = classificar(pergunta, modelo=TIER_VOLUME, max_tokens=10)
# Passo 2: categoria comprovadamente segura resolve embaixo.
if categoria in CATEGORIAS_TIER_VOLUME:
r = gerar(pergunta, contexto, modelo=TIER_VOLUME, max_tokens=300)
# Passo 3: rede de seguranca DETERMINISTICA, nao "o modelo achou
# que ficou bom" — autoavaliacao no mesmo contexto nao e sinal.
if verificacao_deterministica_ok(r, contexto):
metrica.incr("rota.tier_volume")
return r
metrica.incr("rota.escalada_por_verificacao")
# Passo 4: o caro, por excecao — reaproveitando o contexto ja montado.
metrica.incr("rota.tier_raciocinio")
return gerar(pergunta, contexto, modelo=TIER_RACIOCINIO, max_tokens=900)
# A metrica que decide se a cascata vale: acompanhe semanalmente.
# taxa_escalada = (escalada_por_verificacao + tier_raciocinio) / total
# Abaixo de ~20% costuma compensar bem; acima de ~40%, quase nunca.
Alavanca 8: batch é dinheiro na mesa
Tudo que não tem humano esperando deveria rodar em modo assíncrono, com desconto da ordem de metade do preço: geração de embeddings, reindexação, enriquecimento de catálogo, classificação de acervo, execução da eval completa, contextualização de chunks. O time frequentemente usa o caminho síncrono por hábito — é a economia mais fácil de capturar e a mais esquecida, porque não muda nada além da forma de chamar.
Alavanca 10: cache semântico. Diferente do cache de prefixo, ele evita a chamada inteira quando alguém faz uma pergunta equivalente a uma já respondida. Em atendimento e suporte interno, onde o tráfego é altamente repetitivo, é uma das maiores economias disponíveis — e uma das mais perigosas se a invalidação for mal feita.
LIMIAR = 0.94 # calibre no SEU trafego: alto demais nunca acerta,
# baixo demais responde a pergunta errada com confianca.
def responder_com_cache(pergunta, usuario, versao_base):
emb = embed(pergunta)
# A chave inclui o escopo de permissao e a versao do conteudo.
# Sem isso voce serve resposta de outra area ou resposta obsoleta —
# os dois piores incidentes possiveis num cache de IA.
escopo = escopo_de_permissao(usuario)
hit = cache.buscar_mais_proximo(emb, escopo=escopo, versao=versao_base)
if hit and hit.similaridade >= LIMIAR:
metrica.incr("cache_semantico.hit")
return hit.resposta # zero token gasto
resposta = pipeline_completo(pergunta, usuario)
# Nao cacheie tudo: resposta com dado transacional do cliente muda a
# cada minuto e NUNCA pode ser servida para outra pessoa.
if not contem_dado_transacional(resposta):
cache.gravar(emb, resposta, escopo=escopo,
versao=versao_base, ttl_horas=24)
metrica.incr("cache_semantico.miss")
return resposta
Três regras inegociáveis do cache semântico
A chave precisa incluir o escopo de permissão do usuário, ou você serve a resposta de uma área para quem não podia vê-la. Precisa incluir a versão do conteúdo, ou você serve política revogada depois que a base mudou. E resposta com dado transacional — saldo, status, prazo — nunca entra no cache, porque ela é verdadeira por minutos. Cache semântico mal feito não é economia: é incidente com desconto.
Bloco 3 — as que exigem projeto
Alavanca 13: distillation. Você usa um modelo grande para gerar exemplos de alta qualidade numa tarefa específica e treina um modelo menor para reproduzi-los. O ganho por inferência é grande; o custo de entrada é um projeto. A pergunta é sempre a mesma: em quantos meses o investimento se paga?
Tente as opções mais baratas antes
Antes de destilar, teste nesta ordem: prompt melhorado no modelo pequeno; poucos exemplos bem escolhidos no prompt (com o prefixo cacheado, isso é barato); e cascata restrita àquela tarefa. Não é incomum que a combinação dessas três chegue perto do resultado do modelo grande sem nenhum projeto de treinamento — e sem criar um artefato a mais para manter.
📋 Uma tarefa de classificação de tickets roda com o tier de raciocínio, com volume alto e estável, e a eval mostra que o tier de volume perde por pouco.
É a intervenção de menor custo e menor risco: exemplos bem escolhidos costumam fechar uma diferença pequena, e o prefixo cacheado faz o custo desses exemplos ser quase nulo por request. Se funcionar, você capturou a economia em dias, sem criar artefato novo para manter.
Alt: Distillation — Resolve, mas é projeto: geração de conjunto, treino, avaliação e manutenção contínua de mais um modelo versionado.
Alt: Manter no tier de raciocínio — Paga o preço mais alto do catálogo em volume alto para ganhar uma diferença pequena de qualidade.
Alt: Provisioned throughput — Não resolve o problema: só muda a forma de pagar pelo mesmo modelo caro, e exige saturação quase contínua para compensar.
Alavanca 14: capacidade dedicada é a última da fila
Provisioned throughput só ganha quando você satura a capacidade de forma quase contínua — é compromisso pago por hora, ocupada ou não. Antes de considerar, verifique se você já aplicou as treze anteriores: é comum que, depois delas, o volume caiba folgado no sob demanda. E lembre que ela resolve previsibilidade de vazão e latência, não preço por token.
Um sistema com prompt de sistema grande mostra cacheReadInputTokens sempre em zero, mesmo com tráfego contínuo e ponto de cache marcado. Qual é o suspeito número um?
Orçamento de tokens como requisito de produto
A prática que separa times maduros: tratar custo como requisito não funcional, do mesmo jeito que latência. Toda funcionalidade nova nasce com um orçamento declarado, e esse número entra no critério de aceitação — não em uma revisão de custo três meses depois.
O guarda-corpo que mais evita susto
Orçamento mensal avisa tarde: quando o alerta dispara, o gasto já aconteceu. O que protege de verdade é o alerta de variação diária — um salto atípico costuma ser bug em laço, retry descontrolado ou cache que parou de acertar, e todos os três são detectáveis no mesmo dia. Combine com quota por app no gateway, que transforma um incidente de custo em uma recusa controlada.
Falsas economias: o que parece barato e não é
| Falsa economia | Por que parece boa | O que acontece de verdade |
|---|---|---|
| Cortar o contexto e deixar o modelo "deduzir" | Menos tokens de entrada por request | Mais erro, mais reformulação e mais escalonamento para humano — o custo migra e cresce |
| Usar o modelo mais barato em tudo | Menor preço por token | Retentativas e correções, e uma queda de qualidade que custa mais que a economia |
| Desligar guardrails para economizar chamada | Uma etapa a menos | Um incidente de conformidade custa ordens de grandeza mais que a etapa |
| Desligar o logging para reduzir armazenamento | Fatura de log menor | Sem trilha de auditoria e sem dado para otimizar — você fica cego justamente onde precisa medir |
| Reduzir top-k sem medir recall | Menos tokens de contexto | Recall despenca; a resposta certa fica impossível e o usuário reabre o contato |
| Cache semântico com limiar frouxo | Taxa de acerto alta no painel | Responde a pergunta errada com confiança; é o pior tipo de erro |
| Prompt curto demais | Prefixo menor | Instrução essencial removida derruba a qualidade — e o prefixo era cacheado, então economizava pouco |
O padrão comum a todas
Toda falsa economia corta um custo visível (tokens, uma etapa, armazenamento) e cria um custo invisível (retrabalho, escalonamento, incidente, cegueira operacional). Por isso a regra é simples: nenhuma otimização entra em produção sem passar pela eval e sem um contrapeso monitorado. Economia que você não conseguiu medir provavelmente não aconteceu.
O painel mínimo e a rotina
Reexecute o rebaixamento a cada trimestre
O catálogo muda: modelos novos entram, preços mudam e o que era o tier caro vira o intermediário. Um sistema que rodou o protocolo de rebaixamento há seis meses e nunca mais revisou está, quase com certeza, pagando a mais. Como você já tem golden set e juiz calibrado, reexecutar custa pouco — é a rotina de melhor retorno do calendário trimestral.
A diretoria pede corte de 40% no custo de IA. O sistema é um assistente de suporte interno com 300 consultas por dia, RAG sobre uma base grande, e a conta é dominada pela capacidade mínima do vector store. Qual alavanca você aplica primeiro?
Um time propõe cache semântico para o copiloto interno, com chave baseada apenas no embedding da pergunta. Qual é o risco mais grave desse desenho?
Próximo passo
Você tem a arquitetura, os padrões, a régua de qualidade e o manual de custo. Falta o mapa: quem, no mundo real, já colocou isso em produção — organizado por setor e cruzado com o padrão arquitetural que cada um usa. É o próximo módulo, e ele serve de bússola para escolher por onde a sua empresa começa.
Perguntas frequentes
❓ Qual a primeira alavanca para reduzir custo de IA?
❓ Em que ordem aplicar as alavancas de custo?
❓ Quanto se economiza com processamento em lote?
Terminou de ler?
Marcar como concluído registra o XP, mantém sua sequência e coloca 3 cartas deste módulo na fila de revisão espaçada.
Próximos passos sugeridos
Temas deste módulo
Discussão
Carregando comentários…