add-provider-package
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseAdding a New Provider Package
添加新的提供商包
This guide covers the process of creating a new package to integrate an AI service into the AI SDK.
@ai-sdk/<provider>本指南介绍了创建新的包以将AI服务集成到AI SDK中的完整流程。
@ai-sdk/<provider>First-Party vs Third-Party Providers
官方提供商与第三方提供商
- Third-party packages: Any provider can create a third-party package. We're happy to link to it from our documentation.
- First-party packages: If you prefer a first-party package, please create an issue first to discuss.
@ai-sdk/<provider>
- 第三方包:任何提供商都可以创建第三方包。我们会很乐意在文档中添加相关链接。
- 官方包:如果你希望创建官方包,请先创建一个issue进行讨论。
@ai-sdk/<provider>
Reference Example
参考示例
See https://github.com/vercel/ai/pull/8136/files for a complete example of adding a new provider.
Provider Architecture
提供商架构
The AI SDK uses a layered provider architecture following the adapter pattern:
- Specifications (): Defines interfaces like
@ai-sdk/provider,LanguageModelV3, etc.EmbeddingModelV3 - Utilities (): Shared code for implementing providers
@ai-sdk/provider-utils - Providers (): Concrete implementations for each AI service
@ai-sdk/<provider> - Core (): High-level functions like
ai,generateText,streamTextgenerateObject
AI SDK采用遵循适配器模式的分层提供商架构:
- 规范层 ():定义
@ai-sdk/provider、LanguageModelV3等接口。EmbeddingModelV3 - 工具层 ():用于实现提供商的共享代码
@ai-sdk/provider-utils - 提供商层 ():每个AI服务的具体实现
@ai-sdk/<provider> - 核心层 ():高级函数,如
ai、generateText、streamTextgenerateObject
Step-by-Step Guide
分步指南
1. Create Package Structure
1. 创建包结构
Create a new folder with the following structure:
packages/<provider>packages/<provider>/
├── src/
│ ├── index.ts # Main exports
│ ├── version.ts # Package version
│ ├── <provider>-provider.ts # Provider implementation
│ ├── <provider>-provider.test.ts
│ ├── <provider>-*-options.ts # Model-specific options
│ └── <provider>-*-model.ts # Model implementations (e.g., language, embedding, image)
├── package.json
├── tsconfig.json
├── tsconfig.build.json
├── tsup.config.ts
├── turbo.json
├── vitest.node.config.js
├── vitest.edge.config.js
└── README.mdDo not create a file. It will be auto-generated.
CHANGELOG.md在路径下创建新文件夹,结构如下:
packages/<provider>packages/<provider>/
├── src/
│ ├── index.ts # 主导出文件
│ ├── version.ts # 包版本文件
│ ├── <provider>-provider.ts # 提供商实现文件
│ ├── <provider>-provider.test.ts
│ ├── <provider>-*-options.ts # 模型专属配置选项
│ └── <provider>-*-model.ts # 模型实现(例如:语言模型、嵌入模型、图像模型)
├── package.json
├── tsconfig.json
├── tsconfig.build.json
├── tsup.config.ts
├── turbo.json
├── vitest.node.config.js
├── vitest.edge.config.js
└── README.md无需创建文件,它会自动生成。
CHANGELOG.md2. Configure package.json
2. 配置package.json
Set up your with:
package.json"name": "@ai-sdk/<provider>"- (initial version, will be updated by changeset)
"version": "0.0.0" "license": "Apache-2.0""sideEffects": false- Dependencies on and
@ai-sdk/provider(use@ai-sdk/provider-utils)workspace:* - Dev dependencies: ,
@ai-sdk/test-server,@types/node,@vercel/ai-tsconfig,tsup,typescriptzod "engines": { "node": ">=18" }- Peer dependency on (both v3 and v4):
zod"zod": "^3.25.76 || ^4.1.8"
Example exports configuration:
json
{
"exports": {
"./package.json": "./package.json",
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.mjs",
"require": "./dist/index.js"
}
}
}按以下要求设置:
package.json"name": "@ai-sdk/<provider>"- (初始版本,后续会由changeset更新)
"version": "0.0.0" "license": "Apache-2.0""sideEffects": false- 依赖和
@ai-sdk/provider(使用@ai-sdk/provider-utils)workspace:* - 开发依赖:,
@ai-sdk/test-server,@types/node,@vercel/ai-tsconfig,tsup,typescriptzod "engines": { "node": ">=18" }- 对等依赖(支持v3和v4版本):
zod"zod": "^3.25.76 || ^4.1.8"
导出配置示例:
json
{
"exports": {
"./package.json": "./package.json",
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.mjs",
"require": "./dist/index.js"
}
}
}3. Create TypeScript Configurations
3. 创建TypeScript配置
tsconfig.json:
json
{
"extends": "@vercel/ai-tsconfig/base.json",
"include": ["src/**/*.ts"],
"exclude": ["node_modules", "dist"]
}tsconfig.build.json:
json
{
"extends": "./tsconfig.json",
"exclude": [
"**/*.test.ts",
"**/*.test-d.ts",
"**/__snapshots__",
"**/__fixtures__"
]
}tsconfig.json:
json
{
"extends": "@vercel/ai-tsconfig/base.json",
"include": ["src/**/*.ts"],
"exclude": ["node_modules", "dist"]
}tsconfig.build.json:
json
{
"extends": "./tsconfig.json",
"exclude": [
"**/*.test.ts",
"**/*.test-d.ts",
"**/__snapshots__",
"**/__fixtures__"
]
}4. Configure Build Tool (tsup)
4. 配置构建工具(tsup)
Create :
tsup.config.tstypescript
import { defineConfig } from 'tsup';
export default defineConfig({
entry: ['src/index.ts'],
format: ['cjs', 'esm'],
dts: true,
sourcemap: true,
clean: true,
});创建:
tsup.config.tstypescript
import { defineConfig } from 'tsup';
export default defineConfig({
entry: ['src/index.ts'],
format: ['cjs', 'esm'],
dts: true,
sourcemap: true,
clean: true,
});5. Configure Test Runners
5. 配置测试运行器
Create both and (copy from existing provider like ).
vitest.node.config.jsvitest.edge.config.jsanthropic创建和(可复制现有提供商如的配置)。
vitest.node.config.jsvitest.edge.config.jsanthropic6. Implement Provider
6. 实现提供商
Provider implementation pattern:
typescript
// <provider>-provider.ts
import { NoSuchModelError } from '@ai-sdk/provider';
import { loadApiKey } from '@ai-sdk/provider-utils';
export interface ProviderSettings {
apiKey?: string;
baseURL?: string;
// provider-specific settings
}
export class ProviderInstance {
readonly apiKey?: string;
readonly baseURL?: string;
constructor(options: ProviderSettings = {}) {
this.apiKey = options.apiKey;
this.baseURL = options.baseURL;
}
private get baseConfig() {
return {
apiKey: () =>
loadApiKey({
apiKey: this.apiKey,
environmentVariableName: 'PROVIDER_API_KEY',
description: 'Provider API key',
}),
baseURL: this.baseURL ?? 'https://api.provider.com',
};
}
languageModel(modelId: string) {
return new ProviderLanguageModel(modelId, this.baseConfig);
}
// Shorter alias
chat(modelId: string) {
return this.languageModel(modelId);
}
}
// Export default instance
export const providerName = new ProviderInstance();提供商实现模式:
typescript
// <provider>-provider.ts
import { NoSuchModelError } from '@ai-sdk/provider';
import { loadApiKey } from '@ai-sdk/provider-utils';
export interface ProviderSettings {
apiKey?: string;
baseURL?: string;
// 提供商专属配置
}
export class ProviderInstance {
readonly apiKey?: string;
readonly baseURL?: string;
constructor(options: ProviderSettings = {}) {
this.apiKey = options.apiKey;
this.baseURL = options.baseURL;
}
private get baseConfig() {
return {
apiKey: () =>
loadApiKey({
apiKey: this.apiKey,
environmentVariableName: 'PROVIDER_API_KEY',
description: 'Provider API key',
}),
baseURL: this.baseURL ?? 'https://api.provider.com',
};
}
languageModel(modelId: string) {
return new ProviderLanguageModel(modelId, this.baseConfig);
}
// 简写别名
chat(modelId: string) {
return this.languageModel(modelId);
}
}
// 导出默认实例
export const providerName = new ProviderInstance();7. Implement Model Classes
7. 实现模型类
Each model type (language, embedding, image, etc.) should implement the appropriate interface from :
@ai-sdk/provider- for text generation models
LanguageModelV3 - for embedding models
EmbeddingModelV3 - for image generation models
ImageModelV1 - etc.
Schema guidelines:
Provider Options (user-facing):
- Use unless
.optional()is meaningfulnull - Be as restrictive as possible for future flexibility
Response Schemas (API responses):
- Use instead of
.nullish().optional() - Keep minimal - only include properties you need
- Allow flexibility for provider API changes
每种模型类型(语言、嵌入、图像等)都应实现中的对应接口:
@ai-sdk/provider- 文本生成模型实现
LanguageModelV3 - 嵌入模型实现
EmbeddingModelV3 - 图像生成模型实现
ImageModelV1 - 其他模型类型依此类推
Schema规范:
提供商配置选项(面向用户):
- 除非有特定含义,否则使用
null.optional() - 为了未来的灵活性,尽可能设置严格的限制
响应Schema(API响应):
- 使用而非
.nullish().optional() - 保持精简 - 仅包含需要的属性
- 为提供商API的变更预留灵活性
8. Create README.md
8. 创建README.md
Include:
- Brief description linking to documentation
- Installation instructions
- Basic usage example
- Link to full documentation
应包含:
- 简短描述并链接至文档
- 安装说明
- 基础使用示例
- 完整文档链接
9. Write Tests
9. 编写测试
- Unit tests for provider logic
- API response parsing tests using fixtures in subdirectory
__fixtures__ - Both Node.js and Edge runtime tests
See skill for capturing real API responses for testing.
capture-api-response-test-fixture- 提供商逻辑的单元测试
- 使用子目录中的测试数据进行API响应解析测试
__fixtures__ - 同时包含Node.js和Edge运行时测试
可参考工具来捕获真实API响应用于测试。
capture-api-response-test-fixture10. Add Examples
10. 添加示例
Create examples in for each model type the provider supports:
examples/ai-functions/src/- - Basic text generation
generate-text/<provider>.ts - - Streaming text
stream-text/<provider>.ts - - Structured output (if supported)
generate-object/<provider>.ts - - Streaming structured output (if supported)
stream-object/<provider>.ts - - Embeddings (if supported)
embed/<provider>.ts - - Image generation (if supported)
generate-image/<provider>.ts - etc.
Add feature-specific examples as needed (e.g., , ).
<provider>-tool-call.ts<provider>-cache-control.ts在中为提供商支持的每种模型类型创建示例:
examples/ai-functions/src/- - 基础文本生成
generate-text/<provider>.ts - - 流式文本生成
stream-text/<provider>.ts - - 结构化输出(如果支持)
generate-object/<provider>.ts - - 流式结构化输出(如果支持)
stream-object/<provider>.ts - - 嵌入模型(如果支持)
embed/<provider>.ts - - 图像生成(如果支持)
generate-image/<provider>.ts - 其他类型依此类推
根据需要添加特定功能的示例(例如:, )。
<provider>-tool-call.ts<provider>-cache-control.ts11. Add Documentation
11. 添加文档
Create documentation in
content/providers/01-ai-sdk-providers/<last number + 10>-<provider>.mdxInclude:
- Setup instructions
- Available models
- Model capabilities
- Provider-specific options
- Usage examples
- API configuration
在路径下创建文档:
content/providers/01-ai-sdk-providers/<last number + 10>-<provider>.mdx应包含:
- 配置说明
- 可用模型列表
- 模型能力介绍
- 提供商专属配置选项
- 使用示例
- API配置说明
12. Create Changeset
12. 创建变更集
Run and:
pnpm changeset- Select the new provider package
- Choose version (for new packages starting at 0.0.0)
major - Describe what the package provides
运行并:
pnpm changeset- 选择新的提供商包
- 选择版本(对于初始版本为0.0.0的新包)
major - 描述该包提供的功能
13. Update References
13. 更新引用
Run from the workspace root to update tsconfig references.
pnpm update-references在工作区根目录运行以更新tsconfig引用。
pnpm update-references14. Build and Test
14. 构建与测试
bash
undefinedbash
undefinedFrom workspace root
从工作区根目录执行
pnpm build
pnpm build
From provider package
进入提供商包目录
cd packages/<provider>
pnpm test # Run all tests
pnpm test:node # Run Node.js tests
pnpm test:edge # Run Edge tests
pnpm type-check # Type checking
cd packages/<provider>
pnpm test # 运行所有测试
pnpm test:node # 运行Node.js测试
pnpm test:edge # 运行Edge测试
pnpm type-check # 类型检查
From workspace root
从工作区根目录执行
pnpm type-check:full # Full type check including examples
undefinedpnpm type-check:full # 完整类型检查,包含示例
undefined15. Run Examples
15. 运行示例
Test your examples:
bash
cd examples/ai-functions
pnpm tsx src/generate-text/<provider>.ts
pnpm tsx src/stream-text/<provider>.ts测试你的示例代码:
bash
cd examples/ai-functions
pnpm tsx src/generate-text/<provider>.ts
pnpm tsx src/stream-text/<provider>.tsProvider Method Naming
提供商方法命名规范
- Full names: ,
languageModel(id),imageModel(id)(required)embeddingModel(id) - Short aliases: ,
.chat(id),.image(id)(for DX).embedding(id)
- 完整名称:,
languageModel(id),imageModel(id)(必填)embeddingModel(id) - 简写别名:,
.chat(id),.image(id)(提升开发体验).embedding(id)
File Naming Conventions
文件命名规范
- Source files:
kebab-case.ts - Test files:
kebab-case.test.ts - Type test files:
kebab-case.test-d.ts - Provider classes: ,
<Provider>Provider, etc.<Provider>LanguageModel
- 源文件:
kebab-case.ts - 测试文件:
kebab-case.test.ts - 类型测试文件:
kebab-case.test-d.ts - 提供商类:,
<Provider>Provider等<Provider>LanguageModel
Security Best Practices
安全最佳实践
- Never use directly - use
JSON.parseorparseJSONfromsafeParseJSON@ai-sdk/provider-utils - Load API keys securely using from
loadApiKey@ai-sdk/provider-utils - Validate all API responses against schemas
- 切勿直接使用- 请使用
JSON.parse中的@ai-sdk/provider-utils或parseJSONsafeParseJSON - 使用中的
@ai-sdk/provider-utils安全加载API密钥loadApiKey - 验证所有API响应是否符合Schema
Error Handling
错误处理
Errors should extend from and use a marker pattern:
AISDKError@ai-sdk/providertypescript
import { AISDKError } from '@ai-sdk/provider';
const name = 'AI_ProviderError';
const marker = `vercel.ai.error.${name}`;
const symbol = Symbol.for(marker);
export class ProviderError extends AISDKError {
private readonly [symbol] = true;
constructor({ message, cause }: { message: string; cause?: unknown }) {
super({ name, message, cause });
}
static isInstance(error: unknown): error is ProviderError {
return AISDKError.hasMarker(error, marker);
}
}错误应继承自中的并使用标记模式:
@ai-sdk/providerAISDKErrortypescript
import { AISDKError } from '@ai-sdk/provider';
const name = 'AI_ProviderError';
const marker = `vercel.ai.error.${name}`;
const symbol = Symbol.for(marker);
export class ProviderError extends AISDKError {
private readonly [symbol] = true;
constructor({ message, cause }: { message: string; cause?: unknown }) {
super({ name, message, cause });
}
static isInstance(error: unknown): error is ProviderError {
return AISDKError.hasMarker(error, marker);
}
}Pre-release Mode
预发布模式
If is set up to publish releases, no further action is necessary. Just make sure not to backport it to the stable branch since it will result in an npm version conflict once we exit pre-release mode on .
mainbetavX.Ymain如果分支已配置为发布版本,则无需额外操作。只需注意不要将其回传到稳定分支,否则在分支退出预发布模式后会导致npm版本冲突。
mainbetavX.YmainChecklist
检查清单
- Package structure created in
packages/<provider> - configured with correct dependencies
package.json - TypeScript configs set up (,
tsconfig.json)tsconfig.build.json - Build configuration ()
tsup.config.ts - Test configurations (,
vitest.node.config.js)vitest.edge.config.js - Provider implementation complete
- Model classes implement appropriate interfaces
- Unit tests written and passing
- API response test fixtures captured
- Examples created in
examples/ai-functions/src/ - Documentation added in
content/providers/01-ai-sdk-providers/ - README.md written
- Major changeset created
- run
pnpm update-references - All tests passing (from package)
pnpm test - Type checking passing (from root)
pnpm type-check:full - Examples run successfully
- 在中创建了包结构
packages/<provider> - 正确配置了的依赖
package.json - 设置了TypeScript配置(,
tsconfig.json)tsconfig.build.json - 配置了构建工具()
tsup.config.ts - 配置了测试运行器(,
vitest.node.config.js)vitest.edge.config.js - 完成了提供商实现
- 模型类实现了对应的接口
- 编写并通过了单元测试
- 捕获了API响应测试数据
- 在中创建了示例
examples/ai-functions/src/ - 在中添加了文档
content/providers/01-ai-sdk-providers/ - 编写了README.md
- 创建了major版本的变更集
- 运行了
pnpm update-references - 所有测试通过(在包目录执行)
pnpm test - 类型检查通过(在根目录执行)
pnpm type-check:full - 示例运行成功
Common Issues
常见问题
- Missing tsconfig references: Run from workspace root
pnpm update-references - Type errors in examples: Run to catch issues early
pnpm type-check:full - Test failures: Ensure both Node and Edge tests pass
- Build errors: Check that is configured correctly
tsup.config.ts
- 缺少tsconfig引用:在工作区根目录运行
pnpm update-references - 示例中出现类型错误:运行提前发现问题
pnpm type-check:full - 测试失败:确保Node.js和Edge运行时的测试都通过
- 构建错误:检查的配置是否正确
tsup.config.ts
Related Documentation
相关文档
- Provider Architecture
- Provider Development Notes
- Develop AI Functions Example
- Capture API Response Test Fixture
- 提供商架构
- 提供商开发说明
- 开发AI函数示例
- 捕获API响应测试数据