Why hybrid
Vector search alone misses exact identifiers (file name (e.g.pg_hba.conf), a ticket
number, or a specific concept) because embeddings blur precise strings into approximate meaning. Keyword search
alone misses the meaning, so memloom runs both (plus an entity arm) inside the database, in a
single SQL function (memloom_fuse), and fuses the rankings. There’s no reranker service and
no second round trip: one query, one fused result list.
All arms rank saved memories and context chunks together in one pool, so “search my
memories” and “search my files” are the same operation.
The three arms
The entity arm has an abstention gate: it only fires when the query is clearly about a
known entity (query ↔ entity cosine ≥ 0.60). A vague query anchors to nothing and the arm
contributes nothing, so it never drags in unrelated results. The keyword arm abstains
the same way: no lexical match, no votes.
Reciprocal-rank fusion
Each arm produces a ranking; fusion combines ranks rather than scores (cosine distances and FTS ranks aren’t comparable):rrfScore: the fused rank score. This is the order results arrive in.similarity: the raw cosine signal alone, useful as a “how semantically close” query is to the result.
What makes results good in practice
- Exact identifiers are excellent queries. The keyword arm makes
memloom recall "pg_hba.conf"precise in a way pure-vector systems can’t be. - Chunks embed their breadcrumb. A markdown chunk is stored as
Guide > Setup > Postgres\n\n<text>: the heading path is prepended to the text, so both the vector and the keyword arm see the heading context along with the paragraph. - Index your store. The entity arm only works over what
memloom indexhas processed. An unindexed store still recalls fine on the other two arms. - Stale never surfaces. Every arm filters
status = 'active', so superseded versions of a belief can’t shadow the current one.
In offline mode (no API key) the vector arm runs on deterministic hash embeddings, which makes texts
sharing words score as similar, which is a real but low signal compared to cloud embedding. The keyword arm works at
full quality offline; the entity arm needs indexing, which needs the LLM. For production
recall quality, just configure a key here.