Skip to content

Scoped Sandbox

A ScopedSandbox lets you serve specific functions via RPC for an agent to use instead of giving the agent full access.

When to use

  • Sandbox — agent has full notebook access, good for exploration
  • ScopedSandbox — agent can only call functions you expose, good for controlled experiments

Writing interface files

An interface file defines what GPU functions the agent can call.

# interface.py
from transformers import AutoModel, AutoTokenizer
import torch

model_path = get_model_path("google/gemma-2-9b")  # injected
model = AutoModel.from_pretrained(model_path, device_map="auto")
tokenizer = AutoTokenizer.from_pretrained(model_path)

@expose
def get_embedding(text: str) -> dict:
    inputs = tokenizer(text, return_tensors="pt").to(model.device)
    with torch.no_grad():
        outputs = model(**inputs, output_hidden_states=True)
    embedding = outputs.hidden_states[-1].mean(dim=1).squeeze()
    return {"embedding": embedding.tolist()}

Rules: - @expose marks functions the agent can call - Must return JSON-serializable types (use .tolist() for tensors) - get_model_path() is injected — returns cached model path - Load models at module level, not inside functions

Serving the interface

scoped = ScopedSandbox(SandboxConfig(
    gpu="A100",
    models=[ModelConfig(name="google/gemma-2-9b")],
)).start()

model_tools = scoped.serve(
    "interface.py",
    expose_as="library",  # or "mcp"
    name="model_tools"
)

expose_as options: - "library" — agent imports it: import model_tools - "mcp" — agent sees functions as MCP tools

Using with local session

workspace = Workspace(libraries=[model_tools])
session = create_local_session(workspace, workspace_dir)

async for msg in run_agent(prompt, mcp_config={}):
    pass

The agent runs locally. When it calls model_tools.*, the call goes to the GPU via RPC.