Écrire des plug-ins Genkit

Les fonctionnalités de Firebase Genkit sont conçues pour être étendues par des plug-ins. Les plug-ins Genkit sont des modules configurables pouvant fournir des modèles, des récupérateurs, des indexeurs, des magasins de traces, etc. Vous avez déjà vu des plug-ins en action simplement en utilisant Genkit :

import { configureGenkit } from '@genkit-ai/core';
import { vertexAI } from '@genkit-ai/vertexai';

configureGenkit({
  plugins: [vertexAI({ projectId: 'my-project' })],
});

Le plug-in Vertex AI effectue la configuration (telle que l'ID de projet Google Cloud de l'utilisateur) et enregistre divers nouveaux modèles, intégrateurs et plus encore dans le registre Genkit. Le Registre alimente l'UI locale de Genkit pour exécuter et inspecter des modèles, des invites, etc., et sert également de service de recherche pour les actions nommées au moment de l'exécution.

Créer un plug-in

Pour créer un plug-in, vous devez généralement créer un package NPM :

mkdir genkitx-my-plugin
cd genkitx-my-plugin
npm init -y
npm i --save @genkit-ai/core
npm i --save-dev typescript
npx tsc --init

Définissez et exportez ensuite votre plug-in à partir de votre point d'entrée principal :

import { genkitPlugin } from '@genkit-ai/core';

interface MyPluginOptions {
  // add any plugin configuration here
}

export const myPlugin = genkitPlugin(
  'my-plugin',
  async (options: MyPluginOptions) => {
    // initialize your plugin here...
  }
);

Conseils sur les options de plug-in

En général, votre plug-in doit accepter un seul argument options qui inclut toute configuration à l'échelle du plug-in nécessaire au fonctionnement. Pour toute option de plug-in qui requiert une valeur secrète, comme des clés API, vous devez proposer à la fois une option pour la configurer:

import { genkitPlugin, GenkitError } from '@genkit-ai/core';

interface MyPluginOptions {
  apiKey?: string;
}

export const myPlugin = genkitPlugin(
  'my-plugin',
  async (options: MyPluginOptions) => {
    const apiKey = options.apiKey || process.env.MY_PLUGIN_API_KEY;
    if (!apiKey)
      throw new GenkitError({
        source: 'my-plugin',
        status: 'INVALID_ARGUMENT',
        message:
          'Must supply either `options.apiKey` or set `MY_PLUGIN_API_KEY` environment variable.',
      });
    // ... continue initialization
  }
);

Créer votre plug-in

Un seul plug-in peut activer de nombreuses nouvelles fonctionnalités dans Genkit. Par exemple, le plug-in Vertex AI active plusieurs nouveaux modèles ainsi qu'un outil d'intégration.

Plug-ins du modèle

Les plug-ins de modèle Genkit ajoutent un ou plusieurs modèles d'IA générative au registre Genkit. Un modèle représente toute capable de recevoir une requête en entrée et de générer du texte, des contenus multimédias ou des données en sortie. En règle générale, un plug-in de modèle effectue un ou plusieurs appels defineModel dans sa fonction d'initialisation.

Un modèle personnalisé se compose généralement de trois composants:

  1. Métadonnées définissant les fonctionnalités du modèle.
  2. Un schéma de configuration avec les paramètres spécifiques compatibles avec le modèle.
  3. Une fonction qui implémente le modèle en acceptant GenerateRequest et renvoyant GenerateResponse.

Pour créer un plug-in de modèle, vous devez utiliser le package @genkit-ai/ai:

npm i --save @genkit-ai/ai

De manière générale, un plug-in de modèle peut se présenter comme suit:

import { genkitPlugin, GenkitError } from '@genkit-ai/core';
import { defineModel, GenerationCommonConfigSchema } from '@genkit-ai/ai/model';
import { simulateSystemPrompt } from '@genkit-ai/ai/model/middleware';
import { z } from 'zod';

