AI SDK·续
Use it in Think
Return a model from getModel():
import { Think } from "@cloudflare/think";
import { createAI } from "agents/models/ai-sdk";
export class Assistant extends Think {
getModel() {
return createAI({ binding: this.env.AI })("@cf/moonshotai/kimi-k2.7-code");
}
}
import { Think } from "@cloudflare/think";
import { createAI } from "agents/models/ai-sdk";
export class Assistant extends Think<Env> {
getModel() {
return createAI({ binding: this.env.AI })("@cf/moonshotai/kimi-k2.7-code");
}
}
Cache responses
AI Gateway can cache responses. Set cacheTtl in seconds, and optionally a cacheKey. Pass skipCache: true on a call to bypass the cache:
const ai = createAI({ binding: env.AI, id: "prod", cacheTtl: 60 });
// A longer TTL for one model.
const faq = ai("@cf/zai-org/glm-4.7-flash", {
cacheTtl: 3600,
cacheKey: "faq-v1",
});
// Skip the cache for one call.
await generateText({
model: faq,
prompt: "What changed today?",
providerOptions: { cloudflare: { skipCache: true } },
});
Tag requests for logs and analytics
Attach metadata to the gateway log entry. Set it once on the provider and add to it per call. Metadata merges key by key:
const ai = createAI({ binding: env.AI, metadata: { app: "support-bot" } });
await generateText({
model: ai(anthropic("claude-opus-5-5")),
prompt: "Summarize this ticket",
providerOptions: {
cloudflare: { metadata: { userId: "u_123" }, eventId: "ticket-42" },
},
});
eventId groups several requests into one gateway event, such as all the model calls in one agent turn.
Fall back to another model
fallback lists models to try in order if the primary model fails before it produces any output. A fallback model can be a Workers AI id, a catalog id, a dynamic route, or a model object:
const model = ai(anthropic("claude-opus-5-5"), {
fallback: ["openai/gpt-5.5", "dynamic/support", "@cf/zai-org/glm-4.7-flash"],
});
A model object in the list goes to the provider-native endpoint, like ai(model).
A request that the vendor rejects falls back. So does a stream that fails before its first output part. Once a model has produced output, its answer is final, errors included. providerMetadata.cloudflare.model names the model that answered.
Each fallback model uses the chain's gateway options. The chain's id, cacheTtl, and the other gateway options win over a fallback model's own, and metadata merges. The headers, Workers AI options, and vendorKey a fallback model was built with stay its own.
Fallback runs in your Worker and moves across models. Within one catalog model, AI Gateway already retries across that model's providers, and a dynamic route runs its own fallback on the gateway.
Set options
Set gateway options on the provider, on a model, or per call under providerOptions.cloudflare. A per-call option wins over a per-model option, which wins over the provider's:
// Provider
const ai = createAI({ binding: env.AI, id: "prod", metadata: { app: "demo" } });
// Model
const model = ai("anthropic/claude-opus-5.5", { cacheTtl: 3600 });
// Call
await generateText({
model,
prompt: "hi",
providerOptions: {
cloudflare: { skipCache: true, metadata: { userId: "u1" } },
},
});
The provider removes providerOptions.cloudflare before the call reaches a vendor's model, so the vendor never sees it.
Gateway options can be given flat or nested: { cacheTtl: 60 } and { gateway: { cacheTtl: 60 } } are the same.
| Option | Type | Description |
|---|---|---|
binding |
Ai |
The AI binding. Provider only. |
accountId |
string |
The account for an account id and API token. Provider only. |
apiToken |
string |
A Cloudflare API token for that account. Provider only. |
id |
string |
Gateway id. Defaults to "default", which is created the first time you use it. |
gateway |
string \| GatewayOptions |
The gateway id, or the gateway options nested. |
skipCache |
boolean |
Bypass the gateway cache. |
cacheTtl |
number |
Cache lifetime in seconds. |
cacheKey |
string |
Cache key to use instead of the one derived from the request. |
collectLog |
boolean |
Whether the gateway stores the request and response in its log. |
metadata |
Record<string, string \| number \| boolean \| null> |
Values attached to the gateway log entry. |
eventId |
string |
Groups several requests into one gateway event. |
requestTimeoutMs |
number |
Timeout for the upstream request. |
retries |
{ maxAttempts, retryDelayMs, backoff } |
Gateway retry policy for the upstream call. maxAttempts is 1 to 5. |
byokAlias |
string |
A stored BYOK key, by alias. Catalog models and model objects. |
zdr |
boolean |
Zero Data Retention on or off for a Unified Billing request. Model objects only. |
vendorKey |
"gateway" \| "request" |
"request" forwards the vendor key on the request. Model objects only, per model. |
fallback |
(CloudflareLanguageModelId \| LanguageModelV4)[] |
Models to try in order. Model and call only. |
headers |
Record<string, string> |
Extra request headers, merged last. Model and call only. |
sessionAffinity |
string |
Workers AI only. Sends requests with the same key to one replica for prefix caching. |
reasoningEffort |
"low" \| "medium" \| "high" \| null |
Sent as reasoning_effort. null turns reasoning off on models that allow it. |
chatTemplateKwargs |
Record<string, unknown> |
Workers AI only. Sent as chat_template_kwargs, for example { enable_thinking: false }. |
reasoningEffort applies to Workers AI models, catalog models, and dynamic routes. When it is not set, the AI SDK's reasoning call option maps onto it. For a model object, ask for reasoning with the AI SDK's reasoning call option or the vendor's own providerOptions. The provider ignores reasoningEffort and chatTemplateKwargs on a model object and adds a warning.
Read gateway metadata
Every result, and every stream's finish part, carries providerMetadata.cloudflare. For a vendor's model it sits next to the vendor's own metadata:
const { providerMetadata } = await generateText({
model: ai(anthropic("claude-opus-5-5")),
prompt: "hi",
});
providerMetadata?.cloudflare;
// {
// model: "claude-opus-5-5",
// provider: "anthropic",
// gateway: "default",
// logId: "019a7b3e-5f2c-7c41-9d3e-2b8f6a1c4e07",
// cacheStatus: "MISS",
// ...
// }
| Field | Description |
|---|---|
model |
The model that answered, after any fallback. |
gateway |
The gateway id, when a gateway handled the request. |
provider |
The gateway provider, for a model object. |
logId |
The gateway log entry, from cf-aig-log-id. |
eventId |
The gateway event, from cf-aig-event-id. |
requestId |
The gateway request id, from cf-aig-request-id. |
traceId |
The trace this request belongs to, from cf-aig-trace-id. |
runId |
The streamed run, from cf-aig-run-id, for a catalog model or a dynamic route. |
cacheStatus |
HIT or MISS, from cf-aig-cache-status. |
step |
The step of a gateway route that answered, from cf-aig-step. |
Only model is always present. Check for the other fields before you use them.
Handle errors
The provider throws CloudflareAIError, which extends the AI SDK's APICallError, for Workers AI failures, AI Gateway failures, failed stream resumes, and a fallback chain where every model failed. The AI SDK's retry loop reads its isRetryable flag:
import { CloudflareAIError } from "agents/models/ai-sdk";
try {
await generateText({ model: ai("@cf/zai-org/glm-4.7-flash"), prompt: "hi" });
} catch (error) {
if (error instanceof CloudflareAIError) {
console.log(error.status, error.code, error.logId, error.model);
// error.attempts lists every fallback model that failed.
}
}
code is one of "auth", "rate-limit", "not-found", "bad-request", "provider-error", "gateway-error", or "unknown".
For a model object, CloudflareAIError covers the gateway's own failures, such as a missing gateway or an unpaid account. The vendor's own errors, such as an unknown model id or a rate limit, come from the vendor's provider in its own error type.
Use other modalities
Embeddings, images, speech, transcription, and reranking use Workers AI models from the same provider. Each method also has its ProviderV4 name, such as ai.embeddingModel():
import {
embedMany,
generateImage,
generateSpeech,
rerank,
transcribe,
} from "ai";
const { embeddings } = await embedMany({
model: ai.embedding("@cf/baai/bge-base-en-v1.5"),
values: ["hello", "world"],
});
const { image } = await generateImage({
model: ai.image("@cf/black-forest-labs/flux-1-schnell"),
prompt: "A cyberpunk lizard",
});
const { audio } = await generateSpeech({
model: ai.speech("@cf/deepgram/aura-1"),
text: "Hello from Cloudflare.",
});
const { text } = await transcribe({
model: ai.transcription("@cf/openai/whisper-large-v3-turbo"),
audio: audio.uint8Array,
});
const { rerankedDocuments } = await rerank({
model: ai.reranking("@cf/baai/bge-reranker-base"),
documents: ["a cyberpunk lizard", "a rainy Tuesday"],
query: "Which one is cooler?",
});
Model-specific settings go under providerOptions.cloudflare:
| Modality | Call options used | providerOptions.cloudflare |
|---|---|---|
| Image | prompt, n, size, seed, files, mask |
steps, guidance, negativePrompt, strength |
| Speech | text, voice (as speaker), outputFormat (as encoding), language (MeloTTS only) |
None |
| Transcription | audio, mediaType |
language, task, initialPrompt, prefix, vadFilter |
| Reranking | query, documents, topN (as top_k) |
None |
An option a model does not take is listed in the result's warnings instead of being sent. For example, flux-1-schnell takes only a prompt and steps, and @cf/deepgram/nova-3 takes language but not the Whisper-only transcription options. Image generation makes one image per request, so generateImage with a larger n sends parallel requests.
These methods take Workers AI @cf/ ids only, including in fallback. To route a vendor's own embedding, image, speech, or transcription model through AI Gateway, pass it to ai.routed(model). It goes to the provider-native endpoint, like ai(model). ai.routed() takes the gateway options, headers, sessionAffinity, and vendorKey.
Use a provider registry
createAI returns a ProviderV4, so it works with createProviderRegistry and as the AI SDK's global default provider:
import { createProviderRegistry, generateText } from "ai";
const registry = createProviderRegistry({ cloudflare: ai });
await generateText({
model: registry.languageModel("cloudflare:anthropic/claude-opus-5.5"),
prompt: "Hi",
});
// Bare strings now resolve through this provider.
globalThis.AI_SDK_DEFAULT_PROVIDER = createAI({ binding: env.AI });
await generateText({ model: "@cf/zai-org/glm-4.7-flash", prompt: "Hi" });
A string can be a Workers AI id, a catalog id, or a dynamic route.
Limitations
@cf/deepgram/fluxtakes websocket connections only, so it throws aCloudflareAIErrorbefore any request is sent. Use@cf/deepgram/nova-3or@cf/openai/whisper-large-v3-turbofor transcription.chatTemplateKwargsandsessionAffinityapply to Workers AI models only.zdrapplies to model objects only.- Workers AI streams and model object streams do not resume after a dropped connection.
Related resources
- pi-ai provider
- Model catalog
- Dynamic routing
- AI Gateway provider-native endpoints
- AI Gateway Worker binding methods
- Unified Billing
Was this helpful?
YesNo
On this page
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/agents/models/ai-sdk/#page","headline":"AI SDK","description":"Use createAI from agents/models/ai-sdk to call Workers AI models, AI Gateway catalog models, dynamic routes, and vendor AI SDK models through the AI binding or an account id and API token.","url":"https://developers.cloudflare.com/agents/models/ai-sdk/","inLanguage":"en","image":"https://developers.cloudflare.com/agents/models/ai-sdk/og.png?v=43ec00ce16b33b7e","dateModified":"2026-10-26","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"},"keywords":["AI"]}
description: Use createAI from agents/models/pi-ai to run Workers AI models, AI Gateway catalog models, dynamic routes, and Pi AI model objects through the AI binding or an account id and API token with Pi AI, Pi Durable, and the Pi harness. title: Pi AI image: https://developers.cloudflare.com/agents/models/pi-ai/og.png?v=0a20561ab61bea68
Documentation Index
Fetch the complete documentation index at: https://developers.cloudflare.com/agents/llms.txt
Use this file to discover all available pages before exploring further.
Docs