Cloud Intelligence™Cloud Intelligence™

Cloud Intelligence™

O Guia de Engenharia para Otimizar Custos do Amazon Bedrock

By Paul O'BrienApr 16, 202616 min read

Esta página também está disponível em English, Deutsch, Español, Français, Italiano e 日本語.

On-demand vs. provisioned throughput, batch inference, seleção de modelos e cache de tokens — com números reais.

TL;DR — Cinco estratégias que, somadas, geram 60-80% de economia no Bedrock:

  1. Batch inference para workloads assíncronos → 50% de desconto, zero impacto na qualidade
  2. Prompt caching para contexto repetido → 90% mais barato em tokens de input em cache
  3. Roteamento de modelos (modelos baratos para tarefas simples) → redução de 40-70% nos custos
  4. Benchmarking + LLM-as-a-judge para validar que modelos mais baratos entregam o suficiente
  5. Observabilidade (OTel + DoiT GenAI Intelligence) para detectar drift e manter a economia travada

Levamos um cliente de US$ 40 mil/mês para US$ 18 mil usando esse playbook. Detalhes abaixo.

Lidero o time de engenharia da APAC na DoiT. No último trimestre, um cliente do setor financeiro me pediu para revisar o gasto deles com Bedrock. Eles rodavam Claude Sonnet para tudo — classificação de tickets, extração de documentos, chat com cliente final — e a fatura mensal tinha passado discretamente dos US$ 40 mil. Duas semanas depois, baixamos para US$ 18 mil sem mexer na qualidade do output.

Esse é o playbook. Se você é responsável pelos custos do Bedrock em um time de engenharia ou de dados, essas são as alavancas que de fato mexem na sua conta.

Os exemplos de cliente neste artigo são composições baseadas em padrões observados em vários projetos — não são estudos de caso individuais.

Entendendo os Dois Modelos de Pricing

O Bedrock tem dois modelos de pricing, e já vi erros caros nas duas pontas. (Para uma análise detalhada de como o pricing do Bedrock funciona — incluindo custos de fine-tuning, estimativa de tokens e estratégias de tagging — veja o guia CloudOps de pricing do Bedrock do Josh Palmer. Este artigo foca nas decisões de engenharia que cortam a conta.)

Pricing On-Demand

Você paga por token — input e output, com preços separados. Sem compromisso, sem mínimo.

Escolha essa opção quando o uso for irregular, você ainda estiver experimentando ou seu gasto mensal estiver abaixo do ponto de cruzamento (mais sobre isso adiante).

O que pega muita gente: tokens de output costumam custar de 3 a 5 vezes mais que tokens de input. Aquele cliente do setor financeiro que mencionei? Eles estavam estimando custos só com base no preço dos tokens de input e subestimavam a fatura real em quase 3x. Uma tarefa que consome 1.000 tokens de input mas gera 2.000 tokens de output é dominada pelo custo do output. Sempre modele os dois lados.

Provisioned Throughput

Você compra model units por hora (ou com commitments de 1 ou 6 meses). Um model unit é o bloco de capacidade reservada do Bedrock — pense em "uma faixa na rodovia" pela qual você paga por hora, usando ou não.

Escolha essa opção quando tiver workloads sustentados e previsíveis, sua utilização estiver consistentemente acima do limiar de cruzamento e você precisar de latência garantida.

Trabalhei com uma empresa de mídia no ano passado que tinha provisioned throughput rodando a 15% de utilização. Eles configuraram durante um teste de carga, esqueceram de voltar atrás e sangraram dinheiro por três meses até alguém perceber. Migrar para on-demand foi uma mudança de uma linha de configuração que economizou milhares na hora. Provisioned throughput com baixa utilização é o erro mais caro que existe no Bedrock.

Encontrando o Ponto de Cruzamento

Custo mensal on-demand = (input_tokens × input_price) + (output_tokens × output_price)
Custo mensal provisioned = model_units × hourly_rate × 730 horas

Na maioria dos modelos, o provisioned fica mais barato em torno de 60-70% de utilização sustentada de um model unit. A palavra "sustentada" é a chave aqui — não olhe para o pico de uso. Tráfego que fica em torno de 70% o dia todo com pequenos picos é um bom candidato; tráfego que fica ocioso a 10% e dispara para 100% por cinco minutos a cada hora não é.

Batch Inference: O Desconto de 50% Que Passa Despercebido

Provavelmente é o assunto que mais gosto de discutir com clientes, porque a reação é sempre a mesma: "Espera, a gente pode simplesmente... pagar metade?"

Pode. O Bedrock cobra tokens em batch a ~50% das tarifas on-demand para os modelos suportados. Mesmos modelos, mesma qualidade, metade do preço. (No momento em que escrevo — confira a página de pricing antes de apostar um roadmap nesse número.) O tradeoff é um SLA de 24 horas sem streaming — seus jobs entram em uma fila e completam de forma assíncrona.

Qualquer workload que não precise de resposta em tempo real é candidato. Categorizar tickets de suporte, processar corpora de documentos para RAG, gerar descrições de produto, rodar suítes de avaliação, extrair dados estruturados de documentos não estruturados. Eu chutaria que a maioria dos times tem 30-40% do workload no Bedrock que poderia migrar para batch sem nenhum impacto para o usuário final.

Na prática, fica assim. Pegue 10.000 requisições com média de 500 tokens de input e 200 tokens de output cada, usando Claude Sonnet (preço on-demand em ap-southeast-2):

Modo Custo de Input Custo de Output Total
On-demand US$ 15,00 US$ 37,50 US$ 52,50
Batch US$ 7,50 US$ 18,75 US$ 26,25

US$ 26,25 economizados em uma única execução em batch. Pipelines diários transformam isso em milhares por mês. E a implementação é só arquivos JSONL no S3 — é uma mudança de encanamento, não de arquitetura.

Seleção de Modelo Como Estratégia de Custo

Escolher o modelo certo é uma decisão de custo com variação de 10 a 60x. A maioria dos times acaba usando algo mais caro do que precisa, porque escolheu na fase de prototipação e nunca mais revisitou a decisão.

A Arquitetura em Tiers

Os deployments mais econômicos de Bedrock que vi usam tiers:

  • Tier 1 (Haiku, Mistral 7B, Llama 3 8B) — classificação, roteamento, extração, Q&A simples. Frações de centavo por requisição. Deve dar conta de 60-80% do seu tráfego.
  • Tier 2 (Sonnet, Mistral Large, Llama 3 70B) — raciocínio complexo, geração com nuances. 5-10x mais barato que o tier do topo.
  • Tier 3 (Opus, Claude 3.5 Sonnet) — só as tarefas mais difíceis. Pricing premium, reservado para o que realmente exige.

O Padrão Router

O Bedrock tem uma solução nativa só para roteamento dentro da mesma família. O Intelligent Prompt Routing dá um único endpoint serverless que roteia requisições entre modelos da mesma família com base na complexidade do prompt. Especifique o ARN de uma família de modelos (ex.: Anthropic Claude), e o Bedrock decide se cada requisição vai para o Haiku ou o Sonnet. A AWS afirma redução de até 30% nos custos — pelo que vi com clientes, é uma estimativa razoável. Zero código customizado: você só troca o ID do modelo pelo ARN do prompt router.

Para roteamento entre famílias (Haiku para classificação, Mistral para extração, Sonnet para raciocínio complexo), você precisa construir algo por conta própria. E, sinceramente, é o que a maioria dos times em produção faz. Não existe framework pronto e maduro que resolva isso bem o suficiente para eu recomendar sem ressalvas.

Três padrões que funcionam, em ordem aproximada de maturidade:

Classificação baseada em regras é onde a maioria dos times começa, e muitos ficam por aí. Escreva 5-10 regras a partir de sinais estruturais — palavras-chave do tipo de tarefa, tamanho do input, formato de output esperado, profundidade da conversa. Sem ML, sem dependências, deployável em um dia. Acerta 70-80% das decisões de roteamento. São apenas algumas centenas de linhas de lógica condicional.

