在构建 AI 应用时,我们经常面临一个痛点:如何在代码中优雅地管理多个模型供应商?
特别是当你需要同时使用 OpenAI、Anthropic,甚至还需要接入国内的 Qwen(通义千问)或 DeepSeek 时,代码往往会充斥着各种 import 和分散的配置对象。
Vercel AI SDK Core 提供了一套强大的 Provider Management(供应商管理) 机制,让你通过统一的注册表和简单的字符串 ID 来管理所有模型。
本文将带你深入了解如何使用 customProvider(自定义供应商)和 Provider Registry(供应商注册表)来标准化你的 AI 基础设施。
1. 核心概念:为什么需要它?
在没有管理机制时,切换模型通常意味着修改导入语句和配置参数。而使用 Provider Management 后,你可以实现:
- 统一入口:在一个文件中配置所有模型。
- 别名系统:用
my-gpt代替gpt-4-turbo-2024-04-09,方便日后升级。 - 预设配置:强制某个模型始终开启 "思维链" 或设置特定的
reasoningEffort。 - 混合使用:通过 ID(如
openai:gpt-4或qwen:turbo)无缝切换供应商。
2. 自定义供应商 (Custom Providers)
customProvider 允许你创建一个“虚拟”的供应商,用来包装现有的模型,并预设规则。
场景 A:给模型起别名 (Model Aliasing)
通过别名,你可以将业务代码与具体模型版本解耦。
TypeScript
import { customProvider } from 'ai';
import { openai } from '@ai-sdk/openai';
// 创建一个名为 'my-company' 的自定义供应商
export const myCompany = customProvider({
languageModels: {
// 业务代码中只需引用 'writer',底层可以是任何模型
writer: openai('gpt-4o'),
// 业务代码中引用 'fast',底层是 mini 模型
fast: openai('gpt-4o-mini'),
},
// 设置回退供应商(可选):如果请求的模型 ID 不在上面列表中,尝试从这里加载
fallbackProvider: openai,
});
场景 B:预设模型参数 (Middleware Integration)
这是最强大的功能之一。你可以使用 wrapLanguageModel 和中间件来强制应用某些设置(例如 API 调用时的特殊 Header 或推理强度)。
TypeScript
import { customProvider, wrapLanguageModel, defaultSettingsMiddleware } from 'ai';
import { openai } from '@ai-sdk/openai';
export const structuredOpenAI = customProvider({
languageModels: {
// 创建一个名为 'reasoning-high' 的模型 ID
'reasoning-high': wrapLanguageModel({
model: openai('o1'), // 底层模型
middleware: defaultSettingsMiddleware({
settings: {
// 强制设置推理强度为 high
providerOptions: {
openai: { reasoningEffort: 'high' },
},
},
}),
}),
},
});
场景 C:限制可用模型 (Allowlist)
如果你不希望开发者随意调用昂贵的模型,可以创建一个不包含 fallbackProvider 的自定义供应商,只暴露允许的模型。
TypeScript
export const restrictedProvider = customProvider({
languageModels: {
'cheap-model': openai('gpt-4o-mini'),
},
// 不设置 fallbackProvider,这样调用 'restricted-provider:gpt-4' 将会报错
});
3. 供应商注册表 (Provider Registry)
createProviderRegistry 是将多个供应商(包括官方的和自定义的)组合在一起的终极方案。它允许你通过字符串 ID(如 provider:model)来调用模型。
基础配置
创建一个 registry.ts 文件:
TypeScript
// registry.ts
import { createProviderRegistry } from 'ai';
import { openai } from '@ai-sdk/openai';
import { anthropic } from '@ai-sdk/anthropic';
export const registry = createProviderRegistry({
// 注册官方供应商
openai,
anthropic,
// 你也可以在这里注册上面的 customProvider
// 'my-company': myCompany
});
在业务中使用
配置好注册表后,你在调用 generateText 或 streamText 时,不再需要导入具体的模型对象,直接使用注册表生成的模型实例即可。
TypeScript
import { generateText } from 'ai';
import { registry } from './registry';
async function main() {
const { text } = await generateText({
// 语法:registry.languageModel('供应商ID:模型ID')
model: registry.languageModel('openai:gpt-4o'),
prompt: '为我写一个关于 Rust 语言的笑话。',
});
console.log(text);
}
4. 实战:整合国内模型 (OpenAI 兼容协议)
国内开发者经常需要使用 DeepSeek、通义千问 (Qwen) 或 Moonshot。由于 Vercel AI SDK 提供了 createOpenAICompatible,我们可以轻松将它们加入注册表。
这是一个包含国内模型 + 官方模型 + 别名配置的完整 registry.ts 示例:
TypeScript
// registry.ts
import { createProviderRegistry, customProvider } from 'ai';
import { createOpenAICompatible } from '@ai-sdk/openai-compatible';
import { openai } from '@ai-sdk/openai';
// 1. 定义兼容 OpenAI 协议的国内供应商(以 DeepSeek 为例)
const deepseek = createOpenAICompatible({
name: 'deepseek',
baseURL: 'https://api.deepseek.com', // 替换为实际的 Base URL
apiKey: process.env.DEEPSEEK_API_KEY,
});
// 2. 定义自定义业务供应商(设置别名)
const myApp = customProvider({
languageModels: {
// 定义 'smart' 指向 GPT-4o
smart: openai('gpt-4o'),
// 定义 'local' 指向 DeepSeek V3
local: deepseek('deepseek-chat'),
},
});
// 3. 创建注册表
export const registry = createProviderRegistry({
// 注册标准供应商
openai,
// 注册国内供应商
deepseek,
// 注册业务自定义供应商
myapp: myApp,
});
使用方式:
TypeScript
// 调用 DeepSeek
registry.languageModel('deepseek:deepseek-coder');
// 调用我们定义的别名 (myapp:smart -> openai:gpt-4o)
registry.languageModel('myapp:smart');
5. 高级技巧:自定义分隔符
默认情况下,注册表使用冒号 : 作为分隔符(例如 openai:gpt-4)。如果你不喜欢这个风格,或者你的模型 ID 本身包含冒号,你可以自定义分隔符。
TypeScript
export const registry = createProviderRegistry(
{ openai, anthropic },
{ separator: ' > ' } // 使用 " > " 作为分隔符
);
// 调用方式变为:
registry.languageModel('openai > gpt-4o');
总结
Vercel AI SDK 的 Provider Management 是构建生产级 AI 应用的基石。
- 保持代码整洁:业务逻辑不再依赖具体的 SDK 导入。
- 灵活切换:通过修改
registry.ts即可全局替换底层模型。 - 精细控制:利用 Middleware 和 Custom Provider 锁定模型参数,防止 Token 滥用。
建议尽早在你的 Next.js 或 Node.js 项目中引入 registry.ts 模式,这将为你未来的模型迭代节省大量重构时间。