Skip to content

Code Search

search_code 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 get_chunk.

--features code-search or --features full

RRF fusion of three lanes:

  1. Vector lane — KNN over embedded code chunks.
  2. BM25 lane — Okapi BM25 (k1=1.2, b=0.75) over symbol names, signatures, docs, and body text.
  3. Exact symbol lane — scope-aware identifier resolution against the symbol index, so query: "spawn" matches function definitions named spawn exactly.

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).

{
"query": "spawn background task",
"mode": "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.

Vector KNN alone — pure semantic search. No text matching, no symbol resolution. Useful when you want “code that means this” regardless of naming.

{
"query": "spawn background task",
"mode": "semantic",
"limit": 20
}

Requires embeddings to be enabled ([code_search] embed = true, the default).

Native BM25 alone. No vectors, no symbol resolution. Works even with embeddings disabled. Full-text search over code.

{
"query": "spawn",
"mode": "keyword",
"limit": 50
}

search_code returns pointers with chunk ID, path, byte span, and a snippet. Fetch the full source body with get_chunk:

{
"path": "src/scanner.rs",
"chunk_id": "abc123"
}

Two-call pattern mirrors search_symbolsexpand: cheap search returns pointers, then fetch only what you need.

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"
  • Use search_code for semantic queries about what code does. “Find code that spawns a background task” → semantic search.
  • Use keyword mode for term search. “Find the word spawn” → faster, no embeddings.
  • Use hybrid mode when you want all signals. Symbol matches win for exact names, semantic search wins for meaning, BM25 wins for terminology.
  • Fetch with get_chunk only what you need. Search returns pointers; don’t waste tokens re-reading the whole file.
  • Enable rerank if latency allows. Cross-encoder reranking improves top-1 relevance but adds ~50–100 ms per query.

Code intelligence · Document search