Embeddings and Vectors Without the Math

Embeddings turn text, images, and video into lists of numbers that capture meaning - powering semantic search, recommendations, and RAG. Here's how they work and how to build with them today.

TL;DR: An embedding converts any piece of content - text, image, video - into a list of numbers that encodes its meaning. Similar content gets similar numbers. That single idea powers semantic search, recommendations, and the retrieval step in every RAG pipeline you'll ever build.

The Problem With Keywords

You search your note app for "car." You typed "vehicle" in the note. Nothing comes back. Keyword search is dumb in this specific, frustrating way - it matches letters, not ideas.

Embeddings solve this. An embedding model reads "car" and "vehicle" and decides they belong in roughly the same neighborhood in meaning-space. Search a vector database for "car" and a note about "vehicles" floats to the top, because the model understands they're the same idea wearing different clothes.

This is semantic search. It understands what you mean, not just what you typed.

What an Embedding Actually Is

An embedding is a list of floating-point numbers - sometimes 256 of them, sometimes 1024, sometimes 3072 - where each number captures some sliver of the content's meaning. You don't read those numbers. A machine does math on them.

Think of it like a coordinate system for meaning. "King" and "queen" land close together. "Steak" and "sirloin" land close together. "Steak" and "algebra" land far apart.

The length of the list is called the dimension count. Higher dimensions can capture more nuance, but also cost more to store and compute. Models like Voyage AI's voyage-4 (recommended by Anthropic's documentation) default to 1024 dimensions, with options for 256, 512, or 2048 depending on your storage and latency budget.

Here's what the raw output looks like when you embed two short phrases:

[-0.013131560757756233, 0.019828535616397858, ...]   # "The conference call is Thursday"
[-0.0069352793507277966, 0.020878976210951805, ...]  # "When is the meeting scheduled?"

Those vectors look nothing alike to a human eye. But the math says they point in almost the same direction - because "conference call Thursday" and "meeting scheduled" mean the same thing.

How Similarity Is Measured

Once content becomes vectors, finding what's similar is a geometry problem. The standard metric is cosine similarity - it measures the angle between two vectors, not their length.

When embedding providers normalize their vectors to unit length - which Voyage AI and OpenAI both do - cosine similarity becomes a simple dot product. Cheaper to compute. Same result.

In practice you don't write this math yourself. You embed your query, embed your documents, then call a vector database that does nearest-neighbor search for you - surfacing the top-K most similar documents in milliseconds even across millions of vectors.

Semantic Search and RAG in Three Steps

Here's the full loop, from raw content to useful retrieval:

  1. Index time. Break your content into chunks (a few hundred tokens each works well). Pass each chunk to an embedding model. Store the resulting vectors in a vector database alongside the original text.
  2. Query time. Embed the user's question with the same model. Do a nearest-neighbor search against the index. Retrieve the top K matching chunks.
  3. Generate. Hand those chunks to an LLM as context. The model answers using the retrieved, relevant information - not just its training data.

This is RAG - retrieval-augmented generation. Embeddings are what make the retrieval step work. Without them you'd be doing keyword matching, which misses synonyms, paraphrases, and conceptual leaps.

Anthropic's research on contextual retrieval found that using Contextual Embeddings - where a brief summary of each chunk's context is prepended before embedding - reduced retrieval failure by 35%. Combining Contextual Embeddings with BM25 lexical search pushed that to 49%. Adding a reranking step reached 67%. The lesson: embeddings are the foundation, but prepending context and layering exact-match search on top makes production systems significantly more reliable.

A Minimal Working Example

pip install -U voyageai numpy
import voyageai
import numpy as np

vo = voyageai.Client()  # uses VOYAGE_API_KEY env var

documents = [
    "Creators of Today is a video-first feed of real people building things.",
    "The feed ranks content by engagement quality, not raw view count.",
    "Creators can submit their work for review by the editorial team.",
]

# Embed documents once at index time
doc_embeddings = vo.embed(
    documents, model="voyage-4", input_type="document"
).embeddings

# Embed the query at search time
query = "how does the ranking system work?"
query_embedding = vo.embed(
    [query], model="voyage-4", input_type="query"
).embeddings[0]

# Find the most similar document
scores = np.dot(doc_embeddings, query_embedding)
best = np.argmax(scores)
print(documents[best])
# -> "The feed ranks content by engagement quality, not raw view count."

That's it. No database yet - just NumPy doing dot products in memory. For production you'd swap the NumPy array for Pinecone, Weaviate, Qdrant, or pgvector, which handle indexing and approximate nearest-neighbor search at scale.

