Skip to content

About

BM25 hybrid reranking for Hermes Agent — inspired by MemPalace searcher.py

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

2 Commits

Folders and files

Repository files navigation

hermes-agent-bm25

BM25 hybrid reranking for Hermes Agent session search — inspired by MemPalace searcher.py

Overview

This module extends Hermes Agent's SessionDB.search_messages() with Okapi-BM25 reranking. When FTS5 returns results, BM25 re-orders them by keyword match quality, so exact-term matches surface first instead of relying solely on FTS5's positional ranking.

How It Works

FTS5 query → initial results → BM25 scoring → hybrid rank (50% FTS5 + 50% BM25) → final results

Example: Searching for "python" — a message containing both "python" and "machine learning" will rank above a message that only mentions "python" once in a later position.

BM25 Parameters

Parameter Value Description
k1 1.5 Term-frequency saturation
b 0.75 Length normalization
BM25_WEIGHT 0.5 BM25 contribution to final score
VECTOR_WEIGHT 0.5 FTS5 rank contribution (semantic proxy)

Parameters are MemPalace's proven defaults.

Files

File Description
hermes_state.py Modified SessionDB class with BM25 methods added
test_hermes_state.py Unit + integration tests (16 new test cases)
LICENSE MIT License

Integration

Copy the BM25 methods from hermes_state.py into your SessionDB class:

# In SessionDB class (hermes_state.py):

# Constants (add to class)
_TOKEN_RE = re.compile(r"[\w\u0080-\U0000FFFF]{2,}", re.UNICODE)
_BM25_K1 = 1.5
_BM25_B = 0.75
_VECTOR_WEIGHT = 0.5
_BM25_WEIGHT = 0.5

# Methods to add (see hermes_state.py for full implementation):
@staticmethod
def _tokenize(text: str) -> list[str]: ...

@staticmethod
def _bm25_scores(query: str, documents: list[str]) -> list[float]: ...

@staticmethod
def _bm25_rerank(matches: list[dict], query: str) -> list[dict]: ...

# In search_messages(): call _bm25_rerank(matches, query) after FTS5 results
# and before context enrichment (both FTS5 and LIKE fallback paths)

Requirements

  • Zero external dependencies — pure Python stdlib (math, re)
  • Python 3.10+
  • SQLite with FTS5 enabled

Testing

pytest tests/test_hermes_state.py::TestBM25RerankUnit -v
pytest tests/test_hermes_state.py::TestBM25RerankIntegration -v

All 16 BM25 tests pass. Full suite: 210 tests, 0 failures.

Comparison with Other Approaches

Approach External deps Index needed Best for
This (BM25 rerank) None No Small corpus, Hermes-scale (~20 msgs/query)
rank_bm25 numpy Yes Medium corpus
bm25s numpy+numba Yes Large corpus
knowledge-rag rank_bm25+ChromaDB Yes Full RAG pipelines

License

MIT — same as Hermes Agent and MemPalace.

About

BM25 hybrid reranking for Hermes Agent — inspired by MemPalace searcher.py

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages