技術 約9分で読めます

Cloudflare Agents Week 2026のProject Think・Browser Run刷新・Workflows v2

いけさん目次

Cloudflare Agents Week 2026の3日目(4月15日)に発表された3本。

発表概要
Project ThinkAgents SDKの上に乗るエージェントフレームワーク層
Browser RunBrowser Renderingの改称+AIエージェント向け機能の大幅追加
Workflows v2コントロールプレーン再設計でコンカレント11倍

1日目・2日目の発表は Sandboxes GA・Durable Object Facets・統合CLIMesh・エンタープライズMCP参照アーキテクチャ を参照。

Project Think

Cloudflareが「Project Think」として、次世代のAgents SDKプレビューを発表した。既存の agents パッケージが「軽量プリミティブ集」だったのに対し、Project Thinkは思考・行動・永続化まで一貫して扱う「batteries-included」なプラットフォームを目指している。

エージェントの3つのウェーブ

発表記事ではAIエージェントの進化を3つのウェーブとして整理している。

Wave世代特徴
1チャットボットステートレス、リアクティブ
2コーディングエージェントステートフル、ツール使用。Claude Code、Cursorなど
3インフラとしてのエージェント耐障害、分散、サーバーレス

コーディングエージェントが普及したことで、「LLMを1回呼ぶチャットボット」と「自律的に数十分動き続けるエージェント」の間に設計上の断絶が生じている。
LLM呼び出し1回で30秒、マルチターンのエージェントループなら数分〜数十分。
その間にプロセスがクラッシュしたら? 状態をどこに保存する? 複数サブタスクの並行実行は?
Project ThinkはこうしたWave 3の課題に応えるフレームワークだ。

Fibers(耐障害実行)

「クラッシュしても途中から再開できる関数」の仕組み。runFiber() を呼ぶと関数の呼び出し情報がSQLiteに記録されてから実行が始まる。実行中に ctx.stash() でチェックポイントを保存でき、クラッシュ後の再起動時に onFiberRecovered が呼ばれる。

async startResearch(topic: string) {
  void this.runFiber("research", async (ctx) => {
    const findings = [];
    for (let i = 0; i < 10; i++) {
      const result = await this.callLLM(`Research step ${i}: ${topic}`);
      findings.push(result);
      ctx.stash({ findings, step: i, topic }); // チェックポイント保存
      this.broadcast({ type: "progress", step: i });
    }
    return { findings };
  });
}

async onFiberRecovered(ctx) {
  if (ctx.name === "research" && ctx.snapshot) {
    const { topic } = ctx.snapshot;
    await this.startResearch(topic); // 前回のtopicで再開
  }
}

Fiber実行中はSDKがエージェントを自動的に生かし続ける(keepAlive() 相当)。
動画生成やCIパイプラインのような長時間処理では、エージェントがジョブIDを永続化して一旦ハイバネートし、コールバックで再起動するパターンも使える。

サブエージェント

子Durable Objectを親エージェントと同居させ、それぞれ独立したSQLiteと型付きRPCを持たせる仕組み。Durable Object Facetsの上に実装されている。

export class Orchestrator extends Agent {
  async handleTask(task: string) {
    const researcher = await this.subAgent(ResearchAgent, "research");
    const reviewer = await this.subAgent(ReviewAgent, "review");

    const [research, review] = await Promise.all([
      researcher.search(task),
      reviewer.analyze(task)
    ]);

    return this.synthesize(research, review);
  }
}

各サブエージェントは独立した会話ツリーとツールセットを持つ。RPCはストリーミングコールバック付きで呼べるため、子エージェントの出力をリアルタイムで親に流すことができる。

Session API(会話の永続化)

実験的APIで、会話履歴をツリー構造で保管する。親子関係(parent_id)を持つメッセージで構成され、以下の操作が非破壊的に行える。

操作内容
フォーキング途中から別のアプローチを試す。元の会話は消えない
コンパクション古いメッセージを削除せず要約に置き換えてコンテキストを節約
全文検索SQLite FTS5 により会話履歴全体を検索できる
import { Session, SessionManager } from "agents/experimental/memory/session";

export class MyAgent extends Agent {
  sessions = SessionManager.create(this);

