编写 Genkit 插件

Firebase Genkit 的功能设计为通过插件进行扩展。Genkit 插件是可配置的模块,可以提供模型、检索器、索引器、轨迹存储区等。您已经通过使用 Genkit 看到了插件的实际运用:

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

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

Vertex AI 插件会接受配置(例如用户的 Google Cloud 项目 ID),并通过 Genkit 注册表注册各种新模型、嵌入器等。该注册表可为 Genkit 的本地界面提供支持,以运行和检查模型、提示等,并在运行时作为命名操作的查找服务。

创建插件

如需创建插件,您通常需要创建新的 NPM 软件包:

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

然后,从主入口点定义并导出您的插件:

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(...)
    // ....
  });
};

插件选项指南

通常,您的插件应接受单个 options 参数,其中包含运行所需的所有插件级配置。对于任何需要密钥值的插件选项(例如 API 密钥),您都应提供选项和默认环境变量来对其进行配置:

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(...)
    
    // ....
  });
};

构建插件

单个插件可以在 Genkit 中激活许多新功能。例如,Vertex AI 插件会激活数个新模型以及一个嵌入器。

模型插件

Genkit 模型插件会向 Genkit 注册表添加一个或多个生成式 AI 模型。模型代表能够接收提示作为输入并生成文本、媒体或数据作为输出的任何生成模型。通常,模型插件会在其初始化函数中进行一次或多次 defineModel 调用。

自定义模型通常由三个部分组成:

  1. 定义模型功能的元数据。
  2. 具有模型支持的任何特定参数的配置架构。
  3. 用于实现接受 GenerateRequest 并返回 GenerateResponse 的模型的函数。

如需构建模型插件,您需要使用 @genkit-ai/ai 软件包:

npm i --save @genkit-ai/ai

概括来讲,模型插件可能如下所示:

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


转换请求和响应

Genkit 模型插件的主要工作是将 GenerateRequest 从 Genkit 的通用格式转换为模型 API 识别和支持的格式,然后将模型的回答转换为 Genkit 使用的 GenerateResponseData 格式。

有时,这可能需要对数据进行处理或操纵,以规避模型限制。例如,如果您的模型原生不支持 system 消息,您可能需要将提示的系统消息转换为用户/模型消息对。

模型引用

使用 defineModel 注册模型后,系统会在按名称请求时始终提供该模型。不过,为了改进打字和 IDE 自动补全功能,您可以从软件包中导出模型引用,其中仅包含模型的元数据,而非其实现:

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

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

调用 generate() 时,模型引用和字符串模型名称可以互换使用:

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

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

发布插件

Genkit 插件可以作为常规 NPM 软件包发布。为了提高可发现性并最大限度地提高一致性,您的软件包应命名为 genkitx-{name},以表明它是 Genkit 插件,并且您应在 package.json 中添加与您的插件相关的尽可能多的以下 keywords

  • genkit-plugin:请务必在软件包中添加此关键字,以指明它是 Genkit 插件。
  • genkit-model:如果您的软件包定义了任何模型,请添加此关键字。
  • genkit-retriever:如果您的软件包定义了任何检索器,请添加此关键字。
  • genkit-indexer:如果您的软件包定义了任何索引编制程序,请添加此关键字。
  • genkit-embedder:如果您的软件包定义了任何索引编制程序,请添加此关键字。
  • genkit-tracestore:如果您的软件包定义了任何轨迹存储区,请添加此关键字。
  • genkit-statestore:如果您的软件包定义了任何状态存储区,请添加此关键字。
  • genkit-telemetry:如果您的软件包定义了遥测提供程序,请添加此关键字。
  • genkit-deploy:如果您的软件包包含用于将 Genkit 应用部署到云服务提供商的帮助程序,请添加此关键字。
  • genkit-flow:如果您的软件包增强了 Genkit 流程,请添加此关键字。

提供检索器、嵌入器和模型的插件可能具有如下所示的 package.json

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