Embeddings
Embedding providers turn text into numeric vectors. The vector is what a vector store indexes, what cosine similarity measures, and what hybrid search combines with BM25.
LogicGrid.Memory serves three providers — local (Ollama) OpenAI Client and OpenAI
compatible hosted-API servers (vLLM, TEI, Gemini).
dotnet add package LogicGrid.Memory
EmbeddingClientBase contract
public abstract class EmbeddingClientBase
{
public abstract string ModelName { get; }
public abstract int Dimensions { get; }
public abstract Task<float[]> EmbedAsync(
string text, CancellationToken ct = default);
// Override for providers with native batching (OpenAI, vLLM, TEI).
// Default implementation calls EmbedAsync in a loop.
public virtual Task<float[][]> EmbedBatchAsync(
IList<string> texts, CancellationToken ct = default);
}
Dimensions is sometimes 0 until the first call (Ollama
discovers it from the response); pass the known dimension count to
the constructor when you have it to avoid that round-trip.
OllamaEmbeddingClient
public OllamaEmbeddingClient(
string baseUrl = "http://localhost:11434",
string defaultModel = "nomic-embed-text",
int dimensions = 0) // 0 = discover on first call
Common used models
| Model | Dimensions | When to use |
|---|---|---|
nomic-embed-text (default) | 768 | General-purpose, balanced quality/size. |
mxbai-embed-large | 1024 | Higher quality, slightly slower. |
bge-m3 | 1024 | Multilingual. |
How to use it
var embedder = new OllamaEmbeddingClient(defaultModel: "nomic-embed-text");
var vec = await embedder.EmbedAsync("Hybrid search combines dense and sparse retrieval.");
Console.WriteLine($"Dimensions: {embedder.Dimensions}"); // 768
OpenAiEmbeddingClient
public OpenAiEmbeddingClient(
string apiKey,
string defaultModel = "text-embedding-3-small",
int dimensions = 1536)
The OpenAI API. text-embedding-3-small is the cheap default;
text-embedding-3-large is the higher-quality option.
How to use it
var embedder = new OpenAiEmbeddingClient(
apiKey: Environment.GetEnvironmentVariable("OPENAI_API_KEY")!,
defaultModel: "text-embedding-3-small");
OpenAiCompatibleEmbeddingClient
public OpenAiCompatibleEmbeddingClient(
string baseUrl,
string defaultModel,
int dimensions = 0,
string? apiKey = null)
Anything that exposes the OpenAI Embeddings API at /v1/embeddings:
vLLM, TEI (HuggingFace Text Embeddings Inference), LM Studio, Gemini
via its OpenAI-compatible endpoint.
// vLLM serving an embedding model locally
var vllm = new OpenAiCompatibleEmbeddingClient(
baseUrl: "http://localhost:8000",
defaultModel: "BAAI/bge-large-en-v1.5",
dimensions: 1024);
// TEI
var tei = new OpenAiCompatibleEmbeddingClient(
baseUrl: "http://localhost:3000",
defaultModel: "BAAI/bge-base-en-v1.5",
dimensions: 768);
Batch embedding
EmbedBatchAsync is significantly cheaper per item — every provider
batches under the hood. The RAG pipeline uses it automatically when
ingesting documents.
var vectors = await embedder.EmbedBatchAsync(new[]
{
"First chunk.",
"Second chunk.",
"Third chunk.",
});
Where next
- Vector stores — InMemory, Qdrant, Hybrid.
- Semantic memory — durable, role-scoped memory built on top of an embedding model and a vector store.
- RAG pipeline — full end-to-end ingest + search.