第 3 章 · Provider 管理:AI Gateway 与自定义 Provider
本章目标:
- 掌握 Vercel AI Gateway 的三种认证方式与 provider 实例配置
- 学会用
createOpenAICompatible接入任意 OpenAI 兼容服务端- 使用
customProvider实现模型别名、预设设置与可用模型限制- 用
createProviderRegistry集中管理多 provider,通过字符串 ID 访问模型
3.1 AI Gateway:一个接口访问所有模型
AI Gateway 通过单一接口连接多家 AI provider 的模型。无需分别集成各家 SDK,即可访问 OpenAI、Anthropic、Google、Meta、xAI 等 provider 及其模型。
核心特性:
- 无需安装额外的 provider 模块/依赖即可访问多 provider 模型;
- 不同 AI provider 之间代码结构完全一致;
- 轻松切换模型与 provider;
- 部署到 Vercel 时自动认证;
- 在 Vercel 控制台查看跨 provider 定价与可观测性数据。
3.2 三种基本用法
用法一:直接传模型字符串(全局 provider 默认即 Gateway):
import { generateText } from 'ai';
const { text } = await generateText({
model: 'openai/gpt-5',
prompt: 'Hello world',
});用法二:从 ai 包导入默认实例 gateway(v5.0.36+):
import { generateText, gateway } from 'ai';
const { text } = await generateText({
model: gateway('openai/gpt-5'),
prompt: 'Hello world',
});用法三:createGateway 创建自定义实例(需要自定义配置时):
import { createGateway } from 'ai';
const gateway = createGateway({
apiKey: process.env.AI_GATEWAY_API_KEY ?? '',
});何时需要自定义实例:设置自定义 API key / Vercel access token / baseURL / headers;在 provider registry 中使用;用 middleware 包装;或为应用不同部分使用不同设置。
可选配置项:
| 配置 | 说明 |
|---|---|
baseURL | API 调用前缀,默认 https://ai-gateway.vercel.sh/v4/ai |
apiKey | 认证密钥,默认读 AI_GATEWAY_API_KEY 环境变量 |
teamIdOrSlug | 多团队 Vercel access token 场景下限定请求范围 |
headers | 自定义请求头 |
fetch | 自定义 fetch 实现(可用于拦截或测试) |
3.3 认证方式
API Key 认证——环境变量方式(推荐):
AI_GATEWAY_API_KEY=your_api_key_here或直接传入 provider。
Vercel Access Token 认证——用于模型请求的动态运行时认证:
import { createGateway } from 'ai';
const gateway = createGateway({
apiKey: 'your_vercel_access_token_here',
teamIdOrSlug: 'your-team', // 多团队 token 必填
});OIDC 认证——部署到 Vercel 后可凭 OIDC token 免 API Key 认证:生产/预览部署自动处理;本地开发用 vercel dev 自动刷新(token 12 小时过期)。若存在 API key 或 access token,则始终优先于 OIDC。
3.4 自定义 OpenAI 兼容 Provider
不经过 Gateway、直连任何 OpenAI 兼容服务端时,使用 @ai-sdk/openai-compatible 包的 createOpenAICompatible:
import { createOpenAICompatible } from '@ai-sdk/openai-compatible';
import { streamText } from 'ai';
const myProvider = createOpenAICompatible({
name: 'my-provider', // 用于错误信息与遥测的提供商标识
baseURL: process.env.OPENAI_COMPATIBLE_BASE_URL ?? '', // 如 https://api.custom.com/v1
apiKey: process.env.OPENAI_COMPATIBLE_API_KEY ?? '',
});
const result = streamText({
model: myProvider('gpt-4o-mini'), // 模型名按你的服务端实际填写
prompt: 'Invent a new holiday and describe its traditions.',
});💡 Gateway 与自定义 provider 产出的 model 对象完全可互换。本课程所有章节示例都遵循这一约定,两种写法任选其一即可运行。
3.5 Custom Provider:别名、预设与限制
当你需要在多处复用同一批模型时,可以用 customProvider 创建带语义别名的 provider:
import { customProvider, gateway } from 'ai';
// custom provider with alias names:
export const anthropic = customProvider({
languageModels: {
opus: gateway('anthropic/claude-opus-4.1'),
sonnet: gateway('anthropic/claude-sonnet-4.5'),
haiku: gateway('anthropic/claude-haiku-4.5'),
},
fallbackProvider: gateway,
});之后就能用 anthropic('sonnet') 调用——将来升级模型版本只需改这一处。
也可以预设模型参数(借助 wrapLanguageModel + defaultSettingsMiddleware):
import {
gateway,
customProvider,
defaultSettingsMiddleware,
wrapLanguageModel,
} from 'ai';
export const openai = customProvider({
languageModels: {
// replacement model with custom provider options:
'gpt-5.1': wrapLanguageModel({
model: gateway('openai/gpt-5.1'),
middleware: defaultSettingsMiddleware({
settings: {
providerOptions: {
openai: {
reasoningEffort: 'high',
},
},
},
}),
}),
},
fallbackProvider: gateway,
});还可以限制系统内可用的模型集合(不设 fallback 即严格白名单):
import {
customProvider,
defaultSettingsMiddleware,
wrapLanguageModel,
gateway,
} from 'ai';
export const myProvider = customProvider({
languageModels: {
'text-medium': gateway('anthropic/claude-3-5-sonnet-20240620'),
'text-small': gateway('openai/gpt-5-mini'),
'reasoning-medium': wrapLanguageModel({
model: gateway('openai/gpt-5.1'),
middleware: defaultSettingsMiddleware({
settings: {
providerOptions: {
openai: {
reasoningEffort: 'high',
},
},
},
}),
}),
'reasoning-fast': wrapLanguageModel({
model: gateway('openai/gpt-5.1'),
middleware: defaultSettingsMiddleware({
settings: {
providerOptions: {
openai: {
reasoningEffort: 'low',
},
},
},
}),
}),
},
embeddingModels: {
embedding: gateway.embeddingModel('openai/text-embedding-3-small'),
},
// no fallback provider —— 未列出的模型一律不可用
});3.6 Provider Registry:集中式模型注册表
createProviderRegistry 把多个 provider 聚合到一个注册表,用简单字符串 ID 访问所有模型:
import { createProviderRegistry, gateway } from 'ai';
import { createOpenAICompatible } from '@ai-sdk/openai-compatible';
export const registry = createProviderRegistry({
// register provider with prefix and default setup using gateway:
gateway,
// register an OpenAI-compatible provider with custom setup:
custom: createOpenAICompatible({
name: 'provider-name',
apiKey: process.env.CUSTOM_API_KEY,
baseURL: 'https://api.custom.com/v1',
}),
});默认以 : 作为分隔符,也可自定义:
export const customSeparatorRegistry = createProviderRegistry(
{
gateway,
},
{ separator: ' > ' },
);通过 languageModel 方法按 providerId:modelId 格式访问语言模型:
import { generateText } from 'ai';
import { registry } from './registry';
const { text } = await generateText({
model: registry.languageModel('gateway:openai/gpt-5.1'), // default separator
prompt: 'Invent a new holiday and describe its traditions.',
});Embedding 与图像模型各有对应方法:
import { embed } from 'ai';
import { registry } from './registry';
const { embedding } = await embed({
model: registry.embeddingModel('custom:text-embedding-3-small'),
value: 'sunny day at the beach',
});import { generateImage } from 'ai';
import { registry } from './registry';
const { image } = await generateImage({
model: registry.imageModel('custom:image-gen-v1'),
prompt: 'A beautiful sunset over a calm ocean',
});3.7 综合实战:一个文件管理全部模型
Provider 管理的核心思想是:用一个文件集中声明所有 provider 与模型——预设设置、定义别名、限制范围。下面是官方综合示例(改写为 Gateway + OpenAI 兼容组合):
import { createOpenAICompatible } from '@ai-sdk/openai-compatible';
import {
createProviderRegistry,
customProvider,
defaultSettingsMiddleware,
gateway,
wrapLanguageModel,
} from 'ai';
export const registry = createProviderRegistry(
{
// pass through gateway with a namespace prefix
gateway,
// access an OpenAI-compatible provider with custom setup
custom: createOpenAICompatible({
name: 'provider-name',
apiKey: process.env.CUSTOM_API_KEY,
baseURL: 'https://api.custom.com/v1',
}),
// setup model name aliases + pre-configured settings
smart: customProvider({
languageModels: {
fast: gateway('openai/gpt-5-mini'),
writing: gateway('anthropic/claude-sonnet-4.5'),
reasoning: wrapLanguageModel({
model: gateway('anthropic/claude-sonnet-4.5'),
middleware: defaultSettingsMiddleware({
settings: {
maxOutputTokens: 100000, // example default setting
},
}),
}),
},
fallbackProvider: gateway,
}),
},
{ separator: ' > ' },
);
// usage:
const model = registry.languageModel('smart > reasoning');这个模式实现了:
- 带命名空间前缀透传 Gateway(
gateway > *); - 自定义 API key/baseURL 的 OpenAI 兼容 provider(
custom > *); - 模型名别名(
smart > fast、smart > writing、smart > reasoning); - 预配置模型设置(
smart > reasoning); - fallback provider(
smart > *); - 无 fallback 的严格白名单 provider。
全局 Provider
AI SDK 还支持全局 provider 特性——直接用纯字符串指定模型:
import { streamText } from 'ai';
const result = await streamText({
model: 'openai/gpt-5.1', // Uses the global provider (defaults to gateway)
prompt: 'Invent a new holiday and describe its traditions.',
});默认全局 provider 是 Vercel AI Gateway;也可在启动时替换:
import { createOpenAICompatible } from '@ai-sdk/openai-compatible';
globalThis.AI_SDK_DEFAULT_PROVIDER = createOpenAICompatible({
name: 'my-provider',
baseURL: process.env.OPENAI_COMPATIBLE_BASE_URL ?? '',
apiKey: process.env.OPENAI_COMPATIBLE_API_KEY ?? '',
});import { streamText } from 'ai';
const result = await streamText({
model: 'my-model', // Uses your custom global provider without prefix
prompt: 'Invent a new holiday and describe its traditions.',
});这简化了 provider 的使用,让你在不修改业务代码中模型引用的前提下切换 provider。
本章小结
- AI Gateway 有三种用法:纯模型字符串、
gateway默认实例、createGateway自定义实例; - 认证优先级:显式传入 key >
AI_GATEWAY_API_KEY环境变量 > OIDC; createOpenAICompatible是接入任意自建/OpenAI 兼容服务端的通用钥匙;customProvider提供三大能力:模型别名、defaultSettingsMiddleware预设、无 fallback 白名单限制;createProviderRegistry以providerId:modelId字符串统一调度多 provider,配合languageModel/embeddingModel/imageModel方法使用。
🧪 随堂测验
点击你认为正确的选项。答错时会展示正确答案与原因解析。
1. 当同时存在 apiKey、AI_GATEWAY_API_KEY 环境变量和 OIDC 时,Gateway 认证的优先级是?
2. 接入任意 OpenAI 兼容服务端应使用哪个包的哪个函数?
3. customProvider 不设置 fallbackProvider 意味着什么?
4. 关于 Provider Registry,以下说法错误的是?
🛠️ 动手实践
- 写一个
provider.ts,导出两个函数getModel(mode: 'gateway' | 'custom'),分别返回 Gateway 与 OpenAI 兼容实例构造的同能力 model,验证互换性。 - 基于
customProvider为你的团队设计一套语义别名体系(如chat-fast、chat-smart、embed-base),并说明升级模型时只需改动哪里。 - 用
createProviderRegistry同时注册 Gateway 和一个自定义 provider,分别用languageModel('gateway:...')与languageModel('custom:...')各调用一次并对比响应。