Code Search
code mode semantic (basemind code semantic on the CLI) finds code by meaning,
full-text term, or exact symbol match. Three lanes fuse results via Reciprocal Rank Fusion
(RRF): vector (semantic), BM25 (keyword), and exact symbol. Optional cross-encoder
reranking re-scores the fused results. Returns code pointers; fetch bodies with code chunk.
--features code-search or --features full
hybrid (default)
Section titled “hybrid (default)”RRF fusion of three lanes:
- Vector lane — KNN over embedded code chunks.
- BM25 lane — Okapi BM25 (
k1=1.2,b=0.75) over symbol names, signatures, docs, and body text. - Exact symbol lane — scope-aware identifier resolution against the symbol index,
so
query: "spawn"matches function definitions namedspawnexactly.
Fusion is score-scale-agnostic, so it blends L2 distance, BM25 score, and symbol order without normalization. Degrades gracefully if a lane is unavailable (e.g., without embeddings).
{ "mode": "semantic", "query": "spawn background task", "lane": "hybrid", "limit": 10, "rerank": true}Each hit carries per-lane provenance: matched_lanes lists which of exact / vector /
keyword matched, plus the 1-based rank in each contributing lane (exact_rank,
vector_rank, keyword_rank). This lets you tell an exact-symbol match from a semantic
neighbor or a cross-lane agreement without a second call.
semantic
Section titled “semantic”Vector KNN alone — pure semantic search. No text matching, no symbol resolution. Useful when you want “code that means this” regardless of naming.
{ "mode": "semantic", "query": "spawn background task", "lane": "semantic", "limit": 20}Requires embeddings to be enabled ([code_search] embed = true, the default).
keyword
Section titled “keyword”Native BM25 alone. No vectors, no symbol resolution. Works even with embeddings disabled. Full-text search over code.
{ "mode": "semantic", "query": "spawn", "lane": "keyword", "limit": 50}Fetching results
Section titled “Fetching results”code semantic returns pointers with chunk ID, path, byte span, and a snippet. Fetch
the full source body with code chunk:
{ "mode": "chunk", "path": "src/scanner.rs", "chunk_id": "abc123"}Two-call pattern mirrors code symbols → code expand: cheap search returns pointers,
then fetch only what you need.
Configuration
Section titled “Configuration”In .basemind/basemind.toml:
[code_search]embed = true # toggle embeddings (default: true)
[code_search.reranker]enabled = true # cross-encoder reranking (default: false)preset = "bge-reranker-base"Discipline
Section titled “Discipline”- Use
code semanticfor queries about what code does. “Find code that spawns a background task” → semantic search. - Use the
keywordlane for term search. “Find the wordspawn” → faster, no embeddings. - Use the
hybridlane when you want all signals. Symbol matches win for exact names, semantic search wins for meaning, BM25 wins for terminology. - Fetch with
code chunkonly what you need. Search returns pointers; don’t waste tokens re-reading the whole file. - Enable
rerankif latency allows. Cross-encoder reranking improves top-1 relevance but adds ~50–100 ms per query.