How to Configure Vector Stores (FAISS, Pinecone, Qdrant, PgVector) with Semantica: A Complete Guide
Configure any supported vector database in Semantica by setting the backend parameter in VectorStore—choose from "faiss", "qdrant", "pinecone", or "pgvector"—and pass backend-specific connection details to instantiate the concrete store class.
Semantica provides a backend-agnostic vector store abstraction that unifies FAISS, Pinecone, Qdrant, PgVector, and Weaviate under a single API. This design lets you swap vector databases without changing your application code. According to the semantica-agi/semantica source code, the VectorStore class in semantica/vector_store/vector_store.py orchestrates backend selection and delegates operations to specialized implementations.
Supported Vector Store Backends
Semantica supports five production-ready vector databases through dedicated modules in semantica/vector_store/:
| Backend | Module | Primary Classes | Best For |
|---|---|---|---|
| FAISS | faiss_store.py |
FAISSStore, FAISSIndex, FAISSSearch |
Local, in-process similarity search without external dependencies |
| Qdrant | qdrant_store.py |
QdrantStore, QdrantClient, QdrantCollection |
Self-hosted or cloud vector search with rich filtering |
| Pinecone | pinecone_store.py |
PineconeStore, PineconeClient, PineconeIndex |
Fully managed, scalable vector search SaaS |
| PgVector | pgvector_store.py |
PgVectorStore |
Existing PostgreSQL infrastructure with SQL-native queries |
| Weaviate | weaviate_store.py |
WeaviateStore |
GraphQL-based semantic search with modular AI integrations |
Each backend implements the same core interface: add_vectors(), search_similar(), save(), load(), delete(), and count().
Architecture: How Backend Selection Works
Backend Discovery in VectorStore.init
The VectorStore class maintains a SUPPORTED_BACKENDS registry. When you instantiate it with backend="qdrant" (or any supported value), VectorStore.__init__ performs a lazy import of the corresponding module:
# From semantica/vector_store/vector_store.py
class VectorStore:
SUPPORTED_BACKENDS = {"faiss", "qdrant", "pinecone", "pgvector", "weaviate"}
def __init__(self, backend: str, **backend_kwargs):
if backend not in self.SUPPORTED_BACKENDS:
raise ValueError(f"Unsupported backend: {backend}")
# Lazy import keeps optional dependencies truly optional
if backend == "faiss":
from .faiss_store import FAISSStore
self._backend_store = FAISSStore(**backend_kwargs)
elif backend == "qdrant":
from .qdrant_store import QdrantStore
self._backend_store = QdrantStore(**backend_kwargs)
# ... etc
Optional dependency guards (FAISS_AVAILABLE, QDRANT_AVAILABLE, etc.) ensure import errors are raised with helpful messages if required SDKs are missing.
Unified API Contract
All backend classes satisfy the VectorStore contract:
add_vectors(vectors, ids, metadata)— Bulk insertion with optional metadata per vectorsearch_similar(query_vector, k, **options)— Returns list of{id, score, metadata, vector, distance}dictionariessave(path)/load(path)— Persistence (where backend supports it)delete(ids)/count()— Lifecycle operations
Metadata Translation for Hybrid Search
Each store converts Semantica's generic metadata filters into native backend formats:
- Qdrant:
Filterobjects withmust/should/must_notclauses - Pinecone: Python
metadatadictionaries - PgVector: SQL
WHEREclauses with@@operator - FAISS: In-memory attribute filtering (if index supports it)
This enables vector + metadata hybrid search across all backends without query syntax changes.
Configuration Examples by Backend
FAISS: Local In-Memory Search
Use FAISS when you need zero external dependencies and can hold indexes in memory or on local disk.
from semantica.vector_store import FAISSStore
import numpy as np
# Initialize with embedding dimension
store = FAISSStore(dimension=768)
# Add vectors with string IDs
vectors = np.random.rand(1000, 768).astype('float32')
store.add_vectors(
vectors=vectors,
ids=[f"doc_{i}" for i in range(1000)],
metadata=[{"source": "local_docs"}] * 1000
)
# Search
results = store.search_similar(
query_vector=np.random.rand(1, 768).astype('float32'),
k=5
)
print(results) # [{id, score, metadata, vector, distance}, ...]
# Persist to disk
store.save("/path/to/faiss_index.bin")
Key classes in semantica/vector_store/faiss_store.py: FAISSStore wraps FAISSIndex for index management, FAISSSearch for query execution, and FAISSIndexBuilder for construction-time optimization.
Qdrant: Self-Hosted or Cloud
Use Qdrant when you need persistent collections, payload filtering, and horizontal scaling.
from semantica.vector_store import QdrantStore
# Connect to Qdrant server
store = QdrantStore(
url="http://localhost:6333", # or cloud endpoint
api_key=None # set for Qdrant Cloud
)
store.connect()
# Create collection with cosine similarity
store.create_collection(
name="semantic_search",
vector_size=768,
distance="Cosine" # also "Euclid", "Dot"
)
# Insert with metadata for filtering
store.add_vectors(
vectors=np.random.rand(500, 768).astype('float32'),
ids=list(range(500)),
metadata=[{"category": "tech", "year": 2024}] * 500
)
# Hybrid search: vector similarity + metadata filter
results = store.search_similar(
query_vector=np.random.rand(1, 768).astype('float32'),
k=10,
filter={
"must": [
{"key": "category", "match": {"value": "tech"}},
{"key": "year", "range": {"gte": 2023}}
]
}
)
The QdrantStore class in semantica/vector_store/qdrant_store.py manages QdrantClient connections and QdrantCollection lifecycle. QdrantSearch handles payload-aware similarity queries.
Pinecone: Managed Vector Search
Use Pinecone when you want serverless scaling without infrastructure management.
from semantica.vector_store import PineconeStore
# Authenticate and connect
store = PineconeStore(
api_key="YOUR_PINECONE_API_KEY",
environment="us-west1-gcp" # or "us-east-1-aws", etc.
)
store.connect()
# Create index (one-time setup)
store.create_index(
name="semantic-index",
dimension=768,
metric="cosine" # or "dotproduct", "euclidean"
)
# Target specific index for operations
store.use_index("semantic-index")
# Upsert vectors with metadata
store.add_vectors(
vectors=np.random.rand(100, 768).astype('float32'),
ids=[str(i) for i in range(100)],
metadata=[{"topic": "machine_learning", "priority": "high"}] * 100
)
# Query with optional namespace
results = store.search_similar(
query_vector=np.random.rand(1, 768).astype('float32'),
k=5,
namespace=None # for multi-tenant isolation
)
PineconeStore in semantica/vector_store/pinecone_store.py wraps the official PineconeClient, with PineconeIndex for index operations and PineconeSearch for query execution.
PgVector: PostgreSQL-Native Vectors
Use PgVector when your application already runs on PostgreSQL and you want to keep vectors with relational data.
from semantica.vector_store import PgVectorStore
# Connection string with pgvector extension enabled
store = PgVectorStore(
connection_string="postgresql://user:pass@localhost:5432/semantic_db"
)
store.connect()
# Ensure table exists (creates with pgvector column)
store.ensure_table(
table_name="document_vectors",
dimension=768,
metric="cosine" # creates appropriate HNSW index
)
# Insert with JSONB metadata
store.add_vectors(
vectors=np.random.rand(200, 768).astype('float32'),
ids=list(range(200)),
metadata=[{"doc_id": f"doc_{i}", "section": "header"} for i in range(200)]
)
# Search with SQL filter
results = store.search_similar(
query_vector=np.random.rand(1, 768).astype('float32'),
k=5,
filter_sql="metadata->>'section' = 'header'"
)
PgVectorStore in semantica/vector_store/pgvector_store.py uses psycopg2 with the pgvector Python client. The ensure_table() method verifies the vector extension is installed and creates optimized HNSW or IVFFlat indexes.
Weaviate: GraphQL Semantic Search
Use Weaviate for GraphQL-native queries and modular AI integrations.
from semantica.vector_store import WeaviateStore
store = WeaviateStore(
url="http://localhost:8080", # or WCS cloud URL
auth_client_secret="YOUR_API_KEY" # for WCS
)
store.connect()
# Schema is auto-created based on configuration
store.create_schema(
class_name="Document",
vectorizer=None, # use custom vectors (Semantica handles embeddings)
properties=[
{"name": "title", "dataType": ["text"]},
{"name": "category", "dataType": ["text"]}
]
)
store.add_vectors(
vectors=np.random.rand(50, 768).astype('float32'),
ids=[f"uuid-{i}" for i in range(50)],
metadata=[{"title": f"Doc {i}", "category": "research"} for i in range(50)]
)
# Near-vector search with GraphQL filter
results = store.search_similar(
query_vector=np.random.rand(1, 768).astype('float32'),
k=5,
filter_path=["category"],
filter_value="research"
)
CLI Configuration
Semantica's command-line interface in semantica/vector_store/cli.py exposes vector store selection via the --backend flag:
# Index documents using Qdrant
python -m semantica index \
--source /path/to/documents \
--backend qdrant \
--qdrant-url http://localhost:6333
# Search using existing Pinecone index
python -m semantica search \
--query "machine learning applications" \
--backend pinecone \
--pinecone-api-key $PINECONE_KEY \
--pinecone-index my-index
The CLI forwards backend and backend-specific arguments to VectorStore.__init__, demonstrating the same abstraction pattern used programmatically.
Dependency Requirements
Install only the SDKs you need:
# FAISS only
pip install faiss-cpu # or faiss-gpu for CUDA
# Qdrant only
pip install qdrant-client
# Pinecone only
pip install pinecone-client
# PgVector only
pip install psycopg2-binary pgvector
# Weaviate only
pip install weaviate-client
# All backends
pip install faiss-cpu qdrant-client pinecone-client psycopg2-binary pgvector weaviate-client
Semantica's lazy imports ensure missing optional dependencies raise clear errors only when that backend is instantiated.
Performance and Feature Comparison
| Feature | FAISS | Qdrant | Pinecone | PgVector | Weaviate |
|---|---|---|---|---|---|
| Deployment | Local/embedded | Self-hosted/cloud | Fully managed | PostgreSQL extension | Self-hosted/cloud |
| Persistence | File-based | Server persistence | Server persistence | PostgreSQL tables | Server persistence |
| Metadata filtering | Limited | Rich payload filters | Metadata filters | SQL WHERE | GraphQL filters |
| Hybrid search | Approximate | Full support | Full support | SQL + vector | Full support |
| Horizontal scaling | Manual sharding | Built-in | Automatic | Read replicas | Built-in |
| Best for | Prototyping, edge | Production, multi-tenant | Serverless scale | SQL-centric apps | GraphQL-native apps |
Summary
- Semantica's
VectorStoreabstracts FAISS, Pinecone, Qdrant, PgVector, and Weaviate through a unified interface insemantica/vector_store/vector_store.py - Backend selection happens via the
backendparameter with lazy imports guarding optional dependencies - All backends implement
add_vectors(),search_similar(), and persistence methods with identical signatures - Metadata filters are automatically translated to each backend's native query language
- CLI support provides
--backendflag for command-line workflows
Frequently Asked Questions
How do I switch from FAISS to Qdrant without changing my code?
Change only the initialization call. Replace FAISSStore(dimension=768) with QdrantStore(url="http://localhost:6333") and ensure your add_vectors() and search_similar() calls use the same parameters. The unified API in semantica/vector_store/vector_store.py ensures method compatibility across backends.
Does Semantica support multiple vector stores simultaneously?
Yes. Instantiate separate store objects for each backend in the same process. Each maintains independent state through its _backend_store attribute. There is no global singleton—VectorStore instances are fully isolated.
What happens if I try to use PgVector without installing psycopg2?
PgVectorStore.__init__ checks PGVECTOR_AVAILABLE (set by attempting import pgvector). If unavailable, it raises ImportError with instructions to pip install psycopg2-binary pgvector. This lazy import pattern applies to all optional backends in semantica-agi/semantica.
Can I use Weaviate's built-in vectorizers instead of providing embeddings?
No—Semantica manages embedding generation externally and passes vectors to WeaviateStore.add_vectors(). Set vectorizer=None in create_schema() as shown in the Weaviate example above. This design keeps Semantica's embedding pipeline consistent across all backends.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →