Перейти к содержанию

Точность контекста (Contextual Precision)

Метрика Contextual Precision измеряет точность ранжирования найденных фрагментов контекста -- правильно ли релевантные фрагменты расположены выше нерелевантных в списке результатов.

Это метрика, вдохновлённая классическим Precision@K из информационного поиска (Information Retrieval). Она не просто проверяет, есть ли среди результатов релевантные фрагменты, но и оценивает их позицию в списке. Идеальный ретривер должен ранжировать релевантные фрагменты на первых позициях.

Как это работает

Метрика использует формулу Precision@K, адаптированную для оценки RAG-контекста:

\[ \text{Context Precision@K} = \frac{\sum_{k=1}^{K} (\text{Precision@k} \times v_k)}{\text{Number of relevant chunks}} \]

Где \(v_k = 1\), если фрагмент \(k\) релевантен эталонному ответу, \(0\) -- в противном случае.

Алгоритм работает в три этапа:

  1. Проверка релевантности (Relevance Check) -- для каждого фрагмента контекста определяет, релевантен ли он эталонному ответу (expected_output). Решение принимает LLM.
  2. Оценка ранжирования (Ranking Evaluation) -- проверяет, расположены ли релевантные фрагменты перед нерелевантными.
  3. Расчёт точности (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 Нерелевантные фрагменты ранжированы выше релевантных -- плохое качество поиска

Практические советы

  1. Contextual Precision особенно важна для систем с ограниченным контекстным окном. Если LLM видит только первые N фрагментов, критически важно, чтобы релевантные были в начале.
  2. Низкая Contextual Precision при высокой Contextual Recall означает, что ретривер находит нужную информацию, но плохо ранжирует -- попробуйте re-ranking модели.
  3. Используйте top_k для ограничения оценки, если у вас много фрагментов: это и экономит стоимость API, и показывает качество ранжирования "головы" списка.