Почему RAG терпит неудачу с реальными документами: разбиение на чанки, гибридный поиск, переранжирование и методы оценки.
Почему RAG терпит неудачу с реальными документами и способы это исправить: двухэтапная архитектура, выбор способов разбиения на части, гибридный поиск, переранжирование и оценка процесса поиска в отдельности.
Источники: Production-Ready RAG Architecture: Core Patterns Explained
Почему демо-версии не работают с реальными данными
Учебные материалы по RAG обычно тестируются на аккуратно оформленных PDF-файлах или данных из Википедии, что является неправильным условием тестирования. Если применить ту же самую схему обработки к реальным корпоративным материалам с неравномерным форматированием, заявками на поддержку и обширными внутренними вики-сайтами, ответы начинают приходить неполными, выдуманными или явно неверными. Почти все сбои в реальных условиях объясняются двумя основными причинами.
- RAG прежде всего является системой поиска информации, а лишь во вторую очередь — системой генерации текста. Если при поиске находится неверный контекст, у модели практически нет шансов дать правильный ответ, какой бы сильной она ни была.
- Общее качество системы определяется самым слабым звеном, а не средним показателем. Даже мощная модель вкладки не сможет исправить ситуацию, когда инструмент разбиения текста разделяет предложение на две части.
Две фазы
Каждая система RAG делится на фазу оффлайн-индексации и фазу онлайн-запросов:
Indexing (offline): documents → chunks → embeddings → vector store
Query (online): question → embedding → retrieval → context assembly → LLM
Системы производства добавляют к этому ядру механизмы кэширования, переранжирования, ограничений, мониторинга и логику резервного варианта, но он по-прежнему остается основой для всего остального, и никакие инструменты не могут исправить слабую основу.
Разбиение на фрагменты приносит наибольшую пользу
Большинство систем терпят неудачу при разбиении на фрагменты, и эта проблема остается незаметной до тех пор, пока вы не начнёте отлаживать неверный результат на следующих этапах. Это важно, потому что модели встраивания работают наилучшим образом с связными участками текста, окна контекста ограничены, слишком крупные фрагменты создают шум, а слишком маленькие приводят к потере сопутствующих фактов, необходимых для ответа.
Разбиение на фрагменты фиксированного размера осуществляется с интервалом каждые N токенов при 10–20 процентах перекрытия. Этот метод прост и предсказуем, но не учитывает границы предложений и абзацев, поэтому может разделить определение, не заметив этого. Это распространённая отправная точка, но редко является лучшим решением.
Рекурсивное или иерархическое разбиение сначала ищет естественные разделители — двойные переносы строк, затем одиночные переносы, затем предложения, затем слова, и обращается к альтернативным методам лишь тогда, когда секция по-прежнему слишком велика. Сегодня большинство фреймворков используют именно этот подход, и он явно превосходит метод с фиксированным размером блоков.
Разбиение с учетом структуры следует собственной структуре документа: заголовкам, разделам, блокам кода и таблицам. Для технической документации и Markdown этот метод часто оказывается наиболее эффективным. Сохраняйте связи между родительскими и дочерними элементами, чтобы можно было сначала работать с небольшим точным блоком, а затем расширяться до всего родительского раздела при необходимости дополнительного контекста.
Семантическое разбиение использует модель вживления или большую языковую модель для определения мест, где действительно меняется тема, и разделяет документ именно там. Оно обеспечивает наиболее целостные блоки, но с реальной дополнительной стоимостью, поскольку каждое решение о границе требует вызова модели; поэтому его обычно применяют в корпусах данных, где качество поиска оправдывает такие затраты.
Разумные стандартные настройки:
- Начните с рекурсивного или учитывающего структуру разделения и избегайте метода фиксированного размера.
- Стремитесь к кускам длиной примерно от 300 до 800 токенов, затем настраивайте параметры на основе собственного набора данных для оценки, а не на основе цифр с блога.
- Храните метаданные для каждого куска, такие как исходный документ, название раздела и номер страницы или абзаца. Это необходимо для фильтрации и формирования цитат позже.
- Соберите небольшой набор реальных вопросов и проверьте, что именно извлекается, прежде чем применять модель эмбеддингов. Некорректное разделение данных тихо портит результаты, поэтому исправьте его перед настройкой любых последующих элементов.
Эмбеддинги и хранилища векторов
Модели эмбеддингов помещают текст в высокомерное пространство, где семантическая близость превращается в геометрическую близость, которая обычно оценивается с помощью косинусного сходства или скалярного произведения. Модель действительно важна, но качество данных и их разбиение на фрагменты обычно имеют большее значение, чем выбор конкретной модели в процессе обработки. К основным категориям относятся универсальные открытые модели, специализированные эмбеддинги для юридического, медицинского или кодового текста, а также проприетарные API. Выбирайте модель исходя из словарного запаса вашей области, а не только по рейтингу на топ-листах.
Настоящая задача хранилища векторов — быстрый приближенный поиск ближайшего соседа, поскольку точное сравнение методом перебора работоспособно только для небольших наборов данных. Большинство хранилищ используют индексы на основе графов, такие как HNSW, или индексы на основе кластеров, такие как IVF, что позволяет избежать сравнения запроса со всеми векторами. Взамен возникает небольшая, настраиваемая вероятность упуска настоящего ближайшего соседа, но время обработки запроса остается сублинейным. Обычно это настраивается позже, но знание о его существовании помогает понять, почему не был найден очевидно подходящий результат.
При выборе хранилища стоит узнать, фильтрует ли оно по метаданным, поддерживает ли оно встроенный гибридный поиск векторов и ключевых слов (BM25), насколько легко им пользоваться локально по сравнению с версией с управлением, а также как выглядят функции сохранения данных, репликации и масштабирования при вашем объеме данных. К распространенным вариантам относятся Qdrant, Weaviate, Pinecone, Chroma, pgvector и OpenSearch k-NN.
В начале бренд магазина имеет меньшее значение, чем четыре других фактора: аккуратные данные, надежное разделение информации на блоки, корректные метаданные и возможность сочетания поиска по векторам и ключевым словам. Гибридный поиск используется практически во всех серьезных реализациях, поскольку чистый поиск по векторам продолжает упускать такие литеральные элементы, как коды ошибок, SKU и идентификаторы продуктов, которые с легкостью находятся с помощью поиска по ключевым словам. Сочетание плотных и разреженных оценок обычно контролируется одним весом, поэтому один запрос может ориентироваться на смысл или на точные термины в зависимости от сценария использования. Концептуальная структура гибридного поиска выглядит примерно так, хотя точный API отличается в разных магазинах:
# Conceptual shape of a hybrid query — exact API varies by vector store
results = vector_store.hybrid_search(
query=user_question,
alpha=0.5, # weight between dense (1.0) and keyword (0.0) search
filters={"doc_type": "runbook", "product": "checkout-service"},
top_k=25,
)
Что за пределами схожести top-k
Выбор k наиболее близких фрагментов — это лишь начало процесса поиска, а не его конец. Реальные задачи продолжают выявлять те же проблемы: ближайший фрагмент не всегда является наиболее полезным, факты ответа распределены между несколькими фрагментами, модели уделяют слишком мало внимания информации, находящейся в середине длинного контекста, даже если она там присутствует (эффект «потери в середине»), а модель вкладчиков может не понимать словарный состав вашей области.
Техники, которые стоит добавить, примерно в порядке отдачи от усилий:
- Переоценка. С помощью дешевого векторного поиска собирается большой набор кандидатов — например, топ-20 до 50, а иногда и 100 — затем их оценивают с использованием кросс-энкодера или небольшой модели большого языкового модели, прежде чем отобрать те, которые попадут в запрос. Этот метод постоянно входит в число лучших дополнений к пайплайну. Кросс-энкодер оценивает одновременно запрос и документ, что гораздо точнее, чем сравнение двух отдельно вычисленных векторов, однако он должен работать с каждым кандидатом отдельно и не может обрабатывать всю коллекцию. Поиск с использованием би-энкодера дешев и приблизительен, но сужает круг кандидатов, тогда как кросс-энкодер дорог и точен, но анализирует только те элементы, которые остались после предыдущих этапов.
- Гибридный поиск, сочетающий плотные векторы с разреженным поиском по ключевым словам, чтобы точные токены не оставались на усмотрение случая.
Оценка качества поиска отдельно
Набор для оценки лучше интуитивных предположений. Составьте от 20 до 50 реалистичных вопросов, укажите, какие фрагменты информации следует извлекать для каждого из них, и напрямую проверьте, попадает ли правильный фрагмент в топ-5 или топ-10 (Recall@k). Добавьте судью в виде большой языковой модели для оценки релевантности только тогда, когда ручная проверка завоюет ваше доверие. Если качество извлечения информации никогда не оценивается отдельно от качества ответа, усилия тратятся на оптимизацию неверного этапа. Такие инструменты, как Ragas, учитывают специфические метрики RAG, поэтому вам не нужно создавать всю систему вручную.
LlamaIndex или LangChain: концептуально
LlamaIndex ориентирован на данные и предлагает четкие абстракции для механизмов индексации, поиска и обработки запросов; он кажется естественным решением, когда основной проблемой является большой объем документов, требующих эффективного поиска. LangChain предназначен для универсального использования, возник на основе концепций цепочек и агентов, и имеет гораздо более развитую экосистему интеграций. Он более гибкий, но в то же время требует больше ресурсов, если нужен только поиск. Ни один из них не является волшебным решением, поскольку оба используют одни и те же основные принципы работы. Выберите один из них, хорошо изучите его концепции и не будьте догматичными — архитектурные знания будут полезны независимо от используемой синтаксиса.
Итоги
- Индексация и поиск — это отдельные этапы, поэтому их следует проектировать независимо друг от друга.
- Разбиение данных на чанки — это важный элемент проектирования, а не стандартное решение фреймворка.
- Хранилища векторов представляют собой инфраструктуру, а преимущества используются в процессах фильтрации и гибридного поиска, а не в самом бренде продукта.
- Качество поиска необходимо оценивать отдельно от качества ответа.
- Фреймворки являются инструментами, а не архитектурой, поэтому изучайте соответствующие шаблоны и рассматривайте их как заменяемые элементы.
Связанные материалы
- Расширенный подход к RAG в производстве: архитектура, инструменты и компромиссы — обзор процесса использования RAG в производстве: загрузка данных, парсинг, разбиение на части, генерация векторов, хранилища векторов, гибридный поиск, переранжирование, оценка и безопасность, включая компромиссы каждого из этих элементов.
- Полная дорожная карта RAG: от основ до проблем в производстве — два потока обработки данных, три этапа и список типичных сбоев: как работает генерация с усилением поиска, где возникают сбои и какие решения устраняют каждую проблему.