Cascading baseado em confiança é o padrão de maior ROI que já vi. Mande cada requisição primeiro para o modelo mais barato. Verifique se a resposta tem linguagem hesitante, output mal formatado ou campos obrigatórios faltando. Se falhar, escale para o próximo tier. Espere uma latência adicional equivalente a uma chamada de modelo nos ~5-15% de requisições que escalam. Um time com quem trabalhei — uma plataforma de e-commerce processando consultas de produto — saiu de US$ 38 mil/mês para US$ 15 mil/mês desse jeito. A taxa de escalonamento ficou em apenas 8%. O classificador não precisa ser perfeito; precisa acertar com frequência suficiente para que o escalonamento dê conta das exceções. Se a taxa de escalonamento passar de 25-30%, conserte o classificador.

Híbrido de regras + classificador ML é o passo seguinte. Quando você tiver algumas semanas de tráfego em produção com resultados rotulados, treine um classificador pequeno (DistilBERT ou regressão logística sobre TF-IDF) que adicione menos de 5ms de latência. O classificador em si deve adicionar milissegundos de um dígito; o custo real é a disciplina de engenharia de rotular dados e retreinar periodicamente. Times que fazem isso normalmente sobem a precisão do roteamento de ~78% para ~91%.

Avaliei a fundo os frameworks existentes. O RouteLLM, do time da LMSys, tem respaldo de pesquisa, mas é fundamentalmente um router de dois modelos treinado em dados gerais de chat — para workloads específicos de domínio no Bedrock, você precisaria retreinar. O LiteLLM é excelente para infraestrutura (API unificada, fallbacks, retries), mas o roteamento dele é load balancing, não seleção de modelo baseada em qualidade. Nenhum dos dois é uma solução plug-and-play para o problema entre famílias.

Comece com o Intelligent Prompt Routing. Quando tiver evidências de que o roteamento entre famílias economizaria um valor relevante, construa um classificador baseado em regras. É previsível, debugável, e os times com quem trabalho que seguiram esse caminho relatam consistentemente reduções de 40-70% nos custos.

Benchmark de Qualidade vs. Custo do Modelo

Não presuma que você precisa do modelo mais caro. Rode suas tarefas reais em vários modelos e meça a precisão no seu caso de uso específico, o custo por tarefa (não por token) e a latência.

Fizemos esse exercício com o cliente do setor financeiro. A tarefa de classificação de tickets ficou em 94% de precisão no Haiku contra 97% no Sonnet — a 1/15 do custo. Aqueles 3% de diferença não importavam para o caso de uso deles. Os números vão variar para o seu, mas o padrão é consistente: faça benchmark antes de se comprometer.

Automatizando a Avaliação de Qualidade com LLM-as-a-Judge

Para classificação ou extração, dá para validar qualidade de forma programática, mas para geração aberta — resumos, explicações, respostas para clientes — pontuar tradicionalmente significava revisores humanos. Isso não escala.

O Bedrock tem uma resposta nativa: a avaliação de modelos com LLM-as-a-judge. Você fornece um dataset de prompts (opcionalmente com respostas de referência), escolhe um modelo avaliador, e o Bedrock roda os outputs do modelo candidato pelo juiz em métricas como correção, completude, utilidade, coerência, relevância e segurança. Roda como um job gerenciado — você recebe de volta scores por prompt e agregados, armazenados no S3.

O objetivo é provar que um modelo que custa de 5 a 15 vezes menos por token é "bom o suficiente" antes de mover tráfego real. Prepare um arquivo JSONL com seus prompts representativos, rode o mesmo job de avaliação contra Haiku, Sonnet e o que mais estiver considerando, e compare os scores lado a lado. A AWS publicou um walkthrough com exemplos de código e há um Jupyter notebook complementar no GitHub.

Algumas coisas que aprendi usando isso com clientes.

Use o mesmo modelo avaliador em todas as comparações — se você julga o output do Haiku com um modelo e o do Sonnet com outro, está medindo diferenças entre avaliadores, não entre modelos.

Inclua seus prompts reais de produção, não benchmarks genéricos. O MT-Bench serve para uma checagem de sanidade, mas seus prompts de classificação de tickets vão se comportar de forma diferente de perguntas e respostas acadêmicas.

A própria avaliação custa dinheiro (o modelo juiz processa cada output), então comece com 200-500 prompts representativos em vez do dataset inteiro. Normalmente é o suficiente para ver se o modelo barato é claramente pior, claramente bom ou "precisa de mais investigação".

