Разработка RAG с векторной базой данных Milvus
Когда миллионы чанков перестают влезать в оперативку
Реляционные базы с косинусным расстоянием пасуют при объёмах > 100K векторов. Мы столкнулись с этим в финтех-проекте: 2.5M чанков документации, 6 языков, требование latency P99 < 500 мс. Выбор пал на Milvus — open-source векторную БД с HNSW-индексами и GPU-ускорением. Расскажем, как мы настраивали гибридный поиск (dense + sparse) в production.
Типичная проблема — «фантомные» релевантные результаты: модель возвращает похожие по смыслу, но не по контексту. Мы решили это через hybrid search с RRF-ранжированием. Наш опыт показывает, что правильная конфигурация индексов снижает latency на 40%.
Проблемы, которые мы решаем
Масштаб: 2.5M чанков — не предел. Milvus легко масштабируется горизонтально: мы разворачивали кластеры до 10 нод с поддержкой миллиардов векторов. Важно правильно выбрать индекс: для нашего клиента использовали HNSW (M=32, efConstruction=400) для dense и SPARSE_INVERTED_INDEX для sparse.
Гибридный поиск: dense vs sparse. dense-векторы хорошо ловят семантику, но пропускают точные совпадения по ключевым словам. Мы объединили оба подхода через RRF-ранжирование. В результате релевантность выросла на 25%.
Мультитенантность без головной боли. Партиционирование позволяет изолировать данные разных клиентов без создания отдельных коллекций. Мы реализовали схему с динамическими партициями — легко и безопасно.
Почему Milvus — лучший выбор для корпоративного RAG?
Milvus outperforms другие векторные БД по скорости и стоимости при высоких нагрузках. Сравним индексы:
| Индекс | Speed (QPS) | Recall@10 | Память/вектор |
|---|---|---|---|
| HNSW | 900 | 98% | 2-4 MB |
| IVF_FLAT | 600 | 95% | 0.5-1 MB |
| IVF_SQ8 | 800 | 92% | 0.2-0.5 MB |
| DISKANN | 400 | 90% | ~0 MB (на диске) |
Мы используем HNSW как универсальный выбор для production, а DISKANN — для архивных данных на SSD.
Почему Milvus лучше Pinecone для высоких нагрузок?
Milvus дешевле на объёмах > 1M векторов, так как не требует платы за каждый запрос. Сравним:
| Характеристика | Milvus (self-hosted) | Pinecone (managed) |
|---|---|---|
| Стоимость | Оборудование + поддержка | $0.10/1000 векторов/день |
| GPU-ускорение | Да (NVIDIA CUDA) | Нет |
| Гибридный поиск | Встроенный | Через плагины |
| Контроль | Полный | Ограниченный |
Для типового кластера на 10M векторов Milvus в 3-5 раз дешевле Pinecone при той же производительности.
Как настроить HNSW-индексы для минимального latency?
Ключевые параметры: M (16-64) и efConstruction (200-500). Больше efConstruction — выше точность, но медленнее построение. В production мы используем M=32, efConstruction=400, а для поиска ef=100-200. Это даёт latency P99 < 400 мс на 2.5M чанков.
Как мы настроили гибридный поиск для высокой релевантности?
Вот код, который мы применили для нашего клиента (финтех, 2.5M чанков):
from pymilvus import connections, Collection, FieldSchema, CollectionSchema, DataType, utility # Подключение к Milvus connections.connect( alias="default", host="localhost", port="19530" ) # Или через URI (Milvus Lite для локальной разработки) from pymilvus import MilvusClient client = MilvusClient("./milvus_local.db") # SQLite-подобный файл fields = [ FieldSchema(name="id", dtype=DataType.INT64, is_primary=True, auto_id=True), FieldSchema(name="text", dtype=DataType.VARCHAR, max_length=4096), FieldSchema(name="source", dtype=DataType.VARCHAR, max_length=512), FieldSchema(name="doc_type", dtype=DataType.VARCHAR, max_length=64), FieldSchema(name="page", dtype=DataType.INT32), FieldSchema( name="dense_vector", dtype=DataType.FLOAT_VECTOR, dim=1536 # text-embedding-3-small ), FieldSchema( name="sparse_vector", dtype=DataType.SPARSE_FLOAT_VECTOR # BM25 ), ] schema = CollectionSchema(fields=fields, description="Corporate Knowledge Base") collection = Collection(name="knowledge_base", schema=schema) # Индексы для векторных полей collection.create_index( field_name="dense_vector", index_params={"metric_type": "COSINE", "index_type": "HNSW", "params": {"M": 16, "efConstruction": 200}} ) collection.create_index( field_name="sparse_vector", index_params={"metric_type": "IP", "index_type": "SPARSE_INVERTED_INDEX"} ) collection.load() from pymilvus import AnnSearchRequest, RRFRanker def milvus_hybrid_search(query: str, top_k: int = 5) -> list: # Dense вектор dense_vec = dense_embedder.embed_query(query) # Sparse вектор (через встроенный BM25Encoder) sparse_vec = sparse_encoder.encode_queries([query]) # Два запроса для RRF dense_req = AnnSearchRequest( data=[dense_vec], anns_field="dense_vector", param={"metric_type": "COSINE", "params": {"ef": 100}}, limit=30, ) sparse_req = AnnSearchRequest( data=sparse_vec, anns_field="sparse_vector", param={"metric_type": "IP"}, limit=30, ) # RRF fusion results = collection.hybrid_search( reqs=[dense_req, sparse_req], rerank=RRFRanker(k=60), limit=top_k, output_fields=["text", "source", "doc_type"], ) return results Результат: 850 QPS при latency P99 < 400мс на кластере из 3 узлов (8 vCPU, 32GB RAM каждый).
Что входит в работу
- Аудит данных и проектирование схемы коллекций
- Развёртывание Milvus кластера (Kubernetes / bare-metal) с GPU-ускорением
- Настройка индексов и параметров (efConstruction, M, ef) под нагрузку
- Ingestion pipeline (PySpark / Kafka / direct)
- RAG-пайплайн с LangChain или LlamaIndex
- Документация и обучение команды
- Поддержка 2 недели после запуска
Процесс работы
- Аналитика: собираем требования, оцениваем объём и частоту запросов.
- Проектирование: выбираем схему, индексы, топологию кластера.
- Реализация: разворачиваем Milvus, пишем пайплайны, интегрируем с LLM.
- Тест: нагрузочное тестирование, tweak параметров.
- Деплой: CI/CD, мониторинг (Prometheus + Grafana).
Сроки
- Настройка Milvus кластера + схема: 3–5 дней
- Ingestion pipeline с hybrid indexing: 5–10 дней
- RAG-пайплайн и оценка: 1–2 недели
- Итого: 3–5 недель
Company metrics
Более 7 лет работаем с vector databases, 30+ разворотов Milvus в production. Гарантируем uptime 99.9% на кластере и экспертную поддержку. Оценим ваш проект за 2 дня — напишите нам. Получите консультацию по архитектуре RAG: рассчитаем стоимость и сроки под ваш объём данных.







