Como escrever um plug-in de modelo Genkit

Os plug-ins de modelo do Genkit adicionam um ou mais modelos de IA generativa ao Genkit de registros. Um modelo representa qualquer modelo generativo capaz de receber um comando como entrada e gerar texto, mídia ou dados como saída.

Antes de começar

Leia Como escrever plug-ins do Genkit (em inglês) para informações sobre como escrever qualquer tipo de plug-in Genkit, incluindo plug-ins de modelo. Observe especificamente que cada plug-in precisa exportar uma função Init, que os usuários precisam chamar antes de usar o plug-in.

Definições de modelos

Geralmente, um plug-in de modelo faz uma ou mais chamadas ai.DefineModel na Função Init: uma vez para cada modelo, o plug-in fornece uma interface

Uma definição de modelo consiste em três componentes:

  1. Metadados que declaram os recursos do modelo.
  2. Um tipo de configuração com quaisquer parâmetros específicos aceitos pelo modelo.
  3. Uma função de geração que aceita uma ai.GenerateRequest e retorna uma ai.GenerateResponse, provavelmente usando um modelo de IA para gerar o segundo modelo.

De modo geral, ele fica assim no código:

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

Como declarar recursos do modelo

Cada definição de modelo precisa conter, como parte de seus metadados, um O valor ai.ModelCapabilities que declara a quais recursos o modelo oferece suporte. O Genkit usa essas informações para determinar certos comportamentos, como verificar se certas entradas são válidas para o modelo. Por exemplo, se o modelo não for compatível com interações de várias interações, será um erro transmitir uma mensagem história.

Observe que essas declarações se referem às capacidades do modelo conforme fornecido pelo seu plug-in e não necessariamente associam um a um às capacidades do um modelo subjacente e uma API de modelo. Por exemplo, mesmo que a API do modelo não fornecer uma maneira específica de definir mensagens do sistema, o plug-in ainda poderá declarar suporte para o papel do sistema e implementá-lo como uma lógica especial que insere mensagens do sistema no prompt do usuário.

Como definir o esquema de configuração do modelo

Para especificar as opções de geração compatíveis com um modelo, defina e exporte uma tipo de configuração. O Genkit tem um tipo ai.GenerationCommonConfig que contém geralmente compatíveis com serviços de modelos de IA generativa, que podem incorporar ou usar imediatamente.

A função de geração deve verificar se a solicitação contém o tipo de opção.

Como transformar solicitações e respostas

A função de geração realiza o trabalho principal de um plug-in de modelo Genkit: Transformar o ai.GenerateRequest do formato comum do Genkit para um formato com suporte da API do seu modelo e, em seguida, transformar a resposta do seu modelo no formato ai.GenerateResponse usado pelo Genkit.

Às vezes, isso pode exigir massagens ou manipulação de dados para contornar o modelo limitações. Por exemplo, se o modelo não oferecer suporte nativo a uma system talvez seja necessário transformar uma mensagem do sistema de um prompt em um modelo de usuário par de mensagens.

Exportações

Além dos recursos que todos os plug-ins precisam exportar, um Init e um tipo Config. Um plug-in de modelo também precisa exportar os seguintes:

  • Um tipo de configuração de geração, conforme discutido anteriormente.

  • Uma função Model, que retorna referências aos modelos definidos do plug-in. Muitas vezes, isso pode ser simplesmente:

    func Model(name string) *ai.Model {
        return ai.LookupModel(providerID, name)
    }
    
  • Opcional: uma função DefineModel, que permite aos usuários definir modelos que seu plug-in pode fornecer, mas que você não define automaticamente. Existem dois motivos principais para fornecer essa função:

    • Seu plug-in fornece acesso a muitos modelos para que seja possível registrar cada um. Por exemplo, o plug-in Ollama pode fornecer acesso a dezenas de diferentes modelos, e os que são adicionados com mais frequência. Por esse motivo, ele não define automaticamente os modelos e exige que o usuário chame DefineModel para cada modelo que quiserem usar.

    • Para dar aos usuários a capacidade de usar modelos recém-lançados que ainda não foram adicionados ao seu plug-in.

    A função DefineModel de um plug-in normalmente é um front-end para ai.DefineModel que define uma função de geração, mas permite que o usuário especifique o nome do modelo e as capacidades do modelo.