learn-rag-with-phoebe / Builder session 1 of 10
Learn RAG with Phoebe · Builder track · Session 1 of 10

Embeddings 101: turning meaning into numbers

Retrieval stands on one idea: if you can turn a piece of text into a list of numbers that captures what it means, then "find related text" becomes "find nearby numbers". This session builds that intuition from zero - what a vector is, why cosine similarity ranks by meaning, and why a question rarely shares words with its answer. You will feel it in a live playground before you write a line of Python, then meet the real embedding models. This is where Recall, the assistant you grow all track, gets its senses.

🟢 Builder track Practitioners · some Python Live playground included Start here
0-3 · Welcome 3-18 · Concepts 18-40 · Build-along 40-45 · Q&A
Part 0

The one idea the whole course rests on

Everything in RAG - vector databases, chunking, hybrid search, reranking - is machinery around a single trick: an embedding turns text into a point in space, and nearby points mean similar things. Get this one idea in your hands and the rest of the track is engineering. Get it wrong and no amount of infrastructure will save your retrieval. So we start slow, and we start with a playground you can poke at right now.

Live - presented in session Self-study - full depth after class ★ Try it now Sources covered at the end
★ What you build today A working intuition for embeddings and cosine similarity, hands-on time in a live retrieval playground over Recall's first corpus, and the Python to embed text with a real model and rank passages by similarity - the beating heart of every RAG system you will ever ship.
Part 1 · covers embeddings + vector space

A vector is meaning, written as numbers 7 min live

An embedding model reads a piece of text and outputs a fixed-length list of numbers - often hundreds or thousands of them. Each number is a coordinate, so the text becomes a point in a high-dimensional space. The magic is what the model was trained to do: place texts that mean similar things close together, even if they use different words.

dimension 1 → dimension 2 → "book a flight" "aisle seat" "travel plans" "get my money back" "return policy" "refund window" "the weather today" Different words, same meaning, land together. Real space has hundreds of dimensions - same idea.
🔍 Click to zoom - embedding space (projected to 2D): meaning becomes location
LiveFrom text to coordinates3 min

