Best Embedding Models for RAG Agents (2026)
Ranked evaluation of the best embedding models for RAG agents in 2026 — text-embedding-v4, OpenAI text-embedding-3-large, Cohere embed-v3, Voyage-3. Dimensions, chunking strategies, cost per million tokens, and which model for which use case.
TL;DR — For RAG agents in 2026, the best embedding model depends on your language mix and cost sensitivity. text-embedding-v4 (on SandBase) leads for multilingual/CJK workloads with its 8192-token context. OpenAI’s text-embedding-3-large remains the safe default for English-heavy pipelines. Cohere embed-v3 excels at retrieval-specific tasks. Voyage-3 is the dark horse for code and technical content. This guide covers dimensions, chunking, cost, and decision frameworks.
Why embedding model choice matters for RAG
The embedding model is the foundation of every RAG system. Choose wrong and:
- Your retrieval misses relevant chunks (low recall)
- Your context window fills with irrelevant content (low precision)
- Your costs scale unnecessarily (too many dimensions, too many chunks)
- Your multilingual content returns garbage (model doesn’t understand the language)
The difference between a mediocre embedding model and the right one can mean 15–25% improvement in end-to-end RAG quality — measured by answer correctness, not just retrieval metrics.
For a deep dive into text-embedding-v4 specifically, see our text-embedding-v4 guide. For broader pricing context, see our LLM API pricing guide.
The 2026 embedding landscape
| Model | Vendor | Dimensions | Max tokens | Best for |
|---|---|---|---|---|
| text-embedding-v4 | Alibaba (SandBase) | 1536 | 8192 | Multilingual, CJK + English |
| text-embedding-3-large | OpenAI | 3072 (or custom) | 8191 | English-primary, general |
| text-embedding-3-small | OpenAI | 1536 | 8191 | Budget English workloads |
| embed-v3 | Cohere | 1024 | 512 | Retrieval-optimized |
| Voyage-3 | Voyage AI | 1024 | 16000 | Code, technical content |
| Voyage-3-lite | Voyage AI | 512 | 16000 | Budget code/technical |
Detailed model evaluation
#1: text-embedding-v4 (Alibaba) — Best for multilingual RAG
| Dimension | Score | Notes |
|---|---|---|
| English quality | 8.5/10 | Strong, not quite OpenAI-level |
| CJK quality | 9.5/10 | Best-in-class Chinese/Japanese/Korean |
| Multilingual | 9.5/10 | 100+ languages, excellent alignment |
| Code understanding | 8.0/10 | Good for code-mixed content |
| Context window | 9.0/10 | 8192 tokens — fewer chunks needed |
| Cost efficiency | 9.0/10 | Competitive pricing |
| SandBase native | 10/10 | Single API key, unified billing |
Model ID: alibaba/text-embedding-v4
Why choose it: If your content is multilingual (especially CJK + English), text-embedding-v4 is the clear winner. The 8192-token context means you can embed longer chunks, which improves retrieval coherence and reduces your vector store size.
from openai import OpenAI
client = OpenAI(
base_url="https://api.sandbase.ai/v1",
api_key="your-sandbase-api-key"
)
# Embed multilingual content
response = client.embeddings.create(
model="alibaba/text-embedding-v4",
input=[
"How do autonomous agents handle multi-step planning?",
"自主 Agent 如何处理多步规划?",
"자율 에이전트는 다단계 계획을 어떻게 처리하나요?"
]
)
# All three embeddings are aligned in the same space
# Cross-language retrieval works out of the box
embeddings = [item.embedding for item in response.data]
#2: text-embedding-3-large (OpenAI) — Best for English-primary
| Dimension | Score | Notes |
|---|---|---|
| English quality | 9.5/10 | Best English embeddings |
| CJK quality | 7.5/10 | Adequate but not optimized |
| Multilingual | 8.0/10 | Good coverage, English-centric training |
| Code understanding | 8.5/10 | Strong code-text alignment |
| Context window | 9.0/10 | 8191 tokens |
| Cost efficiency | 7.0/10 | ~$0.13/1M tokens (higher) |
| Dimension flexibility | 9.0/10 | Can reduce to 256/512/1024 via API |
Why choose it: If your content is primarily English and you want maximum retrieval quality, text-embedding-3-large is the safe bet. The dimension reduction feature (Matryoshka representation) lets you trade quality for cost at deployment time.
from openai import OpenAI
client = OpenAI(api_key="your-openai-key")
# Full dimensions (3072) — maximum quality
response = client.embeddings.create(
model="text-embedding-3-large",
input="How do autonomous agents handle multi-step planning?",
dimensions=3072 # Or 1536, 1024, 512, 256
)
# Reduced dimensions (1024) — 67% less storage, ~95% quality
response_small = client.embeddings.create(
model="text-embedding-3-large",
input="How do autonomous agents handle multi-step planning?",
dimensions=1024
)
#3: Cohere embed-v3 — Best for retrieval tasks
| Dimension | Score | Notes |
|---|---|---|
| English quality | 9.0/10 | Excellent for retrieval |
| CJK quality | 7.0/10 | Limited optimization |
| Multilingual | 8.0/10 | 100+ languages claimed |
| Code understanding | 7.0/10 | Basic |
| Context window | 6.0/10 | 512 tokens (limiting) |
| Cost efficiency | 8.5/10 | Competitive |
| Retrieval-specific | 9.5/10 | Trained specifically for search |
Why choose it: Cohere’s embed-v3 is specifically optimized for retrieval tasks with separate embedding types for documents vs. queries. This asymmetric approach improves recall. The 512-token limit means more chunks and more calls, but each chunk is optimally sized for retrieval.
import cohere
co = cohere.Client(api_key="your-cohere-key")
# Document embedding (store these)
doc_response = co.embed(
texts=["Document content here..."],
model="embed-v3",
input_type="search_document"
)
# Query embedding (at search time)
query_response = co.embed(
texts=["user question"],
model="embed-v3",
input_type="search_query"
)
#4: Voyage-3 — Best for code and technical content
| Dimension | Score | Notes |
|---|---|---|
| English quality | 8.5/10 | Strong general quality |
| CJK quality | 7.0/10 | Basic support |
| Multilingual | 7.0/10 | Limited |
| Code understanding | 9.5/10 | Best-in-class code embeddings |
| Context window | 10/10 | 16,000 tokens |
| Cost efficiency | 8.0/10 | Mid-range |
| Technical content | 9.5/10 | Optimized for technical docs |
Why choose it: If you’re building a RAG system over code repositories, technical documentation, or developer content, Voyage-3 is the specialist choice. The 16,000-token context window means you can embed entire files or documentation pages in a single vector.
Chunking strategies for 8192-token models
With models like text-embedding-v4 and text-embedding-3-large supporting 8192 tokens, chunking strategy changes significantly:
Strategy comparison
| Strategy | Chunk size | Overlap | Chunks per doc (10K tokens) | Retrieval quality | Storage |
|---|---|---|---|---|---|
| Small, no overlap | 256 tokens | 0 | ~39 | Low (context lost) | High |
| Small with overlap | 256 tokens | 64 | ~50 | Medium | Very high |
| Medium (traditional) | 512 tokens | 128 | ~26 | Good | Medium |
| Large (8K models) | 2048 tokens | 256 | ~6 | Very good | Low |
| Page-level | 4096 tokens | 512 | ~3 | Excellent (coherent) | Very low |
| Full document | 8192 tokens | 0 | ~2 | Best coherence | Minimum |
Recommended approach for 8192-token models
from typing import Generator
def chunk_document(
text: str,
chunk_size: int = 2048,
overlap: int = 256,
separator: str = "\n\n"
) -> Generator[str, None, None]:
"""Chunk a document with paragraph-aware boundaries."""
paragraphs = text.split(separator)
current_chunk = ""
for para in paragraphs:
# If adding this paragraph exceeds chunk_size, yield current and start new
if len(current_chunk) + len(para) > chunk_size * 4: # ~4 chars per token estimate
if current_chunk:
yield current_chunk
# Keep overlap from end of previous chunk
overlap_text = current_chunk[-(overlap * 4):]
current_chunk = overlap_text + separator + para
else:
yield para
current_chunk = ""
else:
current_chunk += separator + para if current_chunk else para
if current_chunk:
yield current_chunk
Impact on vector store economics
Using larger chunks with 8192-token models dramatically reduces storage:
| Document size | Small chunks (256 tok) | Large chunks (2048 tok) | Savings |
|---|---|---|---|
| 1 article (2K tokens) | 8 vectors | 1 vector | 87% |
| 100 articles (200K tokens) | 780 vectors | 100 vectors | 87% |
| Documentation (2M tokens) | 7,800 vectors | 1,000 vectors | 87% |
| Code repo (10M tokens) | 39,000 vectors | 5,000 vectors | 87% |
Fewer vectors = lower storage cost + faster search + fewer tokens in context window.
Cost per million tokens
| Model | Cost/1M tokens | Cost for 10M tokens | Cost for 100M tokens |
|---|---|---|---|
| text-embedding-v4 | ~$0.02 | $0.20 | $2.00 |
| text-embedding-3-small | $0.02 | $0.20 | $2.00 |
| text-embedding-3-large | $0.13 | $1.30 | $13.00 |
| Cohere embed-v3 | ~$0.10 | $1.00 | $10.00 |
| Voyage-3 | ~$0.06 | $0.60 | $6.00 |
| Voyage-3-lite | ~$0.02 | $0.20 | $2.00 |
Cost winner: text-embedding-v4 and text-embedding-3-small tie at ~$0.02/1M tokens. But v4 has larger context (8192 vs 8191) and much better multilingual quality.
Total cost of ownership (embedding + storage + search)
For a 10M token knowledge base:
| Model | Embedding cost | Vectors stored | Vector DB cost/month | Total year 1 |
|---|---|---|---|---|
| v4 (2048-token chunks) | $0.20 | ~5,000 | ~$5 | ~$60 |
| 3-large (2048 chunks) | $1.30 | ~5,000 | ~$8 (3072d) | ~$97 |
| embed-v3 (512 chunks) | $1.00 | ~20,000 | ~$10 | ~$121 |
| Voyage-3 (4096 chunks) | $0.60 | ~2,500 | ~$4 | ~$49 |
Dimension choices and trade-offs
| Dimensions | Storage per vector | Search speed | Quality impact |
|---|---|---|---|
| 256 | 1 KB | Very fast | -10-15% recall |
| 512 | 2 KB | Fast | -5-8% recall |
| 1024 | 4 KB | Good | -2-3% recall |
| 1536 | 6 KB | Good | Baseline |
| 3072 | 12 KB | Slower | +1-2% recall |
Practical guidance:
- 1536 dimensions is the sweet spot for most production systems
- 1024 works well if you’re cost-sensitive and have a large index
- 3072 is rarely worth the 2× storage cost for the marginal quality gain
- 256-512 only for very high-volume, latency-sensitive applications (product search)
Which model for which use case
| Use case | Recommended model | Why |
|---|---|---|
| English documentation RAG | text-embedding-3-large (1536d) | Best English quality |
| Multilingual knowledge base | text-embedding-v4 | Best CJK + cross-lingual |
| Code repository search | Voyage-3 | Best code understanding |
| E-commerce product search | text-embedding-v4 or 3-small | Cost-efficient, multilingual |
| Legal document retrieval | Cohere embed-v3 | Retrieval-optimized |
| Customer support RAG (English) | text-embedding-3-large (1024d) | Quality + reduced cost |
| Customer support RAG (Chinese) | text-embedding-v4 | Superior CJK performance |
| Agent memory system | text-embedding-v4 | Long context, multilingual |
| Research paper search | Voyage-3 | Technical content, long context |
| Budget chatbot (<$50/mo) | text-embedding-v4 or 3-small | $0.02/1M tokens |
Integration example: RAG pipeline with text-embedding-v4
from openai import OpenAI
import numpy as np
client = OpenAI(
base_url="https://api.sandbase.ai/v1",
api_key="your-sandbase-api-key"
)
class RAGPipeline:
"""Production RAG pipeline using text-embedding-v4."""
def __init__(self):
self.documents = [] # In production: use a vector database
self.embeddings = []
def index_documents(self, texts: list[str], batch_size: int = 25):
"""Index documents in batches."""
for i in range(0, len(texts), batch_size):
batch = texts[i:i + batch_size]
response = client.embeddings.create(
model="alibaba/text-embedding-v4",
input=batch
)
for j, item in enumerate(response.data):
self.documents.append(batch[j])
self.embeddings.append(item.embedding)
def search(self, query: str, top_k: int = 5) -> list[dict]:
"""Search for relevant documents."""
# Embed query
response = client.embeddings.create(
model="alibaba/text-embedding-v4",
input=[query]
)
query_embedding = np.array(response.data[0].embedding)
# Cosine similarity
doc_embeddings = np.array(self.embeddings)
similarities = np.dot(doc_embeddings, query_embedding) / (
np.linalg.norm(doc_embeddings, axis=1) * np.linalg.norm(query_embedding)
)
# Top-k results
top_indices = np.argsort(similarities)[-top_k:][::-1]
return [
{"text": self.documents[i], "score": float(similarities[i])}
for i in top_indices
]
def answer(self, query: str) -> str:
"""Full RAG: retrieve then generate."""
results = self.search(query, top_k=3)
context = "\n\n".join(r["text"] for r in results)
response = client.chat.completions.create(
model="openai/gpt-4o-mini",
messages=[
{"role": "system", "content": "Answer based on the provided context. Cite sources."},
{"role": "user", "content": f"Context:\n{context}\n\nQuestion: {query}"}
]
)
return response.choices[0].message.content
Migration guide: switching embedding models
When migrating from one embedding model to another, you must re-embed all documents (embeddings from different models are not compatible). Here’s a cost estimation for common migration scenarios:
| Corpus size | Tokens (est.) | Re-embedding cost (v4) | Re-embedding cost (3-large) | Time (batch) |
|---|---|---|---|---|
| Small (1K docs) | ~2M | $0.04 | $0.26 | <1 min |
| Medium (10K docs) | ~20M | $0.40 | $2.60 | ~5 min |
| Large (100K docs) | ~200M | $4.00 | $26.00 | ~30 min |
| Very large (1M docs) | ~2B | $40.00 | $260.00 | ~5 hours |
Related Reading
- Alibaba text-embedding-v4: The Bilingual Embedding Model Your CJK Pipeline Actually Needs
- RAG Cost Structure: Embedding + Search + LLM
- Top 6 AI Search APIs for Agent Workflows in 2026
- Best 1M-Context Models for Agents (2026)
- LLM API Pricing in 2026: The Complete Guide
- AI Agent Infrastructure Stack 2026
Conclusion
The embedding model landscape in 2026 offers clear specializations:
- text-embedding-v4 — best value for multilingual RAG, especially CJK workloads, available natively on SandBase
- text-embedding-3-large — highest English quality, flexible dimensions
- Cohere embed-v3 — retrieval-optimized with asymmetric embeddings
- Voyage-3 — code and technical content specialist
For most teams building on SandBase, text-embedding-v4 is the default recommendation: excellent multilingual quality, 8192-token context for larger chunks, cost-effective at $0.02/1M tokens, and zero additional integration work (same API key as everything else). Switch to a specialist model only when your specific use case clearly demands it.


