Технологии

«Решить, что выбросить, может значить больше, чем правильно упорядочить»: вышла библиотека jev-reranker для фильтрации контекста

Yuichi Tateno (hotchpotch) опубликовал Python-библиотеку jev-reranker, которая использует Jev от TypeSafe.AI, чтобы переранжировать результаты поиска и отсеивать документы, вряд ли полезные для ответа. На NanoHotpotQA фильтр релевантности убрал около 92% документов-кандидатов и при этом показал nDCG@10 0.975 против 0.833 у гибридного поиска: меньший набор не дал потерь по этой метрике.

«Решить, что выбросить, может значить больше, чем правильно упорядочить»: вышла библиотека jev-reranker для фильтрации контекста

Что вышло

19 сентября 2026 года в блоге Hugging Face вышла статья о новой библиотеке: jev-reranker — это Python-библиотека, которая использует Jev от TypeSafe.AI, чтобы переранжировать результаты поиска и отфильтровывать документы, вряд ли помогающие ответить на вопрос. Запись помечена как Community Article, то есть это публикация автора библиотеки, а не корпоративное объявление Hugging Face. Пакет лежит на PyPI, где на момент проверки актуальной версией была 0.1.2, а исходники и скрипт оценки — в открытом репозитории на GitHub.

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

Как это выглядит в коде

Установка описана одной командой — uv add jev-reranker, после чего запрос и найденные документы передаются в объект JevReranker вместе с ключом API, а вызов relevance_rerank принимает порог. Автор показывает это на бытовом примере: вопрос «сколько у меня времени на возврат онлайн-заказа в ACME Shop» и пять пассажей. Два пассажа, которые действительно отвечают на вопрос, получают оценки 0.98 и 0.97 и остаются; три остальных — про возврат покупки в магазине, про годовую гарантию на ремонт и про другой магазин — выглядят похоже по теме, но не отвечают на заданный вопрос, набирают меньше порога 0.2 и удаляются.

Чем фильтрация отличается от ранжирования

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

Результаты на NanoHotpotQA

Оценка проведена на NanoHotpotQA — компактном наборе для retrieval, сэмплированном из мультихопового HotpotQA. Базовая линия — гибридный поиск: BM25 вместе с плотным поиском, где для плотной части использована модель harrier-oss-v1-270m, а в качестве кандидатов взяты топ-100 документов на запрос. Прогон использовал все 50 запросов сплита NanoHotpotQA из NanoBEIR-en и полные пулы кандидатов, по 100 документов на запрос, а оба метода Jev считались в режиме listwise.

У гибридного поиска nDCG@10 составил 0.833 при 100 сохранённых документах на запрос, то есть без отсева. Переранжирование тем же Jev подняло метрику до 0.969, сохранив все 100 документов. Фильтр релевантности дал 0.975 и оставил в среднем 7.62 документа на запрос, отбросив 92.38% кандидатов.

Важная деталь честности измерения: фильтр сохранил все 97 размеченных положительных документов, которые присутствовали в пулах кандидатов, тогда как ещё трёх положительных там не было уже до переранжирования. Оценки релевантности дали одинаковый nDCG@10 до и после пороговой фильтрации, поэтому меньший сохранённый набор в этом прогоне не стоил потерь по метрике. Порог настраивается — документ сохраняется при score не ниже порога: при 0.05 сохранится больше, при 0.5 отсеется больше, а подходящий отсекающий уровень автор советует подбирать на собственных данных. Числа получены на версии jev-1.13.0, и обновление модели может изменить как оценки, так и поведение выбранного порога.

Зачем обёртка вокруг API

Вызывать Jev напрямую достаточно для базовой идеи, а библиотека добавляет практические части, которые всплывают в реальном retrieval-конвейере. Есть два способа укладки входа: listwise помещает запрос и документы-кандидаты в один контекст, pointwise отправляет запрос с каждым документом отдельно. Библиотека поддерживает оба; в сравнениях автора listwise был в целом быстрее и давал лучшие результаты, поэтому выбран режимом по умолчанию, хотя другие задачи могут предпочесть pointwise.

Длинные входы требуют аккуратности, особенно когда listwise складывает много документов в один запрос: здесь важен бюджет Jev в 32k на состояние плюс самый длинный вопрос, и библиотека делит запросы на группы по подсчёту символов или токенов, чтобы уложиться в заданные бюджеты. Точный предварительный подсчёт длины упирается в отсутствие публичного токенизатора Jev: как отмечает автор, он такого токенизатора или API для точного preflight пока не нашёл, поэтому библиотека работает с оценками. Кроме того, поддерживаются ограниченная конкурентность с настраиваемым числом запросов в полёте и повторы с ожиданием при транзитных сбоях и срабатывании лимитов.

Почему это направление автору интересно

Между просьбой к языковой модели принимать каждое решение и обучением отдельной модели под каждую задачу есть полезное пространство. Языковая модель может быть медленнее, чем нужно приложению, а специализированная модель требует данных, усилий по обучению и людей, способных её сопровождать; подход Jev к структурированным решениям попадает в промежуток между ними. Возможность управлять суждением через инструкции автор считает особенно привлекательной именно для retrieval: то, что должно стоять первым, зависит от контекста, и широко релевантный теме пассаж может остаться бесполезным для ответа, который должно выдать приложение. Поэтому он хочет видеть больше моделей в этом направлении — общих моделей для структурированных решений, которые практично разместить внутри приложения.

Границы применимости

Это оценка автора библиотеки на одном публичном сплите, а не независимое сравнение. Ожидание, что меньший объём менее отвлекающего материала поможет модели меньше галлюцинировать, автор прямо помечает как ожидание о дальнейшем использовании, а не как измеренный результат: сама оценка измеряет retrieval, а не качество финального ответа. Для сравнения со своим стеком он приложил скрипт оценки и упоминает CrossEncoder bge-reranker-v2-m3 как ориентир для тех, кто уже его использует.

Отдельно стоит держать в голове статус публикации: материал вышел как Community Article в блоге Hugging Face, то есть перед нами первичная публикация автора библиотеки, а не анонс платформы. Практический вывод для RAG-конвейеров здесь не в рекорде метрики, а в смене акцента: если генератору передаётся меньший, но проверенный набор документов, порог фильтрации становится таким же инженерным параметром, как и выбор модели поиска, и его поведение нужно держать под наблюдением при обновлении версии модели.

Первоисточники

  1. Hugging Face Blog (Yuichi Tateno, hotchpotch) — «Introducing jev-reranker: Reranking and Relevance Filtering for RAG», 19 сентября 2026 (Community Article)
  2. GitHub — репозиторий hotchpotch/jev-reranker (исходный код и скрипт оценки)
  3. PyPI — пакет jev-reranker (версия 0.1.2 на момент проверки)
  4. Hugging Face — карточка модели BAAI/bge-reranker-v2-m3 (ориентир, упомянутый автором)