Write an agent loop in code with smolagents (sandboxed)
Stand up a smolagents CodeAgent that writes Python to act instead of emitting JSON tool calls, and run that model-written code in a sandbox, not on your machine.
Run this workflow
CI-verified, 2/2 fixtures passing.
Build this with your agent
One copy-paste hands Claude Code, Codex, or Cursor the full recipe, steps included, nothing to fetch.
Intended Use
Anyone starting an agent loop without a heavy framework. CI compiles the agent script (python3 py_compile, no smolagents install needed) and asserts it builds a CodeAgent, defines a tool, names a model, and sets a sandboxed executor. No keys, no model call, no code execution. The agent run is fenced.
Not for
- Running model-written code on your own box, always set a sandboxed executor (E2B/Docker); the unsandboxed default is the foot-gun
- Complex stateful orchestration, the library is deliberately small and you may outgrow it; great to start, not always where you finish
The Stack
Tested Against
huggingface.co/docs/smolagents (2026-06)python@3.12 (py_compile, stdlib)Side effects & data flow
- Network
- none, local only
- Writes
- ./agent.py
- Credentials
- none required
Prerequisites
- pip install smolagents + an E2B or Docker sandbox (only to actually run it)
- A model provider key (run-time only)
Steps
- 1
Write the code-agent and structure-check it
Write agent.py: a CodeAgent with a typed tool, a model via LiteLLM, and executor_type set to a sandbox. CI compiles it and checks the calls. Actually running it needs smolagents, a sandbox, and a key, so that step is fenced.
cat > agent.py <<'PY' from smolagents import CodeAgent, LiteLLMModel, tool @tool def get_weather(city: str) -> str: "Return the current weather for a city." return "sunny in " + city agent = CodeAgent( tools=[get_weather], model=LiteLLMModel(model_id="anthropic/claude-opus-4.8"), executor_type="e2b", ) if __name__ == "__main__": print(agent.run("What is the weather in Paris?")) PY python3 - <<'CHECK' import py_compile, sys src = open("agent.py").read() try: py_compile.compile("agent.py", doraise=True) except py_compile.PyCompileError: print("BAD: agent.py does not compile"); sys.exit(1) def need(tok, msg): if tok not in src: print("BAD: " + msg); sys.exit(1) need("CodeAgent", "no smolagents CodeAgent") need("@tool", "no tool defined") need("model=", "no model set") sandbox = "e2b" if 'executor_type="e2b"' in src else ("docker" if 'executor_type="docker"' in src else "") if not sandbox: print("BAD: executor_type is not a sandbox (set e2b or docker)"); sys.exit(1) print("config OK: smolagents CodeAgent compiles, defines a tool, names a model, runs in a sandbox (executor_type=" + sandbox + ")") CHECK - 2
Run the agent (the model + execution step, not checked by CI)
pip install smolagents, set your model key and an E2B key (or Docker), and run agent.py. The agent writes Python and the sandbox executes it off your machine. The run is fenced.
Eval, 2 fixtures
Last passed: verified todayagent-okcontainstimeout 30s · max $0Expected:
config OK: smolagents CodeAgent compiles, defines a tool, names a model, runs in a sandbox (executor_type=e2b)clean-exitexit_codetimeout 30s · max $0Expected:
0
Results
smolagents is a ~1k-line library whose move is code-agents: the agent emits Python, which is often more expressive and uses fewer tokens than JSON tool calls. You can read the whole control flow. Because executing model-written code is risky, this recipe wires it to a sandbox from the start.
Did this work for you?
Our CI checks the setup runs. You tell us if the whole thing worked. Tell us straight.
Related workflows
- promptfoo: make agent evals fail the build, not the user
- E2B: run model-written code in a sandbox, not on your box
- DSPy: program the pipeline, compile the prompts (stop hand-tuning)
- Hermes /learn: author a reusable skill from a source, not by hand
- Text your own AI assistant on WhatsApp: Hermes wired to FreeLLMAPI
- FreeLLMAPI: one socket, sixteen free model tiers with auto-fallback
Liked this workflow?
Get new verified workflows in WebAfterAI, three issues a week (Tue, Thu, Sat).