Milvus — облачно-нативная векторная БД, способная индексировать миллиарды векторов. Горизонтальное масштабирование, гибридный поиск, GPU-индексация и глубокая интеграция с AI-фреймворками.
Milvus — это облачно-нативная векторная БД, созданная для масштаба миллиардов векторов. В отличие от Qdrant (лёгкий, однонодовый по умолчанию), Milvus изначально распределённый: компоненты Proxy, Query Node, Data Node и Index Node масштабируются независимо. Если у вас десятки миллионов документов и нагрузка растёт непредсказуемо — Milvus ваш выбор.
Ключевые фичи: GPU-индексация (построение индексов на GPU в 10x быстрее), IVF-индексы для approximate search на гигантских датасетах, multi-vector поиск (несколько векторов на одну сущность), и нативная потоковая обработка через Pulsar/Kafka. Milvus используют в поисковых системах, рекомендательных движках и AI-агентах с живым обновлением данных.
# Установка Milvus Standalone через Docker Compose wget https://github.com/milvus-io/milvus/releases/download/v2.4.0/milvus-standalone-docker-compose.yml \ -O docker-compose.yml docker compose up -d # Проверка docker compose ps curl http://localhost:9091/healthz # Установка PyMilvus SDK pip install pymilvus==2.4.0
Milvus требует явного определения схемы коллекции — в отличие от schema-less Qdrant. Вы задаёте поля, их типы (VARCHAR, INT64, FLOAT_VECTOR, etc.) и первичный ключ. Это даёт строгую типизацию и возможность строить индексы не только на векторных, но и на скалярных полях. Для AI-агентов схема обычно включает: id, text, embedding (float_vector), source, timestamp.
Выбор индекса критичен для performance. Для точного поиска — FLAT (brute-force, медленно на больших данных). Для approximate — IVF_FLAT (хороший баланс), IVF_SQ8 (экономия памяти), HNSW (быстрый поиск, дорогой build). Для GPU-ускорения — IVF_GPU. Для миллиардов векторов — DiskANN (поиск с диска).
from pymilvus import MilvusClient, DataType client = MilvusClient(uri="http://localhost:19530") # Схема коллекции для RAG-агента schema = client.create_schema( auto_id=False, enable_dynamic_field=True, # для гибких метаданных description="AI Agent Knowledge Base" ) schema.add_field(field_name="id", datatype=DataType.INT64, is_primary=True) schema.add_field(field_name="text", datatype=DataType.VARCHAR, max_length=65535) schema.add_field(field_name="embedding", datatype=DataType.FLOAT_VECTOR, dim=1536) schema.add_field(field_name="source", datatype=DataType.VARCHAR, max_length=512) schema.add_field(field_name="tenant", datatype=DataType.VARCHAR, max_length=128) # Создаём коллекцию с IVF_FLAT индексом index_params = client.prepare_index_params() index_params.add_index( field_name="embedding", index_type="IVF_FLAT", metric_type="COSINE", params={"nlist": 1024} ) client.create_collection( collection_name="agent_knowledge", schema=schema, index_params=index_params, consistency_level="Strong" # для актуальности данных )
Milvus поддерживает batch-вставку (до тысяч записей за вызов) и streaming-вставку для real-time данных. Для поиска доступны: ANN (приближённый), range search (все векторы в радиусе), и hybrid search — комбинация векторного поиска со скалярной фильтрацией. Hybrid search в Milvus выполняет фильтрацию на этапе поиска, а не после, что даёт точные результаты даже на больших данных.
Для поиска с фильтрацией используйте boolean expressions в стиле SQL: tenant == "acme" and timestamp > 1700000000000. Milvus компилирует это в эффективный план выполнения, используя индексы на скалярных полях.
import numpy as np # Пакетная вставка эмбеддингов data = [ {"id": i, "text": chunk_text, "embedding": embedding.tolist(), "source": "docs/api.md", "tenant": "acme-corp"} for i, (chunk_text, embedding) in enumerate(chunks) ] client.insert(collection_name="agent_knowledge", data=data) client.flush(collection_name="agent_knowledge") # Гибридный поиск: ANN + фильтр по tenant results = client.search( collection_name="agent_knowledge", data=[query_embedding.tolist()], limit=5, filter='tenant == "acme-corp"', output_fields=["text", "source"], search_params={"metric_type": "COSINE", "params": {"nprobe": 16}} ) for hits in results: for hit in hits: print(f"Score: {hit['distance']:.3f}, Source: {hit['entity']['source']}") print(f"Text: {hit['entity']['text'][:100]}...")
Milvus поддерживает партиции — логические разделы внутри коллекции. Для multi-tenant AI-агента создайте партицию на каждого клиента. Это даёт изоляцию данных на уровне поиска (запросы в пределах партиции быстрее, чем фильтр по всему набору) и позволяет гибко управлять retention: удалять данные ушедшего клиента одной командой.
Внутри партиций данные делятся на сегменты — это единицы роста и слияния. Когда данные растут (insert), сегменты наполняются; когда достигают порога, Milvus автоматически строит индекс и запечатывает сегмент (sealed). Запечатанные сегменты оптимизированы для чтения и обслуживают основную поисковую нагрузку.
# Создаём партиции для каждого клиента tenants = ["acme-corp", "globex", "initech"] for tenant in tenants: client.create_partition( collection_name="agent_knowledge", partition_name=tenant ) # Вставка данных в партицию клиента client.insert( collection_name="agent_knowledge", data=acme_data, partition_name="acme-corp" ) # Поиск внутри партиции (быстрее, чем фильтр) results = client.search( collection_name="agent_knowledge", data=[query_embedding.tolist()], partition_names=["acme-corp"], limit=5, output_fields=["text"] ) # Удаление данных клиента при расторжении client.release_partitions( collection_name="agent_knowledge", partition_names=["globex"] ) client.drop_partition( collection_name="agent_knowledge", partition_name="globex" )
LangChain имеет нативную интеграцию с Milvus через langchain_milvus. Вы можете использовать Milvus как векторное хранилище для retrieval-цепочек, с поддержкой фильтрации через search_kwargs. Milvus также поддерживает self-querying retriever: LLM сам генерирует фильтр по метаданным из вопроса пользователя, и Milvus применяет его при поиске.
Для production RAG-агентов используйте Milvus с multi-vector поиском: храните отдельно dense-векторы (семантический поиск) и sparse-векторы (keyword BM25) в одной коллекции. LangChain поддерживает это через MilvusVectorStore с hybrid search конфигурацией.
from langchain_milvus import Milvus from langchain_openai import OpenAIEmbeddings, ChatOpenAI from langchain.chains import RetrievalQAWithSourcesChain embeddings = OpenAIEmbeddings(model="text-embedding-3-small") # Подключаем существующую коллекцию Milvus vectorstore = Milvus( embedding_function=embeddings, collection_name="agent_knowledge", connection_args={ "uri": "http://localhost:19530", "token": "root:Milvus" }, primary_field="id", text_field="text", vector_field="embedding", ) # Self-querying retriever: LLM сам строит фильтр retriever = vectorstore.as_retriever( search_type="similarity", search_kwargs={ "k": 5, "expr": 'tenant == "acme-corp"' } ) # RAG с источниками chain = RetrievalQAWithSourcesChain.from_chain_type( llm=ChatOpenAI(model="gpt-4o", temperature=0), chain_type="stuff", retriever=retriever, return_source_documents=True ) response = chain.invoke({ "question": "Как настроить IVF_FLAT индекс в Milvus?" }) print(response["answer"]) print("Sources:", response["sources"])
Для продакшена критически правильно настроить Milvus. Consistency level: Strong для точности, Bounded для скорости, Eventually для максимальной производительности (данные могут отставать на секунды). Load balancing: распределяйте поисковую нагрузку через несколько Query Node. Мониторинг: Milvus экспортирует метрики в Prometheus — отслеживайте latency поиска, размер коллекций, количество sealed/growing сегментов.
Важные подсказки: используйте load_collection() перед поиском, чтобы загрузить индексы в память Query Node (первый поиск без загрузки будет медленным). Включите autoindex для автоматического выбора оптимального индекса. Для GPU-ускорения настройте Index Node с доступом к CUDA — построение индексов ускоряется в 5-10 раз.
# Продакшен-оптимизации Milvus from pymilvus import MilvusClient client = MilvusClient(uri="http://localhost:19530") # 1. Загружаем коллекцию в память перед поиском client.load_collection("agent_knowledge") # 2. Проверяем статус загрузки load_state = client.get_load_state("agent_knowledge") print(f"Loaded: {load_state['state']}") # 3. Статистика коллекции stats = client.get_collection_stats("agent_knowledge") print(f"Row count: {stats['row_count']}") # 4. Оптимизированные параметры поиска results = client.search( collection_name="agent_knowledge", data=[query_embedding.tolist()], limit=10, search_params={ "metric_type": "COSINE", "params": { "nprobe": 32, # больше = точнее, но медленнее "radius": 0.6, # минимальный порог сходства "range_filter": 0.85 # максимальный порог } } ) # 5. Освобождаем память когда коллекция не используется client.release_collection("agent_knowledge")
Milvus — правильный выбор когда ваш AI-агент работает с миллионами документов, требует горизонтального масштабирования и строгой типизации данных. Его распределённая архитектура (Proxy, Query/Data/Index Nodes) позволяет масштабировать чтение и запись независимо. Используйте партиции для multi-tenant изоляции, IVF_FLAT для баланса точности и скорости, и GPU-индексацию для ускорения построения индексов. Интеграция с LangChain через langchain_milvus даёт бесшовный RAG-пайплайн. Начните с Milvus Standalone для разработки, переходите на Milvus Distributed когда данные перевалят за 10 миллионов векторов.