  async onStart() {
    const session = this.sessions.create("main");
    const forked = this.sessions.fork(session.id, messageId, "alternative-approach");
  }
}

FTS5を使った search_context ツールによって、エージェントが自分自身の過去の会話を検索できる。

サンドボックスコード実行(実行ラダー)

エージェントが使えるコード実行能力を5段階で定義している。

Tier名称提供される能力使用技術
0Workspaceファイル読み書き・grep・diff@cloudflare/shell + SQLite + R2
1Dynamic WorkerサンドボックスJS実行(ネットワークなし)V8 isolate, @cloudflare/codemode
2npm Runtimenpmパッケージをランタイムに解決@cloudflare/worker-bundler + esbuild
3Headless Browserナビゲート・クリック・スクリーンショットCloudflare Browser Run
4SandboxフルOS(git、コンパイラ、テストランナー)Cloudflare Sandbox

「Tier 0だけでも実用になるよう設計し、各Tierは加算的に追加する」という設計原則が明記されている。Dynamic Worker(Tier 1)のV8 isolateはコンテナより約100倍高速に起動する。

従来のツール呼び出し方式では、エージェントが1エンドポイントにつき1ツールを逐次呼んでいた。代わりにプログラム全体を書いてDynamic Workerで実行すれば、トークン消費を大幅に削減できる。Cloudflareはこれを「99.9%の削減」と述べている。

Self-authored extensions(自己拡張)

エージェントが自分自身のツールをTypeScriptで書き、JSONマニフェストで権限を宣言してDynamic Workerにバンドルする仕組み。

{
  "name": "github",
  "description": "GitHub integration: PRs, issues, repos",
  "tools": ["create_pr", "list_issues", "review_pr"],
  "permissions": {
    "network": ["api.github.com"],
    "workspace": "read-write"
  }
}

デフォルトで globalOutbound: null(ネットワーク接続なし)から始まり、リソースごとに明示的に権限を付与する。Cloudflareはこれを「振る舞いの制約ではなく能力モデルによる構造的セキュリティ」と表現している。拡張はDurable Objectストレージに永続化され、ハイバネーションをまたいで生存する。

Thinkベースクラス

Project Thinkの目玉は @cloudflare/think パッケージが提供するThinkクラスだ。チャットのライフサイクル全体(ストリーミング、永続化、ツール実行、ストリーム再開)を管理するopinionatedなハーネスで、最小実装は getModel() をオーバーライドするだけで済む。

import { Think } from "@cloudflare/think";
import { createWorkersAI } from "workers-ai-provider";

export class MyAgent extends Think<Env> {
  getModel() {
    return createWorkersAI({ binding: this.env.AI })(
      "@cf/moonshotai/kimi-k2.5"
    );
  }
}

オーバーライド可能なメソッドとフック:

メソッド用途
getModel()使用するモデルを指定
getSystemPrompt()システムプロンプトを定義
getTools()利用可能なツールを宣言
maxStepsエージェントループの上限
configureSession()メモリ・コンパクション・検索の設定

ライフサイクルフックの実行順序:

beforeTurn()
  → streamText()
    → beforeToolCall()
    → afterToolCall()
  → onStepFinish()
→ onChatResponse()

Context blocks(永続メモリ)

システムプロンプト内の構造化セクションで、モデルがハイバネーション間をまたいで読み書きできる。トークン占有率インジケーター(MEMORY (42%, 462/1100 tokens))が表示され、モデルは set_context ツールで能動的に内容を更新する。

configureSession(session: Session) {
  return session
    .withContext("soul", {
      provider: {
        get: async () => "You are a helpful coding assistant."
      }
    })
    .withContext("memory", {
      description: "Important facts learned during conversation.",
      maxTokens: 2000
    })
    .withCachedPrompt();
}

コストモデルの変化

Durable ObjectsをエージェントのIDと永続化の単位に使うことで、スケーリングのコスト構造が変わる。

指標VM/コンテナDurable Objects
アイドルコスト常にフル課金ゼロ(ハイバネーション)
10,000エージェント・稼働率1%10,000インスタンス約100インスタンス

