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
- You provide a question and one or more data sources.
- The root model writes Python for the next step.
- The runtime executes that code on your machine, with access to the configured data.
- The model observes the output and decides whether to query more data, make subcalls, or finish.
- 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.