Cloudflare が Worker Previews を発表:AI が書いたすべての変更をクラウド上で直接実行・検証可能に
各 Git ブランチに安定した URL、独立した設定、実行ログを紐付けることで、Agent はコード生成からテスト、問題特定、修正までを一気通貫で完結できるようになります。重要なのは、どの状態が自動で分離され、どのリソースに個別設定が必要かを見極めることです。
AI は開発者がより多くのコードをコミットするのを支援しますが、コードが生成された後、それが実際のランタイム環境で意図通りに動作するかを確認する必要があります。変更が多ければ多いほど、検証すべき箇所も増加します。
最も厄介なのは、ローカル環境やステージング環境(Staging)では正常に動いていたものが、本番環境(Production)にデプロイした途端に異なる挙動を示すケースや、複数の Agent やチームメンバーが同一のテスト環境を共有した結果、データベースが乱雑に書き換えられて互いに競合してしまうケースです。
この課題を解決するため、Cloudflare は Worker Previews をリリースしました。Worker は Cloudflare のエッジネットワーク上で動作する軽量なアプリケーションであり、開発者が自ら基盤サーバーを管理する必要はありません。一方、Git ブランチはメインラインのコードから独立した開発用コピーであり、チームメンバーや Agent が互いに干渉することなく個別にコードを変更できるようにします。Worker Previews は、Git の「ブランチ分離」という概念を実行環境レイヤーへと拡張したものです。各 Git ブランチに対して、独立した URL、独立した設定、プレビュー単位で分離された Durable Objects およびコンテナ状態、そして独立したモニタリングを備えた、クラウド上で直接動作する検証用バージョン(プレビュー環境)を作成できます。人間も Agent もこの環境に対してリクエストを送信し、ページを確認し、エラーを監視した上で、コードを修正することが可能です。
コードブランチがあるのに、なぜ環境ブランチも必要なのか
従来のソフトウェア開発フローでは、まずローカルで単体テストを実施し、チーム共有のステージング環境(Staging)へプッシュし、最後に本番環境へリリースするのが一般的でした。しかし、AI コーディングの時代において、このワークフローには 2 つの課題が生じます。
- 共有テスト環境がボトルネック化する:複数の開発者や Agent が同時に変更をコミットする場合、全員が 1 つの Staging 環境を共有していると、ブランチごとのデータベース変更や設定更新が互いに衝突する恐れがあります。
- 単体コンポーネントのテストではシステム全体の挙動を再現できない:現代の複雑なアプリケーションの多くは、エッジランタイム(Cloudflare Workers など)、分散ストレージ、OAuth 認証、非同期キューに深く依存しています。ローカル環境でモックテスト(実サービスの代わりに模擬的な依存関係を使用するテスト)を行っても、実際のクラウド環境との差異を完全に再現することはできず、ローカルでは通過しても本番で異なる挙動を示す原因になります。
Cloudflare はこのようなプロセスを Agent 開発ライフサイクル(Agent Development Lifecycle, ADLC) と呼んでいます。これは、あらゆる変更を個別にデプロイ、観察、修正できる 1 つの単位として扱うアプローチです。
上図のように、隔離されたプレビュー環境を用意して Workers Builds を設定すれば、ブランチをプッシュするだけでクラウド上で変更を実行できます。テストが失敗した場合は開発段階へ直接フィードバックして修正でき、チームはテスト結果に基づいて本番メインラインへマージするかどうかを判断できます。
同一 Worker 内で、各ブランチが独自の実行環境を保持
これまで Cloudflare 上で複数環境のテストを行う場合、従来の「Wrangler environments」(環境ごとに独立した Worker をデプロイして管理する必要がある)を使用するか、従来のプレビュー URL(現在は Version URLs と改称。アップロードされた特定の Worker バージョンを指すものの、依然として本番リソースにアクセスする可能性がある)に依存する必要がありました。
Worker Previews は、これらの環境を同一の Worker 配下で一元管理できるようにします。1 つの Worker の下で、数百ものプレビュー環境を並行して稼働させることができます。
上図から分かるように、同一の my-worker プロジェクト内において:
- 本番環境(Production):メインブランチのコードを実行し、本番データベース(Cloudflare のデータベースである
D1:prodなど)にバインドされます。 - 通常の機能ブランチ(fix-button, new-feature など):プレビュー設定を自動的に継承し、共通のテスト用データベース(
D1:staging)を参照します。必要に応じてブランチ専用のオブジェクトストレージ(R2:feature-assets)を追加することも可能です。 - 破壊的変更ブランチ(d1-migration など):破壊的なテーブル定義の変更をテストするために、個別に設定を上書きして専用の一時テスト用データベース(
D1:migration-test)に向け直すことで、マイグレーションの影響を選択したテスト用 DB 内に限定できます。
設定の複製はデータベースの複製とは異なります:図に示されている通り、fix-button と new-feature の 2 つのブランチは設定上で同一の D1:staging テスト用データベースを共有しており、D1:migration-test を独立して参照しているのは破壊的変更ブランチのみです。これは、同一のテスト用 DB に接続しているブランチ間では、同時書き込みによる相互影響が発生し得ることを意味します。このようなストレージバインディングは開発者が要件に応じて明示的に設定するものであり、各ブランチ専用の D1 データベース、R2 バケット、KV ストレージの複製が自動生成されるわけではありません。
Cloudflare ダッシュボード(Dashboard)では、この切り替え操作が Git ブランチの切り替えと同じくらい直感的に行えるよう設計されています。
開発者やレビュアーは、上部のドロップダウンメニューから対象のブランチ(new-feature、d1-migration、fix-button など)を選択するだけで、そのブランチ専用のモニタリング、バインドされたリソース、実行状態を即座に確認できます。これにより、レビュー時に実行バージョン、設定、ログを正確に対応付けることが可能になります。
なぜ Durable Objects とコンテナ状態の分離が必要なのか
静的ウェブサイトやステートレスな API であれば、ブランチプレビューの実装はそれほど複雑ではありません。しかし、現代のアプリケーションはセッション、カウンター、履歴などの状態(State)を保持することが一般的です。Cloudflare のエコシステムにおいて、今回重点的にサポートされたステートフルコンポーネントは、Durable Objects(永続化オブジェクト、略称 DO)とエッジベースのコンテナ(Containers)です。
同一のオブジェクト ID が本番データと衝突するリスク
Durable Objects はグローバルシングルトンモデル(Singleton Model)を採用しています。端的に言えば、同一の名前空間(Namespace)内では、1 つのオブジェクト ID がそのオブジェクトおよびストレージを管理するアクティブなインスタンスに対応します。 もしプレビューブランチが分離なしに本番環境の DO 名前空間を共有してしまうと、プレビュー環境でのテスト書き込みが、実トラフィックを処理しているメモリ上のシングルトンを直接変更し、本番データに影響を与える恐れがあります。
Cloudflare の解決策:独立した名前空間の動的導出
現在では、npx wrangler preview を実行するだけで、Cloudflare の基盤がそのブランチ用に独立した Durable Object 名前空間とコンテナアプリケーション(Container application)をオンデマンドで自動生成します。
開発者はコード内で複雑な「環境判別ロジック」を記述する必要はなく、対象のクラスをエクスポートし、マイグレーション設定を追加した上で、ctx.exports 経由でアクセスするだけで済みます。以下は公式発表で示されたメカニズムの抜粋です(実際の利用では cloudflare:workers から DurableObject 基底クラスを明示的にインポートし、クラス内部に具体的な処理を実装した上で、設定ファイルにマイグレーションを定義する必要があります):
export class Counter extends DurableObject {}
export default {
async fetch(request, env, ctx) {
// ポイント: ctx.exports 経由で Counter を参照
const id = ctx.exports.Counter.idFromName("demo");
const counter = ctx.exports.Counter.get(id);
return counter.fetch(request);
},
};
同一コードがどのように異なる状態へアクセスするのか:
- このコードが本番環境で実行される場合、
ctx.exports.Counterは自動的に本番環境の Durable Object 名前空間へと解決されます。 - 同一コードがプレビューブランチで実行される場合、システムはそのブランチ専用のプレビュー名前空間へ透過的に解決先をリダイレクトします。
これにより、サンドボックスのコールドスタート最適化に取り組んでいるエンジニアは、隔離された環境下で各ブランチの初回起動時と起動後のレスポンス性能を並行して比較検証できます。
ベース設定が共通設定を担い、個別ブランチで上書き可能
開発におけるもう 1 つの課題は、ブランチを新規作成するたびに環境変数、シークレット、リソースバインディングを再設定する手間が発生することでした。
Worker Previews では Base Configuration(ベース設定) の概念が導入されました。Wrangler の設定ファイル(wrangler.json または wrangler.toml)内に previews ブロックを一度宣言するだけで対応できます:
{
"vars": {
"ENVIRONMENT": "production"
},
"r2_buckets": [
{
"binding": "UPLOADS",
"bucket_name": "prod-uploads"
}
],
"previews": {
"vars": {
"ENVIRONMENT": "preview"
},
"r2_buckets": [
{
"binding": "UPLOADS",
"bucket_name": "r2-staging"
}
]
}
}
上記の設定において:
- トップレベルの設定は本番環境用であり、
prod-uploadsバケットを使用します。 previewsブロック配下の内容はすべてのプレビューブランチ共通のベースとなり、デフォルトで変数をpreviewに切り替え、ファイルアップロード先をテスト専用のr2-stagingバケットへと誘導します。
ダッシュボードの Settings 画面では、本番環境の設定とプレビューのベース設定が並んで表示されます:
特定のブランチで特別な要件がある場合(例えば、新しいカウンターを開発中の add-new-websiter-counter ブランチで、追加のテスト用 KV ストレージが必要な場合など)は、その単一ブランチに対して設定の上書き(Override)を行うことができます:
この継承の仕組みにより、日常的な開発における手軽さと、複雑な変更検証時に求められる独立した柔軟性が両立されています。
Agent が画面上の問題をバックエンドリクエストまで追跡する方法
アクセス可能な URL とそれに対応する実行ログが揃って初めて、Agent はテスト、問題特定、コード修正、再テストの一連のサイクルを自律的に連携させることができます。
これまで AI Agent に Web サイトのテストを実行させる際、画面上にエラーが表示されても、背後にあるサーバーの実行ログが確認できないため、不具合の原因がフロントエンドにあるのかバックエンドにあるのかを判断しづらいという課題がありました。
Worker Previews のアーキテクチャでは、各ブランチに独立した Workers Observability(ログ、エラー、メトリクス、分散トレースを確認できる機能群) が備わっています:
MCP(Model Context Protocol:Agent がブラウザやログなどの外部ツールを呼び出すための標準プロトコル)を介して、以下のフローを連携させることができます:
- 自動デプロイとブラウザ操作の実行:Workers Builds と連携させることで、ブランチのプッシュ時に自動デプロイが行われます。また
npx wrangler previewを実行することも可能です。同一ブランチへの後続プッシュは同一の安定した URL を更新します。Agent は Playwright MCP 経由で Cloudflare Browser Run(クラウド型ヘッドレスブラウザ)を操作し、バックグラウンドで URL を開いて登録、ログイン、クリックなどの操作を順次実行し、DOM イベントの記録やスクリーンショット取得をリアルタイムで行います。 - エンドツーエンドの障害特定:ある操作が失敗した場合(ボタンをクリックしても反応がないなど)、Agent は Workers Observability MCP Server を直接呼び出して関連イベントやトレースを検索し、リクエスト内の fetch、バインディング操作、ハンドラー呼び出しなどを調査できます。
上記の公式デモでは、フロントエンド画面(Region: Earth)自体は正常にレンダリングされたものの、ランタイム監視によってバックエンドエンドポイントが 500 エラー(GET /api/observability/scenario?case=6)を返し、キャパシティルールの評価に失敗(preview_capacity_rule_failed)していることが検知されました。図中では、該当リージョンのユーザーが Dashboard の入口ボタンを正常に開けない可能性があるというユーザー影響も明示され、追跡調査用のデバッグ識別子 pr-5-wobs-15min-1788388576($metadata.error Exists フィルタと組み合わせて検索可能)が提示されています。これらの手がかりをもとに、Agent や開発者はさらに調査を進め、マージ前に Dashboard の入口ルーティングを再検証できます。
人間の判断が必要な局面では、レビュアーが Live View でブラウザ操作をリアルタイムに確認したり、Human in the Loop を通じて介入したりすることが可能です。
ログインと権限をエンドツーエンドのフローでテストする
テスト環境を本番環境により近づけるためには、避けて通れない 2 つのハードルがあります。それがクロスオリジン制約とログイン認証です。
現代の多くのアプリケーションは、外部アイデンティティプロバイダ(Google や GitHub アカウントによるログインなど)や厳格な Cookie / CORS ポリシーに深く依存しています。テスト環境が *.workers.dev のようなランダムなサブドメインでしか動かせない場合、サードパーティ製 OAuth のリダイレクト URI(Redirect URI)の許可リストを都度設定する必要があり、ログインフローの検証に支障をきたします。
この課題に対応するため、Worker Previews はカスタムドメイン(Custom Domains)へのバインドをサポートしています:
例えば本番サイトが example.com で稼働している場合、プレビューブランチを feature-login.previews.example.com にルーティングできます。このようなカスタムドメイン環境は本番構成に近づきますが、完全な検証を行うには、サードパーティのアイデンティティプロバイダ側で OAuth コールバックアドレス(Redirect URI)を適切に構成し、Cookie のスコープやクロスオリジンリソース共有(CORS)ポリシーを整合させる必要があります。また、未リリースのコードへの不正なアクセスを防ぐため、Cloudflare Access を設定して訪問者に事前のログインを要求することも可能です。
なぜ CloudflareOS は権限システムを含めて検証する必要があったのか
Cloudflare は本機能を一般公開する前に、社内オープンソースプロジェクトである CloudflareOS の開発とテストにこれを活用していました。 CloudflareOS の主な責務は、AI Agent を企業社内の Google、GitHub、Slack などの本番システムと安全に連携させることです。その中核モジュールが Gatekeepers(ゲートキーパー認可層)であり、Agent が呼び出せる権限範囲を厳格に制限する役割を担っています。
Gatekeeper モジュールのコードは権限管理に直結するため、変更には細心の注意が必要であり、わずかな論理的欠陥でも Agent が権限を逸脱して企業の機密データにアクセスしてしまうリスクがあります。また、マルチパーティの OAuth 認可リダイレクト、権限承認フロー、アプリケーションのリアルタイムな状態が絡み合う複雑なロジックは、個々のコンポーネントを単体でテストするだけではシステム全体の振る舞いを証明できません。 Cloudflare チームが取ったアプローチはまさに、Gatekeeper に対する変更のたびに独立した Worker Preview を立ち上げ、承認・認証プロセスを一貫して実行し、失敗があれば修正して再テストを行ってからマージするというものでした。
公式発表では、先行ユーザーからの声も紹介されています:
- Supermemory 創業者 Dhravya Shah 氏:Durable Objects の呼び出しを含む HTTP フローのテストに Worker Previews を使用しており、開発速度を落とすことなく、より早い段階で不具合を検知できていると述べています。
- Ramp シニアエンジニア Dylan Garcia 氏:プレビュー環境が常にオンラインであるため、自身の Agent(Inspect)が生成した PR プレビューの挙動を、モバイル端末から直接確認・検証できると共有しています。
まだプレビュー環境内に自動で閉じ込められない呼び出し
Worker Previews は、すべてのリソースや呼び出しパスを現時点で自動分離できているわけではありません。公式に公表されている既知の制限事項と今後のロードマップは以下の通りです:
- Worker 間呼び出し(Service Bindings)の完全分離は未対応:
- 現在の状況:プレビューブランチ内の Worker が Service Binding 経由で連携先の別 Worker を呼び出す場合、デフォルトでは依然として対象 Worker の本番デプロイメントへとリクエストが送信されます。
- 今後の方向性:呼び出し元と呼び出し先でプレビュー環境同士をマッチングさせ、呼び出しチェーン全体を対応するプレビュー環境内に留めるルーティング機能を開発中です。
- 非同期キューおよびワークフローのコンシューマ分離:
- 現在の状況:プレビュー環境から Queues(キュー)へのメッセージ送信はサポートされていますが、メッセージの消費(コンシューマ処理)は行えません。また、Workflows の実行を分離するには個別設定が必要です。
- 今後の方向性:メッセージキューや非同期ワークフローを含む非同期パイプライン全体を、ブランチのスコープ内に完全に閉じ込められるよう開発を進めています。
- 長期間持続する環境(Long-lived Previews)のサポート:
- 複数の開発イテレーションにまたがって長期運用される固定のステージング環境や QA 環境向けに、Cloudflare は長期利用を前提としたプレビューサポートの設計を進めています。
