Escribe complementos de Genkit

Las capacidades de Firebase Genkit están diseñadas para que las extiendan los complementos. Los complementos de Genkit son módulos configurables que pueden proporcionar modelos, recuperadores, indexadores, almacenes de seguimiento y mucho más. Ya has visto complementos en acción con solo usar Genkit:

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

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

El complemento de Vertex AI toma la configuración (como el ID del proyecto de Google Cloud del usuario) y registra una variedad de modelos nuevos, incorporaciones y mucho más con Genkit Registry. El registro potencia la IU local de Genkit para ejecutar y también inspeccionar modelos, mensajes y mucho más, además sirve como un servicio de búsqueda de acciones con nombre en el entorno de ejecución.

Cómo crear un complemento

Para crear un complemento, por lo general, debes crear un nuevo paquete de 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

Luego, define y exporta el complemento desde tu punto de entrada 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...
  }
);

Orientación sobre las opciones de complementos

En general, tu complemento debería tomar un solo argumento options que incluya cualquier configuración de todo el complemento necesaria para funcionar. Para cualquier opción de complemento que requiera un valor secreto, como las claves de API, debes ofrecer una opción y una variable de entorno predeterminada para configurarla:

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

Cómo compilar tu complemento

Un solo complemento puede activar muchas funciones nuevas dentro de Genkit. Por ejemplo, el complemento de Vertex AI activa muchos modelos nuevos y una incorporaciones.

Complementos del modelo

Los complementos de modelos de Genkit agregan uno o más modelos de IA generativa al registro de Genkit. Un modelo representa cualquier modelo generativo que pueda recibir un mensaje como entrada y generar texto, contenido multimedia o datos como salida. Por lo general, un complemento de modelo realizará una o más llamadas a defineModel en su función de inicialización.

En general, un modelo personalizado consta de tres componentes:

  1. Metadatos que definen las capacidades del modelo
  2. Un esquema de configuración con cualquier parámetro específico que admite el modelo.
  3. Es una función que implementa el modelo que acepta GenerateRequest y muestra GenerateResponse.

Para compilar un complemento de modelo, tendrás que usar el paquete @genkit-ai/ai:

npm i --save @genkit-ai/ai

En un nivel alto, un complemento de modelo podría verse de la siguiente manera:

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

Transformación de solicitudes y respuestas

La tarea principal de un complemento de modelo de Genkit es transformar el GenerateRequest del formato común de Genkit en un formato que la API de tu modelo reconozca y admita y, luego, transformar la respuesta de tu modelo al formato GenerateResponseData que usa Genkit.

A veces, esto puede requerir masaje o manipulación de datos para eludir las limitaciones del modelo. Por ejemplo, si tu modelo no admite de forma nativa un mensaje system, es posible que debas transformar el mensaje del sistema de un mensaje en un par de mensajes de usuario/modelo.

Referencias del modelo

Una vez que se registra un modelo con defineModel, siempre está disponible cuando se solicita por nombre. Sin embargo, para mejorar la escritura y el autocompletado del IDE, puedes exportar una referencia del modelo desde tu paquete que incluya solo los metadatos de un modelo, pero no su implementación:

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

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

Cuando llamas a generate(), las referencias de modelos y los nombres de modelos de string se pueden usar indistintamente:

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

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

Complementos de telemetría

Consulta Cómo escribir un complemento de telemetría de Genkit.

Publica un complemento

Los complementos de Genkit se pueden publicar como paquetes de NPM normales. Para aumentar la visibilidad y maximizar la coherencia, tu paquete debe llamarse genkitx-{name} para indicar que es un complemento de Genkit y debes incluir todos los keywords siguientes en tu package.json como sean relevantes para tu complemento:

  • genkit-plugin: Incluye siempre esta palabra clave en tu paquete para indicar que es un complemento de Genkit.
  • genkit-model: Incluye esta palabra clave si tu paquete define algún modelo.
  • genkit-retriever: Incluye esta palabra clave si tu paquete define algún retriever.
  • genkit-indexer: Incluye esta palabra clave si tu paquete define algún indexador.
  • genkit-embedder: Incluye esta palabra clave si tu paquete define algún indexador.
  • genkit-tracestore: Incluye esta palabra clave si tu paquete define algún almacén de seguimiento.
  • genkit-statestore: Incluye esta palabra clave si tu paquete define algún almacén de estado.
  • genkit-telemetry: Incluye esta palabra clave si tu paquete define un proveedor de telemetría.
  • genkit-deploy: Incluye esta palabra clave si tu paquete incluye asistentes para implementar apps de Genkit en proveedores de servicios en la nube.
  • genkit-flow: Incluye esta palabra clave si tu paquete mejora los flujos de Genkit.

Un complemento que proporcionó un retriever, un embedder y un modelo podría tener un package.json similar al siguiente:

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