Cersei

Embeddings API

Full API reference for the cersei-embeddings crate — trait, providers, index, store, and factory.

cersei-embeddings API

Complete public surface. Every item here is re-exported from the crate root.


EmbeddingProvider

The single trait every embedding backend implements.

#[async_trait]
pub trait EmbeddingProvider: Send + Sync {
    fn name(&self) -> &str;
    fn dimensions(&self) -> usize;
    async fn embed(&self, text: &str) -> Result<Vec<f32>, EmbeddingError>;
    async fn embed_batch(&self, texts: &[String]) -> Result<Vec<Vec<f32>>, EmbeddingError>;
}
MethodDescription
name()Short identifier ("openai", "gemini", …) — handy for logging.
dimensions()Vector width. Used by VectorIndex to size the HNSW graph.
embed(text)Embed one string. Default impl calls embed_batch(&[text]).
embed_batch(texts)Embed many. Implementors handle provider-specific batch limits.

Implementing your own provider takes ~30 lines. See the cookbook.


GeminiEmbeddings

Google Gemini embeddings. Default model text-embedding-004 (768 dimensions), 100-per-batch chunking to respect the Gemini API limit, per-text character truncation at 2000.

use cersei_embeddings::GeminiEmbeddings;

// Explicit key
let provider = GeminiEmbeddings::new("AIza...");

// From GOOGLE_API_KEY or GEMINI_API_KEY
let provider = GeminiEmbeddings::from_env()?;

// Override model (remember to set dimensions if it differs from 768)
let provider = GeminiEmbeddings::from_env()?
    .with_model("text-embedding-004")
    .with_truncate_chars(4000);

Prop

Type


OpenAiEmbeddings

OpenAI (and OpenAI-compatible) embeddings. Default model text-embedding-3-small (1536 dimensions), base URL https://api.openai.com/v1, per-text truncation at 2000.

use cersei_embeddings::OpenAiEmbeddings;

// From OPENAI_API_KEY
let provider = OpenAiEmbeddings::from_env()?;

// Azure OpenAI / Ollama / any compatible endpoint
let provider = OpenAiEmbeddings::new("sk-...")
    .with_base_url("http://localhost:11434/v1")
    .with_model("nomic-embed-text")
    .with_dimensions(768);

Prop

Type


VectorIndex

Thin usearch::Index wrapper. HNSW approximate nearest-neighbor search with a configurable metric.

use cersei_embeddings::{VectorIndex, Metric};

let index = VectorIndex::new(1536, Metric::Cosine)?;
index.reserve(1_000)?;
index.add(42, &my_embedding)?;

let hits = index.search(&query_embedding, 10)?;
for hit in hits {
    println!("key={} sim={:.3} dist={:.3}", hit.key, hit.similarity, hit.distance);
}

One-shot construction from a batch of pre-computed embeddings

let vectors: Vec<Vec<f32>> = /* ... */;
let index = VectorIndex::from_vectors(&vectors, Metric::Cosine)?;
// Keys are 0..vectors.len()

Prop

Type

Metric

pub enum Metric { Cosine, L2, InnerProduct }
Metricusearch kindsimilarity formula
CosineCos1.0 - distance
L2L2sq1.0 / (1.0 + distance)
InnerProductIPdistance (already a similarity)

SearchHit

pub struct SearchHit {
    pub key: u64,
    pub distance: f32,
    pub similarity: f32,
}

EmbeddingStore<P>

Provider + index bundled together. Use it when the "add text → search by text" flow is all you need.

use cersei_embeddings::{EmbeddingStore, OpenAiEmbeddings, Metric};

let store = EmbeddingStore::new(OpenAiEmbeddings::from_env()?, Metric::Cosine)?;

store.add_batch(&[
    (1, "doc one text".into()),
    (2, "doc two text".into()),
]).await?;

let hits = store.search("query text", 5).await?;

Prop

Type


auto_from_model

Construct a provider by inferring the family from an LLM model string.

let provider: Box<dyn EmbeddingProvider> =
    cersei_embeddings::auto_from_model("openai/gpt-4o")?;

Detection rules (first match wins):

Model string contains or starts withProviderEnv var(s)
gpt, o1, o3, or openaiOpenAiEmbeddingsOPENAI_API_KEY
gemini or googleGeminiEmbeddingsGOOGLE_API_KEYGEMINI_API_KEY
anything elseOpenAiEmbeddings (default)OPENAI_API_KEY

Returns EmbeddingError::Config if the relevant key is missing or empty.


EmbeddingError

pub enum EmbeddingError {
    Http(reqwest::Error),   // transport failure
    Api(String),            // non-2xx from the API
    Parse(String),          // malformed response
    Index(String),          // usearch operation failed
    Config(String),         // missing / invalid configuration
}

Implements std::error::Error via thiserror and From<reqwest::Error> for ? ergonomics.

On this page