mcpField
C
cloudflare-workers-ai

cloudflare-workers-ai

github.com/jackspaceクラウド・DevOps1643 回インストール12 週間前に更新
リポジトリ

cloudflare-workers-ai について

Cloudflare Workers AI を使うアプリ開発者向けのリファレンススキルです。モデル呼び出しや本番運用のパターンに加え、AI Gateway、制限、エラー処理を扱います。

主な機能

  1. 01テキスト生成とストリーミング
  2. 02埋め込み・画像・ビジョンモデルの呼び出し
  3. 03モデル選択とパラメーターの解説
  4. 04AI Gateway の連携パターン
  5. 05制限・監視・エラー処理

活用シーン

  1. 01Worker にテキストや画像生成を追加
  2. 02埋め込みを RAG フローで利用
  3. 03AI Gateway 経由でリクエストを記録・キャッシュ

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/jackspace/claudeskillz --skill cloudflare-workers-ai

インストール後、Claude Code で/cloudflare-workers-aiを入力して読み込まれたか確認します。

同梱ファイルREADME.mdSKILL.json

詳細

Cloudflare Workers AI - 完全リファレンス

Cloudflare Workers AI を使用して AI 搭載アプリケーションを構築するための、本番環境対応のナレッジドメインです。

ステータス:本番環境対応 ✅ 最終更新日:2025-10-21 依存関係:cloudflare-worker-base(Worker のセットアップ用) 最新バージョン:[email protected]、@cloudflare/[email protected]


目次

  1. クイックスタート(5 分)
  2. Workers AI API リファレンス
  3. モデル選択ガイド
  4. 一般的なパターン
  5. AI Gateway の統合
  6. レート制限と料金
  7. 本番環境チェックリスト

クイックスタート(5 分)

1. AI バインディングを追加

wrangler.jsonc:

{
  "ai": {
    "binding": "AI"
  }
}
2. 最初のモデルを実行
export interface Env {
  AI: Ai;
}

export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    const response = await env.AI.run('@cf/meta/llama-3.1-8b-instruct', {
      prompt: 'What is Cloudflare?',
    });

    return Response.json(response);
  },
};
3. ストリーミングを追加(推奨)
const stream = await env.AI.run('@cf/meta/llama-3.1-8b-instruct', {
  messages: [{ role: 'user', content: 'Tell me a story' }],
  stream: true, // Always use streaming for text generation!
});

return new Response(stream, {
  headers: { 'content-type': 'text/event-stream' },
});

ストリーミングを使う理由

  • 大きなレスポンスがメモリにバッファリングされるのを防ぎます
  • 最初のトークンが届くまでの時間を短縮します
  • 長文コンテンツのユーザーエクスペリエンスが向上します
  • Worker のタイムアウト問題を回避できます

Workers AI API リファレンス

env.AI.run()

AI モデルの推論を実行します。

シグネチャ:

async env.AI.run(
  model: string,
  inputs: ModelInputs,
  options?: { gateway?: { id: string; skipCache?: boolean } }
): Promise<ModelOutput | ReadableStream>

パラメーター:

  • model(string、必須)- モデル ID(例:@cf/meta/llama-3.1-8b-instruct)
  • inputs(object、必須)- モデル固有の入力
  • options(object、任意)- 追加オプション
    • gateway(object)- AI Gateway の設定
      • id(string)- Gateway ID
      • skipCache(boolean)- AI Gateway のキャッシュをスキップします

戻り値:

  • 非ストリーミング:Promise<ModelOutput - JSON レスポンス
  • ストリーミング:ReadableStream - サーバー送信イベントのストリーム

テキスト生成モデル

入力形式:

{
  messages?: Array<{ role: 'system' | 'user' | 'assistant'; content: string }>;
  prompt?: string; // Deprecated, use messages
  stream?: boolean; // Default: false
  max_tokens?: number; // Max tokens to generate
  temperature?: number; // 0.0-1.0, default varies by model
  top_p?: number; // 0.0-1.0
  top_k?: number;
}

出力形式(非ストリーミング):

{
  response: string; // Generated text
}

例:

const response = await env.AI.run('@cf/meta/llama-3.1-8b-instruct', {
  messages: [
    { role: 'system', content: 'You are a helpful assistant.' },
    { role: 'user', content: 'What is TypeScript?' },
  ],
  stream: false,
});

console.log(response.response);

テキスト埋め込みモデル

入力形式:

{
  text: string | string[]; // Single text or array of texts
}

出力形式:

{
  shape: number[]; // [batch_size, embedding_dimensions]
  data: number[][]; // Array of embedding vectors
}

例:

const embeddings = await env.AI.run('@cf/baai/bge-base-en-v1.5', {
  text: ['Hello world', 'Cloudflare Workers'],
});

console.log(embeddings.shape); // [2, 768]
console.log(embeddings.data[0]); // [0.123, -0.456, ...]

画像生成モデル

入力形式:

{
  prompt: string; // Text description
  num_steps?: number; // Default: 20
  guidance?: number; // CFG scale, default: 7.5
  strength?: number; // For img2img, default: 1.0
  image?: number[][]; // For img2img (base64 or array)
}

出力形式:

  • バイナリ画像データ(PNG/JPEG)

例:

const imageStream = await env.AI.run('@cf/black-forest-labs/flux-1-schnell', {
  prompt: 'A beautiful sunset over mountains',
});

return new Response(imageStream, {
  headers: { 'content-type': 'image/png' },
});

ビジョンモデル

入力形式:

{
  messages: Array<{
    role: 'user' | 'assistant';
    content: Array<{ type: 'text' | 'image_url'; text?: string; image_url?: { url: string } }>;
  }>;
}

例:

const response = await env.AI.run('@cf/meta/llama-3.2-11b-vision-instruct', {
  messages: [
    {
      role: 'user',
      content: [
        { type: 'text', text: 'What is in this image?' },
        { type: 'image_url', image_url: { url: 'data:image/png;base64,iVBOR...' } },
      ],
    },
  ],
});

モデル選択ガイド

テキスト生成(LLM)
モデル最適な用途レート制限サイズ
@cf/meta/llama-3.1-8b-instruct汎用、高速300/min8B
@cf/meta/llama-3.2-1b-instruct超高速、単純なタスク300/min1B
@cf/qwen/qwen1.5-14b-chat-awq高品質、複雑な推論150/min14B
@cf/deepseek-ai/deepseek-r1-distill-qwen-32bコーディング、技術コンテンツ300/min32B
@hf/thebloke/mistral-7b-instruct-v0.1-awq高速、効率的400/min7B
テキスト埋め込み
モデル次元数最適な用途レート制限
@cf/baai/bge-base-en-v1.5768汎用 RAG3000/min
@cf/baai/bge-large-en-v1.51024高精度検索1500/min
@cf/baai/bge-small-en-v1.5384高速、低ストレージ使用量3000/min
画像生成
モデル最適な用途レート制限速度
@cf/black-forest-labs/flux-1-schnell高品質、フォトリアリスティック720/min高速
@cf/stabilityai/stable-diffusion-xl-base-1.0汎用720/min中速
@cf/lykon/dreamshaper-8-lcm芸術的、スタイライズされた画像720/min高速
ビジョンモデル
モデル最適な用途レート制限
@cf/meta/llama-3.2-11b-vision-instruct画像理解720/min
@cf/unum/uform-gen2-qwen-500m高速な画像キャプション生成720/min

一般的なパターン

パターン 1:履歴を使ったチャット補完
app.post('/chat', async (c) => {
  const { messages } = await c.req.json<{
    messages: Array<{ role: string; content: string }>;
  }>();

  const response = await c.env.AI.run('@cf/meta/llama-3.1-8b-instruct', {
    messages,
    stream: true,
  });

  return new Response(response, {
    headers: { 'content-type': 'text/event-stream' },
  });
});

