−25%

no Windows com pagamento anual, até 31/10. Ver planos

EQVPS
Começar

Sua primeira tarefa de agente numa sandbox: um LLM escreve o código, uma microVM executa

Monte o menor loop útil de execução de código por IA: um modelo escreve um script Python, uma sandbox Firecracker o executa, e os erros voltam ao modelo até o script funcionar. Cerca de 40 linhas, mais a mesma tarefa via MCP sem código nenhum.

Um agente que escreve código só é útil se algo executar esse código com segurança e devolver o resultado. Este guia monta esse loop do começo ao fim: um modelo escreve um script Python, uma sandbox o executa e, se falhar, o erro volta ao modelo. Depois, a mesma tarefa sem escrever código, via MCP.

Você precisa do Python 3.8+, de um token de conta EQVPS (veja conectar sua conta) e de uma chave de API de um modelo.

1. Defina antes um limite de gasto

Um agente cria sandboxes por conta própria, então dê a ele um teto antes de começar. Dois dólares por dia e vinte por mês sobram para experimentos:

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

Quando um limite é atingido, novas sandboxes recebem 429 budget_exceeded e as efêmeras em execução são apagadas. Os detalhes estão em limites e cobrança de sandboxes.

2. Instale as duas bibliotecas

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

O exemplo usa um provedor de modelos, mas nada depende dele. Só a função ask() conversa com o modelo.

3. O loop escrever, rodar, corrigir

Salve isto 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."},
        ]

Rode:

python3 agent.py

Uma execução típica imprime attempt 1: exit code 0 e depois 78498. Se o primeiro script falhar, você verá a segunda tentativa com o erro corrigido.

O que cada parte faz:

  • Sandbox.create(..., idle_timeout=120) inicia uma microVM em cerca de um segundo. Se seu script morrer no meio, a sandbox se apaga sozinha após 2 minutos ociosa de qualquer jeito.
  • sb.run(code, timeout=55) executa o código e devolve código de saída, stdout e stderr. Uma falha no código é um resultado normal, não uma exceção, então o loop pode mostrá-la ao modelo.
  • r.stderr[-3000:] envia só o final do erro. Um traceback completo de um script grande pode desperdiçar muito contexto do modelo.
  • Três tentativas é um limite proposital. Um modelo que não consertou um script em três tentativas geralmente precisa de uma descrição melhor da tarefa, não de uma quarta tentativa.

4. Quando a tarefa precisa de mais de 55 segundos

Uma chamada síncrona dura no máximo 55 segundos. Para trabalhos mais longos, rode em segundo plano e espere:

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

A tarefa continua rodando mesmo se o seu wait estourar o tempo, e você pode retomá-la com sb.task(task_id).

5. A mesma tarefa via MCP, sem código

Se você usa um cliente MCP como Claude Desktop ou Cursor com o servidor MCP da EQVPS, o agente já tem as ferramentas de sandbox: create_sandbox, run_code, exec_command, upload_file, download_file e kill_sandbox. Basta um prompt:

Crie uma sandbox efêmera pequena. Escreva um script Python que conte os números primos menores que 1.000.000, rode lá, corrija se falhar, me diga o resultado e apague a sandbox.

O agente faz as mesmas chamadas que o script acima. Quais ferramentas liberar sem confirmação está explicado em proteções do MCP.

Quanto custou

A sandbox viveu bem menos de um minuto e foi cobrada pelo mínimo de 60 segundos: US$ 0,00055 na small. A chamada ao modelo custa mais que a sandbox. O crédito de teste de US$ 1 de uma conta nova cobre cerca de 1.800 execuções como esta.

Para onde ir agora

Perguntas frequentes

Por que não rodar o código do modelo direto na minha máquina?

Porque você não sabe o que ele vai fazer. Código gerado pode apagar arquivos, ler suas chaves ou entrar em loop infinito. Numa sandbox ele roda numa microVM separada, com kernel próprio, e a sandbox é apagada depois.

Funciona com outros modelos além do exemplo?

Sim. O loop só precisa de uma função que receba mensagens e devolva texto. Troque a função ask() por qualquer API de chat, inclusive um modelo local.

O que impede um agente de criar sandboxes sem parar?

Defina um limite de gasto diário e mensal antes de começar. Quando ele é atingido, novas sandboxes são recusadas com 429 budget_exceeded. Além disso, só dois comandos rodam ao mesmo tempo por conta, então um loop desgovernado não se multiplica.

O código gerado consegue acessar a internet?

Sim, as sandboxes têm acesso de saída à internet para o código instalar pacotes e baixar dados. Não há portas de entrada. Não coloque segredos no prompt nem no código; passe os que um script realmente precisa como variáveis de ambiente.

Comentários

Nenhum comentário ainda. Seja o primeiro.

Deixe um comentário

Os comentários são moderados antes de aparecerem.