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_query or llm_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-4-5 \
  --subcall-model gemini-2.5-flash

With hosted /rlm/execute:

{
  "model": "claude-sonnet-4-5",
  "subcall_model": "gemini-2.5-flash",
  "query": "Analyze the support backlog",
  "context": {"tickets": []}
}

Use model IDs returned by mrl models 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. 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 none

Raise reasoning effort only when a delegated task genuinely requires it:

{
  "subcall_max_output_tokens": 4096,
  "subcall_reasoning_effort": "low"
}

Supported effort values are none, minimal, low, medium, high, and xhigh. Provider support varies; values outside the resolved provider’s supported subset are rejected.

Limit the loop

Control CLI default Purpose
--max-iterations 10 Maximum root code-generation cycles
--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

Hosted requests use the equivalent JSON fields without the leading dashes.

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

  1. Start with default limits and inspect iterations, subcalls, and usage.
  2. Use deterministic Python or SQL for filtering and arithmetic.
  3. Send only ambiguous semantic work to model subcalls.
  4. Prefer llm_batch for independent items that can run concurrently.
  5. Set the smallest output cap that fits the delegated task.
  6. 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.