|
| 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