What is Embeddings?
Embeddings is an AI engineering fundamental for people who work with LLMs. Text turned into vectors: what similarity captures and where it misleads.
A help center had a search box that matched keywords. A customer typed: I can't get into my account. Zero results.
The right article was called: how to reset your password. Not a single word in common. Same topic.
So the team switched the search to embeddings, and that question started finding the right article. Two weeks later, a new bug. People searching cancel subscription got, as the very first result: how to subscribe to the annual plan.
Similar topic, opposite intent. These two cases show exactly what embeddings capture, and where they mislead. And by the end of this lesson, you'll know when to trust them, and when to reach for something else.
An embedding is a list of numbers, a vector, that represents the meaning of a text. An embedding model was trained so that texts with similar meaning become vectors that sit close together.
Picture a huge map. Every text gets a point on it. Reset password and can't get into my account land on the same street. Delivery times by region lands in another neighborhood entirely.
You start with two texts. A customer's question and a help article, for example.
The same embedding model processes both.
Each text becomes a vector, with hundreds or thousands of dimensions.
A simple calculation, usually cosine similarity, compares the two vectors.
And the result tells you how close the meanings are. The meanings, not the words.
One rule people learn the hard way. The question and the documents have to go through the same model. Each model draws a different map. Comparing a vector from one model with vectors from another is like comparing a street address with a map of another planet. So if you change the embedding model, you rebuild the whole index.
So what does similarity capture well? Synonyms and paraphrases. Get into my account sits close to log in, and to reset password.
Different languages, if the model is multilingual. Reembolso, in Portuguese, sits close to refund.
And the general topic. Texts about the same theme cluster together.
In Brazilian support, this shows up all the time. Pix didn't land, and transfer not credited, share almost no words. They name the same pain. Embeddings catch that. A search that only matches keywords doesn't.
Now where it misleads. Negation and intent. Cancel subscription and subscribe to a plan share a topic, and the vector sees the topic first.
Numbers and codes. Order forty-five twenty-one and order forty-five twelve end up almost identical. The vector sees: this is an order number. For identifiers, tax IDs and tracking codes, filter in the database. Not by similarity.
Rare terms from your domain. Internal acronyms and product names may be unknown to the model.
And texts that are too long. A twenty page document becomes one single vector, and the meaning of each passage gets diluted. That's why documents are split into chunks before they become embeddings.
That last one is the classic beginner trap. The team embeds a forty page policy as one vector. A question about the return window for electronics hits a blob that mixes vacation, refunds, returns and a code of ethics. The similarity score can even be high. But the useful passage is not isolated. Chunking exists so each vector stands for one topic.
Here's one for you. Back to the help center. A customer searches cancel subscription, and the first result is how to subscribe to the annual plan. Is the index broken? What's the right reading of that ranking?
The index is fine. The embedding did its job. It clustered the subscription topic. Intent just came out inverted. To break that tie, you need a signal beyond similarity. Keywords, a filter, reranking, or a classifier.
And swapping for a model that's better in Portuguese won't fix it either. The same thing happens in English, with cancel and subscribe. The model might nudge the order. The intent limit stays.
So where do embeddings show up in practice? Semantic search. Compare the question with chunks of documents, and take the closest.
Retrieval for generation, or RAG. Use that search to choose what goes into the model's context. That's the next lesson.
Clustering. Group similar tickets or feedback, without labeling anything first.
Cheap routing. Compare the message with examples of each route. But watch for ties. A message like I was charged twice for order forty-five twenty-one sits right between billing and orders. Below a threshold, send it to a classifier or a person, instead of forcing first place.
And semantic cache. Reuse the answer to a question that's very close to one you already answered. It inherits the same trap. How do I cancel sits close to how do I subscribe. With a loose threshold, the cache serves the wrong answer. So treat the threshold as part of the contract, and test it with opposite intent cases.
On the page there's an experiment that runs on your laptop, no API key, with a small open multilingual model. You compare one question against four help articles, and print the scores.
Start with I can't get into my account, and watch reset your password come out on top.
Then change the question to I want to cancel my subscription, and see where the annual plan article lands. Finally, test order forty-five twenty-one against order forty-five twelve. The numbers will show you, on their own, everything this lesson explained.
And one warning. The scores you see belong to this model. Don't copy someone else's threshold from the internet as if it were sacred. Measure your own pairs. The ones that should match, and the ones that must not.
So what changes in your designs? Embedding only search is rarely enough. Combining it with keyword search is a pattern called hybrid search. Remember Pix didn't land? With embeddings alone, the right article sat in fifth place. Turning on keywords pushed it to first, because Pix is a rare, valuable term your domain needs to get right.
Re-sorting the top results with a model is called reranking.
How you cut documents into chunks changes search quality as much as the model does.
And identifiers, dates and amounts get exact filters in the database. Pull the order number out of the question, filter by it, and use similarity only on the free text that's left.
So here's the idea to take with you. Embeddings put meaning on a map, which is why they find the password article without a single shared word. But a map shows closeness, not direction. Cancel and subscribe are neighbors, and two order numbers look like twins. Use meaning where meaning matters, and exact filters everywhere else.
In the next lesson, we'll put embeddings to work in the pattern that grounds a model in your own documents: retrieval augmented generation. See you there.
Embeddings
Embeddings is an AI engineering fundamental for people who work with LLMs. Text turned into vectors: what similarity captures and where it misleads.
The help center search used keywords. A customer typed “I can’t get into my account” and got zero results, because the right article was called “How to reset your password”. No words in common, same topic.
The team switched search to embeddings. The question started finding the right article. Two weeks later another bug arrived: people searching “cancel subscription” got “How to subscribe to the annual plan” as the first result. Similar topic, opposite intent.
Both cases show what embeddings capture and where they mislead.
An embedding is a list of numbers (a vector) that represents the meaning of a text. An embedding model was trained so that texts with similar meaning become vectors that sit close together.
flowchart LR
T1(["1. Text A"]):::io --> E(["2. Embedding model"]):::llm
T2(["1. Text B"]):::io --> E
E --> V1["3. Vector A"]:::tool
E --> V2["3. Vector B"]:::tool
V1 --> S{"4. Similarity"}
V2 --> S
S --> R(["5. How alike they are"]):::io
The query model and the document model have to be the same, or a pair trained to work together. Mixing an embedding from one provider with another from a second provider produces numbers that do not mean closeness. If you change the model, you rebuild the whole index.
In Brazil this shows up constantly in support. “Pix não caiu” (“the Pix payment did not land”; Pix is Brazil’s instant payment system) and “transferência não creditada” (“the transfer was not credited”) share almost no words and name the same pain. Embedding catches that case. Keyword search alone does not.
Tax IDs, invoice numbers, and tracking codes are the extreme of the numbers case. The difference between two IDs is a few digits; the vector sees “this is an ID” and finds them similar. Filter in the database, not similarity.
The beginner trap is embedding the entire policy PDF as one vector. The question “what is the return window for electronics?” hits a blob that mixes vacation, refunds, returns, and a code of ethics. The similarity number can even be high. The useful passage is not isolated.
| Use | How |
|---|---|
| Semantic search | Compares the question with document chunks and takes the closest |
| RAG | Uses semantic search to choose what goes into the model’s context |
| Clustering | Groups similar tickets or feedback without labels |
| Cheap routing | Compares the message with examples of each route |
| Semantic cache | Reuses the answer to a question very close to one already answered |
Semantic cache inherits the same trap. “How do I cancel?” close to “How do I subscribe?” can return the wrong answer if the similarity threshold is loose. Treat the threshold as part of the contract, and measure it with opposite-intent cases.
This experiment runs locally, with no API key, using an open multilingual model: pip install sentence-transformers.
from sentence_transformers import SentenceTransformer, util
model = SentenceTransformer("sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2")
query = "I can't get into my account"
docs = [
"How to reset your password",
"How to cancel your subscription",
"How to subscribe to the annual plan",
"Delivery times by region",
]
scores = util.cos_sim(model.encode(query), model.encode(docs))[0]
for doc, score in sorted(zip(docs, scores), key=lambda x: -x[1]):
print(f"{score:.2f} {doc}")
Then change the query to “I want to cancel my subscription” and see where “How to subscribe to the annual plan” lands. Finally, test “order 4521” against “order 4512”. The numbers will show on their own what this page explained.
The cosine values you see belong to this model, on this hardware. Do not copy someone else’s 0.73 from the internet as a sacred threshold. Measure your own pairs: the ones that should match and the ones that must not.
Answer the 6 questions to complete this lesson. Watching alone does not complete it: the check is what counts toward the trail and the certificate.
Embeddings is an AI engineering fundamental for people who work with LLMs. Text turned into vectors: what similarity captures and where it misleads.