mozak.tech Arquitetura de IA Corporativa 57%

Parte 5 — AI FinOps, Inflação de Tokens e Roteamento de Modelos

5.4 — Otimização de Payload no Harness: Contenção de Contexto e Redução de Overengineering

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 aceitar

Essa 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étricaAntes da contençãoDepois
Custo médio por turno (turno 15+)US$ 0,0840US$ 0,0210
Taxa de reaproveitamento de cache12%68%
Tokens de saída médios por chamada2.400340
Taxa de retrabalho pós-resposta22%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".