pimenov.ai

База знаний

@cloudflare/computer — долговечная файловая система и среды исполнения для ИИ-агента

Практическое руководство по @cloudflare/computer: Workspace в Durable Object, среды исполнения, Git, тесты, безопасность и проверяемый аудит.

Опубликовано Обновлено

@cloudflare/computer — ранняя предварительная версия Cloudflare для создания долговечной рабочей среды ИИ-агента. Материал показывает, как выбрать среду выполнения, подключить контейнер и проверить обратную синхронизацию файлов.

⚠️
Статус на 8 сентября 2026 года: пакет предназначен для экспериментов, исследования и прототипов. API нестабилен, а дизайн продолжает меняться. Для воспроизводимой работы фиксируйте версию пакета или commit SHA и сверяйте код с документацией той же версии.
💡
Workspace — виртуальная рабочая папка агента. Её файловая система хранится на базе SQLite внутри Durable Object.

Что это такое

@cloudflare/computer объединяет виртуальную файловую систему на базе SQLite с инструментами чтения, записи, редактирования файлов, shell-командами и Git. Workspace создаётся внутри Durable Object, а выполнение маршрутизируется к изоляту или Linux-контейнеру.

На высоком уровне анонс Cloudflare описывает два класса исполнения: быстрый изолят и полноценный контейнер. Текущая документация runtime показывает три именованных backend, поэтому ниже они разобраны отдельно.

Основные возможности: рабочая среда агента

Обычному агенту для работы с кодом недостаточно цикла рассуждений и текстовых ответов. Ему нужны файлы, Git, команды терминала, зависимости и средство запуска проверок.

@cloudflare/computer добавляет общий Workspace между агентом и средами выполнения:

graph TD
    A["ИИ-агент"] --> B["Файловые инструменты и exec"]
    B --> C["Workspace в Durable Object"]
    C --> D["Файловая система на базе SQLite"]
    C --> E["worker-shell"]
    C --> F["worker-javascript"]
    C --> G["container-shell"]
    G <-->|"FUSE и синхронизация"| D

Файлы Workspace остаются авторитетным состоянием. worker-shell использует хранилище на стороне хоста и не требует отдельного обмена файлами. JavaScript-модули обращаются к Workspace через возможности хоста. Контейнер держит собственную виртуальную файловую систему. Перед запуском команды изменения передаются в контейнер, после выполнения они синхронизируются обратно. При сбое обратной синхронизации сама команда может остаться завершённой, но sync.status будет pending.

FUSE — механизм, через который контейнер видит подключённое файловое дерево. Для контейнерных команд последовательность выглядит так:

push → spawn → events/result → pull

Это позволяет файловому инструменту записать документ в Workspace, контейнеру прочитать его через FUSE, создать артефакт и вернуть его в долговечное хранилище.

Кому подходит пакет

Пакет полезен:

  • командам, которые прототипируют собственную среду для агента, работающего с кодом;
  • агентам с небольшим долговечным рабочим набором файлов;
  • задачам, где лёгкие операции нужно отделить от команд, требующих полноценного Linux;
  • экспериментам с генерацией файлов и последующей обработкой в контейнере.

Пакет пока не следует использовать как готовую платформу для промышленной эксплуатации с SLA. Если рабочее дерево большое или операции интенсивные, заранее проведите собственный нагрузочный эксперимент: переданные источники не задают универсального лимита производительности.

Три среды выполнения (backend) и правила выбора

Workspace предоставляет единый маршрутизатор выполнения workspace.runtime.exec(). Параметр backend определяет, как интерпретируется переданный исходный текст.

Среда выполненияПодходящие задачиОсобенности
worker-shellGit, поиск, простая обработка текста и файловИспользует just-bash в Dynamic Workers, возвращает буферизованный результат и не предоставляет полноценный пользовательский слой Linux (userland)
worker-javascriptСтруктурированная обработка данных и выполнение JavaScript-модулейМожет обращаться к Workspace через node:fs/promises и возвращать структурированное значение
container-shellПакетные менеджеры, сборка, тесты и нативные бинарникиЗапускает команды в Linux-контейнере и синхронизирует изменения до и после выполнения

