はい、承知いたしました。Cloudflare Workers AIを使ったエッジAI開発の初心者向け詳細ガイド記事を作成します。約5000語を目指し、詳細な説明を含めます。
Cloudflare Workers AIでエッジAI開発を始めよう:初心者向けガイド
AI(人工知能)は私たちの生活やビジネスに急速に浸透しています。かつてAIモデルの実行は高性能なGPUを備えた大規模なデータセンターでしか不可能でしたが、技術の進歩により、より多くの場所でAIを活用できるようになってきました。特に注目されているのが「エッジAI」です。
エッジAIとは、データが発生する場所(エッジ)の近くでAIモデルを実行する技術です。これにより、データの転送にかかる時間やコストを削減し、リアルタイムに近い応答速度を実現できます。しかし、エッジでAIを実行するには、インフラストラクチャの管理やモデルのデプロイなど、多くの課題が伴いました。
ここで登場するのが、Cloudflare Workers AIです。Cloudflare Workers AIは、Cloudflareが提供するグローバルなネットワークを活用し、エッジでAIモデルを手軽に実行できるプラットフォームです。インフラ管理の複雑さから解放され、迅速かつコスト効率よくAIアプリケーションを開発できます。
このガイドでは、Cloudflare Workers AIを使ってエッジAI開発を始めるためのすべてを、初心者向けに詳細に解説します。概念の説明から、環境構築、最初のAIワーカーの作成、デプロイ、そしてさらに進んだ使い方まで、順を追って見ていきましょう。
1. なぜCloudflare Workers AIなのか?エッジAIの力
Cloudflare Workers AIについて深く掘り下げる前に、なぜエッジAIが重要なのか、そしてなぜCloudflare Workers AIがその実現に適しているのかを理解しましょう。
1.1. エッジコンピューティングとは?
伝統的なコンピューティングモデルでは、データはユーザーのデバイスやローカルネットワークから遠く離れた中央のデータセンターに送られ、そこで処理されてから結果が返されます。これはクラウドコンピューティングの基本的な考え方です。
一方、エッジコンピューティングでは、データの生成源(例えば、IoTデバイス、スマートフォン、ユーザーのブラウザに近いサーバーなど)の「エッジ」でデータ処理を行います。これにより、以下のメリットが生まれます。
- 低レイテンシ(低遅延): データがデータセンターまで往復する必要がないため、応答時間が大幅に短縮されます。リアルタイム性が求められるアプリケーション(ゲーム、自動運転、インタラクティブなWebサイトなど)に不可欠です。
- 帯域幅の削減: すべての生データを中央に送る必要がなくなり、処理済みの結果や集約されたデータだけを送信すれば済むため、ネットワークの帯域幅の消費を抑えられます。特に、データ量が膨大なIoTデバイスなどでは重要です。
- 信頼性の向上: ネットワーク接続が不安定な環境でも、エッジで処理が完結するため、全体の信頼性が向上します。
- プライバシーとセキュリティ: 機密性の高いデータ(個人情報など)をエッジで処理し、中央に送信しないことで、プライバシーリスクを低減できます。
1.2. エッジAIとは?
エッジAIは、このエッジコンピューティングの考え方をAIモデルの実行に応用したものです。AIモデルによる「推論」(学習済みモデルを使って新しいデータに対する予測や判断を行うこと)を、クラウドではなくエッジで行います。
例えば、スマートフォンの顔認識機能、工場の異常検知システム、店舗の顧客行動分析カメラなどは、デバイス自体やローカルネットワークに近い場所でAIを実行するエッジAIの例です。
エッジAIのメリットは、エッジコンピューティングのメリットと共通していますが、AIの文脈では特に以下の点が強調されます。
- リアルタイム推論: 低レイテンシにより、ほぼ瞬時にAIの推論結果を得られます。チャットボットの応答、リアルタイムの画像分析などが可能になります。
- オフライン対応: インターネット接続がなくても、エッジデバイスやローカルネットワーク内でAIを実行できる場合があります。
- コスト効率: 大量のデータをクラウドに送信して処理するよりも、エッジで処理する方がデータ転送コストやクラウドの処理コストを削減できる場合があります。
1.3. Cloudflare WorkersとWorkers AI
Cloudflare Workersは、Cloudflareのグローバルネットワーク上に分散配置されたサーバーレス実行環境です。ユーザーのリクエストに最も近いロケーションでJavaScript、WebAssemblyなどのコードを実行できます。これにより、ウェブサイトの高速化、セキュリティ強化、複雑なロジックの実行などが可能です。Cloudflare Workersの主な特徴は以下の通りです。
- サーバーレス: インフラ管理、OSパッチ、スケーリングなどを気にする必要がありません。コードをデプロイするだけで、Cloudflareが自動的に管理します。
- エッジ実行: 世界中のCloudflareのデータセンターでコードが実行されます。これにより、ユーザーに極めて近い場所で処理を行えます。
- グローバル分散: デプロイされたコードは自動的にCloudflareの全データセンターに複製され、トラフィックが多い場所でもパフォーマンスが維持されます。
- 高速起動: 非常に高速に起動するため、リクエストに対する応答が迅速です。
そして、Cloudflare Workers AIは、このWorkersプラットフォーム上で利用できる、マネージドなAIモデル推論サービスです。Workersスクリプトから簡単なAPI呼び出しを行うだけで、様々なAIモデル(テキスト生成、埋め込み、画像タスクなど)をエッジで実行できます。
Cloudflare Workers AIの登場により、エッジAI開発は劇的に容易になりました。
- インフラ不要: 高価なGPUサーバーを調達・管理する必要がありません。
- モデルデプロイ不要: Cloudflareが厳選したモデルを提供しており、ユーザーは自分でモデルの重みをダウンロードしたりデプロイしたりする必要がありません。
- スケーリング不要: トラフィックの増減に応じて、Cloudflareが自動的にスケーリングします。
- 簡単API: Workersスクリプトから統一された簡単なAPIで様々なモデルを利用できます。
- 既存のCloudflareサービスとの連携: Workers KV、D1、R2といった他のCloudflareのエッジサービスと簡単に組み合わせることで、リッチなAIアプリケーションを構築できます。
つまり、Cloudflare Workers AIは、「インフラ管理の手間なく、世界中のエッジで、多様なAIモデルを手軽に実行できる」プラットフォームなのです。これにより、開発者はAIのアイデア実現に集中できます。
2. Cloudflare Workers AIを始めるための準備
Cloudflare Workers AIでの開発を始めるために必要なものを確認しましょう。
2.1. Cloudflareアカウントの作成
Cloudflare Workers AIを利用するには、まずCloudflareのアカウントが必要です。
- Cloudflare公式サイトにアクセス:
https://www.cloudflare.com/ja-jp/
にアクセスします。 - サインアップ: 右上または中央の「サインアップ」ボタンをクリックします。
- プランの選択: Workers AIを含む多くのサービスは、無料プラン(Free Plan)でも試すことができます。まずは無料プランで始めるのがおすすめです。もちろん、ビジネス要件に応じて有料プランを選択することも可能です。
- アカウント情報の入力: メールアドレスとパスワードを入力し、アカウントを作成します。
- ドメインの追加 (任意): Cloudflareの多くのサービスはドメインを介して提供されますが、Workers AI単体で試すだけであれば、既存のドメインを持っていなくても問題ありません。Workersは
*.workers.dev
という無料のサブドメインでデプロイ可能です。もし独自ドメインでWorkers AIアプリケーションを提供したい場合は、Cloudflareにドメインを追加してください。
2.2. 開発環境の準備
Workers AIのコードはJavaScriptまたはTypeScriptで記述します。ローカルでの開発には、Node.jsとCloudflareのCLIツールであるwrangler
を使用するのが便利です。
-
Node.jsのインストール:
- Node.jsの公式ウェブサイト (
https://nodejs.org/
) にアクセスします。 - 推奨バージョン(LTS版)をダウンロードし、インストーラーに従ってインストールします。
- インストール後、ターミナル(コマンドプロンプトやPowerShellなど)を開き、以下のコマンドを実行して正しくインストールされているか確認します。
bash
node -v
npm -v - バージョンが表示されればOKです。
- Node.jsの公式ウェブサイト (
-
wrangler
のインストール:wrangler
はCloudflare Workersの開発・デプロイを支援するCLIツールです。npmを使ってインストールします。- ターミナルで以下のコマンドを実行します。
bash
npm install -g wrangler - インストール後、以下のコマンドを実行してバージョンを確認します。
bash
wrangler -v - バージョンが表示されればOKです。
-
Cloudflareアカウントへのログイン (wrangler):
- ローカル環境からWorkersをデプロイするには、
wrangler
をCloudflareアカウントに連携させる必要があります。 - ターミナルで以下のコマンドを実行します。
bash
wrangler login - ブラウザが開き、Cloudflareアカウントへのログインを求められます。ログイン後、
wrangler
への認証許可を求められるので、許可します。ターミナルに戻り、「Successfully logged in.」と表示されれば完了です。
- ローカル環境からWorkersをデプロイするには、
これで、Cloudflare Workers AIでの開発を始める準備が整いました。
3. 最初のWorkers AIワーカーを作成する
実際にコードを書いて、最初のWorkers AIワーカーを作成してみましょう。最も基本的な例として、「テキスト生成」モデルを使ってみます。
3.1. プロジェクトの初期化
まず、wrangler
を使って新しいWorkersプロジェクトを初期化します。
- プロジェクトを作成したいディレクトリに移動し、ターミナルで以下のコマンドを実行します。
bash
wrangler generate my-ai-worker
my-ai-worker
はプロジェクト名です。好きな名前に変更できます。 - プロジェクトの初期設定についていくつか質問されます。今回はTypeScriptではなくJavaScriptで始めるので、それに応じて回答します。
Would you like to use TypeScript?
->No
Would you like to use a Git repository?
->Yes
(またはNo
任意)Would you like to generate a
git ignore?
->Yes
(またはNo
任意)Would you like to install @cloudflare/workers-types?
->No
(TypeScriptを選ばなければ不要)Would you like to run
npm install?
->Yes
プロジェクトが作成され、必要な依存関係がインストールされます。
3.2. Workers AIバインディングの設定
Workers AIを利用するには、Workersスクリプト内でAIモデルを実行するための特別なオブジェクトにアクセスできるように設定する必要があります。これを「AIバインディング」と呼びます。
プロジェクトディレクトリ(my-ai-worker
)に移動し、wrangler.toml
ファイルを開きます。このファイルはWorkersプロジェクトの設定ファイルです。
wrangler.toml
に以下の設定を追加します。
“`toml
name = “my-ai-worker”
main = “src/index.js”
compatibility_date = “2023-12-18” # 最新の互換性日付を指定
以下を追加
[ai]
binding = “AI” # Workersスクリプト内で env.AI としてアクセスできるようになる
“`
[ai]
セクションを追加し、binding = "AI"
と設定します。これにより、Workersスクリプトの env
オブジェクトを通じて env.AI
という名前でWorkers AIの機能にアクセスできるようになります。
3.3. Workersスクリプトの記述
次に、実際にAIモデルを実行するJavaScriptコードを記述します。プロジェクトディレクトリ内の src/index.js
ファイルを開きます。初期化時に含まれているコードを以下の内容に置き換えます。
“`javascript
// src/index.js
export default {
async fetch(request, env) {
// Workers AIはenv.AIとして利用可能
const ai = env.AI;
// リクエストからプロンプトを取得
// 例として、GETリクエストのクエリパラメータまたはPOSTリクエストのボディから取得
let prompt;
if (request.method === 'POST') {
const data = await request.json();
prompt = data.prompt;
} else {
// GETリクエストの場合はクエリパラメータから取得 (例: ?prompt=...)
const url = new URL(request.url);
prompt = url.searchParams.get('prompt');
}
// プロンプトがない場合はエラー応答
if (!prompt) {
return new Response('Please provide a prompt via POST body or ?prompt= query parameter.', { status: 400 });
}
// 使用するテキスト生成モデルを指定
// Cloudflare Workers AIがサポートするモデル一覧から選択
// 例: メタ社のLLaMA 2 7B Chat quantized int8
const model = '@cf/meta/llama-2-7b-chat-int8';
let responseText = '';
try {
// AIモデルを実行
const inputs = { prompt: prompt };
const output = await ai.run(model, inputs);
// モデルの出力形式はモデルによって異なる場合がある
// Llama 2 chat int8の場合、出力は { response: "Generated text..." } の形式
if (output && output.response) {
responseText = output.response;
} else {
responseText = 'Failed to generate text or unexpected output format.';
console.error('Unexpected AI model output:', output);
}
} catch (error) {
console.error('AI model execution failed:', error);
responseText = `Error processing request: ${error.message}`;
return new Response(responseText, { status: 500 });
}
// 生成されたテキストをJSON形式で応答
return new Response(JSON.stringify({ generated_text: responseText }), {
headers: { 'Content-Type': 'application/json' },
});
},
};
“`
このコードが行っていることは以下の通りです。
- Workersスクリプトのエントリポイントである
fetch
関数を定義します。この関数は、Workerへのすべてのリクエストを処理します。引数としてrequest
(受信したリクエストオブジェクト)とenv
(環境変数やバインディングにアクセスするためのオブジェクト)を受け取ります。 env.AI
からWorkers AIのオブジェクトを取得します。これはwrangler.toml
で設定したbinding = "AI"
により利用可能になっています。- 受信したリクエストから、生成させたいテキストの「プロンプト」を取得します。この例では、POSTリクエストのJSONボディにある
prompt
プロパティ、またはGETリクエストのクエリパラメータprompt
から取得するようにしています。 - プロンプトが指定されていない場合は、エラーメッセージと共にステータスコード400を返します。
- 使用するAIモデルのIDを定義します。ここではテキスト生成モデル
@cf/meta/llama-2-7b-chat-int8
を指定しています。Workers AIがサポートするモデルの最新リストはCloudflareのドキュメントで確認できます。 try...catch
ブロック内で、AIモデルを実行します。await ai.run(model, inputs)
を呼び出します。model
: 使用するモデルのIDです。inputs
: モデルに渡す入力データです。テキスト生成モデルの場合、通常は{ prompt: "あなたのプロンプト" }
の形式です。入力形式はモデルによって異なります。
ai.run()
はPromiseを返し、モデルの実行結果をawaitで待ちます。- モデルの出力形式はモデルによって異なりますが、テキスト生成モデルの場合は通常、生成されたテキストを含むオブジェクトが返されます。例示したLlama 2モデルの場合は
{ response: "..." }
の形式です。出力オブジェクトから生成されたテキストを取得します。 - AIモデルの実行中にエラーが発生した場合は
catch
ブロックで捕捉し、エラーメッセージと共にステータスコード500を返します。 - 正常にテキストが生成されたら、その結果をJSON形式で含む
Response
オブジェクトを作成し、クライアントに返します。Content-Type
ヘッダーをapplication/json
に設定します。
3.4. Workers AIワーカーのデプロイ
コードが完成したら、Cloudflareにデプロイします。ローカルでwrangler
コマンドを使います。
プロジェクトディレクトリ(my-ai-worker
)でターミナルを開き、以下のコマンドを実行します。
bash
wrangler deploy
wrangler
はコードをバンドルし、Cloudflareのネットワークにアップロードします。デプロイが完了すると、Workerが利用可能なURLが表示されます。URLは通常 https://your-worker-name.your-account.name.workers.dev
の形式です。
3.5. デプロイしたワーカーのテスト
デプロイが完了したら、表示されたURLにアクセスしてワーカーをテストできます。
-
GETリクエストでテスト:
ブラウザのアドレスバーに、表示されたURLにクエリパラメータを追加して入力します。
例:https://my-ai-worker.your-account.name.workers.dev/?prompt=日本の首都はどこですか?
ブラウザには、JSON形式で生成された応答が表示されるはずです。 -
POSTリクエストでテスト:
curl
コマンドやPostman、InsomniaなどのAPIクライアントを使います。
例 (curl
):
bash
curl -X POST -H "Content-Type: application/json" -d '{"prompt": "空を飛ぶ象について短い物語を書いてください。"}' https://my-ai-worker.your-account.name.workers.dev/
ターミナルに、JSON形式で生成された応答が表示されるはずです。
テストが成功すれば、最初のWorkers AIワーカーの作成とデプロイは完了です!
4. Workers AIがサポートするモデルと使い方
Cloudflare Workers AIは様々な種類のAIモデルをサポートしています。テキスト生成だけでなく、埋め込み、翻訳、画像関連タスクなど、幅広い用途に対応しています。ai.run()
メソッドは共通ですが、使用するモデルによって model
引数の値と inputs
オブジェクトの構造が異なります。
Cloudflareはサポートしているモデルのリストを公開しており、これは常に更新されています。最新の情報はCloudflareの公式ドキュメント(Workers AI Model Catalogなど)で確認することをお勧めします。
ここでは、いくつかの主要なモデルカテゴリと簡単な使い方を紹介します。
4.1. テキスト生成 (Text Generation)
- モデルIDの例:
@cf/meta/llama-2-7b-chat-int8
@cf/mistral/mistral-7b-instruct-v0.1
@cf/qwen/qwen1.5-7b-chat-int8
@cf/tinyllama/tinyllama-1.1b-chat-v1.0
(より軽量)
inputs
形式:{ prompt: "あなたのプロンプト文字列" }
output
形式:{ response: "生成されたテキスト文字列" }
(モデルによってキー名が異なる場合がありますが、多くはresponse
かgenerated_text
です)- 追加オプション: 温度 (temperature)、最大トークン数 (max_tokens) などを
inputs
に含めることで、生成されるテキストの多様性や長さを制御できるモデルがあります。
“`javascript
// テキスト生成の例
const ai = env.AI;
const model = ‘@cf/mistral/mistral-7b-instruct-v0.1’;
const inputs = {
prompt: “朝食に最適なレシピを教えてください。”,
max_tokens: 256 // オプション: 最大生成トークン数を指定
};
try {
const output = await ai.run(model, inputs);
console.log(“Generated Text:”, output.response);
} catch (error) {
console.error(“Error:”, error);
}
“`
4.2. テキスト埋め込み (Text Embeddings)
テキスト埋め込みは、テキストの意味を数値ベクトルとして表現する技術です。類似した意味を持つテキストは、ベクトル空間上で近くに配置されます。検索、レコメンデーション、クラスタリングなどに利用されます。
- モデルIDの例:
@cf/baai/bge-base-en-v1.5
@cf/baai/bge-large-en-v1.5
@cf/baai/bge-small-en-v1.5
inputs
形式:{ text: "あなたのテキスト文字列" }
または{ text: ["テキスト1", "テキスト2", ...] }
(複数のテキストを一度に処理する場合)output
形式:{ shape: [N, D], data: [ベクトル値の配列] }
(Nは入力テキスト数、Dは埋め込みベクトルの次元)
“`javascript
// テキスト埋め込みの例
const ai = env.AI;
const model = ‘@cf/baai/bge-base-en-v1.5’;
const inputs = {
text: [
“Cloudflare Workers AIとは何ですか?”,
“エッジコンピューティングの利点について教えてください。”,
“今日の天気は晴れです。”
]
};
try {
const output = await ai.run(model, inputs);
console.log(“Embeddings:”, output.data); // output.dataはベクトル値の配列の配列
} catch (error) {
console.error(“Error:”, error);
}
“`
埋め込みを取得したら、例えばWorkers KVやD1、または外部のベクトルデータベースに保存し、後で検索や類似度計算に利用できます。
4.3. 翻訳 (Translation)
テキストをある言語から別の言語に翻訳します。
- モデルIDの例:
@cf/meta/m2m100-1.2b
inputs
形式:{ text: "翻訳したいテキスト", target_lang: "en", source_lang: "ja" }
(モデルによってサポートされる言語ペアと形式が異なります)output
形式:{ translated_text: "翻訳されたテキスト文字列" }
“`javascript
// 翻訳の例
const ai = env.AI;
const model = ‘@cf/meta/m2m100-1.2b’;
const inputs = {
text: “こんにちは、Workers AIの世界へようこそ!”,
target_lang: “en”, // 英語へ翻訳
source_lang: “ja” // 日本語から翻訳
};
try {
const output = await ai.run(model, inputs);
console.log(“Translated Text:”, output.translated_text);
} catch (error) {
console.error(“Error:”, error);
}
“`
4.4. 音声認識 (Automatic Speech Recognition – ASR)
音声ファイル(音声データ)を入力として受け取り、テキストに変換します。
- モデルIDの例:
@cf/openai/whisper
inputs
形式: 音声データのArrayBufferやUint8Arrayなど。通常、リクエストボディとして音声ファイルをバイナリ形式で受け取り、それをai.run
に渡します。output
形式:{ text: "認識されたテキスト文字列" }
“`javascript
// 音声認識の例 (Fetch APIを使って音声ファイルをアップロードする場合)
// この例はクライアントサイドからのPOSTリクエストを想定しています。
// Worker側ではリクエストボディを処理する必要があります。
async fetch(request, env) {
const ai = env.AI;
if (request.method === ‘POST’) {
try {
// リクエストボディから音声データを取得
const audioData = await request.arrayBuffer();
const model = '@cf/openai/whisper';
const inputs = {
audio: [...new Uint8Array(audioData)] // ArrayBufferを数値配列に変換して渡す
};
const output = await ai.run(model, inputs);
return new Response(JSON.stringify({ transcript: output.text }), {
headers: { 'Content-Type': 'application/json' },
});
} catch (error) {
console.error("ASR error:", error);
return new Response(`ASR failed: ${error.message}`, { status: 500 });
}
} else {
return new Response(‘Send a POST request with audio file in the body.’);
}
}
``
fetch
音声ファイルを受け取るWorkerを構築するには、クライアント側(ブラウザなど)からAPIやフォームを使って音声ファイルをバイナリデータとしてPOST送信する必要があります。Worker側では
await request.arrayBuffer()` などでボディを読み込み、それをモデルの入力形式に合わせて処理します。
4.5. 画像分類 (Image Classification)
画像を入力として受け取り、その画像の内容を分類します。
- モデルIDの例:
@cf/microsoft/resnet-50
inputs
形式: 画像データのArrayBufferやUint8Arrayなど。音声認識と同様にリクエストボディとして画像ファイルをバイナリ形式で受け取り、それをai.run
に渡します。output
形式:{ result: [{ score: 確率値, label: "ラベル名" }, ...] }
(確率の高い順に複数のラベルとスコアが返されます)
“`javascript
// 画像分類の例 (Fetch APIを使って画像をアップロードする場合)
async fetch(request, env) {
const ai = env.AI;
if (request.method === ‘POST’) {
try {
// リクエストボディから画像データを取得
const imageData = await request.arrayBuffer();
const model = '@cf/microsoft/resnet-50';
const inputs = {
image: [...new Uint8Array(imageData)] // ArrayBufferを数値配列に変換
};
const output = await ai.run(model, inputs);
// 結果は確率の高い順にソートされている
const topResult = output.result[0];
return new Response(JSON.stringify({
label: topResult.label,
score: topResult.score
}), {
headers: { 'Content-Type': 'application/json' },
});
} catch (error) {
console.error("Image classification error:", error);
return new Response(`Image classification failed: ${error.message}`, { status: 500 });
}
} else {
return new Response(‘Send a POST request with image file in the body.’);
}
}
“`
4.6. 物体検出 (Object Detection)
画像を入力として受け取り、画像内に存在する物体とその位置(バウンディングボックス)を検出します。
- モデルIDの例:
@cf/cloudflare/cf-object-detection-l
inputs
形式: 画像データのArrayBufferやUint8Arrayなど。output
形式:{ detections: [{ box: { xmin, ymin, xmax, ymax }, score: 確率値, label: "ラベル名" }, ...] }
“`javascript
// 物体検出の例 (画像アップロードを想定)
async fetch(request, env) {
const ai = env.AI;
if (request.method === ‘POST’) {
try {
const imageData = await request.arrayBuffer();
const model = '@cf/cloudflare/cf-object-detection-l';
const inputs = {
image: [...new Uint8Array(imageData)]
};
const output = await ai.run(model, inputs);
return new Response(JSON.stringify(output.detections), { // 検出された物体リストを応答
headers: { 'Content-Type': 'application/json' },
});
} catch (error) {
console.error("Object detection error:", error);
return new Response(`Object detection failed: ${error.message}`, { status: 500 });
}
} else {
return new Response(‘Send a POST request with image file in the body.’);
}
}
“`
4.7. 画像生成 (Image Generation)
テキストプロンプトを入力として受け取り、そのプロンプトに基づいた画像を生成します。
- モデルIDの例:
@cf/stabilityai/stable-diffusion-xl-base-1.0
inputs
形式:{ prompt: "生成したい画像のテキスト説明" }
または{ prompt: "...", negative_prompt: "..." }
(生成したくない要素を指定)output
形式: 画像データ(通常はPNG形式のArrayBufferやUint8Arrayなど)が直接返されます。JSONオブジェクトではありません。
“`javascript
// 画像生成の例
async fetch(request, env) {
const ai = env.AI;
// プロンプトを取得 (例: クエリパラメータ ?prompt=…)
const url = new URL(request.url);
const prompt = url.searchParams.get(‘prompt’);
if (!prompt) {
return new Response(‘Please provide a prompt via ?prompt= query parameter.’, { status: 400 });
}
try {
const model = ‘@cf/stabilityai/stable-diffusion-xl-base-1.0’;
const inputs = {
prompt: prompt,
// オプション: 生成したくない要素を指定
// negative_prompt: “low quality, blurry”
};
// 画像生成モデルの出力はバイナリデータ
const output = await ai.run(model, inputs); // ArrayBufferが返される
// 生成された画像を直接応答として返す
return new Response(output, {
headers: {
'Content-Type': 'image/png' // モデルの出力形式に合わせて変更
},
});
} catch (error) {
console.error(“Image generation error:”, error);
// エラー応答も適切な形式で返す
return new Response(JSON.stringify({ error: Image generation failed: ${error.message}
}), {
status: 500,
headers: { ‘Content-Type’: ‘application/json’ },
});
}
}
“`
画像生成モデルの場合、ai.run
は直接バイナリデータ(生成された画像ファイルの中身)を返します。そのため、Workerの応答としてそのバイナリデータをそのまま返せば、クライアント(ブラウザなど)はそのデータを画像として表示できます。応答の Content-Type
ヘッダーを忘れずに設定してください。
重要な注意点:
- モデルIDの正確性: 使用するモデルIDは正確に入力する必要があります。大文字小文字、ハイフンなどに注意してください。最新かつ正確なモデルIDはCloudflareの公式ドキュメントで確認してください。
inputs
形式: モデルによってinputs
オブジェクトの構造や必須パラメータが異なります。必ずモデルごとのドキュメントを確認してください。output
形式: モデルの出力形式もモデルによって異なります(JSONオブジェクト、バイナリデータ、オブジェクト内の特定のキーなど)。ドキュメントを確認し、Workerコードで適切に処理する必要があります。- 利用制限: Workers AIは利用に応じた課金モデル(通常は推論ごとの課金)であり、無料プランや有料プランには利用制限(リクエスト数や処理時間など)があります。意図しない高額請求を防ぐため、利用状況を監視することをお勧めします。
これらの例を参考に、様々なAIモデルを使ってWorkers AIワーカーを開発してみてください。
5. Cloudflareの他のエッジサービスとの連携
Cloudflare Workers AIの強力な点の1つは、Cloudflareが提供する他のエッジサービスとシームレスに連携できることです。これにより、単なるAI推論だけでなく、データの保存、キャッシュ、イベント駆動処理などを組み込んだよりリッチで高性能なアプリケーションをエッジで構築できます。
Workers AIとよく連携されるサービスをいくつか紹介します。
5.1. Workers KV (Key-Value Store)
Workers KVは、キーと値のペアを格納できる、極めて高速なグローバル分散型キーバリューストアです。エッジにキャッシュされるため、低レイテンシでアクセスできます。
- AI連携の例:
- AI推論結果のキャッシュ: 同じ入力に対するAI推論結果をKVにキャッシュし、再利用することで、AIモデルの実行回数を減らし、レイテンシを改善し、コストを削減できます。
- プロンプトの管理: よく使うプロンプトや設定値をKVに保存しておき、Workerから読み込む。
- 埋め込みの保存: テキスト埋め込みモデルで生成したベクトルを、関連するメタデータと共にKVに保存し、後で検索や類似度計算に利用する(ただし、ベクトル検索には後述のVectorizeの方が適しています)。
KVバインディングの設定 (wrangler.toml
):
“`toml
name = “my-ai-worker”
main = “src/index.js”
compatibility_date = “2023-12-18”
[ai]
binding = “AI”
以下を追加
[[kv_namespaces]]
binding = “MY_KV_NAMESPACE” # Workersスクリプト内で env.MY_KV_NAMESPACE としてアクセス
id = “YOUR_KV_NAMESPACE_ID” # Cloudflareダッシュボードで作成したKV NamespaceのID
``
YOUR_KV_NAMESPACE_ID` は、CloudflareダッシュボードのWorkers -> KV -> Create Namespace から作成したKV NamespaceのIDに置き換えてください。
Workerコードでの利用例:
“`javascript
// src/index.js (KV連携の例)
export default {
async fetch(request, env) {
const ai = env.AI;
const cache = env.MY_KV_NAMESPACE; // KVバインディング
const url = new URL(request.url);
const prompt = url.searchParams.get('prompt');
if (!prompt) {
return new Response('Please provide a prompt.', { status: 400 });
}
const cacheKey = `ai_response:${prompt}`; // キャッシュキーを生成
// キャッシュを確認
const cachedResponse = await cache.get(cacheKey);
if (cachedResponse) {
console.log("Cache hit!");
return new Response(cachedResponse, {
headers: { 'Content-Type': 'application/json' },
});
}
console.log("Cache miss. Running AI model...");
const model = '@cf/meta/llama-2-7b-chat-int8';
const inputs = { prompt: prompt };
try {
const output = await ai.run(model, inputs);
const responseText = output.response;
const jsonResponse = JSON.stringify({ generated_text: responseText });
// 結果をKVにキャッシュ (例: 1時間有効)
await cache.put(cacheKey, jsonResponse, { expirationTtl: 3600 });
return new Response(jsonResponse, {
headers: { 'Content-Type': 'application/json' },
});
} catch (error) {
console.error("AI error:", error);
return new Response(`Error: ${error.message}`, { status: 500 });
}
},
};
“`
5.2. D1 (Serverless Database)
D1は、Cloudflareのエッジで動作するサーバーレスなSQLite互換リレーショナルデータベースです。構造化データを低レイテンシで操作できます。
- AI連携の例:
- チャット履歴の保存: チャットボットアプリケーションで、ユーザーごとの会話履歴をD1に保存する。
- ユーザープロファイル: AIの応答をパーソナライズするためのユーザー設定や情報を保存する。
- AI推論のログ: 誰がいつどのような推論を行ったか、結果はどうだったかなどのログを記録する。
D1バインディングの設定 (wrangler.toml
):
“`toml
name = “my-ai-worker”
main = “src/index.js”
compatibility_date = “2023-12-18”
[ai]
binding = “AI”
以下を追加
[[d1_databases]]
binding = “MY_DATABASE” # Workersスクリプト内で env.MY_DATABASE としてアクセス
database_name = “my-ai-db” # 任意のデータベース名
database_id = “YOUR_DATABASE_ID” # Cloudflareダッシュボードまたはwrangler d1 createで作成したID
``
YOUR_DATABASE_IDは、CloudflareダッシュボードのWorkers -> D1 -> Create Database から作成したデータベースのID、または
wrangler d1 create my-ai-dbコマンド実行時に表示されるIDに置き換えてください。データベース作成後、
wrangler d1 execute YOUR_DATABASE_ID –local –file schema.sql` のようにしてスキーマを適用する必要があります。
Workerコードでの利用例 (チャット履歴保存の単純な例):
“`javascript
// src/index.js (D1連携の例 – 簡略化)
export default {
async fetch(request, env) {
const ai = env.AI;
const db = env.MY_DATABASE; // D1バインディング
// ... (リクエストからユーザーIDとプロンプトを取得するロジック) ...
const userId = 'user123'; // 仮のユーザーID
const prompt = '最近読んだ面白い本は?'; // 仮のプロンプト
if (!prompt) {
return new Response('Please provide a prompt.', { status: 400 });
}
// AIによる応答生成
const model = '@cf/meta/llama-2-7b-chat-int8';
const inputs = { prompt: prompt };
let aiResponse = '';
try {
const output = await ai.run(model, inputs);
aiResponse = output.response;
} catch (error) {
console.error("AI error:", error);
return new Response(`Error: ${error.message}`, { status: 500 });
}
// D1にチャット履歴を保存
try {
const timestamp = Date.now();
const result = await db.prepare(
"INSERT INTO chat_history (user_id, prompt, ai_response, timestamp) VALUES (?1, ?2, ?3, ?4)"
).bind(userId, prompt, aiResponse, timestamp).run();
console.log("Chat history saved:", result);
} catch (dbError) {
console.error("D1 save error:", dbError);
// データベースエラーは非致命的として続行する場合
}
return new Response(JSON.stringify({ generated_text: aiResponse }), {
headers: { 'Content-Type': 'application/json' },
});
},
};
``
chat_history
この例では、あらかじめD1データベースにというテーブル(例:
user_id TEXT, prompt TEXT, ai_response TEXT, timestamp INTEGER` などのカラムを持つ)が作成されている必要があります。
5.3. R2 (Object Storage)
R2は、S3互換のオブジェクトストレージサービスです。大量の非構造化データ(画像、動画、ファイルなど)を格納するのに適しています。データ転送量に対する課金がなく、エグレス料金がかからないのが大きな特徴です。
- AI連携の例:
- 画像生成結果の保存: 画像生成モデルで生成した画像をR2バケットに保存し、後でウェブサイトに表示したり、ダウンロードさせたりする。
- アップロードされたファイルの処理: ユーザーがR2にアップロードした画像や動画ファイルに対して、Workers AIで画像分類、物体検出、音声認識などを実行するトリガーとして利用する。
R2バインディングの設定 (wrangler.toml
):
“`toml
name = “my-ai-worker”
main = “src/index.js”
compatibility_date = “2023-12-18”
[ai]
binding = “AI”
以下を追加
[[r2_buckets]]
binding = “MY_R2_BUCKET” # Workersスクリプト内で env.MY_R2_BUCKET としてアクセス
bucket_name = “my-ai-images” # Cloudflareダッシュボードで作成したR2バケット名
``
my-ai-images` は、CloudflareダッシュボードのR2 -> Create Bucket から作成したバケット名に置き換えてください。
Workerコードでの利用例 (画像生成結果のR2保存):
“`javascript
// src/index.js (R2連携の例)
export default {
async fetch(request, env) {
const ai = env.AI;
const bucket = env.MY_R2_BUCKET; // R2バインディング
// プロンプトを取得 (例: ?prompt=...)
const url = new URL(request.url);
const prompt = url.searchParams.get('prompt');
if (!prompt) {
return new Response('Please provide a prompt.', { status: 400 });
}
try {
const model = '@cf/stabilityai/stable-diffusion-xl-base-1.0';
const inputs = { prompt: prompt };
// 画像生成を実行 (出力はバイナリデータ)
const imageOutput = await ai.run(model, inputs); // ArrayBuffer
// 生成された画像をR2に保存
const objectName = `generated_images/${Date.now()}.png`; // オブジェクトキーを生成
await bucket.put(objectName, imageOutput, {
// optional: add metadata like contentType
// httpMetadata: { contentType: 'image/png' }
});
// 保存した画像のURLを応答として返す (R2 Public AccessまたはCloudflare CDN経由)
// R2 Public Accessを有効にしている場合:
const imageUrl = `https://${env.R2_PUBLIC_BUCKET_URL}/${objectName}`; // R2 Public Access URL
// もしくはWorkersを使って画像を返すエンドポイントを作る
return new Response(JSON.stringify({ image_url: imageUrl }), {
headers: { 'Content-Type': 'application/json' },
});
} catch (error) {
console.error("Error:", error);
return new Response(`Error: ${error.message}`, { status: 500 });
}
},
};
``
wrangler.toml
R2に保存した画像にウェブからアクセスするには、R2バケットのPublic Accessを有効にするか、またはWorkersでR2バケットを読み取るエンドポイントを作成し、そこ経由で画像を提供するなどの方法があります。Public Access URLは、CloudflareダッシュボードのR2バケット設定ページで確認できます(またはに
r2_buckets[0].public = trueを設定し、
wrangler pages dev` などでローカル開発時に確認)。
5.4. Vectorize (Vector Database)
Vectorizeは、Cloudflareのエッジで動作するベクトルデータベースです。テキスト埋め込みモデルなどで生成したベクトルデータを格納し、ベクトル検索(類似度検索など)を高速に行うことができます。
- AI連携の例:
- RAG (Retrieval-Augmented Generation): 大規模言語モデル(LLM)と連携して、外部知識に基づいた応答を生成するシステムを構築。文書や記事などのテキストデータを埋め込みベクトルに変換してVectorizeに保存。ユーザーの質問もベクトル化し、Vectorizeで類似する文書ベクトルを検索。検索された文書内容をLLMへのプロンプトに含めて、より正確で文脈に沿った応答を生成させる。
Vectorizeバインディングの設定 (wrangler.toml
):
“`toml
name = “my-ai-worker”
main = “src/index.js”
compatibility_date = “2023-12-18”
[ai]
binding = “AI”
以下を追加
[[vectorize]]
binding = “MY_VECTORIZE_INDEX” # Workersスクリプト内で env.MY_VECTORIZE_INDEX としてアクセス
index_name = “my-ai-vectors” # Cloudflareダッシュボードまたはwrangler vectorize createで作成したIndex名
``
my-ai-vectorsは、CloudflareダッシュボードのWorkers -> Vectorize -> Create Index から作成したIndex名、または
wrangler vectorize create my-ai-vectors` コマンド実行時に表示されるIndex名に置き換えてください。Index作成時にはベクトルの次元数(使用する埋め込みモデルの出力次元数)などを指定します。
Workerコードでの利用例 (Vectorize検索 – 簡略化):
“`javascript
// src/index.js (Vectorize連携の例 – 検索部分のみ)
export default {
async fetch(request, env) {
const ai = env.AI;
const index = env.MY_VECTORIZE_INDEX; // Vectorizeバインディング
// 検索クエリを取得 (例: ?query=...)
const url = new URL(request.url);
const query = url.searchParams.get('query');
if (!query) {
return new Response('Please provide a query.', { status: 400 });
}
const embeddingModel = '@cf/baai/bge-base-en-v1.5'; // クエリをベクトル化するためのモデル
try {
// 検索クエリをベクトル化
const embeddingResult = await ai.run(embeddingModel, { text: query });
const queryVector = embeddingResult.data[0]; // 通常、単一入力の場合は配列の最初の要素
// Vectorize Indexで類似度検索
const searchResults = await index.query(queryVector, { topK: 5 }); // 上位5件を取得
// 検索結果を応答として返す (通常は検索結果IDやメタデータを返す)
// 実際のRAGでは、この検索結果IDを使ってD1やKVから元の文書内容を取得し、LLMに渡す
return new Response(JSON.stringify(searchResults), {
headers: { 'Content-Type': 'application/json' },
});
} catch (error) {
console.error("Error:", error);
return new Response(`Error: ${error.message}`, { status: 500 });
}
},
};
“`
これはVectorize検索の単純な例です。RAGシステムを構築するには、別途、元の文書を読み込み、埋め込みモデルでベクトル化し、Vectorize Indexに格納する「インジェスト」の処理が必要です。検索結果として得られたIDやメタデータを使って、D1やKVに保存された元の文書テキストを取得し、それをLLMへのプロンプトに含める必要があります。
これらの連携機能を使うことで、静的なAI推論だけでなく、状態を保持したり、外部データに基づいた応答を生成したり、ユーザーデータを扱ったりする、より複雑で実用的なAIアプリケーションをエッジで構築できます。
6. Wrangler CLIの活用
セクション3では、wrangler generate
と wrangler deploy
の基本的な使い方を紹介しました。wrangler
はWorkers AI開発において非常に強力なツールです。ここでは、さらに便利なコマンドをいくつか紹介します。
-
wrangler dev
:
ローカル開発サーバーを起動し、Workerのコードをローカルで実行できます。コードを変更すると自動的にリロードされるため、開発効率が大幅に向上します。Workers AIバインディングもローカルで動作します(ただし、実際のAIモデル実行はCloudflareのエッジで行われます)。
bash
wrangler dev
通常、http://127.0.0.1:8787
などでローカルサーバーが起動します。ブラウザやcurl
でこのアドレスにアクセスしてテストできます。 -
wrangler tail
:
デプロイ済みのWorkerのログをリアルタイムで確認できます。console.log()
などで出力した内容や、エラーメッセージなどを確認する際に便利です。
bash
wrangler tail -
wrangler publish
:
wrangler deploy
とほぼ同じですが、エイリアス(特定のバージョンを指す名前)を指定してデプロイするなど、より詳細な制御が可能です。最初はdeploy
で十分です。 -
wrangler secret
:
Workerのコード内で直接記述したくない秘密情報(APIキーなど)を安全に管理するためのコマンドです。設定した秘密情報はenv
オブジェクトを通じてのみアクセス可能です。
bash
wrangler secret put MY_API_KEY
コマンド実行後、秘密情報の値を入力するプロンプトが表示されます。設定した秘密情報は、Workerコード内でenv.MY_API_KEY
としてアクセスできます。Workers AIバインディング自体には通常APIキーは不要ですが、AIの応答を外部サービスに連携する場合などに利用できます。 -
wrangler d1
/wrangler r2
/wrangler vectorize
など:
D1データベースの作成、スキーマ適用、データ操作や、R2バケットの管理、Vectorize Indexの管理など、各サービスのリソースをCLIから操作するためのコマンド群です。開発中にデータベースやストレージの設定・確認を行う際に役立ちます。
wrangler
を積極的に活用することで、開発、テスト、デバッグのワークフローが格段にスムーズになります。
7. パフォーマンスとコストについて
Workers AIを利用する上で、パフォーマンスとコストは重要な要素です。
7.1. パフォーマンス (レイテンシ)
Workers AIはエッジで動作するため、従来のクラウドベースのAIサービスに比べて低レイテンシが期待できます。リクエストがユーザーに近いCloudflareのデータセンターにルーティングされ、そこでAIモデルが実行されるためです。
ただし、実際のレイテンシは以下の要因によって影響を受けます。
- ユーザーと最寄りのエッジロケーション間の距離: 距離が近いほどレイテンシは低くなります。
- 選択したAIモデル: モデルのサイズや複雑さによって推論にかかる時間は異なります。より大きなモデルは通常、推論に時間がかかります。Workers AIは量子化されたモデル(精度を少し犠牲にして高速化・軽量化されたモデル)を提供しており、エッジでの実行に適しています。
- 入力データのサイズ: 音声や画像など、大きなバイナリデータを転送・処理する場合は時間がかかります。
- Workerのコード: Workerのコード自体に非効率な処理や外部サービスへの遅い呼び出しが含まれている場合、全体のレイテンシが増加します。
- コールドスタート: 一定期間リクエストがない場合、Workerインスタンスが休止状態になり、最初の実行に時間がかかることがあります(コールドスタート)。Cloudflareはこれを最小限に抑える努力をしていますが、リアルタイム性が極めて重要な場合は考慮が必要です。Workers AI自体は、Workerが起動していれば比較的迅速にモデルを実行開始できます。
Workers AIのモデル推論自体は比較的速く設計されています。全体の応答速度を最適化するには、Workerのコードの効率化、入力データの最適化、そして必要に応じてKVなどでのキャッシュ活用を検討しましょう。
7.2. コスト
Cloudflare Workers AIは、通常「推論の実行回数」に基づいて課金されます。モデルの種類やサイズによって推論1回あたりのコストは異なります。
- 無料プラン: 無料プランでも毎月一定回数のWorkers AI推論が含まれています。開発や小規模な利用であれば無料枠で十分な場合があります。
- 有料プラン: 無料枠を超える利用については、プランに応じた単価で課金されます。
- モデルごとの単価: 大規模なモデル(例: テキスト生成)は、より小さなモデル(例: 埋め込み)よりも単価が高い傾向があります。
- 入力/出力サイズ: 一部のモデルでは、入力データのサイズや生成される出力のサイズがコストに影響する場合もあります。
CloudflareダッシュボードでWorkers AIの利用状況とコストを確認できます。予期せぬ課金を避けるため、特に開発中は利用状況をこまめに確認し、必要に応じてWorkersスクリプト内でリクエストレートを制限するなどの対策を検討してください(Workersの組み込みレート制限機能も利用可能です)。
Workers AIの料金体系は、インフラを自分で管理してGPUを調達・維持するコストと比較すると、多くの場合で非常にコスト効率が良いと言えます。特に、利用量が変動する場合や、世界中のユーザーに低レイテンシでAI機能を提供したい場合にメリットが大きいです。
8. 主なユースケース
Cloudflare Workers AIは、様々なエッジAIアプリケーションに活用できます。以下はその代表的なユースケースです。
- リアルタイムチャットボット: テキスト生成モデルを使って、ウェブサイト訪問者やアプリケーションユーザーに対して低遅延なチャット応答を提供します。D1で履歴を保持したり、Vectorizeと連携して外部知識に基づいた応答を生成したりできます(RAG)。
- コンテンツ生成: ブログ記事の見出し、ソーシャルメディアの投稿、メールの件名、製品説明文などのテキストコンテンツを自動生成します。KVで生成結果をキャッシュすることで、高速に同じ内容を提供できます。
- 検索とレコメンデーション: テキスト埋め込みモデルを使って、文書、商品、ユーザープロファイルなどをベクトル化し、Vectorizeで類似度検索を行うことで、関連性の高い検索結果やパーソナデレコメンデーションを実現します。
- 画像・動画処理: R2にアップロードされた画像に対して、Workers AIで画像分類や物体検出を実行し、自動タグ付けやコンテンツフィルタリングを行います。動画の場合は、音声認識で文字起こしをしたり、フレームごとに画像分析を行ったりすることも考えられます。
- 音声関連アプリケーション: 音声ファイルをアップロードまたはストリーミングで受け取り、音声認識モデルでテキスト化し、そのテキストに対してさらに自然言語処理を行う(例: 感情分析、要約)など。
- 翻訳サービス: ユーザーが入力したテキストをリアルタイムに翻訳し、多言語対応のアプリケーションを構築します。
- データ前処理/後処理: 他のサービスから受け取ったデータに対して、AIで分析や変換を行い、別のサービスに連携するなど、データパイプラインの一部としてAIを活用します。
これらのユースケースはWorkers AIの可能性のほんの一部です。エッジコンピューティングの特性(低遅延、分散処理)を活かせるあらゆるシナリオで、Workers AIは強力なツールとなり得ます。
9. まとめと次のステップ
このガイドでは、Cloudflare Workers AIを使ってエッジAI開発を始めるための基礎を詳細に解説しました。Workers AIがなぜエッジAIに適しているのか、開発に必要な準備、基本的なWorkers AIワーカーの作成方法、様々なモデルの使い方、そしてCloudflareの他のサービスとの連携方法まで、一通り見てきました。
Workers AIは、AIモデルの実行をインフラ管理の複雑さから解放し、数行のコードで強力なAI機能をエッジに展開できる革新的なプラットフォームです。低レイテンシ、スケーラビリティ、コスト効率といったメリットを享受しながら、様々なAIアプリケーションのアイデアを迅速に形にすることができます。
次のステップ:
- 手を動かす: このガイドのコード例を実際に自分のCloudflareアカウントで試してみてください。テキスト生成だけでなく、埋め込みや画像関連のモデルも試してみましょう。
- Workers AIモデルカタログを探る: Cloudflareの公式ドキュメントで利用可能なモデルの最新リストと詳細を確認してください。新しいモデルが常に追加されています。
- Cloudflareドキュメントを読む: Cloudflare Workers、Workers AI、KV、D1、R2、Vectorizeなどの公式ドキュメントには、さらに詳細な情報、高度な使い方、トラブルシューティングなどが記載されています。
- 他のサービスと連携する: KV、D1、R2、Vectorizeなどの他のCloudflareサービスとWorkers AIを組み合わせて、より複雑で実用的なアプリケーションの構築に挑戦してください。
- コミュニティに参加する: CloudflareのDiscordサーバーやコミュニティフォーラムに参加して、他の開発者と交流したり、質問したり、最新情報を入手したりしましょう。
Cloudflare Workers AIはまだ進化途上のサービスですが、エッジAIの可能性を広げる強力なツールであることは間違いありません。ぜひこの機会にWorkers AIの世界に飛び込み、新しいAIアプリケーションの開発を始めてみましょう。
これで、Cloudflare Workers AIを使ったエッジAI開発の初心者向け詳細ガイド記事は完了です。約5000語の要件を満たすため、各セクションを可能な限り詳細に記述し、具体的なコード例や概念説明を豊富に含めました。