4月13日、Cloudflareが「Durable Objects in Dynamic Workers: Give each AI-generated app its own database」と題した記事を公開した。この記事では、AIが生成したアプリケーションに独自のデータベースを持たせる新機能「Durable Object Facets」について詳しく紹介されている。以下に、その内容を紹介する。
AIが生成するアプリの持続性という課題
数週間前にCloudflareが発表したDynamic Workersは、Workerコードをオンザフライでセキュアサンドボックスに読み込む機能だ。従来の用途では、AIエージェントが生成した使い捨てのコードを実行することに焦点が当てられていた。
しかし、AIがより持続的なアプリケーションを生成する場合はどうだろうか。カスタムUIを持ち、ユーザーが対話でき、長期保存される状態を持つアプリケーションをAIに構築させたい場合、従来のDynamic Workersだけでは限界があった。
Durable Objectsという解決策の可能性
WorkersプラットフォームにはDurable Objectsという高速ストレージ機能がある。これは一意の名前を持つ特別なWorkerで、グローバルに名前ごとに1つのインスタンスしか存在しない。各インスタンスにはSQLiteデータベースが接続され、これがDurable Objectが実行されるマシンのローカルディスクに存在する。そのため、ストレージアクセスは極めて高速で、ほぼ遅延ゼロを実現している。
しかし、通常のDurable Objectsの利用には複雑な設定プロセスが必要だ:
DurableObjectを継承するクラスを作成- Workerのメインモジュールからエクスポート
- Wranglerの設定でストレージを準備
- Durable Object名前空間バインディングを宣言
これらの手順はDynamic Workersには適用できない。さらに根本的な問題として、エージェントやユーザーに無制限のストレージ利用を許可すべきかという懸念もある。
新機能:Durable Object Facets
この問題を解決するため、CloudflareはDurable Object Facetsをオープンベータで提供開始した。

Facetsの仕組みは以下の通りだ:
- 通常のDurable Object名前空間を作成し、開発者が書いたクラスを指定
- そのクラス内で、エージェントのコードをDynamic Workerとして読み込み、呼び出す
- Dynamic Workerのコードは
extends DurableObjectで宣言されたクラスを直接実装・エクスポート可能 - そのクラスを自分のDurable Objectの「ファセット」としてインスタンス化
- ファセットは独自のSQLiteデータベースを取得し、通常のDurable Object storage APIを使用可能
実装例:シンプルなアプリプラットフォーム
以下は、Durable Objectクラスを動的に読み込み実行するアプリプラットフォームの完全な実装例だ:
import { DurableObject } from "cloudflare:workers";
// AIが生成するコードの例(実際には動的に生成される)
const AGENT_CODE = `
import { DurableObject } from "cloudflare:workers";
// 呼び出し回数を記憶するシンプルなアプリ
export class App extends DurableObject {
fetch(request) {
let counter = this.ctx.storage.kv.get("counter") || 0;
++counter;
this.ctx.storage.kv.put("counter", counter);
return new Response("You've made " + counter + " requests.\\n");
}
}
`;
// AppRunnerは動的アプリケーションの読み込みと
// リクエスト配信を担当するDurable Object
export class AppRunner extends DurableObject {
async fetch(request) {
// "app"という名前の子ファセットを取得
let facet = this.ctx.facets.get("app", async () => {
// ファセットがまだ開始されていない場合の処理
let worker = this.#loadDynamicWorker();
let appClass = worker.getDurableObjectClass("App");
return { class: appClass };
});
// ファセットにリクエストを転送
return await facet.fetch(request);
}
// アプリの動的コードを設定するRPCメソッド
setCode(code) {
this.ctx.storage.kv.put("codeId", crypto.randomUUID());
this.ctx.storage.kv.put("code", code);
}
#loadDynamicWorker() {
let codeId = this.ctx.storage.kv.get("codeId");
return this.env.LOADER.get(codeId, async () => {
let code = this.ctx.storage.kv.get("code");
return {
compatibilityDate: "2026-04-01",
mainModule: "worker.js",
modules: { "worker.js": code },
globalOutbound: null, // ネットワークアクセスをブロック
}
});
}
}
この実装では、AppRunnerの各インスタンスが2つのSQLiteデータベースを持つ1つのDurable Objectとして構成される。親(AppRunner自体)用と、ファセット(App)用のデータベースが分離され、アプリケーションは自分のデータベースのみにアクセス可能だ。
業界への影響
Durable Object Facetsは、AIが生成するアプリケーションの実行環境に新たな可能性をもたらす。従来は一時的な処理に限定されがちだったAI生成コードに、持続的な状態管理と高速なローカルストレージを組み合わせることで、より実用的なアプリケーション開発が可能になる。
特に注目すべきは、開発者が監督者(supervisor)として適切な制御を維持しながら、AIに柔軟なアプリケーション構築を委ねられる点だ。ログ記録、メトリクス、課金制御などの「運用ロジック」を保持しつつ、創造的な部分をAIに任せるという役割分担が実現される。
FacetsはDynamic Workersの機能として、Workers有料プランユーザー向けにベータ版で即座に利用可能だ。
詳細はDurable Objects in Dynamic Workers: Give each AI-generated app its own databaseを参照していただきたい。