−25%

en Windows con pago anual, hasta el 31/10. Ver planes

EQVPS
Empezar

Tu primera tarea de agente en una sandbox: un LLM escribe el código, una microVM lo ejecuta

Construye el bucle útil más pequeño de ejecución de código con IA: un modelo escribe un script de Python, una sandbox Firecracker lo ejecuta y los errores vuelven al modelo hasta que el script funciona. Unas 40 líneas, más la misma tarea por MCP sin código.

Un agente que escribe código solo es útil si algo ejecuta ese código con seguridad e informa del resultado. Esta guía construye ese bucle de principio a fin: un modelo escribe un script de Python, una sandbox lo ejecuta y, si falla, el error vuelve al modelo. Después, la misma tarea sin escribir código, por MCP.

Necesitas Python 3.8+, un token de cuenta de EQVPS (ver conectar tu cuenta) y una clave de API de un modelo.

1. Fija primero un tope de gasto

Un agente crea sandboxes por su cuenta, así que dale un techo antes de empezar. Dos dólares al día y veinte al mes sobran para experimentar:

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

Cuando se alcanza un tope, las sandboxes nuevas reciben 429 budget_exceeded y las efímeras en marcha se borran. Los detalles están en límites y facturación de sandboxes.

2. Instala las dos bibliotecas

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

El ejemplo usa un proveedor de modelos, pero nada depende de él. Solo la función ask() habla con el modelo.

3. El bucle escribir, ejecutar, corregir

Guarda esto como 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."},
        ]

Ejecútalo:

python3 agent.py

Una ejecución típica imprime attempt 1: exit code 0 y luego 78498. Si el primer script falla, verás el segundo intento con el error corregido.

Qué hace cada parte:

  • Sandbox.create(..., idle_timeout=120) arranca una microVM en un segundo. Si tu script muere a mitad, la sandbox se borra sola igualmente tras 2 minutos de inactividad.
  • sb.run(code, timeout=55) ejecuta el código y devuelve el código de salida, stdout y stderr. Un fallo en el código es un resultado normal, no una excepción, así que el bucle puede mostrárselo al modelo.
  • r.stderr[-3000:] envía solo el final del error. Un traceback completo de un script grande puede desperdiciar mucho contexto del modelo.
  • Tres intentos es un límite deliberado. Un modelo que no ha arreglado un script en tres intentos suele necesitar una mejor descripción de la tarea, no un cuarto intento.

4. Cuando la tarea necesita más de 55 segundos

Una llamada síncrona dura como máximo 55 segundos. Para trabajos más largos, lánzalos en segundo plano y espera:

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

La tarea sigue corriendo aunque tu wait agote su tiempo, y puedes retomarla con sb.task(task_id).

5. La misma tarea por MCP, sin código

Si usas un cliente MCP como Claude Desktop o Cursor con el servidor MCP de EQVPS, el agente ya tiene las herramientas de sandbox: create_sandbox, run_code, exec_command, upload_file, download_file y kill_sandbox. Basta con un prompt:

Crea una sandbox efímera pequeña. Escribe un script de Python que cuente los números primos menores que 1.000.000, ejecútalo ahí, corrígelo si falla, dime el resultado y borra la sandbox.

El agente hace las mismas llamadas que el script de arriba. Qué herramientas conviene permitir sin confirmación se explica en salvaguardas de MCP.

Lo que costó

La sandbox vivió bastante menos de un minuto y se facturó con el mínimo de 60 segundos: 0,00055 $ en small. La llamada al modelo cuesta más que la sandbox. El crédito de prueba de 1 $ de una cuenta nueva cubre unas 1.800 ejecuciones como esta.

Adónde seguir

Preguntas frecuentes

¿Por qué no ejecutar sin más el código del modelo en mi máquina?

Porque no sabes qué hará. El código generado puede borrar archivos, leer tus claves o entrar en un bucle infinito. En una sandbox se ejecuta en una microVM aparte con su propio kernel, y la sandbox se borra después.

¿Funciona con otros modelos además del del ejemplo?

Sí. El bucle solo necesita una función que reciba mensajes y devuelva texto. Cambia la función ask() por cualquier API de chat, incluido un modelo local.

¿Qué impide que un agente cree sandboxes sin fin?

Fija un tope de gasto diario y mensual antes de empezar. Al alcanzarlo, las sandboxes nuevas se rechazan con 429 budget_exceeded. Además, por cuenta solo se ejecutan dos comandos a la vez, así que un bucle desbocado no puede multiplicarse.

¿Puede el código generado acceder a Internet?

Sí, las sandboxes tienen acceso saliente a Internet para que el código pueda instalar paquetes y descargar datos. No tienen puertos de entrada. No pongas secretos en el prompt ni en el código; pasa los que un script realmente necesite como variables de entorno.

Comentarios

Aún no hay comentarios. Sé el primero.

Deja un comentario

Los comentarios se moderan antes de aparecer.