Skip to content

Commit bf8f116

Browse files
Sravan1011claude
andcommitted
fix: guard recall@10 alongside recall@5 in the regression check
The suite computes and stores recall_at_10 in both results and the baseline, but the guard only compared recall_at_5 — a change that preserves the top 5 while dropping documents ranked 6-10 would pass CI with recall@10 silently regressed. The guard now loops over both metrics with the same threshold, reports each in the log, and lists every regressed metric in the failure message. conftest help text and README updated to match. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 062eebc commit bf8f116

3 files changed

Lines changed: 32 additions & 22 deletions

File tree

benchmarks/ci/README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,8 @@ variable pointing at a shared or production index cannot be destroyed.
6767
The harness compares the current run's metrics against `baseline.json`:
6868

6969
- **Latency**: Fails if P95 increases by more than the threshold (default 20%)
70-
- **Recall**: Fails if Recall@5 drops by more than the threshold (default 5pp)
70+
- **Recall**: Fails if Recall@5 **or** Recall@10 drops by more than the
71+
threshold (default 5pp)
7172

7273
The latency guard arms itself from the baseline file:
7374

benchmarks/ci/conftest.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,6 @@ def pytest_addoption(parser: pytest.Parser) -> None:
3131
"--recall-threshold",
3232
type=float,
3333
default=0.05,
34-
help="Max allowed absolute decrease in recall@5 vs baseline "
35-
"(default: 0.05 = 5 percentage points)",
34+
help="Max allowed absolute decrease in recall@5 and recall@10 vs "
35+
"baseline (default: 0.05 = 5 percentage points)",
3636
)

benchmarks/ci/test_bench_ci_moss.py

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -481,29 +481,38 @@ def test_no_recall_regression(self, request, benchmark_results):
481481
with open(baseline_path) as f:
482482
baseline = json.load(f)
483483

484-
baseline_recall = baseline.get("recall", {}).get("recall_at_5")
485-
current_recall = benchmark_results.get("recall", {}).get("recall_at_5")
486-
487-
if baseline_recall is None or current_recall is None:
488-
_missing_required_input(
489-
"Recall measurement data missing — the recall test did not run"
490-
)
484+
# Guard every recall metric the suite records — checking only
485+
# recall@5 would let a change that preserves the top 5 but drops
486+
# documents ranked 6-10 pass while recall@10 regresses.
487+
recall_pairs: dict[str, tuple[float, float]] = {}
488+
for key in ("recall_at_5", "recall_at_10"):
489+
baseline_val = baseline.get("recall", {}).get(key)
490+
current_val = benchmark_results.get("recall", {}).get(key)
491+
if baseline_val is None or current_val is None:
492+
_missing_required_input(
493+
f"Recall measurement data missing for {key} — "
494+
"the recall test did not run"
495+
)
496+
recall_pairs[key] = (baseline_val, current_val)
491497

492498
_assert_baseline_compatible(baseline, benchmark_results)
493499

494-
drop = baseline_recall - current_recall
495-
500+
failures: list[str] = []
496501
print("\n Recall regression check:")
497-
print(f" Baseline Recall@5 : {baseline_recall:.4f}")
498-
print(f" Current Recall@5 : {current_recall:.4f}")
499-
print(f" Drop : {drop:+.4f}")
500-
print(f" Threshold : {threshold:.4f}")
501-
502-
assert drop <= threshold, (
503-
f"Recall@5 dropped by {drop:.4f} "
504-
f"(baseline={baseline_recall:.4f}, current={current_recall:.4f}, "
505-
f"threshold={threshold:.4f})"
506-
)
502+
print(f" Threshold: {threshold:.4f}")
503+
for key, (baseline_val, current_val) in recall_pairs.items():
504+
drop = baseline_val - current_val
505+
print(
506+
f" {key}: baseline={baseline_val:.4f} "
507+
f"current={current_val:.4f} drop={drop:+.4f}"
508+
)
509+
if drop > threshold:
510+
failures.append(
511+
f"{key} dropped by {drop:.4f} (baseline={baseline_val:.4f}, "
512+
f"current={current_val:.4f}, threshold={threshold:.4f})"
513+
)
514+
515+
assert not failures, "Recall regression: " + "; ".join(failures)
507516

508517

509518
class TestWriteResults:

0 commit comments

Comments
 (0)