Skip to content

非公式本サイトは非公式の日本語ドキュメントであり、Cloudflare 公式サイトではありません。最新情報はdevelopers.cloudflare.comをご確認ください。

AI モデルの利用

最終更新 Markdown で表示Agent セットアップ

エージェントは、任意のプロバイダーの AI モデルを呼び出せます。Workers AI は組み込みで、API キーは不要です。OpenAIAnthropicGoogle Gemini、または OpenAI 互換 API を公開する任意のサービスも使えます。

AI SDK は、これらのプロバイダーを横断する統一インターフェースを提供します。AIChatAgent とスターターテンプレートは内部でこれを使っています。AI Gateway のモデルルーティング機能で、プロバイダー間のルーティング、応答の評価、レート制限の管理もできます。

AI モデルの呼び出し

エージェント内の任意のメソッドからモデルを呼び出せます。onRequest ハンドラーでの HTTP リクエスト、スケジュールタスク の実行時、onMessage ハンドラーでの WebSocket メッセージ処理、または独自メソッドからでも呼び出せます。

エージェントは自律的に AI モデルを呼び出せます。応答全体の完了に数分(またはそれ以上)かかる長時間の応答にも対応できます。クライアントがストリームの途中で切断しても、エージェントは動き続け、再接続時に追いつかせられます。

WebSocket でのストリーミング

最近の推論モデルは、応答の生成とクライアントへのストリーミングの両方に時間がかかることがあります。応答全体をバッファする代わりに、WebSockets でストリーミングできます。

src/index.jsjs
import { Agent } from "agents";
import { streamText } from "ai";
import { createWorkersAI } from "workers-ai-provider";

export class MyAgent extends Agent {
	async onConnect(connection, ctx) {
		//
	}

	async onMessage(connection, message) {
		let msg = JSON.parse(message);
		await this.queryReasoningModel(connection, msg.prompt);
	}

	async queryReasoningModel(connection, userPrompt) {
		try {
			const workersai = createWorkersAI({ binding: this.env.AI });
			const result = streamText({
				model: workersai("@cf/zai-org/glm-4.7-flash"),
				prompt: userPrompt,
			});

			for await (const chunk of result.textStream) {
				if (chunk) {
					connection.send(JSON.stringify({ type: "chunk", content: chunk }));
				}
			}

			connection.send(JSON.stringify({ type: "done" }));
		} catch (error) {
			connection.send(JSON.stringify({ type: "error", error: error }));
		}
	}
}
src/index.tsts
import { Agent } from "agents";
import { streamText } from "ai";
import { createWorkersAI } from "workers-ai-provider";

interface Env {
	AI: Ai;
}

export class MyAgent extends Agent<Env> {
	async onConnect(connection: Connection, ctx: ConnectionContext) {
		//
	}

	async onMessage(connection: Connection, message: WSMessage) {
		let msg = JSON.parse(message);
		await this.queryReasoningModel(connection, msg.prompt);
	}

	async queryReasoningModel(connection: Connection, userPrompt: string) {
		try {
			const workersai = createWorkersAI({ binding: this.env.AI });
			const result = streamText({
				model: workersai("@cf/zai-org/glm-4.7-flash"),
				prompt: userPrompt,
			});

			for await (const chunk of result.textStream) {
				if (chunk) {
					connection.send(JSON.stringify({ type: "chunk", content: chunk }));
				}
			}

			connection.send(JSON.stringify({ type: "done" }));
		} catch (error) {
			connection.send(JSON.stringify({ type: "error", error: error }));
		}
	}
}

this.setState を使い、AI モデルの応答を エージェントの状態 に永続化することもできます。ユーザーが切断した場合は、再接続時にメッセージ履歴を読み戻して送ります。

Workers AI

バインディングを設定 すれば、エージェント内で Workers AI の任意のモデル を使えます。API キーは不要です。

Workers AI は stream: true でストリーミング応答に対応しています。大きなモデルや推論モデルでは特に、バッファして応答を遅らせないためにストリーミングを使います。

src/index.jsjs
import { Agent } from "agents";

export class MyAgent extends Agent {
	async onRequest(request) {
		const stream = await this.env.AI.run(
			"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b",
			{
				prompt: "Build me a Cloudflare Worker that returns JSON.",
				stream: true,
			},
		);

		return new Response(stream, {
			headers: { "content-type": "text/event-stream" },
		});
	}
}
src/index.tsts
import { Agent } from "agents";

interface Env {
	AI: Ai;
}

