Зачем нужна оценка RAG
Поймите два независимых источника сбоев в системах RAG: сбой поиска и сбой генерации, а также узнайте, почему для диагностики каждого из них нужны отдельные метрики.
«Зачем нужна оценка RAG» — бесплатный урок AI Engineering Academy на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения AI Engineering Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс AI Engineering Academy содержит 4 уроков всего.
Невозможно улучшить то, что Вы не измеряете
Система RAG может казаться работоспособной, поскольку возвращает беглые и правдоподобные ответы. Но без измерений Вы не знаете, извлекает ли она действительно правильные фрагменты и создаёт ли достоверные ответы. Команды, пропускающие этап оценки, часто месяцами настраивают стратегии разделения текста и форматы запросов, полагаясь на интуицию, а затем обнаруживают, что только ухудшили результат. Строгая оценка превращает разработку RAG из угадывания в инженерную работу.
Два независимых режима отказа
В RAG есть два отдельных этапа, каждый из которых может отказать независимо: извлечение и генерация. Извлечение завершается неудачно, когда релевантные фрагменты не входят в результаты K лучших: LLM не сможет создать хороший ответ, если нужная информация вообще не была извлечена. Генерация завершается неудачно, когда правильные фрагменты были извлечены, но LLM проигнорировала их, неправильно поняла или добавила выдуманные сведения. Для каждого этапа нужны отдельные метрики, чтобы определить, какой компонент вызывает проблему.
Опасность оценки только от начала до конца
Измерение только качества итогового ответа скрывает источник сбоев. Предположим, Ваша система даёт неправильные ответы в 30 % случаев. Происходит ли это потому, что извлечение не находит нужные фрагменты, или потому, что LLM игнорирует хорошие фрагменты? Если Вам известна только итоговая доля ошибок, Вы не сможете понять, какой компонент нужно исправить. Оснастите измерениями оба этапа отдельно: оценивайте качество извлечения с помощью эталонных наборов данных, а качество генерации — с помощью показателей достоверности.
# Diagnosis example: which stage is failing?
# Test 1: Is retrieval finding the right chunks?
retrieval_hit_rate = evaluate_retrieval(questions, ground_truth_chunks)
print(f'Retrieval hit rate@5: {retrieval_hit_rate:.1%}')
# If this is low (< 80%), fix chunking and embedding first
# Test 2: Given perfect context, does LLM generate correct answers?
generation_faithfulness = evaluate_generation(questions, perfect_context)
print(f'Generation faithfulness: {generation_faithfulness:.1%}')
# If retrieval is fine but this is low, fix your promptsСоздание эталонного набора данных
Для оценки нужен эталонный набор данных: набор пар «вопрос–ответ», для которых известен правильный ответ и, в идеале, документ и фрагмент, из которых он взят. Для минимального пригодного набора оценки соберите 50–100 вопросов, отражающих реальные запросы пользователей. Ответьте на них вручную или изучив исходные документы. Включите разнообразные типы вопросов: поиск фактов, сравнения, многошаговые рассуждения и вопросы не по теме, на которые система должна отказаться отвечать.
# Golden dataset format
golden_dataset = [
{
'question': 'How many vacation days do employees receive in their first year?',
'answer': '15 days',
'relevant_chunks': ['employee_handbook_p24', 'benefits_summary_p3'],
'source_doc': 'employee_handbook_2025.pdf'
},
{
'question': 'What is the parental leave duration for primary caregivers?',
'answer': '16 weeks fully paid',
'relevant_chunks': ['parental_leave_policy_p1'],
'source_doc': 'parental_leave_policy.pdf'
}
]Создание эталонных наборов данных с помощью LLM
Создавать 100 вопросов вручную утомительно. Ускорьте этот процесс с помощью LLM для генерации данных: передайте каждый фрагмент документа GPT-4o и попросите его создать 3–5 разнообразных вопросов, ответы на которые можно найти в этом фрагменте, а также текст ожидаемого ответа. Вручную проверьте выборку, чтобы выявить проблемы с качеством. Такой подход позволяет быстро масштабироваться до тысяч вопросов, однако некоторые особые случаи, о которых спросили бы только реальные пользователи, могут остаться незамеченными.
def generate_qa_pairs_for_chunk(chunk_text, llm_client):
prompt = (
'Given the following document excerpt, generate 3 diverse questions '
'that can be answered using ONLY this text. '
'For each question, provide the exact answer from the text.\n\n'
f'Text:\n{chunk_text}\n\n'
'Format each as JSON: {"question": ..., "answer": ...}'
)
response = llm_client.chat.completions.create(
model='gpt-4o-mini',
messages=[{'role': 'user', 'content': prompt}]
)
return response.choices[0].message.contentОценка поиска: доля попаданий
Доля попаданий@K — это доля вопросов, для которых хотя бы один релевантный фрагмент присутствует среди первых K результатов поиска. Это самая простая и интуитивно понятная метрика поиска. Доля попаданий@5, равная 85%, означает, что для 85 из 100 вопросов релевантный фрагмент оказался среди 5 первых результатов. Отслеживайте долю попаданий отдельно для разных типов документов, длин запросов и тематических категорий, чтобы понять, где ваш механизм поиска испытывает наибольшие трудности.
def compute_hit_rate(golden_dataset, retriever, top_k=5):
hits = 0
for item in golden_dataset:
results = retriever.retrieve(item['question'], top_k=top_k)
retrieved_ids = {r['id'] for r in results}
relevant_ids = set(item['relevant_chunks'])
if retrieved_ids & relevant_ids: # intersection not empty
hits += 1
hit_rate = hits / len(golden_dataset)
print(f'Hit rate@{top_k}: {hit_rate:.1%} ({hits}/{len(golden_dataset)})')
return hit_rateОценка генерации: достоверность
Достоверность показывает, содержит ли сгенерированный ответ только информацию, которую можно подтвердить в найденном контексте. Недостоверный ответ добавляет факты, которые контекст не подтверждает, — это галлюцинация. Оценивайте достоверность, поручив проверяющей LLM (или человеку-оценщику) сопоставить каждое предложение ответа с контекстом и отметить утверждения, не подтверждённые найденными фрагментами. Для систем, используемых в рабочей среде, целевым показателем является достоверность не ниже 95%.
def evaluate_faithfulness(answer, context, llm_client):
prompt = (
'Given this context and answer, evaluate faithfulness.\n\n'
f'Context: {context}\n\n'
f'Answer: {answer}\n\n'
'For each sentence in the answer, determine if it is '
'supported by the context (FAITHFUL) or not (HALLUCINATED). '
'Return a JSON: {"score": 0.0-1.0, "issues": ["sentence..."]}.'
)
response = llm_client.chat.completions.create(
model='gpt-4o',
messages=[{'role': 'user', 'content': prompt}]
)
return response.choices[0].message.contentОценка генерации: релевантность ответа
Релевантность ответа показывает, действительно ли сгенерированный ответ отвечает на вопрос пользователя. Даже очень достоверный ответ может не попасть в цель, если он отвечает на связанный, но другой вопрос. Измеряйте релевантность отдельно от достоверности. Используйте проверяющую LLM, чтобы оценить по шкале от 1 до 5, насколько ответ непосредственно соответствует заданному вопросу. Низкая релевантность ответа часто указывает на проблему в структуре запроса или на то, что в найденном контексте на самом деле нет ответа.
def evaluate_answer_relevance(question, answer, llm_client):
prompt = (
f'Question: {question}\n\n'
f'Answer: {answer}\n\n'
'Rate how well this answer addresses the question on a 1-5 scale:\n'
'5 = fully answers the question\n'
'3 = partially answers but misses key aspects\n'
'1 = does not address the question at all\n\n'
'Return JSON: {"score": 1-5, "reason": "brief explanation"}'
)
response = llm_client.chat.completions.create(
model='gpt-4o',
messages=[{'role': 'user', 'content': prompt}]
)
return response.choices[0].message.contentОтслеживание метрик во времени
Оценка наиболее полезна, когда вы отслеживаете метрики во времени по мере внесения изменений. Храните результаты оценки в базе данных или электронной таблице с отметками времени и метками версий (например, chunk_size=500, embed=3-small, k=5). Когда вы пробуете новую стратегию разбиения на фрагменты или модель эмбеддингов, проводите ту же оценку и сравнивайте результаты. Это предотвращает регрессии: например, вы можете повысить достоверность, но случайно снизить долю попаданий. Всегда проводите полную оценку перед объединением изменений с рабочей версией.
import json
from datetime import datetime
def save_evaluation_results(metrics, config, output_file='eval_history.jsonl'):
record = {
'timestamp': datetime.utcnow().isoformat(),
'config': config,
'metrics': metrics
}
with open(output_file, 'a') as f:
f.write(json.dumps(record) + '\n')
print(f'Saved eval result: hit_rate={metrics["hit_rate"]:.1%}, '
f'faithfulness={metrics["faithfulness"]:.1%}')Подход к оценке
Помимо конкретных метрик, оценка требует изменения образа мышления: рассматривайте RAG как систему машинного обучения с измеримыми показателями, а не как чат-бота, которого оценивают субъективно, общаясь с ним. Заранее определите критерии успеха (например, доля попаданий@5 > 85%, достоверность > 95%). Сформируйте тестовый набор, который остаётся неизменным и никогда не используется для принятия решений при разработке. Для итераций выделите отдельный набор разработки. Такая дисциплина отличает команды, выпускающие надёжные системы RAG, от команд, выпускающих впечатляющие демонстрации, которые не работают в рабочей среде.
Тестовый набор и набор разработки
Важный принцип машинного обучения, применимый и к оценке RAG, — это разделение на обучающий, рабочий и тестовый наборы. Ваш тестовый набор должен быть полностью неизменным и никогда не использоваться для принятия решений при разработке. Для экспериментов со стратегиями разбиения на фрагменты, изменениями запросов и моделями эмбеддингов используйте отдельный набор разработки. Запускайте проверку на тестовом наборе только тогда, когда считаете изменение готовым для рабочей среды. Такое разделение предотвращает подгонку вашего конвейера RAG под тестовый набор и гарантирует, что итоговые опубликованные метрики отражают настоящую способность к обобщению.
import json
from sklearn.model_selection import train_test_split
def split_golden_dataset(all_questions, test_ratio=0.3, seed=42):
dev_set, test_set = train_test_split(
all_questions,
test_size=test_ratio,
random_state=seed
)
print(f'Dev set: {len(dev_set)} questions')
print(f'Test set: {len(test_set)} questions (FROZEN)')
with open('eval/dev_set.json', 'w') as f:
json.dump(dev_set, f, indent=2)
with open('eval/test_set.json', 'w') as f:
json.dump(test_set, f, indent=2)
return dev_set, test_setБыстрая проверка
Проверьте, насколько хорошо вы усвоили концепции инженерии ИИ из этого урока.
Итоги урока
В этом уроке вы узнали: о двух независимых режимах отказа — поиска и генерации, для которых нужны отдельные метрики; о создании эталонного набора данных из троек «вопрос–ответ–фрагмент» для объективной оценки; о доле попаданий как основной метрике поиска, а также о достоверности и релевантности ответа как основных метриках генерации; и о важности отслеживания метрик во времени для предотвращения регрессий. Далее мы реализуем конкретные метрики поиска, включая MRR и NDCG.
Часто задаваемые вопросы
Урок «Зачем нужна оценка RAG» бесплатный?
Да — полный текст урока «Зачем нужна оценка RAG» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс AI Engineering Academy, подпишись на CoddyKit PRO. Курс AI Engineering Academy содержит 4 уроков всего.
Чему я научусь в уроке «Зачем нужна оценка RAG»?
Поймите два независимых источника сбоев в системах RAG: сбой поиска и сбой генерации, а также узнайте, почему для диагностики каждого из них нужны отдельные метрики. Ты практикуешь AI Engineering Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать AI Engineering Academy?
Предыдущий опыт не требуется. AI Engineering Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.
Сколько времени занимает урок «Зачем нужна оценка RAG»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке AI Engineering Academy?
Да. Каждый урок AI Engineering Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Зачем нужна оценка RAG
- Метрики поиска: доля попаданий, MRR и NDCG
- Метрики генерации: достоверность и релевантность ответа
- Создание автоматизированной системы оценки