Перейти к содержимому
31 окт. 2024 г.·7 мин чтения

Когда реранкер окупается: recall, задержка и цена

Разберём, когда реранкер окупается в поиске: как считать прирост recall, влияние на задержку, цену запроса и где лишний шаг не нужен.

Когда реранкер окупается: recall, задержка и цена

Почему спорят о лишнем шаге в поиске

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

Для системы это выглядит терпимо. Для человека - нет. Пользователь почти всегда смотрит верх списка, и ошибка в первых позициях бьет сильнее, чем промах внизу. Если правильный ответ есть в выдаче, но спрятан слишком низко, человек все равно считает, что поиск не сработал.

Поэтому команды добавляют реранкер. Он берет короткий список кандидатов, например 20 или 50 документов, и пересортировывает его уже не по грубому сходству, а по более точному совпадению с вопросом. Идея простая: не искать заново, а поднять наверх результат, который уже найден, но стоит не там.

Спор обычно не про саму идею, а про цену этого шага.

Если реранкер поднимает нужный ответ с 7 места на 2-е, пользователь замечает это сразу. В службе поддержки, внутреннем поиске по базе знаний или RAG для оператора разница видна быстро. Один и тот же набор документов начинает казаться "умнее" только потому, что порядок стал лучше.

Но лишний шаг не бывает бесплатным. Команда платит временем ответа, отдельным вызовом модели и более сложным пайплайном поиска.

И даже хороший реранкер окупается не всегда. Если базовый поиск и так стабильно кладет нужный документ в верхние позиции, второй шаг почти ничего не меняет. Он просто добавляет миллисекунды и счет за инференс.

Бывает и обратная ситуация. Базовый поиск находит "похожие" документы, но путает близкие формулировки, версии инструкций или почти одинаковые карточки товара. Тогда реранкер часто исправляет именно ту ошибку, которую замечает человек: ставит выше более точный фрагмент, а не просто самый похожий текст.

Из-за этого спор не затихает. Одни смотрят на recall по всему списку и говорят, что база уже справляется. Другие смотрят на верх выдачи и видят, что пользователь до правильного ответа не доходит. На практике все решает разница между выигрышем в рабочем топе и потерями в задержке и цене.

Что считать выигрышем, а что расходом

Понять, окупается ли реранкер, можно только на уровне задачи, а не по красивой метрике в отчете. Команда часто видит рост качества на длинном списке кандидатов и делает неверный вывод. Пользователь не читает топ-100. Он видит первые 3-5 результатов или сразу получает готовый ответ.

Метрика, которая ближе к делу

Смотрите прежде всего на recall в рабочем топе. Если реранкер поднял нужный документ с 18 места на 4-е, это уже реальная польза. Если он просто переставил документы внутри топ-50, а в топ-5 ничего не изменилось, пользы почти нет.

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

Такой взгляд быстро отрезвляет. Рост recall на кандидатах сам по себе не платит за лишний шаг. Платит только тот прирост, который меняет исход задачи.

Хороший тест устроен просто. Берете набор реальных запросов, смотрите топ без реранкера и с ним, а потом отмечаете не только позицию правильного документа, но и то, смог ли человек или бот завершить работу. Для службы поддержки разница между документом на 2 месте и на 9 месте огромна. Для аналитика, который и так откроет 20 карточек, она может быть почти нулевой.

Цена и задержка по слоям

Расход тоже надо считать по шагам. Если свести все в одну цифру за день, картина быстро ломается. Считайте цену на один запрос и раскладывайте ее на поиск кандидатов, реранкер и финальную генерацию ответа.

С задержкой та же логика. Отдельно меряйте, сколько времени занял первый поиск, сколько добавил реранкер и сколько ушло на ответ модели. Иначе легко пропустить неприятный сценарий: реранкер дал плюс 4% к recall в топ-5, но добавил 350 мс, и бот начал отвечать заметно медленнее.

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

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

Когда реранкер реально помогает

