Skip to content

Commit 0aad7d1

Browse files
authored
Merge pull request #52 from vektori-ai/pr-49-milvus
Pr 49 milvus
2 parents 2500816 + 402960c commit 0aad7d1

13 files changed

Lines changed: 2563 additions & 16 deletions

README.md

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ SENTENCE LAYER (L2) <- raw conversation. Sequential NEXT edges. The full story.
2929
<img src="assets/screenshots/layers.jpeg" alt="Three-layer memory graph: Facts → Episodes → Sentences" width="680" />
3030
</p>
3131

32-
Search hits Facts, graph discovers Episodes, traces back to source Sentences. SQLite by default — swap to Postgres, Neo4j, or Qdrant when you're ready to scale.
32+
Search hits Facts, graph discovers Episodes, traces back to source Sentences. SQLite by default — swap to Postgres, Neo4j, Qdrant, or Milvus when you're ready to scale.
3333

3434
---
3535

@@ -49,7 +49,8 @@ Still improving. Run your own in [`/benchmarks`](benchmarks/).
4949
pip install vektori # SQLite + Postgres
5050
pip install 'vektori[neo4j]' # + Neo4j support
5151
pip install 'vektori[qdrant]' # + Qdrant support
52-
pip install 'vektori[neo4j,qdrant]' # all backends
52+
pip install 'vektori[milvus]' # + Milvus support
53+
pip install 'vektori[neo4j,qdrant,milvus]' # all backends
5354
```
5455

5556
No Docker, no external services. SQLite by default.
@@ -221,6 +222,21 @@ v = Vektori(
221222
embedding_dimension=1024,
222223
)
223224

225+
# Milvus — high-scale vector store with partition-key isolation
226+
v = Vektori(
227+
storage_backend="milvus",
228+
database_url="http://localhost:19530",
229+
embedding_dimension=1024,
230+
)
231+
232+
# Milvus / Zilliz Cloud
233+
v = Vektori(
234+
storage_backend="milvus",
235+
database_url="https://your-cluster-endpoint",
236+
milvus_token="your-api-key-or-token",
237+
embedding_dimension=1024,
238+
)
239+
224240
# In-memory — tests / CI
225241
v = Vektori(storage_backend="memory")
226242
```
@@ -229,7 +245,7 @@ v = Vektori(storage_backend="memory")
229245
```bash
230246
git clone https://github.com/vektori-ai/vektori
231247
cd vektori
232-
docker compose up -d # starts Postgres, Neo4j, and Qdrant
248+
docker compose up -d # starts Postgres, Neo4j, Qdrant, and Milvus
233249

234250
# Postgres
235251
DATABASE_URL=postgresql://vektori:vektori@localhost:5432/vektori python examples/quickstart_postgres.py
@@ -239,11 +255,18 @@ VEKTORI_STORAGE_BACKEND=neo4j VEKTORI_DATABASE_URL=bolt://localhost:7687 vektori
239255

240256
# Qdrant
241257
VEKTORI_STORAGE_BACKEND=qdrant VEKTORI_DATABASE_URL=http://localhost:6333 vektori add "I prefer dark mode" --user-id u1
258+
259+
# Milvus
260+
VEKTORI_STORAGE_BACKEND=milvus VEKTORI_DATABASE_URL=http://localhost:19530 vektori add "I prefer dark mode" --user-id u1
261+
262+
# Milvus Cloud
263+
MILVUS_TOKEN=your-api-key VEKTORI_STORAGE_BACKEND=milvus VEKTORI_DATABASE_URL=https://your-cluster-endpoint vektori add "I prefer dark mode" --user-id u1
242264
```
243265

244266
**CLI storage flags:**
245267
```bash
246268
vektori config --storage-backend qdrant --database-url http://localhost:6333
269+
vektori config --storage-backend milvus --database-url http://localhost:19530
247270
vektori add "my note" --user-id u1
248271
vektori search "preferences" --user-id u1
249272
```

docker-compose.yml

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,70 @@ services:
4747
timeout: 5s
4848
retries: 10
4949