Ground truth é opcional, mas valioso — para tarefas em que você tem outputs conhecidos como bons, as métricas de fidelidade e correção ficam muito mais significativas.

O benchmark_bedrock.py captura custo e latência; o LLM-as-a-judge pontua qualidade. Rode os dois e você terá o panorama completo de custo vs. qualidade sem revisão manual.

Prompt Caching: 90% de Economia em Contexto Repetido

Me surpreende quantos poucos times têm isso habilitado. Tokens de input em cache são cobrados com 90% de desconto sobre o preço padrão.

Quando você envia uma requisição com caching habilitado, o Bedrock armazena o prefixo do seu prompt. Requisições subsequentes que compartilham esse prefixo batem no cache. Cache hits custam ~10% da tarifa normal. Cache writes (primeira requisição) custam um pouco mais, então só economiza dinheiro quando você reusa o mesmo prefixo várias vezes — mas se você tem um system prompt ou exemplos few-shot, o retorno é imediato.

Onde brilha: system prompts acima de 1.500 tokens, exemplos few-shot estáticos, contexto de documento compartilhado em aplicações RAG, histórico de conversa multi-turn.

A conta é gritante. Um system prompt de 2.000 tokens com 10.000 requisições/dia no Claude Sonnet:

Cenário Custo Diário (parte do system prompt)
Sem caching 2.000 × 10.000 × US$ 0,003/1K = US$ 60,00
Com caching (99% de hit rate) ~US$ 7,00

US$ 53/dia. Mais de US$ 1.500/mês. Só no system prompt. Passei por esse cálculo com um cliente mês passado e eles habilitaram caching antes da nossa call terminar.

Pegadinhas para ter em mente:

  • O comprimento mínimo de prefixo cacheável varia por modelo (normalmente 1.024-2.048 tokens)
  • Matching exato de prefixo — espaços em branco e ordem importam
  • TTL / expiração após inatividade (seu cache esfria se o tráfego cair)
  • Nem todos os modelos suportam caching ainda — confira a documentação atual

Construindo um Framework de Benchmarking

Suas decisões de otimização devem ser orientadas por dados dos seus workloads reais. É o que meu time recomenda.

Para cada modelo e configuração que você testar, capture: custo por tarefa, contagens de tokens de input/output, latência (tempo até o primeiro token e total) e um score de qualidade específico para a tarefa.

O processo: escolha 3-5 tarefas que representem o mix do seu workload real, crie 100-500 exemplos de teste por tarefa com outputs conhecidos como bons, rode cada tarefa em todo modelo candidato, calcule o custo por tarefa (não por token — modelos tokenizam de forma diferente) e plote custo vs. qualidade para encontrar o joelho da curva. Mesmo um scatter plot tosco já dá — você está procurando "mesma qualidade, muito mais barato" ou "qualidade um pouco pior, drasticamente mais barato".

Montei um script em Python (benchmark_bedrock.py) que automatiza isso — roda prompts em vários modelos do Bedrock, registra contagens de tokens e latência, gera CSV e imprime estatísticas resumidas. Faça um fork e adapte aos seus workloads.

Ao interpretar os resultados, procure modelos onde a qualidade estabiliza (Haiku a 93% vs. Sonnet a 95% — vale 10x por esses 2%?), outliers de latência, diferenças de eficiência de tokens (um modelo mais barato por token, mas 2x mais verboso, não é, na prática, mais barato) e candidatos a batch.

Visibilidade Unificada de Custos GenAI com DoiT GenAI Intelligence

A maioria dos times com quem trabalho não roda só Bedrock. Eles têm OpenAI para alguns workloads, Anthropic direto para outros, talvez Vertex AI em algum projeto GCP. Os dados de custo acabam espalhados por quatro consoles com dimensões incompatíveis.

Construímos o GenAI Intelligence para resolver isso. Ele consolida dados de custo e uso de IA do Bedrock, Vertex AI, Azure ML, Databricks, Anthropic e OpenAI em uma única visão normalizada. Seu gasto com Bedrock aparece junto com tudo o mais. Sem ETL customizado.

