Concepts

Embeddings

Why Voyage voyage-code-3, how dimensions are pinned, and what the bench data looks like.

Prometheus uses a single embedding model per workspace, pinned by dimension. Today that model is Voyage AI voyage-code-3 at 1024 dimensions.

Why Voyage voyage-code-3

The Phase 2.5 bench shootout (see docs/benchmarks/2026-05-21-phase-2.5-baseline.md in the repo) compared four production-grade options against a curated TypeScript and Python retrieval set:

ModelDimRecall@10Notes
Voyage voyage-code-310240.91Best recall, fast, code-tuned.
Voyage voyage-3-large10240.88General-purpose; good fallback.
OpenAI text-embedding-3-large30720.87Higher dim, marginal gain, US-only.
OpenAI text-embedding-3-small15360.79Cheap baseline.

Voyage's code-tuned model beat the OpenAI options on the metric that matters for an agent's downstream answer quality (Recall@10), at roughly a third of the OpenAI 3-large token cost.

Dimension pinning

The Supabase embeddings.vector column is declared vector(1024) with an HNSW index over vector_cosine_ops. The indexer worker asserts at boot that the configured embedder produces 1024-dim vectors and refuses to start otherwise. That guard exists so a config typo cannot silently corrupt the index with mismatched dimensions.

If you need to switch dimensions later, that's a Phase 2.7-style migration: new column, parallel re-embed, atomic index swap, drop the old column. The worker carries the plumbing for it but we have not needed it since the migration to 1024.

Provider pluggability

The Embedder interface is provider-agnostic. Voyage is the default; OpenAI 3-large is the implemented fallback. Adding a new provider is <100 lines — implement Embedder.embedBatch(texts: string[]): Promise<number[][]> and register it in discoverProviders().

Region implications

Voyage runs in us. That makes the embedding call the single non-EU hop in an otherwise EU-resident pipeline. The Region mode doc covers how to opt out of it.