# embedding provider (app.Embedding)

> `app.Embedding` declares the embedding model the app uses to turn text into vectors for semantic search over `[Searchable]` fields (see `Memory.Search`). You name a `Provider`, a `Model` string, the `ApiKey` (a `Secret.X` handle), and the vector `Dimensions` — plus an optional `BaseUrl` to run the model at an endpoint you choose. A singleton.

<!-- id: config-embedding · area: config · stability: stable · html: https://osysharp.com/reference/config/embedding/ -->

## Summary        {#summary}
`app.Embedding` declares the embedding model your application uses to turn text into vectors, so that semantic search
over `[Searchable]` fields (queried through `Memory.Search`) has something to embed against. You name a **provider**, a
**model**, the **secret** that authenticates to that provider, and the **dimensions** of the vectors it returns. It is a
**singleton** — one embedding configuration per app.

```osy syntax
app.Embedding = new EmbeddingConfig {
  Provider   = EmbeddingProvider.OpenAI,
  Model      = "text-embedding-3-small",
  ApiKey     = Secret.OpenAI,
  Dimensions = 1536,
};
```

## Signature      {#signature}
```osy
app.Secrets = [ new Secret("OpenAI") ];   // the handle the config below reads

app.Embedding = new EmbeddingConfig {
  Provider   = EmbeddingProvider.OpenAI,   // which embedding provider
  Model      = "text-embedding-3-small",   // the provider's embedding model id
  ApiKey     = Secret.OpenAI,              // a Secret.X handle from app.Secrets
  Dimensions = 1536,                       // the width of the produced vectors
  BaseUrl    = "https://…/v1/embeddings",  // optional — where to run it (default: the provider's own endpoint)
};
```

`app.Embedding` is a single value, not a list — an app configures exactly one embedding model.

## Description    {#description}
An `EmbeddingConfig` has five members, four of them required in practice:

- **`Provider`** — an `EmbeddingProvider` enum member naming which service produces the vectors. The example uses
  `EmbeddingProvider.OpenAI`.
- **`Model`** — the provider's embedding model id, as a string (for example `"text-embedding-3-small"`). This chooses
  which model the provider runs.
- **`ApiKey`** — a `Secret.X` handle referencing a secret declared in `app.Secrets`. It authenticates calls to the
  provider; the value itself lives outside your source.
- **`Dimensions`** — the width of each produced vector (for example `1536`). This must match the vector size the chosen
  model emits, so that stored `[Searchable]` vectors and query vectors are comparable.
- **`BaseUrl`** — optional. The endpoint that actually computes the embeddings. Omit it and the provider's own
  endpoint is used; give it and the model runs wherever you say — a service you host, a regional deployment, an
  inference endpoint inside a particular jurisdiction. It is the whole URL, not a host to append a path to, because a
  compatible service may mount the protocol wherever it likes.

`Provider` takes one of three values:

| Provider | What it means |
|---|---|
| `EmbeddingProvider.OpenAI` | OpenAI's own embeddings endpoint. `BaseUrl` optional (a proxy in front of it). |
| `EmbeddingProvider.Google` | Google's embeddings. |
| `EmbeddingProvider.OpenAICompatible` | Any service speaking the OpenAI embeddings protocol. **`BaseUrl` required** — the provider means "that protocol, at an endpoint you name", so there is no sensible default. |

> **The platform ships no embedding model of its own, on purpose.** A vector column is sized for the model that
> fills it, and vectors from one model are never comparable with another's — so an app that embedded with a small
> bundled model in development and a hosted one in production was never testing the feature it shipped. Declare one
> embedder and use it everywhere: locally, in tests, in production. It costs nothing to keep it free and offline:
> run an OpenAI-protocol embedding server on your own machine or in your own network and point
> `EmbeddingProvider.OpenAICompatible` at it — the second example below is exactly that.

**Why `BaseUrl` matters even when you are using OpenAI.** Where a model runs can be a requirement rather than a
preference — data-residency obligations are usually written about *where the data goes*, and embedding is the
operation that reads every indexed row. [default LLM model (app.DefaultModel)](https://osysharp.com/reference/agent/default-model/) takes a `BaseUrl` for the same reason — chat and
embeddings answer the same placement question, and an app that must place one almost always has to place both.

`app.Embedding` is a **singleton**: an application declares one embedding configuration, and every `[Searchable]` field
and every `Memory.Search` query uses it.

## Examples       {#examples}
Declare the secret, then configure OpenAI embeddings against it:

```osy title="basic" test app=config-embedding-example
app.Secrets = [ new Secret("OpenAI") ];

app.Embedding = new EmbeddingConfig {
  Provider = EmbeddingProvider.OpenAI,
  Model = "text-embedding-3-small",
  ApiKey = Secret.OpenAI,
  Dimensions = 1536,
};
```

Place the model at your own endpoint — the same declaration, with the provider and endpoint changed:

```osy title="an embedding model you host" test app=config-embedding-placed
app.Secrets = [ new Secret("Embeddings") ];

app.Embedding = new EmbeddingConfig {
  Provider   = EmbeddingProvider.OpenAICompatible,
  Model      = "bge-m3",
  ApiKey     = Secret.Embeddings,
  Dimensions = 1024,
  BaseUrl    = "https://embeddings.internal.example/v1/embeddings",
};
```

## See also       {#see-also}
- [declaring secrets (app.Secrets)](https://osysharp.com/reference/config/secrets/) — `app.Secrets`, where the `ApiKey` handle referenced by `Embedding` is declared
- [[Searchable]](https://osysharp.com/reference/memory/searchable/) — marking a field `[Searchable]` so its text is embedded for search
- [using Memory (semantic search)](https://osysharp.com/reference/memory/search/) — `Memory.Search`, the query that runs against the embedded vectors
- [default LLM model (app.DefaultModel)](https://osysharp.com/reference/agent/default-model/) — `app.DefaultModel`, the same placement question for the chat model
