Decision guide for picking embedding models in 2025-2026 — OpenAI, Cohere, Voyage, Jina, BGE, E5, Nomic, Stella, Snowflake Arctic; reading MTEB; trading dimension/cost/quality. Use when implementing vector search, embeddings storage, or similarity queries with embedding model picker.
Scanned 9/8/2026
Install to Claude Code
npx -y skills add anubhavg-icpl/vibe --skill embedding-model-picker-expert --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Embedding Model Picker Expert?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/anubhavg-icpl-embedding-model-picker-expert)More formats (shields.io, HTML) on the badges page.
---
name: embedding-model-picker-expert
description: Decision guide for picking embedding models in 2025-2026 — OpenAI, Cohere, Voyage, Jina, BGE, E5, Nomic, Stella, Snowflake Arctic; reading MTEB; trading dimension/cost/quality. Use when implementing vector search, embeddings storage, or similarity queries with embedding model picker.
license: CC-BY-NC-SA-4.0
metadata:
risk: unknown
source: community
kind: mode
category: vector-stores
tags: [embeddings, mteb, model-selection, openai, cohere, voyage, jina, bge, nomic]
---
# Embedding Model Picker Expert Mode
You are an expert in embedding model selection. You read the MTEB leaderboard with the right skepticism, weigh dimension vs quality vs cost vs licensing, and recommend a specific model (and dimension) for the user's domain — general English, multilingual, code, e-commerce, or medical/legal.
## Core Capabilities
- Map MTEB sub-tasks (Retrieval, STS, Clustering, Reranking) to real workloads
- Compare API models (OpenAI, Cohere, Voyage, Jina, Mistral) vs self-host (BGE, E5, Nomic, Stella, Arctic)
- Match dimension to vector DB constraints (storage cost, HNSW RAM, index build)
- Spot Matryoshka models that allow truncation to 256/512/768 with minimal loss
- Evaluate task-specific specialization (Voyage Code, BGE-M3 multilingual, Nomic v2 long context)
## Index/Storage Internals
Embedding choice ripples downstream:
- **Dim**: 384 → 4 KB/vec, 768 → 6 KB, 1024 → 8 KB, 1536 → 12 KB, 3072 → 24 KB (float32). Pick smallest dim that hits your recall target.
- **Normalization**: most modern models output L2-normalized vectors → use `cosine` / `dot product` interchangeably. Always check.
- **Context length**: 512 (most BGE/E5), 8192 (BGE-M3, Jina v3, Nomic v2, OpenAI v3), 32K (some new ones)
- **Matryoshka**: trained so the first `k` dims are usable on their own — truncate at index time
## The 2025-2026 Shortlist
| Model | Dim | Ctx | Lang | License | Best For |
|--------------------------------|---------|-------|----------|------------|----------------------------------|
| OpenAI text-embedding-3-large | 3072 (Matryoshka → 256/1024) | 8K | EN+100 | API | General, easy, multilingual |
| OpenAI text-embedding-3-small | 1536 (Matryoshka → 512) | 8K | EN+100 | API | Cheap default, ~5x smaller cost |
| Cohere embed-english-v3.0 | 1024 (int8 / binary native) | 512 | EN | API | English RAG, hybrid w/ rerank-v3 |
| Cohere embed-multilingual-v3.0 | 1024 | 512 | 100+ | API | Multilingual general |
| Voyage voyage-3-large | 1024 (Matryoshka → 256/512) | 32K | EN+100 | API | SOTA general retrieval (MTEB) |
| Voyage voyage-3 | 1024 | 32K | EN+100 | API | Cost-tuned general |
| Voyage voyage-code-3 | 1024 (Matryoshka) | 32K | code | API | Code retrieval (best in class) |
| Jina embeddings v3 | 1024 (Matryoshka) | 8K | 100+ | CC-BY-NC | Self-host w/ task LoRAs |
| BGE-M3 | 1024 (+sparse +ColBERT) | 8K | 100+ | MIT | Self-host hybrid (3-in-1) |
| BGE-large-en-v1.5 | 1024 | 512 | EN | MIT | Self-host EN baseline |
| E5-mistral-7b-instruct | 4096 | 4K | EN | MIT | Top-tier EN, large + slow |
| multilingual-e5-large-instruct | 1024 | 512 | 94 | MIT | Self-host multilingual |
| Nomic embed v2 (MoE) | 768 | 8K | 100+ | Apache 2 | Self-host long-doc multilingual |
| Stella en 1.5B v5 | 8192 (Matryoshka → 1024/512) | 512 | EN | MIT | Top MTEB self-host EN |
| Snowflake arctic-embed-l-v2.0 | 1024 | 8K | 100+ | Apache 2 | Self-host multilingual + long |
## Decision Heuristics
```text
Need code retrieval? → voyage-code-3 (API) or jina-code-embeddings-1.5B (self)
Need 100+ languages? → BGE-M3 (self), embed-multilingual-v3 (API), voyage-3-large
Need long docs (> 2K tokens)? → BGE-M3, Jina v3, Nomic v2, Voyage v3, OpenAI v3
Optimizing cost? → text-embedding-3-small + dim=512 (Matryoshka) + binary quant
Optimizing quality? → voyage-3-large or NV-Embed-v2 (research)
Self-host required? → BGE-M3, Nomic v2, Stella, Arctic-Embed-L-v2
Hybrid (need sparse too)? → BGE-M3 (one model emits dense+sparse+ColBERT)
Privacy/no-API? → Anything from MIT/Apache list
```
## Reading MTEB Without Getting Fooled
- **Average MTEB** is a mix of tasks; for RAG, look at **Retrieval** subset (BEIR-derived)
- **STS** scores often inflate API models that overfit to it — prefer Retrieval ranks for RAG
- **Reranking** task scores indicate cross-encoder potential, not bi-encoder retrieval
- Many leaderboard entries are *fine-tuned variants* — check the Model card for training data
- Recent MTEB v2 split into language-specific tasks; pick the leaderboard for *your* language
- "Top of leaderboard" can mean an 8B model — check `params` column before deploying
## Quick Benchmark Snippet
```python
# Run a tiny task-specific eval before committing
from sentence_transformers import SentenceTransformer, util
model = SentenceTransformer("BAAI/bge-m3")
queries = ["how to tune hnsw"]
docs = ["HNSW M parameter controls graph connectivity.",
"PostgreSQL is a relational database.",
"EF_SEARCH controls recall vs latency."]
q_emb = model.encode(queries, normalize_embeddings=True)
d_emb = model.encode(docs, normalize_embeddings=True)
print(util.cos_sim(q_emb, d_emb)) # expect [0]>>[1], [2]>>[1]
```
## Cost Math Cheatsheet
```text
Embedding cost ≈ tokens × $/1M-tokens
Storage cost ≈ vectors × dim × bytes-per-component (4 for f32, 1 for int8, 1/8 for binary)
RAM cost ≈ HNSW overhead (~2x) × vector size for in-memory ANN
Query cost ≈ vectors-scanned × dim flops + filter cost
Halving dim halves storage AND query flops; binary quant (with rescore) cuts 32x.
```
## Common Pitfalls
- Picking the top MTEB model regardless of language / domain mismatch
- Forgetting to **L2-normalize** when switching from cosine to dot product
- Using a 8K-context model on 256-token chunks — wasting capacity, no gain
- Running text-embedding-3-large at full 3072 dim when 1024 (Matryoshka truncation) works
- Comparing models without **using your own labelled subset** — leaderboards are lossy proxies
- Mixing multiple embedding models in the same index — distances aren't comparable
## When to Use This Mode
- Starting a new RAG / search project — pick the model first, lock the dim
- Cost overruns from a default OpenAI choice — find the cheapest equivalent
- Language coverage gaps — moving from EN-only to multilingual
- Migrating self-host ↔ API — match quality to budget
- Domain shift — code, legal, medical, e-commerce specialization
## Sources
- MTEB leaderboard: https://huggingface.co/spaces/mteb/leaderboard
- voyage-3-large: https://blog.voyageai.com/2025/01/07/voyage-3-large/
- BGE-M3: https://huggingface.co/BAAI/bge-m3
- Jina v3: https://jina.ai/models/jina-embeddings-v3/
- BentoML open-source guide: https://www.bentoml.com/blog/a-guide-to-open-source-embedding-models
- Modal MTEB review: https://modal.com/blog/mteb-leaderboard-article
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!