Skip to content
Runtime

DSPy code execution give ReAct a secure Linux sandbox

Pass Runtime's four sandbox functions to dspy.ReAct as tools. The program's shell commands then run in a Firecracker microVM.

On Runtime, a DSPy program can run real software, not only pure Python. DSPy's own PythonInterpreter runs code in Pyodide, a WebAssembly build of Python, under Deno on your machine. That keeps code off your filesystem. But it offers no shell and no compiler, and only the packages built for Pyodide. A Runtime sandbox is an Ubuntu 24.04 microVM with its own kernel, Python 3.12, Node.js 24, gcc, pip and sudo. dspy 3.4.1 was the current PyPI release on 25 October 2026.

Where DSPy runs code

Module Default interpreter What the code can use
dspy.ProgramOfThought PythonInterpreter (Deno and Pyodide) Pyodide's Python and its packages
dspy.CodeAct PythonInterpreter Pyodide's Python, plus the tools you pass
dspy.RLM PythonInterpreter Pyodide's Python, plus the tools you pass
dspy.ReAct with Runtime tools A Runtime microVM A bash shell, any package, files, the network you allow

The PythonInterpreter docstring in dspy 3.4.1 describes it as a "local interpreter for secure Python execution using Deno and Pyodide" with "no access to the host filesystem, network, or environment by default". It needs Deno installed (pip install "dspy[deno]"). The three code modules accept an interpreter_factory argument, which selects another interpreter.

ReAct with a sandbox

DSPy tools are plain Python functions with type hints and docstrings. ReAct takes them in a list and converts them itself. sandbox_tools(sbx) returns four such functions.

Terminalpip install dspy withruntime
Pythonimport dspyfrom withruntime import Sandboxfrom withruntime.tools import sandbox_toolsdef solve(task: str) -> dspy.Prediction:    with Sandbox.create(        network={"internet": True, "allow": ["pypi.org", "*.pythonhosted.org"]},        timeout_seconds=900,        on_lease_end="stop",    ) as sbx:        agent = dspy.ReAct("task -> answer", tools=sandbox_tools(sbx), max_iters=12)        return agent(task=task)

Configure the language model first, as in any DSPy program, with dspy.configure(lm=dspy.LM(...)). The result has answer, reasoning and a trajectory. The trajectory records every thought, tool call and observation, so you can see which commands ran:

Pythonresult = solve("Install sympy, then factor x**6 - 1 and print the factors.")for step, value in result.trajectory.items():    print(step, value)print(result.answer)

This loop ran on 25 September 2026 with dspy 3.3.1. dspy.utils.DummyLM scripted the model. ReAct called runtime_exec, recorded the sandbox's exit code and stdout as the observation, and finished with the answer.

Optimizing a program that runs code

Optimizers such as MIPROv2 and BootstrapFewShot call your program once per training example and candidate. Give each call its own sandbox inside the module. Every trial then starts from the same clean machine. Nothing one trial installs can leak into the next score:

Pythonimport dspyfrom withruntime import Sandboxfrom withruntime.tools import sandbox_toolsclass Solver(dspy.Module):    def __init__(self):        super().__init__()        self.signature = dspy.Signature("task -> answer")    def forward(self, task: str) -> dspy.Prediction:        with Sandbox.create(network={"internet": False}, timeout_seconds=300, on_lease_end="stop") as sbx:            react = dspy.ReAct(self.signature, tools=sandbox_tools(sbx), max_iters=8)            return react(task=task)

Runtime bills the CPU the commands use, at $0.025 per vCPU-hour. It also bills $0.0075 per GiB-hour of memory. A thousand one-minute runs at 2 vCPU and 4 GiB, each using 20 CPU-seconds, cost $0.64. A sandbox idling while the model thinks costs $0.03125 an hour (pricing). A paid account runs 100 sandboxes at the same time, so each parallel evaluation thread gets a machine.

Keep keys and budgets safe

  • The LM key stays with DSPy. DSPy calls the model from your process. The sandbox receives only the commands ReAct chooses, never the key.
  • No network while scoring. network={"internet": False} gives the sandbox no network card at all, so model-written code cannot send your training data anywhere.
  • Tokens the code needs are stored as Runtime secrets. Inside the sandbox, they appear only as placeholders.
  • A long optimization run cannot overspend. Put a daily spending limit on the key the optimizer uses. When a create would exceed the limit, the create fails with spending_limit_reached. Nothing is charged (read-only keys and daily limits).

Pyodide or a microVM?

Keep PythonInterpreter when the code is short, pure Python, and needs nothing outside Pyodide. Use Runtime when a step needs a package that Pyodide lacks, a command-line tool, a test suite, several languages, or a file that must survive from one step to the next. The trade-off is covered in Pyodide vs a server sandbox and WebAssembly vs a microVM. Evaluation at scale is covered in agent evals and SWE-bench. A new account gets 100 free hours of a 1 GB machine in its first 30 days, with no card needed:

Terminalprintf '%s\n' 'print(sum([125, 250, 375]))' > invoice.pynpx withruntime sandboxes run -- python3 - < invoice.py

Sources

  • DSPy: ReAct and tools, plain functions as tools, max_iters and trajectory, read 25 October 2026
  • dspy on PyPI, version 3.4.1; the PythonInterpreter docstring and the interpreter_factory defaults of ProgramOfThought, CodeAct and RLM were read from that release's source on 25 October 2026

Facts on this page were checked on 25 October 2026.

Related.

100 free hoursin your first 30 days.

of a 1 GB machine

  • No credit card
  • Four sandboxes at once, 2 vCPU and 4 GiB each
  • Then prepaid credit from $10, no plan fee
Start free, no card
Start free, no card