Cloudflare Workers AIをSvelteKitで使った話

Cloudflare Workers AIを使うと、Cloudflareのエッジネットワーク上でAIモデルを直接実行できます。外部のAI APIを別途契約しなくても、Cloudflareアカウントだけで利用できます。


セットアップ

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

"ai": {
  "binding": "AI"
}

2. src/app.d.ts に型を追加

interface Platform {
  env: {
    DB: D1Database;
    BUCKET: R2Bucket;
    VISIT_COUNTER: KVNamespace;
    AI: Ai;                    // ← 追加
    GITHUB_CLIENT_ID: string;
    GITHUB_CLIENT_SECRET: string;
  };
}

実装例:テキスト生成

src/routes/ai/+page.server.ts

import type { PageServerLoad, Actions } from './$types';

export const load: PageServerLoad = () => {
  return { answer: null };
};

export const actions: Actions = {
  ask: async ({ request, platform }) => {
    const data = await request.formData();
    const question = data.get('question') as string;

    const result = await platform!.env.AI.run(
      '@cf/meta/llama-3.1-8b-instruct',
      {
        prompt: question,
      }
    );

    return { answer: result.response };
  },
};

src/routes/ai/+page.svelte

<script lang="ts">
  import { enhance } from '$app/forms';
  let { form } = $props();
</script>

<h1>Workers AI チャット</h1>

<form method="POST" action="?/ask" use:enhance>
  <input type="text" name="question" placeholder="質問を入力" style="width: 300px" />
  <button type="submit">送信</button>
</form>

{#if form?.answer}
  <h2>回答</h2>
  <p>{form.answer}</p>
{/if}

入力形式について

モデルによって受け付ける入力形式が異なります。

形式 説明
prompt シンプルなテキスト入力
messages チャット形式(role: system/user/assistant)

@cf/meta/llama-3.1-8b-instructprompt 形式で動作します。messages 形式を使う場合は as any でキャストが必要になることがあります。

// prompt形式(動作確認済み)
const result = await platform!.env.AI.run(
  '@cf/meta/llama-3.1-8b-instruct',
  { prompt: question }
);

// messages形式(型エラーが出る場合はas anyでキャスト)
const result = await (platform!.env.AI.run as any)(
  '@cf/meta/llama-3.1-8b-instruct',
  {
    messages: [
      { role: 'system', content: 'あなたは親切なアシスタントです。' },
      { role: 'user', content: question },
    ],
  }
);

無料枠と課金について

項目 内容
無料枠 10,000 Neurons / 日
超過した場合 自動課金($0.011 / 1,000 Neurons)
使用量の確認 ダッシュボード → AI → Workers AI

学習用途では無料枠を超えることはほぼありません(質問1回あたり数十Neurons程度)。

課金を防ぐ対策

① KVでリクエスト数を制限する

const kv = platform!.env.VISIT_COUNTER;
const today = new Date().toISOString().slice(0, 10);
const key = `ai-count:${today}`;
const count = Number(await kv.get(key) ?? 0);

if (count >= 10) {
  return { answer: null, error: '本日の利用上限に達しました' };
}

await kv.put(key, String(count + 1), { expirationTtl: 60 * 60 * 24 });

② 本番デプロイはせずローカルのみで使う

wrangler dev はローカル実行でもCloudflareのAPIを経由しますが、URLが公開されないため外部から叩かれる心配はありません。

③ 使わないときはバインディングを外す

wrangler.jsonc"ai" の設定を削除してデプロイすれば、本番環境からAI機能を無効化できます。


主なモデルカテゴリ

カテゴリ モデル例 用途
テキスト生成 @cf/meta/llama-3.1-8b-instruct チャット・要約・翻訳
画像生成 @cf/black-forest-labs/flux-1-schnell テキストから画像
埋め込み @cf/baai/bge-base-en-v1.5 ベクトル検索
画像分類 @cf/microsoft/resnet-50 画像の内容認識

利用可能なモデルの一覧はCloudflareダッシュボードの AI → モデル から確認できます。


まとめ

  • wrangler.jsonc"ai": { "binding": "AI" } を追加するだけで利用できる
  • platform.env.AI.run(モデル名, 入力) でAI推論を実行する
  • モデルによって prompt 形式と messages 形式がある
  • 無料枠は10,000 Neurons/日で学習用途には十分
← トップページに戻る