No caso do Bedrock, o valor está nos labels normalizados. Model / Model Family rastreia o custo por modelo entre provedores. Usage Type quebra o gasto entre tokens de input e de output — a divisão que a maioria dos times subestima. Cached mostra se as operações usaram tokens em cache, então você consegue medir o ROI do caching a partir dos dados de billing. GenAI Spend marca todos os custos de IA generativa, independente do provedor, para tracking total de orçamento.

Você pode fazer perguntas como "Quanto os tokens em cache no Claude Sonnet nos economizaram no mês passado?" ou "Qual a divisão de gasto entre Haiku e Sonnet na classificação de tickets?" — entre provedores, em um só lugar.

O dashboard vem com relatórios pré-configurados: gasto por provedor (mensal), custo por família de modelo (diário nos últimos 14 dias — pega picos rápido), breakdown de tokens por modelo (30 dias) e uso de tokens por hora por provedor (últimos 2 dias — útil para correlacionar com deploys). Como os dados de GenAI fluem para o nosso engine de Cloud Analytics, você também ganha budgets, alocações, detecção de anomalias e forecasting sobre o seu gasto com IA.

Digamos que você esteja rodando Haiku para classificação e Sonnet para raciocínio, com caching nos dois:

Modelo Cached Custo Mensal Uso de Tokens
Claude Haiku true US$ 45 18M tokens
Claude Haiku false US$ 320 12M tokens
Claude Sonnet true US$ 180 4M tokens
Claude Sonnet false US$ 2.100 6M tokens

O cache hit rate do Haiku está sólido (60% dos tokens em cache). O do Sonnet está ruim (40%). Corrigir o caching do Sonnet pode economizar centenas por mês — e você identificou isso sem escrever uma única query no CloudWatch.

Para começar: conecte sua conta AWS à DoiT, vá em Dashboards → GenAI Intelligence, e seus dados do Bedrock são populados automaticamente. Sem necessidade de instrumentação no lado do Bedrock.

Observabilidade com OpenTelemetry

Benchmarking dá um snapshot pontual. Workloads em produção sofrem drift — prompts mudam, padrões de tráfego mudam, novos modelos são lançados. O GenAI Intelligence cobre o lado de billing da visibilidade contínua. Para instrumentação no nível da aplicação — latência, decisões de roteamento, cache hits por requisição — OpenTelemetry é o que recomendo.

As convenções semânticas do GenAI fazem com que qualquer backend compatível com OTel (Grafana, Datadog, Honeycomb) entenda os seus spans. Envolva cada invocação do Bedrock em um span com estes atributos:

  • gen_ai.system"aws.bedrock"
  • gen_ai.request.model — o ID do modelo
  • gen_ai.usage.input_tokens / output_tokens — dos metadados da resposta
  • gen_ai.usage.cost — calculado a partir da sua tabela de pricing
  • task.type — o nome da tarefa no nível da aplicação

O que você ganha: tendências de custo por tarefa ao longo do tempo (pega prompt drift antes de bater na sua fatura), validação do roteamento de modelos (o Tier 1 de um cliente estava lidando com 40% em vez dos 70% esperados — um bug que custava US$ 800/mês a mais) e monitoramento de cache hit rate (pegue quedas em horas, não no fim do ciclo de billing).

Você também ganha os dados para correlacionar com o ModelUnitUtilization do CloudWatch nas decisões de provisioned throughput.

Instrumentação mínima:

from opentelemetry import trace
tracer = trace.get_tracer("bedrock-client")
def invoke_with_telemetry(client, model_id, prompt, max_tokens, task_type="unknown"):
with tracer.start_as_current_span("bedrock.invoke") as span:
span.set_attribute("gen_ai.system", "aws.bedrock")
span.set_attribute("gen_ai.request.model", model_id)
span.set_attribute("gen_ai.request.max_tokens", max_tokens)
span.set_attribute("task.type", task_type)
resp = client.invoke_model(modelId=model_id, body=body, contentType="application/json")
data = json.loads(resp["body"].read())
in_tok = data["usage"]["input_tokens"]
out_tok = data["usage"]["output_tokens"]
span.set_attribute("gen_ai.usage.input_tokens", in_tok)
span.set_attribute("gen_ai.usage.output_tokens", out_tok)
return data

