Gerar conteúdo

O Firebase Genkit oferece uma interface fácil para gerar conteúdo com LLMs.

Modelos

Os modelos no Firebase Genkit são bibliotecas e abstrações que dão acesso a vários LLMs do Google e de terceiros.

Os modelos estão totalmente instrumentados para observabilidade e vêm com ferramentas integrações fornecidas pela interface de usuário do Genkit Developer. É possível testar qualquer modelo usando no executor de modelos.

Ao trabalhar com modelos no Genkit, primeiro é preciso configurar o modelo que você quer trabalhar. A configuração do modelo é realizada pelo sistema do plug-in. Em Neste exemplo, você vai configurar o plug-in da Vertex AI, que oferece o Gemini de modelos de machine learning.

Go

import "github.com/firebase/genkit/go/ai"
import "github.com/firebase/genkit/go/plugins/vertexai"
// Default to the value of GCLOUD_PROJECT for the project,
// and "us-central1" for the location.
// To specify these values directly, pass a vertexai.Config value to Init.
if err := vertexai.Init(ctx, nil); err != nil {
  return err
}

Para usar modelos fornecidos pelo plug-in, você precisa de uma referência ao modelo específico e versão:

Go

gemini15pro := vertexai.Model("gemini-1.5-pro")

Modelos compatíveis

O Genkit oferece suporte a modelos pelo sistema de plug-ins. Os plug-ins a seguir são oficialmente suportados:

Plug-in Modelos
IA generativa do Google Gemini Pro e Gemini Pro Vision
Vertex AI do Google Gemini Pro, Gemini Pro Vision, Gemini 1.5 Flash, Gemini 1.5 Pro e Imagen2
Ollama (em inglês) Muitos modelos locais, como Gemma, Llama 2, Mistral, entre outros

Consulte a documentação de cada plug-in para ver informações de configuração e uso.

Como gerar conteúdo

O Genkit fornece uma função auxiliar simples para gerar conteúdo com modelos.

Basta chamar o modelo:

Go

request := ai.GenerateRequest{Messages: []*ai.Message{
  {Content: []*ai.Part{ai.NewTextPart("Tell me a joke.")}},
}}
response, err := gemini15pro.Generate(ctx, &request, nil)
if err != nil {
  return err
}

responseText, err := response.Text()
if err != nil {
  return err
}
fmt.Println(responseText)

É possível transmitir opções com a chamada de modelo. As opções compatíveis dependem do modelo e da API dele.

Go

request := ai.GenerateRequest{
  Messages: []*ai.Message{
      {Content: []*ai.Part{ai.NewTextPart("Tell me a joke about dogs.")}},
  },
  Config: ai.GenerationCommonConfig{
      Temperature:     1.67,
      StopSequences:   []string{"abc"},
      MaxOutputTokens: 3,
  },
}

Respostas de streaming

O Genkit é compatível com streaming em partes de respostas de modelo:

Go

Para usar o streaming em partes, transmita uma função de callback para Generate():

request := ai.GenerateRequest{Messages: []*ai.Message{
  {Content: []*ai.Part{ai.NewTextPart("Tell a long story about robots and ninjas.")}},
}}
response, err := gemini15pro.Generate(
  ctx,
  &request,
  func(ctx context.Context, grc *ai.GenerateResponseChunk) error {
      text, err := grc.Text()
      if err != nil {
          return err
      }
      fmt.Printf("Chunk: %s\n", text)
      return nil
  })
if err != nil {
  return err
}

// You can also still get the full response.
responseText, err := response.Text()
if err != nil {
  return err
}
fmt.Println(responseText)

Entrada multimodal

Se o modelo oferecer suporte à entrada multimodal, é possível transmitir comandos de imagem:

Go

imageBytes, err := os.ReadFile("img.jpg")
if err != nil {
  return err
}
encodedImage := base64.StdEncoding.EncodeToString(imageBytes)

request := ai.GenerateRequest{Messages: []*ai.Message{
  {Content: []*ai.Part{
      ai.NewTextPart("Describe the following image."),
      ai.NewMediaPart("", "data:image/jpeg;base64,"+encodedImage),
  }},
}}
gemini15pro.Generate(ctx, &request, nil)

O formato exato do comando de imagem (URL de https, URL gs, URI de data) é dependente do modelo.

Chamada de função (ferramentas)

Os modelos Genkit oferecem uma interface para chamada de função, para modelos que oferecem suporte reimplantá-lo.

Go

myJoke := &ai.ToolDefinition{
  Name:        "myJoke",
  Description: "useful when you need a joke to tell",
  InputSchema: make(map[string]any),
  OutputSchema: map[string]any{
      "joke": "string",
  },
}
ai.DefineTool(
  myJoke,
  nil,
  func(ctx context.Context, input map[string]any) (map[string]any, error) {
      return map[string]any{"joke": "haha Just kidding no joke! got you"}, nil
  },
)

request := ai.GenerateRequest{
  Messages: []*ai.Message{
      {Content: []*ai.Part{ai.NewTextPart("Tell me a joke.")},
          Role: ai.RoleUser},
  },
  Tools: []*ai.ToolDefinition{myJoke},
}
response, err := gemini15pro.Generate(ctx, &request, nil)

Isso vai chamar automaticamente as ferramentas para atender ao comando do usuário.

Gravando histórico de mensagens

Os modelos Genkit oferecem suporte à manutenção de um histórico das mensagens enviadas ao modelo e suas respostas, que podem ser usadas para construir experiências interativas, como chatbots.

Go

No primeiro comando de uma sessão, o "histórico" é simplesmente o prompt do usuário:

history := []*ai.Message{{
  	Content: []*ai.Part{ai.NewTextPart(prompt)},
  	Role:    ai.RoleUser,
  }}

request := ai.GenerateRequest{Messages: history}
response, err := gemini15pro.Generate(context.Background(), &request, nil)

Quando você receber uma resposta, adicione-a ao histórico:

history = append(history, response.Candidates[0].Message)

É possível serializar esse histórico e mantê-lo em um armazenamento de sessão ou banco de dados. Adicione as próximas solicitações do usuário ao histórico antes de ligar. Generate():

history = append(history, &ai.Message{
  Content: []*ai.Part{ai.NewTextPart(prompt)},
  Role:    ai.RoleUser,
})

request = ai.GenerateRequest{Messages: history}
response, err = gemini15pro.Generate(ctx, &request, nil)

Se o modelo que você está usando for compatível com o papel do sistema, será possível usar a histórico para definir a mensagem do sistema:

Go

history = []*ai.Message{{
  	Content: []*ai.Part{ai.NewTextPart("Talk like a pirate.")},
  	Role:    ai.RoleSystem,
  }}