−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. Кроме того, на аккаунте одновременно выполняются только две команды, так что разогнавшийся цикл не размножится.

Есть ли у сгенерированного кода доступ в интернет?

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

Комментарии

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

Оставить комментарий

Комментарии проходят модерацию перед публикацией.