Workers binding migration
The env.AI.autorag() binding is the legacy API for AI Search. It will continue to work, but all new features and improvements are only available through the new AI Search bindings.
Here is a summary of the key differences between the legacy and new bindings:
| Legacy | New | |
|---|---|---|
| Wrangler config | ai binding | ai_search or ai_search_namespaces binding |
| Access pattern | env.AI.autorag("name") | env.MY_INSTANCE or env.AI_SEARCH.get("name") |
| Search format | query string | messages array or query string |
| Response format | data array | chunks array |
AI Search provides two new bindings:
Instance binding (ai_search) binds directly to a single instance. This is the simplest migration path from env.AI.autorag().
// wrangler.jsonc{ "ai_search": [ { "binding": "MY_SEARCH", "instance_name": "my-instance", }, ],}Namespace binding (ai_search_namespaces) gives you access to all instances within a namespace. Use this if you need dynamic instance management, cross-instance search, or the Items API.
// wrangler.jsonc{ "ai_search_namespaces": [ { "binding": "AI_SEARCH", "namespace": "default", }, ],}For more details on the difference, refer to Namespaces.
The new bindings require the following minimum package versions for TypeScript types and local development support.
| Package | Minimum version |
|---|---|
@cloudflare/workers-types | 4.20260304.0 |
wrangler | 4.68.1 |
Existing instances are in the default namespace. For a simple upgrade path, use the instance binding. For the namespace binding, refer to AI Search bindings.
Before:
{ "$schema": "./node_modules/wrangler/config-schema.json", "ai": { "binding": "AI" }}[ai]binding = "AI"After:
{ "$schema": "./node_modules/wrangler/config-schema.json", "compatibility_date": "2026-03-27", "ai_search": [ { "binding": "MY_INSTANCE", "instance_name": "my-instance" } ]}compatibility_date = "2026-03-27"
[[ai_search]]binding = "MY_INSTANCE"instance_name = "my-instance"Update the Env interface to use the new binding type.
Before:
export interface Env { AI: Ai;}After:
export interface Env { MY_INSTANCE: AiSearchInstance;}Replace env.AI.autorag() calls with the new binding.
Before:
const result = await env.AI.autorag("my-instance").search({ query: "What is Cloudflare?",});After:
const result = await env.MY_INSTANCE.search({ messages: [{ role: "user", content: "What is Cloudflare?" }],});The response shape changed from a data array to a chunks array.
| Old field | New field |
|---|---|
data[] | chunks[] |
data[].file_id | chunks[].id |
data[].filename | chunks[].item.key |
data[].score | chunks[].score |
data[].content[].text | chunks[].text |
data[].attributes.modified_date | chunks[].item.timestamp |
In the legacy binding, streaming with env.AI.autorag().aiSearch({ stream: true }) only returned the streamed response without the retrieved chunks.
The new binding sends the retrieved chunks first as a chunks event, followed by the streamed response. This allows you to display source chunks immediately while streaming the generated response.
The new binding uses Vectorize-style metadata filtering. Filters are now passed inside ai_search_options.retrieval.filters.
| Old format | New format |
|---|---|
eq | $eq (or implicit) |
ne | $ne |
gt | $gt |
gte | $gte |
lt | $lt |
lte | $lte |
$in (new) | |
$nin (new) |
Filter by a single metadata field using implicit equality:
Before:
const result = await env.AI.autorag("my-instance").search({ query: "What is Cloudflare?", filters: { type: "eq", key: "folder", value: "customer-a/", },});After:
const result = await env.MY_INSTANCE.search({ messages: [{ role: "user", content: "What is Cloudflare?" }], ai_search_options: { retrieval: { filters: { folder: "customer-a/" }, }, },});Combine multiple conditions where all must match:
Before:
const result = await env.AI.autorag("my-instance").search({ query: "What is Cloudflare?", filters: { type: "and", filters: [ { type: "eq", key: "folder", value: "customer-a/" }, { type: "gte", key: "timestamp", value: "1735689600000" }, ], },});After:
const result = await env.MY_INSTANCE.search({ messages: [{ role: "user", content: "What is Cloudflare?" }], ai_search_options: { retrieval: { filters: { folder: "customer-a/", timestamp: { $gte: 1735689600 }, }, }, },});The env.AI.autorag() binding will continue to work indefinitely. You do not need to migrate immediately.
For the legacy API reference, refer to Workers binding (legacy).