Janela de contexto, degradação e extração de fatos
Objetivos de aprendizagem
- Identificar o que consome tokens na janela de contexto e por que
tool_results acumulam desproporcionalmente à sua relevância. - Reconhecer os sinais de degradação de contexto em sessões longas (respostas inconsistentes, "padrões típicos" no lugar de classes específicas).
- Explicar o efeito lost in the middle e como mitigá-lo com resumo inicial e section headers.
- Aplicar o padrão "case facts": extrair fatos transacionais para um bloco persistente fora do histórico resumido.
- Aparar (trim) tool outputs verbosos antes que eles se acumulem no contexto.
O que consome a janela de contexto
A janela de contexto é o orçamento total de tokens que o modelo enxerga em uma chamada. Tudo entra na conta:
- System prompt e definições de
tools(schemas JSON completos de cada ferramenta); - Histórico da conversa — todas as mensagens
usereassistantanteriores; - Blocos
tool_useetool_resultde cada chamada de ferramenta já executada; - Documentos e arquivos anexados ao prompt;
- Saída em geração (limitada por
max_tokens).
A API é stateless: para manter coerência conversacional, cada request subsequente precisa reenviar o histórico completo da conversa. É por isso que o crescimento do contexto é cumulativo — cada turno adiciona ao custo de todos os turnos seguintes.
Tool results dominam o consumo. Um lookup de pedido pode devolver 40+ campos (endereços, metadados de frete, histórico fiscal...) quando apenas 5 são relevantes para a tarefa — por exemplo, os campos ligados a devolução. Em sessões multi-turno, esses payloads inteiros ficam no histórico e são reenviados a cada chamada, consumindo tokens de forma desproporcional à sua relevância.
Sinais de degradação de contexto
Em sessões estendidas (exploração de codebase, atendimento longo, pesquisa multi-etapa), o contexto lotado degrada a qualidade das respostas antes mesmo de estourar o limite. Sinais clássicos que a prova cobra:
- Respostas inconsistentes com o que foi estabelecido em turnos anteriores (o modelo "esquece" decisões já tomadas);
- Generalização no lugar de especificidade: o modelo passa a citar "padrões típicos" ("normalmente um serviço de pagamento teria...") em vez das classes e funções específicas que ele mesmo descobriu no início da sessão;
- Repetição de trabalho: refazer buscas ou releituras já feitas;
- Perda de fatos numéricos: valores, datas e números de pedido citados de forma imprecisa.
Lost in the middle
Modelos processam com confiabilidade informação no início e no fim de entradas longas, mas podem omitir achados das seções intermediárias. Em um agregado de resultados de vários subagentes, os achados "do meio" são os mais propensos a sumir da síntese.
Mitigações que a prova espera:
- Colocar um resumo dos achados-chave no início do input agregado;
- Organizar os resultados detalhados com section headers explícitos (ex.:
## Fonte 3 — Relatório Q2), para dar âncoras de posição ao modelo; - Exigir que subagentes retornem saída estruturada com metadados (datas, localização da fonte, contexto metodológico) em vez de prosa verbosa, facilitando a síntese downstream.
O padrão "case facts": fatos fora do histórico resumido
Sumarização progressiva do histórico economiza tokens, mas tem um risco conhecido: condensar valores numéricos, percentuais, datas e expectativas declaradas pelo cliente em resumos vagos ("cliente pediu reembolso de um pedido recente" — qual pedido? de quanto?).
A solução é separar duas camadas de contexto:
| Camada | Conteúdo | Tratamento |
|---|---|---|
| Case facts (bloco persistente) | Fatos transacionais: valores, datas, números de pedido, status, expectativas declaradas | Extraídos de forma estruturada e incluídos verbatim em cada prompt, fora do resumo |
| Histórico conversacional | O vai-e-vem da conversa, raciocínio, cortesias | Pode ser resumido/comprimido com perda aceitável |
Em sessões com múltiplos problemas simultâneos (multi-issue), estruture os dados de cada issue (order IDs, valores, status) nessa camada separada — assim o resumo do histórico nunca é a única fonte dos fatos críticos.
Trim antes de acumular. Filtre tool outputs verbosos para apenas os campos relevantes antes de anexá-los como tool_result ao histórico. Aparar na origem é mais barato do que resumir depois — e evita que 35 campos irrelevantes sejam reenviados a cada turno.
Exemplo: camada de fatos + trim de tool output
import json
import anthropic
client = anthropic.Anthropic()
# Campos relevantes para o fluxo de devolução (5 de 40+ retornados pela API interna)
RETURN_RELEVANT_FIELDS = ["order_id", "amount", "status", "purchase_date", "return_deadline"]
def trim_order_lookup(raw_order: dict) -> dict:
"""Apara o tool output para apenas os campos relevantes antes de entrar no contexto."""
return {k: raw_order[k] for k in RETURN_RELEVANT_FIELDS if k in raw_order}
# Bloco "case facts": fatos transacionais persistidos FORA do historico resumido
case_facts = {
"customer_id": "C-88231",
"issues": [
{"order_id": "ORD-4412", "amount": 289.90, "status": "delivered",
"customer_expectation": "reembolso integral, prometido em ate 5 dias uteis"},
{"order_id": "ORD-4587", "amount": 74.50, "status": "in_transit"},
],
}
summarized_history = "Cliente relatou dois problemas; agente verificou identidade e consultou ambos os pedidos."
response = client.messages.create(
model="claude-opus-5",
max_tokens=2048,
system=(
"Voce e um agente de suporte. Os fatos do caso abaixo sao a fonte de verdade; "
"nunca cite valores ou datas que nao estejam neles.\n\n"
"<case_facts>\n" + json.dumps(case_facts, ensure_ascii=False) + "\n</case_facts>"
),
messages=[
{"role": "user", "content": (
"<historico_resumido>" + summarized_history + "</historico_resumido>\n\n"
"O cliente pergunta: qual o valor exato do reembolso do primeiro pedido e o prazo prometido?"
)},
],
)
print(response.content[0].text)
Repare: o resumo do histórico pode ser vago, mas o valor 289.90 e a expectativa "5 dias úteis" sobrevivem intactos porque vivem no bloco de fatos, não no resumo.
Pegadinhas da prova
- Distrator típico: "resuma todo o histórico com mais frequência" como resposta para perda de valores numéricos. Errado: sumarização progressiva é justamente a causa da perda de fatos transacionais — a resposta correta é extraí-los para um bloco persistente fora do resumo.
- Distrator típico: "aumente
max_tokens" para resolver degradação de contexto.max_tokenslimita a saída, não amplia a janela nem resolve acúmulo de histórico. - Distrator típico: "envie só a última mensagem do usuário para economizar tokens". A API é stateless: sem o histórico (completo ou gerenciado), o modelo perde toda a coerência conversacional.
- Distrator típico: confiar que o modelo "presta atenção igual em tudo". O efeito lost in the middle é real: achados no meio de inputs longos podem ser omitidos — posicione resumos no início e use section headers.
Resumo em 5 linhas
- Tudo consome a janela: system, tools, histórico, tool results — e a API stateless reenvia o histórico a cada turno.
- Tool results acumulam desproporcionalmente: 40+ campos quando 5 importam — apare na origem, antes de entrar no contexto.
- Degradação se manifesta como respostas inconsistentes e "padrões típicos" no lugar das classes específicas já descobertas.
- Lost in the middle: informação no meio de inputs longos some — resumo no início + section headers explícitos mitigam.
- Fatos transacionais (valores, datas, order IDs, expectativas do cliente) vão para um bloco "case facts" persistente, fora do histórico resumido.
Documentação oficial
Questões de fixação
1. Um agente de suporte usa sumarização progressiva do histórico. Após algumas horas, ele passa a citar valores de reembolso incorretos e datas vagas. Qual é a correção mais eficaz?
Gabarito: C. Fatos transacionais devem viver em uma camada persistente fora do resumo — assim a compressão do histórico nunca os degrada. A está errada porque resumir mais é justamente o que condensa números em vagueza. B confunde limite de saída com janela de contexto. D é enforcement por prompt sem garantia: o resumidor continua sendo lossy por natureza.
2. Em uma sessão longa de exploração de codebase, o modelo começa a descrever "padrões típicos de um serviço de pagamentos" em vez das classes específicas que ele mesmo listou no início da sessão. O que esse sintoma indica?
Gabarito: B. Trocar especificidade por "padrões típicos" é o sinal clássico de degradação de contexto em sessões estendidas. A causaria corte abrupto do texto, não generalização. C causaria falhas de request, não mudança qualitativa nas respostas. D é irrelevante: o sintoma não tem relação com tool use.
3. Um coordenador agrega relatórios longos de 6 subagentes de pesquisa e nota que achados dos relatórios do meio são omitidos na síntese. Quais duas medidas mitigam diretamente esse efeito? (escolha duas)
Gabarito: A e D. São as duas mitigações canônicas do lost in the middle: resumo no início (posição confiável) e headers explícitos que ancoram as seções intermediárias. B não afeta atenção posicional — muda aleatoriedade da amostragem. C é instrução sem mecanismo: o efeito é arquitetural, não de obediência. E destrói a capacidade de síntese cruzada entre fontes.
4. Um agente consulta uma API interna de pedidos que retorna 43 campos por pedido; a tarefa usa 5. Em sessões multi-turno o custo por chamada cresce rápido. Qual é a melhor prática?
Gabarito: D. Trim na origem impede que campos irrelevantes se acumulem e sejam reenviados a cada turno — tool results consomem tokens desproporcionalmente à relevância. A ignora o custo cumulativo real. B não economiza um token sequer: os campos continuam no contexto. C destrói a coerência conversacional — a API é stateless e depende do histórico.