Реранкер не расширяет поиск. Он не найдет новый документ, если первый этап вообще не положил его в список кандидатов. Его польза начинается в другой точке: когда recall по кандидатам уже нормальный, но порядок слабый. Нужный фрагмент есть в топ-50 или топ-100, однако лежит слишком низко и не попадает в рабочий топ, который увидит человек или возьмет RAG.

Именно здесь второй шаг часто дает заметный эффект. Быстрый первый поиск собирает широкий набор похожих кусков. Реранкер читает их внимательнее и переставляет по смыслу запроса, а не только по грубой близости. Для метрики это может быть сдвиг с 24-го места на 4-е. Для пользователя разница еще больше: ответ появился сразу, без лишних открытий и уточнений.

Чаще всего это видно на коротких, шумных и двусмысленных запросах. Фразы вроде "лимит по карте", "возврат", "акт", "отпуск" слишком короткие. В них мало контекста, зато много возможных значений. Первый этап нередко находит несколько очень похожих фрагментов, но ставит выше не тот. Реранкер лучше различает, где речь про правило, где про исключение, а где про старую версию текста.

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

В такой базе первый этап честно находит "что-то рядом", но плохо решает, что поставить первым. Реранкер исправляет именно эту ошибку ранжирования.

Картина обычно простая: без него нужный кусок уже есть среди кандидатов, но редко попадает в топ-5 или топ-10. С ним тот же набор кандидатов дает лучший порядок. Если же нужный материал редко попадает даже в топ-100, второй шаг почти бесполезен. Тогда надо чинить сам поиск: разбиение на чанки, фильтры, поля, эмбеддинги и словарь синонимов.

Как посчитать окупаемость

Возьмите не синтетический набор, а живые запросы из логов за 2-4 недели. Для каждого запроса нужен эталон: какой документ должен попадать хотя бы в топ-3 или топ-5. Если команда не согласовала эталон заранее, спор быстро уйдет в ощущения.

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

  1. Сначала снимите базу без реранкера. Замерьте recall@k, долю запросов с правильным документом в рабочем топе, среднюю задержку и p95. Отдельно посчитайте цену на 1000 запросов.
  2. Потом подключите реранкер и прогоните тот же набор запросов без других изменений. Даже мелкая правка промпта или размера чанка ломает сравнение.
  3. Проверьте несколько размеров кандидатного списка, обычно 20, 50 и 100. На 20 реранкеру часто просто нечего спасать. На 100 он может поднять recall, но цена и задержка растут заметно быстрее.
  4. Переведите прирост качества в деньги. Если recall в рабочем топ-3 вырос на 4 п.п., а это убирает 30 ручных проверок на 1000 запросов, умножьте их на стоимость одной проверки. Туда же добавьте цену ошибок, если плохой поиск ведет к неверному ответу, повторному обращению или потере заявки.
  5. Сравните этот выигрыш с расходом на сам шаг. В расход входит вызов реранкера, лишняя нагрузка на CPU или GPU и цена задержки. Для внутреннего поиска лишние 150 мс могут быть терпимы, а для онлайн-чата те же 150 мс часто бьют по SLA и конверсии.

Полезно считать не только абсолютный рост recall, но и цену одного пункта прироста. Бывает, что переход с 0,78 до 0,82 окупается быстро, а рост с 0,82 до 0,83 уже слишком дорогой. В двухэтапном поиске это обычная история.

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

Пример со службой поддержки

Считайте цену без догадок
Сравнивайте модели по ставкам провайдеров и получайте B2B-инвойсинг в тенге.

В службе поддержки польза реранкера лучше всего видна на спорных запросах. Клиент пишет: "Я оплатил товар частично бонусами и картой. Как оформить возврат?" Вопрос короткий, но в нем есть важное исключение: общий порядок возврата не подходит, если часть суммы прошла по другой схеме оплаты.

Базовый поиск обычно цепляется за частые слова: "возврат товара", "оплата", "правила". В топе оказываются общая статья про возвраты, страница с условиями оплаты и стандартный шаблон ответа. Оператор открывает их по очереди и все равно не видит нужную строку про частичную оплату и пересчет суммы.

