English translation is not available yet. Showing Russian content.
Как вы тестируете RAG-систему на новых документах без реальных пользователей?
Краткий тезис
Тестирование RAG-системы на новых документах без реальных пользователей строится на трёх столпах: генерация синтетического датасета (вопросы + эталонные ответы), автоматическая оценка метриками (RAGAS) и непрерывный пайплайн (CI/CD + shadow-режим). Такой подход даёт до 80% уверенности в качестве до выкатки на продакшен, а оставшиеся 20% снимаются A/B-тестированием и мониторингом на реальных данных.
1. Термин: Тестирование RAG без реальных пользователей (offline testing)
Offline-тестирование — это процесс оценки качества RAG-системы на фиксированном наборе документов и синтетических запросов, без участия живых пользователей. Оно необходимо, когда:
- Документы добавляются в базу знаний в первый раз
- Изменяются эмбеддинги, чанкинг, промпты или модель генерации
- Нужно быстро проверить регресс перед релизом
Без пользователей мы не можем опираться на онлайн-метрики (CTR, время ответа, отзывы), поэтому используем синтетические данные и автоматические метрики.
2. Синтетический датасет: генерация вопросов по документам
2.1. Зачем это нужно
- Реальные пользовательские запросы недоступны на этапе добавления новых документов
- Нужен test set, который покрывает все ключевые факты из документов
2.2. Метод: вопросно-ответная генерация через LLM
Берём фрагменты (чанки) документа и просим LLM сгенерировать вопросы, на которые этот чанк отвечает.
Пример реализации на Python (с использованием LangChain):
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import PydanticOutputParser
from pydantic import BaseModel, Field
from typing import List
class QAPair(BaseModel):
question: str = Field(description="Вопрос по тексту")
answer: str = Field(description="Ответ, основанный на тексте")
template = """Ты — ассистент для создания синтетического датасета.
На основе следующего текста придумай {num_questions} вопросов,
на которые можно ответить, используя только этот текст.
Вопросы должны быть разнообразными: фактические, уточняющие, сравнительные.
Текст:
{chunk}
Формат ответа: JSON список {{"question": ..., "answer": ...}}"""
parser = PydanticOutputParser(pydantic_object=List[QAPair])
prompt = ChatPromptTemplate.from_template(template)
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0.7)
chain = prompt | llm | parser
chunk = "Глубокое обучение — это подмножество машинного обучения, которое использует нейронные сети с тремя и более слоями."
qa_pairs = chain.invoke({"chunk": chunk, "num_questions": 3})
print(qa_pairs)
Важные нюансы
- Не генерить вопросы, выходящие за пределы текста (можно задать констрейнт в промпте)
- Перемешать вопросы из разных чанков, чтобы симулировать реальные запросы
- Оценить качество синтетических вопросов: они должны быть осмысленными, разнообразными и покрывать разные уровни сложности
2.3. Поиск эталонных ответов
Для каждого синтетического вопроса нужно указать ground truth (правильный ответ). Лучший подход:
- Ответ берётся из того же чанка, который использовался для генерации вопроса (автоматически)
- Или LLM дополнительно проверяет, что ответ действительно содержится в документе (самопроверка)
- Для оценки retrieval достаточно знать, какие чанки релевантны (gold standard)
Итог получаем датасет {question, ground_truth_answer, relevant_chunks}.
3. Автоматическая оценка метриками (RAGAS)
RAGAS (Retrieval Augmented Generation Assessment) — фреймворк для автоматической оценки RAG без участия человека. Основные метрики:
| Метрика | Что измеряет | Формула / подход |
|---|---|---|
| Faithfulness (правдивость) | Все ли утверждения ответа подтверждаются документами | Доля утверждений, которые можно вывести из контекста |
| Answer Relevance (релевантность ответа) | Насколько ответ соответствует вопросу | Косинусная схожесть эмбеддинга вопроса и сгенерированного ответа |
| Context Precision (точность контекста) | Насколько все релевантные чанки находятся в топе | Средняя точность по рангам |
| Context Recall (полнота контекста) | Сколько релевантных чанков было найдено | Доля найденных релевантных чанков среди всех релевантных |
Пример вычисления Faithfulness с помощью RAGAS (код):
from ragas import evaluate
from datasets import Dataset
from ragas.metrics import faithfulness, answer_relevancy
# Подготовка данных
dataset = Dataset.from_dict({
"question": ["Что такое глубокое обучение?"],
"answer": ["Глубокое обучение использует нейронные сети с тремя и более слоями."],
"contexts": [["Глубокое обучение — это подмножество машинного обучения, которое использует нейронные сети с тремя и более слоями."]],
"ground_truth": ["Глубокое обучение использует нейронные сети с тремя и более слоями."]
})
# Оценка
result = evaluate(dataset, metrics=[faithfulness, answer_relevancy])
print(result.to_pandas())
Трактовка результатов
- Faithfulness < 0.7 → модель галлюцинирует или не использует контекст
- Answer Relevance < 0.8 → ответ не соответствует вопросу (проблемы с промптом или генерацией)
- Context Recall < 0.9 → retrieval пропускает важные документы (плохая индексация или эмбеддинги)
4. Benchmark и фиксация baseline
Перед добавлением новых документов необходимо:
- Зафиксировать текущий baseline на старом наборе документов (метрики RAGAS)
- После обновления базы прогнать тот же синтетический датасет
- Сравнить метрики: если Faithfulness или Context Recall упали больше чем на 5% — откатить изменение или доработать
Пример отчёта
| Метрика | До обновления | После обновления | Дельта | Вердикт |
|---|---|---|---|---|
| Faithfulness | 0.91 | 0.88 | -0.03 | OK (допустимо) |
| Answer Relevance | 0.85 | 0.84 | -0.01 | OK |
| Context Recall | 0.94 | 0.78 | -0.16 | 🔴 ПРОБЛЕМА |
5. CI/CD пайплайн при добавлении документа
Чтобы тестирование было автоматическим и повторяемым, его встраивают в CI/CD (Continuous Integration / Continuous Deployment). Примерный flow:
- Триггер пуш в репозиторий с новыми документами (или загрузка через API)
- Этап 1 Генерация синтетического датасета по новым документам (3–5 вопросов на чанк)
- Этап 2 Прогон evaluation pipeline на старом датасете + новом датасете
- Этап 3 Сравнение метрик с заданными порогами (например, Faithfulness > 0.85, Context Recall > 0.9)
- Решение если все метрики в порядке → автоматический деплой новой версии RAG в staging; иначе → прервать пайплайн и уведомить команду
Инструменты GitHub Actions + RAGAS + Python скрипты.
6. Shadow-режим (сравнение на проде без влияния на пользователей)
Shadow mode — это когда новая версия RAG (с новыми документами) работает параллельно с текущей продакшен-версией, но её ответы не показываются пользователям. При каждом запросе:
- Вызываются обе версии (старая и новая)
- Ответы новой версии логируются вместе с контекстом и метриками (faithfulness, latency)
- Периодически (раз в день) проводится A/B сравнение синтетических метрик между старой и новой версией
Это даёт реалистичную оценку на реальных пользовательских запросах, но без риска для пользовательского опыта. По сути, shadow-режим — это bridge между offline-тестами и полноценным A/B.
7. Ограничения и как повысить уверенность до 100%
Синтетические вопросы + RAGAS дают ~80% уверенности. Основные слабые места:
| Ограничение | Решение |
|---|---|
| Синтетические вопросы могут не совпадать с реальными паттернами | Добавить датасет из реальных логов поиска (если есть хотя бы небольшой поток) |
| RAGAS-метрики не идеальны (например, Faithfulness может пропускать тонкие галлюцинации) | Провести ручную валидацию на 50–100 случайных примерах |
| Метрики агрегируются по всему датасету — можно пропустить выбросы | Ввести мониторинг на уровне отдельных запросов и алерты при падении Confidence Score |
Итог комбинируем синтетический датасет → RAGAS benchmark → shadow mode → ручная выборка. Это даёт уверенность, близкую к 95%.
8. Пет-проект для закрепления
Задача Разработать пайплайн для тестирования RAG-системы при добавлении нового PDF-документа о медицинских препаратах.
Инструменты
- Python + LangChain + OpenAI
- RAGAS для оценки
- Streamlit для демонстрации отчёта
- GitHub Actions для CI/CD
Шаги:
- Разбить PDF на чанки (RecursiveCharacterTextSplitter)
- Загрузить чанки в векторную БД (Chroma)
- Сгенерировать синтетический датасет (30 вопросов по всему документу)
- Оценить baseline на текущей базе (без нового документа)
- Добавить новый документ в БД
- Переоценить на том же датасете
- Вывести сравнительный отчёт (таблица метрик)
- Если Context Recall упал > 10% → откатить изменение
Ожидаемый результат Streamlit-приложение, которое при загрузке нового PDF автоматически прогоняет evaluation и показывает зелёный/красный сигнал для деплоя.
9. Связь с другими вопросами
| Вопрос | Тема |
|---|---|
| 5 | Как оценивать качество retrieval в RAG |
| 9 | Как обновлять документы в существующей RAG-системе |
| 10 | Что такое Self-RAG и когда его использовать |
| 15 | Как вы отслеживаете метрики RAG в продакшене |
| 20 | Какие метрики качества генерации LLM вы знаете |
| 30 | Как вы детектируете галлюцинации в RAG |
10. Навигация
- Предыдущий: 70
- Следующий: 72
- Индекс: 00. Индекс разборов
Навигация
- Предыдущий: 70
- Следующий: 72
- Индекс: 00. Индекс разборов