Hybrid Search
Hybrid search is the recommended default. It runs lexical, semantic, and symbol search in parallel and fuses their rankings with Reciprocal Rank Fusion (RRF). A chunk that several modalities agree on rises to the top, and the method is immune to the fact that BM25 and cosine scores live on completely different scales.
Reciprocal Rank Fusion
RRF ignores raw scores and looks only at rank position within each modality. For every result list, a chunk at rank r (zero-indexed) contributes:
RCE Code uses the canonical constant K = 60. The denominator K + rank means top-ranked items contribute the most and the contribution falls off smoothly down each list. A chunk that appears in multiple modalities accumulates the contribution from each, so cross-modality agreement is what drives final ranking. Because only ranks enter the formula, fusion is unaffected by BM25 returning, say, 8.3 while cosine returns 0.81.
Per-modality weights
The three legs are not weighted equally. Lexical and semantic each carry a weight of 1.0, while symbol matches are weighted 1.5 — an exact symbol-name hit is a strong signal, so it is boosted relative to the ranked text modalities.
| Source | RRF weight |
|---|---|
| Lexical (BM25) | 1.0 |
| Semantic (cosine KNN) | 1.0 |
| Symbol (exact name) | 1.5 |
Over-fetch, then fuse
To give fusion enough material to work with, hybrid over-fetches each modality before combining: for a request of top_k results it pulls top_k * 3 from each leg, fuses them, then truncates the fused ranking back down to top_k. This lets a chunk ranked modestly in two modalities overtake one ranked highly in only one.
Graceful degradation
Hybrid does not require embeddings. When nothing has been embedded, the semantic leg simply returns an empty list and RRF fuses whatever lexical and symbol produced. That is why hybrid is a safe default even on a freshly indexed repo: it behaves like a fused lexical + symbol search until you run engine.embed(), at which point the semantic contribution joins automatically.
Why this is the default
Python API
search_hybrid(query, top_k=10) returns a list[SearchResult]. Every fused result carries .source = SearchSource.HYBRID, and its .score is the accumulated RRF score (larger is better) — small absolute numbers, since each contribution is at most weight / 60.
CLI
Run embed to get the most out of it
rce-code embed (or engine.embed()). The default embedder is offline, so this costs nothing but a one-time pass. See Semantic Search for details.