50+
etcd:
51+
image: quay.io/coreos/etcd:v3.5.5
52+
environment:
53+
ETCD_AUTO_COMPACTION_MODE: revision
54+
ETCD_AUTO_COMPACTION_RETENTION: "1000"
55+
ETCD_QUOTA_BACKEND_BYTES: "4294967296"
56+
ETCD_SNAPSHOT_COUNT: "50000"
57+
command:
58+
- /usr/local/bin/etcd
59+
- -advertise-client-urls=http://127.0.0.1:2379
60+
- -listen-client-urls=http://0.0.0.0:2379
61+
- --data-dir=/etcd
62+
ports:
63+
- "2379:2379"
64+
volumes:
65+
- etcddata:/etcd
66+
healthcheck:
67+
test: ["CMD-SHELL", "ETCDCTL_API=3 etcdctl --endpoints=http://127.0.0.1:2379 endpoint health || exit 1"]
68+
interval: 5s
69+
timeout: 5s
70+
retries: 20
71+
72+
minio:
73+
image: minio/minio:RELEASE.2024-02-17T01-15-57Z
74+
environment:
75+
MINIO_ROOT_USER: minioadmin
76+
MINIO_ROOT_PASSWORD: minioadmin
77+
command: minio server /minio_data
78+
ports:
79+
- "9000:9000"
80+
volumes:
81+
- miniodata:/minio_data
82+
healthcheck:
83+
test: ["CMD-SHELL", "/usr/bin/mc ready local || exit 1"]
84+
interval: 5s
85+
timeout: 5s
86+
retries: 20
87+
88+
milvus:
89+
image: milvusdb/milvus:v2.5.3
90+
command: ["milvus", "run", "standalone"]
91+
environment:
92+
ETCD_ENDPOINTS: etcd:2379
93+
MINIO_ADDRESS: minio:9000
94+
ports:
95+
- "19530:19530" # Milvus API
96+
- "9091:9091" # Health/metrics
97+
volumes:
98+
- milvusdata:/var/lib/milvus
99+
depends_on:
100+
etcd:
101+
condition: service_healthy
102+
minio:
103+
condition: service_healthy
104+
healthcheck:
105+
test: ["CMD-SHELL", "curl -sf http://localhost:9091/healthz || exit 1"]
106+
interval: 5s
107+
timeout: 5s
108+
retries: 20
109+
50110
volumes:
51111
pgdata:
52112
neo4jdata:
53113
qdrantdata:
114+
etcddata:
115+
miniodata:
116+
milvusdata:
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
"""Local Vektori demo using Ollama + Milvus.
2+
3+
Prerequisites:
4+
1) Ollama running locally with:
5+
- nomic-embed-text
6+
- qwen2.5:1.5b (or adjust EXTRACTION_MODEL)
7+
2) Milvus available at http://localhost:19530
8+
9+
Run:
10+
python examples/ollama_milvus_session_demo.py
11+
"""
12+
13+
from __future__ import annotations
14+
15+
import asyncio
16+
17+
from vektori import Vektori
18+
19+
20+
EMBEDDING_MODEL = "ollama:nomic-embed-text"
21+
EXTRACTION_MODEL = "ollama:qwen2.5:1.5b"
22+
MILVUS_URL = "http://localhost:19530"
23+
24+
25+
async def main() -> None:
26+
# nomic-embed-text returns 768-dim vectors; Milvus schema must match.
27+
client = Vektori(
28+
storage_backend="milvus",
29+
database_url=MILVUS_URL,
30+
embedding_model=EMBEDDING_MODEL,
31+
extraction_model=EXTRACTION_MODEL,
32+
embedding_dimension=768,
33+
async_extraction=False,
34+
)
35+
36+
user_id = "demo-user-ollama-milvus"
37+
session_id = "session-ollama-milvus-001"
38+
39+
messages = [
40+
{
41+
"role": "user",
42+
"content": (
43+
"I live in Pune and work remotely as a backend engineer. "
44+
"I prefer calls between 9am and 11am IST, and avoid meetings after 6pm."
45+
),
46+
},
47+
{
48+
"role": "assistant",
49+
"content": "Understood. I will schedule calls in your preferred morning window.",
50+
},
51+
{
52+
"role": "user",
53+
"content": "I also like concise weekly updates every Monday morning.",
54+
},
55+
]
56+
57+
try:
58+
ingest_result = await client.add(
59+
messages=messages,
60+
session_id=session_id,
61+
user_id=user_id,
62+
metadata={"source": "local-demo"},
63+
)
64+
print("Ingestion:", ingest_result)
65+
66+
search_result = await client.search(
67+
query="When should I contact this user and what communication style do they prefer?",
68+
user_id=user_id,
69+
depth="l1",
70+
)
71+
72+
facts = search_result.get("facts", [])
73+
episodes = search_result.get("episodes", [])
74+
sentences = search_result.get("sentences", [])
75+
76+
print("\nFacts:")
77+
for fact in facts:
78+
print(f" - {fact.get('text')}")
79+
80+
print("\nEpisodes:")
81+
for episode in episodes:
82+
print(f" - {episode.get('text')}")
83+
84+
print("\nSentences:")
85+
for sentence in sentences[:5]:
86+
print(f" - {sentence.get('text')}")
87+
88+
finally:
89+
await client.close()
90+
91+
92+
if __name__ == "__main__":
93+
asyncio.run(main())

pyproject.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,7 @@ dynamic = ["version"]
88
description = "Open-source, self-hostable memory engine for AI agents using a three-layer sentence graph architecture."
99
readme = "README.md"
1010
license = { file = "LICENSE" }
11-
authors = [
12-
{ name = "Laxman & Manit" }
13-
]
11+
authors = [{ name = "Laxman & Manit" }]
1412
requires-python = ">=3.10"
1513
classifiers = [
1614
"Development Status :: 3 - Alpha",
@@ -36,6 +34,7 @@ dependencies = [
3634
postgres = ["asyncpg>=0.29", "pgvector>=0.2"]
3735
neo4j = ["neo4j>=5.14"]
3836
qdrant = ["qdrant-client>=1.7"]
37+
milvus = ["pymilvus>=2.5.3"]
3938
anthropic = ["anthropic>=0.20", "voyageai>=0.2"]
4039
sentence-transformers = ["sentence-transformers>=2.6"]
4140
bge = ["FlagEmbedding>=1.2"]
@@ -52,6 +51,7 @@ all = [
5251
"pgvector>=0.2",
5352
"neo4j>=5.14",
5453
"qdrant-client>=1.7",
54+
"pymilvus>=2.5.3",
5555
"anthropic>=0.20",
5656
"voyageai>=0.2",
5757
"sentence-transformers>=2.6",

0 commit comments

Comments
 (0)