Как построить RAG поиск для ИИ больших данных? Обсуждаем проблему.

RAG, который выдаёт 90% точности на 5 000 документов, на 500 000 разваливается до 50%. Та же модель эмбеддингов, тот же ретривер. Что произошло, и при чём тут геометрия embedding-пространства.

Как построить RAG поиск для ИИ больших данных? Обсуждаем проблему.

«У вас RAG, который на 5 000 корпоративных документов выдаёт 90% точности retrieval. Скейлите до 500 000, точность падает до 50%. Та же модель эмбеддингов, тот же ретривер. Объясните, почему».

Самый очевидный ответ: больше документов, больше конкуренции за топ-K слотов. Звучит правдоподобно. И в каком-то смысле верно. Только это никак не объясняет, почему точность падает так драматично. Объём корпуса вырос в 100 раз, а recall просел почти вдвое. Линейного объяснения не получается.

Настоящий ответ — про то, как корпоративные документы устроены в пространстве эмбеддингов.

Кластеры везде, а правды нигде

Любое продуктовое решение в современной компании оставляет за собой шлейф артефактов: транскрипт встречи, тред в Slack, страница в Confluence, тикет в Jira, цепочка email с клиентом. Все они описывают одно событие. И, что критично для нашей истории, все они оседают в одной и той же области пространства эмбеддингов.

Современные эмбеддеры обучаются методом contrastive learning. Их буквально натаскивают подтягивать семантически близкое поближе и отталкивать далёкое подальше. Когда десять разных артефактов обсуждают один и тот же фичефлаг, эмбеддер делает свою работу хорошо: он сжимает их в плотный комок. Для тематического поиска это фича. Для поиска факта это та ещё проблема.

А компания за полгода активной работы генерит таких комков сотни. По каждому проекту, по каждому клиенту, по каждой версии роадмапа, по каждому инциденту. К моменту, когда корпус доползает до 500 000 документов, его embedding-пространство выглядит не как ровное звёздное небо, а как скопление галактик: плотные горячие кластеры похожего, дублирующегося, перекликающегося контента.

Как построить RAG поиск для ИИ больших данных? Обсуждаем проблему.

Один вопрос, десять документов, один правильный

Дальше начинается вторая половина проблемы. Документы из одного кластера говорят про одно событие, но содержат разные факты:

  • тред в Slack: что в итоге решили
  • тикет в Jira: к какому числу выкатить
  • страница в Confluence: техспек и архитектура
  • email-цепочка: что изначально просил клиент
  • транскрипт встречи: почему вообще это обсуждали

Когда пользователь задаёт вопрос «когда у нас дедлайн по проекту X», ответ лежит ровно в одном из этих документов. Остальные тематически релевантны, но фактически бесполезны.

На корпусе в 5 000 документов про этот проект пишут 3-5 артефактов. Нужный почти гарантированно попадает в топ-K, потому что вокруг него мало шума.

На корпусе в 500 000 — 40-60 артефактов. Тот самый, с дедлайном, легко выпихивается из топ-K соседями, которые говорят про тот же проект, но не отвечают на вопрос. Они не «менее релевантны» в геометрическом смысле. По косинусной близости они почти такие же, как нужный. Просто фактически бесполезные.

Как построить RAG поиск для ИИ больших данных? Обсуждаем проблему.

Что показали измерения

Команда Onyx выпустила EnterpriseRAG-Bench, открытый датасет на 500 000+ синтетических корпоративных документов: Slack, Gmail, Jira, GitHub, Confluence, Google Drive, HubSpot, Fireflies, Linear. Со всеми реалистичными артефактами вроде неправильно подшитых файлов, near-duplicates, конфликтующих версий и метаданных «отправлено в нерабочее время».

Они прогнали один и тот же ретривер на пяти размерах корпуса, от 5K до 500K. Результаты:

  • Vector search: 90.7% точности на 5K → 50.6% на 500K. Падение на 40.1 п.п.
  • BM25: 85.8% → 68.4%. Падение на 17.4 п.п. Легче, но тоже больно.

И главное наблюдение, которое они задокументировали: на каждом масштабе плотность окрестности в пространстве эмбеддингов монотонно коррелирует с recall. Чем больше похожих документов вокруг релевантного, тем хуже его достают. Без исключений.

[ИНФОГРАФИКА — embed infographic.html сюда]

Это свойство пространства, а не косяк датасета

Тут было бы соблазнительно списать всё на конкретный датасет. Мол, у Onyx синтетика, near-duplicates руками накидали, на реальных данных так не бывает. Бывает. И за этим эффектом стоит фундаментальная штука, известная двадцать лет.

Aggarwal et al. ещё в 2001 году показали: при росте размерности расстояния между точками концентрируются. Разница между ближайшим и дальним соседом схлопывается до неразличимой. В 768-мерном пространстве (стандарт для современных эмбеддеров вроде OpenAI text-embedding-3, BGE-M3, E5-Mistral) почти все векторы оказываются примерно на одинаковом расстоянии от запроса. «Похожее» перестаёт быть «сильно похожим». Оно становится «чуть-чуть похожим, как и всё остальное».

Свежий препринт Lakshman et al. (февраль 2026) сформулировал проблему через понятие stability: насколько устойчивы ближайшие соседи запроса к малым возмущениям. Они эмпирически показали, что популярные ANN-индексы вроде HNSW и IVF деградируют именно на нестабильных датасетах. Top-10 recall может проседать кратно по сравнению с brute-force kNN на тех же данных.

Salesforce AI Research в работе HERB (бенчмарк для deep search по корпоративным данным) пошли дальше. На пуле всего из 39 190 документов (это, на минуточку, в 13 раз меньше Onyx-овских 500K) даже лучшие агентные RAG-методы получили средний скор 32.96. Главным боттлнеком авторы прямо назвали retrieval. Системы не вытаскивают все нужные доказательства, а потом строят рассуждение на частичном контексте. И галлюцинируют, разумеется.

Отдельная группа исследователей в работе по HNSW нашла ещё более жёсткий артефакт: recall зависит даже от порядка вставки векторов в индекс. Сдвиг до 12 п.п. только за счёт insertion order. То есть один и тот же датасет, один и тот же индекс, разный порядок добавления — разные результаты. И никто из юзеров об этом не предупреждён.

Почему BM25 держится лучше

Это контр-интуитивный момент, но в больших корпусах старичок BM25 часто обгоняет дорогой dense retrieval. Не потому что он умнее. Потому что у него нет проблемы концентрации в принципе: BM25 считает лексические совпадения, а не геометрию.

Если в запросе есть редкое слово, типа артикула, имени клиента, номера тикета или кодового названия проекта, BM25 это слово увидит и достанет нужный документ, даже если в кластере вокруг него ещё 50 семантически близких. Vector search в той же ситуации сигнал задушит, потому что для эмбеддера «PROJ-7341» и «PROJ-7339» это почти один и тот же токен.

Поэтому почти все production-ready RAG-пайплайны последних двух лет — гибридные. По данным Pradeep et al., объединение BM25 и dense retrieval через Reciprocal Rank Fusion даёт прирост recall в 15-30% относительно любой одиночной стратегии. Cross-encoder reranking на втором этапе добавляет ещё до 28% nDCG@10. И это даже до того, как мы упомянули domain-specific эмбеддеры: модели, дотюненные на конкретной предметке (юр, мед, финтех), обходят универсальные на 15-25% на специализированных запросах.

Получается стек: BM25 + dense + RRF + cross-encoder. Каждый слой бьёт по своему классу ошибок. Без одного из них пайплайн на масштабе будет течь.

Что с этим делать

Главный практический вывод грустный, но честный.

90% точности на 5K документов не говорят ничего о том, как ваш ретривер будет работать в продакшене. Бенчмарк, на котором вы тестируете RAG, должен быть масштаба вашего реального корпуса. Не «мы взяли тысячу документов и получили красивые цифры», а «мы прогнали 500K и посмотрели, где у нас ломается кривая recall».

Что конкретно стоит сделать:

  1. Замерить плотность окрестностей в собственном embedding-пространстве. Если у вас в корпусе много кластеров с десятками семантически близких документов, у вас не плохой ретривер. У вас задача такая.
  2. Поставить гибридный поиск, если ещё нет. BM25 на масштабе деградирует мягче, и при коллапсе dense это спасает. Бесплатно, в смысле GPU. Платно в смысле инженерных часов на нормальный fusion.
  3. Добавить cross-encoder reranking. На stage 2 он переоценивает топ-K и часто вытаскивает правильный документ из 5-10 близких соседей. Дорого по латенси, дёшево по точности.
  4. Прогнать свой пайплайн против EnterpriseRAG-Bench в обоих режимах: 5K и 500K. Посмотреть, где сломается ваша собственная кривая. Не «сломается ли», а где именно.

Весь EnterpriseRAG-Bench (датасет, вопросы, evaluation harness) лежит в опенсорсе. Можно брать и проверять.

И последнее. Если ваш RAG показывает 90% на тестовом наборе из тысячи документов, это не значит, что у вас отличный RAG. Это значит, что у вас отличный тестовый набор.
Ссылка на набор данных для тестов системы, чтобы не обнаруживать на проде, что все перестало работать.

У меня нет пока готового решения, на проекте, который мы ведем и где постепенно накапливаются десятки тысяч документов на юзера и близки сотни тысяч это уже начинает становиться проблемой и мы пока работаем с 2 или 3 слойным поиском по векторам. Но это тема отдельной статьи.

Начать дискуссию