编写 Genkit 模型插件

Genkit 模型插件会向 Genkit 注册表添加一个或多个生成式 AI 模型。模型代表能够接收提示作为输入并生成文本、媒体或数据作为输出的任何生成模型。

准备工作

如需了解如何编写任何类型的 Genkit 插件(包括模型插件),请参阅编写 Genkit 插件。特别要注意,每个插件都必须导出一个 Init 函数,用户应在使用此插件之前调用该函数。

模型定义

通常,模型插件会在其 Init 函数中进行一次或多次 ai.DefineModel 调用,对于插件为其提供接口的每个模型,都会进行一次调用。

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

  1. 声明模型功能的元数据。
  2. 包含模型支持的任何特定参数的配置类型。
  3. 接受 ai.GenerateRequest 并返回 ai.GenerateResponse 的生成函数,可能使用 AI 模型生成后者。

概括来讲,代码如下所示:

type MyModelConfig struct {
	ai.GenerationCommonConfig
	CustomOption int
	AnotherCustomOption string
}
ai.DefineModel(
	providerID, "my-model",
	&ai.ModelMetadata{
		Label: "my-model",
		Supports: ai.ModelCapabilities{
			Multiturn:  true,  // Does the model support multi-turn chats?
			SystemRole: true,  // Does the model support syatem messages?
			Media:      false, // Can the model accept media input?
			Tools:      false, // Does the model support function calling (tools)?
		},
	},
	func(ctx context.Context,
		genRequest *ai.GenerateRequest,
		_ ai.ModelStreamingCallback,
	) (*ai.GenerateResponse, error) {
		// Verify that the request includes a configuration that conforms to
		// your schema .
		if _, ok := genRequest.Config.(MyModelConfig); !ok {
			return nil, fmt.Errorf("request config must be type MyModelConfig")
		}

		// Use your custom logic to convert Genkit's ai.GenerateRequest
		// into a form usable by the model's native API.
		apiRequest, err := apiRequestFromGenkitRequest(genRequest)
		if err != nil {
			return nil, err
		}

		// Send the request to the model API, using your own code or the
		// model API's client library.
		apiResponse, err := callModelAPI(apiRequest)
		if err != nil {
			return nil, err
		}

		// Use your custom logic to convert the model's response to Genkin's
		// ai.GenerateResponse.
		response, err := genResponseFromAPIResponse(apiResponse)
		if err != nil {
			return nil, err
		}

		return response, nil
	},
)

声明模型功能

每个模型定义都必须包含一个 ai.ModelCapabilities 值作为其元数据的一部分,以声明模型支持哪些功能。Genkit 会使用这些信息来确定某些行为,例如确认某些输入是否适用于模型。例如,如果模型不支持多轮交互,则将消息记录传递给该模型会出错。

请注意,这些声明是指插件提供的模型功能,并不一定与底层模型和模型 API 的功能一一对应。例如,即使模型 API 未提供定义系统消息的具体方法,插件可能仍会声明支持系统角色,并将其以特殊逻辑的形式实现,以将系统消息插入用户提示中。

定义模型的配置架构

如需指定模型支持的生成选项,请定义并导出配置类型。Genkit 有一个 ai.GenerationCommonConfig 类型,其中包含生成式 AI 模型服务通常支持的选项,您可以嵌入这些选项,也可以直接使用这些选项。

生成函数应验证请求是否包含正确的选项类型。

转换请求和回答

生成函数执行 Genkit 模型插件的主要工作:将 ai.GenerateRequest 从 Genkit 的通用格式转换为模型 API 支持的格式,然后将模型的回答转换为 Genkit 使用的 ai.GenerateResponse 格式。

有时,这可能需要对数据进行调整或操纵,以解决模型限制问题。例如,如果您的模型原生不支持 system 消息,您可能需要将提示的系统消息转换为用户-模型消息对。

导出内容

除了所有插件都必须导出的资源(Init 函数和 Config 类型)之外,模型插件还应导出以下内容:

  • 生成配置类型,如前面所述。

  • Model 函数,用于返回对插件定义的模型的引用。通常,此函数可以简单地表示为:

    func Model(name string) *ai.Model {
        return ai.LookupModel(providerID, name)
    }
    
  • 可选DefineModel 函数,可让用户定义插件可以提供但您不会自动定义的模型。您可能需要提供此类函数的主要原因有两个:

    • 插件提供对过多模型的访问权限,无法实际注册每个模型。例如,Ollama 插件可以提供对数十种不同模型的访问权限,并且会经常添加更多模型。因此,它不会自动定义任何模型,而是要求用户针对要使用的每个模型调用 DefineModel

    • 让用户能够使用您尚未添加到插件的新发布模型。

    插件的 DefineModel 函数通常是定义生成函数的 ai.DefineModel 的前端,但可让用户指定模型名称和模型功能。