Вы собрали RAG-пайплайн: загрузили документы, нарезали на чанки, сгенерировали эмбеддинги, подключили векторную базу. Задаёте вопрос — модель отвечает уверенно и подробно. Показываете заказчику, тот в восторге. Но при тестировании на реальных вопросах оказывается, что на половину из них система отвечает мимо: retrieval находит не тот документ, не тот фрагмент или вообще ничего не находит, а модель уверенно галлюцинирует.
Проблема не в модели. Современные LLM вроде GPT-4 и Claude отвечают хорошо, если им предоставить правильный контекст. Проблема — в retrieval. Качество ответа напрямую зависит от качества извлечённого контекста.
Рассмотрим три основные причины сбоев и способы их устранения.
Проблема 1: чанки нарезаны бездумно
Стандартный подход — делить документ на фрагменты по 500–1000 символов с перекрытием. Но такой способ часто разрезает смысловые блоки пополам.
Например, в договоре пункт о ответственности начинается на одной странице и заканчивается на другой. При нарезке по символам первая часть попадает в один чанк, вторая — в другой. Запрос «какая ответственность по договору» находит только начало, а модель не видит полной информации.
Аналогично с таблицами: заголовок может оказаться в одном чанке, а данные — в другом. Без заголовка данные теряют смысл.
Решение — нарезка по смыслу, а не по длине:
- Используйте RecursiveCharacterTextSplitter, который разделяет текст по естественным границам: сначала по двойным переносам (параграфы), потом по одинарным, затем по точкам.
- Для структурированных документов (договоры, регламенты) нарезайте по разделам: каждый пункт или подраздел — отдельный чанк.
- Добавляйте заголовок раздела к каждому чанку. Это помогает модели понять контекст, даже если фрагмент найден по ключевым словам.
- Для таблиц — дублируйте заголовок в каждом чанке с данными.
Проблема 2: семантический поиск не находит нужное
Сравнение эмбеддингов через cosine similarity — стандарт, но он не справляется в двух случаях:
- Разные формулировки одного понятия: «штрафы за просрочку» и «неустойка за нарушение сроков». Слова разные, эмбеддинги — далеко, особенно если модель не обучена на узкоспециализированных текстах.
- Поверхностное совпадение: запрос «что нужно для оформления возврата» находит общий чанк про «политику возврата», а не конкретные шаги.
Решение — улучшить retrieval за счёт двух подходов.
Гибридный поиск: комбинируйте семантический (на эмбеддингах) и keyword-поиск (BM25).
Параметр alpha балансирует между ними: при alpha=1 — только семантика, при alpha=0 — только ключевые слова. На практике alpha=0.5–0.7 даёт лучший результат, потому что BM25 ловит точные совпадения, а семантический поиск — синонимы.
Reranking: после первичного поиска (retrieval) отберите 20 кандидатов, а затем переранжируйте их с помощью cross-encoder.
В отличие от bi-encoder, который кодирует запрос и документ отдельно, cross-encoder анализирует пару целиком и точнее оценивает релевантность. Он медленнее, поэтому используется не для поиска по всей базе, а только для финальной сортировки топ-20.
Гибридный поиск + reranking значительно повышает точность retrieval.
Проблема 3: отсутствие измерения качества
Многие оценивают RAG на 5–10 вопросах, которые придумал разработчик. Это не показатель. Реальные пользователи задают другие вопросы, и система часто терпит крах.
Решение — создать evaluation dataset: набор реальных или реалистичных вопросов с указанием правильных чанков или ожидаемых ответов. Достаточно 50–100 примеров.
С eval dataset вы можете:
- Проверить, улучшилось ли качество после смены размера чанка.
- Оценить, помог ли reranking или гибридный поиск.
- Сравнить разные эмбеддинг-модели.
Создание датасета — ручная работа, но 50 вопросов можно собрать за час. Зато каждое изменение в пайплайне будет измеримо.
Что ещё влияет на качество
Размер чанка: маленькие (200–500 символов) дают точный retrieval, но мало контекста. Большие (2000–3000) — наоборот. Оптимальный размер зависит от задачи:
- FAQ: 300–500
- Юридические документы: 1000–2000
- Техническая документация: 500–1000
Подбирайте экспериментально и проверяйте через eval dataset.
Эмбеддинг-модель: по умолчанию используют OpenAI text-embedding-3-small или all-MiniLM-L6-v2. Для русскоязычных текстов лучше подходят multilingual-e5-large или BGE-M3 — они обучены на русском языке. Смена модели может дать прирост recall на 10–20% без других изменений.
Промпт: даже с идеальным контекстом модель может галлюцинировать, если промпт слабый.
Вместо «Ответь на вопрос на основе контекста» используйте:
Ответь на вопрос на основе предоставленного контекста. Если в контексте нет информации для ответа, скажи об этом. Не додумывай. Ссылайся на конкретные пункты документа.
Инструкция «не додумывай» снижает галлюцинации, а «ссылайся на пункты» делает ответ проверяемым.
Когда RAG не подходит
RAG эффективен для вопросов по документам: «что написано в договоре», «как настроить сервис». Но он не подходит для задач, требующих анализа или рассуждений:
- «Сравни два договора и скажи, какой выгоднее».
- «Проанализируй тренд в данных за квартал».
Для таких задач нужны агенты с инструментами, а не retrieval.
Также RAG избыточен при малом объёме данных (меньше 10 страниц). Если весь текст помещается в контекст модели — загружайте его целиком. RAG оправдан, когда документов тысячи страниц.
Retrieval — самое слабое звено в RAG. Нарезка по смыслу, гибридный поиск, reranking и eval dataset — четыре практики, которые превращают демо в рабочее решение. Каждую можно внедрить за день, и каждая даёт измеримое улучшение.