パターン 2:RAG(検索拡張生成)
// Step 1: Generate embeddings
const embeddings = await env.AI.run('@cf/baai/bge-base-en-v1.5', {
  text: [userQuery],
});

const vector = embeddings.data[0];

// Step 2: Search Vectorize
const matches = await env.VECTORIZE.query(vector, { topK: 3 });

// Step 3: Build context from matches
const context = matches.matches.map((m) => m.metadata.text).join('\n\n');

// Step 4: Generate response with context
const response = await env.AI.run('@cf/meta/llama-3.1-8b-instruct', {
  messages: [
    {
      role: 'system',
      content: `Answer using this context:\n${context}`,
    },
    { role: 'user', content: userQuery },
  ],
  stream: true,
});

return new Response(response, {
  headers: { 'content-type': 'text/event-stream' },
});

パターン 3:Zod による構造化出力
import { z } from 'zod';

const RecipeSchema = z.object({
  name: z.string(),
  ingredients: z.array(z.string()),
  instructions: z.array(z.string()),
  prepTime: z.number(),
});

app.post('/recipe', async (c) => {
  const { dish } = await c.req.json<{ dish: string }>();

  const response = await c.env.AI.run('@cf/meta/llama-3.1-8b-instruct', {
    messages: [
      {
        role: 'user',
        content: `Generate a recipe for ${dish}. Return ONLY valid JSON matching this schema: ${JSON.stringify(RecipeSchema.shape)}`,
      },
    ],
  });

  // Parse and validate
  const recipe = RecipeSchema.parse(JSON.parse(response.response));

  return c.json(recipe);
});

パターン 4:画像生成と R2 ストレージ
app.post('/generate-image', async (c) => {
  const { prompt } = await c.req.json<{ prompt: string }>();

  // Generate image
  const imageStream = await c.env.AI.run('@cf/black-forest-labs/flux-1-schnell', {
    prompt,
  });

  const imageBytes = await new Response(imageStream).bytes();

  // Store in R2
  const key = `images/${Date.now()}.png`;
  await c.env.BUCKET.put(key, imageBytes, {
    httpMetadata: { contentType: 'image/png' },
  });

  return c.json({
    success: true,
    url: `https://your-domain.com/${key}`,
  });
});

AI Gateway の統合

AI Gateway は、AI リクエストのキャッシュ、ログ記録、分析を提供します。

セットアップ:

const response = await env.AI.run(
  '@cf/meta/llama-3.1-8b-instruct',
  { prompt: 'Hello' },
  {
    gateway: {
      id: 'my-gateway', // Your gateway ID
      skipCache: false, // Use cache
    },
  }
);

メリット:

  • ✅ コスト追跡 - リクエストごとのニューロン使用量を監視します
  • ✅ キャッシュ - 重複する推論コストを削減します
  • ✅ ログ記録 - AI リクエストをデバッグして分析します
  • ✅ レート制限 - 保護をさらに強化します
  • ✅ 分析 - リクエストのパターンとパフォーマンスを把握します

ゲートウェイログへのアクセス:

const gateway = env.AI.gateway('my-gateway');
const logId = env.AI.aiGatewayLogId;

// Send feedback
await gateway.patchLog(logId, {
  feedback: { rating: 1, comment: 'Great response' },
});

レート制限と料金

レート制限(1 分あたり)
タスクの種類デフォルトの上限備考
テキスト生成300/min一部の高速モデル:400-1500/min
テキスト埋め込み3000/minBGE-large:1500/min
画像生成720/minすべての画像モデル
ビジョンモデル720/min画像理解
翻訳720/minM2M100、Opus MT
分類2000/minテキスト分類
音声認識720/minWhisper モデル
料金(ニューロンベース)

無料プラン:

  • 1 日あたり 10,000 ニューロン
  • 毎日 00:00 UTC にリセットされます

有料プラン:

  • 1,000 ニューロンあたり $0.011
  • 1 日あたり 10,000 ニューロンを含みます
  • 無料割り当てを超えても使用量は無制限です

料金例:

