add-provider-package

Par vercel · ai

Guide pour l'ajout de nouveaux packages de fournisseurs IA au AI SDK. À utiliser lors de la création d'un nouveau package `@ai-sdk/<provider>` pour intégrer un service IA dans le SDK.

npx skills add https://github.com/vercel/ai --skill add-provider-package

Ajouter un nouveau package provider

Ce guide couvre le processus de création d'un nouveau package @ai-sdk/<provider> pour intégrer un service IA dans l'AI SDK.

Providers propriétaires vs tiers

  • Packages tiers: Tout provider peut créer un package tiers. Nous serons heureux de le lier depuis notre documentation.
  • Packages propriétaires @ai-sdk/<provider>: Si vous préférez un package propriétaire, veuillez d'abord créer un issue pour en discuter.

Exemple de référence

Consultez https://github.com/vercel/ai/pull/8136/files pour un exemple complet d'ajout d'un nouveau provider.

Architecture du provider

L'AI SDK utilise une architecture provider en couches suivant le pattern adapter :

  1. Spécifications (@ai-sdk/provider): Définit les interfaces comme LanguageModelV4, EmbeddingModelV4, etc.
  2. Utilitaires (@ai-sdk/provider-utils): Code partagé pour implémenter les providers
  3. Providers (@ai-sdk/<provider>): Implémentations concrètes pour chaque service IA
  4. Core (ai): Fonctions haut niveau comme generateText, streamText, generateObject

Guide étape par étape

1. Créer la structure du package

Créez un nouveau dossier packages/<provider> avec la structure suivante :

packages/<provider>/
├── src/
│   ├── index.ts                  # Exports principaux
│   ├── version.ts                # Version du package
│   ├── <provider>-provider.ts    # Implémentation du provider
│   ├── <provider>-provider.test.ts
│   ├── <provider>-*-options.ts   # Options spécifiques au modèle
│   └── <provider>-*-model.ts     # Implémentations de modèles (ex: language, embedding, image)
├── package.json
├── tsconfig.json
├── tsconfig.build.json
├── tsup.config.ts
├── turbo.json
├── vitest.node.config.js
├── vitest.edge.config.js
└── README.md

Ne créez pas de fichier CHANGELOG.md. Il sera auto-généré.

2. Configurer package.json

Configurez votre package.json avec :

  • "name": "@ai-sdk/<provider>"
  • "version": "0.0.0" (version initiale, sera mise à jour par changeset)
  • "license": "Apache-2.0"
  • "sideEffects": false
  • Dépendances sur @ai-sdk/provider et @ai-sdk/provider-utils (utilisez workspace:*)
  • Dépendances de dev: @ai-sdk/test-server, @types/node, @vercel/ai-tsconfig, tsup, typescript, zod
  • "engines": { "node": ">=18" }
  • Dépendance peer sur zod (v3 et v4): "zod": "^3.25.76 || ^4.1.8"

Exemple de configuration des exports :

{
  "exports": {
    "./package.json": "./package.json",
    ".": {
      "types": "./dist/index.d.ts",
      "import": "./dist/index.mjs",
      "require": "./dist/index.js"
    }
  }
}

3. Créer les configurations TypeScript

tsconfig.json:

{
  "extends": "@vercel/ai-tsconfig/base.json",
  "include": ["src/**/*.ts"],
  "exclude": ["node_modules", "dist"]
}

tsconfig.build.json:

{
  "extends": "./tsconfig.json",
  "exclude": [
    "**/*.test.ts",
    "**/*.test-d.ts",
    "**/__snapshots__",
    "**/__fixtures__"
  ]
}

4. Configurer l'outil de build (tsup)

Créez tsup.config.ts:

import { defineConfig } from 'tsup';

export default defineConfig({
  entry: ['src/index.ts'],
  format: ['cjs', 'esm'],
  dts: true,
  sourcemap: true,
  clean: true,
});

5. Configurer les test runners

Créez à la fois vitest.node.config.js et vitest.edge.config.js (copiez depuis un provider existant comme anthropic).

6. Implémenter le provider

Pattern d'implémentation du provider:

// <provider>-provider.ts
import { NoSuchModelError } from '@ai-sdk/provider';
import { loadApiKey } from '@ai-sdk/provider-utils';

export interface ProviderSettings {
  apiKey?: string;
  baseURL?: string;
  // paramètres spécifiques au provider
}

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);
  }

  // Alias plus court
  chat(modelId: string) {
    return this.languageModel(modelId);
  }
}

// Exporter l'instance par défaut
export const providerName = new ProviderInstance();

7. Implémenter les classes de modèle

Chaque type de modèle (language, embedding, image, etc.) doit implémenter l'interface appropriée depuis @ai-sdk/provider :

  • LanguageModelV4 pour les modèles de génération de texte
  • EmbeddingModelV4 pour les modèles d'embedding
  • ImageModelV4 pour les modèles de génération d'image
  • etc.

Directives de schéma:

Options du provider (côté utilisateur):

  • Utilisez .optional() sauf si null a du sens
  • Soyez aussi restrictif que possible pour la flexibilité future

Schémas de réponse (réponses API):

  • Utilisez .nullish() au lieu de .optional()
  • Gardez minimal - incluez uniquement les propriétés dont vous avez besoin
  • Laissez de la flexibilité pour les changements d'API du provider

