−25%

na Windows przy płatności rocznej, do 31.10. Do planów

EQVPS
Zacznij

Pierwsze zadanie agenta w sandboxie: LLM pisze kod, mikro-VM go wykonuje

Zbuduj najmniejszą użyteczną pętlę wykonywania kodu przez AI: model pisze skrypt w Pythonie, sandbox na Firecrackerze go uruchamia, a błędy wracają do modelu, aż skrypt zadziała. Około 40 linijek plus to samo zadanie przez MCP zupełnie bez kodu.

Agent, który pisze kod, jest przydatny tylko wtedy, gdy coś bezpiecznie wykona ten kod i zwróci wynik. Ten poradnik buduje taką pętlę w całości: model pisze skrypt w Pythonie, sandbox go uruchamia, a jeśli skrypt się wysypie, błąd wraca do modelu. Potem to samo zadanie bez pisania kodu, przez MCP.

Potrzebujesz Pythona 3.8+, tokenu konta EQVPS (zob. łączenie konta) i klucza API do modelu.

1. Najpierw ustaw limit wydatków

Agent tworzy sandboxy sam, więc przed startem daj mu sufit. Dwa dolary dziennie i dwadzieścia miesięcznie z nawiązką wystarczą do eksperymentów:

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}'

Po osiągnięciu limitu nowe sandboxy dostają 429 budget_exceeded, a działające tymczasowe są usuwane. Szczegóły w limitach i rozliczeniach sandboxów.

2. Zainstaluj dwie biblioteki

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

Przykład używa jednego dostawcy modeli, ale nic od niego nie zależy. Z modelem rozmawia tylko funkcja ask().

3. Pętla napisz, uruchom, popraw

Zapisz to jako 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."},
        ]

Uruchom:

python3 agent.py

Typowy przebieg wypisuje attempt 1: exit code 0, a potem 78498. Jeśli pierwszy skrypt się wysypie, zobaczysz drugą próbę z poprawionym błędem.

Co robi każda część:

  • Sandbox.create(..., idle_timeout=120) uruchamia mikro-VM w około sekundę. Jeśli twój skrypt umrze w połowie, sandbox i tak usunie się sam po 2 minutach bezczynności.
  • sb.run(code, timeout=55) wykonuje kod i zwraca kod wyjścia, stdout i stderr. Wysypanie się kodu to zwykły wynik, nie wyjątek, więc pętla może pokazać go modelowi.
  • r.stderr[-3000:] wysyła tylko końcówkę błędu. Pełny traceback dużego skryptu może zmarnować sporo kontekstu modelu.
  • Trzy próby to celowy limit. Model, który nie naprawił skryptu w trzech podejściach, zwykle potrzebuje lepszego opisu zadania, a nie czwartej próby.

4. Gdy zadanie potrzebuje więcej niż 55 sekund

Wywołanie synchroniczne trwa najwyżej 55 sekund. Dłuższą pracę uruchom w tle i poczekaj:

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

Zadanie działa dalej, nawet jeśli twój wait przekroczy limit czasu, i możesz do niego wrócić przez sb.task(task_id).

5. To samo zadanie przez MCP, bez kodu

Jeśli korzystasz z klienta MCP, takiego jak Claude Desktop czy Cursor, z serwerem MCP EQVPS, agent ma już narzędzia do sandboxów: create_sandbox, run_code, exec_command, upload_file, download_file i kill_sandbox. Wystarczy prompt:

Utwórz mały tymczasowy sandbox. Napisz skrypt w Pythonie, który liczy liczby pierwsze mniejsze od 1 000 000, uruchom go tam, popraw, jeśli się wysypie, podaj mi wynik i usuń sandbox.

Agent wykona te same wywołania co skrypt powyżej. Które narzędzia można bezpiecznie zezwolić bez potwierdzenia, omówiono w zabezpieczeniach MCP.

Ile to kosztowało

Sandbox żył znacznie krócej niż minutę i został rozliczony za minimum 60 sekund: 0,00055 $ na small. Wywołanie modelu kosztuje więcej niż sandbox. Próbny 1 $ nowego konta wystarczy na około 1800 takich uruchomień.

Co dalej

FAQ

Dlaczego po prostu nie uruchomić kodu modelu na własnej maszynie?

Bo nie wiesz, co zrobi. Wygenerowany kod może usunąć pliki, odczytać twoje klucze albo wpaść w nieskończoną pętlę. W sandboxie działa w osobnej mikro-VM z własnym jądrem, a potem sandbox jest usuwany.

Czy to działa z innymi modelami niż w przykładzie?

Tak. Pętla potrzebuje tylko funkcji, która przyjmuje wiadomości i zwraca tekst. Podmień funkcję ask() na dowolne API czatu, także na model lokalny.

Co powstrzyma agenta przed tworzeniem sandboxów bez końca?

Przed startem ustaw dzienny i miesięczny limit wydatków. Po jego osiągnięciu nowe sandboxy są odrzucane z 429 budget_exceeded. Poza tym na jednym koncie działają naraz tylko dwa polecenia, więc rozpędzona pętla się nie rozmnoży.

Czy wygenerowany kod ma dostęp do internetu?

Tak, sandboxy mają wychodzący dostęp do internetu, żeby kod mógł instalować pakiety i pobierać dane. Nie mają portów przychodzących. Nie wkładaj sekretów do promptu ani kodu; te, których skrypt naprawdę potrzebuje, przekazuj jako zmienne środowiskowe.

Komentarze

Brak komentarzy. Bądź pierwszy.

Zostaw komentarz

Komentarze są moderowane przed pojawieniem się.