From 48f1d6f01063ecd802fc18b0cd9dd8166826ca88 Mon Sep 17 00:00:00 2001 From: Yash Singh <123385188+yashs33244@users.noreply.github.com> Date: Fri, 19 Jun 2026 12:49:50 +0530 Subject: [PATCH] fix(reranker): clamp out-of-range LLM scores instead of mis-parsing them (#5635) --- mem0/reranker/llm_reranker.py | 10 +++++----- tests/rerankers/test_llm_reranker_rerank.py | 17 +++++++++++++++++ 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/mem0/reranker/llm_reranker.py b/mem0/reranker/llm_reranker.py index 16d7f47c3..b89e25f4a 100644 --- a/mem0/reranker/llm_reranker.py +++ b/mem0/reranker/llm_reranker.py @@ -90,14 +90,14 @@ class LLMReranker(BaseReranker): def _extract_score(self, response_text: str) -> float: """Extract numerical score from LLM response.""" - # Look for decimal numbers between 0.0 and 1.0 - pattern = r'\b([01](?:\.\d+)?)\b' - matches = re.findall(pattern, response_text) - + # Prefer a decimal, fall back to an integer, then clamp: out-of-range outputs + # like "2.0"/"5" become 1.0 instead of being mis-parsed into a stray 0/1 digit. + matches = re.findall(r'-?\d+\.\d+', response_text) or re.findall(r'-?\d+', response_text) + if matches: score = float(matches[0]) return min(max(score, 0.0), 1.0) # Clamp between 0.0 and 1.0 - + # Fallback: return 0.5 if no valid score found return 0.5 diff --git a/tests/rerankers/test_llm_reranker_rerank.py b/tests/rerankers/test_llm_reranker_rerank.py index 607d99b1b..c7798cb1d 100644 --- a/tests/rerankers/test_llm_reranker_rerank.py +++ b/tests/rerankers/test_llm_reranker_rerank.py @@ -27,6 +27,23 @@ class TestExtractScore: def test_clamps_to_1(self, reranker): assert reranker._extract_score("1.0") == 1.0 + @pytest.mark.parametrize( + "text,expected", + [ + ("2.0", 1.0), + ("5", 1.0), + ("10", 1.0), + ("-0.3", 0.0), + ("-2", 0.0), + ], + ) + def test_out_of_range_scores_are_clamped(self, reranker, text, expected): + assert reranker._extract_score(text) == expected + + def test_decimal_score_preferred_over_leading_integer(self, reranker): + # A distractor integer before the score must not be picked up. + assert reranker._extract_score("Confidence 100%. Relevance: 0.1") == 0.1 + class TestRerank: def test_empty_documents(self, mock_llm):