The answer. Workers AI is inference on Cloudflare's GPUs behind one call: env.AI.run(modelId, input). The binding is a TOML table, [ai] binding = "AI", with no id because there is nothing to provision. The input shape belongs to the model, so read its page: text generation takes messages (or prompt) and returns response, or a stream of server-sent events when you pass stream: true; embedding models take { text: [...] } and return data as arrays of floats; classifiers and image models take bytes, and the newer image generators take multipart bodies. Model ids start with @cf/. A third argument routes the call through AI Gateway ({ gateway: { id } }) for logs, caching and retries. Nothing runs locally: wrangler dev sends every call to the network and it counts against your allowance.
The pattern.
[ai]
binding = "AI"
// streamed chat completion, returned straight to the client
const stream = await env.AI.run("@cf/meta/llama-3.3-70b-instruct-fp8-fast",
{ messages: [{ role: "user", content: prompt }], stream: true }, { gateway: { id: "default" } });
return new Response(stream, { headers: { "content-type": "text/event-stream" } });
// embeddings for a search index
const { data } = await env.AI.run("@cf/baai/bge-base-en-v1.5", { text: chunks }); // data[i] is a float[]
Watch out.
- The free allowance is per day and fails closed when spent; production callers need a pending state and a retry path, not a crash.
- Output is model-specific too: some return
response, someresult, some an object per input. Type the call site per model. - Expect seconds, not milliseconds, for large models and images; stream text and queue image jobs.
Related: ai-gateway-in-front-of-every-provider-call · vectorize-index-plus-embeddings-for-semantic-search · queue-work-returns-202-client-polls-a-status-row