Neste tutorial, demonstramos como acessar a API Gemini para seu aplicativo Go usando o SDK da IA do Google para Go.
Neste tutorial, você aprenderá a fazer o seguinte:
- Configurar seu projeto, incluindo a chave de API
- Gerar texto com base em uma entrada somente de texto
- Gerar texto com base em entradas de texto e imagem (multimodal)
- Criar conversas em várias interações (chat)
- Usar o streaming para interações mais rápidas
Além disso, este tutorial contém seções sobre casos de uso avançados (como embeddings e tokens de contagem), bem como opções para controlar a geração de conteúdo.
Pré-requisitos
Para acompanhar este tutorial, você precisa estar familiarizado com a criação de aplicativos em Go.
Para concluir este tutorial, verifique se o ambiente de desenvolvimento atende aos seguintes requisitos:
- Go 1.20 ou superior
Configurar seu projeto
Antes de chamar a API Gemini, você precisa configurar seu projeto, o que inclui configurar sua chave de API, instalar o pacote do SDK e inicializar o modelo.
Configurar sua chave de API
Para usar a API Gemini, você precisa de uma chave de API. Se você ainda não tiver uma, crie uma chave no Google AI Studio.
Proteger sua chave de API
É altamente recomendável não fazer a verificação de uma chave de API no sistema de controle de versões. Em vez disso, use um armazenamento de secrets para a chave de API.
Em todos os snippets deste tutorial, supomos que você esteja acessando sua chave de API como uma variável de ambiente.
Instalar o pacote do SDK
Para usar a API Gemini no seu aplicativo, você precisa get
o pacote do SDK do Go
no seu diretório de módulos:
go get github.com/google/generative-ai-go
Inicializar o modelo generativo
Antes de fazer qualquer chamada de API, é preciso importar e inicializar o modelo generativo.
import "github.com/google/generative-ai-go/genai"
import "google.golang.org/api/option"
ctx := context.Background()
// Access your API key as an environment variable (see "Set up your API key" above)
client, err := genai.NewClient(ctx, option.WithAPIKey(os.Getenv("API_KEY")))
if err != nil {
log.Fatal(err)
}
defer client.Close()
// The Gemini 1.5 models are versatile and work with most use cases
model := client.GenerativeModel("gemini-1.5-flash")
Ao especificar um modelo, observe o seguinte:
Use um modelo específico para seu caso de uso (por exemplo,
gemini-1.5-flash
é para entrada multimodal). Neste guia, as instruções para cada implementação listam o modelo recomendado para cada caso de uso.
Implemente casos de uso comuns
Agora que seu projeto está configurado, é possível usar a API Gemini para implementar diferentes casos de uso:
- Gerar texto com base em uma entrada somente de texto
- Gerar texto com base em entradas de texto e imagem (multimodal)
- Criar conversas em várias interações (chat)
- Usar o streaming para interações mais rápidas
Na seção de casos de uso avançados, você encontra informações sobre a API Gemini e embeddings.
Gerar texto com base em uma entrada somente de texto
Quando a entrada do comando incluir apenas texto, use um modelo Gemini 1.5 ou
Gemini 1.0 Pro com generateContent
para gerar a saída de texto:
ctx := context.Background()
// Access your API key as an environment variable (see "Set up your API key" above)
client, err := genai.NewClient(ctx, option.WithAPIKey(os.Getenv("API_KEY")))
if err != nil {
log.Fatal(err)
}
defer client.Close()
// The Gemini 1.5 models are versatile and work with both text-only and multimodal prompts
model := client.GenerativeModel("gemini-1.5-flash")
resp, err := model.GenerateContent(ctx, genai.Text("Write a story about a magic backpack."))
if err != nil {
log.Fatal(err)
}
Gerar texto com base em entradas de texto e imagem (multimodal)
O Gemini oferece vários modelos que lidam com entradas multimodais (modelos Gemini 1.5) para que você insira texto e imagens. Confira os requisitos de imagem para comandos.
Quando a entrada do comando incluir texto e imagens, use um modelo Gemini 1.5
com o método generateContent
para gerar a saída de texto:
ctx := context.Background()
// Access your API key as an environment variable (see "Set up your API key" above)
client, err := genai.NewClient(ctx, option.WithAPIKey(os.Getenv("API_KEY")))
if err != nil {
log.Fatal(err)
}
defer client.Close()
// The Gemini 1.5 models are versatile and work with both text-only and multimodal prompts
model := client.GenerativeModel("gemini-1.5-flash")
imgData1, err := os.ReadFile(pathToImage1)
if err != nil {
log.Fatal(err)
}
imgData2, err := os.ReadFile(pathToImage1)
if err != nil {
log.Fatal(err)
}
prompt := []genai.Part{
genai.ImageData("jpeg", imgData1),
genai.ImageData("jpeg", imgData2),
genai.Text("What's different between these two pictures?"),
}
resp, err := model.GenerateContent(ctx, prompt...)
if err != nil {
log.Fatal(err)
}
Criar conversas de várias interações (chat)
Com o Gemini, você pode criar conversas em formato livre em vários turnos. O
SDK simplifica o processo gerenciando o estado da conversa. Portanto, diferentemente de
GenerateContent
, não é necessário armazenar o histórico
de conversas.
Para criar uma conversa de vários turnos (como um chat), use um modelo Gemini 1.5 ou
Gemini 1.0 Pro e inicialize a conversa chamando startChat()
.
Em seguida, use sendMessage()
para enviar uma nova mensagem de usuário, que também anexará a mensagem e a resposta ao histórico de chat.
Há duas opções possíveis para role
associados ao conteúdo em uma
conversa:
user
: o papel que fornece os comandos. Esse valor é o padrão para chamadasSendMessage
.model
: o papel que fornece as respostas. Esse papel pode ser usado ao chamarStartChat()
comhistory
.
ctx := context.Background()
// Access your API key as an environment variable (see "Set up your API key" above)
client, err := genai.NewClient(ctx, option.WithAPIKey(os.Getenv("API_KEY")))
if err != nil {
log.Fatal(err)
}
defer client.Close()
// The Gemini 1.5 models are versatile and work with multi-turn conversations (like chat)
model := client.GenerativeModel("gemini-1.5-flash")
// Initialize the chat
cs := model.StartChat()
cs.History = []*genai.Content{
&genai.Content{
Parts: []genai.Part{
genai.Text("Hello, I have 2 dogs in my house."),
},
Role: "user",
},
&genai.Content{
Parts: []genai.Part{
genai.Text("Great to meet you. What would you like to know?"),
},
Role: "model",
},
}
resp, err := cs.SendMessage(ctx, genai.Text("How many paws are in my house?"))
if err != nil {
log.Fatal(err)
}
Use o streaming para interações mais rápidas
Por padrão, o modelo retorna uma resposta após concluir todo o processo de geração. Para ter interações mais rápidas, não espere o resultado todo e, em vez disso, use o streaming para processar resultados parciais.
O exemplo a seguir mostra como implementar o streaming com o
método GenerateContentStream
para gerar texto com base em um prompt de entrada de texto
e imagem.
ctx := context.Background()
// Access your API key as an environment variable (see "Set up your API key" above)
client, err := genai.NewClient(ctx, option.WithAPIKey(os.Getenv("API_KEY")))
if err != nil {
log.Fatal(err)
}
defer client.Close()
// The Gemini 1.5 models are versatile and work with both text-only and multimodal prompts
model := client.GenerativeModel("gemini-1.5-flash")
imageBytes, err := os.ReadFile(pathToImage)
img := genai.ImageData("jpeg", imageBytes)
prompt := genai.Text("Tell me a story about this animal")
iter := model.GenerateContentStream(ctx, img, prompt)
for {
resp, err := iter.Next()
if err == iterator.Done {
break
}
if err != nil {
log.Fatal(err)
}
// ... print resp
}
Você pode usar uma abordagem semelhante para casos de uso de entrada somente de texto e chat.
prompt := genai.Text("Tell me a story about a lumberjack and his giant ox")
iter := model.GenerateContentStream(ctx, prompt)
prompt := genai.Text("And how do you feel about that?")
iter := cs.SendMessageStream(ctx, prompt)
Implementar casos de uso avançados
Os casos de uso comuns descritos na seção anterior deste tutorial ajudam você a se familiarizar com o uso da API Gemini. Esta seção descreve alguns casos de uso que podem ser considerados mais avançados.
Usar embeddings
Embedding é uma técnica usada para representar informações como uma lista de números de ponto flutuante em uma matriz. Com o Gemini, é possível representar textos (palavras, frases e blocos de texto) em forma vetorial, facilitando a comparação e o contraste de embeddings. Por exemplo, dois textos que compartilham um assunto ou sentimento semelhante precisam ter embeddings semelhantes, que podem ser identificados por meio de técnicas de comparação matemática, como a semelhança de cossenos.
Use o modelo embedding-001
com o método EmbedContent
(ou o método BatchEmbedContent
) para gerar embeddings. O exemplo abaixo
gera um embedding para uma única string:
ctx := context.Background()
// Access your API key as an environment variable (see "Set up your API key" above)
client, err := genai.NewClient(ctx, option.WithAPIKey(os.Getenv("API_KEY")))
if err != nil {
log.Fatal(err)
}
defer client.Close()
// For embeddings, use the embedding-001 model
em := client.EmbeddingModel("embedding-001")
res, err := em.EmbedContent(ctx, genai.Text("The quick brown fox jumps over the lazy dog."))
if err != nil {
panic(err)
}
fmt.Println(res.Embedding.Values)
Chamadas de função
A chamada de função facilita a geração de saídas de dados estruturados de modelos generativos. Depois, use essas saídas para chamar outras APIs e retornar os dados de resposta relevantes ao modelo. Em outras palavras, a chamada de função ajuda você a conectar modelos generativos a sistemas externos, para que o conteúdo gerado inclua as informações mais atualizadas e precisas. Saiba mais no tutorial sobre chamada de função.
Contar tokens
Ao usar prompts longos, pode ser útil contar os tokens antes de enviar qualquer conteúdo para o modelo. Os exemplos abaixo mostram como usar CountTokens()
em vários casos de uso:
// For text-only input
text := "Parrots can be green and live a long time."
resp, err := model.CountTokens(ctx, genai.Text(text))
if err != nil {
log.Fatal(err)
}
fmt.Println(resp.TotalTokens)
// For text-and-image input (multimodal)
text := "Parrots can be green and live a long time."
imageBytes, err := os.ReadFile(pathToImage)
if err != nil {
log.Fatal(err)
}
resp, err := model.CountTokens(
ctx,
genai.Text(text),
genai.ImageData("png", imageBytes))
if err != nil {
log.Fatal(err)
}
fmt.Println(resp.TotalTokens)
Opções para controlar a geração de conteúdo
É possível controlar a geração de conteúdo definindo parâmetros do modelo e usando as configurações de segurança.
Configurar parâmetros do modelo
Cada comando que você envia ao modelo inclui valores de parâmetro que controlam como o modelo gera uma resposta. O modelo pode gerar diferentes resultados para diferentes valores de parâmetros. Saiba mais sobre os parâmetros do modelo. A configuração é mantida durante todo o ciclo de vida da instância do modelo.
// ...
// The Gemini 1.5 models are versatile and work with most use cases
model := client.GenerativeModel("gemini-1.5-flash")
// Configure model parameters by invoking Set* methods on the model.
model.SetTemperature(0.9)
model.SetTopK(1)
// ...
Usar as configurações de segurança
Use as configurações de segurança para ajustar a probabilidade de receber respostas que possam ser consideradas prejudiciais. Por padrão, as configurações de segurança bloqueiam conteúdo com probabilidade média e/ou alta de não ser seguro em todas as dimensões. Saiba mais sobre as Configurações de segurança.
Veja como definir uma configuração de segurança:
// ...
// The Gemini 1.5 models are versatile and work with most use cases
model := client.GenerativeModel("gemini-1.5-flash")
model.SafetySettings = []*genai.SafetySetting{
{
Category: genai.HarmCategoryHarassment,
Threshold: genai.HarmBlockOnlyHigh,
},
}
// ...
Também é possível definir mais de uma configuração de segurança:
// ...
// The Gemini 1.5 models are versatile and work with most use cases
model := client.GenerativeModel("gemini-1.5-flash")
model.SafetySettings = []*genai.SafetySetting{
{
Category: genai.HarmCategoryHarassment,
Threshold: genai.HarmBlockOnlyHigh,
},
{
Category: genai.HarmCategoryHateSpeech,
Threshold: genai.HarmBlockMediumAndAbove,
},
}
// ...
A seguir
Design de prompt é o processo de criação de prompts que extraem a resposta desejada dos modelos de linguagem. Escrever solicitações bem estruturadas é uma parte essencial para garantir respostas precisas e de alta qualidade de um modelo de linguagem. Saiba mais sobre as práticas recomendadas para a criação de comandos.
O Gemini oferece diversas variações de modelo para atender às necessidades de diferentes casos de uso, como tipos de entrada e complexidade, implementações para chat ou outras tarefas de linguagem de caixas de diálogo e restrições de tamanho. Saiba mais sobre os modelos do Gemini disponíveis.