Главная / Статьи

Как отладить ситуацию, когда система RAG не возвращает ничего при попытке получения данных.

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

Издатель: REACTAPP.TOP9 мин чтения2016 слов

Источники: **Part II — When RAG Returns Nothing**

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

Поиск может сбоить во многих местах

Пустой результат — это не один конкретный вид сбоя. Кандидат на ответ может исчезнуть на этапах загрузки, генерации векторных представлений, векторного поиска, фильтрации метаданных, установления порогов или ранжирования. Оптимизация проходит быстрее, если проверять каждый этап отдельно и не рассматривать всю структуру RAG как единый «черный ящик».

1. Начните с индексации и генерации векторных представлений

Прежде чем взаимодействовать с механизмом поиска, убедитесь, что в базе знаний действительно содержится то, что вы считаете. Успешная обработка показывает логичную последовательность преобразований: от исходных документов к разобранному тексту, затем к фрагментам, эмбеддингам и сохранённым векторам. Если было сгенерировано 2 000 фрагментов, но в хранилище попали лишь 200 векторов, никакая настройка механизма поиска не поможет.

  • Вручную откройте несколько сохранённых фрагментов. В них должен быть читаемый текст, стабильные идентификаторы, эмбеддинги и любые метаданные, от которых зависят ваши фильтры.
  • Используйте одинаковые модели и размерности эмбеддингов как для документов, так и для запросов пользователей. Замена модели запроса без пересоздания индекса приведёт к потере смысла значений сходства.
  • Оцените также работу парсера. PDF-файлы, сканы, таблицы и HTML-страницы могут превращаться в пустые или повреждённые фрагменты, при этом система всё равно будет сообщать об успешном выполнении задачи.

2. Проверьте пороговые значения, значение оценок и фильтры

Агрессивные пороговые значения оценок часто являются причиной отсутствия результатов. Оценки в формате эмбеддингов не представляют собой проценты уверенности, а полезный диапазон варьируется в зависимости от модели, метрики расстояния, данных и базы векторных данных. Во время отладки выведите топ-10 или топ-20 кандидатов без каких-либо пороговых значений и просмотрите их исходные оценки:

results = vector_store.search(query_embedding, top_k=10)
for r in results:
    print(r.score, r.metadata.get('source'))

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

Фильтры могут удалять хорошие результаты

Фильтрация метаданных крайне важна для систем с несколькими арендаторами, при определении прав доступа, диапазонов продуктов, дат, языков и типов документов; кроме того, это один из самых простых способов получить пустой набор результатов. К типичным причинам относятся сравнение строк с целыми числами, несогласованность регистра, старые записи без метаданных, неверные идентификаторы арендаторов, а также фильтры, каждый из которых сам по себе допустим, но вместе они делают поиск невозможным.

3. Пересмотр переписывания запроса и качества фрагментов

Переписывание запроса может способствовать его поиску, но при этом может быть устранен именно тот термин, который сделал запрос поисковым. Представьте, что кто-то спрашивает, как сбросить настройки X500, в то время как инструмент переписывания преобразует этот вопрос в «восстановление стандартных настроек для серии X». Если руководство должно называться «Сброс настроек X500», то формулировка пользователя, скорее всего, лучше с ним совпадет. Записывайте как исходный, так и переписанный запросы и тестируйте каждый из них. Для точных идентификаторов, кодов ошибок, названий продуктов и параметров API сохраняйте буквальные формулировки, даже если остальная часть запроса нормализована.

Разбиение на части также сопряжено с аналогичными проблемами. Заголовок вроде «Сброс маршрутизатора X500» не должен отделяться от инструкций, расположенных ниже него. Необходимо разбивать документ в соответствии с его структурой, чтобы заголовок, его абзацы, пункты списка и окружающий контекст оставались целыми. Оптимальный размер части зависит от объема работы; разумный начальный диапазон — от 500 до 1 000 токенов с умеренным перекрытием, после чего проводится оценка на реальных запросах.

Что измерять: возьмите небольшой набор меткированных запросов и запишите, появляется ли ожидаемый источник среди результатов топ-k. Такой тест, ориентированный на показатель воспроизводимости, лучше, чем выбор размеров частей или пороговых значений на основе интуиции.

4. Сочетание лексического и векторного поиска

Векторный поиск проявляет себя наилучшим образом, когда пользователь и документ выражают одну и ту же идею по-разному. Лексический поиск, такой как BM25, эффективен, когда важны точные токены. Поскольку сложные запросы редко бывают одного типа, в производственных системах часто используются оба метода. BM25 обычно преобладает в случаях с кодами ошибок (например, ERR-XK-1042), артикулами, номерами счетов-фактур, названиями продуктов, названиями классов, ключами конфигурации и именами параметров API. Векторный поиск позволяет находить близкие по смыслу варианты, в то время как BM25 гарантирует, что точные лексические данные не будут упущены. Типичная схема работы заключается сначала в получении широкого набора кандидатов, а затем в применении более точного алгоритма ранжирования для повышения точности результатов.