「1タスクにつき1エージェント」「1顧客につき1エージェント」モデルが現実的なコストで実現できると述べている。既存の AIChatAgent をThinkに移行する場合、クライアント側のコードは変更不要。

インストール

npm install @cloudflare/think agents ai @cloudflare/shell zod workers-ai-provider
npx wrangler deploy

APIは安定しているが進化中のプレビュー扱いで、既に数千の本番エージェントが既存のAgents SDK上で動いている。

Browser Run

「Browser Rendering」が「Browser Run」に改称され、AIエージェントが実際のブラウザを使うことを前提とした機能が一括でリリースされた。名前変えただけじゃないのは確かで、Live View、Human in the Loop、CDPエンドポイント直接公開、WebMCP対応、セッション記録、並行数4倍増と変更点が多い。

既存のBrowser Renderingユーザーにとっては既存APIの変更はなく、新機能が追加される形になる。

Live View

エージェントが実行中のブラウザセッションをリアルタイムで観察できる機能。ページの内容、DOM構造、コンソールログ、ネットワークリクエストがすべて見える。

エージェントが失敗したとき「なぜ失敗したのか」を追うのが難しい問題は、ブラウザ自動化では昔からある。Lightpandaのようなヘッドレスブラウザでは目視確認すらできない。
Live Viewはその診断をブラウザセッションが生きている間にリアルタイムで行える。

Human in the Loop

ログインページや予期しないフォームに直面したときにエージェントが人間に制御を渡し、人間が操作を完了したらエージェントに戻すワークフロー。
MFAや社内認証など、エージェントがクレデンシャルを持てない場面で現実的な回避策になる。

将来的にはエージェント側から「支援を要求する」シグナルを送る機能が追加される予定。
現時点ではLive Viewを通じて手動で引き継ぐ形になる。

CDPエンドポイントの直接公開

Chrome DevTools Protocol(CDP)はブラウザを外部から操作するための低レベルプロトコルで、PuppeteerやPlaywrightはその上に構築されたハイレベルラッパーにあたる。Chrome DevTools MCPもこのCDPの上に乗っている。

Browser RunがCDPエンドポイントを直接公開したことで、既存のCDPスクリプトが1行の変更でCloudflare上で動く。

// 変更前(自前のChrome)
const browser = await puppeteer.connect({
  browserWSEndpoint: 'ws://localhost:9222/devtools/browser'
});

// 変更後(Browser Run)
const browser = await puppeteer.connect({
  browserWSEndpoint: 'wss://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/browser-rendering/devtools/browser'
});

Chromiumのバージョン管理やセキュリティアップデートの追随が不要になる点も大きい。

WebMCP対応

WebMCPはGoogleのChromeチームが提案している新しいブラウザAPIで、WebサイトがAIエージェント向けにツールを構造的に公開できる仕組みだ。

エージェントはスクリーンショットを撮ってVisionモデルに「ボタンを探せ」と投げる代わりに、サイトが用意しているアクション一覧を取得して直接呼び出せる。

// サイトが公開しているツール一覧を取得
const tools = await navigator.modelContextTesting.listTools();

// 直接実行
await navigator.modelContextTesting.executeTool("searchFlights", {
  origin: "NRT", destination: "SFO", date: "2026-05-01"
});

Browser RunでWebMCPを使うには、/devtools/browser リクエストに lab=true パラメータを追加して実験的プール(Chromeベータ版実行環境)を使う。WebMCPが普及すれば、「ページを解析してボタンをクリックする」脆弱な自動化から、「サイトが提供するAPIを型安全に呼ぶ」自動化に移行できる。

セッション記録とスケーリング

ブラウザセッション全体をJSONで記録する機能も追加された。
DOMの変更、キーボード・マウスイベント、ページナビゲーションがすべて含まれ、rrweb-player で後から再生できる。
デバッグとコンプライアンス両方で使える。

スケーリング面も大きく変わった。

指標
同時並行ブラウザ数(デフォルト上限)30120(4倍)
Quick Actions レート制限記載なし10リクエスト/秒
コールドスタートありウォームインスタンスへのグローバルアクセス

/crawl エンドポイントも提供されており、1回のAPIコールでサイト全体をクローリングしてHTMLまたはMarkdown・構造化JSONで返せる。Workers Free・Paid 両プランで利用可能。