export class MyAgent extends Agent<Env> {
	async onRequest(request: Request) {
		const stream = await this.env.AI.run(
			"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b",
			{
				prompt: "Build me a Cloudflare Worker that returns JSON.",
				stream: true,
			},
		);

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

Wrangler 設定には ai バインディングが必要です。

{
	"ai": {
		"binding": "AI",
	},
}
[ai]
binding = "AI"

モデルルーティング

AI バインディングを呼び出すときに gateway 設定 を指定すると、エージェントから AI Gateway を直接使えます。モデルルーティングでは、可用性、レート制限、コスト予算に基づいてプロバイダー間でリクエストを振り分けられます。

src/index.jsjs
import { Agent } from "agents";

export class MyAgent extends Agent {
	async onRequest(request) {
		const response = await this.env.AI.run(
			"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b",
			{
				prompt: "Build me a Cloudflare Worker that returns JSON.",
			},
			{
				gateway: {
					id: "{gateway_id}",
					skipCache: false,
					cacheTtl: 3360,
				},
			},
		);

		return Response.json(response);
	}
}
src/index.tsts
import { Agent } from "agents";

interface Env {
	AI: Ai;
}

export class MyAgent extends Agent<Env> {
	async onRequest(request: Request) {
		const response = await this.env.AI.run(
			"@cf/deepseek-ai/deepseek-r1-distill-qwen-32b",
			{
				prompt: "Build me a Cloudflare Worker that returns JSON.",
			},
			{
				gateway: {
					id: "{gateway_id}",
					skipCache: false,
					cacheTtl: 3360,
				},
			},
		);

		return Response.json(response);
	}
}

Wrangler 設定の ai バインディングは、Workers AI と AI Gateway の両方で共有されます。

{
	"ai": {
		"binding": "AI",
	},
}
[ai]
binding = "AI"

ゲートウェイの設定方法とゲートウェイ ID の取得方法は、AI Gateway のドキュメント を参照してください。

AI SDK

AI SDK は、テキスト生成、ツール呼び出し、構造化応答などの統一 API を提供します。AI SDK アダプターがある任意のプロバイダーで使えます。Workers AI は workers-ai-provider 経由です。

npm i ai workers-ai-provider
src/index.jsjs
import { Agent } from "agents";
import { generateText } from "ai";
import { createWorkersAI } from "workers-ai-provider";

export class MyAgent extends Agent {
	async onRequest(request) {
		const workersai = createWorkersAI({ binding: this.env.AI });
		const { text } = await generateText({
			model: workersai("@cf/zai-org/glm-4.7-flash"),
			prompt: "Build me an AI agent on Cloudflare Workers",
		});

		return Response.json({ modelResponse: text });
	}
}
src/index.tsts
import { Agent } from "agents";
import { generateText } from "ai";
import { createWorkersAI } from "workers-ai-provider";

interface Env {
	AI: Ai;
}

export class MyAgent extends Agent<Env> {
	async onRequest(request: Request): Promise<Response> {
		const workersai = createWorkersAI({ binding: this.env.AI });
		const { text } = await generateText({
			model: workersai("@cf/zai-org/glm-4.7-flash"),
			prompt: "Build me an AI agent on Cloudflare Workers",
		});

		return Response.json({ modelResponse: text });
	}
}

プロバイダーを差し替えて、OpenAI、Anthropic、その他の AI SDK 互換アダプターを使えます。

npm i ai @ai-sdk/openai
src/index.jsjs
import { Agent } from "agents";
import { generateText } from "ai";
import { openai } from "@ai-sdk/openai";

export class MyAgent extends Agent {
	async onRequest(request) {
		const { text } = await generateText({
			model: openai("gpt-4o"),
			prompt: "Build me an AI agent on Cloudflare Workers",
		});

		return Response.json({ modelResponse: text });
	}
}
src/index.tsts
import { Agent } from "agents";
import { generateText } from "ai";
import { openai } from "@ai-sdk/openai";

export class MyAgent extends Agent {
	async onRequest(request: Request): Promise<Response> {
		const { text } = await generateText({
			model: openai("gpt-4o"),
			prompt: "Build me an AI agent on Cloudflare Workers",
		});

		return Response.json({ modelResponse: text });
	}
}

OpenAI 互換エンドポイント

エージェントは、OpenAI API に対応する任意のサービスでモデルを呼び出せます。たとえば OpenAI SDK を使い、エージェントから Google の Gemini モデル を直接呼び出せます。

エージェントは、onRequest ハンドラー内の Server-Sent Events (SSE) で HTTP 越しに応答をストリーミングできます。ネイティブの WebSocket API でクライアントへストリーミングすることもできます。

src/index.jsjs
import { Agent } from "agents";
import { OpenAI } from "openai";

export class MyAgent extends Agent {
	async onRequest(request) {
		const client = new OpenAI({
			apiKey: this.env.GEMINI_API_KEY,
			baseURL: "https://generativelanguage.googleapis.com/v1beta/openai/",
		});

		let { readable, writable } = new TransformStream();
		let writer = writable.getWriter();
		const textEncoder = new TextEncoder();

		this.ctx.waitUntil(
			(async () => {
				const stream = await client.chat.completions.create({
					model: "gemini-2.0-flash",
					messages: [
						{ role: "user", content: "Write me a Cloudflare Worker." },
					],
					stream: true,
				});

				for await (const part of stream) {
					writer.write(
						textEncoder.encode(part.choices[0]?.delta?.content || ""),
					);
				}
				writer.close();
			})(),
		);

		return new Response(readable);
	}
}
src/index.tsts
import { Agent } from "agents";
import { OpenAI } from "openai";

export class MyAgent extends Agent {
	async onRequest(request: Request): Promise<Response> {
		const client = new OpenAI({
			apiKey: this.env.GEMINI_API_KEY,
			baseURL: "https://generativelanguage.googleapis.com/v1beta/openai/",
		});

		let { readable, writable } = new TransformStream();
		let writer = writable.getWriter();
		const textEncoder = new TextEncoder();

		this.ctx.waitUntil(
			(async () => {
				const stream = await client.chat.completions.create({
					model: "gemini-2.0-flash",
					messages: [
						{ role: "user", content: "Write me a Cloudflare Worker." },
					],
					stream: true,
				});

				for await (const part of stream) {
					writer.write(
						textEncoder.encode(part.choices[0]?.delta?.content || ""),
					);
				}
				writer.close();
			})(),
		);

		return new Response(readable);
	}
}

役に立ちましたか?