5. Сначала получить широкий набор результатов, затем переранжировать

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

Часто используется подход, при котором собираются от 20 до 50 кандидатов с помощью векторного и лексического поиска, они объединяются и удаляются дубликаты, после чего происходит переусловливание для отбора лучших 5–10 результатов. Кросс-кодеры эффективны и предназначены для оценки релевантности, тогда как механизм переусловливания на основе больших языковых моделей может выполнять более сложные инструкции, но обычно работает медленнее и стоит дороже.

Избегайте преждевременного отсеивания кандидатов. Если жесткий порог оценки опережает механизм переусловливания, результат, который действительно мог бы помочь, может так и не попасть в поле зрения более совершенной модели оценки релевантности. Часто более эффективным оказывается первичный просмотр с последующим переусловливанием, чем полная передача ответственности за ранжирование на векторную оценку.

Слияние результатов и удаление дубликатов

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

6. Расширение запроса с запланированным резервным вариантом

Люди и документы редко используют один и тот же словарный запас. Тот, кто пишет «Я не могу войти», может нуждаться в страницах с названиями «Ошибка аутентификации», «Устранение проблем с входом» или «Доступ к учётной записи». Система расширения генерирует несколько альтернативных запросов, выполняет их все, затем удаляет дубликаты и переустанавливает рейтинги результатов. Необходимо контролировать этот процесс: не трогать именованные сущности и точные идентификаторы, не создавать большое количество почти идентичных запросов и ограничивать количество попыток, чтобы один сложный вопрос не запускал дорогостоящий цикл.

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

docs = retrieve(query)
if not useful(docs): docs = retrieve(expand(query), hybrid=True)
if not useful(docs): return ask_for_clarification_or_no_answer()

Пустой результат против некорректного поиска

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

7. Более устойчивая архитектура производства

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

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

Уровень доверия определяет следующий шаг

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

Не вовлекайте безопасность в цикл повторных попыток

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

8. Сделать процесс поиска прозрачным

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

log({
  'query': query, 'rewritten': rewritten_query, 'filters': filters,
  'candidate_count': len(raw_results), 'scores': scores,
  'selected_chunk_ids': selected_ids, 'fallback': fallback_stage
})

Разумный порядок отладки

Когда возникает проблема с пустыми результатами поиска, следует начинать с самых простых и надежных проверок, постепенно переходя к более сложным и субъективным методам анализа. Это помогает командам не настраивать параметры запросов или векторные представления, когда на самом деле проблема заключается в отсутствии индекса или некорректном фильтре.

  1. Сначала проверка процесса загрузки данных: учитываются количество документов, обработанный текст, количество чанков, сохраненные векторы, а также несколько записей, которые, как известно, должны существовать.
  2. Затем — прямой поиск: отправляется исходный запрос без всех необязательных фильтров и пороговых значений, после чего считаются лучшие результаты и соответствующие им оценки.
  3. Постепенно возвращаются фильтры, что позволяет определить именно тот фильтр, который приводит к пустым результатам.
  4. Проверяется семантика оценок: лучше ли более высокие или более низкие значения, применяется ли какая-либо нормализация?
  5. Сравниваются исходный и измененный запросы, сохраняя точные идентификаторы, чтобы выяснить, способствует ли изменение запроса улучшению или ухудшению качества поиска.
  6. Оцените гибридный метод поиска и переранжирования на основе набора запросов с метками, проверив, появляются ли ожидаемые источники в списке топ-k и топ-n после переранжирования.
  7. Протестируйте режим резервного варианта, сгенерировав пустые или слабые результаты, чтобы убедиться, что система дает пояснения или отклоняет запрос, не выдумывая информацию.

Что измерять

Одного качества ответа недостаточно для оценки процесса поиска. Отслеживайте показатель воспроизводимости@k (попал ли ожидаемый источник в список кандидатов?), точность после переранжирования, долю пустых результатов, долю запросов, обработанных в режиме резервного варианта, задержку и долю запросов, требующих дополнительной информации или уточнений. Разделяйте эти показатели по типу запросов — например, семантические вопросы против точных идентификаторов, — а также по арендатору, языку и коллекции документов, поскольку общие средние значения могут скрыть проблемы в отдельных группах.

Не вините сначала большие языковые модели

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

Связанные материалы

  • RAG при обработке десяти миллионов документов: конвейеры поиска, маршрутизаторы, агенты и метрики оценки — Конвейер поиска с временем обработки запроса менее 200 мс, включающий фильтры SQL, гибридный поиск и переранжирование, а также маршрутизацию запросов, оркестрацию агентов, метрики оценки и скрипт потока Qdrant.
  • Практические рекомендации: улучшение производительности RAG — Часть 2: HyDE (гипотетический документ) — Пошаговое руководство по применению практических рекомендаций: улучшение производительности RAG — Часть 2: HyDE (гипотетический документ), включающее шаблоны контрактов, проверок и блоки кода для команд, использующих эту модель.