AI Engineering Academy · Урок

Метрики генерации: достоверность и релевантность ответа

Используйте RAGAS, чтобы измерить, соответствуют ли сгенерированные ответы найденному контексту и действительно ли отвечают на вопрос пользователя, не создавая галлюцинаций.

Урок 3 из 413 шагов

«Метрики генерации: достоверность и релевантность ответа» — бесплатный урок AI Engineering Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения AI Engineering Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс AI Engineering Academy содержит 4 уроков всего.

Измерение этапа генерации

Даже если ваш механизм поиска находит идеальные фрагменты, этап генерации всё равно может завершиться ошибкой. LLM может проигнорировать найденный контекст и ответить на основе своей параметрической памяти, неправильно истолковать содержание контекста или ответить на немного другой вопрос, а не на заданный. Метрики генерации количественно оценивают такие ошибки независимо от поиска, чтобы вы могли точно определить и исправить каждую проблему. Две основные метрики генерации — это достоверность и релевантность ответа.

Достоверность: определение

Достоверность показывает, можно ли непосредственно проследить каждое утверждение в сгенерированном ответе до найденного контекста. Достоверный ответ не содержит информации, отсутствующей в контексте. Достоверность измеряется на уровне утверждений: ответ разбивается на отдельные атомарные высказывания, и каждое проверяется на подтверждение в контексте. Оценка достоверности — это доля подтверждённых утверждений.

# Faithfulness = supported_claims / total_claims

example_answer = (
    'Employees receive 15 vacation days per year. '
    'Remote work is allowed on Wednesdays and Fridays. '
    'The CEO is John Smith.'
)
example_context = (
    '15 vacation days are granted annually. '
    'Remote work is permitted on Wednesdays and Fridays.'
)

# Claim 1: 15 vacation days — SUPPORTED
# Claim 2: Remote work Wed+Fri — SUPPORTED
# Claim 3: CEO is John Smith — NOT IN CONTEXT (hallucinated)
# Faithfulness = 2/3 = 0.67

Реализация достоверности с помощью LLM в роли проверяющего

Самый практичный способ масштабно измерять достоверность — использовать мощную LLM в роли проверяющего. Попросите проверяющую LLM разделить ответ на отдельные утверждения, а затем проверить каждое утверждение по контексту. Проверяющая модель возвращает список утверждений с метками SUPPORTED или UNSUPPORTED, после чего вы вычисляете долю подтверждённых утверждений. Такой подход позволяет проводить тысячи оценок в час при стоимости в несколько центов за одну оценку.

import json

def evaluate_faithfulness(answer, context, llm_client):
    prompt = (
        'Task: Evaluate the faithfulness of an answer against a context.\n\n'
        f'Context:\n{context}\n\n'
        f'Answer:\n{answer}\n\n'
        'Steps:\n'
        '1. Break the answer into individual atomic claims.\n'
        '2. For each claim, check if it is supported by the context.\n'
        '3. Return JSON: {"claims": [{"text": "...", "supported": true/false}], "score": 0.0-1.0}'
    )
    response = llm_client.chat.completions.create(
        model='gpt-4o',
        response_format={'type': 'json_object'},
        messages=[{'role': 'user', 'content': prompt}]
    )
    return json.loads(response.choices[0].message.content)

Релевантность ответа: определение

Релевантность ответа показывает, действительно ли сгенерированный ответ отвечает на вопрос пользователя. Даже очень достоверный ответ может не затронуть суть вопроса — например, если пользователь спрашивает: «Как сбросить пароль?», а в ответе подробно объясняется общая политика безопасности компании, но ничего не говорится о процедуре сброса пароля. Релевантность ответа не зависит от достоверности: ответ может быть достоверным (содержать только сведения из контекста), но нерелевантным (не отвечать на заданный вопрос).

Измерение релевантности ответа

RAGAS измеряет релевантность ответа с помощью clever-техники обратной генерации: оценивающая LLM создаёт несколько гипотетических вопросов, на которые отвечал бы сгенерированный ответ, а затем измеряет сходство этих сгенерированных вопросов с исходным вопросом с помощью косинусного сходства эмбеддингов. Высокое сходство между гипотетическими вопросами и исходным вопросом указывает на высокую релевантность ответа.

def evaluate_answer_relevance(question, answer, llm_client, embed_fn):
    # Generate hypothetical questions for this answer
    prompt = (
        f'Given this answer: "{answer}"\n\n'
        'Generate 3 questions that this answer would be a good response to.\n'
        'Return as JSON: {"questions": ["...", "...", "..."]}'
    )
    response = llm_client.chat.completions.create(
        model='gpt-4o-mini',
        response_format={'type': 'json_object'},
        messages=[{'role': 'user', 'content': prompt}]
    )
    hyp_questions = json.loads(response.choices[0].message.content)['questions']

    # Measure similarity to original question
    orig_embedding = embed_fn(question)
    hyp_embeddings = [embed_fn(q) for q in hyp_questions]
    similarities = [cosine_similarity(orig_embedding, e) for e in hyp_embeddings]
    return sum(similarities) / len(similarities)

