Skip to content

Commit 2d6ba6b

Browse files
committed
[LEADS-504] Simplify Ragas context precision metric names
1 parent 807df32 commit 2d6ba6b

9 files changed

Lines changed: 73 additions & 31 deletions

File tree

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -217,8 +217,8 @@ uv run lightspeed-eval --system-config <AGENTS_CONFIG.yaml> --eval-data <PROPOSA
217217
- Context Evaluation
218218
- [`context_recall`](https://docs.ragas.io/en/stable/concepts/metrics/available_metrics/context_recall/)
219219
- [`context_relevance`](https://docs.ragas.io/en/stable/concepts/metrics/available_metrics/nvidia_metrics/#context-relevance)
220-
- [`context_precision_without_reference`](https://docs.ragas.io/en/stable/concepts/metrics/available_metrics/context_precision/#context-precision-without-reference)
221-
- [`context_precision_with_reference`](https://docs.ragas.io/en/stable/concepts/metrics/available_metrics/context_precision/#context-precision-with-reference)
220+
- [`context_utilization`](https://docs.ragas.io/en/stable/concepts/metrics/available_metrics/context_precision/#context-precision-without-reference) (context precision without reference)
221+
- [`context_precision`](https://docs.ragas.io/en/stable/concepts/metrics/available_metrics/context_precision/#context-precision-with-reference) (context precision with reference)
222222
- **Custom**
223223
- Response Evaluation
224224
- [`answer_correctness`](src/lightspeed_evaluation/core/metrics/custom/custom.py)

config/evaluation_data.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
turn_metrics:
2121
- ragas:faithfulness
2222
- ragas:response_relevancy
23-
- ragas:context_precision_without_reference
23+
- ragas:context_utilization
2424
turn_metrics_metadata:
2525
ragas:faithfulness:
2626
threshold: 0.99
@@ -42,7 +42,7 @@
4242
turn_metrics:
4343
- ragas:context_recall
4444
- ragas:context_relevance
45-
- ragas:context_precision_with_reference
45+
- ragas:context_precision
4646

4747
- conversation_group_id: conv_group_3
4848
description: conversation group description

config/system.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ agents:
108108
quality_score:
109109
metrics:
110110
- "ragas:faithfulness"
111-
- "ragas:context_precision_with_reference"
111+
- "ragas:context_precision"
112112
- "custom:tool_eval"
113113
- "custom:answer_correctness"
114114
default: true # If true, all metrics in this list get default: true
@@ -133,11 +133,11 @@ metrics_metadata:
133133
threshold: 0.8
134134
description: "Did we fetch every fact the answer needs?"
135135

136-
"ragas:context_precision_with_reference":
136+
"ragas:context_precision":
137137
threshold: 0.7
138138
description: "How precise the retrieved context is (with reference)"
139139

140-
"ragas:context_precision_without_reference":
140+
"ragas:context_utilization":
141141
threshold: 0.7
142142
description: "How precise the retrieved context is (without reference)"
143143

docs/EVALUATION_GUIDE.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -687,8 +687,8 @@ What are you evaluating?
687687
│ ├─ Context / Retrieval Quality?
688688
│ │ ├─ Found everything needed? → context_recall
689689
│ │ ├─ Is retrieved context relevant? → context_relevance
690-
│ │ ├─ Precision (have expected answer)? → context_precision_with_reference
691-
│ │ └─ Precision (no expected answer)? → context_precision_without_reference
690+
│ │ ├─ Precision (have expected answer)? → context_precision
691+
│ │ └─ Precision (no expected answer)? → context_utilization
692692
│ │
693693
│ ├─ Tool Calls & AI Behavior?
694694
│ │ ├─ Right intent? → intent_eval
@@ -1401,7 +1401,7 @@ The Quality Score aggregates selected sub-metrics into a single number that repr
14011401
quality_score:
14021402
metrics:
14031403
- "ragas:faithfulness"
1404-
- "ragas:context_precision_with_reference"
1404+
- "ragas:context_precision"
14051405
- "custom:tool_eval"
14061406
default: true
14071407
```
@@ -1985,8 +1985,8 @@ lightspeed-eval --eval-data config/eval_batch2.yaml
19851985
| **ragas:faithfulness** | 0-1 | No made-up information | 0.8 | response, contexts |
19861986
| **ragas:context_recall** | 0-1 | Found all needed info | 0.8 | contexts, expected_response |
19871987
| **ragas:context_relevance** | 0-1 | Retrieved info is relevant | 0.7 | query, contexts |
1988-
| **ragas:context_precision_without_reference** | 0-1 | Retrieved info is useful | 0.7 | query, contexts, response |
1989-
| **ragas:context_precision_with_reference** | 0-1 | Retrieved info is useful (vs reference) | 0.7 | query, contexts, response, expected_response |
1988+
| **ragas:context_utilization** | 0-1 | Retrieved info is useful | 0.7 | query, contexts, response |
1989+
| **ragas:context_precision** | 0-1 | Retrieved info is useful (vs reference) | 0.7 | query, contexts, response, expected_response |
19901990
| **custom:answer_correctness** | 0-1 | Matches expected answer | 0.75 | query, response, expected_response |
19911991
| **custom:intent_eval** | 0/1 | Has right intent | 1 | query, response, expected_intent |
19921992
| **custom:tool_eval** | 0/1 | Called correct tools with expected results | 1 | expected_tool_calls, tool_calls |

examples/02_metrics/context_quality/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ uv run lightspeed-eval \
2020
|-----------------------------------------------|---------------------|---------------------------------------------------------------------------------------|--------------------------------------------|-----------------------------|
2121
| `ragas:context_recall` | Context Recall | Measures how well retrieved context covers the expected answer | query, response, contexts, expected_response | query, expected_response |
2222
| `ragas:context_relevance` | Context Relevance | Evaluates relevance of retrieved context to the query | query, response, contexts | query |
23-
| `ragas:context_precision_without_reference` | Context Utilization | Assesses context ranking quality without using reference answer | query, response, contexts | query |
24-
| `ragas:context_precision_with_reference` | Context Precision | Assesses context ranking quality using expected answer | query, response, contexts, expected_response | query, expected_response |
23+
| `ragas:context_utilization` | Context Utilization | Assesses context ranking quality without using reference answer | query, response, contexts | query |
24+
| `ragas:context_precision` | Context Precision | Assesses context ranking quality using expected answer | query, response, contexts, expected_response | query, expected_response |
2525

2626
**Note:** In live mode, `response` and `contexts` are fetched from live API; only `query` and expected fields go in YAML.
2727

examples/02_metrics/context_quality/system.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,11 @@ metrics_metadata:
3131
threshold: 0.7
3232
description: Measures relevance of retrieved context to the query
3333
default: true
34-
ragas:context_precision_without_reference: # ContextUtilization
34+
ragas:context_utilization: # ContextUtilization
3535
threshold: 0.7
3636
description: Evaluates precision of context ranking (no reference needed)
3737
default: true
38-
ragas:context_precision_with_reference: # ContextPrecision
38+
ragas:context_precision: # ContextPrecision
3939
threshold: 0.7
4040
description: Evaluates precision of context using expected answer
4141
default: true

src/lightspeed_evaluation/core/constants.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,3 +137,10 @@
137137
DEFAULT_LOG_SHOW_TIMESTAMPS = True
138138

139139
SUPPORTED_RESULT_STATUSES = ["PASS", "FAIL", "ERROR", "SKIPPED"]
140+
141+
# Deprecated metric names that still work but should be migrated.
142+
# Maps old (deprecated) full identifier -> new canonical identifier.
143+
DEPRECATED_METRIC_NAMES: dict[str, str] = {
144+
"ragas:context_precision_with_reference": "ragas:context_precision",
145+
"ragas:context_precision_without_reference": "ragas:context_utilization",
146+
}

src/lightspeed_evaluation/core/metrics/ragas.py

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"""Ragas metrics evaluation using LLM Manager with Ragas 0.4+ API."""
22

33
import errno
4+
import logging
45
import math
56
import threading
67
from typing import Any, Optional
@@ -28,6 +29,13 @@
2829
from lightspeed_evaluation.core.models import EvaluationScope, TurnData
2930
from lightspeed_evaluation.core.system.exceptions import EvaluationError
3031

32+
logger = logging.getLogger(__name__)
33+
34+
_DEPRECATED_RAGAS_METRICS: dict[str, str] = {
35+
"context_precision_with_reference": "context_precision",
36+
"context_precision_without_reference": "context_utilization",
37+
}
38+
3139

3240
def _clamp_score(score: float) -> float:
3341
"""Clamp score to [0, 1] range to handle floating-point precision issues.
@@ -88,10 +96,11 @@ def __init__(self, llm_manager: LLMManager, embedding_manager: EmbeddingManager)
8896
# Context/Retrieval evaluation metrics
8997
"context_recall": self._evaluate_context_recall,
9098
"context_relevance": self._evaluate_context_relevance,
91-
"context_precision_with_reference": self._evaluate_context_precision_with_reference,
92-
"context_precision_without_reference": (
93-
self._evaluate_context_precision_without_reference
94-
),
99+
"context_precision": self._evaluate_context_precision,
100+
"context_utilization": self._evaluate_context_utilization,
101+
# Deprecated aliases (backward compatibility)
102+
"context_precision_with_reference": self._evaluate_context_precision,
103+
"context_precision_without_reference": self._evaluate_context_utilization,
95104
}
96105

97106
@property
@@ -133,6 +142,14 @@ def evaluate(
133142
scope: EvaluationScope,
134143
) -> tuple[Optional[float], str]:
135144
"""Evaluate a Ragas metric."""
145+
if metric_name in _DEPRECATED_RAGAS_METRICS:
146+
new_name = _DEPRECATED_RAGAS_METRICS[metric_name]
147+
logger.warning(
148+
"Metric 'ragas:%s' is deprecated, use 'ragas:%s' instead.",
149+
metric_name,
150+
new_name,
151+
)
152+
136153
if metric_name not in self.supported_metrics:
137154
return None, f"Unsupported Ragas metric: {metric_name}"
138155

@@ -220,16 +237,16 @@ def _evaluate_faithfulness(
220237
score = _clamp_score(float(result.value))
221238
return score, f"Ragas faithfulness: {score:.2f}"
222239

223-
def _evaluate_context_precision_without_reference(
240+
def _evaluate_context_utilization(
224241
self,
225242
_conv_data: Any,
226243
_turn_idx: Optional[int],
227244
turn_data: Optional[TurnData],
228245
is_conversation: bool,
229246
) -> tuple[Optional[float], str]:
230-
"""Evaluate context precision without reference using Ragas 0.4+ score()."""
247+
"""Evaluate context utilization using Ragas 0.4+ ContextUtilization."""
231248
if is_conversation:
232-
return None, "Context precision without reference is a turn-level metric"
249+
return None, "Context utilization is a turn-level metric"
233250

234251
query, response, contexts = self._extract_turn_data(turn_data)
235252

@@ -242,21 +259,21 @@ def _evaluate_context_precision_without_reference(
242259
)
243260

244261
score = _clamp_score(float(result.value))
245-
return score, f"Ragas context precision without reference: {score:.2f}"
262+
return score, f"Ragas context utilization: {score:.2f}"
246263

247-
def _evaluate_context_precision_with_reference(
264+
def _evaluate_context_precision(
248265
self,
249266
_conv_data: Any,
250267
_turn_idx: Optional[int],
251268
turn_data: Optional[TurnData],
252269
is_conversation: bool,
253270
) -> tuple[Optional[float], str]:
254-
"""Evaluate context precision with reference using Ragas 0.4+ score()."""
271+
"""Evaluate context precision using Ragas 0.4+ ContextPrecision."""
255272
if is_conversation:
256-
return None, "Context precision with reference is a turn-level metric"
273+
return None, "Context precision is a turn-level metric"
257274

258275
if turn_data is None:
259-
return None, "TurnData is required for context precision with reference"
276+
return None, "TurnData is required for context precision"
260277

261278
query, _, contexts = self._extract_turn_data(turn_data)
262279

@@ -269,7 +286,7 @@ def _evaluate_context_precision_with_reference(
269286
)
270287

271288
score = _clamp_score(float(result.value))
272-
return score, f"Ragas context precision with reference: {score:.2f}"
289+
return score, f"Ragas context precision: {score:.2f}"
273290

274291
def _evaluate_context_recall(
275292
self,

src/lightspeed_evaluation/core/system/validator.py

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import yaml
88
from pydantic import ValidationError
99

10+
from lightspeed_evaluation.core.constants import DEPRECATED_METRIC_NAMES
1011
from lightspeed_evaluation.core.models import EvaluationData, TurnData
1112
from lightspeed_evaluation.core.models.data import DatasetMetadata
1213
from lightspeed_evaluation.core.system.exceptions import DataValidationError
@@ -32,6 +33,15 @@
3233
"required_fields": ["response", "contexts"],
3334
"description": "requires 'response' and 'contexts' fields",
3435
},
36+
"ragas:context_precision": {
37+
"required_fields": ["response", "contexts", "expected_response"],
38+
"description": "requires 'response', 'contexts', and 'expected_response' fields",
39+
},
40+
"ragas:context_utilization": {
41+
"required_fields": ["response", "contexts"],
42+
"description": "requires 'response' and 'contexts' fields",
43+
},
44+
# Deprecated aliases (backward compatibility)
3545
"ragas:context_precision_with_reference": {
3646
"required_fields": ["response", "contexts", "expected_response"],
3747
"description": "requires 'response', 'contexts', and 'expected_response' fields",
@@ -455,7 +465,11 @@ def _validate_metrics_availability(self, data: EvaluationData) -> None:
455465
for turn_data in data.turns:
456466
if turn_data.turn_metrics:
457467
for metric in turn_data.turn_metrics:
458-
if metric not in self._turn_level_metrics:
468+
canonical = DEPRECATED_METRIC_NAMES.get(metric, metric)
469+
if (
470+
metric not in self._turn_level_metrics
471+
and canonical not in self._turn_level_metrics
472+
):
459473
turn_data.add_invalid_metric(metric)
460474
self.validation_errors.append(
461475
f"Conversation {conversation_id}, Turn {turn_data.turn_id}: "
@@ -465,7 +479,11 @@ def _validate_metrics_availability(self, data: EvaluationData) -> None:
465479
# Validate conversation metrics
466480
if data.conversation_metrics:
467481
for metric in data.conversation_metrics:
468-
if metric not in self._conversation_level_metrics:
482+
canonical = DEPRECATED_METRIC_NAMES.get(metric, metric)
483+
if (
484+
metric not in self._conversation_level_metrics
485+
and canonical not in self._conversation_level_metrics
486+
):
469487
data.add_invalid_metric(metric)
470488
self.validation_errors.append(
471489
f"Conversation {conversation_id}: Unknown conversation metric '{metric}'"

0 commit comments

Comments
 (0)