If you’ve looked into RAG or semantic search, you’ve hit the word “embeddings” — and maybe bounced off it. It’s simpler than it sounds. This article explains what embeddings actually are, how to generate them in C#, and what you do with them, without the math-heavy hand-waving.
What an embedding is
An embedding is a list of numbers (a vector) that represents the meaning of a piece of text. A model turns “I love my dog” into something like [0.02, -0.11, 0.34, ...] — often hundreds or thousands of numbers. The key property: texts with similar meaning get similar vectors. “I love my dog” and “My puppy is the best” land close together in this number-space; “quarterly tax filing” lands far away.
That’s the whole trick. Once meaning is a vector, “find similar text” becomes “find nearby vectors” — a math operation computers are fast at.
Generating embeddings in C#
You call an embedding model, not a chat model. With Microsoft.Extensions.AI, you use an IEmbeddingGenerator:
using Microsoft.Extensions.AI;
IEmbeddingGenerator<string, Embedding<float>> generator = /* e.g. an OpenAI embeddings client */;
Embedding<float> embedding = await generator.GenerateAsync("I love my dog");
ReadOnlyMemory<float> vector = embedding.Vector; // the array of numbers
Console.WriteLine($"Dimensions: {vector.Length}");
That’s it — text in, vector out. You generate a vector for each chunk of text you want to make searchable, and store them.
Measuring similarity
To compare two vectors, you compute their cosine similarity — a number from -1 to 1 where higher means more similar. Conceptually:
static float CosineSimilarity(ReadOnlySpan<float> a, ReadOnlySpan<float> b)
{
float dot = 0, magA = 0, magB = 0;
for (int i = 0; i < a.Length; i++)
{
dot += a[i] * b[i];
magA += a[i] * a[i];
magB += b[i] * b[i];
}
return dot / (MathF.Sqrt(magA) * MathF.Sqrt(magB));
}
In practice you don’t hand-roll this at scale — a vector database does the nearest-neighbour search for you. But this is what’s happening underneath.
What you actually do with embeddings
Embeddings power a surprising range of features:
- Semantic search — find documents by meaning, not keywords (how-to here).
- RAG — retrieve the most relevant chunks to ground an agent’s answer (RAG in .NET).
- Clustering & deduplication — group similar items, find near-duplicates.
- Classification — label text by comparing it to labelled examples.
- Recommendations — “more like this.”
If your problem is “find things that mean something similar,” embeddings are the tool.
Practical notes
- Use one model consistently. Vectors from different embedding models aren’t comparable — pick one and re-embed everything if you switch.
- Chunk sensibly. Embed paragraphs or sections, not whole documents, so a match points to the right passage.
- Store the original text alongside the vector — you’ll need it when a search returns a hit.
Note: the
IEmbeddingGeneratorinterface is still stabilizing inMicrosoft.Extensions.AI. Verify against the current .NET AI docs; the concept — text becomes a meaning-vector, similarity is distance between vectors — is fundamental and unchanging.
Takeaway
An embedding turns text into a vector of numbers where similar meanings sit close together. Generate them in C# with an IEmbeddingGenerator, compare them with cosine similarity (or let a vector database do it at scale), and you unlock semantic search, RAG, clustering, and recommendations. It’s the quiet workhorse behind most “the AI understood what I meant” features — and far less mysterious than the jargon suggests.
Have a correction or a topic you want covered? Email mani.bc72@gmail.com.