Overview
An embedding maps a piece of text to a vector of floating-point numbers positioned in a high-dimensional space such that semantically similar texts end up close together, and cosine similarity is the standard way to measure that closeness mathematically. This is what powers semantic search, clustering, recommendations, and classification: comparison happens on meaning rather than literal word overlap, so a query and a relevant document can match even when they share no words at all. Embedding dimensionality is a real, tunable trade-off, modern models support shortening a full-length embedding to fewer dimensions for less storage and faster comparison, at some cost to precision, and the right point on that trade-off depends entirely on how much accuracy a specific use case can afford to give up.
Quick Reference
| Concept | What it is |
|---|---|
| Embedding | A vector representing a text's meaning numerically |
| Cosine similarity | A similarity score between two embeddings; higher similarity (closer to 1) = more related |
| Dimensionality | Vector length; fewer dimensions = less storage/compute, some accuracy cost |
| Semantic search | Ranking results by embedding similarity, not literal keyword overlap |
| Use case | What embeddings enable |
|---|---|
| Semantic search | Rank documents by meaning-relatedness to a query |
| Clustering | Group related texts automatically, no manual labels |
| Recommendations | Suggest items with similar textual descriptions |
| Classification | Assign a category based on embedding proximity to labeled examples |
Syntax
response = client.embeddings.create(
model="text-embedding-3-large",
input="The user's password reset email never arrived.",
)
vector = response.data[0].embeddingExamples
# Cosine similarity between two embeddings - closer to 1 means
# more semantically related, regardless of shared vocabulary.
import numpy as np
def cosine_similarity(a, b):
return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))
score = cosine_similarity(query_embedding, document_embedding)Shortened embeddings can still beat an older full-length model
A newer embedding model shortened to fewer dimensions can outperform an older model's unshortened embedding. Dimension count is a real trade-off against a specific model's own accuracy ceiling, not a simple "smaller is always worse" rule.
Visual Diagram
Common Mistakes
- Expecting embeddings to handle exact-match needs (error codes, SKUs, proper nouns) as well as keyword search, when literal string matching is what those actually require.
- Storing full-dimensional embeddings everywhere by default, without evaluating whether a shortened dimension count would meet the use case's accuracy bar at meaningfully lower storage/compute cost.
- Comparing embeddings produced by two different models, or two different dimension settings, and expecting the distances to be meaningfully comparable.
- Treating semantic search as a strict replacement for keyword search instead of combining both (hybrid search) where each is actually stronger.
Performance
- Similarity computation cost scales with both the number of stored vectors and their dimensionality; shortening dimensions is a direct, deliberate lever on query latency and storage at scale.
- Cosine similarity is computationally cheap, effectively a dot product for normalized vectors, so the practical bottleneck at scale is usually the vector index/search structure, not the similarity math itself.
Best Practices
- Use cosine similarity as the default distance metric for comparing embeddings unless a specific model's documentation recommends otherwise.
- Evaluate a shortened embedding dimension against the actual accuracy bar for the use case before defaulting to full length everywhere.
- Combine semantic (embedding) search with keyword search for queries that need both meaning-matching and exact-match precision.
- Never compare embeddings generated by different models or different dimension settings as if their distances were on the same scale.