Embeddings in Practice
Generate, store, and compare embeddings in code; pick an embedding model; and build intuition for what similarity scores do and don't mean.
Every search, retrieval, and "related items" feature in this module rests on one API call: you send text, you get back a long list of numbers. The call itself takes minutes to wire up. What takes longer is everything around it: batching thousands of documents without hitting limits, storing vectors so you can tell which model produced them, comparing them correctly, and resisting the urge to read a similarity score of 0.82 as "82% relevant."
This lesson gets embeddings working in real code for Deskmate's help articles, then builds the intuition you need to use them well. You'll generate and store embeddings, compare them, calibrate what scores mean for your model and your data, and pick an embedding model with a small bake-off instead of a leaderboard glance.
What an embedding API actually gives you
An embedding is a fixed-length array of floating-point numbers (a vector) that an embedding model produces from a piece of text. The model is trained so that texts with similar meaning produce vectors that point in similar directions. "How do I get my money back?" and "Requesting a refund" end up close together even though they share no words.
For a builder, four properties of that array matter more than the theory:
- Dimensions are fixed per model (and configuration). OpenAI's
text-embedding-3-smallreturns 1,536 numbers by default; other models return 256, 1,024, 3,072, or something else. Every vector you compare must have the same length and come from the same model. - Vectors from different models are incompatible. Even two models with the same dimension count place meaning differently. Comparing a vector from model A against one from model B produces a number, but the number means nothing.
- Many models return normalized vectors, scaled to length 1. When that's true, cosine similarity and the dot product give the same answer, which lets databases use the cheaper operation.
- Inputs have a token limit. Text longer than the model's limit is either rejected or silently truncated, depending on the provider and settings. Truncation is the dangerous one: the end of a long article quietly stops counting.
Anthropic doesn't offer an embedding model, and that's fine: the chat model never sees vectors, only the text you retrieve with them. You can pair Claude with any embedding provider. Anthropic's own docs point to Voyage AI; OpenAI, Google, and Cohere offer hosted embedding models too, and there are strong open-weight options you can run yourself.