Гайд · TNWS AI

Как измерить recall HNSW в Azure AI Search через exhaustive KNN

6 мин—

Точный baseline exhaustive:true, Recall@k, стабильный набор запросов и диагностика trade-off качества и задержки.

Задача и применимость

Актуальный русскоязычный запрос: «как измерить recall HNSW Azure AI Search exhaustive». Официальная документация Microsoft проверена 19 сентября 2026 года. Azure AI Search REST API 2026-04-01; поле проиндексировано HNSW, один корпус и одна модель для сравнения двух поисковых режимов.

Задача здесь — выполнить и проверить конкретную операцию в Azure AI Search. Образцовые значения вроде ru-kb, p1 и policy-2026-01 принадлежат тестовому корпусу, а не обязательным именам в вашем сервисе. У вас должны быть полномочия на указанную операцию; для теста можно использовать административный ключ на доверенном сервере, но в пользовательском браузере нужен защищённый серверный посредник. Сначала снимите baseline по контрольному запросу и набору документов, затем меняйте только одну настройку за раз.

Что подтверждает документация

Опциональный vectorQueries.exhaustive вызывает exhaustive KNN на этапе запроса даже для HNSW-поля. HNSW предназначен для приближённого поиска; отличие списка ID от exact baseline измеримо. Качеством нельзя считать разницу @search.score между различными алгоритмами без проверки самих релевантных источников.

Это не обещание одинакового ранжирования для любого русского корпуса. Результат embedding зависит от deployment, подготовки текста, chunking, обновлений модели и состава индекса. Доступность предварительных функций и ограничения сверяйте с документацией и настройками собственного сервиса; цена и длительность операций здесь намеренно не указаны, потому что они не следуют из поискового ответа. Отделяйте успешный HTTP-запрос от оценки полезности найденного фрагмента.

Пошаговое выполнение

  1. Подготовьте хотя бы набор независимых русских вопросов и один embedding на вопрос; не изменяйте корпус между двумя запросами.
  2. Для каждого вопроса получите top-10 с exhaustive:true; сохраните IDs как точный baseline на заданном наборе данных.
  3. Выполните тот же запрос без exhaustive, сохраняя k, fields, filter и select.
  4. Посчитайте пересечение top-10 IDs / 10 для каждого вопроса и среднее по набору; отдельно замерьте p95 задержки.
  5. Если recall низок, изучите параметры HNSW и фильтрацию, а затем повторите тест на новом индексе вместо тюнинга по одному примеру.

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

Готовый REST-шаблон

POST /indexes/ru-kb/docs/search?api-version=2026-04-01
{"select":"id,title","vectorQueries":[{"kind":"vector",
"vector":"<полный массив embedding>","fields":"contentVector",
"k":10,"exhaustive":true}]}

# В реальном JSON замените строку <...> массивом чисел;
# повторите запрос с exhaustive:false для HNSW baseline.

Подставьте своё имя сервиса в https://<service>.search.windows.net, передайте Content-Type: application/json и авторизацию выбранным поддерживаемым способом. Демонстрационный массив из трёх чисел или строка <embedding массива> — только описание формы; они не являются реальным embedding для поля с 1536 измерениями. Перед отправкой проверьте JSON, размерность и отсутствие ключа в клиентском коде.

Входные данные и ожидаемый результат

Вход: десять размеченных вопросов, по одному vector из 1536 чисел; для вопроса Q1 точный список A,B,C,D,E,F,G,H,I,J, ANN список A,B,C,D,E,F,G,H,X,Y. Ожидаемый Recall@10 этого вопроса по совпадению IDs — 8/10=0,8. Это показатель совпадения с точным kNN, а не доказательство, что сами документы отвечают человеку.

Ожидаемый ID — проверяемая гипотеза на подготовленном тестовом наборе. При другом корпусе и другом embedding нельзя честно обещать конкретный score и порядок результатов. Сохраняйте как входное содержимое, так и текст возвращённого фрагмента: найденный ID без исходного подтверждения не годится для публикации ответа от имени компании.

Разбор и границы применения

Формула по IDs проста, но интерпретировать её надо аккуратно. Exact nearest neighbors могут быть нерелевантны: если embedding-модель не понимает предметную область, высокий технический recall будет соседствовать с плохим пользовательским ответом. Дополните сравнение размеченными релевантными документами и ручной оценкой ответа. Разделяйте три метрики: ANN-vs-exact Recall@10, долю полезных документов по ручной разметке и latency. Две группы запросов — короткие точные артикулы и длинные разговорные вопросы — часто ведут себя по-разному, поэтому среднее без сегментов скрывает проблему. Если включён preFilter, одинаковое значение filter обязательно в обеих ветках, иначе точный поиск станет другой задачей. Не смешивайте score и rerankerScore, когда к запросу добавлен semantic ranker. Для p95 используйте многократные вызовы и одинаковый сервисный регион; единичный замер зависит от кэша и нагрузки. Механизм exhaustive может быть дорогим на большом корпусе, поэтому используйте его как проверку на контролируемой выборке, а не обещание всегда включать в production. Результаты эксперимента храните с датой, API-версией, ревизией индекса и embeddings.

Практический контроль именно этой задачи

Для честного измерения создайте таблицу из question_id, ожидаемых документов, raw query vector и документов exact top-10. При каждом эксперименте прикрепляйте хеш списка индексированных id: незаметное изменение корпуса делает сравнение недействительным. Пересечение множеств топ-10 не учитывает порядок, поэтому дополните его метрикой, чувствительной к позиции первых релевантных источников, если важна первая цитата. Нельзя сравнивать один exact запуск утром с ANN запуском после добавления документов вечером. Запускайте пары запросов чередованием, иначе разная нагрузка и кэш исказят p95. Высокий overlap на коротких одинаковых фразах не означает удовлетворительного поиска с отрицанием, аббревиатурами и длинными инструкциями. Сегментируйте набор по типу вопроса. Если точный baseline неверен с точки зрения эксперта, сначала меняйте модель или формирование фрагментов; увеличение efSearch в HNSW не решит несовместимое смысловое пространство. Сохраняйте как индивидуальные ошибки, так и агрегаты.

Критерии проверки

  • Оба режима получают идентичный vector, k=10 и filter.
  • Recall@10 рассчитан по IDs для каждого вопроса.
  • Ручная релевантность оценивается отдельно от ANN recall.
  • p95 сравнивается на одном размере корпуса.

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

Типичные ошибки и что не делать

  • Называть совпадение ID оценкой фактической истинности.
  • Сравнивать запросы с разными k или фильтрами.
  • Измерять только одну latency.
  • Постоянно включать exhaustive без проверки нагрузки.

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

FAQ

Что делает exhaustive:true?

Включает точный перебор соседей при данном запросе.

Как считается Recall@10 здесь?

Доля общих IDs ANN и exact списков top-10.

Может ли exact поиск давать нерелевантный ответ?

Да, качество embedding и корпуса нужно проверять отдельно.

Официальные источники

Частые вопросы

Что делает exhaustive:true?

Включает точный перебор соседей при данном запросе.

Как считается Recall@10 здесь?

Доля общих IDs ANN и exact списков top-10.

Может ли exact поиск давать нерелевантный ответ?

Да, качество embedding и корпуса нужно проверять отдельно.

Читайте также

Комментарии

Пока тихо. Скажите первое слово