Гайд · TNWS AI

Как сохранить несколько embeddings одного документа в Meilisearch

5 мин—

Массив векторов одного документа в _vectors.embeddings для нескольких абзацев, их обновление и проверка релевантности.

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

Русскоязычный запрос: «как хранить несколько embeddings документа Meilisearch». Документация производителя проверена 19 сентября 2026 года. Большая инструкция содержит разные самостоятельные разделы, но должна оставаться одним документом результата. Вместо усреднения несовместимых по смыслу абзацев присвойте документу несколько embeddings одного embedder. Это не то же самое, что два названных embedder для двух моделей: здесь каждый внутренний массив принадлежит одной модели, одной dimension и одному внешнему document ID.

Официальный формат допускает embeddings как массив массивов чисел. Он уместен, например, для вектора каждого абзаца или каждого языкового варианта документа. Полная форма объекта содержит обязательный булев regenerate; при false указанные значения не перезаписываются автоматической генерацией. Meilisearch возвращает документный hit, поэтому для ответа с точной цитатой приложению всё равно нужно восстановить абзац из своих метаданных или хранить отдельные chunk IDs.

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

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

  1. Разбейте страницу на два осмысленных абзаца, сохранив порядок и source_id.
  2. Посчитайте по одному вектору на абзац одной моделью и убедитесь, что все имеют ту же длину.
  3. Добавьте embeddings как [[...],[...]] внутри _vectors.<embedder> и установите regenerate:false.
  4. Дождитесь task индексации и отправьте по одному вопросу к каждому абзацу.
  5. После редактирования одного абзаца пересчитайте соответствующий вектор и обновите набор согласованно.

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

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

{"id":"manual:7", "title":"Оплата и доставка", "source_id":"manual:7",
 "sections":[{"id":"p1","text":"Возврат денег занимает ..."},
             {"id":"p2","text":"Доставка начинается после ..."}],
 "_vectors":{"ru-local-v1":{"embeddings":[[0.1,0.2,0.3],[0.6,0.1,0.2]],
                           "regenerate":false}}}

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

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

Вход: один документ manual:7, абзац p1 о возврате, p2 о доставке и два соответствующих вопроса. Ожидается один document ID в результатах каждого запроса, но это само по себе не доказывает, какой абзац привёл к совпадению. Чтобы показать обоснованную цитату, отдельно проверяйте и возвращайте p1 или p2 из приложения либо индексируйте абзацы как самостоятельные документы.

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

Этот способ экономит на повторении общей метаинформации по каждому фрагменту, но усложняет точность доказательства для RAG. Если для ответа важно указать конкретную строку, лучше хранить абзацы самостоятельными документами с source_id, parent_id и chunk_id. Таблица соответствия vector_index → section_id в отдельном хранилище хрупкая при вставке нового абзаца в середину: позиции сдвигаются. Поэтому при обновлении пересчитывайте manifest и проверяйте его целиком. Ограничивайте максимальное число абзацев и объём документа исходя из измеренной памяти и времени индексации; не приписывайте сервису неподтверждённый лимит. Если вопрос относится к двум абзацам и требует исключения из второго, retrieval одного документа ещё не гарантирует, что LLM получит оба фрагмента. На тестах обрабатывайте такие случаи вручную, а также отрицание и устаревшие редакции документа.

Сравнение решений

ХранениеЕдиница hitКогда выбирать
Много vectors одного документаобщий document IDдостаточно ссылки на страницу
Отдельные chunk-документыконкретный фрагментнужны точные цитаты и ACL по фрагментам

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

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

  • Все внутренние vectors одной длины и одной версии модели.
  • Запросы к обоим абзацам находят страницу на тестовых данных.
  • Для цитаты приложение действительно знает релевантный фрагмент.
  • Новая редакция не оставляет старых embeddings активными.

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

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

  • Путать второй vector с другим embedder.
  • Предполагать, что найден document ID уже доказывает нужный абзац.
  • Вставлять новые абзацы, не обновляя соответствие и embeddings.

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

FAQ

Как выглядит multi-vector?

Массив массивов в _vectors.<имя>.embeddings.

Можно ли использовать разные модели внутри?

Нет, используйте отдельные именованные embedders.

Выдаст ли поиск ID совпавшего абзаца?

Не считайте document hit доказательством абзаца; сохраняйте chunk IDs отдельно.

Что значит regenerate:false?

Автоматическая генерация не заменит переданные vectors.

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

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

Как выглядит multi-vector?

Массив массивов в `_vectors.<имя>.embeddings`.

Можно ли использовать разные модели внутри?

Нет, используйте отдельные именованные embedders.

Выдаст ли поиск ID совпавшего абзаца?

Не считайте document hit доказательством абзаца; сохраняйте chunk IDs отдельно.

Что значит regenerate:false?

Автоматическая генерация не заменит переданные vectors.

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

Комментарии

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