Skip to content

第 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):

ts
import { generateText } from 'ai';

const { text } = await generateText({
  model: 'openai/gpt-5',
  prompt: 'Hello world',
});

用法二:从 ai 包导入默认实例 gateway(v5.0.36+):

ts
import { generateText, gateway } from 'ai';

const { text } = await generateText({
  model: gateway('openai/gpt-5'),
  prompt: 'Hello world',
});

用法三:createGateway 创建自定义实例(需要自定义配置时):

ts
import { createGateway } from 'ai';

const gateway = createGateway({
  apiKey: process.env.AI_GATEWAY_API_KEY ?? '',
});

何时需要自定义实例:设置自定义 API key / Vercel access token / baseURL / headers;在 provider registry 中使用;用 middleware 包装;或为应用不同部分使用不同设置。

可选配置项:

配置说明
baseURLAPI 调用前缀,默认 https://ai-gateway.vercel.sh/v4/ai
apiKey认证密钥,默认读 AI_GATEWAY_API_KEY 环境变量
teamIdOrSlug多团队 Vercel access token 场景下限定请求范围
headers自定义请求头
fetch自定义 fetch 实现(可用于拦截或测试)

3.3 认证方式

API Key 认证——环境变量方式(推荐):

bash
AI_GATEWAY_API_KEY=your_api_key_here

或直接传入 provider。

Vercel Access Token 认证——用于模型请求的动态运行时认证:

ts
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

ts
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:

ts
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):

ts
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 即严格白名单):

ts
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 访问所有模型:

ts
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',
  }),
});

默认以 : 作为分隔符,也可自定义:

ts
export const customSeparatorRegistry = createProviderRegistry(
  {
    gateway,
  },
  { separator: ' > ' },
);

通过 languageModel 方法按 providerId:modelId 格式访问语言模型:

ts
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 与图像模型各有对应方法:

ts
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',
});
ts
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 兼容组合):

ts
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 > fastsmart > writingsmart > reasoning);
  • 预配置模型设置(smart > reasoning);
  • fallback provider(smart > *);
  • 无 fallback 的严格白名单 provider。

全局 Provider

AI SDK 还支持全局 provider 特性——直接用纯字符串指定模型:

ts
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;也可在启动时替换:

ts
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 ?? '',
});
ts
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 白名单限制;
  • createProviderRegistryproviderId:modelId 字符串统一调度多 provider,配合 languageModel/embeddingModel/imageModel 方法使用。

🧪 随堂测验

点击你认为正确的选项。答错时会展示正确答案与原因解析。

1. 当同时存在 apiKey、AI_GATEWAY_API_KEY 环境变量和 OIDC 时,Gateway 认证的优先级是?

2. 接入任意 OpenAI 兼容服务端应使用哪个包的哪个函数?

3. customProvider 不设置 fallbackProvider 意味着什么?

4. 关于 Provider Registry,以下说法错误的是?

🛠️ 动手实践

  1. 写一个 provider.ts,导出两个函数 getModel(mode: 'gateway' | 'custom'),分别返回 Gateway 与 OpenAI 兼容实例构造的同能力 model,验证互换性。
  2. 基于 customProvider 为你的团队设计一套语义别名体系(如 chat-fastchat-smartembed-base),并说明升级模型时只需改动哪里。
  3. createProviderRegistry 同时注册 Gateway 和一个自定义 provider,分别用 languageModel('gateway:...')languageModel('custom:...') 各调用一次并对比响应。