8. Créer README.md

Incluez:

  • Brève description avec lien vers la documentation
  • Instructions d'installation
  • Exemple d'utilisation basique
  • Lien vers la documentation complète

9. Écrire les tests

  • Tests unitaires de la logique du provider
  • Tests de parsing de réponse API utilisant des fixtures dans le répertoire __fixtures__
  • Tests pour les runtimes Node.js et Edge

Consultez la skill capture-api-response-test-fixture pour capturer les vraies réponses API pour les tests.

10. Ajouter des exemples

Créez des exemples dans examples/ai-functions/src/ pour chaque type de modèle supporté par le provider :

  • generate-text/<provider>.ts - Génération de texte basique
  • stream-text/<provider>.ts - Streaming de texte
  • generate-object/<provider>.ts - Sortie structurée (si supportée)
  • stream-object/<provider>.ts - Streaming de sortie structurée (si supportée)
  • embed/<provider>.ts - Embeddings (si supportés)
  • generate-image/<provider>.ts - Génération d'image (si supportée)
  • etc.

Ajoutez des exemples spécifiques aux fonctionnalités selon les besoins (ex: <provider>-tool-call.ts, <provider>-cache-control.ts).

11. Ajouter la documentation

Créez la documentation dans content/providers/01-ai-sdk-providers/<last number + 10>-<provider>.mdx

Incluez:

  • Instructions de configuration
  • Modèles disponibles
  • Capacités du modèle
  • Options spécifiques au provider
  • Exemples d'utilisation
  • Configuration de l'API

12. Créer un changeset

Exécutez pnpm changeset et :

  • Sélectionnez le nouveau package provider
  • Choisissez la version major (pour les nouveaux packages commençant à 0.0.0)
  • Décrivez ce que le package fournit

13. Mettre à jour les références

Exécutez pnpm update-references depuis la racine du workspace pour mettre à jour les références tsconfig.

14. Build et test

# Depuis la racine du workspace
pnpm build

# Depuis le package du provider
cd packages/<provider>
pnpm test              # Exécuter tous les tests
pnpm test:node         # Exécuter les tests Node.js
pnpm test:edge         # Exécuter les tests Edge
pnpm type-check        # Vérification des types

# Depuis la racine du workspace
pnpm type-check:full   # Vérification complète des types incluant les exemples

15. Exécuter les exemples

Testez vos exemples :

cd examples/ai-functions
pnpm tsx src/generate-text/<provider>.ts
pnpm tsx src/stream-text/<provider>.ts

Nommage des méthodes du provider

  • Noms complets: languageModel(id), imageModel(id), embeddingModel(id) (obligatoire)
  • Alias courts: .chat(id), .image(id), .embedding(id) (pour l'expérience développeur)

Conventions de nommage des fichiers

  • Fichiers source: kebab-case.ts
  • Fichiers de test: kebab-case.test.ts
  • Fichiers de test de type: kebab-case.test-d.ts
  • Classes du provider: <Provider>Provider, <Provider>LanguageModel, etc.

Bonnes pratiques de sécurité

  • N'utilisez jamais JSON.parse directement - utilisez parseJSON ou safeParseJSON depuis @ai-sdk/provider-utils
  • Chargez les clés API de manière sécurisée en utilisant loadApiKey depuis @ai-sdk/provider-utils
  • Validez toutes les réponses API par rapport aux schémas

Gestion des erreurs

Les erreurs doivent étendre AISDKError depuis @ai-sdk/provider et utiliser un pattern de marqueur :

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);
  }
}

Mode pré-release

Si main est configuré pour publier des releases beta, aucune action supplémentaire n'est nécessaire. Assurez-vous simplement de ne pas le backporter vers la branche vX.Y stable car cela entraînerait un conflit de version npm une fois que nous sortons du mode pré-release sur main.

Checklist

  • [ ] Structure du package créée dans packages/<provider>
  • [ ] package.json configuré avec les bonnes dépendances
  • [ ] Configs TypeScript mises en place (tsconfig.json, tsconfig.build.json)
  • [ ] Configuration du build (tsup.config.ts)
  • [ ] Configurations des tests (vitest.node.config.js, vitest.edge.config.js)
  • [ ] Implémentation du provider complète
  • [ ] Classes de modèle implémentant les interfaces appropriées
  • [ ] Tests unitaires écrits et passants
  • [ ] Fixtures de test de réponse API capturées
  • [ ] Exemples créés dans examples/ai-functions/src/
  • [ ] Documentation ajoutée dans content/providers/01-ai-sdk-providers/
  • [ ] README.md écrit
  • [ ] Major changeset créé
  • [ ] pnpm update-references exécuté
  • [ ] Tous les tests passants (pnpm test depuis le package)
  • [ ] Vérification des types passante (pnpm type-check:full depuis la racine)
  • [ ] Exemples exécutés avec succès

Problèmes courants

  • Références tsconfig manquantes: Exécutez pnpm update-references depuis la racine du workspace
  • Erreurs de type dans les exemples: Exécutez pnpm type-check:full pour détecter les problèmes tôt
  • Échecs des tests: Assurez-vous que les tests Node et Edge passent
  • Erreurs de build: Vérifiez que tsup.config.ts est configuré correctement

Documentation associée

Skills similaires