Skip to content

Commit 13434a8

Browse files
committed
docs(blog): publish zvec vs Terraphim comparison article
Add comprehensive comparison of Alibaba's zvec neural vector database vs Terraphim's graph-based approach: - Core philosophy differences (embeddings vs knowledge graphs) - Architecture comparison (ANN vs graph traversal) - Feature matrix and performance characteristics - When to use which system - Code examples in Python (zvec) and Rust (Terraphim) - Integration opportunities for hybrid approaches
1 parent 36c2c5a commit 13434a8

1 file changed

Lines changed: 298 additions & 0 deletions

File tree

Lines changed: 298 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,298 @@
1+
---
2+
title: "zvec vs Terraphim: Two Paths to Semantic Search"
3+
description: "A deep dive comparing Alibaba's zvec neural vector database with Terraphim's graph-based approach to semantic search"
4+
author: "Terraphim Team"
5+
date: "2026-02-16"
6+
tags: ["vector-search", "knowledge-graph", "semantic-search", "comparison"]
7+
---
8+
9+
# zvec vs Terraphim: Two Paths to Semantic Search
10+
11+
When it comes to semantic search, there are fundamentally different architectural approaches. Alibaba's [zvec](https://github.com/alibaba/zvec) and Terraphim represent two distinct philosophies: neural embeddings vs. knowledge graphs, scale vs. interpretability, dense vectors vs. co-occurrence relationships.
12+
13+
Let's explore how these systems differ and when to choose one over the other.
14+
15+
## The Core Philosophy
16+
17+
### zvec: Neural Embeddings at Scale
18+
19+
zvec is a lightweight, in-process vector database built on Alibaba's battle-tested Proxima engine. It transforms documents into high-dimensional vectors using neural embedding models (BERT, OpenAI, etc.), then uses Approximate Nearest Neighbor (ANN) algorithms like HNSW to find similar documents.
20+
21+
**Key Characteristics:**
22+
- Dense vectors (typically 384-1536 dimensions)
23+
- ANN indexing (HNSW, IVF, Flat)
24+
- Built-in embedding models (OpenAI, Qwen, SentenceTransformers)
25+
- Billions of vectors, millisecond query times
26+
- Black-box interpretability
27+
28+
### Terraphim: Knowledge Graphs for Understanding
29+
30+
Terraphim takes a radically different approach. Instead of converting documents to opaque vectors, it builds a knowledge graph from term co-occurrences. Each concept becomes a node, relationships become edges, and relevance is calculated by traversing this graph structure.
31+
32+
**Key Characteristics:**
33+
- Co-occurrence graph embeddings
34+
- Aho-Corasick automata for fast pattern matching
35+
- Domain-specific thesauri for synonym expansion
36+
- Role-based graphs for persona-driven search
37+
- Fully explainable relevance scoring
38+
39+
## Architectural Comparison
40+
41+
```
42+
┌─────────────────────────────────────────────────────────────┐
43+
│ zvec │
44+
├─────────────────────────────────────────────────────────────┤
45+
│ Document → Neural Encoder → Dense Vector → HNSW Index │
46+
│ ↓ │
47+
│ Query → Neural Encoder → Query Vector → ANN Search → Top-K │
48+
└─────────────────────────────────────────────────────────────┘
49+
vs
50+
┌─────────────────────────────────────────────────────────────┐
51+
│ Terraphim │
52+
├─────────────────────────────────────────────────────────────┤
53+
│ Document → Term Extraction → Co-occurrence → Graph │
54+
│ ↓ │
55+
│ Query → Aho-Corasick Match → Graph Traversal → Ranked Docs │
56+
└─────────────────────────────────────────────────────────────┘
57+
```
58+
59+
### Data Structures
60+
61+
| Component | zvec | Terraphim |
62+
|-----------|------|-----------|
63+
| **Storage Unit** | Collection (table-like) | RoleGraph (knowledge graph) |
64+
| **Document ID** | String | String |
65+
| **Representations** | Dense/Sparse vectors (768-dim+) | Nodes, Edges, Thesaurus |
66+
| **Index Types** | HNSW, IVF, Flat, Inverted | Hash maps + Aho-Corasick |
67+
| **Persistence** | Disk-based collections | JSON serialization |
68+
69+
### Query Semantics
70+
71+
**zvec Query:**
72+
```python
73+
import zvec
74+
75+
# Semantic similarity via vector comparison
76+
results = collection.query(
77+
zvec.VectorQuery("embedding", vector=[0.1, -0.3, ...]),
78+
topk=10,
79+
filter="category == 'tech'"
80+
)
81+
# Returns: documents with similar vectors (cosine similarity)
82+
```
83+
84+
**Terraphim Query:**
85+
```rust
86+
// Graph traversal with term expansion
87+
let results = role_graph.query_graph(
88+
"async programming",
89+
Some(0), // offset
90+
Some(10) // limit
91+
);
92+
// Returns: documents ranked by graph connectivity
93+
// Matched nodes: "async", "programming", "concurrency", "tokio"
94+
```
95+
96+
## Feature Matrix
97+
98+
| Feature | zvec | Terraphim |
99+
|---------|------|-----------|
100+
| **Dense Embeddings** | ✅ Native | ❌ Not used |
101+
| **Sparse Vectors** | ✅ BM25 supported | ✅ BM25/BM25F/BM25Plus |
102+
| **Knowledge Graph** | ❌ No | ✅ Core architecture |
103+
| **ANN Search** | ✅ HNSW/IVF/Flat | ❌ Not applicable |
104+
| **SQL-like Filters** | ✅ SQL engine | ❌ Graph-based filtering |
105+
| **Explainability** | ⚠️ Low (black box) | ✅ High (show path) |
106+
| **Synonym Expansion** | ⚠️ Via embedding model | ✅ Via thesaurus |
107+
| **Role/Persona Support** | ❌ No | ✅ RoleGraphs |
108+
| **Multi-Haystack** | ❌ Single collection | ✅ Multiple sources |
109+
| **Built-in Rerankers** | ✅ RRF, Weighted | ❌ Graph ranks directly |
110+
| **Quantization** | ✅ INT8/FP16 | ❌ Not needed |
111+
| **Hybrid Search** | ✅ Vectors + Filters | ✅ Graph + Haystacks |
112+
113+
## Performance Characteristics
114+
115+
### zvec (Benchmarks from 10M vector dataset)
116+
117+
- **Throughput**: 2,000-8,000 QPS depending on configuration
118+
- **Recall**: 96-97% with HNSW
119+
- **Latency**: Milliseconds for 10M vectors
120+
- **Memory**: Compressed vectors (INT8/FP16)
121+
- **Scale**: Billions of vectors
122+
123+
### Terraphim (Observed Performance)
124+
125+
- **Throughput**: In-memory graph traversal (very fast)
126+
- **Recall**: Deterministic graph-based ranking
127+
- **Latency**: Sub-millisecond for typical graphs
128+
- **Memory**: Entire graph in memory
129+
- **Scale**: Thousands to tens of thousands of documents
130+
131+
## When to Use Which
132+
133+
### Choose zvec When:
134+
135+
1. **You need to search billions of documents**
136+
- ANN algorithms scale to massive datasets
137+
- Production workloads at Alibaba scale
138+
139+
2. **You're building RAG systems with LLMs**
140+
- Dense embeddings align with LLM representations
141+
- Built-in OpenAI/SentenceTransformer support
142+
143+
3. **You need image/audio similarity search**
144+
- Requires dense embeddings
145+
- CLIP-style multimodal search
146+
147+
4. **Exact semantic similarity matters**
148+
- "King - Man + Woman ≈ Queen" works
149+
- Captures semantic relationships beyond keywords
150+
151+
### Choose Terraphim When:
152+
153+
1. **You need explainable results**
154+
- "Why did this document rank high?"
155+
- Graph path shows: matched node X via edge Y to document Z
156+
157+
2. **You have domain-specific knowledge**
158+
- Custom thesauri for technical terms
159+
- Synonym relationships: "async" ↔ "asynchronous" ↔ "non-blocking"
160+
161+
3. **You're building personal knowledge management**
162+
- Note-taking apps, research assistants
163+
- Domain expert systems
164+
165+
4. **You need role-based search**
166+
- Different personas see different results
167+
- Engineer vs. Scientist vs. Writer views
168+
169+
## Code Comparison
170+
171+
### Document Indexing
172+
173+
**zvec (Python):**
174+
```python
175+
import zvec
176+
177+
schema = zvec.CollectionSchema(
178+
name="docs",
179+
vectors=zvec.VectorSchema("emb", zvec.DataType.VECTOR_FP32, 768),
180+
)
181+
182+
collection = zvec.create_and_open(path="./data", schema=schema)
183+
184+
# Documents must have pre-computed embeddings
185+
collection.insert([
186+
zvec.Doc(
187+
id="doc1",
188+
vectors={"emb": embedding_model.encode("Rust async programming")},
189+
fields={"title": "Async in Rust"}
190+
),
191+
])
192+
```
193+
194+
**Terraphim (Rust):**
195+
```rust
196+
use terraphim_rolegraph::RoleGraph;
197+
use terraphim_types::{Document, RoleName};
198+
199+
let mut graph = RoleGraph::new(
200+
RoleName::new("engineer"),
201+
thesaurus
202+
).await?;
203+
204+
// Documents are indexed into the graph
205+
graph.index_documents(vec![
206+
Document {
207+
id: "doc1".into(),
208+
title: "Async in Rust".into(),
209+
body: "Rust's async/await syntax...".into(),
210+
// Graph extracts terms automatically
211+
..Default::default()
212+
},
213+
]).await?;
214+
```
215+
216+
### Searching
217+
218+
**zvec:**
219+
```python
220+
# Vector similarity search
221+
query_vec = embedding_model.encode("how to write async code")
222+
results = collection.query(
223+
zvec.VectorQuery("emb", vector=query_vec),
224+
topk=5
225+
)
226+
# Results ranked by cosine similarity
227+
```
228+
229+
**Terraphim:**
230+
```rust
231+
// Graph-based search
232+
let results = graph.query_graph("async code", None, Some(5))?;
233+
// Results ranked by:
234+
// 1. Node rank (concept frequency)
235+
// 2. Edge rank (relationship strength)
236+
// 3. Document rank (occurrence count)
237+
```
238+
239+
## Can They Work Together?
240+
241+
Absolutely! Here are some integration patterns:
242+
243+
### 1. Hybrid Retrieval
244+
245+
Use zvec for initial broad retrieval, Terraphim for reranking:
246+
247+
```python
248+
# Step 1: zvec ANN for candidate retrieval
249+
candidates = zvec_collection.query(query_vector, topk=100)
250+
251+
# Step 2: Terraphim graph reranking
252+
# Load candidates into temporary graph
253+
# Re-rank based on knowledge graph connectivity
254+
```
255+
256+
### 2. Sparse BM25 in Terraphim
257+
258+
zvec includes a `BM25EmbeddingFunction` for sparse vectors. Terraphim could add this as another haystack:
259+
260+
```rust
261+
// Hypothetical: Terraphim with zvec-style sparse embeddings
262+
Haystack {
263+
service: ServiceType::BM25Sparse,
264+
embedding_function: "zvec::BM25EmbeddingFunction",
265+
}
266+
```
267+
268+
### 3. Explainable Vector Search
269+
270+
Use Terraphim's graph to explain zvec results:
271+
272+
```
273+
User: "Why did this document match?"
274+
System:
275+
- zvec: "Vector similarity: 0.92"
276+
- Terraphim: "Matched via concepts: async → tokio → concurrency"
277+
```
278+
279+
## Conclusion
280+
281+
zvec and Terraphim solve semantic search with fundamentally different approaches:
282+
283+
- **zvec** scales neural embeddings to billions of documents using ANN algorithms. It's the right choice for large-scale RAG systems, e-commerce search, and any application requiring dense vector similarity.
284+
285+
- **Terraphim** builds interpretable knowledge graphs from term relationships. It excels at personal knowledge management, domain-specific expert systems, and any application where understanding *why* a document matched is as important as finding it.
286+
287+
The exciting possibility is combining both: zvec's scale with Terraphim's explainability. The future of semantic search might just be hybrid.
288+
289+
## References
290+
291+
- zvec GitHub: https://github.com/alibaba/zvec
292+
- zvec Documentation: https://zvec.org/en/docs/
293+
- Terraphim Documentation: https://terraphim.ai/docs
294+
- Proxima (Alibaba's Vector Engine): https://github.com/alibaba/proxima
295+
296+
---
297+
298+
*Have you used zvec or Terraphim? We'd love to hear about your experiences in the comments or on [GitHub Discussions](https://github.com/terraphim/terraphim-ai/discussions).*

0 commit comments

Comments
 (0)