Skip to content

Provider & Model Management

This page adapts the original AI SDK documentation: Provider & Model Management.

When you work with multiple providers and models, it is often desirable to manage them in a central place and access the models through simple string ids.

The AI SDK offers custom providers and a provider registry for this purpose:

  • With custom providers, you can pre-configure model settings, provide model name aliases, and limit the available models.
  • The provider registry lets you mix multiple providers and access them through simple string ids.

You can mix and match custom providers, the provider registry, and middleware in your application.

You can create a current Provider V4 custom provider using customProviderV4. The legacy customProvider helper remains available for V3-only integrations.

You might want to override the default model settings for a provider or provide model name aliases with pre-configured settings.

import SwiftAISDK
import OpenAIProvider
// Custom provider with different provider options:
let customOpenAI = customProviderV4(
languageModels: [
// Replacement model with custom provider options:
"gpt-4o": wrapLanguageModel(
model: try openai.languageModel("gpt-4o"),
middleware: .single(defaultSettingsMiddleware(
settings: DefaultSettings(
providerOptions: openai.options.responses(reasoningEffort: "high")
)
))
),
// Alias model with custom provider options:
"gpt-4o-mini-high-reasoning": wrapLanguageModel(
model: try openai.languageModel("gpt-4o-mini"),
middleware: .single(defaultSettingsMiddleware(
settings: DefaultSettings(
providerOptions: openai.options.responses(reasoningEffort: "high")
)
))
)
],
fallbackProvider: openai
)

You can also provide model name aliases, so you can update the model version in one place in the future:

import SwiftAISDK
import AnthropicProvider
// Custom provider with alias names:
let customAnthropic = customProviderV4(
languageModels: [
"opus": try anthropic.languageModel(modelId: "claude-opus-4-8"),
"sonnet": try anthropic.languageModel(modelId: "claude-sonnet-5"),
"fable": try anthropic.languageModel(modelId: "claude-fable-5")
],
fallbackProvider: anthropic
)

You can limit the available models in the system, even if you have multiple providers.

import SwiftAISDK
import AnthropicProvider
import OpenAIProvider
let myProvider = customProviderV4(
languageModels: [
"text-medium": try anthropic.languageModel(modelId: "claude-sonnet-5"),
"text-small": try openai.languageModel("gpt-4o-mini"),
"reasoning-medium": wrapLanguageModel(
model: try openai.languageModel("gpt-4o"),
middleware: .single(defaultSettingsMiddleware(
settings: DefaultSettings(
providerOptions: openai.options.responses(reasoningEffort: "high")
)
))
),
"reasoning-fast": wrapLanguageModel(
model: try openai.languageModel("gpt-4o-mini"),
middleware: .single(defaultSettingsMiddleware(
settings: DefaultSettings(
providerOptions: openai.options.responses(reasoningEffort: "high")
)
))
)
],
embeddingModels: [
"embedding": openai.textEmbedding("text-embedding-3-small")
]
// No fallback provider
)

You can create a provider registry with multiple providers and models using createProviderRegistry.

import SwiftAISDK
import AnthropicProvider
import OpenAIProvider
let registry = createProviderRegistry(
providers: [
// Register provider with prefix:
"anthropic": anthropic,
// Register provider with custom configuration:
"openai": try createOpenAI(
settings: OpenAIProviderSettings(
apiKey: ProcessInfo.processInfo.environment["OPENAI_API_KEY"]
)
)
]
)

By default, the registry uses : as the separator between provider and model IDs. You can customize this separator:

import SwiftAISDK
import AnthropicProvider
import OpenAIProvider
let customSeparatorRegistry = createProviderRegistry(
providers: [
"anthropic": anthropic,
"openai": openai
],
options: ProviderRegistryOptions(separator: " > ")
)

You can access language models by using the languageModel method on the registry. The provider id will become the prefix of the model id: providerId:modelId.

