Skip to content
sistemo.io beta
GitHub Docs Quickstart

Connect an LLM

Give a model a sandbox as a code-execution tool: it writes code, your app runs it in an isolated microVM, and you feed the result back. This is the core loop of a coding agent.

The flow:

LLM ──writes code──▶ your app ──sb.run()──▶ microVM ──stdout/exit──▶ back to LLM

With Claude (Anthropic)

Define a run_python tool, execute its input in a sandbox, return the output as the tool result.

import anthropic
from sistemo import Sandbox

client = anthropic.Anthropic()        # reads ANTHROPIC_API_KEY

tools = [{
    "name": "run_python",
    "description": "Run Python code in an isolated VM and return its stdout/stderr.",
    "input_schema": {
        "type": "object",
        "properties": {"code": {"type": "string"}},
        "required": ["code"],
    },
}]

with Sandbox(stack="python") as sb:                       # one sandbox for the session
    msg = client.messages.create(
        model="claude-opus-4-8",
        max_tokens=1024,
        tools=tools,
        messages=[{"role": "user", "content": "Compute the 30th Fibonacci number."}],
    )

    for block in msg.content:
        if block.type == "tool_use" and block.name == "run_python":
            r = sb.run(f"python3 -c {__import__('shlex').quote(block.input['code'])}")
            print("tool result:", r.stdout or r.stderr)
            # send this back as a tool_result in your next messages.create(...) call

See the Claude API reference for the full tool-use loop (sending tool_result back until the model stops).

With OpenAI

Same idea with function calling:

from openai import OpenAI
from sistemo import Sandbox
import json, shlex

client = OpenAI()

tools = [{
    "type": "function",
    "function": {
        "name": "run_python",
        "description": "Run Python in an isolated VM; returns stdout/stderr.",
        "parameters": {"type": "object", "properties": {"code": {"type": "string"}}, "required": ["code"]},
    },
}]

with Sandbox(stack="python") as sb:
    resp = client.chat.completions.create(
        model="gpt-4o",
        tools=tools,
        messages=[{"role": "user", "content": "What is 17 factorial?"}],
    )
    for call in resp.choices[0].message.tool_calls or []:
        code = json.loads(call.function.arguments)["code"]
        out = sb.run(f"python3 -c {shlex.quote(code)}")
        print(out.stdout or out.stderr)
        # append a role:"tool" message with this output and call again

Tips for agent loops

  • One sandbox per session — reuse it across tool calls so the model can build on previous state (files, installed deps).
  • Always cap timeout — models write infinite loops.
  • Return stderr too — models self-correct better when they see the actual error.
  • Destroy on session endwith/try-finally so a crash doesn't leak a billing VM.

Next: Install packages the model's code depends on.