ЯдроКодаподготовка к экзаменам
Научная библиотека

Загружаем научный разбор

Подготавливаем текст, источники и редакционные примечания без изменения разметки страницы.

Каталог статейМатериал и источники

RAG: как отделить ошибку поиска от ошибки языковой модели

Автор: · Обновлено

Исследование RAG и собственный мини-корпус на Python: поиск доказательств, проверка ответа, обновление индекса и границы достоверности.

Представим помощника для учебного сайта. Пользователь спрашивает, можно ли пересдать контрольную после окончания курса. Модель уверенно отвечает «да», хотя действующие правила разрешают пересдачу только до закрытия группы. Ошибка возникает не из-за грамматики: системе недостаёт актуального основания для ответа. Даже большая модель не обязана помнить внутренние правила, которые вчера изменил администратор.

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

Что исследовала исходная работа

В статье Lewis и соавторов, NeurIPS 2020, объединены параметры генеративной модели и внешний плотный индекс Wikipedia. Авторы сравнили вариант, использующий найденные фрагменты для всей последовательности, с вариантом, который может выбирать разные фрагменты для отдельных токенов. Это конкретные обучаемые архитектуры и эксперименты на выбранных NLP-задачах; современное бытовое слово RAG охватывает и другие конвейеры. Первичная публикация.

Следовательно, добавление обычного текстового поиска к чат-боту не воспроизводит эксперимент авторов. Однако оно позволяет отдельно изучить важную инженерную границу: найден ли вообще документ, из которого можно получить правильный ответ? Ниже мы исследуем именно эту границу, без обучения нейросети и без внешнего API.

Мини-корпус и проверяемое ожидание

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

import re

documents = {
    "retake-v2": "пересдача контрольной доступна до закрытия группы",
    "archive": "после закрытия группы доступен архив материалов",
    "payment": "оплата курса подтверждается письмом",
}

def words(text):
    return set(re.findall(r"[а-яё]+", text.lower()))

def retrieve(query, limit=2):
    scored = [(len(words(query) & words(text)), key)
              for key, text in documents.items()]
    return [key for score, key in sorted(scored, reverse=True)[:limit]
            if score > 0]

hits = retrieve("пересдача после закрытия группы")
assert "retake-v2" in hits
assert "retake-v2" not in retrieve("можно заново сдать экзамен")
print(hits)

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

Теперь предположим, что генератор получил обе первые карточки и ответил: «После закрытия группы пересдача остаётся доступной в архиве». Он склеил разные утверждения. Поиск прошёл проверку, но ответ ей не соответствует. Ссылка на архив рядом с ответом не исправляет ложный вывод: цитата должна поддерживать конкретное утверждение, а не просто содержать похожие слова.

Как построить измерение

Для каждого вопроса заведите идентификатор, ожидаемые документы и короткое требование к ответу. Например: назвать ограничение пересдачи, не обещать доступ после закрытия. Считайте отдельно долю вопросов, для которых нужный документ попал в первые k результатов, и долю ответов, правильно отражающих правило при уже правильном контексте. Второй тест можно запускать с контекстом, выбранным вручную.

Такой разрез даёт конкретные действия. Если нужная карточка теряется, исследуйте разбиение текста, словарь и ранжирование. Если карточка найдена, а условие пропущено, исследуйте сборку контекста и проверку утверждений. Если правила противоречат друг другу, исправляйте корпус и версионирование. Увеличение числа фрагментов без диагностики может лишь добавить противоречий и увеличить стоимость запроса.

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

Границы вывода и применение

Если ответ генерируется вероятностно, сохраняйте несколько повторов одного контрольного вопроса. Один удачный ответ не показывает устойчивость результата. Полезно отдельно сравнивать короткую прямую формулировку и вопрос с отвлекающими деталями, сохраняя одинаковые ожидаемые основания. Так становится видно, исправили ли вы общий механизм или случайно подобрали удобный запрос. Эти проверки относятся к вашему помощнику; их нельзя приписывать исходной исследовательской работе.

Наш пример проверяет свойства словарного поиска, а не качество модели из исследования. Он не измеряет задержку большого индекса, качество эмбеддингов или вероятность галлюцинаций. Реализация семейства исходных моделей описана в документации Transformers, но её наличие не заменяет оценку собственного продукта.

На практике храните вместе с фрагментом версию документа, дату обновления и права доступа. После изменения правила переиндексируйте его и повторяйте контрольные вопросы. Сохраняйте в диагностике идентификаторы найденных фрагментов, чтобы различать устаревшие данные и ошибку ответа. Для помощника разработчика такой подход делает проверяемыми ответы по API, регламентам и документации проекта: каждое существенное утверждение получает конкретное основание, которое можно открыть и оспорить.

Источники

Формат и права

Формат
Авторский разбор

Атрибуция

Самостоятельный русскоязычный разбор ЯдроКода. Описания первоисточников отделены от авторских учебных примеров и инженерных выводов. Материал не является переводом или перепечаткой.

Код, данные и иллюстрации

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