Recommendations Work the Same Way

The same nearest-neighbor logic that powers search also drives recommendations. Instead of asking "find documents like this query," you ask "find content like this content the user just watched."

Embed a video's transcript and title. Find the K videos with the most similar embeddings. Surface them as "you might also like." The model handles genre, topic, tone, and audience - all encoded in those numbers - without you explicitly labeling any of it.

Domain-specific embedding models push this further. Voyage AI's voyage-finance-2 is tuned for financial documents; voyage-code-3 is tuned for code retrieval. A general-purpose model might conflate "repo" (financial) with "repo" (git) - a domain model knows the difference from context.

Choosing an Embedding Model

Anthropic does not offer its own embedding model. Their documentation explicitly recommends Voyage AI, whose Voyage 4 family (released January 2026) is the current state of the art for general-purpose and multilingual retrieval.

OpenAI also offers strong general-purpose options: text-embedding-3-large (3072 dimensions) and text-embedding-3-small (1536 dimensions), both supporting dimension reduction via a dimensions API parameter so you can shrink vector size without retraining.

The rule of thumb: start with a general-purpose model, switch to a domain-specific one if recall is falling short on your specific content type.

Key Takeaways

Try this next: Once you're comfortable with embeddings, the natural next step is wiring them into a full retrieval pipeline - see RAG and Retrieval: Build Your First Knowledge-Grounded AI to go from a vector index to a working AI that answers questions from your own content.

LearnfundamentalsEmbeddings and Vectors Without the Math
Guidefundamentalscore7 min read

Embeddings and Vectors Without the Math

Embeddings turn text, images, and video into lists of numbers that capture meaning - powering semantic search, recommendations, and RAG. Here's how they work and how to build with them today.

TL;DR: An embedding converts any piece of content - text, image, video - into a list of numbers that encodes its meaning. Similar content gets similar numbers. That single idea powers semantic search, recommendations, and the retrieval step in every RAG pipeline you'll ever build.

The Problem With Keywords

You search your note app for "car." You typed "vehicle" in the note. Nothing comes back. Keyword search is dumb in this specific, frustrating way - it matches letters, not ideas.

Embeddings solve this. An embedding model reads "car" and "vehicle" and decides they belong in roughly the same neighborhood in meaning-space. Search a vector database for "car" and a note about "vehicles" floats to the top, because the model understands they're the same idea wearing different clothes.

This is semantic search. It understands what you mean, not just what you typed.

What an Embedding Actually Is

An embedding is a list of floating-point numbers - sometimes 256 of them, sometimes 1024, sometimes 3072 - where each number captures some sliver of the content's meaning. You don't read those numbers. A machine does math on them.

Think of it like a coordinate system for meaning. "King" and "queen" land close together. "Steak" and "sirloin" land close together. "Steak" and "algebra" land far apart.

The length of the list is called the dimension count. Higher dimensions can capture more nuance, but also cost more to store and compute. Models like Voyage AI's voyage-4 (recommended by Anthropic's documentation) default to 1024 dimensions, with options for 256, 512, or 2048 depending on your storage and latency budget.

Here's what the raw output looks like when you embed two short phrases:

[-0.013131560757756233, 0.019828535616397858, ...]   # "The conference call is Thursday"
[-0.0069352793507277966, 0.020878976210951805, ...]  # "When is the meeting scheduled?"

Those vectors look nothing alike to a human eye. But the math says they point in almost the same direction - because "conference call Thursday" and "meeting scheduled" mean the same thing.

How Similarity Is Measured

Once content becomes vectors, finding what's similar is a geometry problem. The standard metric is cosine similarity - it measures the angle between two vectors, not their length.

  • Score of 1.0 - identical direction, same meaning
  • Score of 0 - perpendicular, unrelated
  • Score of -1.0 - opposite direction, opposite meaning

When embedding providers normalize their vectors to unit length - which Voyage AI and OpenAI both do - cosine similarity becomes a simple dot product. Cheaper to compute. Same result.

In practice you don't write this math yourself. You embed your query, embed your documents, then call a vector database that does nearest-neighbor search for you - surfacing the top-K most similar documents in milliseconds even across millions of vectors.

Semantic Search and RAG in Three Steps

Here's the full loop, from raw content to useful retrieval:

  1. Index time. Break your content into chunks (a few hundred tokens each works well). Pass each chunk to an embedding model. Store the resulting vectors in a vector database alongside the original text.
  2. Query time. Embed the user's question with the same model. Do a nearest-neighbor search against the index. Retrieve the top K matching chunks.
  3. Generate. Hand those chunks to an LLM as context. The model answers using the retrieved, relevant information - not just its training data.