A partir daí, monte quatro painéis — custo diário por modelo, custo por tarefa por modelo, cache hit rate, latência p50/p95 — e revise semanalmente.

Armadilhas Comuns

Os erros que vejo com mais frequência, em ordem aproximada de quanto dinheiro desperdiçam:

Monitore semanalmente a utilização do provisioned throughput. Abaixo de 50% sustentado? Mude para on-demand. Aquela empresa de mídia desperdiçava mais com capacidade provisionada ociosa do que gastava em inferência de verdade.

Modele e limite os tokens de output. Tokens de output custam de 3 a 5 vezes mais que os de input. Um time cortou 40% dos custos de output só adicionando "responda em JSON, sem explicações" aos seus prompts de extração.

Coloque em batch tudo o que não precisa de latência abaixo de 24 horas. 50% de desconto. Sem comprometer qualidade.

Não deixe o Sonnet ser o padrão. Usar para tudo porque funcionou na prototipação é a forma mais comum de gasto excessivo que vejo.

Ative caching onde quer que você reuse prompts. System prompt estático ou exemplos few-shot? Minutos de trabalho, economia imediata.

Meça por tarefa, não por token. Um modelo mais barato que produz output mais verboso pode custar mais por tarefa. Faça benchmark no nível da tarefa.

Juntando Tudo

O caminho de otimização que percorro com a maioria dos times:

  1. Batch inference — mova workloads assíncronos. Economia imediata de 50%, zero impacto na qualidade.
  2. Prompt caching — habilite para contexto repetido. Minutos de trabalho.
  3. Benchmark de modelos alternativos — você provavelmente vai descobrir que 60-80% do seu workload roda bem no Tier 1.
  4. Roteamento de modelos — construa um classificador. Comece com regras.
  5. Provisioned throughput — só depois que os anteriores estiverem estáveis e o seu uso for previsível.

Isso se acumula. Aquele cliente do setor financeiro que mencionei no início? Eles fizeram os passos 1-4 ao longo de seis semanas. Batch inference economizou 22%. Caching economizou 18%. Roteamento de modelos economizou outros 25%. Total: de US$ 40 mil para US$ 18 mil.

Isso não é um projeto de uma vez só, porém. O cenário do Bedrock muda constantemente. Quando o Claude 3.5 Haiku foi lançado, era significativamente melhor que o Claude 3 Haiku, mais ou menos no mesmo ponto de preço — times que tinham hardcoded os IDs dos modelos perderam o upgrade por meses. A AWS já ajustou o pricing do Bedrock várias vezes sem muito alarde. E o seu próprio workload sofre drift: prompts ficam mais longos, novos tipos de tarefa são adicionados, proporções de tráfego mudam.

O que funciona: uma revisão trimestral leve. Rode novamente seus benchmarks contra qualquer modelo novo (leva uma tarde com o script de benchmarking). Use LLM-as-a-judge para validar que a qualidade não regrediu. Cheque seus dashboards de OTel para detectar drift de roteamento — o Tier 1 ainda está lidando com a porcentagem de tráfego que você espera? Sua taxa de cache hit mudou?

Se você é cliente DoiT, o GenAI Intelligence vai te mostrar tendências de custo por modelo que tornam óbvio quando algo mudou. A revisão inteira leva meio dia depois que você faz pela primeira vez.

A empresa de mídia que mencionei antes descobriu, durante uma dessas revisões, que uma mudança de prompt tinha derrubado silenciosamente a taxa de cache hit deles de 94% para 61% — US$ 2 mil/mês a mais que ninguém tinha notado.

Se você está no Bedrock hoje e quer um segundo par de olhos na sua fatura, fico feliz em dar uma olhada — especialmente se você está na APAC. E se já é cliente DoiT, você tem o dashboard do GenAI Intelligence — use-o como ponto de partida para essa revisão trimestral.


O script de benchmarking referenciado neste artigo está disponível em https://github.com/p-obrien/bedrock-cost-model-blog. Rode-o nos seus próprios workloads para gerar os dados que você precisa para tomar decisões fundamentadas.