Гайд · TNWS AI

Как загрузить свои embeddings в Meilisearch через userProvided

4 мин—

Собственные vectors в поле _vectors: dimensions, regenerate:false, запрос vector и проверки несовместимых моделей.

Задача, применимость и подтверждённые факты

Русскоязычный запрос: «как загрузить свои embeddings Meilisearch userProvided». Документация производителя проверена 19 сентября 2026 года. В вашей системе векторы уже считаются локальной моделью, и повторная генерация через облачный embedder не нужна. В примере измерение равно 3 только для проверки формата; production dimension берётся из фактического выхода конкретной версии модели. Документы и поисковые вопросы нужно пропускать через совместимую модель и одинаковые режимы preprocessing.

Для источника userProvided обязателен dimensions, а documentTemplate и documentTemplateMaxBytes несовместимы с этим источником. Данные документа передаются через зарезервированный объект _vectors, его ключ — имя настроенного embedder. У userProvided Meilisearch не создаёт вектор из поисковой строки автоматически: поиск получает числовой vector и hybrid.embedder. Сокращённая форма массива эквивалентна embeddings с regenerate:false.

Прежде чем менять рабочий индекс, сохраните его настройки и небольшой набор контрольных документов с ожидаемыми ID. Важно отделять принятие конфигурации сервером от готовности асинхронной обработки: поисковая выдача до завершения задачи не служит честным тестом качества. Для примеров с токенами ${OPENAI_API_KEY} нужен реальный секрет в защищённом окружении; строки-заглушки не являются рабочими ключами.

Порядок действий

  1. Получите один контрольный embedding модели и проверьте размерность, конечность каждого числа и model revision.
  2. Создайте userProvided embedder ru-local-v1 с ровно такой dimension.
  3. Запишите документ со стабильным ID и _vectors.ru-local-v1; отдельно сохраните title и source_id для цитат.
  4. Дождитесь завершения задачи индексации и повторите загрузку того же ID, проверяя отсутствие дубликата.
  5. Постройте query vector той же моделью и передайте его в POST search вместе с именем embedder.

После каждого шага сохраняйте ID операции или задачи, связанные с тестом версии модели, а не только HTTP-статус. Если задача окончилась ошибкой, не скрывайте её повторным запросом к поиску: сначала устраняйте причину. Применение к Meilisearch Cloud и самостоятельной установке зависит от доступности endpoint и полномочий ключа; здесь используются точные имена HTTP API из официальной документации, но не выдуманные пункты интерфейса.

Готовый запрос или шаблон

PATCH /indexes/kb/settings/embedders
{"ru-local-v1":{"source":"userProvided","dimensions":3}}

POST /indexes/kb/documents
[{"id":"refund:1","title":"Возврат оплаты",
  "_vectors":{"ru-local-v1":{"embeddings":[0.1,0.2,0.3],"regenerate":false}}}]

POST /indexes/kb/search
{"vector":[0.12,0.19,0.28],"hybrid":{"embedder":"ru-local-v1","semanticRatio":1.0},"limit":5}

Никогда не копируйте заглушки URL, API key, model ID или тестовые vectors в рабочую систему без замены и проверки. Векторы длины три демонстрируют контракт данных; они не представляют реальную языковую модель и не позволяют обещать заданный порядок поисковых результатов.

Пример входа и ожидаемого результата

Вход: refund:1 с вектором из трёх чисел и shipping:1 с другим вектором; query [0.12,0.19,0.28]. Ожидаемый технический результат: задача индексации успешна, ответ содержит ID документов, повторная загрузка не увеличивает число уникальных ID. Для проверки смыслового порядка используйте настоящие vectors модели и вручную размеченные вопросы, а не искусственные числа.

Что важно при внедрении

Главная скрытая ошибка — две модели возвращают одинаковую длину, но их координатные системы различаются. Meilisearch видит правильную размерность и принимает запрос, хотя поиск становится бессмысленным. Проводите миграцию через новое имя embedder с параллельным наполнением и сравнивайте Recall@k на одном наборе вопросов. После обновления текста regenerate:false означает, что старый embedding остаётся; ваше приложение обязано пересчитать и повторно загрузить вектор вместе с документом, иначе semantic index отстанет от содержимого. Если результатов нет, сначала проверяйте task и имя ключа в _vectors, потом модель/длину и формат search body. Не передавайте клиенту публичный админ-ключ и не принимайте произвольный vector от пользователя без ограничения размера запроса и прав доступа к индексу. Для RAG держите исходный source_id, чтобы доказать происхождение любого найденного фрагмента.

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

  • dimensions совпадает с длиной каждого embedding.
  • В документах и запросе одинаковые model ID и preprocessing.
  • Асинхронная задача завершилась без ошибки.
  • Обновление текста сопровождается обновлением vector.

Сделайте повторный запуск тех же запросов после изменения модели, схемы, API поставщика или состава корпуса. Фиксируйте source IDs, текст-основание ответа, долю верных top-k и задержку на одинаковых данных. Для RAG найденный hit — свидетельство релевантности, не разрешение придумывать содержание: генератору передавайте только допустимые фрагменты, а утверждения проверяйте по первоисточнику.

Ошибки и чего не делать

  • Задать documentTemplate для userProvided.
  • Смешать две модели с одинаковой размерностью.
  • Ожидать автоматического пересчёта с regenerate:false.
  • Искать только по q, не передавая обязательный vector.

Не используйте высокий _rankingScore как вероятность истинности текста. При незнакомом вопросе возвращайте недостаточность данных вместо уверенной генерации на случайном соседнем документе. Если у вас есть tenant или права доступа, отфильтровывайте документы до передачи LLM и проверяйте отрицательным тестом отсутствие чужого источника.

FAQ

Где хранить массив?

В _vectors под именем настроенного embedder.

Что делает regenerate:false?

Сохраняет указанный vector при обновлениях без автогенерации.

Можно ли искать текстом без vector?

Не с одним userProvided: query embedding нужно создать самому.

Можно ли смотреть vectors в поиске?

Да с retrieveVectors:true при разрешённом displayedAttributes, но обычно это не нужно.

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

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

Где хранить массив?

В `_vectors` под именем настроенного embedder.

Что делает regenerate:false?

Сохраняет указанный vector при обновлениях без автогенерации.

Можно ли искать текстом без vector?

Не с одним userProvided: query embedding нужно создать самому.

Можно ли смотреть vectors в поиске?

Да с `retrieveVectors:true` при разрешённом displayedAttributes, но обычно это не нужно.

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

Комментарии

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