TGViewer
Daria’s room Daria’s room @dariasroom · 1.2K subscribers
Post #119 1.39K
Отделяем текстовый скоринг от продуктового ранжирования

Как оказалось, научить поисковый движок находить релевантные документы = только половина задачи. Следующий вопрос в том, какие из найденных совпадений важнее для конкретного продукта.

Окей, движок уже умеeт строить индексы по нескольким полям (title, abstract и т.д.) и поддерживает разные типы поиска: например term, phrase, prefix, фразовый поиск. Но после поиска вклад каждого совпадения просто добавлялся в итоговый вес документа. Например, для запроса`title:diabetes abstract:"type 1" abstract:insulin*` мы находили три независимых совпадения:

• term - diabetes в title;
• phrase - "type 1" в abstract;
• prefix - insulin* в abstract.

Для каждого совпадения BM25 считал свой вес, после чего все веса просто суммировались:

BM25 total doc score =
BM25(title:diabetes)
+ BM25(abstract:"type 1")
+ BM25(abstract:insulin*)


Базово текстовая релевантность оценена за счет частоты термина, его редкости среди всех документов, длине поля. И это ок, но продуктово мы помимо всего знаем, что совпадения в заголовке обычно важнее совпадения в abstract, и что точная фраза часто ценнее совпадения по одному слову (или хотя бы по префиксу).

Поэтому я подсмотрела идею с Rank Profiles - добавлением правил ранжирования по заданым критериям, который добавляет веса нужным докам без переиндексации.

Пример профиля из конфига:

rank_profile:
name: debug-weights

field_weights:
title: 1.5

query_type_weights:
term: 1.5
phrase: 1.7
prefix: 0.5


Теперь BM25 по-прежнему считает базовый score каждого совпадения, но перед суммированием вклад умножается на коэффициент:

document score =
BM25(title:diabetes) × 1.5 × 1.5
+ BM25(abstract:"type 1") × 1.0 × 1.7
+ BM25(abstract:insulin*) × 1.0 × 0.5


Поскольку индекс уже хранит информацию о каждом найденном совпадении (поле, тип запроса и базовый вес), политику ранжирования теперь можно менять прямо во время поиска - без переиндексации документов с явным разделением ответственности:

• основная retrieval часть находит совпадения и сохраняет их контекст;
• BM25 считает базовую текстовую релевантность;
• Rank Profile задает правила, по которым совпадения влияют на итоговый вес документа;
• Explain разбивка помогает понять, почему документ получил именно такой вес.

Чтобы было проще отлаживать ранжирование, добавила Explain-панель. Для каждого документа можно посмотреть, из каких вкладов сложился итоговый вес: какое совпадение сработало, в каком поле, какой базовый вес посчитал BM25, какие коэффициенты применились и какой вклад каждое совпадение внесло в итоговый результат.

На скрине из TUI (который, кстати, был тщательно причесан и допичкан инфо панельками) как раз видно такую разбивку по весам для каждого найденного документа.

Сейчас Rank Profile умеет учитывать поле документа и тип совпадения. В дальнейшем список сигналов можно расширить: например, добавить свежесть документа, популярность или поведенческие сигналы (клики пользователей). Главное, чтобы поисковый движок умел вычислить такой сигнал - тогда его можно включить в ranking pipeline без изменения индекса.

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

#fts #projects
  • ❤ 13
  • 🔥 4
  • 👍 2
  • 🤯 2
More from @dariasroom
  1. Sep 15, 2026Автоматическое сжатие на клиенте vs ручное на сервере Стандартный клиент http.Transport са…
  2. Sep 5, 2026Причина перекосов в уровне балансировки L4-балансировщик выбирает серверную ноду при созда…
  3. Aug 28, 2026Итераторы… TL;DR: в iter.Seq итератор сам передаёт следующие элементы в код внутри range,…
  4. Aug 17, 2026Что на самом деле нужно сохранять при сериализации сложной структуры? TL;DR: Важно отделит…
  5. Aug 13, 2026Привет! Вас стало больше, так что пора наконец представиться 🙂 Я Даша, давно пишу на Go,…
  6. Aug 12, 2026HNSW: как устроен графовый индекс для векторного поиска One million years later, я наконец…
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 →