Context Engineering: porque o seu agent fica mais burro no turno 40
Mover um facto três linhas abaixo num prompt com 2,6 % da janela faz a recuperação cair de 84 % para 19 %. A janela nunca foi o problema.
Nesta página
Aqui está um prompt enviado 288 vezes ao mesmo modelo com descodificação greedy. Tem 853 tokens. Contém um registo de vinte e cinco tickets de suporte — cidade, fila, prioridade, responsável, extensão — e uma pergunta: Marta Ferreira precisa de uma chamada de retorno sobre o seu ticket. Qual é a extensão direta desse ticket?
O registo é idêntico todas as vezes. O modelo é idêntico todas as vezes. A única coisa que muda é qual das vinte e cinco linhas contém a resposta.
| posição da resposta | acertos | taxa de recuperação | intervalo de 95 % |
|---|---|---|---|
| 1 de 25 | 27/32 | 84 % | 68–93 % |
| 4 de 25 | 6/32 | 19 % | 9–35 % |
| 7 de 25 | 6/32 | 19 % | 9–35 % |
| 10 de 25 | 9/32 | 28 % | 16–45 % |
| 13 de 25 | 8/32 | 25 % | 13–42 % |
| 16 de 25 | 6/32 | 19 % | 9–35 % |
| 19 de 25 | 6/32 | 19 % | 9–35 % |
| 22 de 25 | 3/32 | 9 % | 3–24 % |
| 25 de 25 | 7/32 | 22 % | 11–39 % |
Trinta e dois ensaios por linha, um ticket diferente em cada ensaio, intervalos de Wilson de Capítulo 4, porque dezassete em vinte não distingue nada de nada.
A posição um é respondida 84 % das vezes. Todas as outras posições ficam entre 9 % e 28 % e os oito intervalos sobrepõem-se, por isso a leitura honesta é primeiro, e depois todo o resto. Liu et al. encontraram um U — alto nas duas extremidades, baixo no meio — e o braço de recência não aparece aqui com clareza: 22 % na última posição está dentro da dispersão das posições intermédias. O que não está dentro de nada é a queda da posição 1 para a posição 4. Três linhas.
A context window deste modelo é de 32.768 tokens. O prompt usa 853 deles, 2,6 %. Nada transbordou, nada foi truncado, nenhum limite foi atingido, nenhum aviso apareceu. O modelo deixou de encontrar uma linha que lhe tinha sido dada, porque a linha desceu três posições numa lista de vinte e cinco.
O Capítulo 16 pôs preço à context window e terminou com o aviso de que ter um milhão de tokens não é usá-los, apontando para aqui. Aqui está.
Mostrar detalhes
O que este capítulo precisa dos anteriores.
- Capítulo 9 derivou self-attention e o seu custo . Cada token faz attention a todos os outros, por isso o número de relações par a par cresce com o quadrado do comprimento. Esse facto é usado abaixo, não rederivado.
- Capítulo 16 contou os cinco baldes de tokens faturáveis e mostrou que a fatura de uma conversa cresce quadraticamente. Este capítulo é o que se faz quanto a isso sem partir o agent.
- Capítulo 18 construiu o catálogo de ferramentas e mediu que vinte ferramentas não prejudicaram a seleção, mas multiplicaram o prompt por seis. Aqui está a fatura delas.
- Capítulo 19 construiu a recuperação. A recuperação just-in-time abaixo é esse capítulo aplicado ao histórico do próprio agent; chunking não volta a ser explicado.
- Capítulo 23 construiu o harness. Tudo neste capítulo é uma política que corre dentro do seu ciclo, e é por isso que está em TypeScript: o artefacto é um serviço duradouro que mantém estado, não um notebook que mantém tensores.
Dois trabalhos com nomes parecidos
Ligação para a secção: Dois trabalhos com nomes parecidosA Anthropic traçou a linha em setembro de 2025 e as duas frases pertencem lado a lado. Prompt engineering é «métodos para escrever e organizar instruções de LLM para resultados ideais». Context engineering é «o conjunto de estratégias para curar e manter o conjunto ideal de tokens (informação) durante a inferência de LLM, incluindo toda a outra informação que possa lá aterrar fora dos prompts».1
A diferença operacional é quando, e por quem. Um prompt é escrito uma vez, por uma pessoa, e revisto. Um contexto é montado em cada chamada, por código que ninguém está a olhar, a partir de material que ninguém escreveu à mão: quarenta turnos de histórico, seis resultados de ferramentas, quatro passagens recuperadas, um perfil de utilizador, doze esquemas JSON. O Capítulo 15 mediu o que instruções melhores compram. Este capítulo é sobre os outros noventa por cento dos tokens, que chegam sozinhos.
O mesmo documento nomeia o recurso que todos eles gastam: os modelos «têm um “attention budget” ao qual recorrem ao analisar grandes volumes de contexto. Cada novo token introduzido esgota este orçamento em alguma medida». E nomeia o sintoma: «à medida que o número de tokens na context window aumenta, a capacidade do modelo de recordar informação desse contexto com precisão diminui» — context rot.1
Essa última frase é uma afirmação sobre comportamento, o que significa que pode ser verificada, e a tabela no topo desta página é a verificação.
Como essa tabela foi feita
Ligação para a secção: Como essa tabela foi feitaQuarenta linhas contra o endpoint local do Capítulo 22 — um pequeno servidor Python com Qwen2.5-0.5B-Instruct no CPU e a falar no formato chat-completions, para o ciclo ficar em TypeScript e os tensores ficarem do outro lado da porta.
const DEPTHS = [0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1];
for (const d of DEPTHS) {
const slot = Math.round(d * (N - 1));
let hits = 0, other = 0;
for (let t = 0; t < TRIALS; t++) {
const recs = buildRecords(N, 1000 + t); // 25 unique tickets
const gold = recs[Math.floor(rng(7 + t)() * N)]; // a different one each trial
const rest = recs.filter((x) => x.ticket !== gold.ticket).slice(0, N - 1);
const lines = [...rest.slice(0, slot).map((x) => x.line),
gold.line,
...rest.slice(slot).map((x) => x.line)];
const r = await complete(prompt(lines, ask(gold.owner)), { maxTokens: 12 });
const said = /\d{4}/.exec(r.text)?.[0];
if (said === String(gold.ext)) hits++;
else if (said && recs.some((x) => String(x.ext) === said)) other++;
}
}O contador other é o que transforma um resultado dececionante num resultado útil: quando o modelo erra, está perdido ou está confiante?
A resposta é: confiante. Nas oito posições que não são a primeira, 136 das 205 respostas erradas eram a extensão de outro ticket — um número real de quatro dígitos, formatado corretamente, lido da linha errada. Na posição 1, apenas uma das cinco falhas foi assim; na posição 7, vinte e uma de vinte e seis foram.
Essa distinção é o que importa em produção. Um modelo que diz não consigo encontrar é um bug que se nota; um modelo que devolve o número de uma linha vizinha é um bug que se envia, porque no ecrã os dois parecem idênticos. É a falha contra a qual o Capítulo 19 construiu citações verificáveis, chegada de dentro do prompt em vez de vir do índice.
Não é só onde. É quanto.
Ligação para a secção: Não é só onde. É quanto.A posição é um eixo. O comprimento é o outro, e mais fácil de testar: mantenha a resposta no meio e aumente a lista.
| registos | tokens do prompt | acertos | taxa | intervalo de 95 % | linha errada | nenhum |
|---|---|---|---|---|---|---|
| 1 | 97 | 18/20 | 90 % | 70–97 % | 0 | 2 |
| 3 | 159 | 11/20 | 55 % | 34–74 % | 9 | 0 |
| 8 | 315 | 3/20 | 15 % | 5–36 % | 17 | 0 |
| 20 | 695 | 2/20 | 10 % | 3–30 % | 16 | 2 |
| 40 | 1.324 | 3/20 | 15 % | 5–36 % | 15 | 2 |
| 80 | 2.587 | 1/20 | 5 % | 1–24 % | 18 | 1 |
| 140 | 4.477 | 2/20 | 10 % | 3–30 % | 18 | 0 |
Um registo e 97 tokens: 90 %. Três registos e 159 tokens: 55 %. Oito registos e 315 tokens: 15 %, e a partir daí baixo e plano até 140 registos e 4.477 tokens. Toda a derrocada acontece entre a primeira e a oitava linha de uma lista.
A última coluna é tudo o que não é nem a extensão certa nem a de outro registo, o que, com um único registo na página, é o único sítio onde uma resposta errada pode cair. As duas falhas com um registo merecem ser reportadas em vez de arredondadas para fora, porque nenhuma foi uma recusa: uma respondeu 5806 a um registo cuja única linha diz 5805. Com 97 tokens e um único candidato, este modelo ainda copia mal um dígito duas vezes em vinte, e esse é o piso contra o qual tudo o resto é medido.
Daqui decorrem duas coisas. Uma context maior compra o direito de enviar mais, não a certeza de ser lido: este modelo tem uma janela de 32.768 tokens e um intervalo funcional, nesta tarefa, de algumas centenas de tokens. E não há limiar, precipício, nem estado de «contexto cheio» — a degradação já está em curso no terceiro registo e completa no oitavo, a um por cento da janela. Seja o que for um limite de contexto, não é isso que governa isto.
Costumam ser propostos dois mecanismos. O primeiro é a aritmética do Capítulo 9, que a Anthropic formula nos mesmos termos deste curso: os modelos «baseiam-se na arquitetura transformer, que permite a cada token fazer attention a todos os outros tokens em todo o contexto. Isto resulta em n² relações par a par para n tokens».1 Attention sobre uma sequência mais longa não é a mesma operação aplicada a mais material; é um orçamento fixo de massa de probabilidade espalhado por mais concorrentes. O segundo é o treino: os modelos veem muito mais sequências curtas do que longas, por isso os padrões posicionais de longo alcance são a parte menos praticada da rede. Isso é um argumento, não uma medição, e este capítulo não o pode resolver.
O que está resolvido é a forma, e está-o desde 2023. Liu et al. testaram resposta a perguntas multi-documento e recuperação key-value em famílias e tamanhos de modelos e descobriram que «o desempenho é muitas vezes mais alto quando a informação relevante ocorre no início ou no fim do contexto de entrada, e degrada-se significativamente quando os modelos têm de aceder a informação relevante no meio de contextos longos, mesmo em modelos explicitamente de contexto longo».2 O Capítulo 15 retirou desse artigo a sua regra de posição; o Capítulo 19 retirou dele a razão pela qual vinte chunks recuperados podem pontuar pior do que quatro. A forma prática do facto é a única frase aqui sobre a qual deve agir: isto demora cinco minutos a medir no seu próprio modelo com os seus próprios dados, e nenhuma curva publicada substitui a sua.
Ninguém sabe o que está na sua janela
Ligação para a secção: Ninguém sabe o que está na sua janelaPergunte a uma equipa o que preenche o contexto do seu agent e recebe uma estimativa, porque nenhuma API devolve a resposta: a resposta dá-lhe prompt_tokens, um número para tudo.
Pode recuperar a decomposição com quatro contagens e três subtrações — o prompt renderizado inteiro, o mesmo sem definições de ferramentas, só a mensagem de sistema com e sem elas, e tudo com os resultados de ferramentas removidos:
async function buckets(messages: Msg[]) {
const sys = messages.slice(0, 1);
const withoutResults = messages.filter((m) => m.role !== "tool");
const [total, sysWithTools, sysNoTools, noResults] = await Promise.all([
countPrompt(messages, CATALOGUE), // everything
countPrompt(sys, CATALOGUE), // system + scaffolding + schemas
countPrompt(sys), // system + scaffolding
countPrompt(withoutResults, CATALOGUE), // everything but tool output
]);
return {
system: sysNoTools,
tools: sysWithTools - sysNoTools,
toolResults: total - noResults,
conversation: total - sysWithTools - (total - noResults),
total,
};
}countPrompt aplica o template de chat do próprio modelo antes de tokenizar, o que importa mais do que parece: o seu texto não é o que é contado. Marcadores de função, o preâmbulo de tool-calling e a renderização do esquema são todos tokens que paga e que nunca escreveu. O Capítulo 7 construiu um tokenizer e o Capítulo 16 contou com js-tiktoken; aqui a contagem vem do mesmo modelo que vai ler o prompt, que é a única contagem exatamente certa.
Agora corra um agent real através disto: quarenta turnos de uma investigação de incidente, doze ferramentas, um ambiente operacional falso a devolver dumps de logs e séries de métricas realistas.
| turno | sistema | definições de ferramentas | conversa | resultados de ferramentas | prompt total | input faturado neste turno |
|---|---|---|---|---|---|---|
| 1 | 85 | 1.817 | 155 | 490 | 2.547 | 4.370 |
| 2 | 85 | 1.817 | 282 | 529 | 2.713 | 5.275 |
| 5 | 85 | 1.817 | 647 | 1.870 | 4.419 | 8.093 |
| 10 | 85 | 1.817 | 946 | 2.141 | 4.989 | 4.951 |
| 20 | 85 | 1.817 | 1.500 | 2.943 | 6.345 | 6.316 |
| 30 | 85 | 1.817 | 2.187 | 4.000 | 8.089 | 8.059 |
| 40 | 85 | 1.817 | 3.053 | 5.677 | 10.632 | 21.090 |
Leia a primeira linha contra a última.
No turno 1, o prompt tem 2.547 tokens e 71 % dele são definições de ferramentas. O system prompt é 3 %. O que o utilizador escreveu é 6 %. O agent ainda não fez nada e já carrega 1.817 tokens de esquema JSON.
No turno 40, o prompt tem 10.632 tokens e as proporções inverteram-se: definições 17 %, conversa 29 %, resultados de ferramentas 53 %. A saída de ferramentas ultrapassou as definições no turno 5; a conversa só as ultrapassou no turno 25, por isso, durante os primeiros sessenta por cento da sessão, o catálogo de ferramentas era maior do que tudo o que tinha sido dito.
Depois, o total. Em 57 chamadas ao modelo, a execução faturou 370.291 tokens de input para um contexto final de 10.632 — o último prompt foi pago cerca de trinta e cinco vezes, que é o quadrático do Capítulo 16 com o multiplicador de um agent por cima. Desses 370.291, 103.569, ou 28 % de tudo o que foi faturado, eram as doze definições de ferramentas, reenviadas byte a byte idênticas em cada chamada.
Quanto custa uma definição de ferramenta
Ligação para a secção: Quanto custa uma definição de ferramentaO catálogo de ferramentas é o maior custo fixo de um agent e é invisível, porque nunca o vê: passa um array de objetos e o provider renderiza-o no prompt por si. Medido, nas mesmas doze ferramentas:
system prompt + chat scaffolding, no tools: 85 tokens
all twelve definitions: 1,817 tokens
of which fixed tool-calling scaffolding: 126 tokens
three tools instead of twelve: 605 tokens
same twelve, one-sentence descriptions,
no parameter prose: 1,291 tokens (-29 %)Por ferramenta, o custo marginal vai de 80 tokens para get_current_time, que aceita uma string, a 263 para search_tickets, que aceita quatro parâmetros com um enum e uma frase de orientação cada. Essa é a taxa de câmbio por trás do conselho central do Capítulo 18 de que a descrição é a API: uma boa descrição custa cerca de cem tokens em cada pedido durante o resto da vida do agent. Três consequências.
Uma ferramenta que não usa continua a faturar. O agent chamou sete das doze. As outras cinco custaram 697 tokens em cada um dos 57 pedidos — 39.729 no total, mais de um décimo de tudo o que a execução faturou, por capacidades em que nunca tocou. Uma das cinco carrega o detalhe mais afiado do trace: o modelo tentou três vezes chamar read_log, que não existe. A ferramenta que queria era search_logs, a segunda definição mais cara do catálogo, com 237 tokens. Pagou por essa definição 57 vezes, nunca a usou e nunca encontrou o nome dela.
Cortar prosa é a otimização mais barata disponível, e é uma troca. Reduzir descrições a uma frase e remover documentação de parâmetros poupou 526 tokens por chamada, 29 por cento, sem tocar numa linha de lógica — e fez o modelo chamar pior as ferramentas, que foi o que o Capítulo 18 mediu. O ponto é que os dois lados dessa troca estão agora na mesma unidade.
A certa escala, enviar definições deixa de fazer sentido. A Anthropic pôs-lhe um número em novembro de 2025: um grande conjunto de servidores ligados significa processar «centenas de milhares de tokens» de definições antes de o pedido ser lido, e substituir isso por execução de código — o agent descobre e carrega apenas as definições de que precisa — «reduz o uso de tokens de 150.000 tokens para 2.000 tokens, uma poupança de tempo e custo de 98,7%».3 A mesma ideia do resto deste capítulo, aplicada a esquemas em vez de histórico: mantenha o índice, resolva a entrada a pedido.
Parti-lo de propósito
Ligação para a secção: Parti-lo de propósitoForam plantadas duas coisas nessa transcrição de quarenta turnos. No turno 2, antes de qualquer trabalho real, o utilizador declara uma regra permanente: qualquer ticket que abras deve ser registado sob o meu número de funcionário, 4417. No turno 19, no meio do incidente, um facto: o shard afetado é pay-shard-7, confirmado pela equipa de pagamentos. No turno 40, o utilizador pede ao agent para abrir o ticket de incidente, o que precisa de ambos. Cada sonda é feita em seis formulações diferentes e pontuada em seis — a descodificação greedy é determinística, por isso uma chamada dá um sim ou não irrepetível e seis dão uma taxa.
A transcrição é então reproduzida sob sete políticas de contexto. Reproduzida em vez de reexecutada, deliberadamente: as mensagens, as chamadas de ferramentas e os resultados de ferramentas são byte a byte idênticos nas sete, por isso a única variável é o que cada política decidiu manter. O Capítulo 16 mostrou por que motivo uma janela deslizante é uma má jogada económica, porque destrói o prefixo cacheável. Aqui está o que faz ao comportamento:
| política de contexto | tokens de input ao longo dos 40 turnos | prompt do turno 40 | regra do turno 2 | facto do turno 19 |
|---|---|---|---|---|
| histórico completo | 370.291 | 10.632 | 6/6 | 5/6 |
| janela deslizante, últimas 12 mensagens | 157.578 | 2.922 | 5/6 | 0/6 |
| omitir resultados de ferramentas com mais de 4 turnos | 243.445 | 6.311 | 6/6 | 3/6 |
| compactação a cada 6 turnos | 195.515 | 3.220 | 6/6 | 0/6 |
| compactação mais notas escritas pelo modelo | 200.849 | 3.286 | 6/6 | 0/6 |
| fixar os turnos do próprio utilizador, à frente | 168.550 | 3.559 | 6/6 | 5/6 |
| fixar os turnos do próprio utilizador, atrás | 168.835 | 3.564 | 6/6 | 6/6 |
| controlo: os dois turnos e nada mais | — | 1.981 | 6/6 | 6/6 |
As linhas de compactação incluem o que compactar custou: 18.581 tokens de input para sete resumos e mais 3.392 para o tomador de notas. A linha de controlo está ali para que um zero possa ser lido como zero — com as duas mensagens sozinhas num prompt de 1.981 tokens, este modelo responde perfeitamente às duas sondas, por isso nenhuma linha é a tarefa ser demasiado difícil.
O histórico completo lembra-se, e é a coisa mais cara na tabela: 370.291 tokens de input para uma sessão cujo conteúdo durável são duas frases.
Isso responde a uma pergunta que a abertura deixou em aberto. Porque é que uma transcrição de 10.632 tokens guarda um facto que um registo de 853 tokens perde? Porque o comprimento é a variável errada. O registo contém vinte e cinco extensões de quatro dígitos em vinte e cinco frases idênticas — vinte e quatro iscos quase perfeitos para a que quer. A transcrição contém exatamente um número de funcionário e um nome de shard. Context rot é interferência antes de ser volume, e é por isso que 136 das 205 respostas erradas lá em cima eram o valor de um vizinho. A pergunta útil sobre uma janela não é quão longa é; é quantas coisas nela se parecem com a resposta.
A janela deslizante é 57 % mais barata e perdeu o incidente. O número de funcionário sobrevive apenas porque o agent o tinha repetido nos turnos recentes. O shard, declarado uma vez no turno 19, não está nas últimas doze mensagens — e o modelo não o diz. Perguntado seis vezes, respondeu «the affected payment shard is shard 4417», esticando-se para o número de funcionário, o único outro identificador que restava na sua janela, e duas vezes «pool», retirado da string pool_exhausted numa linha de log.
A compactação é barata e perdeu o mesmo facto. Sete resumos, escritos pelo modelo sob uma instrução explícita para manter identificadores, números, instruções permanentes e perguntas em aberto, e pay-shard-7 não aparece em nenhum dos que importavam; as seis suposições foram shard 1, pay_shard_1 e pool. A compactação não falha em voz alta. Produz uma sessão fluente, plausível e muito mais curta que deixou cair silenciosamente uma linha.
Três linhas pontuaram 0/6 no facto do turno 19 — a janela deslizante, a compactação e a compactação com notas. Dezoito respostas erradas entre elas, e nem uma delas foi «não sei».
Depois vem a linha que devia envergonhar. Manter as quarenta mensagens do próprio utilizador verbatim, mais os últimos quatro turnos na íntegra e nada mais, custa 168.550 tokens — 54 % menos do que o histórico completo — e responde às duas sondas tão bem como, ou melhor do que, o histórico completo. Sem sumarizador, sem tomador de notas, sem segundo modelo: um filtro em role === "user". As palavras do utilizador são os tokens de alto valor mais baratos na janela de um agent, e a maioria dos designs descarta-as juntamente com tudo o resto.
As duas últimas linhas são novamente a tabela de abertura, dentro do agent. O mesmo bloco fixado, movido da mensagem de sistema para o fim do prompt: 5/6 torna-se 6/6. Em seis ensaios, isto não é uma diferença significativa e não é apresentado como tal — é apresentado como lembrete de que onde é um parâmetro que está a definir, saiba-o ou não.
Quatro maneiras de gastar menos janela
Ligação para a secção: Quatro maneiras de gastar menos janelaAs quatro estratégias abaixo são da Anthropic, pela sua ordem, embora só as últimas três pertençam à sua lista de longo horizonte.1 Todas as quatro são variações de uma instrução: não carregue o que pode ir buscar, e não carregue em bruto o que pode carregar comprimido.
Recuperação just-in-time
Ligação para a secção: Recuperação just-in-timeNão pré-carregue conteúdo. Mantenha identificadores — um caminho de ficheiro, uma consulta, um número de ticket, um nome de ferramenta e os seus argumentos — e resolva-os quando necessário. O maior balde no agent acima é a saída de ferramentas que foi lida uma vez, usada uma vez e depois carregada por mais trinta turnos. Substituir todos os resultados com mais de quatro turnos por um stub que diz o que era e como recuperá-lo são seis linhas:
const elide: Policy = (h) => [SYSTEM, ...h.flatMap((turn, ti) =>
turn.map((m) => (ti < h.length - 4 && m.role === "tool"
? { role: "tool", name: m.name,
content: `[${m.name} result from turn ${ti + 1}, ${m.content.length} chars, ` +
`elided; call ${m.name} again with the same arguments to re-read it]` }
: m)))];Isto é o Capítulo 19 com o corpus substituído pelo passado do próprio agent. A maquinaria de recuperação já existe — é o catálogo de ferramentas.
Compactação
Ligação para a secção: CompactaçãoQuando a transcrição passa um limiar, substitua a parte mais antiga por um resumo escrito pelo modelo e continue. O prompt que escreve o resumo é todo o design, e é aí que a compactação se ganha ou se perde: mantenha identificadores, números, instruções permanentes e perguntas em aberto; descarte cortesias e saída de ferramentas que possa voltar a buscar.
A compactação é lossy por construção, o que perde é escolhido por um modelo em seu nome, e nada dá erro quando ele escolhe mal. Também não é gratuita: cada compactação é uma chamada extra cujo input é a coisa a compactar.
Tomada de notas estruturada
Ligação para a secção: Tomada de notas estruturadaMantenha um pequeno repositório fora do contexto e reinjete-o inteiro em cada turno. Ao contrário de um resumo, é append-only e endereçável: uma regra escrita no turno 2 continua lá verbatim no turno 400. A versão medida aqui pergunta ao modelo, depois de cada mensagem do utilizador, se ela contém algo durável:
const r = await complete([
{ role: "system", content:
"You keep a durable note file for a support session. Given one user message, " +
"output one short note ONLY if it states a standing rule, an identifier or a fact " +
"that must survive the rest of the session. Otherwise output exactly NONE." },
{ role: "user", content: `Turn ${i + 1}: ${user}` },
], { maxTokens: 40 });
if (!/^none\b/i.test(r.text.trim())) notes.push(`turn ${i + 1}: ${r.text.trim()}`);Esta é a estratégia com o teto mais alto aqui, e foi a que falhou na medição. Ao longo de quarenta mensagens de utilizador, o tomador de notas guardou três notas e nenhuma das duas que importavam: uma linha de conselho de runbook, um anúncio de que a sessão ia terminar, e Europe/Madrid is currently 13:45 — uma hora que inventou, uma vez que a ferramenta que estava a parafrasear devolveu 09:52 UTC. O tomador de notas é um modelo, e tudo neste capítulo também se aplica a ele.
Sub-agents
Ligação para a secção: Sub-agentsDê a uma tarefa focada a sua própria janela — o seu próprio system prompt, o seu próprio pequeno catálogo, nada do histórico do pai — e devolva uma resposta curta em vez de uma transcrição. O Capítulo 23 pôs um atrás de um esquema de ferramenta e deixou a fatura aqui; a fatura é que a resposta do filho é a única parte da janela do filho pela qual o pai alguma vez paga.
O sub-agent não está na tabela acima porque não corre durante quarenta turnos: corre uma vez, numa janela que alguém delimitou para ele. Dado o system prompt, os turnos 17 a 19 e nada mais — 2.737 tokens — respondeu à sonda do shard 6/6, melhor do que qualquer política na tabela, e à sonda do funcionário 0/6, porque esse número não está nos três turnos que lhe foram entregues.
Isso são sub-agents em dois números: uma janela limpa não é inteligência, é âmbito, e o âmbito é definido antecipadamente por código que já tem de saber que turnos importam. Vale a pena guardar mais uma coisa nessas respostas. Esta foi a única política que respondeu «None available» em vez de inventar algo. Um modelo com um contexto pequeno e coerente sabe o que lhe falta; um modelo com um contexto grande e ruidoso não sabe.
As três memórias
Ligação para a secção: As três memóriasQuase todas as conversas confusas sobre memória de agent são três mecanismos a vestir uma só palavra. Têm tempos de vida, donos e modos de falha diferentes, e um sistema que os mantém no mesmo sítio tem um problema de que ainda não se apercebeu.
| histórico da conversa | recuperação | memória persistente do utilizador | |
|---|---|---|---|
| contém | o que foi dito nesta sessão | documentos seus | factos sobre uma pessoa |
| vive | uma sessão | até ser reindexada | em todas as sessões, para sempre |
| escrita por | o ciclo, automaticamente | uma pipeline de ingestão | o modelo, de propósito |
| entra no prompt | na íntegra, em cada chamada | quatro passagens, quando uma consulta corresponde | na íntegra, em cada chamada |
| falha por | crescer até apodrecer | recuperar o chunk errado | lembrar-se de algo errado sobre si |
| construída em | Capítulo 23 | Capítulo 19 | este capítulo |
O enquadramento académico é o da CoALA, que organiza language agents em torno de «componentes de memória modulares» e separa memória de trabalho de stores episódicos, semânticos e procedimentais.4 MemGPT leva a mesma ideia literalmente, tomando emprestada a memória virtual dos sistemas operativos: uma camada rápida dentro da janela, uma camada lenta fora dela, e o próprio modelo a mover dados entre ambas com function calls.5 Ambos forçam a pergunta a que um produto tem de responder de qualquer forma — não quanto posso guardar, mas a que store pertence isto, e quando expira.
O teste prático é uma pergunta por facto: o que deve continuar a ser verdade amanhã? Um resultado de ferramenta do turno 12, nada. Um resumo da sessão, até a sessão terminar. Que o número de funcionário do utilizador é 4417, até ele mudar de emprego. Três respostas, três stores.
Para onde isto vai a seguir
Ligação para a secção: Para onde isto vai a seguirAgora pode medir o que está numa janela, decidir o que fica nela e distinguir entre um agent que se esqueceu de algo e um que o carregava mas não olhou.
A última das quatro estratégias é a que não cabe aqui. Um sub-agent não é uma política de contexto, é um segundo agent, e no momento em que há dois tem de decidir o que passa entre eles e quem manda. O Capítulo 25 é isso: os cinco padrões de orquestração e de onde vem realmente cada um dos seus nomes, as duas topologias que se confundem — pedir a um sub-agent e receber uma resposta de volta, contra entregar-lhe a conversa e não a receber de volta — e a descoberta medida de que, na tarefa a que põe preço, o arranjo mais simples ganha — seguida pelo teste para saber quando deixa de ganhar.
Também herda exatamente o que este capítulo acabou de medir. Um sub-agent devolve um resumo. Um resumo é uma compactação que não escreveu, produzida por um modelo cuja janela não consegue ver, e o pai não tem forma de distinguir um bom resumo de um errado confiante — a mesma distinção que separou 84 % de 19 % no topo desta página, e que transformou dezoito factos em falta em dezoito invenções. Portanto: quando o sub-agent está errado, o que é que o pai pode exatamente ver?
Fontes e método
Ligação para a secção: Fontes e métodoTodos os números aqui foram produzidos nesta máquina e nenhum foi estimado. O modelo é Qwen2.5-0.5B-Instruct em float32 no CPU com descodificação greedy, servido por loopback por um pequeno endpoint Python que fala no formato chat-completions e expõe uma rota de contagem de tokens — novamente a costura do Capítulo 14, tensores do lado Python e o ciclo do lado TypeScript — por isso cada contagem é o tokenizer do próprio modelo aplicado ao seu próprio template de chat. A tabela de posição são 288 chamadas, nove posições por trinta e dois ensaios com um ticket diferente em cada ensaio; a tabela de comprimento são 140 chamadas; a execução do agent são 57 chamadas ao modelo ao longo de 43 minutos de relógio; a tabela de políticas é essa transcrição reproduzida sob sete políticas. Os intervalos são de Wilson, do Capítulo 4. Nenhuma API paga foi chamada, e é também por isso que não há um único preço no capítulo: as contagens de tokens são exatas e as taxas pelas quais as multiplicaria são as do Capítulo 16.
Referências
Ligação para a secção: Referências-
Anthropic, Effective context engineering for AI agents, 29 de setembro de 2025,
anthropic.com/engineering/effective-context-engineering-for-ai-agents, lido a 7 de setembro de 2026. Fonte das duas definições citadas no topo, do «attention budget» e da afirmação de que cada novo token o esgota, da descrição de context rot, do enquadramento das relações par a par n², e das estratégias usadas como espinha dorsal deste capítulo. Três delas são a sua lista de longo horizonte — compactação, tomada de notas estruturada e arquiteturas multi-agent; a recuperação just-in-time surge antes no mesmo artigo, em context retrieval e agentic search, e é agrupada aqui com elas. ↩ ↩2 ↩3 ↩4 -
Liu, N. F., Lin, K., Hewitt, J., Paranjape, A., Bevilacqua, M., Petroni, F. e Liang, P. Lost in the Middle: How Language Models Use Long Contexts. arXiv:2307.03172 (v1 julho de 2023, v3 novembro de 2023). Citado nos Capítulos 15, 16 e 19 e medido aqui. A frase citada vem do resumo; as duas tarefas do artigo são resposta a perguntas multi-documento e recuperação key-value, e a sua descoberta de que o efeito persiste em modelos explicitamente de contexto longo é a parte que importa para uma decisão de produto. ↩
-
Anthropic, Code execution with MCP: building more efficient agents, 4 de novembro de 2025,
anthropic.com/engineering/code-execution-with-mcp, lido a 7 de setembro de 2026. Fonte da redução de 150.000 para 2.000 tokens e do valor de 98,7 %, e da observação de que definições de ferramentas carregadas à cabeça ocupam contexto antes de o pedido ser lido. ↩ -
Sumers, T. R., Yao, S., Narasimhan, K. e Griffiths, T. L. Cognitive Architectures for Language Agents. arXiv:2309.02427 (2023). Organiza language agents em torno de «componentes de memória modulares, um espaço de ação estruturado para interagir com memória interna e ambientes externos, e um processo generalizado de tomada de decisão para escolher ações», e divide a memória em trabalho, episódica, semântica e procedimental. O Capítulo 22 usou a sua taxonomia para o learning agent; a tabela de três stores acima é a sua sombra prática. ↩
-
Packer, C., Wooders, S., Lin, K., Fang, V., Patil, S. G., Stoica, I. e Gonzalez, J. E. MemGPT: Towards LLMs as Operating Systems. arXiv:2310.08560 (outubro de 2023). Propõe «virtual context management, uma técnica inspirada nos sistemas hierárquicos de memória dos sistemas operativos tradicionais», com o próprio modelo a mover dados entre uma camada rápida dentro da janela e uma camada lenta fora dela. A afirmação mais clara em qualquer lado de que a janela é uma cache e não uma memória. ↩