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 in a sandbox 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 its usage and execution trajectory.
question + data
│
▼
root model writes Python
│
▼
sandbox queries and reduces data ──► llm_query / llm_batch
│ │
└──────────── intermediate output ◄────┘
│
▼
answer + trajectory + usage
The available data helpers depend on the execution mode. Local CLI runs can access attachments and read-only SQLite. Hosted runs accept inline context, context handles, or a wrapper_v1 service.
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.