Quanto custa um agente de IA em produção: a conta real de tokens
Seu protótipo custou R$ 12 no primeiro dia. Em produção, com 200 usuários, ele custa quase R$ 4.000 por mês. E ninguém no time sabe explicar por quê.
Quanto custa um agente de IA não é uma pergunta de tabela de preço. A resposta está na planilha que ninguém abre: quanto cada camada do agente (system prompt, definições de tool, chunks de RAG, histórico, tool results) empurra de token para dentro de cada chamada. Você não paga por pergunta. Você paga por contexto reenviado, turno após turno.
Neste post eu abro a conta de token de um agente em produção, linha a linha, com os preços públicos de hoje. Depois aplico três alavancas (compressão de prompt, pruning de histórico e seleção de contexto) e mostro a mesma planilha com os números depois. Corte final: 73%.
TL;DR
- O que é: a anatomia de custo de token de um agente de suporte em produção, com planilha antes e depois.
- Stack/Modelos: Claude Sonnet 5 (US$ 2/MTok entrada, US$ 10/MTok saída), tool calling, RAG, prompt caching, context editing.
- Cenário: 200 usuários, 18 conversas/mês cada, 6 turnos por conversa, 12 tools declaradas.
- Resultado: de US$ 728,64/mês (R$ 3.935) para US$ 196,67/mês (R$ 1.062), sem trocar de modelo e sem cortar feature.
- Câmbio usado: R$ 5,40 por dólar. Ajuste para o câmbio do dia.
Onde o token vai embora: anatomia de uma chamada cara
Pega o turno 6 de uma conversa de suporte. O usuário digitou uma frase de 120 tokens. Foi isso que ele fez. Agora olha o que a sua aplicação mandou junto:
| Camada | Tokens de entrada | % da chamada |
|---|---|---|
| System prompt (persona, regras, formato) | 1.800 | 8,5% |
| Definições das 12 tools (JSON Schema) | 4.200 | 19,9% |
| Chunks de RAG (5 × 600) | 3.000 | 14,2% |
| Histórico dos 5 turnos anteriores | 2.500 | 11,8% |
| Tool results acumulados (4 chamadas) | 9.500 | 45,0% |
| Mensagem do usuário | 120 | 0,6% |
| Total de entrada | 21.120 | 100% |
A pergunta do usuário é 0,6% da conta.
E três camadas que quase ninguém revisa (tool results, definições de tool e chunks de RAG) somam 79,1%. É aí que some o dinheiro. Não no modelo, não no output, não na "IA cara". Some em payload que você montou uma vez, achou razoável, e nunca mais mediu.
Custo dessa chamada única no Claude Sonnet 5, a US$ 2 por milhão de tokens de entrada e US$ 10 por milhão de saída, com 350 tokens de resposta:
entrada: 21.120 × $2 / 1.000.000 = $0,042240
saída: 350 × $10 / 1.000.000 = $0,003500
---------
total do turno 6: $0,045740
Quatro centavos e meio. Parece nada. Multiplica por 6 turnos, por 18 conversas, por 200 usuários, por 12 meses, e você tem um item de linha que o financeiro vai perguntar sobre.
Essa conta (e as decisões de arquitetura que a mudam: roteamento de tools, memória, grounding, tracing) é o módulo 11 do AI Engineering Lab 3ª Edição, imersão ao vivo nos dias 19 e 20 de setembro, das 9h às 13h. É onde a gente destrincha o agente inteiro, não só a camada de custo.
Como medir isso sem chutar
Não estime com tiktoken nem com "divide por 4". Meça com o endpoint de contagem, camada por camada, por diferença:
import anthropic
client = anthropic.Anthropic()
MODELO = "claude-sonnet-5"
PING = [{"role": "user", "content": "."}]
def tokens(**kwargs) -> int:
return client.messages.count_tokens(
model=MODELO, messages=PING, **kwargs
).input_tokens
piso = tokens()
com_system = tokens(system=SYSTEM_PROMPT)
com_tools = tokens(system=SYSTEM_PROMPT, tools=TOOLS)
print("system:", com_system - piso) # 1.800
print("tools :", com_tools - com_system) # 4.200
Rode isso no CI. Se alguém adicionar a décima terceira tool, o diff mostra +380 tokens em toda chamada do produto, para sempre. Isso é uma decisão de arquitetura, não um commit de rotina.
O custo escondido do histórico que ninguém poda
Aqui está a parte que quebra o modelo mental de quem veio de API REST: numa conversa, você paga o turno 1 seis vezes.
O contexto é stateless. Cada chamada reenvia tudo. A conta cresce por turno:
| Turno | Entrada (tokens) | Acumulado |
|---|---|---|
| 1 | 9.120 | 9.120 |
| 2 | 11.520 | 20.640 |
| 3 | 13.920 | 34.560 |
| 4 | 16.320 | 50.880 |
| 5 | 18.720 | 69.600 |
| 6 | 21.120 | 90.720 |
Uma conversa de 6 turnos consome 90.720 tokens de entrada para 2.100 tokens de saída. Proporção de 43:1.
entrada: 90.720 × $2 / 1.000.000 = $0,181440
saída: 2.100 × $10 / 1.000.000 = $0,021000
---------
por conversa: $0,202440
Agora o mês: 200 usuários × 18 conversas = 3.600 conversas.
3.600 × $0,202440 = $728,64/mês → R$ 3.934,66
Contra R$ 12 do dia de teste (75 conversas curtas, de 3 turnos, sem tool result gordo acumulado). O protótipo não estava errado. Ele só media outra coisa.
A primeira alavanca é gratuita: prompt caching
A base fixa (system + tools) são 6.000 tokens idênticos em toda chamada. O prompt caching cobra escrita de cache a 1,25x o preço de entrada (TTL de 5 minutos) ou 2x (TTL de 1 hora), e leitura a 0,1x. Ou seja: a partir da segunda chamada, aquele bloco custa 10% do que custava.
O detalhe que trava gente: o mínimo cacheável é de 1.024 tokens no Sonnet 5 e 512 no Opus 5. Prefixo menor que isso não cacheia, e a API não reclama. Fica silenciosamente caro.
Dois breakpoints resolvem a conversa inteira. Um estático no fim do system (congela tools + system, que é a ordem de renderização) e um móvel no fim do histórico:
response = client.messages.create(
model="claude-sonnet-5",
max_tokens=1024,
tools=TOOLS,
system=[{
"type": "text",
"text": SYSTEM_PROMPT,
"cache_control": {"type": "ephemeral"}, # congela tools + system
}],
messages=historico_com_breakpoint_movel + [nova_pergunta],
)
u = response.usage
total = u.input_tokens + u.cache_creation_input_tokens + u.cache_read_input_tokens
print(f"read={u.cache_read_input_tokens} write={u.cache_creation_input_tokens}")
Se cache_read_input_tokens vier zero em requisições repetidas, tem invalidador silencioso no seu prefixo: um datetime.now() no system prompt, um JSON de tools serializado sem ordenação estável, um user_id interpolado antes do breakpoint. Qualquer byte que muda no prefixo mata tudo que vem depois. Esse mecanismo é o mesmo que faz sua sessão de assistente de código evaporar, e eu já detalhei os sete jeitos de quebrar ele em como economizar tokens em Claude Code, Codex e Cursor.
Só com cache incremental, a mesma conversa cai de US$ 0,2024 para US$ 0,0877. O mês vai para US$ 315,72 (R$ 1.704). Corte de 57% sem tocar em uma linha do prompt.
Tool results: o maior vilão do contexto
45% da chamada mais cara são tool results. Vale entender por que isso acontece com quase todo agente.
Uma tool devolve o que a API devolve. Você chama consultar_pedido e recebe 2.400 tokens de JSON: endereço completo, histórico de status, dados do transportador, campos de auditoria, três níveis de objeto aninhado que ninguém lê. O modelo precisava de duas coisas: status e data prevista.
Pior: esse JSON fica no histórico. Turno 3 chamou a tool. Turno 6 ainda está pagando por ele. Quatro tool results acumulados viram 9.500 tokens que você reenvia até a conversa acabar.
Tem duas formas de podar isso, e elas resolvem problemas diferentes.
Na aplicação, antes de mandar. Você controla o formato. Projete o retorno da tool para o modelo, não para o log:
def podar_tool_results(messages, manter=3, resumo=200):
"""Mantém os N tool results mais recentes na íntegra.
Os antigos viram uma linha de sumário."""
indices = [i for i, m in enumerate(messages) if eh_tool_result(m)]
for i in indices[:-manter]:
messages[i] = resumir(messages[i], limite=resumo)
return messages
No servidor, com context editing. A estratégia clear_tool_uses_20250919 limpa os tool results mais antigos antes do prompt chegar no modelo, mantendo os N mais recentes:
resp = client.beta.messages.create(
model="claude-sonnet-5",
max_tokens=4096,
betas=["context-management-2025-06-27"],
context_management={"edits": [{
"type": "clear_tool_uses_20250919",
"trigger": {"type": "input_tokens", "value": 30000},
"keep": {"type": "tool_uses", "value": 3},
"clear_at_least": {"type": "input_tokens", "value": 5000},
"exclude_tools": ["consultar_pedido"],
}]},
tools=TOOLS,
messages=messages,
)
print(resp.context_management.applied_edits)
# [{'cleared_tool_uses': 8, 'cleared_input_tokens': 50000}]
Cuidado com a interação: toda limpeza invalida o prefixo cacheado. Se você limpar 800 tokens e reescrever 12.000 de cache, você perdeu dinheiro. É exatamente para isso que serve o clear_at_least: só aplica a edição se ela valer o custo da reescrita.
A justificativa nem é só financeira. A documentação da Anthropic é direta: "contexto deve ser tratado como um recurso finito com retornos marginais decrescentes". Existe o efeito de context rot: conforme o número de tokens cresce, a capacidade do modelo de recuperar informação daquele contexto cai. Você paga mais para o agente errar mais.
Tutorial te mostra o caminho — no Clã você constrói junto. Aula ao vivo toda semana, projetos reais de Engenharia de IA, ao lado de quem já está em produção.
Entrar no ClãCompressão e pruning na prática, com números antes e depois
Três alavancas, aplicadas na mesma chamada do turno 6.
1. Compressão de prompt. O system prompt de 1.800 tokens tinha quatro exemplos few-shot que faziam a mesma coisa. Ficaram dois: 1.650. As 12 tools eram declaradas sempre, em toda chamada, mesmo quando a conversa era só sobre rastreio. Roteamento por domínio carrega 5: de 4.200 para 1.750.
2. Pruning de histórico e tool results. Os 3 tool results mais recentes ficam íntegros, os antigos viram sumário de uma linha: de 9.500 para 4.100. Os turnos 1 a 3 do histórico viram um parágrafo de resumo: de 2.500 para 1.400.
3. Seleção de contexto. Os 5 chunks de RAG entravam em toda chamada por default. Com rerank e corte por score, entram 2, e só quando a query pede recuperação: de 3.000 para 1.200.
O turno 6 depois:
| Camada | Antes | Depois | Delta |
|---|---|---|---|
| System prompt | 1.800 | 1.650 | -8% |
| Definições de tools | 4.200 | 1.750 | -58% |
| Chunks de RAG | 3.000 | 1.200 | -60% |
| Histórico | 2.500 | 1.400 | -44% |
| Tool results | 9.500 | 4.100 | -57% |
| Mensagem do usuário | 120 | 120 | - |
| Total | 21.120 | 10.620 | -49,7% |
A conversa inteira cai de 90.720 para 46.020 tokens de entrada. Com os dois breakpoints de cache por cima:
| Cenário | Por conversa | Por mês (3.600) | Em reais |
|---|---|---|---|
| Baseline, sem cache, sem pruning | $0,2024 | $728,64 | R$ 3.934,66 |
| Só prompt caching | $0,0877 | $315,72 | R$ 1.704,89 |
| Caching + compressão + pruning | $0,0546 | $196,67 | R$ 1.062,02 |
Corte de 73%. Mesmo modelo, mesma feature, mesma qualidade de resposta.
E repara no que mudou de figura: no cenário otimizado, os US$ 0,021 de saída viraram 38% do custo da conversa. Enquanto o input estava obeso, o output era ruído estatístico. Depois de podar, ele vira o próximo gargalo. É aí que entram limite de verbosidade, output_config.effort mais baixo em rotas simples e structured output para cortar preâmbulo.
Se o seu caso não precisa de resposta em tempo real (classificação em lote, enriquecimento noturno, geração de relatório), a Batch API corta mais 50% por cima disso, com a maioria dos lotes terminando em menos de uma hora.
O cálculo de margem: quando o produto não fecha a conta
Agora a parte que decide se o produto existe.
Assinatura de R$ 79 por usuário. 200 usuários. MRR de R$ 15.800.
| Custo de token | % da receita | Custo por usuário | |
|---|---|---|---|
| Baseline | R$ 3.934,66 | 24,9% | R$ 19,67 |
| Otimizado | R$ 1.062,02 | 6,7% | R$ 5,31 |
SaaS vive de margem bruta de 70% a 80%. Com inferência comendo 25% da receita, antes de infra, observabilidade, suporte e folha, não sobra produto. Com 6,7%, sobra.
Mas a média mente. O que mata margem é a cauda.
| Perfil | Conversas/mês | Custo otimizado | Receita | Resultado |
|---|---|---|---|---|
| Mediana | 18 | R$ 5,31 | R$ 79 | saudável |
| P95 | 90 | R$ 26,55 | R$ 79 | apertado |
| P99 | 300 | R$ 88,50 | R$ 79 | prejuízo de R$ 9,50 |
No baseline, esse mesmo usuário P99 custava R$ 327,89 por mês para pagar R$ 79. Um único power user destruía a margem de quatro clientes medianos.
Três consequências de produto, não de engenharia:
- Preço plano ilimitado só funciona se o teto de custo for arquitetural. Ou você limita turnos por conversa, ou você limita conversas por ciclo, ou você cobra por consumo. Não existe quarta opção.
- O custo por usuário precisa estar num dashboard, não num relatório trimestral. Grave
input_tokens,cache_read_input_tokens,cache_creation_input_tokenseoutput_tokenspor requisição, comuser_ide rota. Uma tabelatoken_ledgere um gráfico. É meio dia de trabalho e paga o ano. - Token é só um dos baldes. Eval em runtime, observabilidade, vector store, fila, pessoas. Se você quer a fatura completa de um agente ao longo de seis meses, é o que eu abri em Quanto custa um agente em produção em 2026: planilha real de TCO. Este post aqui é só a linha de inferência dela, aberta em camadas.
FAQ rápido
Afinal, quanto custa um agente de IA em produção?
Depende quase inteiramente de quantos tokens você reenvia por turno, não do preço do modelo. No cenário deste post, o mesmo agente custa entre R$ 1.062 e R$ 3.935 por mês para os mesmos 200 usuários. A variável não é o vendor. É a sua arquitetura de contexto.
O preço por token não está caindo? Não é melhor esperar?
O preço por token cai, mas o consumo por tarefa sobe mais rápido, porque agente novo faz mais turnos e usa mais tool. É uma discussão de mercado que eu destrinchei em IA vai ficar mais cara?. Para a sua planilha do mês que vem, o preço de lista é a variável que você não controla. Contexto é a que você controla.
Trocar de modelo não resolve mais rápido que otimizar contexto?
Às vezes, e vale medir. Mas cache é escopado por modelo: uma cascata de dois modelos abre dois namespaces de cache e você perde reuso nos dois. Faça a higiene de contexto primeiro (que é grátis), meça de novo, e só então troque de modelo com dado na mão.
Por que meu cache_read_input_tokens vive zerado?
Alguma coisa no prefixo muda a cada chamada. Os suspeitos de sempre: timestamp no system prompt, ordenação não determinística no JSON das tools, ID de sessão interpolado antes do breakpoint, ou prefixo menor que o mínimo cacheável do modelo (1.024 tokens no Sonnet 5). Log o usage cru de duas chamadas seguidas e compare byte a byte.
Fechando a planilha: quanto custa um agente de IA no seu caso
A conta de um agente em produção não é um número que você descobre. É um número que você projeta.
Cada tool que entra, cada exemplo few-shot que alguém cola no system prompt, cada chunk de RAG a mais no top-k: tudo isso é uma decisão de custo recorrente, multiplicada por todo turno de toda conversa de todo usuário. E quase nada disso aparece em code review.
O caminho é sempre o mesmo: meça por camada, cacheie o que é estável, pode o que é velho, selecione o que é relevante. Nessa ordem. Nesse cenário deu 73% de corte sem trocar de modelo.
Depois de fechar a linha de inferência, o próximo passo é olhar os cinco baldes que sobraram (eval, observabilidade, infra, dados e gente) e decidir build vs buy com número na mão.
Você sabe quanto custa a última chamada que o seu agente fez? Se a resposta for "não", esse é o primeiro bug para corrigir.
{AI Engineer} — apaixonado por Laravel, arquitetura de software e construir produtos com impacto. Compartilho aqui tutoriais, descobertas e reflexões sobre o dia a dia de engenharia.
Conteúdo é o que não falta. Falta quem desembaralhe: o que importa agora é como implementar do jeito certo. No Clã você tem isso ao vivo, toda semana, com quem já filtrou o ruído.
Entrar no Clã