モデル入力(100 万トークン)出力(100 万トークン)
Llama 3.2 1B$0.027$0.201
Llama 3.1 8B$0.088$0.606
BGE-base の埋め込み$0.005該当なし
Flux 画像生成約 $0.011/画像該当なし

本番環境へのデプロイ前チェックリスト

デプロイ前
  • コスト追跡とログ記録のために AI Gateway を有効化 します
  • すべてのテキスト生成エンドポイントに ストリーミングを実装 します
  • 指数バックオフによる レート制限の再試行を追加 します
  • トークン上限エラーを防ぐために 入力の長さを検証 します
  • 適切なタイムアウトを設定 します(Workers:CPU のデフォルトは 30 秒、最大 5 分)
  • Cloudflare ダッシュボードで ニューロン使用量を監視 します
  • モデルが利用できない場合やレート制限時の エラー処理をテスト します
  • プロンプトインジェクションを防ぐために 入力のサニタイズを追加 します
  • ブラウザーから使用する場合は CORS を設定 します
  • スケールを計画 します。必要に応じて有料プランにアップグレードします
エラー処理
async function runAIWithRetry(
  env: Env,
  model: string,
  inputs: any,
  maxRetries = 3
): Promise<any> {
  let lastError: Error;

  for (let i = 0; i < maxRetries; i++) {
    try {
      return await env.AI.run(model, inputs);
    } catch (error) {
      lastError = error as Error;
      const message = lastError.message.toLowerCase();

      // Rate limit - retry with backoff
      if (message.includes('429') || message.includes('rate limit')) {
        const delay = Math.pow(2, i) * 1000; // Exponential backoff
        await new Promise((resolve) => setTimeout(resolve, delay));
        continue;
      }

      // Other errors - throw immediately
      throw error;
    }
  }

  throw lastError!;
}
監視
app.use('*', async (c, next) => {
  const start = Date.now();

  await next();

  // Log AI usage
  console.log({
    path: c.req.path,
    duration: Date.now() - start,
    logId: c.env.AI.aiGatewayLogId,
  });
});

OpenAI 互換性

Workers AI は OpenAI 互換のエンドポイントをサポートしています。

OpenAI SDK の使用:

import OpenAI from 'openai';

const openai = new OpenAI({
  apiKey: env.CLOUDFLARE_API_KEY,
  baseURL: `https://api.cloudflare.com/client/v4/accounts/${env.CLOUDFLARE_ACCOUNT_ID}/ai/v1`,
});

// Chat completions
const completion = await openai.chat.completions.create({
  model: '@cf/meta/llama-3.1-8b-instruct',
  messages: [{ role: 'user', content: 'Hello!' }],
});

// Embeddings
const embeddings = await openai.embeddings.create({
  model: '@cf/baai/bge-base-en-v1.5',
  input: 'Hello world',
});

エンドポイント:

  • /v1/chat/completions - テキスト生成
  • /v1/embeddings - テキスト埋め込み

Vercel AI SDK の統合

npm install workers-ai-provider ai
import { createWorkersAI } from 'workers-ai-provider';
import { generateText, streamText } from 'ai';

const workersai = createWorkersAI({ binding: env.AI });

// Generate text
const result = await generateText({
  model: workersai('@cf/meta/llama-3.1-8b-instruct'),
  prompt: 'Write a poem',
});

// Stream text
const stream = streamText({
  model: workersai('@cf/meta/llama-3.1-8b-instruct'),
  prompt: 'Tell me a story',
});

制限の概要

機能上限
同時リクエスト数ハードリミットなし(レート制限は適用されます)
入力トークンの最大数モデルによって異なります(通常 2K-128K)
出力トークンの最大数モデルによって異なります(通常 512-2048)
ストリーミングチャンクのサイズ約 1 KB
画像サイズ(出力)約 5 MB
リクエストのタイムアウトWorkers のタイムアウトが適用されます(デフォルト 30 秒、CPU の最大値 5 分)
1 日あたりの無料ニューロン数10,000
レート制限「レート制限と料金」セクションを参照してください

参考資料

コメント