Managed knowledge
Upload and search an app-owned AI Search knowledge base with the DeepSpace worker helper.
On this page
DeepSpace can provision one managed Cloudflare AI Search instance per app. Declare it in wrangler.toml; the app calls it through the typed knowledge(env) worker helper, and usage is charged to the app owner.
Configure the binding#
[[ai_search]]
binding = "KNOWLEDGE"
instance_name = "auto"
instance_name must be "auto", and an app may declare only one ai_search binding. DeepSpace owns provisioning and app isolation. The KNOWLEDGE name is manifest metadata rather than an AI Search object you call directly from application code.
Use it from the worker#
import { knowledge } from 'deepspace/worker'
const kb = knowledge(env)
const added = await kb.add(
new File(
['DeepSpace keeps records in app-owned Durable Objects.'],
'architecture.md',
{
type: 'text/markdown',
},
),
{ folder: 'docs' },
)
const results = await kb.search('Where are records stored?', {
folder: 'docs',
mode: 'hybrid',
limit: 5,
})
The helper uses the app's signed platform transport. It does not read env.KNOWLEDGE as a provider binding.
API#
const kb = knowledge(env)
await kb.add(file, { folder: 'docs' })
await kb.list({ folder: 'docs', page: 1, perPage: 20, status: 'completed' })
await kb.remove(itemId)
await kb.search(query, { folder: 'docs', mode: 'hybrid', limit: 5 })
const docs = kb.scoped({ folder: 'docs' })
await docs.add(file)
await docs.list({ page: 1, perPage: 20 })
await docs.search(query, { mode: 'semantic', limit: 5 })
scoped fixes the folder for add, list, and search. Remove remains on the root client because it addresses a provider item ID directly.
Items report one of these statuses: queued, running, completed, error, skipped, or outdated. Upload completion means the provider accepted the item; use list to observe indexing status before assuming it is searchable.
Limits and validation#
- A provider upload part may be at most 4 MiB. The SDK safely splits oversized text files on UTF-8 boundaries; oversized non-text files are rejected so application code can use a format-aware splitter.
- A query may contain at most 4,096 characters.
limitandperPagemust be integers from 1 through 50.- Folders are relative forward-slash paths. Empty segments,
./.., backslashes, control characters, and leading slashes are rejected. Folder plus filename must fit the provider's 128-character item-key limit. modeishybrid,semantic, orfulltext.
Pricing#
The amounts below include the 10% managed-binding markup:
| Operation | Price |
|---|---|
| Text ingestion | $0.825 per 1 million provider-reported tokens |
| Image ingestion | $0.55 per 1 million image tokens, in addition to text ingestion |
| Storage | $2.20 per GB-month |
| Hybrid or semantic search | $0.825 per 1,000 queries |
| Full-text search | $0.11 per 1,000 queries |
Charges settle against actual provider usage when it is available. Uploads reserve a conservative amount first, so a rejected or smaller operation does not become an unbounded charge. DeepSpace credits use 100 credits per US dollar, and managed-knowledge usage appears in the account-wide usage surfaces.
Errors#
Failures throw KnowledgeError, which includes status and a machine-readable code. A split text upload can partially succeed; in that case uploadedItems names the accepted parts so you can avoid uploading them twice.
import { KnowledgeError, knowledge } from 'deepspace/worker'
try {
await knowledge(env).add(file)
} catch (error) {
if (error instanceof KnowledgeError) {
console.error(error.code, error.uploadedItems)
}
}