Гайд · TNWS AI
Как измерить hit rate и MRR поиска в LlamaIndex RetrieverEvaluator
Размеченный вопрос, expected_ids и оценка позиции релевантного узла до тестирования ответов генератора.
Задача и применимость
Поисковый запрос: «как измерить hit rate MRR LlamaIndex RetrieverEvaluator». Факты и синтаксис сверены с официальной документацией LlamaIndex Framework для Python 19 сентября 2026 года. Пример предназначен для актуального Python-пакета llama-index и указанных в коде интеграций; доступность конкретной модели и конфигурация её провайдера зависят от среды запуска. Если код обращается к embeddings или LLM, ключ задаётся через серверное окружение и здесь не приводится. Точный релиз локально не установлен, поэтому перед рабочим запуском фиксируйте номер установленной версии и повторите тест на ней.
RetrieverEvaluator.from_metric_names принимает имена метрик, например mrr и hit_rate, и объект retriever. Метод evaluate получает строку query и expected_ids релевантных node IDs. Руководство также показывает aevaluate_dataset для набора запросов и ручное составление датасета. Эти метрики оценивают retrieval, не фактическую точность LLM.
Нумерованный порядок работы
- Сохраните ID узла, содержащего ответ, до запуска оценки; ID документа и node ID могут отличаться.
- Постройте retriever с явным similarity_top_k и составьте тестовый вопрос.
- Создайте RetrieverEvaluator с mrr и hit_rate и передайте expected_ids.
- Повторите на вопросе с другим релевантным узлом и на отрицательном случае.
- Разберите позиции релевантных узлов и только после этого меняйте chunking или embeddings.
Готовый шаблон Python
from llama_index.core import Document, VectorStoreIndex
from llama_index.core.evaluation import RetrieverEvaluator
index = VectorStoreIndex.from_documents([
Document(text="Возврат по R7: 14 дней.", id_="R7"),
Document(text="Доставка по D9: по будням.", id_="D9"),
])
retriever = index.as_retriever(similarity_top_k=2)
question = "Сколько дней на возврат по R7?"
seen = retriever.retrieve(question)
# ID эталонного узла размечают ВРУЧНУЮ по содержимому, не выбирают top-1.
expected_ids = [n.node.node_id for n in seen if "14 дней" in n.node.get_content()]
evaluator = RetrieverEvaluator.from_metric_names(
["mrr", "hit_rate"], retriever=retriever)
print(evaluator.evaluate(query=question, expected_ids=expected_ids))
Код ниже в статье предназначен для тестовых источников без персональных сведений. Вызовы SDK не выполнялись в данном окружении с реальной моделью; синтаксис Python проверен отдельно. Не переносите вывод демонстрационного эксперимента на любой корпус и любого провайдера без повторной проверки.
Пример входа и ожидаемого результата
Вход: вопрос про R7 и два узла, один про возврат, второй про доставку. Ожидается попадание вручную размеченного узла в выдачу; hit rate отмечает наличие, MRR учитывает его позицию. В коде фильтр по содержимому демонстрирует форму ID, но для честной оценки эталоны надо разметить до просмотра выдачи, иначе метрика будет завышена.
Сохраните входные файлы, идентификаторы документов и ожидаемое утверждение в отдельном проверочном наборе. При неуспехе выделяйте слой ошибки: чтение источника, преобразование в nodes, получение embedding, поиск, синтез ответа или UI. Правильная форма ответа ещё не гарантирует правильного происхождения сведений.
Диагностика и границы решения
Главная ловушка evaluation — утечка ответа при создании эталона. Если брать expected_ids прямо из первых результатов retriever, он гарантированно проверяет самого себя и может получить высокий score при плохой релевантности. В рабочем наборе человек читает исходные узлы независимо от поиска и связывает вопрос с корректным ID заранее. MRR отражает позицию первого релевантного результата и полезен, когда генератор видит мало документов; hit rate говорит о факте попадания в top_k. Увеличение k почти всегда повышает шанс попадания, но может ухудшить итоговый ответ из-за шумного контекста. Фиксируйте версию корпуса, модель embeddings и способ разбиения для каждого отчёта. Если два узла вместе нужны для ответа, дополнительные метрики полноты или ручная проверка необходимы.
Дополнительный проверочный сценарий
Сформируйте группы вопросов: точные коды, перефразировки, отрицания, вопросы об исключениях и запросы без ответа. По каждой группе сохраните список node IDs и проверьте доступность источника для данного пользователя. Разница между 0.8 и 0.9 на пяти вопросах не является серьёзным доказательством улучшения; нужен отложенный размеченный набор. При смене chunk_size старые node IDs могут поменяться, поэтому переотметьте соответствие узлов, не переписывая сами ожидаемые факты задним числом. После измерения retrieval оцените отдельно, правильно ли генератор воспользовался найденным фрагментом; метрики поиска не могут гарантировать правдивость ответа. Не показывайте в пользовательском интерфейсе сырые внутренние ID без привязки к документу.
Критерии проверки
- Эталон размечен независимо от результата.
- Релевантный node ID попадает в top_k.
- Позиция и наличие интерпретированы раздельно.
Помимо положительного теста проводите отрицательный: отсутствующий факт, чужой документ, старая редакция либо несовместимая модель — в зависимости от задачи. Если одна проверка не проходит, не объявляйте настройку готовой. При работе с чужими источниками доступ к исходнику и цитате должен проверяться отдельно от поисковой релевантности.
Типичные ошибки и что не делать
- Не формировать expected_ids из результатов тестируемого retriever.
- Не считать hit_rate проверкой ответа LLM.
- Не сравнивать разные версии корпуса как одинаковый эксперимент.
Не передавайте ключи, личные документы и приватные пути в опубликованный пример или сторонний trace без оценки прав доступа. Не исправляйте отсутствие нужного текста одним только промптом: генератор не восстановит источник, который не загрузили или не нашли. При смене модели либо backend повторяйте тест на зафиксированном наборе вопросов.
FAQ
Что передают в expected_ids?
ID релевантных узлов.
Что измеряет MRR?
Позицию первого релевантного узла.
Зачем отложенный набор?
Чтобы настройка не переобучилась на тех же вопросах.
Официальные источники
Частые вопросы
Что передают в expected_ids?
ID релевантных узлов.
Что измеряет MRR?
Позицию первого релевантного узла.
Зачем отложенный набор?
Чтобы настройка не переобучилась на тех же вопросах.
Читайте также
Как ограничить размер пакета при индексации в LlamaIndex VectorStoreIndex
insert_batch_size при from_documents: контролируем память и задержки загрузки, не путая пакет с размером чанка.
Как обновить одну редакцию документа в LlamaIndex без смешивания версий
Стабильный id_, update_ref_doc и контроль старого и нового правила в поисковой выдаче.
Как показывать ответ LlamaIndex по мере генерации через streaming
streaming=True, response_gen и проверка полного ответа, отмены запроса и ограничений streaming-модели.
Комментарии
Пока тихо. Скажите первое слово