Recursive Language Models

A recursive language model uses code as part of its reasoning process. Instead of placing an entire dataset in one prompt, a root model writes and executes Python to inspect the data, reduce it, and make targeted model subcalls.

RLM is useful when the route to an answer is not known in advance: the model may need to inspect a schema, query several tables, compare subsets, compute statistics, or revise its approach based on intermediate results.

The execution loop

  1. You provide a question and one or more data sources.
  2. The root model writes Python for the next step.
  3. The runtime executes that code on your machine, with access to the configured data.
  4. The model observes the output and decides whether to query more data, make subcalls, or finish.
  5. The run returns an answer plus usage.
question + data
 root model writes Python
 code queries and reduces data ─────► llm_query / llm_batch
       │                                      │
       └──────────── intermediate output ◄────┘
                   answer + usage

The loop runs in your boundary. ModelRelay sees only the root and subcall
inference requests the generated code chooses to make, and it reports trajectory
content as unavailable rather than retaining it implicitly.

Running in your boundary is not the same as being contained by it. mrl rlm
executes model-written Python as the current user, with that user’s filesystem
and network access; it is an execution environment, not an isolation boundary.
Where that matters, run it under a dedicated least-privilege account or an
operating-system boundary — see
Security and Data Boundaries.

The available data helpers depend on what you mount: attachments and stdin
always, plus a read-only SQL source or remote MCP tools when configured. See
Data Sources.

RLM versus other approaches

Approach Best fit Constraint
One model request A known, relevant prompt fits comfortably in context Quality and cost degrade as irrelevant context grows
Retrieval/RAG Fast lookup of a few relevant passages The retrieval pipeline decides what the model can see
Text-to-SQL One question maps cleanly to one query Limited iteration and cross-query analysis
RLM Exploration, aggregation, computation, and synthesis across many records More latency and model usage than simple lookup

RLM is an analysis runtime, not a replacement for every search query. Use an index or direct query when the task is only “find this record.” Use RLM when answering requires connecting evidence across records or adapting the analysis as it proceeds.

Sandbox interface

Every run exposes:

Name Purpose
context Inline JSON or attached-file metadata and content
llm_query(prompt) Make one bounded model subcall
llm_batch(prompts) Process independent prompts in parallel
answer['content'] Store the final answer
answer['ready'] Set to True when the answer is complete

Data sources add their own namespaced helpers. A local SQLite source named db, for example, is available through db.query(...) and related schema-inspection methods.

llm_query and llm_batch are model subcalls. They do not start a nested RLM loop. The root loop remains responsible for code generation, data access, and completion.

Good RLM tasks

  • Compare revenue changes across customers, products, and time periods.
  • Analyze a large support backlog and find themes with supporting examples.
  • Trace a failure across many log files.
  • Reconcile conflicting facts across documents.
  • Find anomalies that require both deterministic calculations and semantic judgment.

Start here