Skip to content
Packages Examples Agents Blog Get started

Vector storage infrastructure for the Oridecon Framework with Qdrant, ChromaDB, PGVector, Pinecone, and in-memory backends. Provides embedding clients, vector search, hybrid retrieval, reranking, and Named DI multi-store support.


Vector storage infrastructure for the Oridecon Framework with Qdrant, ChromaDB, PGVector, Pinecone, and in-memory backends. Provides embedding clients, vector search, hybrid retrieval, reranking, and Named DI multi-store support.

Architecture note: This package provides infrastructure and data-layer functionality for vector storage and retrieval. While it is commonly used by AI and RAG features (oridecon-ai-rag), it is a general-purpose vector database abstraction suitable for any use case requiring semantic search, similarity matching, or high-dimensional data storage.

Full documentation: docs.oridecon.dev

Deep-dive guide: Vector Stores in oridecon-vector

Terminal window
uv add oridecon oridecon-vector
# With Qdrant support
uv add "oridecon-vector[qdrant]"
# With ChromaDB support
uv add "oridecon-vector[chroma]"
# With PGVector support (requires oridecon-sql for database access)
uv add "oridecon-vector[pgvector]"
# With Pinecone support
uv add "oridecon-vector[pinecone]"
# With embedding support
uv add openai # or anthropic, cohere, etc.
import asyncio
from oridecon import Application
from oridecon.contracts.data.vector import (
CollectionConfig,
SearchQuery,
VectorRecord,
VectorStoreProtocol,
)
from oridecon.vector import VectorModule
async def main() -> None:
async with Application.boot(modules=[VectorModule.stub()]) as app:
store = await app.container.resolve(VectorStoreProtocol)
# Create a collection
await store.create_collection(
CollectionConfig(name="documents", dimension=1536)
)
# Upsert vectors through the collection handle
collection = await store.get_collection("documents")
await collection.upsert(
[
VectorRecord(
id="doc1",
vector=[0.1] * 1536,
metadata={"title": "Document 1", "category": "tech"},
),
VectorRecord(
id="doc2",
vector=[0.2] * 1536,
metadata={"title": "Document 2", "category": "science"},
),
]
)
# Search
results = await collection.search(SearchQuery(vector=[0.15] * 1536, top_k=5))
for result in results:
print(f"{result.id}: {result.metadata['title']} (score: {result.score})")
if __name__ == "__main__":
asyncio.run(main())

Zero-config usage: Call VectorModule.configure() with no arguments to start with all built-in defaults — no config file or environment variables needed. See the Config reference below for all default values.

Option 1 — YAML file (use when config lives in a single explicit file)

Section titled “Option 1 — YAML file (use when config lives in a single explicit file)”

Declare config in a YAML file loaded at a fixed, explicit path. ORI_* environment variables override YAML values at startup.

config_section = "vector" is already set on this class — section= can be omitted in all calls. Pass an explicit section= only to override the default (e.g. when this config is nested under a non-standard key).

# application.yaml — copy example.yaml for a fully-annotated starting point
vector:
backend: "qdrant" # memory, pgvector, pinecone, qdrant, chroma
default_dimension: 1536 # 1536 = OpenAI text-embedding-3-small
upsert_batch_size: 100
qdrant:
url: "http://localhost:6333"
api_key: null # ORI_VECTOR__QDRANT__API_KEY

Then load and wire it in your composition root:

from oridecon.vector.config import VectorConfig
from oridecon.vector import VectorModule
config = VectorConfig.from_yaml("application.yaml")
app.add_module(VectorModule.configure(config))

Environment variables override YAML values and use the ORI_VECTOR__ prefix:

Terminal window
ORI_VECTOR__BACKEND=qdrant
Section titled “Option 2 — Profiles + Environment Variables (recommended for production, staging, Docker, CI/CD)”

Loads a base application.yaml, then overlays an environment-specific file (application.production.yaml, application.staging.yaml, etc.) based on the ORI_PROFILE environment variable. ORI_* env vars are applied last as the final override layer.

Terminal window
# Set ORI_VECTOR__* env vars before starting the process
export ORI_VECTOR__ENABLED=true
from oridecon.vector.config import VectorConfig
from oridecon.vector import VectorModule
config = VectorConfig.from_env_profile()
app.add_module(VectorModule.configure(config))

Loading order: application.yaml (base) → application.{profile}.yaml (overlay, if ORI_PROFILE is set) → ORI_* environment variables (final override). Missing files are silently skipped so this is safe to call in all environments.

Option 3 — Python (use when config is dynamic or computed at boot)

Section titled “Option 3 — Python (use when config is dynamic or computed at boot)”

