Repository navigation
Semantic Search
MemoryVault supports three search modes: lexical, semantic, and hybrid (default). Semantic search uses Cloudflare Vectorize and Workers AI embeddings.
Traditional substring matching against memory content, title, key, and source. Fast, no AI required. Works locally without --remote.
Vector similarity search using embeddings. Finds conceptually related memories even when keywords don't match. Requires Workers AI and Vectorize bindings.
Combines lexical and semantic results using Reciprocal Rank Fusion (RRF). Best of both worlds — catches exact matches and conceptual similarity.
-
Model:
@cf/baai/bge-base-en-v1.5(Cloudflare Workers AI) - Dimensions: 768
- Max input: 8,000 characters per memory
Each memory is converted to embedding text by concatenating (in order):
type: note
title: My Memory Title
key: my-fact-key
source: api
tags: tag1, tag2
content: The actual memory content...
Empty fields are skipped. The result is capped at 8,000 characters.
Both search backends run simultaneously:
-
Lexical: SQL
LIKEquery against content, title, key, source fields - Semantic: Embed the query, then query Vectorize for nearest neighbors
Each result gets a fused score based on its rank in each result set:
K = 60 (fusion constant)
lexical_score = 1 / (K + lexical_rank)
semantic_score = 1 / (K + semantic_rank)
similarity = normalized_cosine_similarity * 0.25
Final score by mode:
| Mode | Formula |
|---|---|
lexical |
lexical_score |
semantic |
semantic_score + similarity |
hybrid |
semantic_score * 0.7 + lexical_score * 0.3 + similarity * 0.15 |
Results are sorted by fused score descending, with updated_at as tiebreaker.
If a memory appears in both result sets, scores are merged (not duplicated).
Vectors are stored in Cloudflare Vectorize with:
-
Namespace:
brain_id(tenant isolation) -
Vector ID:
m_{memory_id}(prefixed) - Metadata: brain_id, memory_id, type, key, title, source, tags, timestamps, archived flag
Memory write operations (save, update, delete, consolidate, forget, snapshot restore) automatically sync vectors. The sync:
- Deletes vectors for archived/deleted memories
- Generates embeddings for active memories (batch size: 16)
- Upserts vectors (batch size: 500)
Use memory_reindex to rebuild vectors for existing memories:
{
"name": "memory_reindex",
"arguments": {
"limit": 500,
"wait_for_index": true,
"wait_timeout_seconds": 180
}
}The wait_for_index option (default true) blocks until Vectorize has processed all mutations, ensuring subsequent searches return up-to-date results.
| Constant | Value | Description |
|---|---|---|
EMBEDDING_MODEL |
@cf/baai/bge-base-en-v1.5 |
Workers AI model |
EMBEDDING_BATCH_SIZE |
16 | Memories per embedding call |
VECTORIZE_QUERY_TOP_K_MAX |
20 | Max semantic results |
VECTORIZE_UPSERT_BATCH_SIZE |
500 | Vectors per upsert call |
VECTORIZE_DELETE_BATCH_SIZE |
500 | Vectors per delete call |
MEMORY_SEARCH_FUSION_K |
60 | RRF fusion constant |
MEMORY_SEARCH_DEFAULT_LIMIT |
20 | Default search result limit |
Semantic search requires:
-
AIbinding inwrangler.toml(Workers AI) -
MEMORY_INDEXbinding (Vectorize index with 768 dimensions, cosine metric)
Without these bindings, memory_search falls back to lexical-only mode.
npx wrangler vectorize create ai-memory-semantic-v1 --dimensions=768 --metric=cosineFor dev environment:
npx wrangler vectorize create ai-memory-semantic-v1-dev --dimensions=768 --metric=cosineReference
Concepts
Features