Примеры явной маршрутизации:

const search = await workspace.runtime.exec("grep -R TODO .", {
  backend: "worker-shell",
  cwd: "/workspace",
  encoding: "utf8",
});

const tests = await workspace.runtime.exec("npm test", {
  backend: "container-shell",
  cwd: "/workspace/repo",
  encoding: "utf8",
});

const moduleRun = await workspace.runtime.exec(
  `
import fs from "node:fs/promises";
export default async () =>
  fs.readFile("/workspace/package.json", "utf8");
`,
  { backend: "worker-javascript" },
);

Если backend не указан, runtime выбирает первый настроенный backend. Поэтому порядок конфигурации влияет на поведение по умолчанию.

🔴
Выбор backend задаёт маршрут выполнения, но не проверяет права. Сервер должен проверять это значение по собственной allowlist-политике.

Файловые инструменты и выполнение команд

Официальный changelog перечисляет совместимые с AI SDK инструменты read, write, edit, ls и exec.

ИнструментНазначение
readЧтение файлов Workspace
lsПросмотр содержимого каталога
writeСоздание или полная запись файла
editТочечное изменение существующего файла
execПередача исходного текста выбранному backend

Для чтения и точечного изменения проекта предпочтительнее специализированные файловые инструменты. Shell полезен для Git и существующих команд проекта, а контейнер — для зависимостей, тестовых раннеров и нативного окружения.

Пакет устанавливается командой:

npm install @cloudflare/computer

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

Что возвращает маршрутизатор выполнения

Вызов workspace.runtime.exec() возвращает дескриптор выполнения. Итог получают через result():

const handle = await workspace.runtime.exec("npm test", {
  backend: "container-shell",
  cwd: "/workspace/repo",
  encoding: "utf8",
  timeoutMs: 120_000,
});

const result = await handle.result();

Результат содержит:

  • status: completed, failed или cancelled;
  • exitCode;
  • stdout и stderr;
  • value для backend, возвращающих структурированное значение;
  • счётчики pushed и pulled;
  • пропущенные записи skipped;
  • состояние синхронизации sync.

Командные backend не заполняют value. worker-javascript использует это поле для структурированного результата модуля и сообщает завершённую синхронизацию без записей.

Успешный exitCode: 0 ещё не гарантирует, что созданные контейнером файлы уже попали обратно в Workspace. Команда может завершиться, а обратная синхронизация перейти в sync.status: "pending". Приложение должно проверять оба результата и настраивать повтор синхронизации, если артефакты критичны.

Дескриптор рассчитан на одного потребителя: используйте либо result(), либо поток событий. Не пытайтесь одновременно читать оба представления одной операции.

Подключение контейнера

Актуальный официальный пошаговый пример показывает интеграцию с @cloudflare/think. Durable Object владеет контейнерным backend, а Workspace подключает его как среду исполнения:

import {
  CloudflareContainerBackend,
  withWorkspaceContainer,
} from "@cloudflare/computer/backends/container";
import { Think } from "@cloudflare/think";
import {
  type DurableObjectStorageLike,
  type ThinkWorkspaceCompatibility,
  Workspace,
} from "@cloudflare/computer";

class RecipeBase extends Think {}

export class RecipeAgent extends withWorkspaceContainer(RecipeBase) {
  readonly #backend = new CloudflareContainerBackend({
    container: () => this,
    workspace: {
      binding: "RecipeAgent",
      id: this.ctx.id.toString(),
    },
    egress: { mode: "direct" },
  });

  override workspace = new Workspace({
    storage: this.ctx.storage as unknown as DurableObjectStorageLike,
    backends: [this.#backend],
    useThink: true,
  }) as Workspace & ThinkWorkspaceCompatibility;

  override async fetch(request: Request): Promise<Response> {
    return new URL(request.url).pathname === "/api"
      ? this.#backend.handleFetch(request)
      : super.fetch(request);
  }
}

