エージェントは、任意のプロバイダーの AI モデルを呼び出せます。Workers AI は組み込みで、API キーは不要です。OpenAI ↗、Anthropic ↗、Google Gemini ↗、または OpenAI 互換 API を公開する任意のサービスも使えます。
AI SDK ↗ は、これらのプロバイダーを横断する統一インターフェースを提供します。AIChatAgent とスターターテンプレートは内部でこれを使っています。AI Gateway のモデルルーティング機能で、プロバイダー間のルーティング、応答の評価、レート制限の管理もできます。
エージェント内の任意のメソッドからモデルを呼び出せます。onRequest ハンドラーでの HTTP リクエスト、スケジュールタスク の実行時、onMessage ハンドラーでの WebSocket メッセージ処理、または独自メソッドからでも呼び出せます。
エージェントは自律的に AI モデルを呼び出せます。応答全体の完了に数分(またはそれ以上)かかる長時間の応答にも対応できます。クライアントがストリームの途中で切断しても、エージェントは動き続け、再接続時に追いつかせられます。
最近の推論モデルは、応答の生成とクライアントへのストリーミングの両方に時間がかかることがあります。応答全体をバッファする代わりに、WebSockets でストリーミングできます。
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 }));
}
}
}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 の任意のモデル を使えます。API キーは不要です。
Workers AI は stream: true でストリーミング応答に対応しています。大きなモデルや推論モデルでは特に、バッファして応答を遅らせないためにストリーミングを使います。
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" },
});
}
}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 を直接使えます。モデルルーティングでは、可用性、レート制限、コスト予算に基づいてプロバイダー間でリクエストを振り分けられます。
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);
}
}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 ↗ は、テキスト生成、ツール呼び出し、構造化応答などの統一 API を提供します。AI SDK アダプターがある任意のプロバイダーで使えます。Workers AI は workers-ai-provider ↗ 経由です。
npm i ai workers-ai-provideryarn add ai workers-ai-providerpnpm add ai workers-ai-providerbun add ai workers-ai-providerimport { 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 });
}
}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/openaiyarn add ai @ai-sdk/openaipnpm add ai @ai-sdk/openaibun add ai @ai-sdk/openaiimport { 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 });
}
}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 API に対応する任意のサービスでモデルを呼び出せます。たとえば OpenAI SDK を使い、エージェントから Google の Gemini モデル ↗ を直接呼び出せます。
エージェントは、onRequest ハンドラー内の Server-Sent Events (SSE) で HTTP 越しに応答をストリーミングできます。ネイティブの WebSocket API でクライアントへストリーミングすることもできます。
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);
}
}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);
}
}