This is RAG - retrieval-augmented generation. Embeddings are what make the retrieval step work. Without them you'd be doing keyword matching, which misses synonyms, paraphrases, and conceptual leaps.

Anthropic's research on contextual retrieval found that using Contextual Embeddings - where a brief summary of each chunk's context is prepended before embedding - reduced retrieval failure by 35%. Combining Contextual Embeddings with BM25 lexical search pushed that to 49%. Adding a reranking step reached 67%. The lesson: embeddings are the foundation, but prepending context and layering exact-match search on top makes production systems significantly more reliable.

A Minimal Working Example

pip install -U voyageai numpy
import voyageai
import numpy as np

vo = voyageai.Client()  # uses VOYAGE_API_KEY env var

documents = [
    "Creators of Today is a video-first feed of real people building things.",
    "The feed ranks content by engagement quality, not raw view count.",
    "Creators can submit their work for review by the editorial team.",
]

# Embed documents once at index time
doc_embeddings = vo.embed(
    documents, model="voyage-4", input_type="document"
).embeddings

# Embed the query at search time
query = "how does the ranking system work?"
query_embedding = vo.embed(
    [query], model="voyage-4", input_type="query"
).embeddings[0]

# Find the most similar document
scores = np.dot(doc_embeddings, query_embedding)
best = np.argmax(scores)
print(documents[best])
# -> "The feed ranks content by engagement quality, not raw view count."

That's it. No database yet - just NumPy doing dot products in memory. For production you'd swap the NumPy array for Pinecone, Weaviate, Qdrant, or pgvector, which handle indexing and approximate nearest-neighbor search at scale.

Recommendations Work the Same Way

The same nearest-neighbor logic that powers search also drives recommendations. Instead of asking "find documents like this query," you ask "find content like this content the user just watched."

Embed a video's transcript and title. Find the K videos with the most similar embeddings. Surface them as "you might also like." The model handles genre, topic, tone, and audience - all encoded in those numbers - without you explicitly labeling any of it.

Domain-specific embedding models push this further. Voyage AI's voyage-finance-2 is tuned for financial documents; voyage-code-3 is tuned for code retrieval. A general-purpose model might conflate "repo" (financial) with "repo" (git) - a domain model knows the difference from context.

Choosing an Embedding Model

Anthropic does not offer its own embedding model. Their documentation explicitly recommends Voyage AI, whose Voyage 4 family (released January 2026) is the current state of the art for general-purpose and multilingual retrieval.

  • voyage-4-large - best retrieval quality; uses a Mixture-of-Experts architecture with 40% lower serving cost than comparable dense models
  • voyage-4 - balanced quality and efficiency; good default for most RAG use cases
  • voyage-4-lite - lowest latency and cost; use when speed matters more than top-1 recall
  • voyage-4-nano - open-weight (Apache 2.0), runs locally via Hugging Face; good for prototypes and privacy-sensitive apps

OpenAI also offers strong general-purpose options: text-embedding-3-large (3072 dimensions) and text-embedding-3-small (1536 dimensions), both supporting dimension reduction via a dimensions API parameter so you can shrink vector size without retraining.

The rule of thumb: start with a general-purpose model, switch to a domain-specific one if recall is falling short on your specific content type.

Key Takeaways

  • An embedding is a list of numbers that encodes the meaning of content - text, image, or video - in a format machines can compare.
  • Similar meaning produces similar vectors. That's the whole mechanism behind semantic search and recommendations.
  • Cosine similarity (or dot product on normalized vectors) is the standard way to measure how close two embeddings are.
  • RAG uses embeddings to find relevant context for an LLM - index at write time, retrieve at query time.
  • Prepending context to chunks (Contextual Embeddings) before indexing and layering lexical search (BM25) on top of vector search both improve production recall significantly.
  • Anthropic recommends Voyage AI; OpenAI's text-embedding-3 family is the other strong general-purpose option.
  • You don't need to understand the linear algebra. You need to understand the three-step loop: embed, store, retrieve.

Try this next: Once you're comfortable with embeddings, the natural next step is wiring them into a full retrieval pipeline - see RAG and Retrieval: Build Your First Knowledge-Grounded AI to go from a vector index to a working AI that answers questions from your own content.

References & sources

Reviews

Only verified humans can leave reviews. It keeps every rating real.

Verify to review

No reviews yet. Be the first to share your take.