При этом нужный фрагмент часто не пропал совсем. Он лежит где-то в топ-50, но слишком низко. Причина простая: в нем меньше популярных слов и больше редких деталей. В двухэтапном поиске реранкер читает вопрос целиком и поднимает этот фрагмент в топ-3. Для оператора разница очень земная: не нужно просматривать несколько почти подходящих документов, ответ виден сразу.

На таком кейсе легко понять, где этот шаг оправдан. Если оператор и так ждет подсказку около 2 секунд, лишние 300-700 мс редко мешают работе. Зато система чаще кладет наверх точный документ, и сотрудник тратит меньше времени на ручную проверку. За смену это заметнее, чем кажется по одному запросу.

Но в чате с почти мгновенным ответом тот же шаг уже мешает. Если продукт обещает реакцию за 300-500 мс, даже хороший реранкер съедает слишком большой кусок бюджета по времени. Recall и задержка начинают спорить друг с другом: бот отвечает точнее, но пользователь чувствует паузу и считает ответ медленным.

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

Когда реранкер только тянет цену и задержку

Реранкер не нужен по умолчанию. Если первый поиск и так часто ставит нужный документ в первые позиции, второй шаг мало что меняет. Он просто добавляет еще один вызов модели, 100-400 мс задержки и лишние деньги на каждый запрос.

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

Плохой знак - слишком длинный список кандидатов. Команда берет топ-100 или топ-200, отдает это реранкеру и ждет заметного роста качества. На деле нужный документ и без того был в топ-5, а весь хвост только раздувает задержку и счет. Если прирост в рабочем топ-3 или топ-5 почти не двигается, этот шаг не окупается.

Есть и продуктовый момент. Не всякий поиск требует идеального порядка документов. В части сценариев пользователь ценит скорость выше, чем редкое улучшение качества. Если человек ищет короткую справку, внутренний регламент или номер формы, ответ за 0,7 секунды часто лучше, чем чуть более точный ответ за 1,8 секунды.

Реранкер особенно плохо выглядит там, где цена ошибки низкая. Если пользователь может быстро переформулировать запрос, открыть второй документ или нажать новый поиск без серьезного ущерба, команда спокойно живет с частью промахов. Нет смысла платить за дорогую точность, если промах обходится дешево.

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

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

Где команды ошибаются в тестах

Сравните провайдеров в одном месте
Пробуйте OpenAI, Anthropic, Google, DeepSeek и другие модели через единый эндпоинт.

Чаще всего команда смотрит на средний recall и радуется росту на пару пунктов. Проблема в том, что среднее скрывает самые неприятные запросы. Именно в хвосте сидят опечатки, короткие фразы, редкие термины и запросы с лишними словами. Если реранкер помогает только на простых запросах, цифра растет, а человек в работе почти ничего не замечает.

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

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

Синтетические вопросы тоже часто портят картину. Они слишком чистые. Пользователи не пишут как в датасете. Они пишут "не открывается счет", "где отменить заявку", "почему не виден платеж за вчера". На таких формулировках эффект может быть совсем другим. Если у вас есть логи запросов, берите их. Если данные чувствительные, сначала маскируйте личную информацию, а потом собирайте тест.

Команды нередко смешивают качество поиска с качеством итогового ответа модели. Это разные вещи. Реранкер может поднять нужный документ выше, но генерация не изменится, если модель ответа плохо читает контекст. Бывает и наоборот: ответ стал лучше только потому, что вы взяли другую модель, а поиск остался прежним.

Поэтому проверку лучше делить на два слоя. Сначала мерить сам поиск: recall@k, позицию нужного документа и долю промахов. Потом отдельно мерить итоговый ответ по тем же запросам. Для обоих слоев полезно смотреть не только на среднее, но и на p95 по задержке, а цену считать на тысячу запросов, а не на один удачный пример.

