−25%

на річну оплату Windows, до 31.10. До тарифів

EQVPS
Почати

Перше завдання агента в пісочниці: LLM пише код, мікро-VM його виконує

Зберіть мінімальний корисний цикл виконання коду ШІ: модель пише Python-скрипт, пісочниця на Firecracker його запускає, помилки повертаються моделі, доки скрипт не запрацює. Близько 40 рядків, плюс те саме завдання через MCP зовсім без коду.

Агент, який пише код, корисний лише тоді, коли щось безпечно виконує цей код і повідомляє результат. Цей посібник збирає такий цикл повністю: модель пише Python-скрипт, пісочниця його запускає, а якщо він падає, помилка повертається моделі. Потім те саме завдання без жодного рядка коду, через MCP.

Потрібні Python 3.8+, токен акаунта EQVPS (див. підключення акаунта) і API-ключ моделі.

1. Спершу поставте ліміт витрат

Агент створює пісочниці сам, тож до старту дайте йому стелю. Двох доларів на день і двадцяти на місяць для експериментів вистачить із запасом:

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

Коли ліміт досягнуто, нові пісочниці отримують 429 budget_exceeded, а працюючі тимчасові видаляються. Подробиці — у розділі ліміти й оплата пісочниць.

2. Встановіть дві бібліотеки

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

У прикладі використано одного провайдера моделей, але ніщо від нього не залежить. З моделлю спілкується лише функція ask().

3. Цикл «написати — запустити — виправити»

Збережіть це як 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."},
        ]

Запустіть:

python3 agent.py

Зазвичай вивід — attempt 1: exit code 0, а потім 78498. Якщо перший скрипт упаде, ви побачите другу спробу з виправленою помилкою.

Що робить кожна частина:

  • Sandbox.create(..., idle_timeout=120) запускає мікро-VM приблизно за секунду. Якщо ваш скрипт помре на півдорозі, пісочниця однаково видалить себе після 2 хвилин бездіяльності.
  • sb.run(code, timeout=55) виконує код і повертає код повернення, stdout і stderr. Падіння коду — звичайний результат, а не виняток, тож цикл може показати його моделі.
  • r.stderr[-3000:] надсилає лише кінець помилки. Повний traceback великого скрипта може марно з'їсти багато контексту моделі.
  • Три спроби — свідома межа. Якщо модель не виправила скрипт за три рази, зазвичай їй потрібен кращий опис завдання, а не четверта спроба.

4. Коли завданню потрібно більше 55 секунд

Синхронний виклик триває не більше 55 секунд. Довгу роботу запускайте у фоні й чекайте:

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

Завдання продовжує працювати, навіть якщо ваш wait уперся в таймаут, і до нього можна повернутися через sb.task(task_id).

5. Те саме завдання через MCP, без коду

Якщо ви працюєте в MCP-клієнті на кшталт Claude Desktop чи Cursor із MCP-сервером EQVPS, агент уже має інструменти для пісочниць: create_sandbox, run_code, exec_command, upload_file, download_file і kill_sandbox. Вистачить промпту:

Створи невелику тимчасову пісочницю. Напиши Python-скрипт, який рахує прості числа менші за 1 000 000, запусти його там, виправ, якщо впаде, скажи мені результат і видали пісочницю.

Агент зробить ті самі виклики, що й скрипт вище. Які інструменти безпечно дозволяти без підтвердження, розібрано в розділі захист MCP.

Скільки це коштувало

Пісочниця прожила помітно менше хвилини, і за неї списано мінімум у 60 секунд: $0.00055 на small. Виклик моделі коштує дорожче за пісочницю. Пробного $1 нового акаунта вистачить приблизно на 1 800 таких запусків.

Куди далі

Часті питання

Чому б просто не запускати код моделі на своїй машині?

Бо ви не знаєте, що він зробить. Згенерований код може видалити файли, прочитати ваші ключі або піти в нескінченний цикл. У пісочниці він виконується в окремій мікро-VM із власним ядром, а потім пісочниця видаляється.

Чи працює це з іншими моделями, не лише з прикладу?

Так. Циклу потрібна лише функція, яка приймає повідомлення й повертає текст. Замініть функцію ask() на будь-який чат-API, зокрема на локальну модель.

Що завадить агенту створювати пісочниці нескінченно?

Перед стартом поставте денний і місячний ліміт витрат. Коли ліміт досягнуто, нові пісочниці відхиляються з 429 budget_exceeded. Крім того, на акаунті одночасно виконуються лише дві команди, тож розігнаний цикл не розмножиться.

Чи має згенерований код доступ в інтернет?

Так, пісочниці мають вихідний доступ в інтернет, щоб код міг ставити пакети й завантажувати дані. Вхідних портів немає. Не кладіть секрети в промпт чи код; ті, що справді потрібні скрипту, передавайте змінними оточення.

Коментарі

Поки немає коментарів. Будьте першим.

Залишити коментар

Коментарі проходять модерацію перед публікацією.