Think of an embedding as a fingerprint of meaning. "Book a flight to Berlin" and "reserve a seat on the Berlin plane" share almost no words, yet a good embedding model puts them millimeters apart, because it learned what they are about. "The mitochondria is the powerhouse of the cell" lands in a completely different region.

  • Fixed length. Every text, short or long, becomes the same-size list (e.g. 1,536 numbers for OpenAI's text-embedding-3-small). That is what lets you compare any two.
  • Direction carries meaning. It is not the magnitude that matters so much as which way the vector points. Two vectors pointing the same way mean similar things - which is exactly what cosine similarity measures.
  • You do not read them. No single number means "travel". Meaning is spread across all the dimensions at once. You never inspect them by hand - you compare them.
LiveWhy questions rarely share words with answers3 min

Here is the argument for embeddings over old-fashioned keyword search, straight from the OpenAI cookbook: questions often do not lexically overlap with their answers. "How do I get my money back?" and a help-center paragraph titled "Refunds are issued to the original payment method within 5-7 business days" share zero important words. Keyword search misses it. Meaning search nails it, because both land in the same region of embedding space.

Real world

The FAQ nobody could find. A team (anonymized) had a perfect answer to "why was I charged twice?" living under a heading called "Duplicate authorization holds". Keyword search never surfaced it - no shared words. Switching retrieval to embeddings made it the top hit overnight. Same documents, different math.

You will watch exactly this happen in the playground below - type a question in your own words and see it rank a passage that shares none of them.

Part 2 · covers cosine similarity + the retrieval mechanic

Cosine similarity: ranking by angle 8 min live

Once every text is a vector, "most related" becomes "smallest angle between vectors". Cosine similarity measures that: 1.0 means pointing the exact same way (identical meaning), 0 means unrelated (perpendicular). It is the single most common similarity metric in RAG, and the OpenAI cookbook computes it as 1 - cosine_distance.

query: "money back?" "refund policy" cosine 0.82 ✓ "office hours" cosine 0.09 small angle Retrieval = rank every passage by cosine to the query, return the top few.
🔍 Click to zoom - cosine similarity is the angle between the query and each passage
LiveThe metric, without the trigonometry2 min

You do not need to compute cosines by hand, but the shape is worth holding:

  • 1.0 - vectors point the same way. Same meaning. (A text compared with itself scores 1.0.)
  • ~0 - vectors are perpendicular. Unrelated.
  • Rank, don't threshold (at first). Retrieval usually returns the top-k highest-cosine passages rather than "everything above 0.8". Absolute scores drift by model; the ranking is what you trust.
Cosine vs dot product vs L2 Three metrics show up in vector databases: cosine (angle), dot product (angle + magnitude), and Euclidean/L2 (straight-line distance). For text embeddings, cosine is the usual default because it ignores length and compares pure direction. You will see all three as operators when we meet pgvector in b3.
Live★ Build-along: your first retriever, live in the browser6 min

This is Recall's first corpus: Corpus A, the chief-of-staff notes for a managing director. Type a question in your own words and hit Search. Watch each note score by cosine similarity, the best match rise to the top, and the matched terms light up. The vector strip shows your query as its top dimensions - meaning, as numbers.

Honesty note - what this playground really does To run with zero network calls, this tool uses a simplified embedding: term frequency over a small vocabulary, with a synonym map so related words land near each other. Real embedding models are neural and far richer. But the math that ranks the results - cosine similarity over vectors - is exactly what production RAG uses. You are watching the real mechanic with a toy embedder.

Try a query where the answer shares no words with your question ("holiday seating" against "aisle seats"), and one that is not in the corpus at all - notice it still returns its best guess. Deciding when a best guess is too weak to use is the whole of session b7.

Self-studyThe same thing in Python, with a real model4 min read

Outside the browser, you swap the toy embedder for a real one - an API call or a local model - and the rest is identical: embed, then rank by cosine. Here is the whole idea in a few lines, following the OpenAI cookbook pattern.

Python · embed passages and rank by cosinefrom openai import OpenAI import numpy as np client = OpenAI() def embed(texts): resp = client.embeddings.create(model="text-embedding-3-small", input=texts) return [np.array(d.embedding) for d in resp.data] def cosine(a, b): return float(a @ b / (np.linalg.norm(a) * np.linalg.norm(b))) docs = ["Refunds are issued within 5-7 business days.", "Standard shipping takes 3-5 business days.", "Support is open Monday to Friday, 9am-6pm."] doc_vecs = embed(docs) query = "how do I get my money back?" q = embed([query])[0] ranked = sorted(((cosine(q, d), doc) for d, doc in zip(doc_vecs, docs)), reverse=True) for score, doc in ranked: print(f"{score:.3f} {doc}")

The top line will be the refund passage, scoring far above the others - despite sharing not one meaningful word with the question. That gap, and nothing else, is why RAG works. Everything later in the track makes this step faster, cheaper, and more accurate at scale.

Picking an embedding model You will choose between models by three levers: quality (retrieval benchmark scores), dimensions (bigger = richer but more storage and slower), and cost/latency (API vs local). Anthropic's own retrieval work recommends strong models like Voyage and Gemini embeddings; OpenAI's text-embedding-3-small is a common, cheap default. Whatever you pick, embed your documents and your queries with the same model - mismatched spaces do not compare.
Build-along · take it further

Break the retriever on purpose ★ 10 min · the playground above

The fastest way to trust a retriever is to find where it fails. Use the Corpus A playground and hunt for its edges - the same edges real embedding systems have, just louder in a toy one.

Synonym win. Ask for something using completely different words than the note uses ("vacation flight seat" vs the note's "aisle seats"). Confirm it still ranks the right note first, and note the cosine score.

Ambiguity. Type a vague one-word query like "review". See which notes it pulls and why - short, vague queries are where retrieval is weakest, a lesson that returns in b6 (query expansion).

Not in the corpus. Ask something Corpus A cannot answer ("what is our AWS bill?"). Watch it confidently return its closest-but-wrong note. Write down what score the top result got - that number is the seed of session b7's refusal threshold.

Reflect. In one line: what kind of question is this retriever best at, and what kind quietly defeats it? That instinct is worth more than any benchmark.

★ Recall's status after b1 Recall can now turn text into vectors and rank passages by meaning. It has senses. In b2 we feed it real documents - and discover that HOW you cut those documents into chunks decides whether retrieval works at all.
Homework

Before session b2 ◐ 40 min total

Source material

Official sources covered

Taught from official docs and cookbooks. This page covers ~80% of their working content on embeddings and similarity - the rest (hosted infra, paid keys) stays with the source.

OpenAI cookbook · Question Answering Using EmbeddingsPart 1-2 · cosine = 1 - cosine_distance · questions rarely overlap answers · the embed-then-rank pattern
Weaviate · Vector Embeddings ExplainedPart 1 · embeddings as meaning-in-space · small distance = similar
DeepLearning.AI · Vector Databases: from Embeddings to ApplicationsPart 1 covers obtaining and comparing vectors; ANN search lands in b3
Anthropic · Contextual Retrieval (model choice)Self-study · embedding-model recommendations (Voyage, Gemini)
Check yourself

Three questions before you go 🎯 ◐ 90 seconds

1 · An embedding is...

An embedding is a fixed-length vector; texts with similar meaning land close together, which is what makes meaning search possible.

2 · Cosine similarity of 1.0 between a query and a passage means...

Cosine measures the angle between vectors. 1.0 = same direction = same meaning; ~0 = perpendicular = unrelated.

3 · Why does embedding-based retrieval beat keyword search for "how do I get my money back?"

Questions rarely lexically overlap their answers (OpenAI). Meaning search finds the "Refunds" passage even though it shares no words with the question.

Builder session 1 cheat sheet · pin this

EmbeddingA fixed-length vector of numbers representing meaning. Similar meaning → nearby points.
The core trick"Find related text" becomes "find nearby vectors". All of RAG is machinery around this.
Cosine similarityAngle between vectors. 1.0 = same meaning, ~0 = unrelated. Computed as 1 - cosine_distance.
Rank, don't thresholdReturn the top-k by cosine. Absolute scores drift by model; ranking is what you trust.
Why not keywordsQuestions rarely share words with their answers. Meaning search finds the right passage anyway.
MetricsCosine (angle), dot product (angle + size), L2 (distance). Cosine is the text default.
Model leversQuality vs dimensions vs cost/latency. Embed docs and queries with the SAME model.
The pipeline so farembed(text) → cosine(query, each doc) → sort → top-k. Everything later just scales this.