# Workers AI EmbeddingGemma for the link vault

The repository's architectural decision, rationale and consequences.

# Workers AI EmbeddingGemma for the link vault

Date: 2026-10-16. Status: accepted.

## Decision [#decision]

Use Cloudflare Workers AI `@cf/google/embeddinggemma-300m` through the Worker `AI` binding. There is no extra provider key. Store `vector(768)` on `link_embedding` with the model id and a model version on every row.

| Field           | Value                                                |
| --------------- | ---------------------------------------------------- |
| Provider        | Workers AI binding (`env.AI`)                        |
| Model id        | `@cf/google/embeddinggemma-300m` (`EMBEDDING_MODEL`) |
| Version         | `300m` (`EMBEDDING_MODEL_VERSION`)                   |
| Dimensions      | 768 (code constant; matches the column)              |
| Input limit     | 512 tokens                                           |
| Token estimate  | 2 Unicode code points per token (conservative)       |
| Document prefix | `title: {title} \| text: {content}`                  |
| Query prefix    | `task: search result \| query: {q}`                  |

A later swap to EmbeddingGemma 2 (`google/embeddinggemma-2`, not on Workers AI yet) is a config change. The resumable job selects rows whose stored model or version is not the configured pair and re-embeds them.

## Consequences [#consequences]

- Node, Vite, and tests have no `AI` binding. The adapter is unavailable there; hybrid search returns labeled keyword-only results. Tests inject a deterministic mock.
- Incompatible vectors are never compared: semantic retrieval filters on the configured model and version.
- Exact `<=>` scans only. No ANN index and no `pg_vectorsearch`.
- Changing dimensions requires a journaled column migration; do not put `N` in env.

