Точность контекста (Contextual Precision)¶
Метрика Contextual Precision измеряет точность ранжирования найденных фрагментов контекста -- правильно ли релевантные фрагменты расположены выше нерелевантных в списке результатов.
Это метрика, вдохновлённая классическим Precision@K из информационного поиска (Information Retrieval). Она не просто проверяет, есть ли среди результатов релевантные фрагменты, но и оценивает их позицию в списке. Идеальный ретривер должен ранжировать релевантные фрагменты на первых позициях.
Как это работает¶
Метрика использует формулу Precision@K, адаптированную для оценки RAG-контекста:
Где \(v_k = 1\), если фрагмент \(k\) релевантен эталонному ответу, \(0\) -- в противном случае.
Алгоритм работает в три этапа:
- Проверка релевантности (Relevance Check) -- для каждого фрагмента контекста определяет, релевантен ли он эталонному ответу (
expected_output). Решение принимает LLM. - Оценка ранжирования (Ranking Evaluation) -- проверяет, расположены ли релевантные фрагменты перед нерелевантными.
- Расчёт точности (Precision Calculation) -- вычисляет взвешенную точность на основе позиций фрагментов.
Пример расчёта: если у вас 3 фрагмента [Релевантный, Нерелевантный, Релевантный], то:
- Precision@1 = 1/1 = 1.0 (первый фрагмент релевантен)
- Precision@3 = 2/3 = 0.67 (третий фрагмент релевантен)
- Итого: (1.0 * 1 + 0.67 * 1) / 2 = 0.835
Параметры¶
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
model | str | обязательный | Любая модель: "gpt-4o", "anthropic:claude-3-5-sonnet-latest", "google:gemini-2.0-flash", "ollama:llama3" или CustomLLMClient |
threshold | float | 0.7 | Минимальный балл для прохождения теста |
top_k | int | None | Ограничить оценку первыми K фрагментами |
Параметр top_k полезен, если ваш ретривер возвращает много фрагментов, но вы хотите оценить только топ-N. Это также экономит вызовы API.
Обязательные поля¶
| Поле | Обязательно |
|---|---|
input | Да |
actual_output | Да |
expected_output | Да |
retrieval_context | Да |
Использование¶
from eval_lib import ContextualPrecisionMetric, EvalTestCase, evaluate
import asyncio
test_case = EvalTestCase(
input="What is transfer learning?",
actual_output="Transfer learning reuses a pre-trained model on a new task.",
expected_output="Transfer learning is a technique where a model trained on one task is reused as the starting point for a model on a second task.",
retrieval_context=[
"Transfer learning is an ML technique where a model developed for one task is reused for a different task.", # Relevant
"The weather in Tokyo is sunny with temperatures around 25°C.", # Irrelevant
"Fine-tuning is a common approach in transfer learning where pre-trained weights are adjusted.", # Relevant
]
)
metric = ContextualPrecisionMetric(model="gpt-4o", threshold=0.7)
results = asyncio.run(evaluate([test_case], [metric]))
В этом примере релевантные фрагменты (1-й и 3-й) разделены нерелевантным (2-й). Идеальное ранжирование было бы: оба релевантных фрагмента на первых позициях.
Стоимость¶
N вызовов LLM API, где N -- количество фрагментов контекста. Каждый фрагмент оценивается независимо.
Интерпретация результатов¶
| Балл | Интерпретация |
|---|---|
| 1.0 | Все релевантные фрагменты ранжированы выше нерелевантных -- идеальное ранжирование |
| 0.5-0.8 | Релевантные фрагменты перемешаны с нерелевантными |
| < 0.5 | Нерелевантные фрагменты ранжированы выше релевантных -- плохое качество поиска |
Практические советы¶
- Contextual Precision особенно важна для систем с ограниченным контекстным окном. Если LLM видит только первые N фрагментов, критически важно, чтобы релевантные были в начале.
- Низкая Contextual Precision при высокой Contextual Recall означает, что ретривер находит нужную информацию, но плохо ранжирует -- попробуйте re-ranking модели.
- Используйте
top_kдля ограничения оценки, если у вас много фрагментов: это и экономит стоимость API, и показывает качество ранжирования "головы" списка.