AI News / 2026-05-30

Embedding API Selection for Semantic Search and RAG (2025)

XycAi
Embedding API Selection for Semantic Search and RAG (2025)

The embedding decision is more expensive than it looks

Most teams building a RAG pipeline treat the embedding model as an afterthought — grab the first one that works and move on. That's a mistake you'll feel later in your AWS bill and in recall metrics that never quite get there.

Three things make this choice matter more than it appears:

To put numbers on it: a system handling 1 million daily queries against a 5 million-chunk document corpus can run anywhere from a few hundred to tens of thousands of dollars per month — at the embedding layer alone. This decision deserves deliberate attention.


Model comparison: what actually matters

Current embedding models fall into three camps: OpenAI, Cohere, and open-source/self-hosted. Here's how the main options stack up on the dimensions that matter in production:

Model Dimensions Max tokens Price (per 1M tokens) Multilingual Best for
text-embedding-3-small 1536 8191 ~$0.02 Fair Cost-sensitive, English-primary
text-embedding-3-large 3072 8191 ~$0.13 Good High accuracy, mixed language
Cohere embed-v4 1024 512 ~$0.10 Excellent Enterprise search, multilingual
BGE-M3 (open source) 1024 8192 Self-hosted Excellent Cost control, non-English docs
Jina embeddings-v3 768–1024 8192 ~$0.018 Good Long documents, cost efficiency

Two details that get overlooked:

text-embedding-3-large supports Matryoshka Representation Learning — you can truncate vectors to a lower dimension (say, 256) without a significant accuracy penalty. If storage pressure is real, this is worth using:

from openai import OpenAI

client = OpenAI()
response = client.embeddings.create(
    input="Your document text here",
    model="text-embedding-3-large",
    dimensions=256  # truncate to 256 dimensions
)

BGE-M3 consistently leads on non-English MTEB benchmarks, including Chinese. If your documents are primarily non-English and you have GPU capacity, self-hosting BGE-M3 is the highest-value path.


Semantic search vs. RAG: different bottlenecks

Both use embeddings, but where they break down is different.

Semantic search lives and dies by top-k recall and latency. A user submits a query; your system needs the most relevant results back in milliseconds. Here, semantic alignment matters more than raw dimensionality. A 768-dimension model with strong language understanding will typically outperform a 3072-dimension model with weak semantic alignment on real-world recall benchmarks.

Practical guidance: - English-only: text-embedding-3-small is sufficient and cheap - Mixed or non-English: BGE-M3 self-hosted, or Cohere embed-v4 via API - Latency-sensitive (<50ms): prefer lower-dimension models — retrieval time scales with vector size

RAG has a more complex failure surface. Embedding quality matters, but chunk strategy often has a bigger impact on final answer quality than model choice. The common mistake is setting chunk size too small (128 tokens or fewer) under the assumption that finer granularity means better retrieval. In practice, chunks that short strip out the context an LLM needs to generate a useful answer.

What works in practice: 256–512 tokens per chunk, 10–15% overlap. Pair with text-embedding-3-large when output quality is the priority, or BGE-M3 when cost is the constraint.


Three dimensions to guide your embedding API selection

1. Language distribution

Audit your document corpus before picking a model. If more than 30% of your content is non-English, text-embedding-3-small will leave recall on the table — its semantic alignment outside English is noticeably weaker than purpose-built multilingual models. A quick sanity check: take 50 representative queries, run retrieval with two candidate models, and manually evaluate the top-5 results. The gap is usually obvious.

2. Throughput and cost budget

Quick back-of-napkin math:

Monthly cost ≈ (daily document updates + daily queries) × average token count × unit price × 30

At 100,000 daily queries, ~50 tokens each: - text-embedding-3-small: 100,000 × 50 × $0.00000002 × 30 ≈ $3/month - text-embedding-3-large: same conditions ≈ $19.50/month

Document indexing is a one-time cost; queries are recurring. Model those separately or you'll underestimate the ongoing spend.

3. Vector database lock-in

Switching embedding models means rebuilding your vector index from scratch. Moving from text-embedding-3-small (1536 dimensions) to BGE-M3 (1024 dimensions) requires reindexing your entire corpus. That migration cost is real — factor it into the initial selection, not after you've already indexed millions of documents.


A minimal working example

Here's a complete semantic search flow in Python using OpenAI embeddings and Qdrant:

from openai import OpenAI
from qdrant_client import QdrantClient
from qdrant_client.models import Distance, VectorParams, PointStruct

client = OpenAI()
qdrant = QdrantClient(":memory:")

# Collection dimensions must match your model
qdrant.create_collection(
    collection_name="docs",
    vectors_config=VectorParams(size=1536, distance=Distance.COSINE),
)

def embed(text: str) -> list[float]:
    resp = client.embeddings.create(
        model="text-embedding-3-small",
        input=text
    )
    return resp.data[0].embedding

# Index documents
docs = [
    "Semantic search is built on vector similarity",
    "RAG combines retrieval with generation"
]
points = [
    PointStruct(id=i, vector=embed(doc), payload={"text": doc})
    for i, doc in enumerate(docs)
]
qdrant.upsert(collection_name="docs", points=points)

# Query
query_vec = embed("how does vector retrieval work")
results = qdrant.search(
    collection_name="docs",
    query_vector=query_vec,
    limit=2
)
for r in results:
    print(r.score, r.payload["text"])

Swapping models means changing model and size — nothing else in the architecture changes.


What I'd actually do

If you're running A/B tests across multiple embedding providers — comparing OpenAI, BGE, and Cohere on the same dataset — managing separate API keys and format differences gets tedious fast. I use XycAi for exactly this: one OpenAI-compatible endpoint covering 200+ models, with GPT and Claude available from 14% of list price. Switching between models is a single base_url change, which makes iterative embedding API selection dramatically less painful.

One API for 200+ global AI models

GPT · Claude · Gemini official models from 14% of list price. Licensed LLM filing, CN2 direct connect at ~5ms, compliant global invoicing.

Try XycAi →