Models, subcalls, and cost
An RLM run has two different kinds of model work:
- The root model plans the analysis, writes Python, observes results, and decides when to finish.
- Subcall models perform bounded semantic tasks requested through
llm_queryorllm_batch.
Using the same model for both is simple, but it is rarely the most economical configuration. A strong root model can delegate extraction, classification, and summarization to a faster model.
Choose a subcall model
With the CLI:
mrl rlm "Analyze the support backlog" -a ./tickets.json \
--model claude-sonnet-5 \
--subcall-model gemini-3.7-flash \
--subcall-reasoning-effort low
Under an execution grant, both routes come from the immutable profile the preset:<code> selector resolves to. The client cannot override them, and a callback that tries is rejected.
Use model IDs returned by mrl model list or GET /models. Availability and pricing depend on the project configuration.
Bound subcall output
Subcalls default to a maximum of 2,048 output tokens and no reasoning effort (none). Models that cannot disable thinking, including Gemini 3.7 Flash, reject none; pass --subcall-reasoning-effort low for those routes. These defaults prevent a small extraction prompt from consuming an open-ended reasoning budget.
mrl rlm "Extract and compare the contract obligations" -a ./contracts/*.txt \
--subcall-max-output-tokens 1024 \
--subcall-reasoning-effort low
Raise reasoning effort only when a delegated task genuinely requires it:
{
"subcall_max_output_tokens": 4096,
"subcall_reasoning_effort": "high"
}
See the reasoning effort guide for supported values and provider mappings. Values outside the resolved model’s supported subset are rejected.
Limit the loop
| Control | CLI default | Purpose |
|---|---|---|
--max-subcalls |
50 | Maximum llm_query and llm_batch calls |
--max-depth |
1 | Maximum allowed subcall depth |
--exec-timeout-ms |
Runtime default | Maximum time for each Python execution |
An execution profile carries the same limits as max_subcalls, max_depth,
and a run-wide timeout_ms, plus max_concurrency and a total-token budget
that ModelRelay enforces atomically across callbacks. Iteration count is
reported as a diagnostic, not treated as an independent compute authority.
max_depth is a safety limit on the existing subcall path. The public sandbox interface does not currently expose a nested rlm_query function that starts another full RLM loop.
Cost guidance
- Start with default limits and inspect
iterations,subcalls, andusage. - Use deterministic Python or SQL for filtering and arithmetic.
- Send only ambiguous semantic work to model subcalls.
- Prefer
llm_batchfor independent items that can run concurrently. - Set the smallest output cap that fits the delegated task.
- Attribute runs to customer tokens when RLM is embedded in a multi-tenant product.
The response reports aggregate usage for the run. ModelRelay can also attribute the recursive usage to the initiating customer for quota enforcement and billing.