TGViewer
this->notes. this->notes. @thisnotes · 4.52K subscribers
Post #512 1.04K
#common

Сидите вы себе спокойно, разрабатываете поиск каких-нибудь объектов. Может это товары, может странички вики, может код. Что угодно. Ваш поиск — качественный keyword search.

Почесали вы репу и решили, что надо улучшать качество. Обучили новую модель, которая умеет понимать СмЫсЛ и выдавать эмбеддинги объектов. Эмбеддинги вы складываете в какую-нибудь векторную БД. Поиск там работает из коробки.

Вопрос: как интегрировать два поиска?

Проблема тут понятная: так как модели поиска работают различно, взять скор каждого объекта и сравнить со скорами объектов из другого поискового движка просто нельзя (это не имеет смысла, ведь в одном движке скор может быть от 0 до 1, а в другом [0; 1000]; считаются по-разному, означают разное).

Что делать?

Reciprocal Rank Fusion (RRF) — алгоритм объединения нескольких списков результатов поиска в один общий. Идея за ним простая: вместо сравнения сырых скоров из разных поисковых систем мы будем смотреть только на позицию айтема в изначальных списках.
Выражается формулой:

RRF(doc) = SUM( 1 / (k + rank_i(doc) ), i in [1; N]


doc — документ
N — количество поисковых систем/движков
rank_i(doc) — позиция документа doc в i-м списке
k — некоторая константа, положим 60.

Фактически, чем выше документ находится в разных списках, тем больше его итоговый RRF score.

Давайте быстрый пример. Keyword search выдал (номер-документ):

1 A
2 B
3 C
4 D

а vector search:

1 C
2 A
3 E
4 B

Тогда

RRF(A) = 0.0325
RRF(B) = 0.0317
RRF(C) = 0.0323
RRF(D) = 0.0156
RRF(E) = 0.0159

Итоговый результат выглядит так:

1 A
2 C
3 B

D и E можем опустить по некоторому трешхолду или просто потому что они не встретились в результатах обоих движков.

Почему мы взяли k=60?

Понятно, что большее значение k уменьшает влияние первых позиций, а меньшее наоборот: сильнее их награждает.
А 60 это просто значение, использовавшееся в оригинальной статье. Авторы его как-то примерно подобрали и потом отталкивались во всей статье от конкретного значения в формуле.

Плюсы RRF:
• не требует никакого обучения. Простой математический метод.
• очень легко реализовать. Джуна посадите и чекните PR через день.
• неплохо работает даже в самом базовом виде. Без подкручивания k.
• устойчив к разным шкалам score, потому что их не использует.
• очень легко добавлять новые движки.

Минус один, но жирный: не учитывает, на сколько разница между позициями сильная.
Оригинальные скоры для соседних документов в рамках одного движка могут различаться очень сильно, но из-за высокой позиции документ всё ещё может оказаться на высоком месте в итоговом результате.

Фактически RRF — первый бейзлайн для гибридного поиска. Но если хочется качество получше (то есть перестать просто «смешивать» документы, а реально понимать «что лучше показать юзеру»), нужно обучать отдельную модель, которая переранжирует результаты ещё раз. Может она даже будет тяжёлой, но в силу того, что работать ей надо не со всем набором документов, а только с топ-X найденных, это обычно не проблема.

@thisnotes. Patreon, newsletter.
Спасибо Artyom Garkavy и niki4smirn.
  • ❤ 17
  • 🔥 4
  • 👍 3
  • 😁 1
More from @thisnotes
  1. Sep 9, 2026#cpp #books Да, книга 2001ого года. Мы ровесники. И да, в ней в основном обсуждаются какие…
  2. Sep 2, 2026#perf Попробовал собрать в кучку (кажется, немного сумбурно всё же) мысли по двум моментам…
  3. Aug 31, 2026Давайте новый тег заведём: #perf Во-первых, надо понять, что я вообще понимаю под перфом,…
  4. Aug 27, 2026#common Мы часто делаем системы, которые обладают какими-то ограничениями. Ограничения наш…
  5. Aug 24, 2026#list 0. [talk] Achieving Peak Performance for Matrix Multiplication in C++. Aliaksei Sala…
  6. Aug 20, 2026Про контент. Я не буду разбирать и рекомендовать отдельные доклады. Это я сделаю когда дос…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →