Розробка RAG з векторною базою даних Milvus
Milvus — відкрита векторна база даних, розроблена для production-масштабу: мільярди векторів, висока пропускна здатність, горизонтальне масштабування. Підтримує HNSW, IVF_FLAT, IVF_SQ8, DISKANN індекси та гібридний пошук (sparse + dense). Добре підходить для enterprise-систем з великими обсягами даних.
Встановлення та підключення
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()
Гібридний пошук з RRF
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
Практичний кейс: пошук у продуктовій документації
Масштаб: 2.5M чанків (технічна документація на 6 мовах, включаючи українську).
Індекс: HNSW (M=32, efConstruction=400) для dense; SPARSE_INVERTED_INDEX для sparse.
Throughput при гібридному пошуку: 850 QPS при latency P99 < 400мс на кластері з 3 вузлів (8 vCPU, 32GB RAM кожний).
Порівняння з Pinecone Serverless при тому ж обсягу: Milvus self-hosted дешевше в ~8× при високому QPS, але вимагає DevOps-підтримки.
Партиціонування для мультитенантності
# Створення партицій для ізоляції клієнтів
collection.create_partition(partition_name="client_001")
collection.create_partition(partition_name="client_002")
# Пошук лише у партиції клієнта
results = collection.search(
data=[query_vector],
anns_field="dense_vector",
partition_names=["client_001"],
limit=5,
)
Строки
- Налаштування Milvus кластера + схема: 3–5 днів
- Ingestion pipeline з hybrid indexing: 5–10 днів
- RAG-пайплайн та оцінка: 1–2 тижні
- Всього: 3–5 тижнів







