Your first embedding in 5 minutes
Theory later. Right now the goal is to see actual numbers come out of a real model, because everything after this is easier once you’ve watched it happen once.
Pick whichever route suits you. Both take about the same time.
No account, no card, no API key. You download a small model and run it on your own machine. First run pulls about 90 MB and takes a minute; after that it’s instant and offline.
-
Install the library
Terminal window pip install sentence-transformersIt’ll pull in PyTorch, so this is the slow step — a couple of minutes, and a few hundred MB. Go make tea.
-
Write the script
Save this as
first_embedding.py:first_embedding.py from sentence_transformers import SentenceTransformermodel = SentenceTransformer("all-MiniLM-L6-v2")text = "The spare set for the front door is in the kitchen drawer."vector = model.encode(text)print(f"Text: {text}")print(f"Dimensions: {len(vector)}")print(f"First five: {vector[:5]}") -
Run it
Terminal window python first_embedding.py
You’ll see something along these lines (your exact numbers will differ slightly by version and hardware, which is fine and expected):
Text: The spare set for the front door is in the kitchen drawer.Dimensions: 384First five: [-0.0234 0.0871 -0.0412 0.0159 0.0623]Higher quality, nothing to download, but you need an account with a payment method. The good news is embeddings are startlingly cheap — you could embed this entire website many times over for less than a penny.
-
Get an API key
Create one at platform.openai.com/api-keys. Copy it immediately, it’s only shown once.
-
Set it as an environment variable
Terminal window export OPENAI_API_KEY="sk-..." # macOS / Linuxsetx OPENAI_API_KEY "sk-..." # Windows PowerShell, then reopen the terminalNever paste the key directly into your source file. We’ll say this again on every page, and we’re not sorry.
-
Install the SDK
Terminal window pip install openai -
Write the script
first_embedding.py from openai import OpenAIclient = OpenAI() # reads OPENAI_API_KEY from the environmenttext = "The spare set for the front door is in the kitchen drawer."response = client.embeddings.create(model="text-embedding-3-small",input=text,)vector = response.data[0].embeddingprint(f"Text: {text}")print(f"Dimensions: {len(vector)}")print(f"First five: {vector[:5]}")print(f"Tokens used: {response.usage.total_tokens}") -
Run it
Terminal window python first_embedding.py
Output looks roughly like this:
Text: The spare set for the front door is in the kitchen drawer.Dimensions: 1536First five: [0.0212, -0.0145, 0.0083, -0.0331, 0.0097]Tokens used: 13Right. What did we just see?
Section titled “Right. What did we just see?”A number where you expected a sentence. You gave the model twelve words and it handed back a long list of floating-point values. That list is the embedding. There’s no other magic object hiding behind it — this is the thing everybody’s talking about.
A fixed length. 384 numbers from MiniLM, 1,536 from OpenAI’s small model. Notice that the length has nothing to do with how long your text was. Embed a single word or embed three paragraphs; you get the same size list either way. That’s what makes them comparable — you can’t measure the distance between a 5-element list and a 900-element one, so the model always gives you the same shape.
Numbers that mean nothing individually. The first value being 0.0212 tells you precisely nothing. Don’t stare at it. As we said on the previous page, these are only useful in comparison to other embeddings.
The bit that trips everyone up
Section titled “The bit that trips everyone up”You must use the same model for everything you intend to compare. An embedding from MiniLM and an embedding from OpenAI are not comparable, even if you force the dimensions to match. They’re coordinates in two unrelated spaces. Comparing them is like comparing a grid reference in London to one in Tokyo — the numbers are similar-looking and the answer is meaningless.
That includes model versions. If you re-embed your database with a newer model, you have to re-embed all of it, not just the new rows. Mixing generations is one of the most common ways a working search quietly turns to mush, and it produces no error message at all — just steadily worse results that nobody can explain.
You’ve made one embedding. Now make nine and build the actual search:
- Python guide — the full eight-note search, about 40 lines
- .NET / C# guide
- Java guide
- Node / TypeScript guide
Or if you’d rather understand before you build, how text becomes numbers explains what happened inside that encode() call. Wondering which model to use at all? Choosing an embedding model covers the ones people actually pick.
References
Section titled “References”- OpenAI — Embeddings guide — models, dimensions, usage
- OpenAI — Embeddings API reference — every parameter, including
dimensionsandencoding_format - OpenAI — Pricing — check current embedding costs before you budget
- openai-python on GitHub — SDK source and changelog
- sentence-transformers documentation — the local route, in depth
- all-MiniLM-L6-v2 model card — what the local model is and how it was trained