Skip to main content

How it works

Pure semantic (dense) search misses exact-match queries like product codes, names, or technical terms. Pure keyword (sparse) search misses paraphrases and synonyms. MemWire combines both using Qdrant’s hybrid search with reciprocal rank fusion:
  • Dense vectors — sentence embeddings from TextEmbedding (FastEmbed), capturing semantic meaning
  • Sparse vectors — SPLADE token weights from SparseTextEmbedding, capturing exact lexical signal
Both vectors are computed for every stored memory and every query. Results are merged by Qdrant before being returned to MemWire.
Hybrid search is on by default. No extra configuration needed:
from memwire import MemWire, MemWireConfig

config = MemWireConfig(qdrant_path="./memwire_data")   # use_hybrid_search=True by default
memory = MemWire(config=config)

If you want dense-only retrieval (faster, lower memory):
config = MemWireConfig(
    qdrant_path="./memwire_data",
    use_hybrid_search=False,
)
Disabling hybrid search means the sparse model is never loaded. This saves ~200 MB of RAM but reduces retrieval quality for exact-match queries.

Adding a cross-encoder reranker

For the highest retrieval quality, combine hybrid search with a cross-encoder reranker. The reranker re-scores the top candidates using full query-document attention:
config = MemWireConfig(
    qdrant_path="./memwire_data",
    use_hybrid_search=True,
    use_reranking=True,
    reranker_model_name="Xenova/ms-marco-MiniLM-L-6-v2",  # default
)
memory = MemWire(config=config)

results = memory.search("deadline for the project", user_id="alice", top_k=5)
for record, score in results:
    print(f"[{score:.3f}] {record.content}")
The reranker is lazy-loaded — it is only downloaded and initialised on the first search() call.

Models

RoleDefault modelNotes
Dense embeddingsentence-transformers/all-MiniLM-L6-v2384-dim, fast
Sparse embeddingprithivida/Splade_PP_en_v1SPLADE++
RerankerXenova/ms-marco-MiniLM-L-6-v2Cross-encoder, optional
Swap any model via MemWireConfig:
config = MemWireConfig(
    model_name="BAAI/bge-small-en-v1.5",
    sparse_model_name="prithivida/Splade_PP_en_v1",
    reranker_model_name="Xenova/ms-marco-MiniLM-L-6-v2",
    embedding_dim=384,
)

Configuration reference

ParameterDefaultDescription
use_hybrid_searchTrueCombine dense and sparse vectors for retrieval.
use_rerankingFalseApply a cross-encoder reranker to top results.
model_namesentence-transformers/all-MiniLM-L6-v2Dense embedding model.
sparse_model_nameprithivida/Splade_PP_en_v1Sparse (SPLADE) embedding model.
reranker_model_nameXenova/ms-marco-MiniLM-L-6-v2Cross-encoder reranker model.
embedding_dim384Dimension of the dense embedding.
embedding_cache_maxsize10000LRU cache size for embedding vectors.