Pisanie wtyczek Genkit

Funkcje Firebase Genkit są przeznaczone do rozszerzania za pomocą wtyczek. Wtyczki Genkit to moduły konfigurowalne, które mogą udostępniać modele, retrievery, indeksatory, magazyny śladów i inne elementy. Wtyczki można już zobaczyć w działaniu, korzystając z Genkit:

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

const ai = genkit({
  plugins: [vertexAI({ projectId: 'my-project' })],
});

Wtyczka Vertex AI pobiera konfigurację (np. identyfikator projektu Google Cloud) i rejestruje w rejestrze Genkit różne nowe modele, wtyczki i inne elementy. Rejestr obsługuje lokalny interfejs Genkit do uruchamiania i sprawdzania modeli, promptów itp., a także służy jako usługa wyszukiwania nazwanych działań w czasie wykonywania.

Tworzenie wtyczki

Aby utworzyć wtyczkę, zazwyczaj musisz utworzyć nowy pakiet NPM:

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

Następnie zdefiniuj i wyeksportuj wtyczkę z głównego punktu wejścia:

import { Genkit, z } from 'genkit';
import { GenkitPlugin, genkitPlugin } from 'genkit/plugin';

interface MyPluginOptions {
  // add any plugin configuration here
}

export function myPlugin(options?: MyPluginOptions) {
  return genkitPlugin('myPlugin', async (ai: Genkit) => {
    ai.defineModel(...);
    ai.defineEmbedder(...)
    // ....
  });
};

Wskazówki dotyczące opcji wtyczki

Ogólnie rzecz biorąc, w pliku plugina powinien znajdować się jeden argument options, który zawiera dowolną konfigurację potrzebną do działania w całym pliku. W przypadku każdej opcji wtyczki, która wymaga wartości tajnej, takiej jak klucze interfejsu API, należy zaoferować opcję i domyślną zmienną środowiskową, aby ją skonfigurować:

import { Genkit, z } from 'genkit';
import { GenkitPlugin, genkitPlugin } from 'genkit/plugin';
import { GenkitError } from '@genkit-ai/core';

interface MyPluginOptions {
  apiKey?: string;
}

export function myPlugin(options?: MyPluginOptions) {
  return genkitPlugin('myPlugin', async (ai: Genkit) => {
    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.',
      });

    ai.defineModel(...);
    ai.defineEmbedder(...)
    
    // ....
  });
};

Tworzenie wtyczki

Pojedyncza wtyczka może aktywować wiele nowych rzeczy w Genkit. Na przykład wtyczka Vertex AI aktywuje kilka nowych modeli oraz wtyczkę embedder.

Wtyczki modelu

Wtyczki modeli Genkit dodają co najmniej 1 model generatywnej AI do rejestru Genkit. Model to dowolny model generatywny, który może otrzymywać prompt jako dane wejściowe i generować tekst, multimedia lub dane jako dane wyjściowe. Zazwyczaj w funkcji inicjalizacji wtyczka modelu wykonuje co najmniej 1 wywołanie funkcji defineModel.

Model niestandardowy składa się z 3 komponentów:

  1. Metadane określające możliwości modelu.
  2. Schemat konfiguracji z parametrami obsługiwanymi przez model.
  3. Funkcja, która implementuje model, przyjmuje GenerateRequest i zwraca GenerateResponse.

Aby utworzyć wtyczkę modelu, musisz użyć pakietu @genkit-ai/ai:

npm i --save @genkit-ai/ai

Ogólnie rzecz biorąc, wtyczka modelu może wyglądać tak:

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


export function myPlugin(options?: MyPluginOptions) {
  return genkitPlugin('my-plugin', async (ai: Genkit) => {
    ai.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);
    });
  });
};


Przekształcanie żądań i odpowiedzi

Podstawowym zadaniem wtyczki modelu Genkit jest przekształcenie danych GenerateRequest z powszechnie używanego formatu Genkit na format rozpoznawany i obsługiwany przez interfejs API modelu, a następnie przekształcenie odpowiedzi z Twojego modelu do formatu GenerateResponseData używanego przez Genkit.

Czasami może to wymagać zmodyfikowania lub manipulowania danymi, aby obejść ograniczenia modelu. Jeśli na przykład Twój model nie obsługuje domyślnie wiadomości system, może być konieczne przekształcenie wiadomości systemowej promptu w parę wiadomości dla użytkownika i modela.

Odwołania do modelu

Gdy model zostanie zarejestrowany za pomocą funkcji defineModel, będzie zawsze dostępny, gdy żądanie zostanie wysłane z użyciem jego nazwy. Aby jednak ulepszyć pisanie i autouzupełnianie w IDE, możesz wyeksportować odwołanie do modelu z paczki, które zawiera tylko metadane modelu, a nie jego implementację:

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

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

Podczas wywoływania funkcji generate() można używać zamiennie odwołań do modelu i nazwy modelu ciągu znaków:

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

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

Publikowanie wtyczki

Wtyczki Genkit można publikować jako zwykłe pakiety NPM. Aby zwiększyć widoczność i maksymalizować spójność, nazwa pakietu powinna mieć postać genkitx-{name}, aby wskazać, że jest to wtyczka Genkit. W pliku package.json należy umieścić jak najwięcej z tych keywords, które są istotne dla wtyczki:

  • genkit-plugin: zawsze dołącz to słowo kluczowe do pakietu, aby wskazać, że jest to wtyczka Genkit.
  • genkit-model: dołącz to słowo kluczowe, jeśli Twój pakiet definiuje jakieś modele.
  • genkit-retriever: dołącz to słowo kluczowe, jeśli pakiet definiuje jakiekolwiek retrievery.
  • genkit-indexer: uwzględnij to słowo kluczowe, jeśli Twój pakiet definiuje jakiekolwiek indeksatory.
  • genkit-embedder: uwzględnij to słowo kluczowe, jeśli Twój pakiet definiuje jakiekolwiek indeksatory.
  • genkit-tracestore: uwzględnij to słowo kluczowe, jeśli Twój pakiet definiuje jakiekolwiek magazyny śladów.
  • genkit-statestore: dodaj to słowo kluczowe, jeśli Twój pakiet definiuje jakiekolwiek stany.
  • genkit-telemetry: dołącz to słowo kluczowe, jeśli Twój pakiet definiuje dostawcę telemetrii.
  • genkit-deploy: dodaj to słowo kluczowe, jeśli Twój pakiet zawiera pomocnicze narzędzia do wdrażania aplikacji Genkit u dostawców usług w chmurze.
  • genkit-flow: uwzględnij to słowo kluczowe, jeśli Twój pakiet ulepsza przepływy Genkit.

Wtyczka, która udostępnia retrievera, embedder i model, może mieć element package.json, który wygląda tak:

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