Build config in code at boot time. Use this when settings are derived at runtime — e.g. secrets fetched from a vault, per-tenant configurations, or when you need multiple module instances with different settings.

from oridecon.vector import VectorModule
from oridecon.vector.config import QdrantConfig, VectorConfig
app.add_module(
VectorModule.configure(
VectorConfig(
backend="qdrant",
qdrant=QdrantConfig(
url="http://localhost:6333",
),
)
)
)

Top-level configuration loaded from application.yaml’s vector: key or from ORI_VECTOR__* environment variables.

FieldDefaultEnv varDescription
enabledTrueORI_VECTOR__ENABLEDEnable the vector store subsystem
backend"memory"ORI_VECTOR__BACKENDVector store backend ("memory", "qdrant", "chroma", "pgvector", "pinecone")
default_distance_metricDistanceMetric.COSINEORI_VECTOR__DEFAULT_DISTANCE_METRICDefault distance metric for new collections
default_index_typeIndexType.HNSWORI_VECTOR__DEFAULT_INDEX_TYPEDefault index type for new collections
default_dimension1536ORI_VECTOR__DEFAULT_DIMENSIONDefault vector dimension (matches OpenAI text-embedding-ada-002)
upsert_batch_size100ORI_VECTOR__UPSERT_BATCH_SIZENumber of vectors per upsert batch
max_retries3ORI_VECTOR__MAX_RETRIESMaximum number of retries for operations
retry_delay0.5ORI_VECTOR__RETRY_DELAYDelay between retries in seconds
pgvectorPgVectorConfig()PGVector-specific settings
pineconePineconeConfig()Pinecone-specific settings
qdrantQdrantConfig()Qdrant-specific settings
weaviateWeaviateConfig()Weaviate-specific settings
memoryMemoryConfig()In-memory-specific settings
backends[]List of NamedVectorConfig entries for multi-store support
tenancyVectorTenancyConfig()Per-tenant collection isolation (VectorTenancyConfig)
collection_name"default"ORI_VECTOR__COLLECTION_NAMEDefault collection name for AI-layer operations
enable_cacheFalseORI_VECTOR__ENABLE_CACHEEnable embedding caching (requires a CacheBackend binding)
cache_ttl86400ORI_VECTOR__CACHE_TTLEmbedding cache TTL in seconds (default: 24 hours)

When backends is non-empty, each entry is registered under Annotated[VectorStoreProtocol, Named(entry.name)]. The first entry (or the one with primary=True) also receives the unnamed VectorStoreProtocol binding for backward compatibility.

FieldDefaultEnv varDescription
url"http://localhost:6333"ORI_VECTOR__QDRANT__URLQdrant server URL
api_keyNoneORI_VECTOR__QDRANT__API_KEYQdrant API key (optional)
grpc_port6334ORI_VECTOR__QDRANT__GRPC_PORTgRPC port for Qdrant
prefer_grpcTrueORI_VECTOR__QDRANT__PREFER_GRPCWhether to prefer gRPC over HTTP
timeout30.0ORI_VECTOR__QDRANT__TIMEOUTRequest timeout in seconds
FieldDefaultEnv varDescription
database"primary"ORI_VECTOR__PGVECTOR__DATABASEName of the database backend from db.backends to use
schema"public"ORI_VECTOR__PGVECTOR__SCHEMADatabase schema for vector tables
default_lists100ORI_VECTOR__PGVECTOR__DEFAULT_LISTSDefault number of lists for IVFFlat index
default_probes10ORI_VECTOR__PGVECTOR__DEFAULT_PROBESDefault number of probes for IVFFlat index
default_ef_search64ORI_VECTOR__PGVECTOR__DEFAULT_EF_SEARCHDefault ef_search for HNSW index
table_prefix"vec_"ORI_VECTOR__PGVECTOR__TABLE_PREFIXPrefix for vector storage tables
create_extensionTrueORI_VECTOR__PGVECTOR__CREATE_EXTENSIONWhether to create pgvector extension if missing

Note: PGVector requires oridecon-sql and a configured DatabaseProviderProtocol. The database field refers to a named database backend from db.backends.

FieldDefaultEnv varDescription
api_key""ORI_VECTOR__PINECONE__API_KEYPinecone API key (required)
environment""ORI_VECTOR__PINECONE__ENVIRONMENTPinecone environment (e.g., "us-west1-gcp")
index_name""ORI_VECTOR__PINECONE__INDEX_NAMEName of the Pinecone index
namespace""ORI_VECTOR__PINECONE__NAMESPACEDefault namespace for the index
timeout30.0ORI_VECTOR__PINECONE__TIMEOUTRequest timeout in seconds
pool_threads4ORI_VECTOR__PINECONE__POOL_THREADSNumber of threads for the connection pool
FieldDefaultEnv varDescription
max_collections100ORI_VECTOR__MEMORY__MAX_COLLECTIONSMaximum number of collections in memory
max_vectors_per_collection100,000ORI_VECTOR__MEMORY__MAX_VECTORS_PER_COLLECTIONMaximum number of vectors per collection

