Daita Logo

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.

  • OpenAItext-embedding-3-small, text-embedding-3-large
  • Voyage AIvoyage-3 and 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:

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

python
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

python
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).

python
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
)
ModelDimensionsNotes
text-embedding-3-small1536Fast, cost-effective default
text-embedding-3-large3072Higher accuracy

#Voyage AI

Uses Voyage AI's embedding API, optimised for retrieval tasks.

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

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

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

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

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

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

  1. dimensions property — return the vector dimensionality
  2. _embed_text_impl(text) — embed a single text
  3. _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:

python
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_size for 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