Skip to main content
Documentation

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"
toml

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,
})
ts

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 })
ts

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.
  • limit and perPage must 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.
  • mode is hybrid, semantic, or fulltext.

Pricing#

The amounts below include the 10% managed-binding markup:

OperationPrice
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)
  }
}
ts

See also#