Skip to content

strands.storage.search.bm25

BM25 full-text search strategy powered by SQLite FTS5.

Maintains a SQLite-backed inverted index over storage contents and uses BM25 scoring for relevance ranking. Accounts for term frequency, inverse document frequency, and document length normalization.

Indexes entries at write time via :meth:Bm25SearchStrategy.index so searches do not need to re-read storage contents. Requires a base_dir property on the storage instance only to locate the SQLite database file on the host filesystem.

Zero external dependencies — uses Python’s stdlib sqlite3 module which ships FTS5 support on all modern platforms.

@dataclass
class Bm25SearchStrategyConfig()

Defined in: src/strands/storage/search/bm25.py:179

Configuration for :class:Bm25SearchStrategy.

Attributes:

  • db_path - Path to the SQLite database file for the FTS5 index. Defaults to .<dir>-fts5.sqlite alongside the storage directory.
class Bm25SearchStrategy()

Defined in: src/strands/storage/search/bm25.py:190

BM25 full-text search strategy powered by SQLite FTS5.

Maintains a SQLite-backed inverted index over the storage contents and uses BM25 scoring for relevance ranking. Accounts for term frequency, inverse document frequency, and document length normalization.

Indexes entries at write time via :meth:index — consumers call strategy.index(storage, key, data) on each write, and search() queries the pre-built index. Only entries passed through index() are searchable; pre-existing storage contents are not backfilled automatically.

The FTS5 index is persisted on the host filesystem via the storage’s base_dir and is not sandbox-aware.

Example:

from strands.storage import LocalFileStorage
from strands.storage.search.bm25 import Bm25SearchStrategy
storage = LocalFileStorage("./memory/")
strategy = Bm25SearchStrategy()
await strategy.index(storage, "auth.md", b"OAuth2 authentication flow")
results = await strategy.search(storage, "authentication flow")
await strategy.close()
def __init__(config: Bm25SearchStrategyConfig | None = None) -> None

Defined in: src/strands/storage/search/bm25.py:221

Initialize the BM25 search strategy.

Arguments:

  • config - Optional configuration. See :class:Bm25SearchStrategyConfig.
async def index(storage: LocalFileStorage, key: str, data: bytes,
**kwargs: Any) -> None

Defined in: src/strands/storage/search/bm25.py:232

Index a single entry for future searches.

Skips hidden files (keys whose final segment starts with ’.’). Uses content hashing to avoid redundant re-indexing when the data has not changed.

Arguments:

  • storage - The storage backend (used to locate the index db).
  • key - The storage key being written.
  • data - The raw bytes being stored.
  • **kwargs - Unused; accepted for protocol compatibility.
async def search(storage: LocalFileStorage, query: str,
**kwargs: Any) -> list[StorageSearchResult]

Defined in: src/strands/storage/search/bm25.py:255

Search the index using BM25 full-text search.

Arguments:

  • storage - The storage backend (used to locate the index db).
  • query - Natural-language search query.
  • **kwargs - Unused; accepted for protocol compatibility.

Returns:

Matched keys with BM25 relevance scores, ranked best-first.

Raises:

  • RuntimeError - If the SQLite build lacks FTS5 support.
async def close() -> None

Defined in: src/strands/storage/search/bm25.py:277

Close the SQLite connection and release resources.