docs

Search

Hybrid ranking

hybrid runs both legs and fuses them with reciprocal-rank fusion (k = 60). It is the default because it is the safe choice across corpora: it wins outright on lexical-friendly content and never collapses when one leg is weak — and when the embedder cannot help at all, it becomes full-text search by itself.

The default call

curl -s http://127.0.0.1:7001/v1/spaces/$SPACE/search \
  -H 'content-type: application/json' \
  -d '{"query": "what did we decide about the reranker?",
       "scopes": ["chat", "basic"],
       "limit": 10}'
any search $SPACE "what did we decide about the reranker?" --scopes chat,basic --limit 10
{
  "hits": [
    { "scope": "chat", "objectId": "…", "dataset": "chat_messages",
      "recordId": "…", "data": "…", "score": 0.0328 }
  ],
  "mode": "hybrid",
  "vectorStatus": "used"
}

limit defaults to 10 and caps at 100. score is the fused RRF score — small numbers, comparable only within this one response.

Reciprocal-rank fusion

Each leg returns a ranked list; a document's fused score is the sum over the legs that returned it of weight / (k + rank). Rank, not raw score, is what gets combined, so BM25 and cosine never have to be put on one scale. A document found by both legs rises above one found by only one.

fused(doc) = ftsWeight / (60 + rank_fts) + vectorWeight / (60 + rank_vec)

Full-text operators ("phrases", prefix*, require, exclude) shape the lexical leg's list; the vector leg always embeds the whole query verbatim, stop words included.

Read vectorStatus before trusting recall

The reply's mode is the mode that actually ran, and vectorStatus says whether semantic recall participated and, if not, why. Agents in particular should branch on it before concluding that "nothing matched".

vectorStatus Meaning What to do
used the vector leg ran and contributed trust the fused ranking
unavailable an embedder is configured but unreachable right now — results are lexical-only retry later; results may differ
disabled this server has no embedder — vector can never run until config changes adjust the query toward exact terms; don't retry
skipped the caller asked for mode: "fts" the echo of your own choice

With unavailable or disabled, mode in the reply reads fts even though the request said hybrid. Pure vector mode does not degrade this way — it errors instead (see Vector search).

Why it matters. The embedder is the one moving part that can be absent or temporarily down — a model still downloading, an API outage, a laptop without the shared libraries. Degrading to full-text keeps search answering; reporting it lets the caller decide how much to trust a thin result.

Weighting knobs

All under index.search.* in configuration; defaults reproduce the untuned behaviour, so an absent block changes nothing.

Key Default Effect
ftsWeight 1 RRF weight of the lexical leg
vectorWeight 1 RRF weight of the dense leg
adaptiveWeights false per query, down-weight the FTS leg when its BM25 scores are flat/weak
stopWords true strip stop words from the FTS-leg query
defaultOperator or how bare FTS terms combine
minVectorSim 0 cosine floor applied to vector hits before fusion

Equal weights (1/1) are optimal on the lexical-friendly reference corpus and a safe default elsewhere. Corpora where one leg is much weaker want a tilt: on paraphrastic Q&A the dense leg alone beats equal-weight hybrid, because a weak BM25 list drags the fusion down. adaptiveWeights automates that tilt from the query's own score distribution — a big win where the lexical leg is weak, a small cost where it is strong, hence off by default. It is asymmetric on purpose: only the FTS leg is ever down-weighted, since cosine scores are not calibrated enough to judge.

index:
  search:
    adaptiveWeights: true      # semantic / conversational corpora

Choosing a mode

  • hybrid (default) for anything a person or agent types.
  • fts for identifiers, error codes, exact names, and property-value lookups (props is full-text only anyway).
  • vector when paraphrase recall matters more than precision and you want a hard failure rather than a silent degrade.

The measurements behind these recommendations are on Evaluation.