SmartMemory
Concepts

Hybrid Retrieval

SmartMemory uses Hybrid Retrieval to combine the strengths of semantic (vector) search with keyword (full-text) search, delivering more accurate and relevant results.

The Problem with Pure Approaches

Search TypeStrengthWeakness
Vector SearchUnderstands meaning and contextMay miss exact matches (e.g., proper nouns, codes)
Keyword SearchPerfect for exact termsMisses semantic similarity

How Hybrid Retrieval Works

SmartMemory runs both searches in parallel and combines results using Reciprocal Rank Fusion (RRF).

graph LR
    Q[Query] --> V[Vector Search]
    Q --> K[Keyword Search]
    V --> RRF[Reciprocal Rank Fusion]
    K --> RRF
    RRF --> R[Combined Results]

Reciprocal Rank Fusion (RRF)

RRF scores each document based on its position in each result list:

score = 1/(k + rank_vector) + 1/(k + rank_text)

Where k is a constant (default: 60) that prevents high-ranked items from dominating.

Benefits:

  • Documents appearing in both lists get higher scores
  • No need to normalize scores across different search types
  • Robust to outliers in either list

Usage

SDK

# Hybrid search is enabled by default
results = memory.search("project bedrock", top_k=5)

# Explicitly control hybrid mode
results = memory.search(
    "project bedrock", 
    top_k=5, 
    enable_hybrid=True  # Default
)

# Disable hybrid (vector-only)
results = memory.search(
    "project bedrock",
    top_k=5,
    enable_hybrid=False
)

API

POST /memory/search
{
  "query": "project bedrock",
  "top_k": 5,
  "enable_hybrid": true
}

Backend Support

Hybrid retrieval requires a backend that supports full-text indexing:

BackendFull-Text SupportNotes
FalkorDB (default)✅ YesNative vectors + a FalkorDB full-text index (db.idx.fulltext.queryNodes) in the same instance
usearch (optional)❌ NoVector similarity only — no full-text index, so hybrid retrieval requires the FalkorDB backend

Configuration

The RRF constant k can be tuned:

# Lower k = more weight on top results
results = store.search(query_embedding, query_text="test", rrf_k=30)

# Higher k = more even distribution
results = store.search(query_embedding, query_text="test", rrf_k=100)
ScenarioRecommendation
General knowledge queries✅ Enable hybrid
Code/technical terms✅ Enable hybrid (catches exact identifiers)
Semantic similarity only❌ Disable hybrid
Performance-critical (high volume)❌ Consider disabling

On this page