教程:Gemini API 使用入门


本教程演示了如何使用 Google AI Go SDK 访问适用于 Go 应用的 Gemini API。

在本教程中,您将了解如何执行以下操作:

此外,本教程还包含一些有关高级用例(如嵌入令牌计数)以及控制内容生成的选项。

前提条件

本教程假定您熟悉使用 Go 构建应用。

如需完成本教程,请确保您的开发环境满足以下要求:

  • Go 1.20 及更高版本

设置项目

在调用 Gemini API 之前,您需要设置项目,其中包括设置 API 密钥、安装 SDK 软件包和初始化模型。

设置您的 API 密钥

如需使用 Gemini API,您需要 API 密钥。如果您还没有密钥,请在 Google AI Studio 中创建一个。

获取 API 密钥

保护您的 API 密钥

强烈建议您不要将 API 密钥签入版本控制系统。相反,您应该为 API 密钥使用 Secret 存储区。

本教程中的所有代码段均假定您将 API 密钥作为环境变量进行访问。

安装 SDK 软件包

如需在您自己的应用中使用 Gemini API,您需要在模块目录中对 Go SDK 软件包执行 get 操作:

go get github.com/google/generative-ai-go

初始化生成模型

您需要先导入并初始化生成模型,然后才能进行任何 API 调用。

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")

指定模型时,请注意以下事项:

  • 请使用您的用例专用的模型(例如,gemini-1.5-flash 用于多模态输入)。在本指南中,每种实现的说明列出了每种用例的推荐模型。

实现常见使用场景

现在您的项目已设置完毕,您可以探索如何使用 Gemini API 来实现不同的用例:

在“高级用例”部分,您可以找到有关 Gemini API 和嵌入的信息。

根据纯文本输入生成文本

当提示输入仅包含文本时,请使用 Gemini 1.5 模型或带有 generateContent 的 Gemini 1.0 Pro 模型生成文本输出:

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

根据文本和图片输入生成文本(多模态)

Gemini 提供了多种可处理多模态输入的模型(Gemini 1.5 模型),让您可以输入文字和图片。请务必查看提示的图片要求

当提示输入同时包含文本和图片时,结合使用 Gemini 1.5 模型和 generateContent 方法来生成文本输出:

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

建立多轮对话(聊天)

借助 Gemini,您可以跨多个回合构建自由形式的对话。该 SDK 通过管理对话状态来简化该过程,因此与 GenerateContent 不同,您无需自行存储对话历史记录。

如需构建多轮对话(如聊天),请使用 Gemini 1.5 模型或 Gemini 1.0 Pro 模型,并通过调用 startChat() 初始化对话。然后,使用 sendMessage() 发送一条新的用户消息,此消息也会将此消息和响应附加到聊天记录。

与对话内容相关联的 role 有两种可能的选项:

  • user:提供提示的角色。这是 SendMessage 调用的默认值。

  • model:提供响应的角色。使用现有的 history 调用 StartChat() 时,可以使用此角色。

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

使用流式传输加快互动速度

默认情况下,模型会在完成整个生成过程后返回响应。通过不等待整个结果,您可以实现更快的互动,而是使用流式传输来处理部分结果。

以下示例展示了如何使用 GenerateContentStream 方法实现流式传输,以根据文本和图片输入提示生成文本。

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
}

对于纯文本输入和聊天用例,您可以使用类似的方法。

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)

实现高级用例

本教程上一部分中介绍的常见用例可帮助您熟悉 Gemini API 的使用。本部分介绍了一些可能被视为更高级的用例。

使用嵌入

嵌入是一种用于将信息表示为数组中的浮点数列表的技术。借助 Gemini,您能够以矢量化形式表示文本(字词、句子和文本块),从而更轻松地比较和对比嵌入。例如,主题或情感相似的两个文本应该具有相似的嵌入,这些嵌入可以通过余弦相似度等数学比较技术来识别。

结合使用 embedding-001 模型和 EmbedContent 方法(或 BatchEmbedContent 方法)生成嵌入。以下示例为单个字符串生成嵌入:

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)

调用函数

函数调用可让您更轻松地从生成模型获取结构化数据输出。然后,您可以使用这些输出来调用其他 API,并将相关响应数据返回给模型。换句话说,函数调用可帮助您将生成模型连接到外部系统,以便生成的内容包含最新且准确的信息。如需了解详情,请参阅函数调用教程

计算词元数量

使用长提示时,在向模型发送任何内容之前统计词元数量可能会很有用。以下示例展示了如何针对各种用例使用 CountTokens()

// 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)

用于控制内容生成的选项

您可以通过配置模型参数和使用安全设置来控制内容生成。

配置模型参数

您发送到模型的每个提示都包含参数值,用于控制模型如何生成回答。对于不同的参数值,模型会生成不同的结果。详细了解模型参数。配置会在模型实例的生命周期内保留。

// ...

// 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)

// ...

使用安全设置

您可以使用安全设置来调整获得可能被视为有害响应的可能性。默认情况下,安全设置会在所有维度上屏蔽不安全内容的中等和/或高概率。详细了解安全设置

设置一项安全设置的方法如下:

// ...

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

// ...

您还可以设定多项安全设置:

// ...

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

// ...

后续步骤

  • 提示设计是创建提示以从语言模型引出所需回复的过程。撰写结构合理的提示是确保语言模型做出准确优质响应的重要环节。了解提示撰写的最佳做法

  • Gemini 提供多种模型变体,以满足不同应用场景的需求,例如输入类型和复杂程度、聊天或其他对话语言任务的实现以及大小限制。不妨了解可用的 Gemini 模型