Полнота контекста: достаточно ли данных мы извлекли?

Полнота контекста показывает, содержит ли извлечённый контекст достаточно информации для правильного ответа на вопрос. Проверка выполняется по эталонному ответу, предложение за предложением: можно ли сопоставить каждое предложение с одним из извлечённых фрагментов? Высокая полнота контекста означает, что механизм извлечения нашёл всё необходимое. Низкая полнота контекста означает, что в извлечённых фрагментах отсутствовала ключевая информация, поэтому LLM не сможет ответить правильно даже при идеальной генерации.

def evaluate_context_recall(ground_truth_answer, retrieved_contexts, llm_client):
    prompt = (
        f'Ground truth answer:\n{ground_truth_answer}\n\n'
        f'Retrieved context:\n{",".join(retrieved_contexts)}\n\n'
        'For each sentence in the ground truth answer, determine if it '
        'can be attributed to the retrieved context.\n'
        'Return JSON: {"sentences": [{"text": "...", "in_context": true/false}], "recall": 0.0-1.0}'
    )
    response = llm_client.chat.completions.create(
        model='gpt-4o',
        response_format={'type': 'json_object'},
        messages=[{'role': 'user', 'content': prompt}]
    )
    return json.loads(response.choices[0].message.content)

Точность контекста: релевантны ли извлечённые фрагменты?

Точность контекста показывает, действительно ли извлечённые фрагменты полезны для ответа на вопрос. Высокая точность контекста означает, что извлечённые фрагменты непосредственно релевантны. Низкая точность контекста означает, что многие извлечённые фрагменты представляют собой нерелевантный шум, который LLM приходится читать и отбрасывать, из-за чего повышается риск путаницы. Точность контекста измеряется проверкой того, какие извлечённые фрагменты действительно использовались или упоминались в сгенерированном ответе.

def evaluate_context_precision(question, answer, retrieved_contexts, llm_client):
    precision_scores = []
    for i, context in enumerate(retrieved_contexts, 1):
        prompt = (
            f'Question: {question}\n\n'
            f'Context chunk {i}: {context}\n\n'
            f'Answer: {answer}\n\n'
            'Was this context chunk useful in generating the answer? '
            'Return JSON: {"useful": true/false, "reason": "..."}'
        )
        response = llm_client.chat.completions.create(
            model='gpt-4o-mini',
            response_format={'type': 'json_object'},
            messages=[{'role': 'user', 'content': prompt}]
        )
        result = json.loads(response.choices[0].message.content)
        precision_scores.append(1.0 if result['useful'] else 0.0)
    return sum(precision_scores) / len(precision_scores)

Использование RAGAS для одновременного расчёта всех метрик

Библиотека RAGAS реализует все четыре основные метрики RAG — точность контекста, полноту контекста, достоверность и релевантность ответа — в рамках единой системы. Вызовы оценивающей LLM выполняются внутри библиотеки. Передайте набор данных с вопросами, сгенерированными ответами, извлечёнными контекстами и эталонными ответами и получите подробный отчёт с оценками. RAGAS также поддерживает асинхронную оценку, поэтому можно оценивать сотни примеров параллельно.

from ragas import evaluate
from ragas.metrics import (
    faithfulness, answer_relevancy,
    context_precision, context_recall
)
from datasets import Dataset

# Build evaluation dataset
eval_samples = [
    {
        'question': item['question'],
        'answer': item['generated_answer'],
        'contexts': item['retrieved_texts'],
        'ground_truth': item['expected_answer']
    }
    for item in test_results
]

eval_dataset = Dataset.from_list(eval_samples)
results = evaluate(eval_dataset,
    metrics=[faithfulness, answer_relevancy, context_precision, context_recall]
)
results.to_pandas().to_csv('eval_results.csv', index=False)

Диагностика с помощью сочетаний метрик

Сочетание метрик позволяет выявить конкретные проблемы системы. Низкая достоверность + высокая точность контекста → LLM игнорирует контекст и галлюцинирует (исправьте запрос к модели). Низкая полнота контекста + высокая достоверность → механизм извлечения не находит ключевые фрагменты, но LLM достоверно пересказывает найденное (исправьте разбиение на фрагменты или эмбеддинги). Низкая релевантность ответа + высокая достоверность → извлечённые фрагменты лишь косвенно связаны с вопросом, и LLM достоверно обсуждает их, но не отвечает на сам вопрос (улучшите фильтрацию результатов извлечения или переформулирование запроса).

