Milvus в RAG-системе: настройка, индексы и гибридный поиск

    При построении RAG-системы (Retrieval-Augmented Generation) на базе Milvus многие сталкиваются с неудовлетворительными результатами поиска. Особенно остро проблема стоит при работе с русскоязычными документами. В этой статье мы разберём типичные ошибки, оптимальные конфигурации индексов и метрик, а также подходы к гибридному поиску, чтобы ваша система выдавала релевантные и контекстно-точные результаты.

    Типичные ошибки при работе с Milvus в RAG

    Многие разработчики, используя Milvus для семантического поиска, получают низкое качество результатов. Чаще всего это связано с неверным выбором модели эмбеддингов, неподходящими параметрами индексации или игнорированием особенностей данных. Рассмотрим ключевые моменты.

    Неправильный выбор модели эмбеддингов

    Для русскоязычных текстов критически важно использовать модели, обученные на русском языке. Модель ai-forever/sbert_large_nlu_ru - хороший выбор, но она может не подходить для специфической корпоративной лексики. Рекомендуется протестировать несколько моделей, например, intfloat/multilingual-e5-large или cointegrated/rubert-tiny2 для лёгких сценариев. Также обратите внимание на размерность векторов: чем она выше, тем больше деталей модель может захватить, но растёт и время поиска.

    Неверные параметры чанков (chunking)

    Размер и перекрытие чанков напрямую влияют на качество поиска. chunk_size=500 и chunk_overlap=100 - это лишь отправная точка. Для технической документации с длинными абзацами можно увеличить размер до 1000-1500 символов. Важно, чтобы каждый чанк содержал законченную мысль. Используйте семантический сплиттер (например, SemanticChunker из LangChain) вместо рекурсивного, чтобы разбивка происходила по смысловым границам.

    Выбор индексов и метрик в Milvus

    Для плотных векторов (dense) популярны индексы FLAT, HNSW и IVF_FLAT. Каждый из них имеет свои особенности.

    FLAT (полный перебор)

    FLAT - эталонный индекс, выполняющий полное сканирование. Он точен, но медленен на больших объёмах (более 100 тысяч векторов). Используйте его только для тестирования или при малом количестве данных.

    HNSW (графовый индекс)

    HNSW - лучший выбор для большинства сценариев. Он обеспечивает высокую скорость и точность. Параметры M (количество связей на узел) и efConstruction (размер динамического списка при построении) влияют на скорость и точность. Для коллекций до 1 миллиона векторов используйте M=16, efConstruction=200. Для поиска параметр ef (размер списка при поиске) можно выставить 100-200 для баланса скорости и точности.

    IVF_FLAT (кластеризация)

    IVF_FLAT делит пространство на кластеры (nlist). Для поиска просматриваются ближайшие кластеры (nprobe). Этот индекс быстрее FLAT, но уступает HNSW по точности. Подходит для очень больших коллекций (миллионы векторов), где HNSW потребляет много памяти.

    Метрики расстояния

    Для семантического поиска наиболее подходящая метрика - COSINE (косинусное сходство). Она измеряет угол между векторами и не зависит от их длины. Метрики L2 (евклидово расстояние) и IP (внутреннее произведение) менее эффективны для семантики, так как чувствительны к масштабу векторов. Используйте COSINE для всех моделей, которые нормализуют векторы (например, SBERT).

    Гибридный поиск: плотные + разреженные векторы

    Гибридный поиск объединяет результаты плотных (семантических) и разреженных (ключевых) векторов. Это позволяет компенсировать недостатки каждого подхода. В Milvus для этого используется RRFRanker (ранжирование по взаимному рангу).

    Однако, если плотные векторы дают плохие результаты, гибридный поиск не спасёт - он лишь смешает плохой семантический результат с точным текстовым совпадением. Поэтому сначала добейтесь хорошего качества плотного поиска.

    Оптимизация обработки документов

    Качество поиска напрямую зависит от того, как вы подготовили данные. Используйте Apache Tika для извлечения текста и метаданных из PDF, DOCX и других форматов. Обязательно удаляйте специальные символы, лишние пробелы и нормализуйте текст (приводите к нижнему регистру, убирайте пунктуацию).

    Для разбивки на чанки используйте RecursiveCharacterTextSplitter с разделителями по абзацам и предложениям. Экспериментируйте с размером: для коротких вопросов (FAQ) делайте чанки по 200-300 символов, для инструкций - 500-1000. Перекрытие в 10-20% от размера чанка помогает сохранить контекст.

    Связь результатов поиска с LLM

    После получения релевантных чанков из Milvus, передайте их в промпт LLM (например, GPT или YandexGPT). Важно уложиться в контекстное окно модели. Для этого ограничьте количество возвращаемых чанков (top_k=5-10) и суммарный объём текста (например, до 2000 токенов). Используйте ранжирование по релевантности (score) и при необходимости дополнительное реранжирование с помощью кросс-энкодеров (например, cross-encoder/ms-marco-MiniLM-L-6-v2).

    Если контекстное окно LLM мало, применяйте технику «скользящего окна»: разбивайте длинные документы на несколько запросов, а затем агрегируйте ответы. Или используйте модели с большим контекстом (например, GPT-4-128k или YandexGPT 32k).

    Практические рекомендации по настройке

    • Объём данных: Для коллекций до 1 млн векторов используйте HNSW с COSINE. Для 1-10 млн - IVF_FLAT с nlist=4096 и nprobe=10-50. Для свыше 10 млн - рассмотрите шардирование или переходите на Milvus Distributed.
    • Партиции (Partitioning): Используйте их для разделения данных по категориям (например, по типу документа или дате). Это ускоряет поиск, если вы знаете, в какой партиции искать. Задайте ключ партиции при создании коллекции.
    • Обновление данных: Для инкрементального добавления используйте метод insert с последующим flush. Для полной переиндексации удалите коллекцию и создайте заново. Milvus не поддерживает частичное обновление индекса - при изменении данных требуется перестройка.
    • Мониторинг: Используйте встроенные метрики Milvus (через Prometheus и Grafana) для отслеживания QPS, задержек и загрузки CPU/GPU. Обратите внимание на query_latency и index_build_progress.

    Альтернативы Milvus

    Среди популярных векторных баз данных: Weaviate (простая интеграция с GraphQL), Qdrant (высокая производительность на малых объёмах), Chroma (лёгкая, для прототипов) и PGVector (расширение PostgreSQL, удобно если уже используете Postgres). Milvus выбирают за гибкость, поддержку гибридного поиска и масштабируемость. Однако для небольших проектов (до 100k векторов) Chroma или Qdrant могут быть проще в настройке.

    Заключение

    Качественная RAG-система на Milvus требует тщательной настройки каждого этапа: от выбора модели эмбеддингов до конфигурации индексов. Начните с малого - протестируйте HNSW с COSINE на небольшой выборке, добейтесь хороших результатов плотного поиска, и только потом подключайте гибридный поиск. Используйте семантическое чанкование и реранжирование для улучшения точности. Помните, что Milvus - мощный инструмент, но он требует экспериментов и понимания ваших данных.

    Часто задаваемые вопросы