Quickback Docs

Using Embeddings

Re-embedding rows, semantic search, and practical usage patterns.

This page covers the runtime API for working with embeddings — re-embedding rows, the search service, and practical usage patterns.

Re-embedding Rows

Embeddings have no endpoint of their own. Rows are embedded on INSERT and re-embedded on UPDATE by the generated CRUD routes, after auth, firewall, and guards pass — so PATCH the row to re-embed (with onUpdate: [...fields], include a watched field; resending its current value is enough). The job uses the table's configured model and embeddingColumn.

Search Service

For typed similarity search with classification, use the createEmbeddings() service generated from defineEmbedding() configurations.

const embeddings = createEmbeddings(ctx.env);

const results = await embeddings.jobSimilarity.search(
  "Senior backend engineer with distributed systems experience",
  {
    department: "Engineering",
    limit: 5,
    threshold: 0.70,
  }
);

// Returns: [{ id, score, classification, metadata }]
for (const match of results) {
  console.log(`${match.classification}: ${match.id} (score: ${match.score})`);
}

Classification

Results are automatically classified based on similarity score. The four classification names are fixed; only the cutoffs are configurable, via search.classify on the defineEmbedding() config:

ClassificationDefault ThresholdMeaning
DUPLICATE>= 0.90Near-identical to an existing record
CONFIRMS>= 0.85Strongly similar — corroborates the existing record
RELATED>= 0.75Topically related
NEW< 0.75No significant match

classify accepts only the keys DUPLICATE, CONFIRMS, and RELATED (NEW is the implicit floor). Any other key is silently ignored and its band keeps the default cutoff — see Classification Thresholds.

Gray Zone Detection

For cases where automatic classification isn't sufficient, use gray zone detection:

const results = await embeddings.jobSimilarity.findWithGrayZone(
  "Full-stack developer with React and Node.js",
  { min: 0.60, max: 0.85 }
);

// results.high_confidence — Score >= 0.85 (auto-classified)
// results.gray_zone — 0.60 <= score < 0.85 (needs review)

Raw Embedding

Generate an embedding vector without searching:

const vector = await embeddings.jobSimilarity.embed("Text to embed");
// Returns: number[] (768 dimensions for bge-base)

Vectorize Queries

If your project uses a Vectorize index, you can query it directly for custom search logic:

// Generate embedding for query text
const queryVector = await embeddings.jobSimilarity.embed(searchText);

// Query Vectorize with metadata filters
const results = await ctx.env.VECTORIZE.query(queryVector, {
  topK: 10,
  filter: {
    department: "Engineering",
    organizationId: ctx.activeOrgId,
  },
});

The metadata fields in your defineTable embeddings config are automatically included in the Vectorize index, enabling filtered searches.

Auto-Embed vs Manual

TriggerHowUse Case
Auto (INSERT)Compiler enqueues after successful createDefault behavior
Auto (UPDATE)Compiler enqueues when watched fields changeKeeps embeddings fresh
Re-embedPATCH the row (or PATCH /batch)Re-embedding existing records
Manual (Queue)env.EMBEDDINGS_QUEUE.send(...)Custom pipelines

Security

  • Embedding jobs are only enqueued by the generated write routes, after all security checks pass (auth, firewall, guards) — there is no client-facing embeddings endpoint
  • Jobs are scoped to the writer's activeOrgId
  • The queue consumer is an internal process — it trusts pre-validated jobs

Supported Models

Any Workers AI embedding model can be used:

ModelDimensionsNotes
@cf/baai/bge-base-en-v1.5768Default, good general-purpose
@cf/baai/bge-small-en-v1.5384Faster, smaller
@cf/baai/bge-large-en-v1.51024Higher quality

See Workers AI Models for the full list.

Cloudflare Only

Embeddings require Cloudflare Workers AI and Queues. Cloudflare is the only runtime provider Quickback ships (defineRuntime("cloudflare")), so this is not a portability constraint you have to design around.

See Also

  • Automatic Embeddings — defineTable() config, defineEmbedding() search service, and Vectorize integration
  • Queues — How embedding jobs are processed

On this page