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 wtyczek

Ogólnie rzecz biorąc, w pliku plugina powinien znajdować się jeden argument options, który zawiera dowolną konfigurację wymaganą 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 { GenkitError, Genkit, z } from 'genkit';
import { GenkitPlugin, genkitPlugin } from 'genkit/plugin';

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ę do umieszczania.

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/model:

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

import { genkitPlugin, GenkitPlugin } from 'genkit/plugin';
import { GenerationCommonConfigSchema } from 'genkit/model';
import { simulateSystemPrompt } from 'genkit/model/middleware';
import { Genkit, GenkitError, z } from 'genkit';

export interface MyPluginOptions {
 // ...
}

export function myPlugin(options?: MyPluginOptions): GenkitPlugin {
  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 w taki format, który jest rozpoznawany i obsługiwany przez interfejs API Twojego modelu, a następnie przekształcenie odpowiedzi z Twojego modelu w format GenerateResponseData używany 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 w standardzie 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ć wpisywanie tekstu 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/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';

ai.generate({ model: myModelRef });
// is equivalent to
ai.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 elementów 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: dodaj 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-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.
}