Embeddings in plain words: what they are and why search needs them

An embedding turns text into a set of numbers you can use to find similar meaning. We explain without math, where embeddings come from, and when you do not need a vector database.

5 min · · models · автоматизация

An embedding in machine learning is a list of numbers (a vector) that describes the meaning of a piece of text so that a computer can compare meanings. Two texts with similar meaning get close vectors even when they share no words. Below we explain without formulas what an embedding in a neural network is, where it comes from, why search and RAG need it, and when for small volumes you can skip the vector database entirely.

What an embedding in machine learning is

Imagine every text is assigned a point on a map. Texts about refunds sit next to each other, texts about store opening hours lie in another part of the map. Only the map is not two-dimensional but has hundreds or thousands of dimensions, and a special model calculates the coordinates. The set of those coordinates is the embedding.

According to OpenAI's embeddings guide, an embedding is a vector of floating point numbers, and the distance between two vectors measures how related the texts are: a small distance means high relatedness. For text-embedding-3-small and text-embedding-3-large the default vector length is 1536 and 3072 numbers, and it can be reduced with the dimensions parameter. Pricing depends on the number of input tokens.

Hence the answer to "what is an embedding in a neural network": it is neither a model's answer nor text, but an intermediate numeric representation, which is why separate embedding models exist. A chat model generates words; an embedding model returns only a vector.

How texts are compared

Most often cosine similarity is calculated: the closer the directions of two vectors, the closer the number is to one. A toy example in three dimensions (real vectors are much longer, the values are invented for illustration):

bash
import math

def cosine(a, b):
    dot = sum(x * y for x, y in zip(a, b))
    na = math.sqrt(sum(x * x for x in a))
    nb = math.sqrt(sum(y * y for y in b))
    return dot / (na * nb)

query = [0.8, 0.2, 0.1]            # "how do I get my money back"
docs = {
    "returning a product": [0.9, 0.1, 0.0],
    "store opening hours": [0.1, 0.9, 0.2],
    "courier delivery": [0.2, 0.3, 0.9],
}
for name, vec in docs.items():
    print(name, round(cosine(query, vec), 3))

Program output:

bash
returning a product 0.984
store opening hours 0.363
courier delivery 0.385

The query ends up closest to the document about returns, even though the words "get money back" may not appear in it. That is semantic search.

Why search and RAG need embeddings

The OpenAI guide names these uses: search, clustering similar texts, recommendations, anomaly detection, diversity analysis and classification by the nearest label. The main scenario for chatbots is RAG:

  1. Documents are cut into pieces, an embedding is computed for each piece, and the vectors are saved in a store.
  2. The user's question is also turned into a vector.
  3. The pieces with the closest vectors are found.
  4. Those pieces are inserted into the request to the chat model, and it answers from them.

Semantic search finds text by meaning, not by word match, so "how do I get my money back" will find "processing a return". A side effect: search can miss on rare terms, numbers and part numbers, where an exact match matters more than meaning. That is why serious systems combine it with ordinary keyword search.

LLM embeddings versus a chat model: the difference

Inside any large language model there are its own vector representations of words, but they are usually not used for search. Special embedding models trained specifically for comparing texts are used instead. Two different embedding models produce incompatible vectors: if you change the model, the whole corpus must be recomputed, because vectors from different models cannot be compared.

Where to get embeddings

  • Through a provider's API, for example text-embedding-3-small from OpenAI. An example following the OpenAI guide:
bash
from openai import OpenAI

client = OpenAI()  # key and address of your embeddings provider
resp = client.embeddings.create(
    model="text-embedding-3-small",
    input="How do I get my money back for an order?",
)
vector = resp.data[0].embedding  # a list of 1536 numbers
print(len(vector))
  • Local models that run on your machine or server. They are free per token but need hardware.
  • Built-in models of tools. For example, Open WebUI ships a small default embedding model.

The Zukko gateway endpoint list has no embeddings endpoint: the gateway offers Claude, GPT, Gemini, DeepSeek, Qwen and GLM for text generation. For vector search you will need a separate embedding model, while the answers over the retrieved pieces come from a gateway model.

Do you need a vector database

A vector database is needed when documents are many and must be searched fast. But for small volumes there is an alternative: put the documents into the request whole. Most Zukko models have a 1M token context, Grok 4.x has 256K, and GLM 5.3 has 128K.

Let us calculate. Suppose 200 documents of 2000 tokens give 400,000 tokens. Formula: tokens × input price per million. Prices as of October 18, 2026.

  • The whole corpus in every request on gpt-6.1-sol (input 0.27): 0.4 × 0.27 = $0.108 per question.
  • The same on deepseek-v4.1-flash (input 0.013): 0.4 × 0.013 = $0.0052.
  • Vector search, 5 pieces of 500 tokens (2500 tokens) on gpt-6.1-sol: 2500 × 0.27 / 1,000,000 = $0.000675.

If the corpus is unchanged and questions are many, caching helps: on gpt-6.1-sol a cache read costs 0.013 per million, so the same corpus from cache costs 0.4 × 0.013 = $0.0052 per question, if the cache hits. But a cache lives for a limited time and depends on the provider, so do not rely on it without checking.

The practical takeaway. Long context is convenient for one-off tasks and small corpora: less code, no indexing. But its cost grows with corpus size and question count, and completeness of the answer over a very long input is not guaranteed, so check it on test questions. Vector search starts paying off when documents are many or questions are a steady stream. More on this trade-off: a million-token context and RAG on a cheap model without a vector DB. The full scheme is described in a RAG pipeline on your own data.

The current list of models, context and prices: GET https://api.zukko.pro/v1/models, the "Models" page in your account and the model reference.

FAQ

Are an embedding and a token the same thing?

No. A token is a piece of text into which the model splits the input. An embedding is a vector of numbers describing the meaning of a whole fragment. Tokens are counted for price, embeddings for comparison.

Can vectors from different models be compared?

No. Each model defines its own space, so when you change the model you must recompute all documents.

Must vectors be stored in a special database?

No. For hundreds of documents a plain in-memory array or a file is enough. Special stores are needed for large volumes and fast search.

Are embeddings needed if the model has a long context?

For a small corpus you can do without them; for a large corpus with frequent searches you cannot, because the price of each question grows with corpus size. Try both options on your data. A key for testing is created in your account; access from Russia goes through the gateway, with payment by SBP, MasterCard or crypto.

zukko

Pay 25×
less

for Claude Code & ChatGPT

One fetch_* key and base URL api.zukko.pro — for Cursor, Claude Code, Codex, and any SDK.

Get API keyDocumentation

api.zukko.pro · fetch_*

What an embedding is in machine learning, in plain words · Zukko