---
title: "Vectors and similarity"
summary: "Embeddings turn text into numbers so you can find similar documents mathematically."
track: "The model"
day: 5
minutes: 18
author: "Akash Panchal"
url: https://ai-sdk-patterns.dev/learn/fundamentals/day-5/embeddings
dateModified: 2026-08-29
---

# Vectors and similarity

Embeddings turn text into numbers so you can find similar documents mathematically.

*The model · Day 5: Embeddings primer · ~18 min. Written by [Akash Panchal](https://github.com/akashp1712).*

Canonical: https://ai-sdk-patterns.dev/learn/fundamentals/day-5/embeddings

## After this topic

You will be able to say what an embedding is without waving at “vectors”: a list of numbers that represents meaning, so two sentences about the same thing sit close together even when they share few words. You will know why that is not a chat model, and why RAG is this idea plus a prompt.

## Meaning, as numbers

> An embedding is a list of numbers (a vector) that represents meaning. Sentences about the same thing land close together, even if they share few words.

A chat model writes the next token. An embedding model maps a string to a point. Different jobs, different APIs.

An LLM writes the next token. An embedding model does a different job: it maps a string to a point in a high-dimensional space (hundreds or thousands of numbers). “How do I stream with the AI SDK?” and “token streaming in Next.js” can sit near each other even though the words differ.

You do not train that space in app work. You call embed() (or embedMany) from the AI SDK, store the vector next to the chunk of text it came from, and later embed the user’s question and find the nearest stored points. Those nearby chunks go into the prompt. That pipeline is RAG — retrieval-augmented generation — and it is a later chapter. This topic is the vector, so RAG is not magic when you meet it.

Keyword search fails when the user does not use your docs’ wording. Embeddings fail when two texts are close in vibe but not in fact — you still have to read what you retrieved. They are a ranking tool, not a source of truth.

- Embedding — a number[] that stands for a piece of text
- Similarity — how close two embeddings are (often cosine similarity)
- Index — the stored pairs of (chunk, embedding) you search at ask time
- RAG — retrieve nearby chunks, put them in the prompt, then call the chat model

## One embedding

This turns one string into a number[]. A RAG pipeline does this for every chunk at index time, then again for the query at ask time. The LLM call (generateText / streamText) happens after you have the top chunks, not instead of them.

The model id is an embedding model, not a chat model. Mixing them up is a common first bug: you cannot stream from text-embedding-3-small, and you cannot embed with claude-sonnet-4-5.

### embed-once.ts

```ts
import { embed } from "ai";

const { embedding } = await embed({
  model: "openai/text-embedding-3-small",
  value: "How do I stream with the AI SDK?",
});

// embedding is number[] — store it, then search by cosine similarity.
```

- **embedding models are not LLMs.** text-embedding-3-small does not chat. It only maps text to numbers. You still need generateText later to write the answer.
- **number[] is the product.** Store it next to the chunk (Postgres + pgvector, or a vector store). At query time, embed the question, rank by cosine similarity, take the top k chunks into the prompt.
- **Same Gateway idea.** The model id is still a string. Pick an embedding model, not a chat model. Mixing them up is a common first bug.

## Find, then ask

RAG is four steps you already have the pieces for. Split docs into chunks. Embed each chunk and store it. At ask time, embed the question, take the nearest chunks, put them in the prompt, call the chat model. The model never searched the files. You did.

The quality of the answer is the quality of those chunks. Bad splits, stale index, missing permissions — the model will write a fluent paragraph around whatever you stuffed in. That is still Day 1: if it is not in the request, the model does not have it; if the wrong thing is in the request, the model will use it.

## What this does not replace

Embeddings do not update when your docs change unless you re-index. They do not enforce permissions — if a chunk should not be in the prompt, do not retrieve it. They do not write the answer; the chat model still might hallucinate around the chunks you gave it.

When the question is a keyword (“error TS2345”), a normal search might win. When the question is a paraphrase of a paragraph in your guide, embeddings win. Most products use both.

This is the last topic in The model. Next chapter: the same next-token model, allowed to call your functions, in a loop.

## Common questions

### What is “Vectors and similarity”?

Embeddings turn text into numbers so you can find similar documents mathematically.

### What will I be able to do after this lesson?

You will be able to say what an embedding is without waving at “vectors”: a list of numbers that represents meaning, so two sentences about the same thing sit close together even when they share few words. You will know why that is not a chat model, and why RAG is this idea plus a prompt.

### How long does this lesson take?

About 18 minutes of reading. It is a free chapter in the AI SDK Patterns TypeScript course.

### When should I not use this?

Embeddings do not update when your docs change unless you re-index. They do not enforce permissions — if a chunk should not be in the prompt, do not retrieve it. They do not write the answer; the chat model still might hallucinate around the chunks you gave it.
