RLM 2027 · Capítulo 3 de 24 · 13 min
Guardar o acervo numa variável e deixar o modelo programar a leitura
Três escolhas de desenho separam um RLM de um agente comum, e a primeira tira o prompt inteiro da janela do modelo raiz.
Este capítulo faz parte do curso gratuito RLM 2027. Para marcar como concluído e salvar o progresso, abra este capítulo na página do curso.
Com o limite da janela medido, falta decidir onde o acervo fica enquanto o modelo trabalha. Se ele não cabe na chamada e a leitura de uma vez perde o meio, o material precisa morar em outro lugar, acessível aos pedaços e sob controle de quem pergunta.
Errar esse lugar produz um sistema caro e cego ao mesmo tempo. Quem cola o acervo no histórico de um agente paga por cada token a cada turno e ainda assim bate no teto da janela. Quem esconde o acervo atrás de uma busca volta ao problema dos oito trechos, que custou à Veredas 31 erros de contexto.
O artigo de Zhang, Kraska e Khattab responde com uma decisão simples de enunciar: o prompt vira uma variável num REPL, e o modelo que coordena o trabalho nunca o lê inteiro. Ao terminar, o leitor sabe o que esse modelo recebe no primeiro turno, por que a saída de cada passo é cortada e quais três escolhas o artigo aponta como ausentes nos agentes comuns.
Por que tirar o prompt da janela muda o que o modelo consegue fazer
REPL é um terminal que executa uma linha de código por vez e guarda as variáveis entre uma linha e outra, como um caderno de rascunho que lembra as contas anteriores. O nome vem de read, eval, print e loop: ler, avaliar, imprimir e repetir. Quem já usou um notebook de Python conhece a sensação de definir uma lista numa célula e usá-la três células depois.
No RLM, o prompt do usuário entra nesse caderno como uma variável chamada context. O modelo que coordena, chamado modelo raiz, não recebe o texto. Recebe metadados de tamanho constante: o tipo da variável, o comprimento total em caracteres, o tamanho dos pedaços, um prefixo curto e a forma de acessar o conteúdo. Um acervo de mil páginas e outro de dez mil geram metadados do mesmo tamanho.
A partir daí, o modelo raiz trabalha como um analista com um terminal aberto. Escreve código num bloco marcado como repl, o ambiente executa, e o resultado fica guardado em variáveis. O código pode fatiar o texto, usar expressões regulares e chamar a função llm_query, que manda um pedaço a outro modelo. O prompt do artigo informa ao modelo que essa função aceita cerca de 500 mil caracteres.
Essa ideia nasceu de um incômodo prático. No post de outubro de 2025, Zhang descreve o modelo raiz que não vê o contexto e só sabe o tamanho dele. Por isso a primeira coisa que ele faz é espiar: no exemplo do OOLONG, lê os primeiros 2.000 caracteres para entender o formato. Só depois escreve o código que filtra, divide e delega. O autor chama os RLMs de generalização natural das estratégias de resumo.
Depois de cada execução, só um prefixo curto da saída e o tamanho dela voltam ao histórico do modelo raiz. A saída do REPL é truncada de propósito. Se o modelo imprime o acervo inteiro, recebe de volta as primeiras linhas e um aviso de tamanho. Esse corte força o trabalho a acontecer nas variáveis e nas subchamadas, e não na janela do modelo raiz.
- Etapa 1 de 7: Abrir o REPL
O prompt P vira a variável context, fora da janela
- Etapa 2 de 7: Registrar a subchamada
A função llm_query fica disponível para o código
- Etapa 3 de 7: Entregar metadados
O raiz começa só com tipo, tamanho e prefixo de P
- Etapa 4 de 7: Escrever código
O raiz responde com um bloco repl
- Etapa 5 de 7: Executar
O código roda, fatia P, chama subchamadas e guarda variáveis
- Etapa 6 de 7: Devolver só metadados da saída
Prefixo curto e tamanho entram no histórico
- Etapa 7 de 7: Parar
Quando FINAL ou FINAL_VAR define a resposta
O artigo contrasta esse desenho com um segundo algoritmo, marcado como falho, que descreve como muitos agentes funcionam. A comparação isola três escolhas. Handle simbólico: o prompt fica fora da janela, acessível por um nome; a falha número um é pôr o prompt no histórico. Handle é uma alça, uma referência que permite pegar o objeto sem carregá-lo.
A segunda escolha é a saída construída no REPL. A resposta pode ser montada numa variável, linha a linha, e devolvida no fim, o que permite respostas maiores que a janela do modelo. A falha correspondente é gerar a resposta direto no texto do modelo, limitada ao que ele consegue escrever num turno.
Por último vem a recursão simbólica. O código chama o modelo sobre pedaços do prompt construídos por programa, dentro de laços. Um laço sobre 6.400 documentos pode disparar milhares de subchamadas sem que o modelo raiz escreva milhares de mensagens. A falha número três é tratar a subchamada como uma ação verbal do agente, que ele precisa pedir uma de cada vez e não consegue pôr num laço.
As três escolhas de desenho que o artigo diz faltarem nos agentes comuns
Algoritmo 2, marcado como falho
Coluna a evitar
- O prompt inteiro entra no histórico do modelo
- A resposta final é o texto gerado num turno
- Subchamada é uma ação pedida uma vez por turno
- O tamanho útil do problema para na janela
Algoritmo 1, o RLM
Coluna recomendada
- O prompt fica numa variável, acessível por nome
- A resposta é montada numa variável e devolvida por FINAL_VAR
- Subchamada é uma função, chamável dentro de laços
- O histórico guarda código e metadados, e cresce devagar
Há um custo escondido nesse desenho, e os autores o registram. Se cada turno do modelo raiz for aparado a c tokens, o raiz faz no máximo K dividido por c iterações antes de encher a própria janela K. Cada iteração pode disparar quantas subchamadas quiser, e os autores afirmam que o limite não é fundamental. Na prática, ele explica por que as implementações cortam a saída de cada passo com rigor.
Cada implementação escolheu os próprios nomes e limites. A biblioteca oficial rlms segue o artigo na variável context e nas subchamadas, mas na versão 0.1.3 encerra pelo dicionário answer, e não por FINAL. O dspy.RLM entrega a resposta com SUBMIT e corta a saída do REPL em 10 mil caracteres por padrão. O desenho da Prime Intellect para o verifiers corta em 8.192 caracteres e dá 120 segundos a cada chamada ao REPL. Código escrito para uma implementação não roda em outra sem ajuste.
No DSPy há dois detalhes que mudam o comportamento na prática. Desde a versão 3.2.0, de abril de 2026, a prévia de cada variável mostrada ao modelo tem 1.000 caracteres. E o parâmetro interpreter_factory cria um intérprete novo a cada execução, de modo que nenhuma variável sobra de uma pergunta para a seguinte. A documentação marca o módulo como experimental e avisa que a interface pode mudar.
A Prime Intellect levou a mesma lógica a outra peça, as ferramentas. No desenho publicado em janeiro de 2026, busca na web e outras ferramentas extras ficam disponíveis só para os modelos das subchamadas. O modelo raiz não as recebe, para que as descrições e os resultados delas não inchem a janela de quem coordena. A regra é a mesma do prompt: o raiz decide, e quem lê material volumoso é outro modelo.
Os números que limitam o que volta ao modelo raiz
10.000
caracteres de saída do REPL por passo
Padrão de max_output_chars no dspy.RLM
1.000
caracteres de prévia por variável
DSPy desde a versão 3.2.0, de abril de 2026
8.192
caracteres de saída por turno
Desenho da Prime Intellect no verifiers, ajustável
~500 mil
caracteres por subchamada
Capacidade de llm_query informada ao modelo no prompt do artigo
Fonte: Documentação do dspy.RLM e notas de versão do DSPy; Prime Intellect, janeiro de 2026; Zhang, Kraska e Khattab, versão 3.
Onde cada implementação guarda o contexto e como limita a saída
| Implementação | Onde fica o contexto | Subchamada | Resposta final | Limite de saída |
|---|---|---|---|---|
| Artigo RLM (versão 3) | Variável context | llm_query | FINAL(...) ou FINAL_VAR(...) | Saída truncada |
| Biblioteca rlms 0.1.3 | Variável context | llm_query, llm_query_batched, rlm_query, rlm_query_batched | answer["content"] com answer["ready"] = True | Saída truncada |
| dspy.RLM | Campos da assinatura | llm_query, llm_query_batched | SUBMIT(...) | max_output_chars = 10.000 |
| Prime Intellect (verifiers) | Dados extras só pelo REPL | llm_batch() | answer["content"] com answer["ready"] = True | 8.192 caracteres; 120 s por chamada |
| Prime Agent | Histórico e variáveis num kernel IPython | await rlm(...) | Sessão | Parâmetros --autonomous-max-* |
Fonte: Zhang, Kraska e Khattab (versão 3); documentação do dspy.RLM; Prime Intellect, janeiro e agosto de 2026.
Armadilha comum: abrir o REPL e, no primeiro turno, mandar o modelo imprimir o contexto para “dar uma olhada”. É a falha número um por outra porta. A saída volta truncada, o modelo decide com base nas primeiras linhas e trata o resto como se fosse igual. O desenho pede o contrário: medir, espiar um pedaço pequeno e só então escrever o código que lê.
Rodar código escrito por um modelo exige onde rodá-lo. O README da biblioteca oficial avisa que o ambiente local, que executa no mesmo processo, não deve ser usado em produção. O DSPy usa por padrão um sandbox com Deno e Pyodide, e diz que a alternativa LocalInterpreter não é um sandbox de segurança. Sandbox é uma caixa de areia: um ambiente fechado onde o código não alcança arquivos, credenciais nem rede. A trilha de segurança volta a esse ponto com detalhe.
Como a Veredas pôs 52 milhões de tokens numa variável
Caio começou pelo formato. Em vez de um único texto gigante, montou context como uma lista de 6.400 textos, um por documento. Na primeira linha de cada um, acrescentou um cabeçalho padronizado com empreendimento, tipo de documento, data e código interno. Esse cabeçalho custou dois dias de limpeza e é o que permite ao modelo raiz filtrar sem ler.
Na conta que Caio usou, de 4 caracteres por token, os 52 milhões de tokens equivalem a cerca de 208 milhões de caracteres. Nenhuma subchamada lê isso, porque cada llm_query aceita cerca de 500 mil caracteres. O maior documento do acervo, um estudo de impacto ambiental de 1,9 milhão de caracteres, precisaria ser partido em quatro pedaços antes de ir a uma subchamada.
# Metadados que o modelo raiz recebe no primeiro turno (cenário da Veredas).
# Ele NÃO recebe o conteúdo de context, só esta descrição.
metadados = {
'tipo': 'list[str]',
'itens': 6400,
'caracteres_totais': 208_000_000,
'maior_item': 1_900_000,
'formato_do_item': 'EMPREENDIMENTO: ... | TIPO: ... | DATA: AAAA-MM-DD | COD: ...',
'prefixo': 'EMPREENDIMENTO: PCH Ribeirão Claro | TIPO: laudo de água | DATA: 2019-03-14 ...',
}
# Primeiro bloco repl que o modelo raiz escreveu: medir antes de ler.
import re
from collections import Counter
cabecalhos = [doc.split('\n', 1)[0] for doc in context]
por_tipo = Counter(re.search(r'TIPO: ([^|]+)', c).group(1).strip() for c in cabecalhos)
print(len(context), 'documentos')
print(por_tipo.most_common(12)) # a saída volta truncada ao históricoNo primeiro turno, o modelo raiz fez o que o desenho pede. Não leu nenhum documento: extraiu só os cabeçalhos, contou os tipos e descobriu que o acervo tinha 1.130 laudos de água, 212 documentos de condicionantes e 96 pareceres do órgão ambiental. A saída coube em algumas centenas de caracteres e voltou inteira. No segundo turno, filtrou os documentos de condicionantes e espiou os 2.000 primeiros caracteres de um deles.
Dessa espiada saiu um formato que Caio não tinha documentado. Os documentos de condicionantes da maioria dos empreendimentos traziam uma tabela com número, descrição, prazo e situação, mas os de quatro empreendimentos antigos listavam as condicionantes em texto corrido. O modelo raiz registrou isso numa variável e, no terceiro turno, escreveu dois filtros diferentes, um para cada formato.
O que fica no REPL e o que entra no histórico do modelo raiz
| Item | No REPL (variáveis) | No histórico do raiz |
|---|---|---|
| Acervo | 6.400 documentos, cerca de 208 milhões de caracteres | Metadados de cerca de 300 tokens |
| Contagem por tipo | Dicionário completo com todos os tipos | As 12 linhas impressas |
| Documentos de condicionantes | Lista com 212 textos inteiros | O tamanho da lista e 2.000 caracteres de um item |
| Código escrito | Executado e descartado | Os três blocos, cerca de 400 tokens cada |
| Total após três turnos | O acervo inteiro, intocado | Cerca de 9 mil tokens |
Cenário composto da Veredas. Histórico: 300 de metadados + 3 × 400 de código + 3 × 2.500 de saída (10 mil caracteres ÷ 4) = 9.000 tokens.
A conta da tabela mostra por que o desenho escala. Depois de três turnos, o modelo raiz carrega cerca de 9 mil tokens, contra 52 milhões no acervo. Ao preço de referência do GPT-5, o modelo raiz do artigo, US$ 1,25 por milhão de tokens de entrada, o terceiro turno custa pouco mais de um centavo de dólar. O dinheiro vai para as subchamadas, que leem de fato.
Caio também anotou o que o cabeçalho não resolvia. Dos 6.400 documentos, 140 não tinham data legível no arquivo original e ficaram com a data marcada como desconhecida. O filtro por data ignoraria esses 140 em silêncio. Ele deixou a regra explícita no cabeçalho, com o valor desconhecido escrito por extenso, para que qualquer código que filtrasse por data tivesse de decidir o que fazer com eles.
Helena fez a pergunta que todo gestor faz nesse ponto: se o modelo raiz nunca lê os documentos, como ela confia na resposta? Caio mostrou o rastro. Cada bloco de código, cada saída truncada e cada variável ficam registrados, e o filtro que separou os 212 documentos de condicionantes é uma expressão regular que ela pode ler e contestar. A confiança passa a depender de um rastro auditável, e não de uma impressão sobre o texto gerado.
Caio tomou uma precaução antes de rodar qualquer coisa. Os documentos trazem nomes de proprietários rurais e dados de clientes, e o código que lê esse material é escrito por um modelo. Por isso ele rodou o protótipo no sandbox padrão do DSPy, sem acesso à rede nem às credenciais da empresa. Tudo o que não era necessário para as perguntas de Helena ficou fora do acervo.
O acervo virou uma lista de 6.400 itens com cabeçalho, e o modelo raiz aprendeu a medir antes de ler, com cerca de 9 mil tokens de histórico. Desenhe agora, no papel, a árvore de chamadas que responderia à pergunta de Helena para um único empreendimento; o desenho está pronto quando cada folha couber em 500 mil caracteres.
Seu caderno neste capítulo
Abrir o caderno completoSelecione um trecho do capítulo para destacar ou anotar. No teclado, selecione com Shift e as setas e use Alt+Shift+D para destacar ou Alt+Shift+N para anotar.
Salvo neste navegador. Entre na sua conta para levar o caderno a outros aparelhos.
Entre na sua conta para compartilhar o que aprendeu e convidar alguém para estudar com você.
Voltar ao capítulo anterior: Medir o limite real do contexto e dividir o problema
Todos os capítulos de RLM 2027
- 01Descobrir onde o modelo encontra cada informação que usa
- 02Medir o limite real do contexto e dividir o problema
- 03Guardar o acervo numa variável e deixar o modelo programar a leitura
- 04Desenhar a árvore de chamadas e decidir a profundidade
- 05Explorar o acervo antes de decidir onde cortar
- 06Processar as partes e juntar as respostas sem perder a evidência
- 07Comparar contexto longo, RAG e compactação antes de escolher o RLM
- 08Situar agentes, híbridos e RLM numa matriz de decisão
- 09Julgar um benchmark antes de acreditar no número dele
- 10Comparar métodos nas mesmas condições e ler os resultados contrários
- 11Preparar o acervo e rodar a biblioteca oficial rlm
- 12Montar o protótipo com dspy.RLM e auditar o rastro de cada resposta
- 13Decompor o custo de uma execução e pôr teto em cada parte
- 14Baixar o custo por pergunta e vigiar o que a média esconde
- 15Isolar o código gerado e tratar cada documento como dado
- 16Impedir que o erro de uma folha chegue à resposta final
- 17Treinar um modelo pequeno para decidir quando delegar
- 18Provar uma auto-melhoria antes de acreditar nela
- 19Julgar as apostas de recursão aprendida e execução previsível
- 20Mapear híbridos, imagem e trabalho prolongado com evidência e lacuna
- 21Ler 2027 por sinais observáveis em vez de apostar numa previsão
- 22Escolher onde o RLM entra primeiro e decidir o piloto
- 23Definir o problema e construir quatro alternativas comparáveis
- 24Avaliar as alternativas e dizer em quais condições o RLM compensa