Последняя ловушка всплывает уже после запуска. В тесте команда не считает кеш, батчинг и очередь, а в рабочей системе получает другую задержку. Один и тот же реранкер может добавлять 40 мс в спокойный час и 250 мс в пик, когда запросы ждут своей очереди. Если вы работаете через общий LLM-шлюз или shared GPU, это особенно заметно. Только после такого теста видно, приносит ли шаг реальную пользу или просто делает поиск дороже и медленнее.

Быстрый чек перед запуском

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

Реранкер стоит включать не по ощущению, а после короткой проверки на своих данных. Если у вас нет набора реальных запросов с известным правильным ответом, почти любой вывод будет случайным. Для первого прогона обычно хватает 100-300 запросов, если они взяты из живого трафика, а не придуманы в таблице за полчаса.

Хороший тест смотрит не только на качество. Пользователь не видит ваш recall отдельно от времени ответа и цены. Если ответ приходит на 700 мс позже и обходится вдвое дороже, прирост в пару процентов может ничего не значить.

Перед запуском достаточно проверить пять вещей:

  1. Соберите набор запросов с эталонными документами или правильными ответами. Лучше, если там будут короткие, длинные, расплывчатые и действительно трудные запросы.
  2. Зафиксируйте предел задержки на один запрос. Для внутреннего поиска это одно число, для чата поддержки или кассового сценария - совсем другое.
  3. Считайте полную цену цепочки, а не только цену реранкера. В расчет входят поиск, реранкер, генерация и повторные вызовы, если они бывают.
  4. Прогоните хотя бы 2-3 размера кандидатного списка. Например, топ-20, топ-50 и топ-100.
  5. Разбейте результаты по типам запросов. Часто реранкер лучше работает на длинных вопросах с контекстом и почти бесполезен на простых навигационных запросах.

Небольшой пример. Команда тестирует поиск по базе поддержки и видит средний прирост recall@10 на 4%. Звучит неплохо. Но после разбивки выясняется, что почти весь выигрыш пришелся на редкие многословные вопросы, а на частых запросах вроде "сбросить пароль" реранкер ничего не меняет. В таком случае его разумнее включать не для всех запросов, а по простому правилу маршрутизации.

Если вы сравниваете несколько реранкеров и моделей через единый OpenAI-совместимый шлюз вроде AI Router на airouter.kz, такой тест проще держать чистым. Можно менять маршрут или модель, не переписывая SDK, код и промпты, и легче увидеть, где выигрыш дал именно реранкер, а где другая часть пайплайна.

После этого решения обычно становятся спокойнее. Либо шаг окупается на конкретных сценариях, либо вы честно убираете его и не платите за лишние миллисекунды.

Что делать дальше

Не ставьте реранкер первым шагом по умолчанию. Сначала проверьте базу: как вы режете документы на чанки, какие метаданные даете каждому фрагменту и какой топ-k берете на первом поиске. Очень часто recall растет уже на этом этапе, а задержка почти не меняется.

Если после такой правки ответы все еще промахиваются, подключайте реранкер точечно. Обычно он лучше всего окупается на длинных, шумных и двусмысленных запросах, где первый поиск приносит много "почти подходящих" фрагментов. Простые запросы вроде номера договора, названия тарифа или точной ошибки лучше вести по короткому пути без лишнего шага.

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

Перед полным запуском нужен тест на живом потоке. Подойдет теневой прогон, когда новая схема считает результат параллельно, но не влияет на пользователя. Если трафика хватает, делайте A/B-тест и смотрите не только на среднюю метрику, но и на хвост задержки, цену на 1000 запросов и долю случаев, где реранкер правда меняет рабочий топ.

Решение лучше свести к простой таблице. Обычно хватает четырех колонок: прирост качества на ваших задачах, добавка к p95 или p99 задержки, цена одного запроса или 1000 запросов и риск ошибки, если реранкер выключить.

Такая таблица быстро отрезвляет. Если реранкер дает плюс 6-8% к recall на сложных кейсах и добавляет 150 мс только для части трафика, его стоит оставить. Если он поднимает метрику на доли процента, но делает поиск заметно медленнее и дороже, этот шаг лучше убрать и вложиться в чанки, фильтры и топ-k.