В примере режим direct сохраняет исходящий доступ в Интернет. Если командам контейнера сеть не нужна, используйте { mode: "none" }.

Связка withWorkspaceContainer добавляет в Think жизненный цикл контейнера. Пара workspace: { binding, id } указывает контейнеру на Durable Object, поэтому маршрут /api нужно передать обработчику backend до вызова базового класса.

В полном пошаговом примере entrypoint также экспортирует основной обработчик, класс RecipeAgent и WorkspaceProxy. Имя класса должно совпадать с именем Durable Object binding и записью контейнера, а WorkspaceProxy должен присутствовать в графе модулей runtime.

Для кода этого примера устанавливают зависимости:

npm install @cloudflare/computer @cloudflare/think agents ai zod

Контейнерный образ запускает computerd как PID 1 и монтирует Workspace в каталог, заданный через MOUNT_POINT. Для локального режима нужен запущенный Docker.

Проверка результата: минимальный сценарий

Официальный пошаговый пример строит агента, который записывает Markdown в Workspace, преобразует его в PDF через pandoc внутри контейнера и публикует готовый файл из того же Workspace.

Для проверки самой файловой связки:

  1. Создайте /workspace/hello.txt инструментом write, передав значение hello.
  2. Запустите в container-shell команду, которая читает файл и создаёт копию.
  3. Дождитесь результата команды через result().
  4. Проверьте status, exitCode, stderr и sync.status.
  5. Прочитайте созданную копию через файловый API Workspace.
const handle = await workspace.runtime.exec(
  "cp hello.txt hello-copy.txt && cat hello-copy.txt",
  {
    backend: "container-shell",
    cwd: "/workspace",
    encoding: "utf8",
  },
);

const result = await handle.result();

Признаки успеха:

  • result.status === "completed";
  • result.exitCode === 0;
  • stdout содержит hello;
  • stderr не содержит сообщения об ошибке;
  • result.sync.status === "complete";
  • /workspace/hello-copy.txt доступен через файловый API после завершения команды.

Если команда успешна, но sync.status равен pending, проверка созданного артефакта ещё не завершена.

📌
Материал основан на официальной документации и snapshots, полученных 8 сентября 2026 года. Описанный сценарий при подготовке материала локально не запускался.

Практический сценарий: исправление ошибки в репозитории

Рабочий процесс агента для работы с кодом удобно разделить на пять этапов:

  1. Подготовить репозиторий.
  2. Прочитать инструкции проекта и определить стек.
  3. Найти связанный с задачей код.
  4. Внести минимальную правку.
  5. Запустить существующие проверки и сохранить фактические результаты.

Пример контракта для агента:

Работайте только внутри /workspace.

Перед изменениями:
1. Прочитайте AGENTS.md, README и манифесты проекта.
2. Определите package manager по lock-файлу.
3. Покажите исходный git status.
4. Найдите код и тесты, относящиеся к задаче.

Во время работы:
1. Используйте файловые инструменты для чтения и точечных изменений.
2. Используйте worker-shell для Git и лёгкого поиска.
3. Используйте container-shell для установки зависимостей, сборки и тестов.
4. Не открывайте секреты, .env и файлы учётных данных.
5. Не выполняйте push и не создавайте pull request.

В конце:
1. Выполните git diff --check.
2. Запустите только проверки, определённые проектом.
3. Покажите git status и итоговый diff.
4. Верните команды, backend, exit code, stdout, stderr и sync status.

Не придумывайте команды проверки. Сначала изучите package.json, lock-файл, Makefile, документацию и конфигурацию CI. Для npm-проекта список скриптов можно посмотреть через npm run, но запускать следует только относящиеся к задаче команды.

