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/flux takes websocket connections only, so it throws a CloudflareAIError before any request is sent. Use @cf/deepgram/nova-3 or @cf/openai/whisper-large-v3-turbo for transcription.
  • chatTemplateKwargs and sessionAffinity apply to Workers AI models only.
  • zdr applies to model objects only.
  • Workers AI streams and model object streams do not resume after a dropped connection.

Was this helpful?

YesNo

On this page

AI SDK·续 - 图1Docs

{"@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


Skip to content

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.