fix(reranker): clamp out-of-range LLM scores instead of mis-parsing them (#5635)
This commit is contained in:
@@ -90,14 +90,14 @@ class LLMReranker(BaseReranker):
|
|||||||
|
|
||||||
def _extract_score(self, response_text: str) -> float:
|
def _extract_score(self, response_text: str) -> float:
|
||||||
"""Extract numerical score from LLM response."""
|
"""Extract numerical score from LLM response."""
|
||||||
# Look for decimal numbers between 0.0 and 1.0
|
# Prefer a decimal, fall back to an integer, then clamp: out-of-range outputs
|
||||||
pattern = r'\b([01](?:\.\d+)?)\b'
|
# like "2.0"/"5" become 1.0 instead of being mis-parsed into a stray 0/1 digit.
|
||||||
matches = re.findall(pattern, response_text)
|
matches = re.findall(r'-?\d+\.\d+', response_text) or re.findall(r'-?\d+', response_text)
|
||||||
|
|
||||||
if matches:
|
if matches:
|
||||||
score = float(matches[0])
|
score = float(matches[0])
|
||||||
return min(max(score, 0.0), 1.0) # Clamp between 0.0 and 1.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
|
# Fallback: return 0.5 if no valid score found
|
||||||
return 0.5
|
return 0.5
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,23 @@ class TestExtractScore:
|
|||||||
def test_clamps_to_1(self, reranker):
|
def test_clamps_to_1(self, reranker):
|
||||||
assert reranker._extract_score("1.0") == 1.0
|
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:
|
class TestRerank:
|
||||||
def test_empty_documents(self, mock_llm):
|
def test_empty_documents(self, mock_llm):
|
||||||
|
|||||||
Reference in New Issue
Block a user