O problema real com janelas de contexto grandes
Uma janela de contexto de 200 mil tokens parece mais do que suficiente — até que uma tarefa real começa a consumi-la. A AWS publicou um post técnico detalhando como o gerenciamento de contexto pode se tornar o principal gargalo de agentes de Inteligência Artificial (IA) em produção, especialmente em tarefas de análise de dados e geração de relatórios.
Para ilustrar o problema, o post descreve uma tarefa aparentemente simples: “Analise os dados de vendas e gere um relatório DOCX.” Esse fluxo passa por carregamento e exploração de dados (5 min), análise por categoria (3 min), geração de cinco gráficos para análise de séries temporais (10 min), validação estatística (3 min) e geração do relatório final (5 min) — consumindo mais de 150 mil tokens em 15 minutos. Processar tudo isso em um único contexto causa estouro da janela, degradação de precisão e custos elevados sob precificação por token.
A Anthropic descreve esse fenômeno como context rot: à medida que o número de tokens na janela cresce, a capacidade do modelo de recuperar informações com precisão diminui.
Este artigo é a Parte 2 de uma série. A Parte 1 abordou os cinco desafios de produção em sistemas multi-agente e como o Deep Insight os resolveu. O projeto Deep Insight é uma solução open source de análise de dados multi-agente construída sobre o Strands Agents SDK e o Bedrock AgentCore, e serve como implementação de referência ao longo de todo o post.
O que é engenharia de contexto?
Engenharia de contexto é a disciplina de otimizar as informações dentro da janela de contexto limitada de um Modelo de Linguagem Grande (LLM — Large Language Model) para que os agentes operem com máxima eficiência. Não se trata de uma técnica isolada, mas de uma abordagem em camadas onde cada nível compensa as limitações do anterior — abrangendo design de arquitetura, escrita de prompts, implementação de ferramentas e verificação.
O post organiza as práticas recomendadas pela Anthropic e os recursos nativos do Strands Agents SDK em quatro camadas:
- Camada 1 — Arquitetura: Isolamento de contexto via arquitetura multi-agente
- Camada 2 — Prompts: Controle de saída e regras comportamentais
- Camada 3 — Ferramentas: Externalização de contexto para o sistema de arquivos
- Camada 4 — Verificação: Agentes independentes e salvaguardas
Camada 1: Isolamento de contexto via arquitetura multi-agente
A primeira camada consiste em dar a cada agente especializado sua própria janela de contexto e passar apenas resultados comprimidos para o orquestrador. O Deep Insight implementa isso com uma hierarquia de agentes: Coordinator, Planner, Plan Reviewer, Supervisor e Tool Agents (Coder, Validator, Reporter, Tracker, Auditor).
Com um único agente, todas as informações — desde a requisição do usuário até exploração de dados, análise, geração de gráficos, validação e relatório — se acumulam em um único contexto e facilmente excedem a janela. Com o isolamento, mesmo o agente Coder, que é o mais exigente, fica abaixo de 25 mil tokens no total.
A chave do isolamento está em minimizar as informações compartilhadas. O Deep Insight usa um dicionário Python chamado shared_state que armazena apenas quatro elementos: a última mensagem do agente anterior, resumos comprimidos de cada agente (clues), um checklist do plano e um breve histórico de nomes e mensagens.
# coder_agent_tool.py -- context passing format
CLUES_FORMAT = "Here is clues from {}:\n\n\n{}\n \n\n"
RESPONSE_FORMAT = "Response from {}:\n\n\n{}\n \n\n*Please execute the next step.*"
# After Coder completes: add only compressed result to clues
clues += CLUES_FORMAT.format("coder", response["text"])
Esse padrão é o mesmo recomendado no post da Anthropic How We Built Our Multi-Agent Research System, que descreve um padrão orquestrador-trabalhador onde um agente líder delega para subagentes especializados, cada um operando apenas dentro do seu próprio contexto. O padrão agents-as-tools do Strands Agents SDK fornece esse isolamento diretamente no nível do framework.
Camada 2: Controle de contexto via prompts
O isolamento da Camada 1 não é suficiente sozinho: mesmo com contextos independentes, um agente que gera respostas longas infla o contexto do Supervisor. A Camada 2 limita a saída de cada agente por meio dos prompts.
Como recomenda a Anthropic em seu post Effective Context Engineering for AI Agents: “Comece com o modelo mais forte e um prompt simples. Depois, adicione instruções específicas de forma incremental, com base em falhas realmente observadas.”
Orçamentos de tokens por agente
O prompt de cada agente especifica um número máximo de tokens na resposta. O agente Coder, por exemplo, tem orçamento de 1.000 a 1.500 tokens — porque o código de análise é salvo em arquivos, e o agente retorna apenas um resumo do estado, tarefas concluídas e insights. O Validator tem orçamento de 800 tokens, e o Reporter, de 1.000 tokens.
Todos os agentes do Deep Insight compartilham um formato padronizado de resposta com seções de Status, Tarefas Concluídas, Insights Principais e Arquivos Gerados.
Filosofia de código autocontido
O prompt do agente Coder estabelece explicitamente que “variáveis não persistem entre scripts”. Cada script deve incluir todos os imports necessários e carregar os dados diretamente. O prompt fornece exemplos do que é incorreto e correto:
# WRONG -- Attempting to use a variable from Turn 1 in Turn 2
# Turn 1: df = pd.read_csv('data.csv')
total = df['Amount'].sum()
# Turn 2: print(f"Total: {total}") # NameError: name 'total' is not defined
# CORRECT -- Every script is self-contained
import pandas as pd
df = pd.read_csv('./artifacts/cache/df_main.csv') # Load from cache
total = df['Amount'].sum()
print(f"Total: {total}")
A razão pela qual essa regra se relaciona com engenharia de contexto: referenciar variáveis de scripts anteriores exige que o agente “lembre” conversas passadas, mantendo código antigo no contexto. O princípio autocontido permite que o código passado seja removido com segurança.
Camada 3: “Apenas ponteiros no contexto, dados reais nos arquivos”
Mesmo com isolamento e controle por prompts, quando o agente Coder gera 100 linhas de Python, esse código entra no contexto. A Camada 3 usa o design das ferramentas para mover conteúdo pesado para fora do contexto, no sistema de arquivos.
Ferramenta Write and Execute: código fora do contexto
A abordagem convencional — ferramentas separadas para escrever e executar arquivos — adiciona 100 linhas diretamente ao contexto por script. A solução é colapsar os dois passos em uma única ferramenta, para que o código nunca entre no contexto como mensagem.
# write_and_execute_tool.py
def _handle_write_and_execute_tool(file_path, content, timeout=300):
"""Write a Python script and immediately execute it."""
# Step 1: Write file
with open(file_path, 'w', encoding='utf-8') as f:
f.write(content)
# Step 2: Execute immediately
result = subprocess.run(
f"python {file_path}",
shell=True,
capture_output=True,
timeout=timeout
)
# Return only summary
return f"Written {len(content.split(chr(10)))} lines to {file_path}\n" \
f"Execution successful\n" \
f"Output: {result.stdout[:500]}" # Only first 500 chars
O código fica no arquivo e apenas cerca de três linhas de resumo permanecem no contexto — uma economia de aproximadamente 95% dos tokens por script.
Módulos reutilizáveis para lógica comum
Módulos comuns são reutilizados entre análises. Em vez de regenerá-los a cada vez, o Deep Insight gera um módulo chamado coder_analysis_utils.py antes da primeira tarefa, com funções para converter tipos numpy, rastrear metadados de cálculo e salvar em JSON. Análises subsequentes o importam, substituindo 20 a 30 linhas regeneradas por duas linhas de import.
Anotações estruturadas como barramento de comunicação
O Deep Insight usa um arquivo all_results.txt para compartilhar resultados detalhados de análise sem passá-los pelo contexto de cada agente. O Coder registra resultados detalhados nesse arquivo após cada tarefa; o Reporter o lê ao escrever o relatório final. Sem essa anotação, o Coder passaria resultados detalhados ao Supervisor após cada tarefa, acumulando no contexto. Com ela, apenas uma mensagem de ~30 tokens é passada.
O sistema de arquivos serve como barramento de comunicação entre agentes. Os principais arquivos trocados são:
all_results.txt: log cumulativo de resultados de análise (Coder → Reporter)calculation_metadata.json: registro de cálculos numéricos com fontes e fórmulas (Coder → Validator)citations.json: dados de citação verificados (Validator → Reporter)audit_findings.json: defeitos de citação encontrados no relatório final (Auditor → Reporter)coder_analysis_utils.py: funções utilitárias compartilhadas (Coder → todos os scripts)
Carregamento sob demanda de conhecimento com Skills
Em vez de colocar todo o conhecimento especializado no prompt do sistema, o Deep Insight carrega apenas o que é necessário no momento. Incluir todos os guias de habilidades no prompt adicionaria mais de 20 mil tokens desnecessários a cada chamada. A solução é carregar apenas um catálogo de habilidades de ~500 tokens na inicialização. Quando o usuário solicita “Crie um arquivo README”, o agente decide que precisa da habilidade readme-generator e a carrega sob demanda, obtendo um guia detalhado de ~3 mil tokens.
# 1. Skill Discovery (at initialization)
from src.utils.skills.skill_utils import initialize_skills
available_skills, skill_prompt = initialize_skills(
skill_dirs=["./skills"],
verbose=True
)
# 2. Add to System Prompt (~500-token catalog)
system_prompt = base_prompt + skill_prompt
# 3. Runtime -- Agent loads skill when needed
# Agent decides: "This is README generation, I need the readme-generator skill"
# -> skill_tool(skill_name="readme-generator")
# -> Returns full SKILL.md content (~3K tokens)
O resultado: ~500 tokens no startup em vez de mais de 20 mil tokens com todos os guias completos — uma redução de aproximadamente 97%.
Camada 4: Verificação com agentes independentes e salvaguardas
Mesmo com as três camadas anteriores, um risco persiste: agentes isolados não veem o trabalho uns dos outros. Se o Coder fizer um cálculo errado, o Reporter carrega esse erro para o relatório. A Camada 4 é a última linha de defesa.
Tracker, Validator e Auditor
O Tracker atualiza o checklist do plano em tempo real. Quando o Coder conclui o carregamento de dados, o Supervisor chama o Tracker, que atualiza o item do plano de [ ] para [x].
O Validator re-executa independentemente os cálculos do Coder para verificar a precisão. Ele lê o calculation_metadata.json, reperforma cada cálculo a partir dos dados de origem e compara: correspondências dentro de 0,01 são aprovadas; divergências são sinalizadas. Os cálculos verificados vão para citations.json para o Reporter citar.
Após o Reporter terminar, o Auditor verifica o DOCX final contra citations.json e calculation_metadata.json sem modificá-los. Ele registra defeitos de citação em audit_findings.json e pode solicitar até duas novas tentativas direcionadas ao Reporter.
Priorização de cálculos para verificação
Verificar todos os cálculos é ineficiente. O OptimizedValidator do Deep Insight aplica limiares: acima de 50 cálculos, filtragem agressiva (verifica todos de alta importância + apenas 10 de média); entre 20 e 50, filtragem moderada; 20 ou menos, verifica a maioria. A comparação é feita com segurança de tipos:
# validator.md -- type-safe numerical comparison
try:
match = abs(float(expected) - float(actual)) < 0.01
except:
match = str(expected) == str(actual)
SummarizingConversationManager: a rede de segurança final
O contexto ainda pode transbordar em casos excepcionais. O Deep Insight usa o SummarizingConversationManager do Strands Agents SDK como rede de segurança:
# strands_sdk_utils.py -- safety net configuration at agent creation
agent = Agent(
model=llm,
system_prompt=system_prompts,
tools=tools,
conversation_manager=SummarizingConversationManager(
summary_ratio=0.5, # summarize oldest 50% on overflow
preserve_recent_messages=10, # always preserve 10 most recent messages
summarization_system_prompt=apply_prompt_template("summarization", {})
)
)
No estouro, o LLM resume os 50% mais antigos das mensagens em uma única mensagem, sempre preservando as 10 mais recentes para manter o contexto da tarefa atual.
Cache seletivo de prompts para otimização de custos
A engenharia de contexto também cobre otimização de custos. O Deep Insight habilita cache de prompts por agente com base na frequência de chamadas repetidas com o mesmo prompt. Agentes como Supervisor, Coder, Reporter e Auditor têm cache habilitado (chamadas frequentes com prompts repetidos), enquanto Coordinator, Planner, Validator e Tracker não têm cache (chamadas únicas ou com dados diferentes a cada vez). Agentes com cache habilitado inserem pontos de cache em prompts e definições de ferramentas, reduzindo custos de tokens de entrada em até 90% em chamadas repetidas — um recurso nativo do Strands Agents SDK.
As quatro camadas como sistema de defesa em profundidade
Cada camada forma um sistema de defesa que compensa o que as anteriores deixam passar. Quando o isolamento por arquitetura é insuficiente, os prompts limitam a saída. Quando os prompts não bastam, as ferramentas mantêm o conteúdo externo. E quando problemas ainda surgem, a verificação os detecta.
Boa parte do que a Anthropic recomenda em seus posts de engenharia — Effective Context Engineering for AI Agents, Code Execution with MCP e How We Built Our Multi-Agent Research System — já está implementado nativamente no Strands Agents SDK: o SummarizingConversationManager, o cache de prompts e o padrão agents-as-tools.
O Deep Insight, implementação de referência usada ao longo do post, é open source. O código está disponível no GitHub e há um Workshop para quem quiser aprofundar a implementação.
Fonte
Four layers of context engineering for production AI agents: How Deep Insight applies them in working code (https://aws.amazon.com/blogs/machine-learning/four-layers-of-context-engineering-for-production-ai-agents-how-deep-insight-applies-them-in-working-code/)
Leave a Reply