export const myPlugin = genkitPlugin('my-plugin', async (options: {apiKey?: string}) => {
  defineModel({
    // be sure to include your plugin as a provider prefix
    name: 'my-plugin/my-model',
    // label for your model as shown in Genkit Developer UI
    label: 'My Awesome Model',
    // optional list of supported versions of your model
    versions: ['my-model-001', 'my-model-001'],
    // model support attributes
    supports: {
      multiturn: true, // true if your model supports conversations
      media: true, // true if your model supports multimodal input
      tools: true, // true if your model supports tool/function calling
      systemRole: true, // true if your model supports the system role
      output: ['text', 'media', 'json'], // types of output your model supports
    },
    // Zod schema for your model's custom configuration
    configSchema: GenerationCommonConfigSchema.extend({
      safetySettings: z.object({...}),
    }),
    // list of middleware for your model to use
    use: [simulateSystemPrompt()]
  }, async request => {
    const myModelRequest = toMyModelRequest(request);
    const myModelResponse = await myModelApi(myModelRequest);
    return toGenerateResponse(myModelResponse);
  });
});

Transformer les requêtes et les réponses

Le travail principal d'un plug-in de modèle Genkit consiste à transformer GenerateRequest du format courant de Genkit en un format reconnu et pris en charge par l'API de votre modèle, puis transformer la réponse au format GenerateResponseData utilisé par Genkit.

Parfois, il peut être nécessaire de masser ou de manipuler les données pour contourner les limites du modèle. Par exemple, si votre modèle n'est pas compatible de manière native avec un message system, vous devrez peut-être transformer le message système d'une requête en une paire de messages utilisateur/modèle.

Références de modèles

Une fois qu'un modèle est enregistré avec defineModel, il est toujours disponible lorsque demandé par son nom. Toutefois, pour améliorer la saisie et la saisie semi-automatique dans l'IDE, vous pouvez exporter à partir de votre package une référence de modèle qui ne contient que les métadonnées d'un mais pas son implémentation:

import { modelRef } from "@genkit-ai/ai/model";

export myModelRef = modelRef({
  name: "my-plugin/my-model",
  configSchema: MyConfigSchema,
  info: {
    // ... model-specific info
  },
})

Lorsque vous appelez generate(), les références de modèle et les noms de modèle de chaîne peuvent être utilisés de manière interchangeable :

import { myModelRef } from 'genkitx-my-plugin';
import { generate } from '@genkit-ai/ai';

generate({ model: myModelRef });
// is equivalent to
generate({ model: 'my-plugin/my-model' });

Plug-ins de télémétrie

Consultez Écrire un plug-in de télémétrie Genkit.

Publier un plug-in

Les plug-ins Genkit peuvent être publiés en tant que packages NPM normaux. Pour augmenter la visibilité et la cohérence, votre package doit être nommé genkitx-{name} pour indiquer qu'il s'agit d'un plug-in Genkit et que vous devez l'inclure en tant que de nombreux éléments keywords suivants dans votre package.json, car ils sont pertinents pour votre plugin:

  • genkit-plugin: incluez toujours ce mot clé dans le package pour indiquer qu'il s'agit d'un plug-in Genkit.
  • genkit-model : incluez ce mot clé si votre package définit des modèles.
  • genkit-retriever: inclure ce mot clé si votre package définit des extracteurs.
  • genkit-indexer: incluez ce mot clé si votre package définit des indexeurs.
  • genkit-embedder: incluez ce mot clé si votre package définit des indexeurs.
  • genkit-tracestore : incluez ce mot clé si votre package définit des magasins de traces.
  • genkit-statestore : incluez ce mot clé si votre package définit des magasins d'état.
  • genkit-telemetry: incluez ce mot clé si votre package définit un fournisseur de télémétrie.
  • genkit-deploy: incluez ce mot clé si votre package inclut des assistants permettant de déployer des applications Genkit sur les fournisseurs cloud.
  • genkit-flow: inclut ce mot clé si votre package améliore les flux Genkit.

Un plug-in qui a fourni un extracteur, un outil d'intégration et un modèle peut avoir un package.json qui se présente comme suit :

{
  "name": "genkitx-my-plugin",
  "keywords": ["genkit-plugin", "genkit-retriever", "genkit-embedder", "genkit-model"],
  // ... dependencies etc.
}