# EmbeddingModel Interface

Interface that all embedding model implementations must satisfy.

## Interface Definition

```go
type EmbeddingModel interface {
    // Metadata
    SpecificationVersion() string
    Provider() string
    ModelID() string

    // Capability methods
    MaxEmbeddingsPerCall() int
    SupportsParallelCalls() bool

    // Embedding methods
    DoEmbed(ctx context.Context, input string, opts *provider.EmbedModelOptions) (*types.EmbeddingResult, error)
    DoEmbedMany(ctx context.Context, inputs []string, opts *provider.EmbedModelOptions) (*types.EmbeddingsResult, error)
}
```

`opts` may be `nil`. Use `provider.EmbedModelOptions` when forwarding provider-specific options or custom headers.

```go
type EmbedModelOptions struct {
    ProviderOptions map[string]interface{}
    Headers         map[string]string
}
```

## Methods

### Metadata Methods

| Method | Returns | Description |
|--------|---------|-------------|
| SpecificationVersion() | string | Returns specification version |
| Provider() | string | Provider name (e.g., "openai", "cohere") |
| ModelID() | string | Model ID (e.g., "text-embedding-3-small") |

### Capability Methods

| Method | Returns | Description |
|--------|---------|-------------|
| MaxEmbeddingsPerCall() | int | Maximum embeddings per API call (0 for unlimited) |
| SupportsParallelCalls() | bool | Whether model supports parallel calls for batching |

### Embedding Methods

| Method | Parameters | Returns | Description |
|--------|------------|---------|-------------|
| DoEmbed() | ctx, string, opts | *types.EmbeddingResult, error | Generate single embedding |
| DoEmbedMany() | ctx, []string, opts | *types.EmbeddingsResult, error | Generate multiple embeddings |

## Examples

### Using an Embedding Model

```go
package main

import (
    "context"
    "fmt"
    "log"

    "github.com/digitallysavvy/go-ai/pkg/providers/openai"
)

func main() {
    // Get an embedding model
    provider := openai.New(openai.Config{
        APIKey: "your-api-key",
    })
    model, err := provider.EmbeddingModel("text-embedding-3-small")
    if err != nil {
        log.Fatal(err)
    }

    // Check capabilities
    fmt.Printf("Model: %s\n", model.ModelID())
    fmt.Printf("Provider: %s\n", model.Provider())
    fmt.Printf("Max embeddings per call: %d\n", model.MaxEmbeddingsPerCall())
    fmt.Printf("Supports parallel calls: %v\n", model.SupportsParallelCalls())

    // Generate embedding
    result, err := model.DoEmbed(context.Background(), "Hello, world!", nil)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Printf("Embedding dimensions: %d\n", len(result.Embedding))
}
```

### Batch Embeddings

```go
texts := []string{
    "First text",
    "Second text",
    "Third text",
}

result, err := model.DoEmbedMany(ctx, texts, nil)
if err != nil {
    log.Fatal(err)
}

fmt.Printf("Generated %d embeddings\n", len(result.Embeddings))
for i, emb := range result.Embeddings {
    fmt.Printf("Text %d: %d dimensions\n", i+1, len(emb))
}
```

### Provider Options

Provider-specific embedding options use the same provider-keyed shape as generation APIs:

```go
dimensions := 768
result, err := model.DoEmbed(ctx, "document text", &provider.EmbedModelOptions{
    ProviderOptions: map[string]interface{}{
        "google": google.GoogleEmbeddingProviderOptions{
            TaskType:             "RETRIEVAL_DOCUMENT",
            OutputDimensionality: &dimensions,
        },
    },
})
```

### Respecting Max Embeddings Limit

```go
func embedLargeDataset(model provider.EmbeddingModel, texts []string) ([][]float64, error) {
    maxPerCall := model.MaxEmbeddingsPerCall()
    if maxPerCall <= 0 {
        maxPerCall = len(texts) // Unlimited
    }

    var allEmbeddings [][]float64

    for i := 0; i < len(texts); i += maxPerCall {
        end := i + maxPerCall
        if end > len(texts) {
            end = len(texts)
        }

        batch := texts[i:end]
        result, err := model.DoEmbedMany(ctx, batch, nil)
        if err != nil {
            return nil, err
        }

        allEmbeddings = append(allEmbeddings, result.Embeddings...)
    }

    return allEmbeddings, nil
}
```

## See Also

- [LanguageModel](https://goaisdk.com/docs/reference/providers/language-model.md) - Language model interface
- [Embed](https://goaisdk.com/docs/reference/ai/embed.md) - High-level embedding function
- [EmbedMany](https://goaisdk.com/docs/reference/ai/embed-many.md) - Batch embedding function
- [Custom Provider](https://goaisdk.com/docs/reference/providers/custom-provider.md) - Implementing custom providers
