SandboxesEjecutar Python

API de intérprete de código para código generado por LLM

Un intérprete de código ejecuta el código que escribe un modelo de lenguaje y le devuelve la salida al modelo. En Lizard (lizard.build), CodeSandbox de Lizard SDK lo hace dentro de un sandbox, una microVM de Firecracker, así que el código se ejecuta aparte de tu app y de tu máquina. Arranca la plantilla interpreter, que incluye Python y bibliotecas de datos habituales. Python se ejecuta en un kernel de Jupyter que conserva las variables entre llamadas, y cada resultado incluye la salida impresa, el valor de la última expresión, los gráficos como image/png y cualquier error con su traceback.

Ejecutar código con estado

import { CodeSandbox } from '@lizard-build/sdk';
 
const sandbox = await CodeSandbox.create({ projectId: 'proj_123', timeoutMs: 300_000 });
try {
  await sandbox.runCode('import pandas as pd\ndf = pd.DataFrame({"x": [1, 2, 3]})');
  const run = await sandbox.runCode('df.x.sum()');
  console.log(run.results[0]?.data); // "6"
  const bad = await sandbox.runCode('1/0');
  console.log(bad.error?.name); // "ZeroDivisionError"
} finally {
  await sandbox.kill();
}
from lizard import CodeSandbox
 
with CodeSandbox.create(project_id="proj_123", timeout_ms=300_000) as sandbox:
    sandbox.run_code('import pandas as pd\ndf = pd.DataFrame({"x": [1, 2, 3]})')
    run = sandbox.run_code("df.x.sum()")
    print(run.results[0].data)  # "6"
    print(sandbox.run_code("1/0").error.name)  # "ZeroDivisionError"

Un error del código forma parte del resultado, no es una excepción. Los fallos de la solicitud, como una clave de API incorrecta, sí lanzan una excepción.

¿Qué devuelve runCode?

runCode (Python: run_code) devuelve un Execution:

CampoContenido
stdout, stderrTodo lo que imprimió el código
resultsSalida enriquecida: el valor de la última expresión como text/plain, gráficos de matplotlib e imágenes como image/png en base64, HTML y otros tipos, cada uno con mime y data
errorname, message y traceback cuando el código lanzó una excepción
executionCountEl contador de celdas del kernel (Python: execution_count)

Pasa onStdout, onStderr, onResult u onError (Python: on_stdout, etc.) para recibir la salida mientras se ejecuta el código.

Úsalo como herramienta de un LLM

Dale al modelo una herramienta, por ejemplo run_python con un único argumento de texto code. Cuando el modelo la llame, ejecuta el código en el sandbox y devuelve el texto como resultado de la herramienta. Usa un mismo sandbox durante toda la conversación para que las variables del modelo se conserven entre llamadas.

import { CodeSandbox } from '@lizard-build/sdk';
 
const sandbox = await CodeSandbox.create({ projectId: 'proj_123', timeoutMs: 600_000 });
 
// Call this when the model asks to run Python. Return the text to send back to it.
async function runPython(code: string): Promise<string> {
  const run = await sandbox.runCode(code, { timeoutMs: 30_000 });
  if (run.error) return `${run.error.name}: ${run.error.message}\n${run.error.traceback}`;
  const values = run.results.flatMap((r) =>
    r.type === 'result' && r.mime === 'text/plain' ? [r.data] : [],
  );
  return [run.stdout, ...values].filter(Boolean).join('\n');
}
 
// When the conversation ends:
await sandbox.kill();
from lizard import CodeSandbox
 
sandbox = CodeSandbox.create(project_id="proj_123", timeout_ms=600_000)
 
def run_python(code: str) -> str:
    """Call this when the model asks to run Python. Return the text to send back to it."""
    run = sandbox.run_code(code, timeout_ms=30_000)
    if run.error:
        return f"{run.error.name}: {run.error.message}\n{run.error.traceback}"
    values = [r.data for r in run.results if r.mime == "text/plain"]
    return "\n".join(filter(None, [run.stdout, *values]))
 
# When the conversation ends:
sandbox.kill()

Aquí la duración del sandbox es de diez minutos. Auméntala para conversaciones más largas con setTimeout (Python: set_timeout), o establece timeoutMs: 0 y detén el sandbox tú mismo.

Gráficos

Cuando el código dibuja un gráfico de matplotlib, results contiene un elemento con mime igual a image/png y la imagen en base64 en data:

import base64
from pathlib import Path
 
run = sandbox.run_code("import matplotlib.pyplot as plt\nplt.plot([1, 4, 9])\nplt.show()")
png = next(r.data for r in run.results if r.mime == "image/png")
Path("chart.png").write_bytes(base64.b64decode(png))

Contextos, tiempos de espera y lenguajes

  • Contextos. createContext() (Python: create_context()) inicia un kernel aparte con sus propias variables y su propio directorio de trabajo; pásalo como context a runCode. listContexts(), restartContext(ctx) y deleteContext(ctx) los gestionan. Sin un contexto, cada lenguaje usa su propio contexto predeterminado.
  • Tiempos de espera. timeoutMs (Python: timeout_ms) limita una llamada y por defecto es de 60 segundos. Un kernel de Python que lo supera se interrumpe y conserva su estado; el error.name del resultado es TimeoutError.
  • Otros lenguajes. JavaScript y bash se ejecutan como un proceso nuevo en cada llamada, así que no se conserva el estado y results queda vacío. JavaScript necesita node, que la plantilla interpreter no incluye.
  • Pausa y snapshots. Los kernels se ejecutan dentro del sandbox, así que pause() y resume() conservan sus variables, y snapshot() y fork() las copian.

Ejecutar comandos

process.exec inicia un proceso distinto para cada comando, por lo que las variables de Python no persisten entre llamadas. Úsalo para pasos de shell como pip install, y guarda en archivos los resultados que necesites después. Consulta ejecutar un comando y la referencia del SDK.

Código no confiable

Trata todo lo que escribe el modelo como no confiable. No pases lizardToken a menos que el código necesite Lizard CLI; cualquier proceso del sandbox puede leerlo, así que, si lo pasas, usa una clave limitada al workspace. Mantén otros secretos fuera de envs. Un sandbox que usa un volumen basado en pods comparte el kernel del host; consulta runtime y plantillas.

Almacenamiento y facturación

Las variables y los archivos duran solo lo que dura el sandbox. Las reglas de facturación y almacenamiento están en almacenamiento y facturación; los tamaños y precios, en límites.

Descripción general de Sandboxes · Inicio rápido · Referencia del SDK · Persistent Volumes · Página de Sandboxes

Actualizado