Гайд · TNWS AI
Как создать tensor-поле embeddings в Vespa и проверить размерность
Схема Vespa для tensor<float>, размерность, индекс HNSW и воспроизводимая проверка совместимости embeddings с запросами.
Какую задачу решаем и где применимо
Русскоязычный поисковый запрос: «как создать tensor поле embedding Vespa». Материал проверен по официальной документации Vespa, актуальной на 19 сентября 2026 года. Подходит приложению Vespa с собственной схемой документов и заранее выбранной embedding-моделью. В примере размерность 3 нужна только для наглядного ручного теста; в боевом проекте берите действительную размерность модели, а не копируйте тройку.
Tensor tensor<float>(x[3]) задаёт фиксированную ось. attribute хранит поле для вычисления расстояния; добавление index включает HNSW-поиск по этому полю. distance-metric: angular выбирается на уровне attribute. В отличие от обычного текстового индекса, значение поля должно быть числовым вектором, созданным одной и той же моделью и предобработкой для документов и вопросов.
До начала эксперимента подготовьте маленький набор документов с известными source_id и один отрицательный пример. Сохраните версию schema, embedding-модели, набор входных вопросов и ожидаемые IDs: так результат можно воспроизвести после обновления системы, а не оценивать по одному удачному ответу. Все значения для маленького tensor в шаблоне — иллюстрация контрактов, не показатели качества модели.
Пошаговое выполнение
- Зафиксируйте версию модели, её реальную dimension и правило нормализации текста в manifest корпуса.
- Создайте схему
articleс документными полямиsource_id,text,embedding; текст и источник сохраняйте отдельно от вектора. - Добавьте
attribute | indexдля tensor и явно укажите distance metric. Разворачивайте изменение сначала в тестовом приложении. - Загрузите два canary-документа длины 3, затем попробуйте документ длины 2 и запишите ошибку как отрицательный тест.
- Выполните nearestNeighbor-запрос с query tensor той же длины и проверьте source_id результата.
Эти шаги предполагают доступ к собственному тестовому приложению Vespa. Для Vespa Cloud и самостоятельной установки способы деплоя отличаются; не угадывайте имена кнопок консоли. Используйте показанный интерфейс schema, YQL или CLI, сверяя конкретное окружение и permissions с документацией. При деплое сохраняйте предыдущее определение, чтобы сопоставить результаты и откатить неудачное изменение без смешения двух причин.
Готовый шаблон
schema article {
document article {
field source_id type string { indexing: summary | attribute }
field text type string { indexing: summary | index }
field embedding type tensor<float>(x[3]) {
indexing: attribute | index
attribute { distance-metric: angular }
}
}
rank-profile semantic {
inputs { query(q) tensor<float>(x[3]) }
first-phase { expression: closeness(field, embedding) }
}
}
Шаблон адаптируйте к своей размерности и именам документов. Если он содержит ручной трёхмерный вектор, он полезен для smoke-теста схемы и синтаксиса, но не заменяет настоящий embedding вопроса. Секреты провайдера, токены Vespa и данные закрытых клиентов не вставляйте ни в публичный prompt, ни в статью, ни в логи запроса.
Конкретный вход и ожидаемый выход
Вход: refund:1 с embedding [0.1,0.2,0.3], shipping:1 с [0.7,0.0,0.2]; запрос также содержит три числа. Ожидается принимаемая схема, сохраняемые оба source_id и результат запроса без ошибки типа. Этот игрушечный вектор не обещает конкретного семантического порядка: он только проверяет контракт типов.
Если интерфейс поставщика embedding-модели возвращает иной размер, не меняйте ось ради одного документа. Спланируйте новое versioned поле либо отдельную схему, пересчитайте весь корпус, а переключение выполняйте только после сравнения качества. Нельзя смешивать русскоязычные и англоязычные кодировки текста с разными шаблонами query: и passage: у модели, если её инструкция различает эти режимы. Числовое совпадение dimension ещё не означает совместимости геометрии. Обязательный canary должен подтверждать и доступность поля, и ожидаемую релевантность на разметке. Следите отдельно за расходом памяти: сам tensor, HNSW-граф и сохранённый текст имеют разные профили использования ресурсов.
Проверка результата
- Реальная размерность в manifest равна типу
x[n]и длине каждой записи. - Неверная длина обнаруживается до загрузки всего датасета.
- Query tensor определён в rank-profile с тем же типом.
- Исходный текст и source_id доступны независимо от embedding.
Успех означает прохождение всех перечисленных пунктов на положительных и отрицательных кейсах. Снимите фактические IDs, число hits и latency до и после изменения; если есть LLM-ответ, проверьте цитаты вручную. Пустой результат из-за ошибки типов, времени ожидания, прав доступа или отсутствующей записи нельзя выдавать за низкую релевантность. Удобно хранить отдельный отчёт по каждым case_id, иначе невозможно обнаружить регрессию на редких формулировках.
Типичные ошибки: чего не делать
- Подставлять размерность популярной чужой модели по памяти.
- Смешивать старую и новую версии модели в одном поле.
- Считать успешную загрузку доказательством правильного порядка выдачи.
Не исправляйте нерелевантную выдачу произвольным повышением top-k: сперва отделите ошибку модели, схемы, фильтра и ранжирования. Не отключайте проверку tenant ради красивого теста. Не делайте вывод о производительности на крошечном демонстрационном корпусе; проверяйте рабочий объём, конкурентную нагрузку и p95, а также расход памяти/скорость обновлений там, где они существенно меняются.
FAQ
Нужно ли поле index для HNSW?
Да, вместе с attribute для индексированного ANN-поиска.
Можно ли хранить только embedding?
Можно, но для RAG нужен проверяемый source_id и исходный текст.
Векторы разной длины допустимы?
Нет для одного поля с фиксированной осью x[n].
Официальные источники
Частые вопросы
Нужно ли поле `index` для HNSW?
Да, вместе с `attribute` для индексированного ANN-поиска.
Можно ли хранить только embedding?
Можно, но для RAG нужен проверяемый source_id и исходный текст.
Векторы разной длины допустимы?
Нет для одного поля с фиксированной осью `x[n]`.
Читайте также
Как фильтровать векторный поиск 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.
Комментарии
Пока тихо. Скажите первое слово