On Runtime, the sandbox is a whole Linux machine, not a Python snippet
runner. smolagents' remote executors send the agent's Python snippets away
and return their output. A Runtime sandbox is a Firecracker microVM with its
own kernel, Ubuntu 24.04, Python 3.12, pip and sudo. The agent can install
packages, run test suites and keep files between steps. A 2 vCPU, 4 GiB
sandbox costs $0.03125 an hour while the model is thinking. smolagents
1.26.0 was the current PyPI release on 25 October 2026.
Where smolagents runs code today
A CodeAgent writes Python and hands it to an executor. The executor is chosen
with executor_type. smolagents 1.26.0 accepts five values:
executor_type |
Where the snippet runs | What you set up |
|---|---|---|
local (default) |
Your own process, in smolagents' AST-walking LocalPythonExecutor |
Nothing; imports need an allow-list |
docker |
A Docker container on your machine | Docker installed, smolagents[docker] |
e2b |
An E2B sandbox | An E2B account, smolagents[e2b] |
modal |
A Modal sandbox | A Modal account, smolagents[modal] |
blaxel |
A Blaxel sandbox | A Blaxel account, smolagents[blaxel] |
| Runtime tools | A Runtime microVM, through tool calls | withruntime; one browser approval to start |
The smolagents guide is direct about the default: "no local python sandbox can ever be completely secure", and "the only way to run LLM-generated code with truly robust security isolation is to use remote execution options". It also notes that the remote executors do not support managed agents (multi-agent setups) yet.
Give a ToolCallingAgent the sandbox
sandbox_tools(sbx) returns runtime_exec, runtime_read_file,
runtime_write_file and runtime_list_files as typed functions. Their
docstrings carry an Args: section. smolagents' tool decorator needs exactly
that to build a tool's name, inputs and output type. So wrapping each one takes
one line.
Terminalpip install smolagents withruntimePythonfrom smolagents import ToolCallingAgent, toolfrom withruntime import Sandboxfrom withruntime.tools import sandbox_toolsdef solve(model, task: str) -> str: with Sandbox.create( network={"internet": True, "allow": ["pypi.org", "*.pythonhosted.org"]}, timeout_seconds=900, on_lease_end="stop", ) as sbx: tools = [tool(f) for f in sandbox_tools(sbx)] agent = ToolCallingAgent(tools=tools, model=model, max_steps=15) return str(agent.run(task))model is any smolagents model, such as InferenceClientModel() or
OpenAIModel(...). The sandbox exists for the length of the with block. A
package installed in step two is still there in step nine. The sandbox stops
when the block ends, whether it ends normally or with an error.
Prefer ToolCallingAgent here. A CodeAgent accepts the same tools and can
call them from its code. But the snippets it writes still run in whichever
executor executor_type names, which is your own process by default.
Check the tools before paying for a model
Each wrapped tool can be called on its own, so a smoke test needs no model:
Pythonfrom smolagents import toolfrom withruntime import Sandboxfrom withruntime.tools import sandbox_toolswith Sandbox.create() as sbx: run, read, write, ls = (tool(f) for f in sandbox_tools(sbx)) print(run.inputs) # command, cwd, timeout_seconds print(write(path="fib.py", content="a, b = 0, 1\nfor _ in range(90): a, b = b, a + b\nprint(a)\n")) print(run(command="python3 fib.py")) # {'exit_code': 0, 'stdout': '...', ...}runtime_exec returns the exit code, stdout, stderr and a timed_out flag. The
model then sees a failure as a failure. Relative paths land in /workspace.
Run the whole agent in the sandbox
smolagents' guide describes a second pattern for multi-agent systems. Put the agent, its model calls and its tools all inside the sandbox. The guide's drawback is that this "may require transferring sensitive API keys to the sandbox environment". Runtime removes that step. Store the model key once as a secret, bound to the provider's host:
Terminalprintf %s "$OPENAI_API_KEY" | npx withruntime secrets set OPENAI_API_KEY --host api.openai.comEvery sandbox of the account then has OPENAI_API_KEY set to a placeholder. The
host's proxy swaps in the real key only on HTTPS requests to api.openai.com.
Managed agents inside the sandbox can therefore call the model, while nothing in
the machine can read the key
(secrets sandboxes never see).
Pythonimport sysfrom withruntime import Sandboxtask = "What's the 20th Fibonacci number?"with Sandbox.create( network={"internet": True, "allow": ["api.openai.com", "pypi.org", "*.pythonhosted.org"]}, timeout_seconds=1800, on_lease_end="stop",) as sbx: sbx.files.upload("./my_agents", "/workspace/my_agents") sbx.exec("pip install 'smolagents[openai]'", check=True, timeout_ms=300_000) run = sbx.exec( ["python3", "manager.py", task], cwd="/workspace/my_agents", timeout_ms=1_200_000, on_stdout=sys.stdout.write, ) print(run.exit_code)manager.py is your own smolagents program. It uses OpenAIModel as it would
on your laptop. The allow-list limits the sandbox to the model's API and the
package index.
Keep keys and spending in check
- The model never holds your Runtime key. Your code creates the sandbox and binds the tools. The model only chooses commands and paths.
- Cap each agent run.
timeout_secondswithon_lease_end="stop"ends a forgotten sandbox.max_total_cost_microsstops a sandbox once its total cost reaches the value you set. - Cap the key. Give the application a key with a daily spending limit. Past
that limit, creates fail with
spending_limit_reached, and nothing is charged (read-only keys and daily limits).
Which executor fits
Choose local only for trusted demos. Choose Docker when everything stays on
one machine you control. Choose Runtime when the agent needs a real shell, when
many agents run at the same time, or when managed agents need a model key without holding
it. A paid account runs 100 sandboxes at the same time. Billing is by the
CPU they use: $0.08 an hour for a 2 vCPU, 4 GiB sandbox with both CPUs
busy (pricing).
For the other Python frameworks, see any other framework. For the risks this contains, see run untrusted LLM code. For container isolation compared with a microVM, see microVM vs container. A new account gets 100 free hours of a 1 GB machine in its first 30 days, no card:
Terminalprintf '%s\n' 'print(sum([125, 250, 375]))' > invoice.pynpx withruntime sandboxes run -- python3 - < invoice.pyRelated
Sources
- smolagents: Secure code execution, read 25 October 2026
- smolagents on PyPI, version 1.26.0, read 25 October 2026;
CodeAgent'sexecutor_typevalues and the@toolschema were read from that release's source
Facts on this page were checked on 25 October 2026.