−25%

op Windows bij jaarbetaling, tot 31/10. Naar de pakketten

EQVPS
Aan de slag

Je eerste agenttaak in een sandbox: een LLM schrijft code, een microVM voert hem uit

Bouw de kleinste nuttige lus voor AI-code-uitvoering: een model schrijft een Python-script, een Firecracker-sandbox draait het, fouten gaan terug naar het model tot het script werkt. Zo'n 40 regels, plus dezelfde taak via MCP zonder enige code.

Een agent die code schrijft, is alleen nuttig als iets die code veilig uitvoert en het resultaat terugmeldt. Deze handleiding bouwt die lus van begin tot eind: een model schrijft een Python-script, een sandbox draait het, en als het faalt, gaat de fout terug naar het model. Daarna dezelfde taak zonder een regel code, via MCP.

Je hebt Python 3.8+, een EQVPS-accounttoken (zie je account koppelen) en een API-sleutel voor een model nodig.

1. Stel eerst een uitgavenlimiet in

Een agent maakt zelf sandboxes aan, dus geef hem vooraf een plafond. Twee dollar per dag en twintig per maand is ruim genoeg om te experimenteren:

curl -X PUT https://api.eqvps.com/api/v1/eqvps/sandboxes/budget \
  -H "Authorization: Bearer $EQVPS_API_KEY" -H "Content-Type: application/json" \
  -d '{"daily_usd": 2, "monthly_usd": 20}'

Is een limiet bereikt, dan krijgen nieuwe sandboxes 429 budget_exceeded en worden draaiende tijdelijke sandboxes verwijderd. Details staan in sandbox-limieten en facturering.

2. Installeer de twee bibliotheken

pip install eqvps anthropic
export EQVPS_API_KEY="your-eqvps-token"
export ANTHROPIC_API_KEY="your-model-key"

Het voorbeeld gebruikt één modelaanbieder, maar niets hangt ervan af. Alleen de functie ask() praat met het model.

3. De lus schrijven, draaien, herstellen

Sla dit op als agent.py:

import re
import anthropic
from eqvps import Sandbox

TASK = "Count the prime numbers below 1,000,000 and print only the number."
client = anthropic.Anthropic()

def ask(messages):
    msg = client.messages.create(model="claude-sonnet-5", max_tokens=2000, messages=messages)
    return msg.content[0].text

def extract_code(text):
    m = re.search(r"`{3}(?:python)?\n(.*?)`{3}", text, re.S)
    return m.group(1) if m else text

messages = [{"role": "user", "content": "Write a Python 3 script for this task. "
             "Reply with a single code block and nothing else.\n\nTask: " + TASK}]

with Sandbox.create(tariff="small", idle_timeout=120) as sb:
    for attempt in range(1, 4):
        reply = ask(messages)
        r = sb.run(extract_code(reply), timeout=55)
        print(f"attempt {attempt}: exit code {r.exit_code}")
        if r.ok:
            print(r.stdout.strip())
            break
        messages += [
            {"role": "assistant", "content": reply},
            {"role": "user", "content": f"The script failed with exit code {r.exit_code}.\n"
             f"stderr:\n{r.stderr[-3000:]}\nFix it. Reply with a single code block."},
        ]

Draai het:

python3 agent.py

Een typische run print attempt 1: exit code 0 en daarna 78498. Faalt het eerste script, dan zie je de tweede poging met de fout hersteld.

Wat elk onderdeel doet:

  • Sandbox.create(..., idle_timeout=120) start een microVM in ongeveer een seconde. Sterft je script halverwege, dan verwijdert de sandbox zichzelf toch na 2 minuten inactiviteit.
  • sb.run(code, timeout=55) voert de code uit en geeft exitcode, stdout en stderr terug. Een crash in de code is een normaal resultaat, geen exception, dus de lus kan hem aan het model laten zien.
  • r.stderr[-3000:] stuurt alleen het einde van de fout. Een volledige traceback van een groot script kan veel context van het model verspillen.
  • Drie pogingen is een bewuste grens. Een model dat een script in drie pogingen niet heeft gerepareerd, heeft meestal een betere taakomschrijving nodig, geen vierde poging.

4. Als de taak meer dan 55 seconden nodig heeft

Een synchrone aanroep duurt hooguit 55 seconden. Start langer werk op de achtergrond en wacht:

task = sb.run(code, background=True)
result = task.wait(timeout=1800)

De taak draait door, ook als je wait in een timeout loopt, en je kunt hem weer oppakken met sb.task(task_id).

5. Dezelfde taak via MCP, zonder code

Gebruik je een MCP-client zoals Claude Desktop of Cursor met de MCP-server van EQVPS, dan heeft de agent de sandboxtools al: create_sandbox, run_code, exec_command, upload_file, download_file en kill_sandbox. Een prompt volstaat:

Maak een kleine tijdelijke sandbox. Schrijf een Python-script dat de priemgetallen onder 1.000.000 telt, draai het daar, herstel het als het faalt, vertel me het resultaat en verwijder de sandbox.

De agent doet dezelfde aanroepen als het script hierboven. Welke tools je zonder bevestiging kunt toestaan, staat in MCP-vangrails.

Wat het kostte

De sandbox leefde ruim korter dan een minuut en werd afgerekend tegen het minimum van 60 seconden: $0.00055 op small. De modelaanroep kost meer dan de sandbox. Het proeftegoed van $1 van een nieuw account dekt ongeveer 1.800 van zulke runs.

Waar verder

FAQ

Waarom draai ik de code van het model niet gewoon op mijn eigen machine?

Omdat je niet weet wat hij doet. Gegenereerde code kan bestanden wissen, je sleutels lezen of eindeloos blijven lopen. In een sandbox draait hij in een aparte microVM met een eigen kernel, en daarna wordt de sandbox verwijderd.

Werkt dit ook met andere modellen dan in het voorbeeld?

Ja. De lus heeft alleen een functie nodig die berichten aanneemt en tekst teruggeeft. Vervang ask() door een willekeurige chat-API, ook een lokaal model.

Wat houdt een agent tegen om eindeloos sandboxes aan te maken?

Stel vooraf een dag- en maandlimiet in. Is die bereikt, dan worden nieuwe sandboxes geweigerd met 429 budget_exceeded. Bovendien draaien per account maar twee commando's tegelijk, dus een op hol geslagen lus kan zich niet vermenigvuldigen.

Kan de gegenereerde code het internet op?

Ja, sandboxes hebben uitgaand internet zodat code pakketten kan installeren en data kan ophalen. Ze hebben geen inkomende poorten. Zet geen geheimen in de prompt of de code; geef de geheimen die een script echt nodig heeft mee als omgevingsvariabelen.

Reacties

Nog geen reacties. Wees de eerste.

Laat een reactie achter

Reacties worden gemodereerd voordat ze verschijnen.