MODULE_04 · УРОК 4.4

Cloud-реализация

Local — бесплатно и быстро. Memory — бесплатно и безопаснее для репо. Cloud — ни то ни другое: VM где-то в дата-центре, сеть на каждый read_file, деньги за минуты, жёсткий таймаут. Код провайдера меняется быстрее курса — разберём форму, не live API.

ЧТО ПОЛУЧИТСЯ Понимание, как выглядел бы create_cloud_sandbox, зачем на интерфейсе опциональные expires_at и snapshot, и когда cloud лучше local/memory.

Слова, которые встретятся

  • Cloud sandbox — удалённая VM с настоящим git, npm/pyproject, сетью. Изоляция полная, latency — тоже.
  • expires_at — «умрёшь в HH:MM». Harness может успеть сохранить состояние.
  • snapshot — снимок диска VM; новая VM стартует с того же места (модуль 7).

Урок без сборки

Файлы проекта ученика не меняем. Читаем, отвечаем на вопросы внизу. Если хотите код — набросок в блоке ниже, не обязательный.

Как выглядел бы cloud-бэкенд

sandbox_cloud.py — иллюстрация, не запускаем

import time
from dataclasses import dataclass
from typing import Any

from sandbox import ExecResult


@dataclass
class CloudSandbox:
    type: str
    working_directory: str
    expires_at: int
    _vm: Any  # клиент провайдера: Vercel Sandbox, E2B, свой k8s pod…

    async def read_file(self, path: str) -> str:
        # сеть: десятки–сотни ms на вызов
        return await self._vm.read_file(f"{self.working_directory}/{path}")

    async def exec(self, command: str) -> ExecResult:
        result = await self._vm.run(command, cwd=self.working_directory)
        return {
            "stdout": result.stdout + result.stderr,
            "exit_code": result.exit_code,
        }

    async def stop(self) -> None:
        await self._vm.close()

    async def snapshot(self) -> dict[str, str]:
        snap = await self._vm.snapshot()
        return {"snapshot_id": snap.id}


async def create_cloud_sandbox(config: dict) -> CloudSandbox:
    vm = await ProviderSandbox.create(config)
    return CloudSandbox(
        type="cloud",
        working_directory="/workspace",
        expires_at=int(time.time()) + 30 * 60,
        _vm=vm,
    )

Форма та же, что у local и memory. Tools не меняются — меняется только то, что за exec.

Таблица tradeoffs

local memory cloud
Цена00за минуту
Latencyмикросекундымикросекундысеть на каждый вызов
Изоляциянеткопия / overlayотдельная VM
После stopфайлы на местеtmp удалёнsnapshot или всё пропало
Таймаутнетнетчасто 30–60 мин

Когда что брать

  • local — разработка, доверенная машина, отладка harness.
  • memory — «пусть покопается», ревью чужого кода, страшные промпты.
  • cloud — CI, несколько пользователей, прод, полная изоляция.
ЗАЧЕМ ОПЦИОНАЛЬНЫЕ ПОЛЯ НА ИНТЕРФЕЙСЕ Local не «истекает» и не снапшотится — и не должен притворяться. Cloud без expires_at — сюрприз на 29-й минуте. Опциональность = каждый бэкенд честно говорит, что умеет.

Проверьте (без кода)

  1. Два reason, почему read_file в cloud медленнее local.
  2. Одно предложение: зачем expires_at optional.
  3. Когда вы бы выбрали cloud вместо memory для coding-агента?

Пример ответа на (1): round-trip по сети; сериализация на стороне VM. На (2): local/memory не имеют TTL — поле не применимо.

Готово, если:

  • Можете объяснить latency cloud vs local
  • Понимаете роль expires_at и snapshot
  • Можете назвать сценарий «cloud, не local»
  • Знаете, что tools при смене бэкенда не переписывают
ХОТИТЕ ПОДКЛЮЧИТЬ ЖИВОЙ CLOUD Смотрите Vercel Sandbox или аналог (E2B, Modal, Fly Machines). Методы мапятся на наш Sandbox один в один — провайдер меняет только _vm.