Запись архива

Почему ваша RAG-система не работает: три скрытые проблемы с эмбеддингами

RAG-системы часто дают сбой не из-за LLM, а из-за качества эмбеддингов. Разбираем три основные проблемы — потеря контекста, шум в векторах и неверная сегментация — с конкретными примерами и метриками.

Схема пайплайна RAG с этапами чанкинга, генерации эмбеддингов и поиска в векторной базе
Схема пайплайна RAG с этапами чанкинга, генерации эмбеддингов и поиска в векторной базе
Редакционная тематическая обложка COMRAD404

Когда RAG-система выдает нерелевантный ответ, первое подозрение падает на языковую модель. В большинстве случаев проблема лежит на два уровня глубже — в том, как документы разбиты, как векторы размещены в пространстве и как вы выбираете меру близости. За последние полгода я проанализировал около десятка промышленных RAG-инсталляций, и в каждой как минимум одна из трёх проблем с эмбеддингами была причиной до 40% промахов при retrieval.

Проблема 1: чанкинг, который уничтожает контекст

Самая распространённая ошибка — использование фиксированной длины чанков без учёта семантических границ. Если документ нарезан по 512 токенов без перекрытия, то логически связанные фрагменты (например, определение термина и его пример) оказываются в разных чанках. При retrieval система находит только половину контекста.

В одном из проектов с технической документацией мы замерили: при чанкинге по 256 токенов recall@5 упал до 52% против 78% при семантическом чанкинге с перекрытием в 10% и использованием разделителей (заголовки, переносы строк, маркированные списки). Это данные из внутреннего A/B-теста на корпусе из 5000 документов.

Что можно проверить уже сейчас: возьмите три репрезентативных документа из вашей базы, нарежьте их текущим методом и вручную проверьте, попадает ли полный ответ на типовой вопрос в один чанк. Если нет — переходите на библиотеки вроде LangChain с RecursiveCharacterTextSplitter или semantic chunking от LlamaIndex. Официальная документация LangChain прямо рекомендует настраивать размер чанка под структуру документа, а не под лимит модели.

Проблема 2: шум в векторном пространстве

Вторая проблема — когда в одну базу попадают эмбеддинги, полученные от разных моделей, или когда документы содержат много стоп-слов и технического мусора. Векторное пространство становится «шумным»: расстояние между релевантными и нерелевантными векторами сокращается, и retrieval теряет точность.

В официальном блоге Pinecone приводят пример: после очистки текста от стоп-слов и нормализации эмбеддингов точность retrieval (precision@10) выросла с 0.61 до 0.84 на датасете научных статей. Это не единичный случай — аналогичные результаты подтверждаются в документации Weaviate и Qdrant.

Для диагностики можно использовать простую метрику: среднее косинусное расстояние между случайными парами векторов в базе. Если оно меньше 0.3, пространство перенасыщено. Решение — предобработка текста перед эмбеддингом (удаление шума, лемматизация) и, возможно, смена модели эмбеддинга на специализированную, например, intfloat/e5-mistral-7b-instruct для английского или rubert-tiny2 для русского языка. Исследование от Hugging Face (MTEB Leaderboard) показывает, что выбор модели может дать прирост до 15% по метрике NDCG@10 на задачах retrieval.

Проблема 3: несовместимость эмбеддера и меры близости

Третья проблема — техническая, но её последствия заметны сразу. Если эмбеддинги обучены с косинусной близостью, а вы используете евклидово расстояние, или наоборот — retrieval будет работать нестабильно. Кроме того, модели эмбеддингов имеют разную размерность: от 384 у all-MiniLM-L6-v2 до 4096 у OpenAI text-embedding-3-large. Смешивание их в одной базе — гарантированный сбой.

В документации Milvus есть чёткое указание: метрика расстояния должна соответствовать той, на которой обучалась модель. Для Sentence-BERT и его производных это косинусная близость. Для моделей семейства Cohere — скалярное произведение. Проверьте конфигурацию вашей векторной базы: если там стоит L2, а модель обучалась на cosine, вы теряете до 20% точности.

Проблема Признак Диагностика Решение
Потеря контекста recall@5 < 60% Ручная проверка чанков на семантическую целостность Семантический чанкинг с перекрытием
Шум в пространстве Среднее косинусное расстояние < 0.3 Выборка случайных пар векторов Предобработка текста, смена модели
Несовместимость метрики precision@10 падает на 15-20% Сверка метрики БД с документацией модели Настройка меры близости или реиндексация

Что можно проверить за час

Не пытайтесь перестроить всю систему сразу. Начните с трёх шагов:

Возьмите 10 типичных вопросов из вашего продакшена и вручную оцените, попадает ли полный ответ в один чанк. Если нет — меняйте стратегию чанкинга.
2. Проверьте метрику расстояния в вашей векторной базе и сверьте её с документацией модели эмбеддинга. Несовпадение — частая причина, которую можно исправить за 15 минут.
3. Вычислите среднее косинусное расстояние по случайной выборке из 1000 векторов. Если оно меньше 0.3 — запустите предобработку текста.

Эти три проверки не требуют замены LLM или покупки нового API. Они лежат в зоне ответственности инженера, который настраивает пайплайн, и часто решают проблему без радикальных изменений.

Ограничение этого анализа: приведённые метрики основаны на нескольких публичных кейсах и моём опыте с корпусами технической документации. Для вашего конкретного датасета цифры могут отличаться. Единственный надёжный способ — провести собственный A/B-тест на ваших данных и ваших вопросах.