Гайд · TNWS AI
Как настроить HNSW Vespa: links, insert и exploreAdditionalHits
Индексные и запросные параметры HNSW в Vespa с измерением Recall@10, памяти, скорости загрузки и p95.
Какую задачу решаем и где применимо
Русскоязычный поисковый запрос: «как настроить HNSW Vespa exploreAdditionalHits». Материал проверен по официальной документации Vespa, актуальной на 19 сентября 2026 года. Для Vespa с attribute | index на tensor-поле. max-links-per-node и neighbors-to-explore-at-insert относятся к построению графа, hnsw.exploreAdditionalHits — к поисковому запросу. Тестовые значения в шаблоне не являются рекомендуемыми глобальными настройками.
HNSW — приближённый поиск: увеличение числа связей и explored neighbors при вставке обычно улучшает качество графа ценой памяти или скорости индексирования. hnsw.exploreAdditionalHits увеличивает число узлов, рассматриваемых во время поиска помимо totalTargetHits; это trade-off между recall и задержкой, который можно проверить без превращения всего корпуса в exact.
До начала эксперимента подготовьте маленький набор документов с известными source_id и один отрицательный пример. Сохраните версию schema, embedding-модели, набор входных вопросов и ожидаемые IDs: так результат можно воспроизвести после обновления системы, а не оценивать по одному удачному ответу. Все значения для маленького tensor в шаблоне — иллюстрация контрактов, не показатели качества модели.
Пошаговое выполнение
- Сохраните baseline: размер корпуса, параметры графа, Recall@10, p95, память и скорость feed.
- Создайте экспериментальную конфигурацию HNSW, не затрагивая рабочий индекс без плана отката.
- Разверните схему и дождитесь готовности индекса после изменений, требующих перестроения.
- При неизменном графе прогоните несколько значений
hnsw.exploreAdditionalHitsс равными query vectors. - Выберите профиль по допустимой потере recall и бюджету p95, затем зафиксируйте версию конфигурации.
Эти шаги предполагают доступ к собственному тестовому приложению Vespa. Для Vespa Cloud и самостоятельной установки способы деплоя отличаются; не угадывайте имена кнопок консоли. Используйте показанный интерфейс schema, YQL или CLI, сверяя конкретное окружение и permissions с документацией. При деплое сохраняйте предыдущее определение, чтобы сопоставить результаты и откатить неудачное изменение без смешения двух причин.
Готовый шаблон
field embedding type tensor<float>(x[3]) {
indexing: attribute | index
attribute { distance-metric: angular }
index { hnsw {
max-links-per-node: 16
neighbors-to-explore-at-insert: 100
} }
}
select source_id from article where {totalTargetHits:10,hnsw.exploreAdditionalHits:20}nearestNeighbor(embedding,q)
Шаблон адаптируйте к своей размерности и именам документов. Если он содержит ручной трёхмерный вектор, он полезен для smoke-теста схемы и синтаксиса, но не заменяет настоящий embedding вопроса. Секреты провайдера, токены Vespa и данные закрытых клиентов не вставляйте ни в публичный prompt, ни в статью, ни в логи запроса.
Конкретный вход и ожидаемый выход
Вход: 100 проверочных вопросов и exact top-10 IDs на неизменном corpus snapshot. Сравните профили exploreAdditionalHits=0 и 20: ожидаемый выход — две таблицы фактических Recall@10, p95 и memory, а не заранее объявленная победа большего значения.
Отдельно учитывайте скорость загрузки: улучшение графа может сделать ежедневное обновление корпуса слишком долгим, даже если query p95 устраивает. Высокая размерность и число документов усиливают влияние памяти, а маленький тест из трёх векторов этого не выявит. Для строгих фильтров поведение отличается от глобального поиска; положите в gold set редких и крупных tenant. Подстройка только параметров запроса не компенсирует плохой embedding или неверную метрику. Измеряйте холодную и прогретую нагрузку при рабочей concurrency и документируйте порог приемлемости до эксперимента. Если после настройки recall резко вырос, проверьте, что exact baseline и список документов остались прежними.
Сравнение сценариев
| Параметр | Момент действия | Основная цена |
|---|---|---|
| max-links-per-node | построение графа | память и размер графа |
| neighbors-to-explore-at-insert | индексирование | скорость feed |
| hnsw.exploreAdditionalHits | время запроса | поисковая задержка |
Вывод: сопоставляйте эти варианты на своих вопросах и зафиксированном корпусе. Изменение конфигурации имеет смысл только если оно улучшает оговорённую метрику и укладывается в допустимую задержку.
Проверка результата
- Одинаковый snapshot и набор вопросов в каждом прогоне.
- Recall вычислен против exact на ID.
- p95 и скорость feed измерены отдельно.
- Новые параметры не выдаются за универсальные значения.
Успех означает прохождение всех перечисленных пунктов на положительных и отрицательных кейсах. Снимите фактические IDs, число hits и latency до и после изменения; если есть LLM-ответ, проверьте цитаты вручную. Пустой результат из-за ошибки типов, времени ожидания, прав доступа или отсутствующей записи нельзя выдавать за низкую релевантность. Удобно хранить отдельный отчёт по каждым case_id, иначе невозможно обнаружить регрессию на редких формулировках.
Типичные ошибки: чего не делать
- Повышать три параметра одновременно.
- Публиковать benchmark с тремя документами как production-результат.
- Менять граф без оценки памяти и времени перестроения.
Не исправляйте нерелевантную выдачу произвольным повышением top-k: сперва отделите ошибку модели, схемы, фильтра и ранжирования. Не отключайте проверку tenant ради красивого теста. Не делайте вывод о производительности на крошечном демонстрационном корпусе; проверяйте рабочий объём, конкурентную нагрузку и p95, а также расход памяти/скорость обновлений там, где они существенно меняются.
FAQ
Что менять без перестройки графа?
Поисковый hnsw.exploreAdditionalHits задают в запросе.
Больше links всегда лучше?
Не обязательно: растут затраты; сравнивайте качество и ресурсы.
Чем проверить эффект?
Recall@k относительно exact и latency при целевой нагрузке.
Официальные источники
Частые вопросы
Что менять без перестройки графа?
Поисковый `hnsw.exploreAdditionalHits` задают в запросе.
Больше links всегда лучше?
Не обязательно: растут затраты; сравнивайте качество и ресурсы.
Чем проверить эффект?
Recall@k относительно exact и latency при целевой нагрузке.
Читайте также
Как фильтровать векторный поиск Vespa по tenant без утечки в RAG
YQL-фильтр вместе с nearestNeighbor, серверный tenant, pre-filtering, отрицательный ACL-тест и проверка полного top-k.
Как хранить chunks для RAG в Vespa с проверяемыми source_id
Схема chunk-документов, parent ID, versioned embeddings, готовый prompt и тест цитат по исходным фрагментам.
Как измерить Recall@10 ANN-поиска Vespa через exact baseline
Два сопоставимых nearestNeighbor-запроса с approximate:false, формула Recall@10 и ограничения exact baseline.
Комментарии
Пока тихо. Скажите первое слово