Python package + Typer CLI implementation of the RLM with Modal notebook
Project description
fleet-rlm
A Python package implementing Recursive Language Models (RLM) with DSPy and Modal for secure, cloud-based code execution. This project demonstrates how LLMs can treat long contexts as external environments, using programmatic code exploration in sandboxed environments.
Reference: Recursive Language Models (Zhang, Kraska, Khattab, 2025)
Overview
Recursive Language Models (RLM) represent an inference strategy where:
- LLMs treat long contexts as an external environment rather than direct input
- The model writes Python code to programmatically explore data
- Code executes in a sandboxed environment (Modal cloud)
- Only relevant snippets are sent to sub-LLMs for semantic analysis
This package provides both a comprehensive Jupyter notebook and a Typer CLI for running RLM workflows.
Using dspy.RLM with Claude Code
fleet-rlm is designed to work seamlessly with Claude Code (Claude's agentic coding capabilities). The bundled skills and agents enable Claude to leverage dspy.RLM for complex, long-context tasks.
Why Use RLM with Claude Code?
| Challenge | RLM Solution |
|---|---|
| Context window limits | Code explores data programmatically instead of loading everything |
| Complex multi-step analysis | Sub-agents handle specialized tasks via llm_query() |
| Reproducibility | All exploration steps are Python code — auditable and replayable |
| Secure execution | Modal sandboxes isolate untrusted code from your environment |
Agent Architecture
┌─────────────────────────────────────────────────────────────┐
│ CLAUDE CODE (Orchestrator) │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ rlm-orchestrator│ │ rlm-specialist │ │
│ │ (coordinates │→ │ (executes │ │
│ │ multi-agent │ │ complex RLM │ │
│ │ workflows) │ │ tasks) │ │
│ └─────────────────┘ └─────────────────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌─────────────────────────────────────────┐ │
│ │ ModalInterpreter (dspy.CodeInterpreter) │ │
│ │ • Manages sandbox lifecycle │ │
│ │ • Bridges tools to/from sandbox │ │
│ │ • Handles llm_query() sub-calls │ │
│ └─────────────────────────────────────────┘ │
│ │ │
└────────────────────────┼────────────────────────────────────┘
│ JSON protocol
▼
┌──────────────────────┐
│ MODAL SANDBOX │
│ • Python 3.12 │
│ • Isolated exec() │
│ • Sub-LLM calls │
└──────────────────────┘
Quick Start with Claude Code
-
Install skills and agents to your Claude configuration:
uv run fleet-rlm init
-
Use the
rlmskill in Claude Code for long-context tasks:@rlm Analyze this 500KB log file and extract all error patterns -
Use the
rlm-orchestratoragent for multi-step workflows:@rlm-orchestrator Process these 10 documentation files, extract API endpoints, and generate a summary report
Sub-Agent Patterns
The RLM approach enables powerful sub-agent delegation:
# Inside Modal sandbox, the LLM-generated code can call:
result = llm_query(
"Extract all function signatures from this code",
context=code_snippet
)
# Or batch multiple sub-queries in parallel:
results = llm_query_batched([
{"query": "Summarize section 1", "context": chunk1},
{"query": "Summarize section 2", "context": chunk2},
])
This pattern allows Claude to:
- Delegate semantic analysis to sub-LLMs while keeping orchestration logic in Python
- Process chunks in parallel for large documents
- Accumulate results across multiple iterations using stateful buffers
Features
- Secure Cloud Execution: Code runs in Modal's isolated sandbox environment
- DSPy Integration: Built on DSPy 3.1.3 with custom signatures for RLM tasks
- CLI Interface: Typer-based CLI with multiple demo commands
- Extensible Tools: Support for custom tools that bridge sandbox and host
- Secret Management: Secure handling of API keys via Modal secrets
Technology Stack
| Component | Technology |
|---|---|
| Language | Python >= 3.10 |
| Package Manager | uv (modern Python package manager) |
| Core Framework | DSPy 3.1.3 |
| Cloud Sandbox | Modal |
| CLI Framework | Typer >= 0.12 |
| Testing | pytest >= 8.2 |
| Linting/Formatting | ruff >= 0.8 |
Installation
# Clone the repository
git clone https://github.com/qredence/fleet-rlm.git
cd fleet-rlm
# Install dependencies with uv
uv sync
# For development (includes test tools)
uv sync --extra dev
Skills and Agents Installation
fleet-rlm includes custom Claude skills and agents optimized for RLM workflows. Install them to your user directory for use across all projects:
# List available skills and agents
uv run fleet-rlm init --list
# Install all skills and agents to ~/.claude/
uv run fleet-rlm init
# Or install to a custom directory
uv run fleet-rlm init --target ~/.config/claude
# Force overwrite existing files
uv run fleet-rlm init --force
Note: Skills and agents are workflow definitions only. You still need to configure Modal authentication and secrets separately (see Setup Modal above).
Available Skills:
dspy-signature- Generate and validate DSPy signaturesmodal-sandbox- Manage Modal sandboxesrlm- Run RLM for long-context tasksrlm-batch- Execute parallel tasksrlm-debug- Debug RLM executionrlm-execute- Execute Python in sandboxesrlm-long-context- (EXPERIMENTAL) Research implementationrlm-memory- Long-term memory persistencerlm-run- Run RLM tasks with proper configurationrlm-test-suite- Test and evaluate workflows
Available Agents:
modal-interpreter-agent- Direct Modal sandbox interactionrlm-orchestrator- Multi-agent RLM coordination (recommended for complex tasks)rlm-specialist- Complex RLM task execution with full sandbox accessrlm-subcall- Lightweight sub-LLM calls for delegation patterns
Tip: Start with
rlm-orchestratorfor multi-file or multi-step tasks. It coordinatesrlm-specialistandrlm-subcallautomatically.
Quick Start
1. Configure Environment
Copy the environment template and fill in your values:
# Copy the template
cp .env.example .env
# Edit with your API keys and model configuration
# See .env.example for detailed documentation on each variable
vim .env
Required variables:
DSPY_LM_MODEL- LLM model identifier (e.g.,openai/gpt-4,google/gemini-3-flash-preview)DSPY_LLM_API_KEY- API key for your LLM provider
Optional variables:
DSPY_LM_API_BASE- Custom API endpoint (if using proxy or self-hosted)DSPY_LM_MAX_TOKENS- Maximum response length (default: 8192)
⚠️ Security: The .env file is gitignored and will never be committed. Keep your API keys safe!
2. Setup Modal
Important: Modal authentication and secrets are per user. Each developer needs to run Modal setup in their own environment and create secrets in their own Modal account. Credentials are not shared or bundled with fleet-rlm.
# Authenticate with Modal
uv run modal setup
# Create a Modal volume for data
uv run modal volume create rlm-volume-dspy
# Create Modal secret for API keys
uv run modal secret create LITELLM \
DSPY_LM_MODEL=... \
DSPY_LM_API_BASE=... \
DSPY_LLM_API_KEY=... \
DSPY_LM_MAX_TOKENS=...
3. Run CLI Commands
# Show all available commands
uv run fleet-rlm --help
# Run a basic demo
uv run fleet-rlm run-basic --question "What are the first 12 Fibonacci numbers?"
# Doc-analysis commands require --docs-path
# Extract architecture from documentation
uv run fleet-rlm run-architecture \
--docs-path rlm_content/dspy-knowledge/dspy-doc.txt \
--query "Extract all modules and optimizers"
# Extract API endpoints
uv run fleet-rlm run-api-endpoints --docs-path rlm_content/dspy-knowledge/dspy-doc.txt
# Find error patterns
uv run fleet-rlm run-error-patterns --docs-path rlm_content/dspy-knowledge/dspy-doc.txt
# Inspect trajectory on a document sample
uv run fleet-rlm run-trajectory \
--docs-path rlm_content/dspy-knowledge/dspy-doc.txt \
--chars 5000
# Use custom regex tool
uv run fleet-rlm run-custom-tool \
--docs-path rlm_content/dspy-knowledge/dspy-doc.txt \
--chars 5000
# Check Modal secrets are configured
uv run fleet-rlm check-secret
CLI Commands
| Command | Description |
|---|---|
init |
Install bundled Claude skills and agents |
run-basic |
Basic code generation (Fibonacci example) |
run-architecture |
Extract DSPy architecture from documentation |
run-api-endpoints |
Extract API endpoints using batched queries |
run-error-patterns |
Find and categorize error patterns in docs |
run-trajectory |
Examine RLM execution trajectory |
run-custom-tool |
Demo with custom regex tool |
check-secret |
Verify Modal secret presence |
check-secret-key |
Inspect specific secret key |
Architecture
┌─────────────────────────────────────────────────────────────┐
│ LOCAL (Jupyter/CLI) │
│ ┌─────────────┐ ┌──────────────┐ ┌──────────────────┐ │
│ │ Planner LM │ │ RLM Module │ │ ModalInterpreter │ │
│ │ (decides │→ │ (builds │→ │ (manages sandbox │ │
│ │ what code │ │ signatures) │ │ lifecycle) │ │
│ │ to write) │ │ │ │ │ │
│ └─────────────┘ └──────────────┘ └──────────────────┘ │
│ │ │ │ │
│ │ │ JSON stdin │ gRPC │
│ │ ↓ ↓ │
└───────────┼────────────────┼──────────────────┼─────────────┘
│ │ │
│ │ ▼
│ │ ┌──────────────────────┐
│ │ │ MODAL CLOUD │
│ │ │ ┌────────────────┐ │
│ └────→│ │ Sandbox │ │
│ │ │ - Python 3.12 │ │
│ │ │ - Volume /data │ │
│ │ │ - Secrets │ │
│ │ └────────────────┘ │
│ │ │ │
│ │ ▼ │
│ │ ┌────────────────┐ │
│ │ │ Driver Process │ │
│ │ │ - exec() code │ │
│ │ │ - tool bridging│ │
│ │ └────────────────┘ │
│ └──────────────────────┘
│ │
└────────────────────────────────┘
tool_call requests
(llm_query, etc.)
Package Structure
src/fleet_rlm/
├── __init__.py # Package exports
├── cli.py # Typer CLI interface
├── config.py # Environment configuration
├── driver.py # Sandbox protocol driver
├── interpreter.py # ModalInterpreter implementation
├── runners.py # High-level RLM demo runners
├── signatures.py # DSPy signatures for RLM tasks
└── tools.py # Custom RLM tools
Module Descriptions
config.py: Loads environment variables, configures DSPy's planner LM, guards against Modal package shadowingcli.py: Typer CLI with commands for running demos and checking secretsdriver.py: Runs inside Modal's sandbox as a long-lived JSON protocol driverinterpreter.py: DSPy-compatibleCodeInterpretermanaging Modal sandbox lifecyclerunners.py: High-level functions orchestrating complete RLM workflowssignatures.py: RLM task signatures (ExtractArchitecture, ExtractAPIEndpoints, etc.)tools.py: Custom tools likeregex_extract()for RLM use
RLM Patterns
Pattern 1: Navigate → Query → Synthesize
- Code searches for headers in documentation
llm_query()extracts info from relevant sectionsSUBMIT(modules=list, optimizers=list, principles=str)returns structured output
Pattern 2: Parallel Chunk Processing
- Split documents into chunks by headers
llm_query_batched([chunk1, chunk2, ...])executes in parallel- Aggregate results into final output
Pattern 3: Stateful Multi-Step
- Search for keywords in documentation
- Save matches to variable (persists across iterations)
- Query LLM to categorize findings
- Iterate with refined queries
Testing
# Run all tests
uv run pytest
# Or via Make
make test
| Test File | Purpose |
|---|---|
test_cli_smoke.py |
CLI help display, command discovery, error handling |
test_config.py |
Environment loading, quoted values, fallback API keys |
test_driver_protocol.py |
SUBMIT output mapping, tool call round-trips |
test_tools.py |
Regex extraction, groups, flags |
Development
# Install dev dependencies
make sync-dev
# Run linting
make lint
# Format code
make format
# Run all checks
make check
# Run release validation (lint, tests, build, twine check)
make release-check
# Install pre-commit hooks
make precommit-install
make precommit-run
Release process documentation is in RELEASING.md, including the TestPyPI-first workflow.
Jupyter Notebook
The original implementation is available as a Jupyter notebook:
# Launch Jupyter Lab
uv run jupyter lab notebooks/rlm-dspy-modal.ipynb
# Execute headlessly (for CI/validation)
uv run jupyter nbconvert \
--to notebook \
--execute \
--inplace \
--ExecutePreprocessor.timeout=3600 \
notebooks/rlm-dspy-modal.ipynb
Security
- Secrets Management: All credentials stored in Modal secrets, never in code
- Sandbox Isolation: Code executes in Modal's isolated sandbox environment
- Local .env: Contains API keys - is gitignored and should never be committed
- Shadow Protection:
config.pyguards againstmodal.pynaming conflicts
Troubleshooting
"Planner LM not configured"
Set DSPY_LM_MODEL and DSPY_LLM_API_KEY in .env, then restart your shell or kernel.
"Modal sandbox process exited unexpectedly"
uv run modal token set
uv run modal volume list
"No module named 'modal'"
uv sync
Modal package shadowing
Remove any modal.py file or __pycache__/modal.*.pyc in the working directory.
References
- RLM Paper: Recursive Language Models (also available in
rlm-volume-dspyat/data/rlm-knowledge/) - DSPy Docs: https://dspy-docs.vercel.app/
- Modal Docs: https://modal.com/docs
- UV Docs: https://docs.astral.sh/uv/
- Project Docs: See
docs/directory for detailed guides and architecture documentation
License
This project is licensed under the MIT License.
Contributing
Contributions are welcome! Please see CONTRIBUTING.md for guidelines.
Acknowledgments
This project is based on research from the Recursive Language Models paper by Zhang, Kraska, and Khattab (2025).
Built with:
- DSPy - Framework for programming with language models
- Modal - Serverless computing for AI
- Typer - CLI framework
- Claude Code - Agentic coding with Claude
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 fleet_rlm-0.3.1.tar.gz.
File metadata
- Download URL: fleet_rlm-0.3.1.tar.gz
- Upload date:
- Size: 93.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0498b9ec0e3a192e1d3c1a04af79df50dab7e1a34e1b759616dba437d188efa2
|
|
| MD5 |
b76e73adb56278a531387915354bc9d1
|
|
| BLAKE2b-256 |
14a5a65c5abdb308ce12f31e642d3f9503790d5244123e12ac8be02a98de3d72
|
Provenance
The following attestation bundles were made for fleet_rlm-0.3.1.tar.gz:
Publisher:
release.yml on Qredence/fleet-rlm
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
fleet_rlm-0.3.1.tar.gz -
Subject digest:
0498b9ec0e3a192e1d3c1a04af79df50dab7e1a34e1b759616dba437d188efa2 - Sigstore transparency entry: 933060469
- Sigstore integration time:
-
Permalink:
Qredence/fleet-rlm@d672911d34013d9695cc7ca8333e487c92a2e078 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/Qredence
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@d672911d34013d9695cc7ca8333e487c92a2e078 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file fleet_rlm-0.3.1-py3-none-any.whl.
File metadata
- Download URL: fleet_rlm-0.3.1-py3-none-any.whl
- Upload date:
- Size: 91.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2761bfc931bc62b5d22ffc14443d99176e72843cb6e3b3db6a75e28daa826ad6
|
|
| MD5 |
6d45800f2ced455ef4619c2a539c5079
|
|
| BLAKE2b-256 |
779386624369259da8e93c43b1f10508c97450843db3a05e4e5f759c811115ad
|
Provenance
The following attestation bundles were made for fleet_rlm-0.3.1-py3-none-any.whl:
Publisher:
release.yml on Qredence/fleet-rlm
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
fleet_rlm-0.3.1-py3-none-any.whl -
Subject digest:
2761bfc931bc62b5d22ffc14443d99176e72843cb6e3b3db6a75e28daa826ad6 - Sigstore transparency entry: 933060511
- Sigstore integration time:
-
Permalink:
Qredence/fleet-rlm@d672911d34013d9695cc7ca8333e487c92a2e078 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/Qredence
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@d672911d34013d9695cc7ca8333e487c92a2e078 -
Trigger Event:
workflow_dispatch
-
Statement type: