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-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

  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.