Project Think: Cloudflareで次世代のAIエージェントを構築する
2026年4月15日 | Sunil Pai、Kate Reznykova | 読了時間: 10分
本日、次世代のAgents SDKであるProject Thinkを発表します。Project Thinkは、長時間実行されるエージェント(耐久的実行、サブエージェント、サンドボックス化されたコード実行、永続的セッション)を構築するための新しいプリミティブと、これらすべてを統合する意見的なベースクラスのセットです。プリミティブを使用して必要なものを正確に構築するか、ベースクラスを使用して迅速に開始できます。
何が変わったのか
今年初めに、AIについての考え方を変える出来事が起きました。Pi、OpenClaw、Claude Code、Codexなどのツールは、シンプルながら強力なアイデアを証明しました。LLMにファイルを読む、コードを書く、実行する、学んだことを記憶する能力を与えると、開発者ツールというより汎用アシスタントのようなものが得られるということです。
これらのコーディングエージェントはもはやコードを書くだけではありません。カレンダーの管理、データセットの分析、購入交渉、税務申告、ビジネスワークフロー全体の自動化にエージェントを使用している人々がいます。パターンは常に同じです。エージェントはコンテキストを読み、それについて推論し、アクションを取るためのコードを書き、結果を観察し、反復します。コードは普遍的なアクションの媒体です。
既存の課題
わたしたちのチームはこれらのコーディングエージェントを毎日使用しています。そして、同じ壁に何度も直面しました。
- ノートパソコンまたは高価なVPSでのみ実行される: 共有、コラボレーション、デバイス間のハンドオフがない
- アイドル時に高コスト: エージェントが動作しているかどうかに関わらず、固定の月額費用がかかる
- 管理と手動セットアップが必要: 依存関係のインストール、更新の管理、ID とシークレットの設定
さらに深い構造的な問題があります。従来のアプリケーションは1つのインスタンスから多くのユーザーにサービスを提供します。エージェントは1対1です。各エージェントは一意のインスタンスであり、1人のユーザーにサービスを提供し、1つのタスクを実行します。レストランはメニューと大量の料理を作るために最適化されたキッチンを持っています。エージェントはより個人シェフのようなものです。毎回異なる材料、異なるテクニック、異なるツール。これは根本的にスケーリング数学を変えます。
1億人の知識労働者が各々わずかな同時実行でエージェント型アシスタントを使用する場合、数千万の同時セッションの容量が必要です。現在のコンテナあたりのコストでは、これは持続不可能です。異なる基盤が必要です。
Project Thinkの紹介
Project ThinkはAgents SDKの新しいプリミティブのセットを提供します。
主要なプリミティブ
- ファイバーを使用した耐久的実行: クラッシュ回復、チェックポイント、自動キープアライブ
- サブエージェント: 独自のSQLiteと型付きRPCを持つ分離された子エージェント
- 永続的セッション: ツリー構造のメッセージ、フォーク、圧縮、全文検索
- サンドボックス化されたコード実行: Dynamic Workers、codemode、ランタイムnpm解決
- 実行ラダー: ワークスペース、アイソレート、npm、ブラウザ、サンドボックス
- 自己作成拡張: ランタイムで独自のツールを書くエージェント
これらのそれぞれはAgent基本クラスで直接使用可能です。プリミティブを使用して必要なものを正確に構築するか、Thinkベースクラスを使用して迅速に開始できます。
長時間実行されるエージェント
現在のエージェントは一時的です。セッションのために実行され、単一のプロセスまたはデバイスに結合され、その後消えます。ノートパソコンがスリープするときに死ぬコーディングエージェントはツールです。永続化できるエージェント(オンデマンドで起動でき、中断後に作業を続行でき、ローカルランタイムに依存せずに状態を前に進めることができる)はインフラストラクチャのように見え始めます。そしてそれはエージェントのスケーリングモデルを完全に変えます。
Agents SDKはDurable Objectsの上に構築され、すべてのエージェントにアイデンティティ、永続的な状態、およびメッセージで起動する能力を与えます。これはアクターモデルです。各エージェントはアドレス可能なエンティティであり、独自のSQLiteデータベースを持ちます。休止中はゼロコンピュートを消費します。何かが起こると(HTTPリクエスト、WebSocketメッセージ、スケジュール済みアラーム、受信メール)、プラットフォームはエージェントを起動し、その状態をロードし、イベントを渡します。エージェントは作業を行い、その後スリープに戻ります。
| VMs / コンテナ | Durable Objects |
|---|
| アイドルコスト | 常に完全なコンピュート | ゼロ(休止中) |
| スケーリング | 容量をプロビジョニングして管理 | 自動、エージェントごと |
| 状態 | 外部データベースが必要 | 組み込みSQLite |
| 回復 | 自分で構築(プロセスマネージャー、ヘルスチェック) | プラットフォームが再起動、状態が保存される |
| アイデンティティ / ルーティング | 自分で構築(ロードバランサー、スティッキーセッション) | 組み込み(名前 → エージェント) |
例: 10,000個のエージェント、各々1%の時間アクティブ
- 従来: 10,000個の常時オンインスタンス
- Project Think: 任意の時点で約100個がアクティブ
これはスケール時のエージェント実行の経済学を変えます。「パワーユーザーあたり1つの高価なエージェント」の代わりに、「顧客あたり1つのエージェント」または「タスクあたり1つのエージェント」または「メールスレッドあたり1つのエージェント」を構築できます。新しいエージェントを生成する限界コストは実質的にゼロです。
クラッシュの生き残り: ファイバーを使用した耐久的実行
LLM呼び出しには30秒かかります。マルチターンエージェントループはそれより長く実行できます。その期間中のいつでも、実行環境は消えることができます。デプロイ、プラットフォーム再起動、リソース制限に達する。モデルプロバイダーへのアップストリーム接続は永久に切断され、メモリ内状態は失われ、接続されたクライアントはストリームが説明なく停止するのを見ます。
runFiber()がこれを解決します。ファイバーは耐久的な関数呼び出しです。実行開始前にSQLiteに登録され、stash()を介して任意の時点でチェックポイント可能で、onFiberRecoveredを介して再起動時に回復可能です。
import { Agent } from "agents";
export class ResearchAgent extends Agent {
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);
}
}
}
SDKはファイバー実行中にエージェントを自動的に生かし続けます。特別な設定は不要です。分単位で測定される作業の場合、keepAlive() / keepAliveWhile()はアクティブな作業中の削除を防ぎます。より長い操作(CIパイプライン、デザインレビュー、ビデオ生成)の場合、エージェントは作業を開始し、ジョブIDを永続化し、休止し、コールバックで起動します。
作業の委任: Facetsを介したサブエージェント
単一のエージェントがすべてを自分で行うべきではありません。サブエージェントはFacetsを介して親と同じ場所に配置された子Durable Objectsであり、各々独自の分離されたSQLiteと実行コンテキストを持ちます。
import { Agent } from "agents";
export class ResearchAgent extends Agent {
async search(query: string) { }
}
export class ReviewAgent extends Agent {
async analyze(query: string) { }
}
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);
}
}
サブエージェントはストレージレベルで分離されます。各々は独自のSQLiteデータベースを取得し、それらの間に暗黙的なデータ共有はありません。これはランタイムによって強制され、サブエージェントRPCレイテンシーは関数呼び出しです。TypeScriptはコンパイル時に誤用をキャッチします。
永続化される会話: Session API
数日または数週間実行されるエージェントは、典型的なメッセージのフラットリストより多くが必要です。実験的なSession APIはこれを明示的にモデル化します。Agent基本クラスで利用可能な会話はツリーとして保存され、各メッセージはparent_idを持ちます。これにより、フォーク(元のパスを失わずに代替案を探索)、非破壊的圧縮(メッセージを削除するのではなく要約)、およびFTS5を介した会話履歴全体の全文検索が可能になります。
import { Agent } from "agents";
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 history = session.getHistory();
const forked = this.sessions.fork(session.id, messageId, "alternative-approach");
}
}
SessionはAgent で直接使用可能であり、Thinkベースクラスが構築するストレージレイヤーです。
ツール呼び出しからコード実行へ
従来のツール呼び出しは厄介な形をしています。モデルはツールを呼び出し、結果をコンテキストウィンドウを通して引き戻し、別のツールを呼び出し、それを引き戻します。ツール表面が成長するにつれて、これは高価で不器用になります。100個のファイルは100回のモデルへのラウンドトリップを意味します。しかし、モデルはツール呼び出しゲームをプレイするより、システムを使用するコードを書くのが得意です。
これは@cloudflare/codemodeの背後にある洞察です。順序付きツール呼び出しの代わりに、LLMはタスク全体を処理する単一のプログラムを書きます。
const files = await tools.find({ pattern: "**/*.ts" });
const results = [];
for (const file of files) {
const content = await tools.read({ path: file });
if (content.includes("TODO")) {
results.push({ file, todos: content.match(/\/\/ TODO:.*/g) });
}
}
return results;
モデルへの100回のラウンドトリップの代わりに、単一のプログラムを実行するだけです。これにより、使用されるトークンが少なくなり、実行が高速化され、結果が向上します。
Cloudflare API MCPサーバーはこれを大規模に実証しています。わたしたちは2つのツール(search()とexecute())のみを公開しており、約1,000トークンを消費します。素朴なツール-エンドポイント相当の場合は約1.17百万トークンです。これは99.9%の削減です。
欠落しているプリミティブ: 安全なサンドボックス
モデルがユーザーに代わってコードを書くべきであることを受け入れたら、質問は次のようになります。そのコードはどこで実行されますか?最終的ではなく、製品チームがそれをロードマップアイテムに変えた後ではなく。今、このユーザーのために、このシステムに対して、厳密に定義されたアクセス許可で。
Dynamic Workersがそのサンドボックスです。ランタイムで数ミリ秒で回転する新しいV8アイソレート、数メガバイトのメモリ。これはコンテナより約100倍高速で、最大100倍メモリ効率が良いです。すべてのリクエストに対して新しいものを開始し、コードスニペットを実行し、それを破棄できます。
重要な設計上の選択はケーパビリティモデルです。汎用マシンで開始して制約を試みるのではなく、Dynamic Workersはほぼ環境権限がない状態で開始し(globalOutbound: null、ネットワークアクセスなし)、開発者はバインディングを通じてリソースごとにケーパビリティを明示的に付与します。わたしたちは「これがやりすぎるのをどうやって止めるか」から「これが正確に何ができるようにしたいのか」という質問に移ります。これはエージェントインフラストラクチャの正しい質問です。
実行ラダー
このケーパビリティモデルは自然に計算環境のスペクトラムにつながり、エージェントが必要に応じてエスカレートする実行ラダーです。
Tier 0はワークスペースで、SQLiteとR2によってサポートされる耐久的な仮想ファイルシステムです。読み取り、書き込み、編集、検索、grep、diff。@cloudflare/shellによって駆動されます。
Tier 1はDynamic Workerです。LLM生成JavaScriptがサンドボックス化されたアイソレートで実行され、ネットワークアクセスはありません。@cloudflare/codemodeによって駆動されます。
Tier 2はnpmを追加します。@cloudflare/worker-bundlerはレジストリからパッケージを取得し、esbuildでバンドルし、結果をDynamic Workerにロードします。エージェントはimport { z } from "zod"と書き、それは機能します。
Tier 3はCloudflare Browser Runを介したヘッドレスブラウザです。ナビゲート、クリック、抽出、スクリーンショット。サービスがMCPまたはAPIを介してエージェントをまだサポートしていない場合に便利です。
Tier 4はCloudflare Sandboxです。