RLM 2027 · Capítulo 4 de 24 · 14 min
Desenhar a árvore de chamadas e decidir a profundidade
Profundidade 1 é o padrão do artigo por um motivo medido; saber quando subir e como devolver a resposta evita execuções longas e respostas cortadas.
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 acervo guardado numa variável, o modelo raiz precisa de quem leia os pedaços por ele. Cada leitura delegada é uma subchamada, e o conjunto delas forma uma árvore: o raiz no topo, as subchamadas embaixo e, às vezes, subchamadas das subchamadas.
O formato dessa árvore decide custo, tempo e acerto. Uma árvore rasa demais põe pedaços grandes demais em cada folha e repete o problema do contexto longo. Uma árvore funda demais multiplica chamadas e minutos, e cada nível acrescenta uma chance de erro. E uma resposta montada no lugar errado sai cortada ou sai como plano em vez de resultado.
Ao terminar, o leitor sabe quais funções delegam a leitura e em que diferem, o que a profundidade mede e o que os números do artigo dizem sobre subir de nível. Sabe também como cada implementação devolve a resposta final e por que esse detalhe falha com frequência. A Veredas desenha e roda a árvore de uma pergunta real sobre a PCH.
Subchamadas, as funções com que o modelo raiz delega a leitura
Subchamada é uma chamada a outro modelo feita de dentro do código do REPL, como um coordenador que entrega uma pasta a um assistente e espera o resumo. Na biblioteca oficial rlms existem quatro formas. llm_query manda um texto a um modelo comum e recebe a resposta. llm_query_batched faz o mesmo com uma lista de textos, em paralelo.
As outras duas sobem um degrau. rlm_query entrega o pedaço a um sub-RLM, que ganha o próprio REPL e pode delegar de novo. rlm_query_batched faz isso em paralelo. O paralelismo é limitado pelo parâmetro max_concurrent_subcalls. No DSPy, o dspy.RLM oferece llm_query e llm_query_batched, e o parâmetro sub_lm escolhe o modelo das subchamadas; a documentação recomenda um modelo mais barato.
A divisão de papéis entre modelos pesa no custo. Na configuração principal do artigo, o GPT-5 com raciocínio médio fica no topo e o GPT-5-mini faz as subchamadas. Pelos preços de referência de setembro de 2026, o GPT-5 cobra US$ 1,25 por milhão de tokens de entrada e o GPT-5-mini, US$ 0,25. Como quase toda a leitura acontece nas subchamadas, o modelo barato paga a maior parte da conta.
As funções de subchamada e o que cada uma entrega
| Função | Quem responde | Em paralelo? | Pode delegar de novo? |
|---|---|---|---|
| llm_query | Um modelo comum | Não | Não |
| llm_query_batched | Um modelo comum, uma chamada por item | Sim | Não |
| rlm_query | Um sub-RLM com REPL próprio | Não | Sim |
| rlm_query_batched | Vários sub-RLMs | Sim, até max_concurrent_subcalls | Sim |
Fonte: Repositório alexzhang13/rlm (biblioteca rlms 0.1.3) e documentação do dspy.RLM, setembro de 2026.
Quantas subchamadas uma execução faz depende muito do modelo raiz. No artigo, o GPT-5 fez da ordem de dez subchamadas por pergunta. O Qwen3-Coder-480B fez centenas a milhares num problema simples, e cerca de 500 em média nas trajetórias corretas do OOLONG. Os autores precisaram acrescentar uma linha ao prompt do Qwen3-Coder, porque sem ela o modelo disparava milhares de subchamadas para problemas básicos.
Nos experimentos do artigo, todas as chamadas eram bloqueantes e sequenciais: cada uma esperava a anterior terminar. O próprio blog de outubro de 2025 descreve consultas que levam de alguns segundos a vários minutos, sem garantia de custo total nem de tempo total. As versões em lote e o limite de concorrência da biblioteca existem para cortar esse tempo de espera.
O DSPy põe tetos padrão contra a execução sem fim. O parâmetro max_llm_calls limita a 50 as subchamadas por execução, e max_iters limita a 20 os turnos do REPL antes da extração de reserva. Quem encontrar código antigo com max_iterations deve saber que o nome mudou para max_iters no DSPy 3.3.0, de agosto de 2026. O código antigo precisa de ajuste para rodar nas versões atuais.
Quantos níveis descer e como devolver a resposta final
Profundidade é quantos níveis de RLM a árvore admite. Na profundidade 0 não há subchamada: o modelo raiz usa só o REPL, com código e expressões regulares. Na profundidade 1, as subchamadas são modelos comuns, e esse é o padrão do artigo. Acima de 1, as subchamadas são RLMs com REPL próprio. O artigo escreve a configuração como RLM(model, depth=N).
A intuição diz que mais níveis dão mais capacidade. A tabela principal da versão 3 do artigo, com GPT-5 no topo e GPT-5-mini nas subchamadas, desmente a intuição em parte. No OOLONG-Pairs, que exige cruzar pares de trechos, a profundidade 3 foi a melhor, com F1 de 76,0. No CodeQA, a profundidade 3 marcou 58,0, abaixo dos 66,0 da profundidade 2. F1 é uma nota que pesa ao mesmo tempo o que o sistema acertou e o que deixou de achar.
Profundidade não melhora de forma consistente (tabela 1 do artigo, versão 3)
| Configuração | CodeQA | BrowseComp+ (1K docs) | OOLONG | OOLONG-Pairs (F1) |
|---|---|---|---|---|
| GPT-5, modelo base | 24,0* | 0,0* | 44,0 | 0,1 |
| RLM(GPT-5), profundidade 0 | 58,0 | 88,0 | 36,0 | 43,9 |
| RLM(GPT-5), profundidade 1 | 62,0 | 91,3 | 56,0 | 58,0 |
| RLM(GPT-5), profundidade 2 | 66,0 | 92,0 | 56,5 | 65,5 |
| RLM(GPT-5), profundidade 3 | 58,0 | 92,0 | 58,0 | 76,0 |
| RLM(Qwen3-Coder), profundidades 1, 2 e 3 | 56,0 / 54,0 / 44,0 | 44,7 / 68,0 / 68,7 | 48,0 / 26,0 / 32,0 | 23,1 / 19,0 / 21,1 |
Acurácia em %, exceto OOLONG-Pairs (F1). * = bateu no limite de contexto. Subchamadas do RLM(GPT-5) feitas pelo GPT-5-mini.
Fonte: Zhang, Kraska e Khattab, “Recursive Language Models”, versão 3, tabela 1 (maio de 2026).
No Qwen3-Coder, subir de nível piorou o OOLONG: 48,0 na profundidade 1, 26,0 na 2 e 32,0 na 3. Os autores atribuem a queda a erros de sintaxe que se propagam para os sub-RLMs. No CodeQA com o mesmo modelo, a profundidade 0, sem nenhuma subchamada, marcou 66,0 e superou todas as variantes com subchamadas. O resultado vale para esses modelos e esses testes, e nada garante que se repita em outro acervo.
O custo também oscila com a profundidade. No OOLONG com GPT-5, a profundidade 2 custou em média US$ 1,10 por pergunta, com desvio-padrão de US$ 3,25. Desvio-padrão maior que a média quer dizer que a maioria das execuções saiu barata e algumas saíram muito caras. O artigo descreve essas trajetórias como de cauda longa e alta variância, e a trilha de custo volta a esse número.
Uma reprodução independente, publicada por Daren Wang em março de 2026, mediu o preço em tempo. Com DeepSeek v3.2 no teste S-NIAH e 20 amostras por condição, a resposta levou 3,6 segundos no modelo base, 89,3 na profundidade 1 e 344,5 na profundidade 2. O Kimi K2 chegou a 545,5 segundos por consulta na profundidade 2. Armadilha comum: tratar profundidade como botão de inteligência. Cada nível multiplica chamadas e minutos, e o ganho de acerto aparece em alguns testes e some em outros.
Resta devolver a resposta. No artigo, a execução termina quando o modelo define a resposta final: FINAL(texto) para uma resposta curta escrita direto, FINAL_VAR(nome) para devolver uma variável montada no REPL. A segunda forma permite saídas maiores que a janela do modelo, como uma tabela com todas as condicionantes de um acervo. O DSPy usa SUBMIT(...), e tanto a biblioteca rlms na versão 0.1.3 quanto o desenho da Prime Intellect encerram quando o modelo marca answer["ready"] como verdadeiro.
Como cada implementação encerra a execução e devolve a resposta
| Implementação | Encerramento | Quando usar | Falha conhecida |
|---|---|---|---|
| Artigo RLM | FINAL(texto) | Resposta curta, escrita pelo raiz | O raiz entrega o plano como se fosse a resposta |
| Artigo RLM | FINAL_VAR(nome) | Resposta longa, montada numa variável | Nome de variável errado ou variável ainda vazia |
| dspy.RLM | SUBMIT(...) com os campos da assinatura | Saída tipada pela assinatura | Execução para em max_iters e cai na extração de reserva |
| Biblioteca rlms 0.1.3 e Prime Intellect (verifiers) | answer["content"] e answer["ready"] = True | Uso da biblioteca, treino e avaliação em lote | Resposta pronta sem a marca de pronta |
Fonte: Zhang, Kraska e Khattab, versão 3; documentação do dspy.RLM; Prime Intellect, janeiro de 2026.
Os autores registram que distinguir resposta final de pensamento é frágil: às vezes o modelo entrega o plano de trabalho como se fosse o resultado. O dado de treino confirma o problema. Ao preparar o RLM-Qwen3-8B, 16 por cento dos turnos usavam FINAL de forma errada e 13 por cento usavam FINAL_VAR de forma errada, e os autores precisaram de uma correção programática para consertar o formato.
Para a Veredas, a escolha entre as duas formas tem efeito direto. Uma resposta à pergunta de negócio lista condicionantes, empreendimentos, prazos e o código de cada documento de evidência. Em 38 empreendimentos, essa tabela pode passar de dezenas de milhares de caracteres. Escrita pelo modelo raiz num turno, ela sairia resumida ou cortada. Montada numa variável e devolvida por FINAL_VAR, ela sai inteira, com cada linha rastreável.
Como a Veredas desenhou a árvore de uma pergunta sobre a PCH
Helena escolheu o menor empreendimento com histórico de problema: a PCH Ribeirão Claro, com 140 documentos e cerca de 1,1 milhão de tokens. A pergunta foi a de negócio, restrita a um lugar: “quais condicionantes de monitoramento hídrico da PCH estão vencidas ou com laudos contraditórios, e com que evidência?”. A resposta de referência dela tinha 11 condicionantes hídricas, 3 vencidas e 1 com laudos contraditórios.
Caio fixou profundidade 1, com um modelo raiz forte e um modelo barato nas subchamadas, e rodou. O modelo raiz usou quatro turnos. No primeiro, mediu o acervo pelos cabeçalhos. No segundo, filtrou os 140 documentos da PCH e, dentro deles, os que citavam condicionante e água, turbidez ou vazão: sobraram 23. No terceiro, mandou os 23 em lote a subchamadas, pedindo de cada um a condicionante, o prazo e a data do último laudo.
# Terceiro e quarto blocos repl do modelo raiz (cenário da Veredas, profundidade 1).
import json
from datetime import date
pedido = ('Extraia deste documento, em JSON, uma lista de objetos com: '
'condicionante, prazo (AAAA-MM-DD), data_ultimo_laudo, valor_medido, cod_documento. '
'Se o documento não trouxer um campo, use null. Documento:\n')
respostas = llm_query_batched([pedido + d for d in docs_hidricos_pch]) # 23 subchamadas
linhas = []
for r in respostas:
linhas.extend(json.loads(r))
hoje = date(2026, 9, 23)
vencidas = [l for l in linhas
if l['prazo'] and date.fromisoformat(l['prazo']) < hoje
and not l['data_ultimo_laudo']]
print(len(linhas), 'registros;', len(vencidas), 'vencidas')
# O cruzamento de laudos do mesmo ponto de coleta roda num trecho à parte, omitido aqui.
# A resposta é montada numa variável e devolvida inteira, com o código do documento.
tabela = {'vencidas': vencidas, 'todos_os_registros': linhas}
FINAL_VAR(tabela)- Etapa 1 de 5: Raiz, turno 1
Mede o acervo pelos cabeçalhos: 6.400 documentos
- Etapa 2 de 5: Raiz, turno 2
Filtra por código: 140 da PCH, 23 sobre condicionantes hídricas
- Etapa 3 de 5: Raiz, turno 3
Dispara as 23 leituras em lote por llm_query_batched
- Etapa 4 de 5: Profundidade 1
23 subchamadas, uma por documento, cada uma devolve JSON
- Etapa 5 de 5: Raiz, turno 4
Junta os JSON, compara prazos, cruza laudos e devolve por FINAL_VAR
No quarto turno, o raiz agrupou os registros por ponto de coleta e comparou os laudos de um mesmo trimestre. A execução devolveu 11 condicionantes, 3 vencidas e 1 contradição: dois laudos de turbidez do mesmo ponto, no mesmo trimestre de 2025, com valores incompatíveis. Cada linha trazia o código do documento de origem. Helena conferiu contra a referência e bateu nas três contagens.
A execução inteira levou 1 minuto e 20 segundos. A maior parte do tempo foi das 23 subchamadas, que rodaram em lote e em paralelo; o modelo raiz gastou poucos segundos em cada turno. Se as subchamadas tivessem rodado uma depois da outra, como nos experimentos do artigo, a mesma árvore passaria de cinco minutos pela estimativa de Caio.
Custo da árvore da PCH, peça por peça
| Peça | Tokens | Preço de referência | Custo |
|---|---|---|---|
| Entrada das 23 subchamadas | 690 mil (23 × 30 mil) | GPT-5-mini, US$ 0,25 por milhão | US$ 0,17 |
| Saída das 23 subchamadas | 11,5 mil (23 × 500) | GPT-5-mini, US$ 2 por milhão | US$ 0,02 |
| Entrada do raiz nos 4 turnos | 24 mil (3 + 5 + 7 + 9 mil) | GPT-5, US$ 1,25 por milhão | US$ 0,03 |
| Saída do raiz nos 4 turnos | 3,2 mil (4 × 800) | GPT-5, US$ 10 por milhão | US$ 0,03 |
| Total da pergunta | cerca de 729 mil | cerca de US$ 0,26 |
Cenário composto da Veredas, com preços de referência da OpenAI conferidos em setembro de 2026. Comparação: ler 1,1 milhão de tokens de uma vez a US$ 4 por milhão custaria US$ 4,40 só de entrada.
O ponto que mais impressionou Helena foi o filtro. Das 140 peças da PCH, só 23 foram lidas por um modelo; as outras 117 foram descartadas por código, pelo cabeçalho e por palavra-chave. Caio lembrou o risco: um documento de condicionante sem as palavras do filtro ficaria de fora sem aviso. Por isso ele imprimiu a lista dos 117 descartados por tipo, e Helena a revisou em dez minutos.
Helena ainda abriu cinco dos códigos de documento citados na tabela, escolhidos ao acaso, e leu os trechos originais. Os cinco sustentavam a linha em que apareciam. Esse gesto de conferência, abrir a evidência e comparar, é o que separa uma resposta rastreável de uma resposta apenas convincente, e ele só é possível porque cada linha carrega a origem.
Os dois discutiram então a pergunta de negócio completa, sobre os 38 empreendimentos. A primeira ideia de Caio foi profundidade 2: um rlm_query por empreendimento, cada sub-RLM repetindo a árvore da PCH. A conta assustou. Com 38 sub-RLMs e cerca de 24 subchamadas cada, seriam perto de 900 chamadas por pergunta, 18 vezes o teto padrão de 50 do dspy.RLM. O custo ficaria perto de US$ 9,90, se cada sub-RLM custasse o mesmo que a PCH.
Helena pediu a alternativa rasa, e Caio a desenhou em profundidade 1. Um único filtro por código sobre os 6.400 cabeçalhos separa os documentos de condicionantes hídricas de todos os empreendimentos, e cada documento filtrado ganha uma subchamada. A árvore fica mais larga e menos funda. Qual das duas acerta mais é uma pergunta de medição, e a próxima trilha trata de como explorar o acervo e dividir o trabalho antes de rodar.
A Veredas ganhou sua primeira execução rastreável: 4 turnos, 23 subchamadas, cerca de US$ 0,26 e as três contagens batendo com a referência de Helena. Rode agora a mesma árvore em mais dois empreendimentos e anote quantas subchamadas cada execução fez; se alguma passar de 50, o filtro do segundo turno está largo demais e precisa de outro critério.
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: Guardar o acervo numa variável e deixar o modelo programar a leitura
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