Hybrid Retrieval
Server hybrid retrieval combines enabled channels through weighted Reciprocal Rank Fusion with k=60. The native lexical channel contributes once with default weight 0.8. Other channels can contribute semantic or graph matches, so the final answer is not restricted to lexical AND matches.
results = memory.search("project bedrock", channel_weights={"lexical": 0.8})
# Explicit zero disables the lexical contribution.
results = memory.search("project bedrock", channel_weights={"lexical": 0})Accepted channels are entity-graph, ssg-traversal, semantic, regex-text, lexical, spreading-activation, facts and structural-semantic. The removed contains and keyword-bm25 names raise a validation error naming lexical. Replace owned defaults with one lexical weight of 0.8. Custom weights need an explicit choice.
Lexical terms combine with AND. Quoted phrases preserve word order, repeated tokens and stopwords. Punctuation separates words. Unmatched quotes fail validation. Empty, nonalphanumeric and wholly-stopword input contributes no lexical matches. Public syntax does not expose OR, prefix, wildcard, field-selector or fuzzy operators.
| Backend | Lexical index | Native ranking |
|---|---|---|
| SQLite lite | Contentful FTS5, unicode61 remove_diacritics 0 | bm25 ascending |
| Pinned FalkorDB | Item owner_key/content full-text, no stemming, retained stopwords | Default score descending |
Equal scores break by content then item ID. Cross-engine score or tokenizer identity is not promised. Scoped ownership is resolved before native LIMIT. SQLite lite is single-tenant, and its scoped SQL harness does not establish hosted isolation.
Lite runs graph-first search with conditional FTS5 lexical fill, then vector fill. A full graph result skips lexical fill. enable_hybrid does not select lite dispatch. On the server, disabling hybrid keeps sequential first-nonempty retrieval and does not imply vector-only search.
Bounded refill and hydration postfilters may underfill top_k. Repeated-token phrases receive bounded candidate verification. The separate regex-text lane still scans. CORE-FACT-INDEX-1 owns the deferred fact ranking and path expansion work.
Required lexical unavailability fails the entire search with LexicalIndexUnavailableError, surfaced by the service as HTTP 503. There is no successful partial 200 or scan fallback. Query validation returns HTTP 400. Neo4j lexical search is unsupported.
First-open indexing is O(N). Quiesce old writers, verify the immutable capability pin, and keep maintenance exclusive until readiness checks complete. Use sm rebuild --lexical for the default SQLite target or explicitly select --backend falkordb with the intended graph configuration.
See migration and recovery and the versioned lexical contract for supported semantics, pinning, stored-profile migration and measured limitations.