Workflows v2

Workflowsはもともと「ユーザー登録」「注文処理」のような低頻度のフローを想定して設計されていた。
エージェントの普及で前提が崩れた。単一のエージェントセッションが数十のワークフローインスタンスを起動し、複数エージェントが並行実行すれば数秒で数千インスタンスが生成される。
人間速度から機械速度へのシフトだ。

V1のボトルネック

V1では単一のAccount Durable Object(DO)がアカウント全体のワークフローインスタンスメタデータを一手に管理していた。
DOはシングルスレッドで動作し、高スループット環境で数秒に数千リクエストが集中するとボトルネックになる。いわゆるホットスポット問題だ。

加えて、Engine DOが実際に存在するかを確認せずにインスタンスをキューイングできたため、整合性の取れない状態が生まれることもあった。

SousChefとGatekeeper

V2では2つの新コンポーネントを導入した。

SousChefはAccount DOの補佐役として機能するDO。
ワークフロー単位でインスタンスのメタデータとライフサイクル管理の一部を担い、Account DOへのリクエスト集中を分散させる。
副産物として、あるワークフローへの高負荷が他のワークフローに影響しない構造になった。

GatekeeperはすべてのSousChefsにコンカレンシースロットを分配するDO。
1秒ごとのバッチ処理で動作し、各サイクルでJSRPC呼び出しは1回に抑えられる。
最大最小公平性(max-min fairness)に基づくスロット割り当てで、特定ワークフローのスロット独占を防ぐ。

インスタンス作成フロー

sequenceDiagram
    participant C as Client
    participant CP as Control Plane
    participant E as Engine DO
    participant SC as SousChef
    participant GK as Gatekeeper

    C->>CP: インスタンス作成リクエスト
    CP->>CP: コントロールプレーンバージョン確認
    CP->>CP: キャッシュ済みワークフロー情報確認
    CP->>E: 最小限メタデータを保存
    E->>E: Alarmをセット
    E-->>SC: バックグラウンドでメタデータ同期
    SC-->>GK: コンカレンシースロット報告
    CP-->>C: インスタンスID返却

ホットパスはEngine DOへの直接書き込みに絞られ、SousChefsやGatekeeperとの同期はバックグラウンドで行われる。
DO alarmを組み合わせることで、背景タスクが失敗してもat-least-onceモデルで再試行される。
信頼性を犠牲にせずホットパスを軽量化した設計だ。

スケーリング数値

項目V1V2
コンカレントインスタンス数4,50050,000
インスタンス作成レート100件/10秒300件/秒(アカウント単位)
キュー済みインスタンス100万/ワークフロー200万/ワークフロー

コンカレント数は約11倍、作成レートはバースト換算で約30倍のキャパシティになった。

ライブマイグレーション

既存ユーザーへの影響なしに移行するため、既存のAccount DOをSousChefとして再機能付けするアプローチをとった。SQLテーブル構造を同一にすることで大規模なデータ移行を避け、コードパスの切り替えだけで対応した。

  1. Account OldをSousChef互換にするリリース
  2. アカウント単位でV2を順次有効化
  3. 新規インスタンスは新SousChefsへルーティング、既存Account DOを自動変換
  4. 保持期限の到来でAccount Oldをサンセット

数百万インスタンスの移行をダウンタイムなしで完了させた。Cloudflareのブログではこれを「走行中の車のタイヤを交換する」と表現していた。

コントロールプレーンパターン

今回の再設計は、Cloudflareが公式リファレンスアーキテクチャとして整備している「コントロールプレーン・データプレーン分離パターン」をWorkflows自身に適用した事例でもある。

Durable Object Facetsが「AIが生成したコードごとに独立したSQLiteをDOとして割り当てる」データプレーン側の進化だとすれば、Workflows v2はコントロールプレーン側のスケーリング問題に正面から取り組んだ発表だった。


3日間の発表を通じて、Cloudflareはエージェントが常駐インフラとして動き続ける前提でスタック全体を再設計した。1日目・2日目が実行環境とネットワークなら、3日目はその上で動くフレームワークとスケーリングの話だった。