Configuration for a single named vector store backend (used in multi-store setups):

FieldDescription
nameUnique backend identifier (used as the Named() DI key)
primaryWhether this backend also receives the unnamed VectorStoreProtocol binding
backendVector store driver for this named backend
pgvectorPgVectorConfig for this backend
pineconePineconeConfig for this backend
qdrantQdrantConfig for this backend
memoryMemoryConfig for this backend

Example multi-store setup:

from oridecon.vector.config import (
NamedVectorConfig,
PgVectorConfig,
QdrantConfig,
VectorConfig,
)
VectorModule.configure(
VectorConfig(
backends=[
NamedVectorConfig(
name="primary",
primary=True,
backend="qdrant",
qdrant=QdrantConfig(
url="http://qdrant-primary:6333",
),
),
NamedVectorConfig(
name="rag",
backend="pgvector",
pgvector=PgVectorConfig(
database="rag",
schema="vectors",
),
),
]
)
)

Inject named stores:

from typing import Annotated
from oridecon.contracts.data.vector.protocols import VectorStoreProtocol
from oridecon.di.markers import Named
class MyService:
def __init__(
self,
store: VectorStoreProtocol, # primary
rag: Annotated[VectorStoreProtocol, Named("rag")],
) -> None:
self.store = store
self.rag = rag
MethodDescription
VectorModule.configure(config=None, enable_reranking=False)Vector store with explicit VectorConfig; registers VectorStoreProtocol and VectorCollectionProtocol. enable_reranking enables cross-encoder reranking of retrieval results
VectorModule.stub(config=None)In-memory backend with no external service dependencies, for tests
  • Multi-backend vector storage — Qdrant, ChromaDB, PGVector, Pinecone, and in-memory backends
  • Embedding client — OpenAI-compatible async client for generating embeddings (OpenAICompatibleEmbeddingClient)
  • Embedding cache — In-memory and persistent caching to reduce embedding API calls (EmbeddingCache, InMemoryEmbeddingCache)
  • Vector search — Similarity search with metadata filtering and distance metrics
  • Hybrid retrieval — BM25 + vector search with reciprocal rank fusion (HybridRetriever, BM25Retriever, RRFReranker)
  • Reranking — Cross-encoder reranking, diversity reranking, and similarity reranking for improved relevance (CrossEncoderReranker, DiversityReranker, RerankerPipeline)
  • Metadata filtering — Structured filtering on metadata fields with backend-specific filter compilers
  • Named DI multi-store — Multiple vector stores registered as Annotated[VectorStoreProtocol, Named("rag")]
  • Collection management — Create, delete, list collections with automatic schema inference
  • Batch operations — Efficient batch upsert, delete, and search with configurable batch sizes
  • Distance metrics — Cosine, Euclidean, and dot product similarity metrics
  • Index types — HNSW, IVFFlat, and backend-specific index configuration
async with Application.boot(modules=[VectorModule.stub()]) as app:
store = await app.container.resolve(VectorStoreProtocol)
# Test with the in-memory backend
...
FileWhat it contains
src/oridecon/vector/module.pyVectorModule.configure() and .stub()
src/oridecon/vector/config.pyVectorConfig, VectorTenancyConfig, NamedVectorConfig, backend configs
src/oridecon/vector/di/provider.pyVectorProvider boot and registration
src/oridecon/vector/di/factories.pyFactory functions for creating vector stores
src/oridecon/vector/backends/qdrant/Qdrant backend implementation
src/oridecon/vector/backends/pgvector/PGVector backend implementation
src/oridecon/vector/backends/pinecone/Pinecone backend implementation
src/oridecon/vector/backends/chroma.pyChromaDB backend implementation
src/oridecon/vector/backends/memory.pyIn-memory backend implementation
src/oridecon/vector/tenancy/Tenancy resolver, decorator, and Pinecone namespace resolver
src/oridecon/vector/embedding/client.pyOpenAICompatibleEmbeddingClient
src/oridecon/vector/embedding/cache.pyEmbedding cache implementations
src/oridecon/vector/search/hybrid.pyHybrid retrieval and BM25
src/oridecon/vector/search/reranking.pyReranking strategies
src/oridecon/vector/adapters/vector_store.pyVectorStoreAdapter
src/oridecon/vector/adapters/document_store.pyDocumentVectorStoreAdapter