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 vector
  • search_similar(query_vector, k, **options) — Returns list of {id, score, metadata, vector, distance} dictionaries
  • save(path) / load(path) — Persistence (where backend supports it)
  • delete(ids) / count() — Lifecycle operations

Each store converts Semantica's generic metadata filters into native backend formats:

  • Qdrant: Filter objects with must/should/must_not clauses
  • Pinecone: Python metadata dictionaries
  • PgVector: SQL WHERE clauses 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

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.

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.

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 VectorStore abstracts FAISS, Pinecone, Qdrant, PgVector, and Weaviate through a unified interface in semantica/vector_store/vector_store.py
  • Backend selection happens via the backend parameter 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 --backend flag 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →