Диагностика Mock-интервью
Главная · RAG: поиск + генерация

Векторный поиск и ANN-индексы

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

Интуиция

После того как тексты превращены в эмбеддинги, «найти похожее по смыслу» = «найти ближайшие точки в многомерном пространстве». Близость меряют тремя способами: косинусная близость (cosine similarity, угол между векторами), скалярное произведение (dot product) и евклидово расстояние. Звучит как три разных мира, но если векторы нормировать к единичной длине, все три метрики упорядочивают соседей практически одинаково — поэтому спор «косинус или евклид» на нормированных эмбеддингах почти беспредметен.

Точный поиск — сравнить запрос с каждым из N векторов размерности d:

стоимость ≈ O(N × d) на каждый запрос

Для 10 тысяч векторов — мгновенно. Для 100 миллионов при d = 1024 — уже сотни миллиардов операций на запрос. Не масштабируется.

Как это работает: ANN

ANN (Approximate Nearest Neighbors, приближённый поиск соседей) — сознательный размен: ищем не гарантированно ближайших, а «почти наверняка ближайших», зато на порядки быстрее. Качество индекса меряют метрикой recall@k — какая доля истинных топ-k соседей нашлась. Recall 0.95 значит: в среднем 19 из 20 настоящих соседей на месте.

Отдельная боль — фильтры по метаданным («ищи только среди документов отдела X»). Наивно: найти топ-k, потом отфильтровать — но фильтр может выбить почти всех, и останется два результата из k. Поэтому зрелые движки поддерживают фильтрацию внутри обхода индекса (filter-aware search).

💡 Ключевая мысль ANN — это всегда торговля: recall против скорости и памяти. Ручки вроде nprobe у IVF двигают систему вдоль этой кривой, а не дают «бесплатное» ускорение.

Что выбрать на практике

Выбор движка — вопрос масштаба и стека, а не моды:

Типичная ошибка дизайна — тащить выделенную векторную БД в проект на 50 тысяч документов «на вырост»: операционная сложность реальна уже сегодня, а масштаб, может, не наступит никогда.

⚠️ Подводный камень Recall индекса измеряется относительно точного поиска на ваших данных и ваших запросах. Настройки по умолчанию, дающие 0.99 на бенчмарке, на вашем распределении могут давать 0.7 — особенно с фильтрами по метаданным. Меряйте сами: возьмите выборку запросов, посчитайте честный топ-k перебором и сравните.
🎤 На собеседовании
  • «Косинус или евклид?» — на нормированных векторах ранжирование почти совпадает; важнее, с какой метрикой обучалась модель эмбеддингов и построен индекс.
  • «Объясните HNSW на пальцах» — многослойный граф: сверху «хайвеи» для дальних прыжков, снизу «улицы» для точной доводки; жадный спуск по слоям.
  • «Что крутить в IVF, если recall низкий?» — увеличить nprobe (медленнее, полнее) или число/качество центроидов; проверить случай запросов у границ ячеек.
  • «Как ANN уживается с фильтрами по метаданным?» — пост-фильтрация может оставить меньше k результатов; нужен движок с фильтрацией внутри обхода индекса.