Production-grade RLMs (Recursive Language Models) with tool use, built on DSPy
Project description
[!NOTE] Read the launch post for our optimized SpreadsheetBench skill.
predict-rlm
Production focused Self-harnessed LM runtime (RLM) that allows the LM to call its sub-lm with DSPy signatures. Define your inputs, outputs, and tools — the model handles its own control flow. Get fully interpretable trajectories and performance that scales directly with model improvements. Without context rot.
Based on the Recursive Language Models paper by Alex L. Zhang, Tim Kraska, and Omar Khattab from MIT CSAIL.
crafted with ♥ in MTL · NYC · FLP
by Trampoline AI
Installation
uv add predict-rlm
Docker Sandboxes backend
JSPI/Deno/Pyodide remains the default sandbox. Docker Sandboxes (sbx) is an explicit opt-in backend for environments that want a Linux Python runner:
brew install docker/tap/sbx
sbx login
from predict_rlm import PredictRLM, SbxConfig, SbxPool
rlm = PredictRLM(
"question -> answer",
sandbox_backend="sbx",
sbx_config=SbxConfig(name="my-predict-rlm-sbx"),
)
By default, SbxConfig passes the explicit non-Docker shell template docker.io/docker/sandbox-templates:shell to sbx create. Pass a custom template="..." to override it, or template=None to omit --template and use Docker's CLI default behavior.
For throughput-sensitive evals or optimization loops, create a pool of prewarmed runners and pass it explicitly:
with SbxPool(size=4, config=SbxConfig()) as pool:
rlm = PredictRLM(
"question -> answer",
sandbox_backend="sbx",
sbx_pool=pool,
)
The backend mounts only a per-run staging directory under .predict_rlm_sbx/ by default, preserving model-facing paths such as /sandbox/input/... and /sandbox/output/... without exposing the rest of the repo workspace. Use SbxConfig(extra_workspaces=[...]) only when the sandbox needs explicit additional host mounts. Real sbx integration tests are skipped by default; run them with PREDICT_RLM_RUN_SBX_TESTS=1 uv run pytest -m sbx after the CLI is installed and logged in.
Why RLMs?
- Avoid context rot — The root LM only interacts with its context programmatically through the REPL, staying well within its comfortable operating range — enabling complex, long-horizon tasks that would otherwise cause models to silently degrade.
- Bitter lesson-proof: RLMs improve as LMs improve — Unlike harnesses, which can cap or constrain the base model's capabilities, the performance, speed, and cost of RLM calls correlate directly with improvements to base model capabilities. If the base model handles 10M tokens tomorrow, the RLM handles 100M.
- Symbolic reasoning & recursion — like algebra, RLMs express the structure of computation rather than performing each operation individually; a single line can represent 1M sub-calls — in direct contrast to agents like Claude Code that must mechanically emit each sub-agent call one at a time.
- Interpretability — RLM trajectories are fully readable: you can trace every peek, chunk, sub-call, and verification step the model takes. This not only reveals how the model decomposed a problem, but provides concrete optimization signals which tools like GEPA can ingest to evolve the RLM's strategies.
- Ideal for improving performance per token — RLMs allow small models to punch way above their weight (RLM(GPT-5-mini) outperforms base GPT-5) providing great opportunities for reducing costs or stretching limited compute budgets without sacrificing quality.
Features
- Multimodal — process images, documents, audio, and video through sub-LM calls using native provider multimodal APIs.
- Async tool calling — native RLM async support in the WASM sandbox, enabling concurrent sub-LM invocations and tool calls
- Prompt-optimized skills & tools — predict-rlm skills comes tested and optimized to ensure maximum LM interoperability and performance, bundling instructions, PyPI packages, and tools for domain-specific tasks
- Simple file I/O — pass local or cloud files as typed inputs and outputs via
File, keeping interop with your existing data pipelines straightforward. (S3 files support soon) - Structured sub-LM calls — native Pydantic and DSPy signature support for type-safe sub-LM invocations with structured outputs
Demos
| Description | Input / Output | Preview |
|---|---|---|
| Document Analysis — Analyze documents and extract key dates, entities, and financial information into a structured report | Input: PDFs Output: Structured briefing report (example output) |
|
| Document Redaction — Redact PII from PDFs based on a policy, then verify the redactions visually | Input: PDFs Output: Redacted PDFs (example output) |
|
| Invoice Processing — Extract vendor info, line items, and totals from PDF invoices into a consolidated Excel spreadsheet | Input: PDF invoices Output: Excel spreadsheet (example output) |
|
| Contract Comparison — Compare two contract versions and produce a structured diff report with per-section analysis | Input: 2 PDF contracts Output: Structured diff report (example output) |
Quick start
With your coding agent
Install the predict-rlm skill in Claude Code, Codex, Cursor, or any compatible coding agent:
npx skills add Trampoline-AI/predict-rlm
Then ask your agent to build an RLM:
❯ /rlm build an RLM that extracts line items from PDF invoices into a spreadsheet
Quick Example
import dspy
from predict_rlm import File, PredictRLM
class AnalyzeImages(dspy.Signature):
"""Analyze images and answer the query. Load each image as a base64 data
URI and use predict() with dspy.Image to extract visual information."""
images: list[File] = dspy.InputField()
query: str = dspy.InputField()
answer: str = dspy.OutputField()
rlm = PredictRLM(
AnalyzeImages,
lm="openai/gpt-5.4",
sub_lm="openai/gpt-5.1",
)
result = rlm(
images=[File(path="page.png")],
query="Extract all visible text, then count each letter A-Z (case-insensitive).",
)
print(result.answer)
Using the spreadsheet skill
The optimized spreadsheet skill is built in. Import it and pass it through skills=[spreadsheet] so the RLM gets the spreadsheet-specific instructions, openpyxl, pandas, formulas, and the formula_eval verification module inside its sandbox.
import dspy
from predict_rlm import File, PredictRLM
from predict_rlm.skills import spreadsheet
class UpdateWorkbook(dspy.Signature):
"""Update the workbook following the request.
Use openpyxl for workbook edits, Excel formulas for derived values, and
verify formulas before returning the final .xlsx file.
"""
workbook: File = dspy.InputField(desc="Input .xlsx workbook")
request: str = dspy.InputField(desc="Requested spreadsheet changes")
updated_workbook: File = dspy.OutputField(desc="Updated .xlsx workbook")
rlm = PredictRLM(
UpdateWorkbook,
lm="openai/gpt-5.4",
sub_lm="openai/gpt-5.1",
skills=[spreadsheet],
)
result = rlm(
workbook=File(path="model.xlsx"),
request="Add a Summary sheet with revenue by quarter and formulas for totals.",
)
print(result.updated_workbook.path)
For workflows that combine source documents and spreadsheets, compose skills:
from predict_rlm.skills import pdf, spreadsheet
rlm = PredictRLM(ProcessInvoices, skills=[pdf, spreadsheet])
Next steps
- How it works — understand the sandbox, REPL loop, signatures, and file I/O
- API reference — constructor params for
PredictRLM,File, andSkill - Skills — define, compose, and mount custom skills
- RLM-GEPA — optimize RLM skills from traces and configure
AgentSpec - Examples — end-to-end demos with setup instructions
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file predict_rlm-0.6.0.tar.gz.
File metadata
- Download URL: predict_rlm-0.6.0.tar.gz
- Upload date:
- Size: 159.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4326aba2a39e7c9b919e09e70d6a70a38abcf5c4953f809234f3c699fcb14f3d
|
|
| MD5 |
fa1151d371b48e41ccd7d6a6687aca7d
|
|
| BLAKE2b-256 |
09f746a72a2b3396bafa1731059e95e30c2d9fef9ef3924869eb485082681646
|
Provenance
The following attestation bundles were made for predict_rlm-0.6.0.tar.gz:
Publisher:
release.yml on Trampoline-AI/predict-rlm
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
predict_rlm-0.6.0.tar.gz -
Subject digest:
4326aba2a39e7c9b919e09e70d6a70a38abcf5c4953f809234f3c699fcb14f3d - Sigstore transparency entry: 1537394249
- Sigstore integration time:
-
Permalink:
Trampoline-AI/predict-rlm@9cb86bbbb39c6216df60d794e8969240612806b4 -
Branch / Tag:
refs/tags/v0.6.0 - Owner: https://github.com/Trampoline-AI
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@9cb86bbbb39c6216df60d794e8969240612806b4 -
Trigger Event:
push
-
Statement type:
File details
Details for the file predict_rlm-0.6.0-py3-none-any.whl.
File metadata
- Download URL: predict_rlm-0.6.0-py3-none-any.whl
- Upload date:
- Size: 179.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9e0914639d0b1eef1e5fbe2b3e93ed0c7cb2395584a58a3db2e571270a95153a
|
|
| MD5 |
9cecfa67df94e8d05c3e01ac62ee77d7
|
|
| BLAKE2b-256 |
1345590c98d46ba910f4d2f0edc5adc4f511796b884d664ceea37f3c6360ef84
|
Provenance
The following attestation bundles were made for predict_rlm-0.6.0-py3-none-any.whl:
Publisher:
release.yml on Trampoline-AI/predict-rlm
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
predict_rlm-0.6.0-py3-none-any.whl -
Subject digest:
9e0914639d0b1eef1e5fbe2b3e93ed0c7cb2395584a58a3db2e571270a95153a - Sigstore transparency entry: 1537394362
- Sigstore integration time:
-
Permalink:
Trampoline-AI/predict-rlm@9cb86bbbb39c6216df60d794e8969240612806b4 -
Branch / Tag:
refs/tags/v0.6.0 - Owner: https://github.com/Trampoline-AI
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@9cb86bbbb39c6216df60d794e8969240612806b4 -
Trigger Event:
push
-
Statement type: