
Качество эмбеддингов для RAG нельзя надёжно выбрать по одному рейтингу или демо. Модель, которая хорошо находит похожие предложения в общем бенчмарке, может пропускать нужные фрагменты в документации вашей компании: отличаются терминология, язык запросов и структура источников. Практичный способ сравнения — собрать небольшой набор запросов с размеченными релевантными фрагментами и проверить, что именно извлекает ваш индекс.
Ниже — воспроизводимый тест для проверки эмбеддингов в поисковом этапе RAG. Он помогает отделить проблемы векторного поиска от ошибок генерации и оценить, стоит ли менять модель, настройки индекса или разбиение документов.
Что именно измерять в тесте эмбеддингов для RAG
Эмбеддинги переводят запросы и фрагменты документов в векторы. Поиск сравнивает векторы и возвращает ближайшие фрагменты. Но «близость» не равна полезности: нужный ответ может быть в документе, однако не попасть в первые результаты.
Для первоначальной проверки достаточно двух метрик:
- Recall@k — доля запросов, для которых среди первых *k* результатов нашёлся хотя бы один релевантный фрагмент. Если для запроса размечено несколько подходящих фрагментов, можно считать долю найденных из них.
- MRR (Mean Reciprocal Rank) — среднее обратное место первого релевантного результата. Если он первый, вклад равен 1; если третий — 1/3. Метрика показывает, насколько высоко поиск ставит полезный материал.
Выбор зависит от сценария. Если генератор получает пять фрагментов, полезно оценивать Recall@5: нужный материал должен оказаться в доступном ему контексте. Если в контекст передаётся один или два результата, важнее раннее появление ответа, и MRR покажет, насколько часто он оказывается наверху.
Не смешивайте качество поиска с качеством итогового ответа. На первом этапе оценивайте только найденные фрагменты. Позже можно проверить, использует ли генератор контекст корректно; метрики контекстной точности и полноты в Ragas предназначены для отдельной оценки RAG-пайплайна.
Соберите проверочный набор из реальных вопросов
Начните с запросов, которые действительно задают пользователи или сотрудники. Подойдут обращения в поддержку, поисковые запросы по базе знаний и вопросы из документации. Уберите персональные данные и секреты перед использованием в тестах.
Для каждого вопроса укажите один или несколько фрагментов, которые действительно содержат ответ. Размечайте именно конкретные индексируемые фрагменты, а не только названия документов: один большой документ может включать десятки несвязанных тем.
Пример разметки:
json
[
{
«query»: «Каков срок хранения резервных копий?»,
«relevant_ids»: [«backup-policy-07»]
},
{
«query»: «Что делать, если истёк токен доступа?»,
«relevant_ids»: [«auth-guide-12», «api-errors-03»]
}
]
Это иллюстративный формат, а не готовая разметка конкретного корпуса. В реальном наборе сохраните идентификаторы тех чанков, которые индексируются вашим приложением.
Проверьте, что запросы не дублируют один и тот же шаблон. Добавьте разные формулировки: точное название функции, разговорный вопрос, аббревиатуру, опечатку, запрос по коду ошибки. Для русскоязычной базы отдельно включите англоязычные имена параметров и смешанные запросы, если ими пользуются читатели.
Зафиксируйте корпус и параметры поиска
Сравнение моделей имеет смысл только при одинаковых условиях. Сохраните версию корпуса, правила очистки, размер чанка и перекрытие, метаданные и настройки векторной базы. Если менять эти параметры одновременно с моделью, будет трудно понять причину результата.
Для каждого кандидата зафиксируйте:
модель и версию;
способ формирования эмбеддинга запроса и документа;
3. метрику расстояния и настройки индекса;
4. число результатов *k*;
5. дату и версию тестового корпуса.
Некоторые модели используют разные инструкции для запросов и документов. Следуйте документации выбранной модели: если пропустить рекомендованный префикс или режим, тест будет сравнивать не штатные варианты, а некорректные конфигурации. В документации OpenAI, например, указаны ограничения и рекомендации по использованию embedding-моделей; у Sentence Transformers есть отдельные рекомендации по семантическому поиску и кодированию запросов с учётом архитектуры модели.
Для первого прохода используйте точный поиск по векторам, если он доступен. Приближённый индекс может возвращать не ближайших соседей и тем самым смешивать ошибку поиска с особенностями ANN-настроек. После оценки самих эмбеддингов отдельно измерьте влияние производственного индекса.
Посчитайте Recall@k и MRR
Следующий пример показывает расчёт метрик для результатов поиска. Предполагается, что для каждого запроса есть список идентификаторов релевантных фрагментов, а поисковая система возвращает упорядоченный список найденных ID.
python
def recall_at_k(ranked_ids, relevant_ids, k):
relevant = set(relevant_ids)
if not relevant:
return None
found = set(ranked_ids[:k]) & relevant
return len(found) / len(relevant)
def reciprocal_rank(ranked_ids, relevant_ids):
relevant = set(relevant_ids)
for rank, chunk_id in enumerate(ranked_ids, start=1):
if chunk_id in relevant:
return 1 / rank
return 0
def evaluate(cases, search, k=5):
recalls, reciprocal_ranks = [], []
for case in cases:
ranked_ids = search(case[«query»], k=k)
recall = recall_at_k(
ranked_ids, case[«relevant_ids»], k
)
if recall is not None:
recalls.append(recall)
reciprocal_ranks.append(
reciprocal_rank(ranked_ids, case[«relevant_ids»])
)
return {
f»Recall@{k}»: sum(recalls) / len(recalls) if recalls else 0,
«MRR»: sum(reciprocal_ranks) / len(reciprocal_ranks)
if reciprocal_ranks else 0
}
Перед запуском проверьте, как ваша система трактует дубликаты и фильтры по метаданным. Если фильтр по продукту или языку включён в приложении, он должен действовать и во время оценки. Иначе тест будет измерять не ту конфигурацию, которую увидит пользователь.
Не трактуйте итоговые числа как универсальный порог качества. Recall@5 в 0,8 может быть достаточным для одного сценария и плохим для другого. Сравнивайте кандидатов на одних и тех же запросах, а ошибки просматривайте вручную.
Разберите промахи, а не только среднее значение
Средняя метрика скрывает важные провалы. Для каждого запроса сохраните первые результаты, их ранги и релевантные ID. Затем разделите ошибки на несколько типов:
- Нужный фрагмент не найден вообще. Возможны слабое соответствие эмбеддингов, потеря текста при индексации или неверная разметка.
- Он найден, но слишком низко. Проверьте ранжирование, соседние чанки и наличие близких по смыслу отвлекающих фрагментов.
- Найден правильный документ, но не тот чанк. Это часто указывает на неподходящий размер разбиения или на то, что ответ разнесён между соседними фрагментами.
- Запрос содержит термин, отсутствующий в корпусе. Векторная близость не создаст отсутствующую информацию; проверьте полноту источников и поведение системы при отсутствии ответа.
Публикация BEIR сравнивает системы поиска на разных задачах и корпусах и показывает, почему результат одного бенчмарка нельзя автоматически переносить на другой домен. Используйте внешние наборы для предварительного отбора, но финальный выбор делайте на собственных запросах и документах.
Если запросов мало, приводите не только среднее, но и число тестовых примеров, а также перечень неудачных случаев. Разница в несколько процентных пунктов на маленькой выборке может быть следствием одного-двух вопросов, а не устойчивого преимущества модели.
Проверьте влияние разбиения и гибридного поиска
Сравнение эмбеддингов при одном варианте чанков помогает изолировать модель, но само разбиение тоже влияет на результат. Короткие чанки могут терять контекст; длинные — смешивать несколько тем и занимать место в окне модели. Проведите отдельный эксперимент: изменяйте размер чанка или перекрытие по одному параметру, не меняя остальное.
Затем сравните чистый векторный поиск с гибридным, если ваша система сочетает векторный поиск с полнотекстовым. Это особенно полезно для точных идентификаторов, кодов ошибок и редких названий: лексический поиск может находить совпадение, которое семантическая близость ранжирует ниже. Однако улучшение гибридного поиска не доказывает, что эмбеддинги стали лучше — это эффект другого компонента.
Для честного сравнения запишите результаты по отдельным срезам: обычные вопросы, аббревиатуры, ошибки и запросы на двух языках. Общий показатель может вырасти, хотя одна важная группа запросов стала обрабатываться хуже.
Решите, когда пересчитывать индекс
Смена embedding-модели обычно требует пересчитать векторы документов той же моделью, которой кодируются запросы. Векторы из разных моделей нельзя считать взаимозаменяемыми только потому, что у них совпадает размерность. До миграции уточните формат и совместимость в документации провайдера или библиотеки.
Перед переключением подготовьте повторный прогон на неизменном наборе запросов и зафиксируйте:
- Recall@k и MRR в текущей конфигурации;
- те же метрики для новой модели;
- промахи по категориям запросов;
- время построения индекса, стоимость вычисления и задержку поиска;
- требования к размерности векторов и настройкам хранилища.
Если новая модель выигрывает по среднему, но ухудшает поиск критичных инструкций, решение требует отдельного анализа. Для чувствительных сценариев добавьте тесты на запросы, где пропуск нужного документа имеет высокую цену, и проверяйте их отдельно от общего набора.
Что проверить перед внедрением
Надёжный тест эмбеддингов — это не один показатель, а зафиксированная процедура сравнения. Начните с небольшого набора реальных запросов, размеченных конкретными фрагментами, и сохраните ранжированные результаты. Считайте Recall@k и MRR, затем вручную разберите промахи.
Перед заменой модели проверьте инструкции кодирования, одинаковость корпуса и настроек, поведение на редких терминах и результат при производственном разбиении. Если тестовая выборка мала или содержит только типовые запросы, выводы будут ограничены именно этим набором: расширяйте его по мере появления новых вопросов, а не считайте текущую оценку гарантией качества для всех пользователей.










