Почему нельзя просто заменить имя модели
Embedding-модель превращает запросы и фрагменты документов в координаты одного векторного пространства. При её замене меняются не только размерность и скорость, но и само расположение смыслов. Даже если старая и новая модели выдают одинаковое число координат, смешивать их результаты нельзя: близость имеет смысл только внутри пространства, созданного совместимой моделью и функцией расстояния.
Поэтому обновление embedding-модели в работающем RAG — это миграция данных. Нужно заново получить векторы всего корпуса, не потерять документы, которые появились или изменились во время пересчёта, сравнить качество на реальных вопросах, переключить поиск без остановки и сохранить путь назад.
Официальная документация Qdrant описывает два варианта миграции без простоя: параллельные blue/green-коллекции и дополнительный named vector внутри существующей коллекции. Конкретные команды относятся к Qdrant, но управленческая схема применима к OpenSearch, Milvus, pgvector и другим хранилищам: новая версия строится рядом со старой, проверяется на одинаковом наборе запросов и становится основной только после контролируемого переключения.
Что зафиксировать до начала
Миграция невозможна без исходного текста. Вектор — производный артефакт; по нему нельзя надёжно восстановить документ для новой модели. До расчёта бюджета нужно проверить, где лежат исходные фрагменты и можно ли однозначно повторить их подготовку.
Для каждого фрагмента полезно хранить:
- стабильный `chunk_id`, не зависящий от модели;
- идентификатор и версию документа;
- контрольную сумму нормализованного текста;
- правила разбиения и их версию;
- модель, размерность и функцию расстояния;
- время создания embedding;
- права доступа и арендатора;
- признак удаления или актуальности.
Отдельно снимите базовую линию: число точек, размерность, метрику расстояния, параметры индекса, настройки квантизации, задержку p50/p95 и результаты эталонных запросов. Документация Qdrant называет несоответствие функции расстояния одной из частых причин деградации после миграций. Если базовой линии нет, команда не сможет отличить улучшение модели от случайной смены настроек индекса.
Вариант 1: blue/green-коллекции
Это наиболее переносимая архитектура. Старая коллекция продолжает обслуживать поиск, рядом создаётся новая с размерностью и метрикой новой модели.
Последовательность выглядит так:
1. Создать `rag_v2`, не меняя рабочий алиас `rag_current`, который указывает на `rag_v1`.
2. Включить двойную запись: каждый новый или изменённый фрагмент кодируется обеими моделями и записывается в обе коллекции.
3. Фоновым процессом читать исходные документы, пересчитывать старые фрагменты и идемпотентно записывать их в `rag_v2`.
4. Параллельно отправлять часть запросов в обе версии, не показывая пользователю ответ новой версии.
5. Сверить полноту, права доступа, качество выдачи, задержку и стоимость.
6. Атомарно переключить алиас на `rag_v2`.
7. Сохранить `rag_v1` на согласованный период отката, затем удалить по отдельному решению.
Алиас важен потому, что приложение обращается к стабильному логическому имени. И Qdrant, и OpenSearch документируют атомарное изменение алиаса: конкурентные запросы не должны увидеть промежуточное состояние, когда имя указывает одновременно не туда или никуда.
Цена blue/green — двойное хранение payload и индексов на время миграции. Кроме того, простого двойного upsert недостаточно. Удаления и частичные обновления должны попасть в обе версии. Qdrant прямо предупреждает: если миграционный скрипт обрабатывает только upsert, удалённый документ может вернуться в новую коллекцию во время фонового backfill.
Безопасный вариант — единый журнал операций. Каждая запись получает монотонную версию: `upsert`, `delete`, изменение прав. Фоновый пересчёт фиксирует границу журнала, а после основного прохода применяет все более новые события. Перед переключением выполняется сверка количества актуальных фрагментов и выборочная проверка tombstone.
Вариант 2: два named vector в одной коллекции
В Qdrant 1.18 и новее можно добавить к существующей коллекции новый именованный вектор. Payload, идентификаторы и права остаются на месте; новые embeddings записываются в дополнительное поле, а запрос явно выбирает старое или новое имя.
Этот вариант экономит место на дублировании документов и упрощает удаление: удаление точки удаляет оба вектора. Откат тоже проще — достаточно вернуть поиск к старому имени, пока старый вектор не удалён.
Но ограничения остаются:
- коллекция должна быть спроектирована под named vectors;
- двойная запись нужна для всех новых и изменённых фрагментов;
- старые точки не появятся в новом пространстве сами — нужен backfill;
- сервис запросов должен переключить одновременно модель запроса и имя вектора;
- удалять старый вектор можно только после завершения периода отката.
Главное правило: версия модели запроса и версия индекса являются одной конфигурацией. Если приложение закодирует новый запрос старой моделью и отправит его в новый индекс или наоборот, система может отвечать без технической ошибки, но качество станет непредсказуемым.
Как проверить качество до переключения
Публичный benchmark помогает выбрать кандидатов, но не заменяет тест на документах бизнеса. BEIR показывает, что методы retrieval ведут себя по-разному на разных доменах и задачах. Для производственного решения нужен собственный набор хотя бы из 100–300 реальных вопросов, где эксперты отметили релевантные документы или фрагменты.
Сравнивайте уровни отдельно.
**Retrieval:** Recall@k показывает, попал ли нужный фрагмент в кандидаты; nDCG@k учитывает его позицию. Дополнительно измеряйте долю запросов без полезного результата и пересечение top-k между версиями.
**Ответ:** эксперт проверяет опору на источник, полноту, отсутствие выдуманных фактов и соблюдение прав. Улучшение Recall не гарантирует лучший итоговый ответ: новый retriever может приносить больше похожего, но менее точного контекста.
**Эксплуатация:** p95 задержки, размер очереди на embedding, нагрузка CPU/GPU, объём индекса, время восстановления и стоимость одного принятого ответа. Более качественная модель может увеличить размерность и замедлить поиск или потребовать более дорогого reranker.
Полезен теневой режим: рабочий ответ выдаёт `v1`, а `v2` выполняется параллельно для измерения. Затем небольшой процент сотрудников переводится на управляемый A/B-тест. Автоматическое переключение только по одной метрике опасно; решение принимает владелец процесса вместе с ИТ.
Модельная экономика пересчёта
Рассмотрим условный корпус из 500 тыс. фрагментов по 600 токенов. Это 300 млн входных токенов для повторного embedding. При эффективной пропускной способности 15 тыс. токенов в секунду чистое вычисление займёт около 5,6 часа. Реальный календарный срок будет больше из-за чтения данных, сетевых задержек, повторов, индексации и ограничений очереди.
Если новый вектор имеет 1 024 компонента float32, только сырые векторы занимают примерно 2,05 ГБ: `500 000 × 1 024 × 4 байта`. В эту оценку не входят граф индекса, payload, служебные данные, реплики и запас диска. Во время blue/green нужно одновременно держать старую и новую версии, поэтому бюджет нельзя считать только по размеру итоговой коллекции.
Добавьте расходы на:
- повторное кодирование новых изменений в период двойной записи;
- хранение двух индексов и резервных копий;
- подготовку эталонных вопросов и экспертную оценку;
- наблюдаемость, сверку и обработку повторов;
- период отката после переключения;
- возможное изменение reranker и генеративной модели.
Эти числа модельные и не описывают конкретное внедрение. Для малого бизнеса основной расход часто не GPU, а время экспертов: нужно определить правильные источники, разобрать расхождения и подтвердить, что улучшение влияет на принятые решения.
Безопасность и локальный контур
При использовании внешнего API для embedding весь пересчитываемый текст покидает локальный контур. До миграции надо проверить договор, регион обработки, хранение запросов и допустимость передачи каждого класса документов. Для закрытой базы знаний локальный embedding-сервис часто проще с точки зрения потока данных, но требует собственного контроля версий, производительности и обновлений.
Двойная запись не должна обходить фильтры доступа. Права и tenant-метаданные копируются вместе с документом, а проверка доступа выполняется до векторного поиска в обеих версиях. Теневые запросы также журналируются и подчиняются тем же ограничениям хранения, что и рабочие.
Контрольный список переключения
Переключать алиас можно только когда одновременно выполнены условия:
- 100% актуальных фрагментов имеют новую версию embedding;
- удалённые документы не появились повторно;
- контрольные суммы и права доступа совпадают;
- новый retriever прошёл эталонный набор без критических регрессий;
- p95 задержки и стоимость укладываются в SLA и бюджет;
- мониторинг различает версии модели и индекса;
- инструкция отката проверена на стенде;
- старый индекс защищён от случайного удаления на период отката.
Практический первый шаг — не запускать пересчёт, а восстановить происхождение каждого вектора. Возьмите 100 документов, повторите разбиение и убедитесь, что получаются те же стабильные `chunk_id`. Затем соберите 100 реальных запросов и снимите базовую выдачу. Если эти две операции нельзя воспроизвести, миграция embedding-модели вскроет проблему управления данными раньше, чем даст улучшение качества — и это полезный результат само по себе.