import SwiftAISDK
let result = try await generateText(
model: try registry.languageModel(id: "openai:gpt-4o"), // default separator
// or with custom separator:
// model: try customSeparatorRegistry.languageModel(id: "openai > gpt-4o"),
prompt: "Invent a new holiday and describe its traditions."
)

You can access text embedding models by using the textEmbeddingModel method on the registry. The provider id will become the prefix of the model id: providerId:modelId.

import SwiftAISDK
let result = try await embed(
model: try registry.textEmbeddingModel(id: "openai:text-embedding-3-small"),
value: "sunny day at the beach"
)

You can access image models by using the imageModel method on the registry. The provider id will become the prefix of the model id: providerId:modelId.

import SwiftAISDK
let result = try await generateImage(
model: try registry.imageModel(id: "openai:dall-e-3"),
prompt: "A beautiful sunset over a calm ocean"
)

Combining Custom Providers, Provider Registry, and Middleware

Section titled “Combining Custom Providers, Provider Registry, and Middleware”

The central idea of provider management is to set up a file that contains all the providers and models you want to use. You may want to pre-configure model settings, provide model name aliases, limit the available models, and more.

Here is an example that implements the following concepts:

  • Pass through a full provider with a namespace prefix (here: xai > *)
  • Setup model name aliases (here: anthropic > fast, anthropic > writing, anthropic > reasoning)
  • Pre-configure model settings (here: anthropic > reasoning)
  • Use a fallback provider (here: anthropic > *)
  • Limit a provider to certain models without a fallback (here: groq > gemma2-9b-it, groq > qwen-qwq-32b)
  • Define a custom separator for the provider registry (here: >)
import SwiftAISDK
import AnthropicProvider
import XAIProvider
import GroqProvider
let registry = createProviderRegistry(
providers: [
// Pass through a full provider with a namespace prefix
"xai": asProviderV4(xai),
// Setup model name aliases
"anthropic": customProviderV4(
languageModels: [
"fast": try anthropic.languageModel(modelId: "claude-haiku-4-5"),
// Simple model
"writing": try anthropic.languageModel(modelId: "claude-sonnet-5"),
// Extended reasoning model configuration:
"reasoning": wrapLanguageModel(
model: try anthropic.languageModel(modelId: "claude-opus-4-8"),
middleware: LanguageModelV4MiddlewareInput.single(defaultSettingsMiddleware(
settings: DefaultSettings(
maxOutputTokens: 100000,
providerOptions: ["anthropic": [
"thinking": [
"type": "adaptive",
"display": "summarized"
],
"effort": "max"
]]
)
))
)
],
fallbackProvider: anthropic
),
// Limit a provider to certain models without a fallback
"groq": customProviderV4(
legacyLanguageModels: [
"gemma2-9b-it": try groq.languageModel(modelId: "gemma2-9b-it"),
"qwen-qwq-32b": try groq.languageModel(modelId: "qwen-qwq-32b")
]
)
],
options: ProviderRegistryOptions(separator: " > ")
)
// Usage:
let model = try registry.languageModel(id: "anthropic > reasoning")

You can apply middleware to all language models accessed through the registry:

import SwiftAISDK
import OpenAIProvider
let registry = createProviderRegistry(
providers: [
"openai": openai
],
options: ProviderRegistryOptions(
languageModelMiddleware: .single(
extractReasoningMiddleware(
options: ExtractReasoningOptions(tagName: "think")
)
)
)
)
// All language models from this registry will have reasoning extraction enabled
let result = try await generateText(
model: try registry.languageModel(id: "openai:gpt-4o"),
prompt: "Think step by step and wrap reasoning in <think> tags"
)
  1. Create a central registry file - Define all providers and models in one place (e.g., Registry.swift)
  2. Use aliases for versioning - Map semantic names to specific model versions for easy updates
  3. Combine with middleware - Pre-configure models with default settings or behavior modifications
  4. Limit model access - Use custom providers without fallbacks to restrict available models
  5. Use custom separators - Choose separators that match your naming conventions (:, >, /, etc.)