# Diagnostic matrix
diagnostics = [
    {
        'condition': 'Low faithfulness + High context precision',
        'cause': 'LLM ignoring context, answering from parametric memory',
        'fix': 'Strengthen system prompt: "Answer ONLY from the provided context"'
    },
    {
        'condition': 'Low context recall + High faithfulness',
        'cause': 'Retriever missing relevant chunks',
        'fix': 'Improve chunking strategy, embedding model, or increase top-k'
    },
    {
        'condition': 'Low answer relevance + High context recall',
        'cause': 'Retrieved context is off-topic; LLM is answering wrong question',
        'fix': 'Add query rewriting or improve metadata filters'
    }
]

Калибровка с помощью оценки людьми

Метрики по принципу «LLM в роли оценщика» коррелируют с оценками людей, но не полностью им соответствуют. Откалибруйте автоматические метрики: попросите 3 оценщиков-людей оценить случайную выборку из 50 результатов по достоверности и релевантности ответа по шкале от 1 до 5. Рассчитайте согласованность между оценкой LLM и средней оценкой людей. Если LLM систематически завышает или занижает оценки по сравнению с людьми, примените поправочный коэффициент. Откалиброванные автоматические метрики позволяют быть уверенными, что улучшение оценок отражает реальное повышение качества.

from scipy.stats import spearmanr

def calibrate_judge_vs_humans(samples):
    '''samples: [{"llm_score": 0.9, "human_score": 4.2}, ...]'''
    llm_scores = [s['llm_score'] for s in samples]
    human_scores = [s['human_score'] / 5.0 for s in samples]  # normalize to 0-1

    correlation, pvalue = spearmanr(llm_scores, human_scores)
    print(f'LLM-Human Spearman correlation: {correlation:.3f} (p={pvalue:.4f})')

    mean_llm = sum(llm_scores) / len(llm_scores)
    mean_human = sum(human_scores) / len(human_scores)
    bias = mean_llm - mean_human
    print(f'LLM bias vs humans: {bias:+.3f}')
    return correlation, bias

Задание целевых значений метрик для рабочей среды

Перед развёртыванием RAG-системы в рабочей среде определите минимальные пороговые значения метрик, которым должна соответствовать система. Распространённые целевые значения для рабочей среды таковы: достоверность > 0.90 (галлюцинируется менее 10% утверждений в ответах), релевантность ответа > 0.80 (более 80% ответов действительно отвечают на вопрос), точность контекста > 0.60 (большинство извлечённых фрагментов релевантны) и полнота контекста > 0.75 (большинство ключевых фактов доступно в извлечённом контексте). Системы, не достигающие этих порогов, нельзя развёртывать без дальнейшего улучшения.

PRODUCTION_THRESHOLDS = {
    'faithfulness': 0.90,
    'answer_relevancy': 0.80,
    'context_precision': 0.60,
    'context_recall': 0.75
}

def check_production_readiness(metrics):
    ready = True
    print('Production readiness check:')
    for metric, threshold in PRODUCTION_THRESHOLDS.items():
        score = metrics.get(metric, 0)
        status = 'PASS' if score >= threshold else 'FAIL'
        print(f'  {metric}: {score:.2f} (>= {threshold}) -> {status}')
        if status == 'FAIL':
            ready = False
    print(f'Overall: {"READY" if ready else "NOT READY"}')
    return ready

Быстрая проверка

Проверьте своё понимание концепций инженерии ИИ из этого урока.

Итоги урока

В этом уроке вы узнали: достоверность как метрику на уровне утверждений, проверяющую, подтверждается ли каждое утверждение в ответе извлечённым контекстом; релевантность ответа как метрику, показывающую, отвечает ли ответ на фактический вопрос; полноту и точность контекста для измерения качества извлечения с точки зрения генерации; а также библиотеку RAGAS для автоматической оценки по нескольким метрикам. Далее мы объединим все эти метрики в автоматизированный контур оценки, который можно запускать при каждом изменении.

Можно начать бесплатно

Изучай Python с ИИ-репетитором — бесплатно

Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.

Курсы
30
Уроки
120

Часто задаваемые вопросы

Урок «Метрики генерации: достоверность и релевантность ответа» бесплатный?

Да — полный текст урока «Метрики генерации: достоверность и релевантность ответа» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс AI Engineering Academy, подпишись на CoddyKit PRO. Курс AI Engineering Academy содержит 4 уроков всего.

Чему я научусь в уроке «Метрики генерации: достоверность и релевантность ответа»?

Используйте RAGAS, чтобы измерить, соответствуют ли сгенерированные ответы найденному контексту и действительно ли отвечают на вопрос пользователя, не создавая галлюцинаций. Ты практикуешь AI Engineering Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать AI Engineering Academy?

Предыдущий опыт не требуется. AI Engineering Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.

Сколько времени занимает урок «Метрики генерации: достоверность и релевантность ответа»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке AI Engineering Academy?

Да. Каждый урок AI Engineering Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Зачем нужна оценка RAG
  2. Метрики поиска: доля попаданий, MRR и NDCG
  3. Метрики генерации: достоверность и релевантность ответа
  4. Создание автоматизированной системы оценки
← Назад к AI Engineering Academy