Objetivo da Aula
Aplicar sumarização de contexto, truncamento seletivo e cache de prompt para reduzir custo de API sem perder qualidade de resposta
Identificar o padrão de overengineering gerado pelo próprio modelo — escopo, verbosidade e complexidade além do necessário — e desenhar contenção estrutural no harness
Desenhar estratégia de janela deslizante e sumarização hierárquica para sessões e loops de agente longos
Estruturar prompts para maximizar o aproveitamento de cache de prefixo, reduzindo o custo efetivo por turno
Avaliar o trade-off entre agressividade de contenção de contexto e risco de perda de informação relevante para a tarefa
Por que isso importa
Os três capítulos anteriores desta Parte deram o vocabulário (5.1), a instrumentação (5.2) e o critério de roteamento (5.3) para gerenciar custo de IA como propriedade de arquitetura. Este capítulo fecha o ciclo com a pergunta prática que sobra depois de medir e rotear: dado que o contexto vai crescer, e que nem toda tarefa pode ser resolvida em Tier 1, o que o harness faz, estruturalmente, para conter o payload que efetivamente é enviado a cada chamada?
Existe ainda um segundo problema, menos discutido, mas igualmente custoso: modelos de linguagem têm uma tendência estrutural a overengineering — gerar mais código, mais explicação, mais escopo do que a tarefa pedia. Um agente de codificação instruído a "corrigir um bug de validação de formulário" pode devolver, sem que ninguém tenha pedido, uma refatoração completa do módulo, testes adicionais e um novo sistema de logging. Isso não é só um problema de qualidade de engenharia (mudanças fora de escopo são mais difíceis de revisar) — é um problema de custo direto, porque cada token de saída gerado a mais custa dinheiro, e frequentemente gera mais um ciclo de revisão e correção.
Impacto direto no seu trabalho: contenção de payload não é uma otimização de última hora — é uma decisão de arquitetura do harness, tomada junto com o desenho de contexto (Parte 1, Capítulo 1.2) e de estado (Capítulo 1.4). Um harness que não foi desenhado para conter contexto e escopo desde o início acumula dívida de custo que só piora conforme o sistema escala em uso.
Conceitos Fundamentais
O overengineering como problema de payload, não só de qualidade
Modelos de linguagem grandes são treinados, em grande parte, com exemplos de código e texto "completos" e "bem-feitos" — o que os inclina a preencher lacunas com mais conteúdo, mesmo quando a tarefa pedia o mínimo. Sem contenção explícita no harness, isso se manifesta como inflação de payload de saída — e, em loops de agente, como inflação recursiva de payload de entrada no turno seguinte, porque a saída excessiva de um turno vira contexto do próximo.
Instrução: "Corrija o bug de validação de e-mail na função
validarFormulario()"
Resposta SEM contenção de escopo (comum, sem restrição explícita):
- corrige o bug pedido (correto)
- refatora validarFormulario() inteira para "melhor legibilidade"
- adiciona 3 novas funções de validação não solicitadas
- gera 40 linhas de comentário explicativo
- sugere um novo padrão de arquitetura para o módulo inteiro
Tokens de saída: ~2.400
Resposta COM contenção de escopo (system prompt explícito,
ver "Restringindo escopo de saída" adiante):
- corrige exatamente o bug pedido
- não modifica nenhuma outra parte da função
Tokens de saída: ~180
Diferença de custo de output: ~13x — antes de contar o custo
do ciclo de revisão humana adicional que a resposta maior gera.O ponto central: overengineering não é um problema abstrato de "o modelo é prolixo" — é um multiplicador direto de custo de output (que já é o componente mais caro por token, como visto no Capítulo 5.1) e de custo de contexto acumulado nos turnos seguintes, se o payload extra não for podado.
Sumarização de contexto
A técnica mais direta de contenção é substituir histórico bruto por um resumo compacto, preservando apenas a informação necessária para o modelo continuar a tarefa com coerência.
Sem sumarização (turno 15 de um agente investigativo):
Contexto enviado = system_prompt + 14 turnos completos
≈ 11.200 tokens
Com sumarização (a cada 5 turnos, resume-se o bloco anterior):
Contexto enviado = system_prompt
+ resumo(turnos 1-5) ≈ 300 tokens
+ resumo(turnos 6-10) ≈ 300 tokens
+ turnos 11-14 completos (recentes, sem resumir)
≈ 400 + 300 + 300 + 3.200 = 4.200 tokens
Redução: (11.200 - 4.200) / 11.200 ≈ 62%A regra prática mais comum é manter os turnos mais recentes em texto completo (o modelo raciocina melhor sobre eventos recentes com fidelidade total) e sumarizar progressivamente os turnos mais antigos — um padrão chamado de janela deslizante com sumarização em camadas, detalhado na seção de Aprofundamento.
Truncamento seletivo
Nem toda informação em um contexto longo tem o mesmo valor para a tarefa atual. Truncamento seletivo remove ou reduz partes do contexto com base em relevância, não apenas em idade (diferente da sumarização por janela, que é temporal).
Estratégias de truncamento seletivo, da mais simples à mais sofisticada:
1. Truncamento por posição fixa
Mantém só os últimos N tokens do histórico.
Simples, barato, mas pode descartar informação crítica
estabelecida no início da sessão (ex: a restrição original
da tarefa).
2. Truncamento por relevância a âncoras fixas
Mantém sempre: (a) o prompt de sistema, (b) a instrução
original da tarefa, (c) a janela recente.
Descarta o meio da conversa — que normalmente contém
tentativas intermediárias já superadas.
3. Truncamento por relevância semântica
Usa similaridade de embeddings (Parte 2, Capítulo 2.3)
entre a pergunta atual e os turnos anteriores, mantendo
só os turnos mais relevantes ao problema em curso —
mesmo que estejam distantes no tempo.A estratégia 2 (âncoras fixas) é o padrão mínimo recomendado para qualquer harness de agente de produção: descartar a instrução original da tarefa por estar "velha demais" no histórico é um erro estrutural comum que causa deriva de escopo (o agente esquece a restrição original e passa a operar fora dela) — outro contribuinte direto para o overengineering discutido acima.
Estruturando o payload para maximizar cache de prefixo
O Capítulo 5.1 introduziu o desconto de cache de prompt como alavanca de custo. Esse desconto só se aplica, na prática, à parte do prompt que é idêntica, byte a byte, ao mesmo prefixo já processado em uma chamada anterior. Isso significa que a ordem em que o harness monta o payload importa diretamente para o custo.
Estrutura de payload RUIM para cache (conteúdo variável primeiro):
[ID de sessão + timestamp variável]
[system prompt — estável]
[definição de ferramentas — estável]
[histórico da conversa]
→ Qualquer mudança no início do prompt invalida o cache de
TUDO que vem depois, mesmo que o resto seja idêntico.
Estrutura de payload BOA para cache (conteúdo estável primeiro):
[system prompt — estável] ← cacheável
[definição de ferramentas — estável] ← cacheável
[contexto de sessão/RAG relativamente estável] ← cacheável
[histórico recente — muda a cada turno]
[pergunta atual — sempre nova]
→ O prefixo estável é reaproveitado do cache em toda chamada;
só o final do payload precisa ser reprocessado a preço cheio.Fundamento: Prefixo Estável e Efeito Cascata do Cache
Cache de prompt funciona por correspondência de prefixo: o provedor de modelo reconhece que os primeiros N tokens de uma nova chamada são idênticos a uma chamada processada recentemente, e reaproveita esse processamento. A implicação arquitetural é que qualquer conteúdo dinâmico colocado antes de conteúdo estável — um timestamp, um ID de sessão, uma ordenação não determinística de ferramentas disponíveis — quebra o cache para tudo que vem depois dele no payload, mesmo que o restante do conteúdo seja idêntico byte a byte. Projetar a ordem do payload (estável → variável) não é um detalhe de implementação: é a diferença entre pagar preço cheio ou preço com desconto em uma fração potencialmente grande do contexto enviado a cada chamada.
Aprofundamento Técnico
Sumarização hierárquica multi-nível
Para sessões muito longas (loops de agente investigativo com dezenas de turnos, Capítulo 4.3), sumarizar uma vez não é suficiente — o próprio resumo cresce ao longo do tempo. A solução é sumarização em camadas, onde resumos de blocos antigos são periodicamente resumidos novamente em um nível acima.
Nível 0 (bruto): turnos 1-5, 6-10, 11-15, 16-20 (completos)
Nível 1 (resumo): resumo(1-5), resumo(6-10), resumo(11-15), resumo(16-20)
Nível 2 (meta-resumo): resumo( resumo(1-5) + resumo(6-10) )
= resumo consolidado dos turnos 1-10
Contexto enviado no turno 25, com 3 níveis de compactação:
meta-resumo(turnos 1-10) ≈ 250 tokens
resumo(turnos 11-15) ≈ 300 tokens
resumo(turnos 16-20) ≈ 300 tokens
turnos 21-24 completos ≈ 3.000 tokens
Total: ≈ 3.850 tokens
Contra o custo de enviar 24 turnos completos sem nenhuma
compactação (≈ 19.000+ tokens nesse ponto da sessão):
redução ≈ 80%O custo dessa técnica não é zero: cada sumarização é, ela mesma, uma chamada ao modelo (idealmente Tier 1 — sumarizar é uma tarefa de complexidade baixa, ver Capítulo 5.3), e existe risco de perda de informação a cada nível de compactação. A prática recomendada é sumarizar de forma extrativa quando possível (preservar fatos, decisões e restrições literalmente, não parafrasear) e reservar sumarização mais livre apenas para contexto narrativo de baixo risco.
O trade-off entre agressividade de contenção e risco de perda de informação
Os dois extremos do espectro de contenção trazem trade-offs opostos:
Contenção fraca
- Custo alto, contexto completo preservado, baixo risco de "esquecimento" do agente.
Contenção agressiva
- Custo baixo, risco de perder restrição crítica estabelecida cedo na sessão, gerando decisão incoerente ou repetição de erro já corrigido antes.
Mitigação prática: âncoras fixas (instrução original, restrições de escopo, decisões já tomadas) NUNCA entram na rotina de sumarização/truncamento — ficam fixadas no payload em toda chamada, independente de idade.
Esse é o mesmo princípio do ponto de equilíbrio discutido no Capítulo 5.1: não existe uma configuração de contenção de payload universalmente correta. A calibração certa depende de quanto a tarefa específica depende de fidelidade histórica completa (ex: um agente de auditoria, onde perder um detalhe é inaceitável) versus quanto ela tolera compactação agressiva (ex: um agente de triagem, onde o contexto relevante é sempre o mais recente).
Restringindo escopo de saída para conter overengineering
Contenção de payload não é só sobre o que entra no modelo — é também sobre o que o harness aceita como saída válida. Restringir explicitamente o escopo esperado, no prompt de sistema e na validação pós-resposta, é a defesa mais efetiva contra overengineering.
Instrução de sistema SEM restrição de escopo:
"Você é um assistente de programação. Ajude o usuário a
corrigir o código."
Instrução de sistema COM restrição de escopo explícita:
"Você é um assistente de programação. Corrija APENAS o
problema descrito na instrução do usuário. Não refatore,
não adicione funcionalidade não solicitada, não modifique
arquivos fora do escopo da instrução. Se identificar um
problema adicional relevante, REPORTE-O em uma linha
separada — não o corrija sem aprovação explícita."
Validação pós-resposta (harness, automática):
- diff gerado toca só os arquivos listados no escopo da tarefa?
→ se não, rejeitar e pedir nova tentativa restrita
- tamanho do diff está dentro de um teto razoável para o
tipo de tarefa (ex: bug pontual → diff pequeno esperado)?
→ se muito acima do esperado, sinalizar para revisão humana
antes de aceitarEssa combinação — instrução explícita de escopo mínimo, mais validação estrutural automática no harness — ataca o overengineering em duas camadas: a primeira reduz a probabilidade do modelo gerar excesso; a segunda captura os casos em que, mesmo assim, ele gerar. Nenhuma das duas sozinha é suficiente — instrução sem validação depende inteiramente do modelo obedecer; validação sem instrução clara rejeita respostas sem dar ao modelo um alvo melhor na próxima tentativa.
Medindo o efeito da otimização de payload
Toda técnica deste capítulo só se justifica se movimentar as métricas definidas nos Capítulos 5.1 e 5.2. A prática recomendada é medir antes e depois de qualquer mudança de contenção de payload, isolando o efeito:
| Métrica | Antes da contenção | Depois |
|---|---|---|
| Custo médio por turno (turno 15+) | US$ 0,0840 | US$ 0,0210 |
| Taxa de reaproveitamento de cache | 12% | 68% |
| Tokens de saída médios por chamada | 2.400 | 340 |
| Taxa de retrabalho pós-resposta | 22% | 9% |
A última linha é a mais importante: contenção de payload que reduz custo, mas aumenta taxa de retrabalho (porque cortou informação necessária), pode piorar o custo por unidade de valor (Capítulo 5.1) mesmo reduzindo o custo por chamada.
É essa medição fechando o ciclo — custo (5.1), instrumentação (5.2), roteamento (5.3) e contenção de payload (5.4) — que transforma FinOps de IA de um exercício pontual de corte de custo em uma disciplina de arquitetura contínua: cada mudança estrutural no harness é validada contra dado real, não contra a suposição de que "menos contexto é sempre melhor" ou "modelo maior é sempre mais seguro".