Проверяемый журнал действий

Cloudflare описывает операции Workspace как gated, audited and observed. Прикладной журнал должен формироваться из реальных вызовов инструментов и их результатов.

Файл ACTION_LOG.md, который пишет сам агент, полезен как человеко-читаемая сводка, но не является доказательством. Модель может пропустить операцию, ошибиться в пересказе или изменить этот файл.

Для аудита приложение должно сохранять во внешнем для агента журнале только добавляемые записи:

  • время операции;
  • имя инструмента и backend;
  • команду или тип файлового действия;
  • идентификатор выполнения;
  • status и exitCode;
  • stdout и stderr с безопасными ограничениями объёма;
  • результат синхронизации;
  • список изменённых артефактов.
💡
ACTION_LOG.md и REPORT.md помогают человеку прочитать итог. Источником истины для аудита остаётся журнал, который приложение строит из фактических вызовов и не разрешает агенту изменять.

Полезные сценарии

ЗадачаУсловие и действиеНаблюдаемый результатОграничение
Изучить репозиторий без сборкиРепозиторий уже находится в Workspace. Используйте read, ls, grep и worker-shell для поиска и Git.Получите список файлов, найденные связи и результаты команд.worker-shell не заменяет полный Linux.
Исправить TypeScript-проектЕсть исходники, lock-файл и определённая проектом проверка. Проанализируйте файлы, внесите точечную правку, затем запустите проверку в container-shell.Получите минимальный diff, exitCode: 0 и вывод тестового раннера.Нужно отдельно контролировать зависимости, сеть и синхронизацию.
Обработать JSON в JavaScript-модулеJSON-файл уже записан в Workspace. Запустите worker-javascript с обращением к файлу через разрешённые возможности хоста.Получите структурированное значение в value или новый файл Workspace.Доступны только возможности, разрешённые модульной средой.
Создать PDF или другой бинарный артефактMarkdown-файл находится в Workspace. Запустите pandoc или другую подходящую команду в container-shell и дождитесь result().Файл возвращается из контейнера в Workspace; sync.status показывает complete.Нужно проверить обратную синхронизацию, а не только код завершения.

Ограничения и безопасность

  • exec принимает исходный текст. Командные среды интерпретируют его как shell-синтаксис, поэтому подключайте инструмент только там, где он действительно нужен.
  • Проверяйте backend по серверной allowlist. Описание инструмента для модели не создаёт границу безопасности.
  • Не помещайте в Workspace секреты, которые не требуются задаче.
  • Выдавайте Git-токены без права push, если агенту достаточно чтения.
  • Настраивайте сетевой доступ отдельно. В официальном примере для контейнера показаны режимы direct и none, а инструменту получения данных задан allowlist хоста.
  • Считайте вывод команд недоверенным текстом до его повторной передачи модели или отображения пользователю.
  • Проверяйте status, exitCode, stderr и состояние синхронизации.
  • Не повторяйте автоматически команду после неопределённого транспортного сбоя: она могла успеть запуститься до разрыва соединения.
  • Для длительных и отсоединённых процессов учитывайте различия жизненного цикла. worker-shell сохраняет одновызовное буферизованное поведение и не поддерживает последующее подключение к выполнению; контейнерный и JavaScript-backend предоставляют более развитое управление выполнениями.
  • Фиксируйте версию или commit SHA: предварительный API, конфигурация и набор инструментов могут измениться.
📌
Используйте Workspace для ограниченного рабочего набора: исходников задачи, инструкций, промежуточных файлов и проверяемых артефактов. Производительность большого репозитория и тяжёлых операций ввода-вывода проверяйте отдельным нагрузочным экспериментом.

Официальные ссылки


Следующий шаг

Связанные материалы

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

Если захотите обсудить, как это применить у себя или в команде — пишите в Telegram @pimenov