Embedding Providers
Pluggable embedding provider system for semantic search, memory, and vector operations. Supports OpenAI, Voyage AI, Gemini, Sentence Transformers, and custom providers.
#Overview
Daita ships a dedicated embedding provider system that mirrors the LLM provider pattern: a shared base class, a factory with registry, and built-in providers you can swap without changing application code.
- OpenAI —
text-embedding-3-small,text-embedding-3-large - Voyage AI —
voyage-3and variants - Google Gemini — Google embedding models
- Sentence Transformers — local HuggingFace models (no API key required)
- Mock — deterministic vectors for testing
All providers include automatic LRU caching and tracing.
#Installation
The OpenAI embedding provider uses the core openai dependency. Other providers require optional extras:
# Voyage AI
pip install 'daita-agents[voyage]'
# Local models via HuggingFace
pip install 'daita-agents[sentence-transformers]'
# Google Gemini
pip install 'daita-agents[google]'#Quick Start
#Factory Pattern
from daita.embeddings import create_embedding_provider
# OpenAI (default)
embedder = create_embedding_provider("openai", model="text-embedding-3-small")
# Embed a single text
vector = await embedder.embed_text("Hello, world!")
# Batch embed
vectors = await embedder.embed_texts(["first", "second", "third"])#Direct Instantiation
from daita.embeddings.openai import OpenAIEmbeddingProvider
embedder = OpenAIEmbeddingProvider(
model="text-embedding-3-large",
api_key="sk-..."
)
vector = await embedder.embed_text("semantic search query")
print(f"Dimensions: {embedder.dimensions}")#Providers
#OpenAI
Uses OpenAI's embedding API. Default model: text-embedding-3-small (1536 dimensions).
embedder = create_embedding_provider(
"openai",
model="text-embedding-3-small", # or "text-embedding-3-large" (3072 dims)
api_key="sk-..." # or set OPENAI_API_KEY
)| Model | Dimensions | Notes |
|---|---|---|
text-embedding-3-small | 1536 | Fast, cost-effective default |
text-embedding-3-large | 3072 | Higher accuracy |
#Voyage AI
Uses Voyage AI's embedding API, optimised for retrieval tasks.
embedder = create_embedding_provider(
"voyage",
model="voyage-3",
api_key="pa-..." # or set VOYAGE_API_KEY
)Install with pip install 'daita-agents[voyage]'.
#Google Gemini
Uses Google's embedding models.
embedder = create_embedding_provider(
"gemini",
model="text-embedding-004",
api_key="AIza..." # or set GOOGLE_API_KEY
)Install with pip install 'daita-agents[google]'.
#Sentence Transformers
Run embeddings locally via HuggingFace Sentence Transformers. No API key required — models are downloaded and run on your machine.
embedder = create_embedding_provider(
"sentence-transformers",
model="all-MiniLM-L6-v2"
)Install with pip install 'daita-agents[sentence-transformers]'.
Note: Sentence Transformers is a local-only provider and is not supported in Daita Cloud deployments.
#Mock
Deterministic provider for testing. Returns stable vectors without any API calls.
embedder = create_embedding_provider("mock", model="test")
vector = await embedder.embed_text("anything")
# Returns a deterministic vector based on input hash#Using with the Memory Plugin
The Memory plugin uses embeddings internally for semantic search. By default it creates an OpenAI embedding provider, but you can inject a custom one:
from daita.plugins import MemoryPlugin
from daita.embeddings import create_embedding_provider
# Use Voyage AI embeddings for memory
embedder = create_embedding_provider("voyage", model="voyage-3")
memory = MemoryPlugin(embedder=embedder)The embedder parameter takes precedence over the embedding_provider and embedding_model string parameters.
#Custom Providers
Create custom embedding providers by subclassing BaseEmbeddingProvider:
from daita.embeddings import BaseEmbeddingProvider, register_embedding_provider
from typing import List
class MyEmbeddingProvider(BaseEmbeddingProvider):
"""Custom embedding provider."""
def __init__(self, model: str = "my-model", **kwargs):
super().__init__(model=model, **kwargs)
@property
def dimensions(self) -> int:
return 768
async def _embed_text_impl(self, text: str) -> List[float]:
# Your embedding logic here
return [0.0] * 768
async def _embed_texts_impl(self, texts: List[str]) -> List[List[float]]:
return [await self._embed_text_impl(t) for t in texts]
# Register for factory use
register_embedding_provider("my-provider", MyEmbeddingProvider)
# Now usable via factory
embedder = create_embedding_provider("my-provider")Subclasses implement three things:
dimensionsproperty — return the vector dimensionality_embed_text_impl(text)— embed a single text_embed_texts_impl(texts)— batch embed (override for providers with native batch APIs)
The base class handles LRU caching and tracing automatically.
#Caching
All providers include an LRU cache that avoids redundant API calls for repeated texts. Configure the cache size at construction:
embedder = create_embedding_provider(
"openai",
model="text-embedding-3-small",
cache_size=4096 # default: 2048
)Cache hits are free and instant. The cache is per-provider-instance and in-memory only.
#Best Practices
Provider Selection:
- Cloud agents: OpenAI or Voyage — low latency, high quality
- Local/offline: Sentence Transformers — no API key, no network
- Testing: Mock — deterministic, zero cost
Performance:
- Use
embed_texts()for batches — one API call instead of N - Tune
cache_sizefor workloads with repeated queries - Sentence Transformers is CPU/GPU bound; other providers are network bound
Consistency:
- Use the same provider and model for both storage and retrieval
- Mixing embedding models produces incompatible vector spaces
#Next Steps
- Memory Plugin — Semantic memory powered by embeddings
- LLM Providers — LLM providers for text generation
- Getting Started — Quick start tutorial