SandboxesЗапуск Python

API интерпретатора кода в Lizard Sandboxes

Lizard Sandboxes запускают код LLM в microVM Firecracker, каждая со своим ядром. Это руководство описывает API CodeSandbox в Lizard SDK: @lizard-build/sdk для TypeScript и JavaScript и lizard-sdk для Python. Примеры ниже создают sandbox в Lizard и возвращают его вывод вашему агенту.

CodeSandbox изолирует код от вашего приложения и компьютера. Он запускает шаблон interpreter с Python и основными библиотеками для работы с данными. Python работает в ядре Jupyter, которое сохраняет переменные между вызовами, а каждый результат содержит напечатанный вывод, значение последнего выражения, графики в формате image/png и ошибку с трассировкой, если она возникла.

Запуск кода с сохранением состояния

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); // "np.int64(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)  # "np.int64(6)"
    print(sandbox.run_code("1/0").error.name)  # "ZeroDivisionError"

Ошибка в коде возвращается в результате, а не вызывает исключение в SDK. Сбои запроса, например неверный API-ключ, выбрасывают исключение.

Что возвращает runCode?

runCode (в Python: run_code) возвращает Execution:

ПолеСодержимое
stdout, stderrВсё, что напечатал код
resultsРасширенный вывод: значение последнего выражения, графики matplotlib и изображения, каждый с mime и data
errorname, message и traceback, если код выбросил исключение
executionCountСчётчик ячеек ядра (в Python: execution_count)

Каждый результат содержит один тип MIME — самый полный из тех, что есть у вывода, в таком порядке: image/png, image/jpeg, image/svg+xml, text/html, text/markdown, application/json, text/latex, text/plain. Изображения приходят в base64. Число возвращается как text/plain, а DataFrame из pandas — только как text/html.

Передайте onStdout, onStderr, onResult или onError (в Python: on_stdout и т. д.), чтобы получать вывод, пока код выполняется.

Использование как инструмента LLM

Дайте модели один инструмент, например run_python с единственным строковым аргументом code. Когда модель вызывает его, выполните код в sandbox и отправьте текст обратно как результат инструмента. Пример сохраняет каждый текстовый результат, включая HTML, поэтому модель получает и DataFrame. Держите один sandbox на весь диалог, чтобы переменные модели сохранялись между вызовами.

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.startsWith('text/') ? [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.startswith("text/")]
    return "\n".join(filter(None, [run.stdout, *values]))
 
# When the conversation ends:
sandbox.kill()

В этом примере sandbox работает десять минут. Для более длинных диалогов увеличьте срок через setTimeout (в Python: set_timeout) или задайте timeoutMs: 0 и останавливайте sandbox сами.

Графики

Когда код рисует график matplotlib, в results появляется элемент с mime, равным image/png, и изображением в base64 в 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))

Контексты, таймауты и языки

  • Контексты. createContext() (в Python: create_context()) запускает отдельное ядро со своими переменными и рабочей папкой; передайте его как context в runCode. listContexts(), restartContext(ctx) и deleteContext(ctx) управляют контекстами. Без контекста каждый язык использует свой контекст по умолчанию.
  • Таймауты. timeoutMs (в Python: timeout_ms) ограничивает один вызов, по умолчанию 60 секунд. Ядро Python, которое работает дольше, прерывается и сохраняет состояние; error.name в результате равно TimeoutError.
  • Другие языки. JavaScript и bash выполняются как новый процесс при каждом вызове, поэтому состояние не сохраняется, а results остаётся пустым. JavaScript работает на Node 22 из шаблона, в котором нет npm.
  • Пауза и снимки. Ядра работают внутри sandbox, поэтому pause() и resume() сохраняют их переменные, а snapshot() и fork() их копируют.

Запуск команд

process.exec создаёт отдельный процесс для каждой команды, поэтому переменные Python между вызовами не сохраняются. Используйте его для команд оболочки, например pip install, а результаты, которые понадобятся позже, сохраняйте в файлы. См. запуск команды и справочник SDK.

Недоверенный код

Считайте недоверенным всё, что пишет модель. Не передавайте lizardToken, если коду не нужен Lizard CLI. Если передадите, sandbox получит новый ключ, который ограничен его проектом и удаляется вместе с sandbox, поэтому код в нём сможет менять этот проект. Не кладите другие секреты в envs.

Хранение и оплата

Переменные и файлы доступны, только пока работает sandbox. Правила оплаты и хранения смотрите в разделе хранение и оплата; размеры и цены смотрите в лимитах.

Обзор Sandboxes · Быстрый старт · Справочник SDK · Persistent Volumes · Страница продукта Sandboxes

Обновлено