Google GenAI 聊天
Google GenAI API 允许开发者通过 Gemini Developer API 或 Vertex AI,使用 Google 的 Gemini 模型构建生成式 AI 应用。Google GenAI API 支持多模态提示作为输入,并输出文本或代码。多模态模型能够处理来自多种模态的信息,包括图像、视频和文本。例如,你可以向模型发送一张饼干盘的照片,并要求它提供制作该饼干的配方。
Gemini 是 Google DeepMind 开发的一系列生成式 AI 模型,专为多模态用例设计。Gemini API 可让你访问 多种模型,如 Gemini Flash-Lite、Gemini Flash 或 Gemini Pro。
该实现提供两种身份验证模式:
- Gemini Developer API:使用 API 密钥进行快速原型设计和开发
- Vertex AI:使用 Google Cloud 凭证进行具备企业级功能的生产部署
先决条件
选择以下一种认证方式:
选项 1:Gemini Developer API(API Key)
-
从 Google AI Studio 获取一个 API key
-
将 API key 设置为环境变量,或在应用程序属性中配置
选项 2:Vertex AI(Google Cloud)
-
安装适合你操作系统的 gcloud 命令行工具。
-
运行以下命令进行身份验证。将
PROJECT_ID替换为你的 Google Cloud 项目 ID,将ACCOUNT替换为你的 Google Cloud 用户名。
gcloud config set project <PROJECT_ID> &&
gcloud auth application-default login <ACCOUNT>
自动配置
Spring AI 自动配置和启动器模块的制品名称发生了重大变更。更多信息请参阅升级说明。
Spring AI 为 Google GenAI Chat Client 提供了 Spring Boot 自动配置。要启用它,请将以下依赖项添加到项目的 Maven pom.xml 或 Gradle build.gradle 构建文件中:
- Maven
- Gradle
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-google-genai</artifactId>
</dependency>
dependencies {
implementation 'org.springframework.ai:spring-ai-starter-model-google-genai'
}
请参阅 依赖管理 部分,以在构建文件中添加 Spring AI BOM。
聊天属性
启用和禁用聊天自动配置现在通过以 spring.ai.model.chat 为前缀的顶层属性进行配置。
要启用,设置 spring.ai.model.chat=google-genai(默认情况下已启用)。
要禁用,设置 spring.ai.model.chat=none(或任何不匹配 google-genai 的值)。
此更改旨在支持多个模型的配置。
连接属性
前缀 spring.ai.google.genai 用作属性前缀,用于连接 Google GenAI。
| 属性 | 说明 | 默认值 |
|---|---|---|
| spring.ai.model.chat | 启用 Chat Model 客户端 | google-genai |
| spring.ai.google.genai.api-key | Gemini Developer API 的 API 密钥。提供后,客户端将使用 Gemini Developer API 而非 Vertex AI。 | - |
| spring.ai.google.genai.project-id | Google Cloud Platform 项目 ID(Vertex AI 模式下必需) | - |
| spring.ai.google.genai.location | Google Cloud 区域(Vertex AI 模式下必需) | - |
| spring.ai.google.genai.credentials-uri | 指向 Google Cloud 凭证的 URI。提供后将用于创建用于身份验证的 GoogleCredentials 实例。 | - |
聊天模型属性
前缀 spring.ai.google.genai.chat 是用于配置 Google GenAI Chat 聊天模型实现的属性前缀。
| 属性 | 描述 | 默认 |
|---|---|---|
| spring.ai.google.genai.chat.model | 支持的 Google GenAI Chat models(Gemini API 文档)包括 gemini-2.5-flash、gemini-2.5-flash-lite、gemini-2.5-pro、gemini-3.1-pro-preview、gemini-3.1-flash-lite 和 gemini-3.5-flash。 | gemini-2.5-flash |
| spring.ai.google.genai.chat.response-mime-type | 生成的候选文本的输出响应 MIME 类型。 | text/plain: (default) Text output or application/json: JSON response. |
| spring.ai.google.genai.chat.google-search-retrieval | 使用 Google 搜索 Grounding 功能 | true or false, default false. |
| spring.ai.google.genai.chat.include-server-side-tool-invocations | 当值为 true 时,API 响应将在响应元数据中包含服务端工具调用及响应(例如 Google Search 的调用),从而允许观察服务器的工具使用情况。此功能仅适用于 Gemini Developer API (MLDev),不支持 Vertex AI。参见 Server-Side Tool Invocations。 | false |
| spring.ai.google.genai.chat.temperature | 控制输出的随机性。取值范围为 [0.0, 1.0](包含端点)。取值越接近 1.0,生成的回复越发散多样;取值越接近 0.0,生成的回复通常越具有一致性和可预测性。 | - |
| spring.ai.google.genai.chat.top-k | 采样时考虑的最大令牌(token)数量。生成过程采用联合的 Top-k 与核采样(nucleus sampling)方法。Top-k 采样考虑概率最高的 topK 个令牌。 | - |
| spring.ai.google.genai.chat.top-p | 采样时考虑的最大累积 token 概率。生成模型使用 Top-k 和 nucleus 采样的组合。Nucleus 采样会选择概率之和至少为 topP 的最小 token 集合。 | - |
| spring.ai.google.genai.chat.candidate-count | 要返回的生成响应消息的数量。该值必须在 [1, 8] 范围内(含边界值)。默认为 1。 | 1 |
| spring.ai.google.genai.chat.max-output-tokens | 要生成的最大令牌数。 | - |
| spring.ai.google.genai.chat.frequency-penalty | 用于减少重复的频次惩罚。 | - |
| spring.ai.google.genai.chat.presence-penalty | 存在惩罚以降低重复。 | - |
| spring.ai.google.genai.chat.thinking-budget | 思考过程的思考预算。参见思考配置。 | - |
| spring.ai.google.genai.chat.thinking-level | 模型应生成的思考 Token 级别。有效值:LOW、HIGH、THINKING_LEVEL_UNSPECIFIED。详见 Thinking Configuration。 | - |
| spring.ai.google.genai.chat.include-thoughts | 启用函数调用时的思考签名。对于 Gemini 3 Pro,这是必需的,以避免在工具调用循环中出现验证错误。请参阅思考签名。 | false |
| spring.ai.google.genai.chat.tool-callbacks | 与 ChatModel 注册的 Tool Callbacks。 | - |
| spring.ai.google.genai.chat.safety-settings | 由Google GenAI Safety Settings 定义的一组安全设置,用于控制安全过滤器。每个安全设置可以具有 method、threshold 和 category。 | - |
| spring.ai.google.genai.chat.cached-content-name | 用于此请求的缓存内容名称。当与 use-cached-content=true 一起设置时,缓存内容将作为上下文使用。参见 缓存内容。 | - |
| spring.ai.google.genai.chat.use-cached-content | 是否使用缓存内容(如果可用)。当值为 true 且 cached-content-name 已设置时,系统将使用缓存内容。 | false |
| spring.ai.google.genai.chat.auto-cache-threshold | 自动缓存超出此令牌阈值的提示。设置后,大于该值的提示将被自动缓存以供复用。设置为 null 以禁用自动缓存。 | - |
| spring.ai.google.genai.chat.auto-cache-ttl | 自动缓存内容的生存时间(持续时间),采用 ISO-8601 格式(例如,PT1H 表示 1 小时)。在启用自动缓存时使用。 | PT1H |
| spring.ai.google.genai.chat.enable-cached-content | 启用 GoogleGenAiCachedContentService Bean 以管理缓存内容。 | true |
| spring.ai.google.genai.chat.service-tier | 用于请求的服务层级。有效值:STANDARD、PRIORITY、FLEX。 | - |
| spring.ai.google.genai.chat.tool-choice.mode | 控制当提供工具时,模型如何选择函数。有效值:AUTO(由模型决定)、ANY(始终调用函数)、VALIDATED(调用函数或使用自然语言)、NONE(不调用函数)。参见 Tool Choice。 | - |
| spring.ai.google.genai.chat.tool-choice.allowed-function-names | 模型可调用的函数名的逗号分隔列表。仅当 tool-choice.mode 为 ANY 或 VALIDATED 时生效;其他模式下将被忽略。 | - |
所有以 spring.ai.google.genai.chat 为前缀的属性,都可以通过在 Prompt 调用中添加特定的 Runtime options 来在运行时进行覆盖。
运行时选项
GoogleGenAiChatOptions.java 提供了模型配置,例如 temperature、topK 等。
在启动时,默认选项可以通过 GoogleGenAiChatModel(client, options) 构造函数或 spring.ai.google.genai.chat.* 属性进行配置。
在运行时,你可以向 Prompt 调用添加新的、请求特有的选项来覆盖默认选项。例如,要为某个特定请求覆盖默认的温度参数:
ChatResponse response = chatModel.call(
new Prompt(
"Generate the names of 5 famous pirates.",
GoogleGenAiChatOptions.builder()
.temperature(0.4)
.build()
));
除了模型特定的 GoogleGenAiChatOptions,你还可以使用一个可移植的 ChatOptions 实例,该实例可通过 ChatOptions#builder() 创建。
工具调用
GoogleGenAiChatModel 支持工具调用。模型可以请求执行工具,但本身不会运行工具 —— Spring AI 负责处理执行。
对于大多数应用,请使用 ChatClient 搭配自动注册的 ToolCallingAdvisor——参见 Tool Calling。如需低级控制并自行驱动循环,请参见 ChatModel Tool Calling。
有关 Google 内置工具(搜索、地图、URL 上下文)以及如何将它们与客户端函数调用结合使用,请参见下文中的 服务器端工具调用。
工具选择
GoogleGenAiChatOptions.ToolChoice 配置在提供工具时,模型如何选择函数。它对应 Google GenAI 的 FunctionCallingConfig。
| 模式 | 行为 |
|---|---|
AUTO | 模型决定是调用函数还是返回自然语言响应(默认行为)。 |
ANY | 模型始终预测为函数调用。当设置了 allowedFunctionNames 时,调用仅限于这些函数。 |
VALIDATED | 模型可以调用函数或返回自然语言响应。当设置了 allowedFunctionNames 时,调用仅限于这些函数。 |
NONE | 模型不调用任何函数,仅返回自然语言响应。 |
allowedFunctionNames 仅在模式为 ANY 或 VALIDATED 时生效,对于 AUTO 和 NONE 会被静默忽略。
编程配置
ChatResponse response = chatModel.call(
new Prompt(
"What is the weather in Paris?",
GoogleGenAiChatOptions.builder()
.toolChoice(new GoogleGenAiChatOptions.ToolChoice(
GoogleGenAiChatOptions.ToolChoice.Mode.ANY,
List.of("get_weather")))
.build()
));
要应用某种模式而不限制于特定函数:
GoogleGenAiChatOptions.builder()
.toolChoice(new GoogleGenAiChatOptions.ToolChoice(
GoogleGenAiChatOptions.ToolChoice.Mode.NONE, null))
.build();
基于属性的配置
# Force the model to always call a function
spring.ai.google.genai.chat.tool-choice.mode=ANY
# Optionally restrict to specific functions (only applies when mode is ANY or VALIDATED)
spring.ai.google.genai.chat.tool-choice.allowed-function-names=get_weather,get_forecast
或者在 YAML 中:
spring:
ai:
google:
genai:
chat:
tool-choice:
mode: ANY
allowed-function-names:
- get_weather
- get_forecast
服务端工具调用
当通过 googleSearchRetrieval(true) 启用 Google 搜索或其他服务器端工具时,模型会在服务器上执行这些工具。默认情况下,这些调用对客户不可见——你只能看到最终的文本响应。设置 includeServerSideToolInvocations(true) 后,API 会在响应内容中包含服务器的工具调用及其返回结果,从而使你可以观察模型搜索了什么内容以及获取了哪些结果。
此功能仅在 Gemini Developer API(MLDev / API 密钥认证)下受支持,在 Vertex AI 上不受支持。
配置
通过应用属性启用:
spring.ai.google.genai.chat.google-search-retrieval=true
spring.ai.google.genai.chat.include-server-side-tool-invocations=true
或是在运行时以编程方式进行:
ChatResponse response = chatModel.call(
new Prompt(
"What are the latest developments in quantum computing?",
GoogleGenAiChatOptions.builder()
.model("gemini-2.0-flash")
.googleSearchRetrieval(true)
.includeServerSideToolInvocations(true)
.build()
));
访问服务端工具调用元数据
启用后,响应消息元数据中的 serverSideToolInvocations 键下将包含服务器端工具调用:
ChatResponse response = chatModel.call(prompt);
Map<String, Object> metadata = response.getResult().getOutput().getMetadata();
List<Map<String, Object>> invocations =
(List<Map<String, Object>>) metadata.get("serverSideToolInvocations");
if (invocations != null) {
for (Map<String, Object> invocation : invocations) {
String type = (String) invocation.get("type"); // "toolCall" or "toolResponse"
String id = (String) invocation.get("id"); // Unique invocation ID
String toolType = (String) invocation.get("toolType"); // e.g., "GOOGLE_SEARCH_WEB"
if ("toolCall".equals(type)) {
Map<String, Object> args = (Map<String, Object>) invocation.get("args");
// Inspect what the model searched for
} else if ("toolResponse".equals(type)) {
Map<String, Object> responseData = (Map<String, Object>) invocation.get("response");
// Inspect what search results the model received
}
}
}
列表中的每一项包含:
| 字段 | 描述 |
|---|---|
type | "toolCall"(模型的调用请求)或 "toolResponse"(服务器的返回结果) |
id | 用于将 toolCall 与其对应的 toolResponse 关联起来的唯一标识符 |
toolType | 服务端工具的类型(例如:GOOGLE_SEARCH_WEB、GOOGLE_SEARCH_IMAGE、URL_CONTEXT、GOOGLE_MAPS) |
args | (仅适用于 toolCall)传递给工具的参数 |
response | (仅适用于 toolResponse)工具返回的结果 |
结合客户端工具调用
服务端工具调用可以与客户端工具调用协同工作。您可以在同一请求中同时启用 Google 搜索(服务端)和自定义工具(客户端):
ChatResponse response = chatModel.call(
new Prompt(
"What's the weather in San Francisco? Also search for the latest news about the city.",
GoogleGenAiChatOptions.builder()
.model("gemini-2.0-flash")
.googleSearchRetrieval(true)
.includeServerSideToolInvocations(true)
.toolCallbacks(List.of(
FunctionToolCallback.builder("get_current_weather", new WeatherService())
.description("Get the current weather in a given location")
.inputType(WeatherRequest.class)
.build()))
.build()
));
// The response contains:
// - Weather data from the client-side function call (executed locally)
// - Google Search invocations visible in metadata (executed server-side)
服务器端工具调用仅用于观察 —— 客户端不会执行它们。它们会单独在元数据中呈现,以区别于客户端函数调用,从而避免干扰工具执行循环。
Thinking Configuration
Gemini 模型支持“思维”能力,允许模型在生成响应前进行更深入的推理。该功能通过 ThinkingConfig 进行控制,其中包含三个相关选项:thinkingBudget、thinkingLevel 和 includeThoughts。
思维级别
thinkingLevel 选项控制模型生成的推理 token 深度。此选项适用于支持思维模式的模型(例如 Gemini 3 Pro Preview)。
| 值 | 描述 |
|---|---|
THINKING_LEVEL_UNSPECIFIED | 模型使用默认行为。 |
MINIMAL | 大多数查询下相当于“不思考”设置。最小化延迟。 |
LOW | 低思考。推理 token 最少。 |
MEDIUM | 适合大多数任务的平衡思考。 |
HIGH | 深度思考。适用于需要深入分析和逐步推理的复杂问题。 |
通过属性进行配置
spring.ai.google.genai.chat.model=gemini-3.1-pro-preview
spring.ai.google.genai.chat.thinking-level=HIGH
编程式配置
import org.springframework.ai.google.genai.common.GoogleGenAiThinkingLevel;
ChatResponse response = chatModel.call(
new Prompt(
"Explain the theory of relativity in simple terms.",
GoogleGenAiChatOptions.builder()
.model("gemini-3.1-pro-preview")
.thinkingLevel(GoogleGenAiThinkingLevel.HIGH)
.build()
));
思维预算
thinkingBudget 选项为思考过程设置一个令牌预算:
-
正值:用于思考的最大令牌数(例如
8192) -
零值(
0):完全禁用思考功能 -
未设置:模型根据查询复杂度自动决定
ChatResponse response = chatModel.call(
new Prompt(
"Solve this complex math problem step by step.",
GoogleGenAiChatOptions.builder()
.model("gemini-2.5-pro")
.thinkingBudget(8192)
.build()
));
选项兼容性
thinkingLevel 和 thinkingBudget 互斥。 你无法在同一个请求中同时使用两者——否则会导致 API 错误。
-
对于 Gemini 3.x 模型,请使用
thinkingLevel。Gemini 3 Pro 仅支持LOW和HIGH;Gemini 3 Flash 模型支持所有级别(MINIMAL、LOW、MEDIUM、HIGH)。 -
对于 Gemini 2.5 系列模型,请使用
thinkingBudget(token 数量)。
你可以将 includeThoughts 与 thinkingLevel 或 thinkingBudget 中的任意一个组合使用(但不能同时使用两者):
// For Gemini 3.x (e.g. Pro): use thinkingLevel + includeThoughts
ChatResponse response = chatModel.call(
new Prompt(
"Analyze this complex scenario.",
GoogleGenAiChatOptions.builder()
.model("gemini-3.1-pro-preview")
.thinkingLevel(GoogleGenAiThinkingLevel.HIGH)
.includeThoughts(true)
.build()
));
// For Gemini 2.5: use thinkingBudget + includeThoughts
ChatResponse response = chatModel.call(
new Prompt(
"Analyze this complex scenario.",
GoogleGenAiChatOptions.builder()
.model("gemini-2.5-pro")
.thinkingBudget(8192)
.includeThoughts(true)
.build()
));
模型支持
思维配置选项因模型而异:
| 模型 | 模型 ID | thinkingLevel | thinkingBudget | 备注 |
|---|---|---|---|---|
| Gemini 3 Pro Preview | gemini-3.1-pro-preview | ✅ 仅 LOW 和 HIGH | ⚠️ 仅向后兼容 | 使用 thinkingLevel。无法禁用思考。需要使用 global 端点。 |
| Gemini 3.5 Flash | gemini-3.5-flash | ✅ 所有级别 | ❌ 不支持 | 使用 thinkingLevel,支持包括 MINIMAL 和 MEDIUM 在内的任何级别。 |
| Gemini 3.1 Flash-Lite | gemini-3.1-flash-lite | ✅ 所有级别 | ❌ 不支持 | 使用 thinkingLevel,支持包括 MINIMAL 和 MEDIUM 在内的任何级别。 |
| Gemini 2.5 Pro | gemini-2.5-pro | ❌ 不支持 | ✅ 支持 | 使用 thinkingBudget。设置为 0 可禁用,-1 表示动态。 |
| Gemini 2.5 Flash | gemini-2.5-flash | ❌ 不支持 | ✅ 支持 | 使用 thinkingBudget。设置为 0 可禁用,-1 表示动态。 |
| Gemini 2.5 Flash-Lite | gemini-2.5-flash-lite | ❌ 不支持 | ✅ 支持 | 默认禁用思考。设置 thinkingBudget 以启用。 |
| Gemini 2.0 Flash | gemini-2.0-flash-001 | ❌ 不支持 | ❌ 不支持 | 不可用思考功能。 |
-
在对不支持该功能的模型(例如 Gemini 2.5 或更早版本)使用
thinkingLevel时,将导致 API 错误。 -
对 Gemini 3 Pro 模型使用
MINIMAL或MEDIUM时,将导致IllegalArgumentException。 -
Gemini 3 Pro Preview 仅在 global 端点上可用。请设置
spring.ai.google.genai.location=global或GOOGLE_CLOUD_LOCATION=global。 -
查阅 Google GenAI Thinking 文档 以了解最新的模型能力。
启用思考功能会增加 token 的使用量和 API 成本。请根据查询的复杂度适当使用。
思维签名
Gemini 3 Pro 引入了思考签名(thought signatures),这是一种不透明的字节数组,用于在函数调用过程中保留模型的推理上下文。当启用 includeThoughts 时,模型会返回思考签名,这些签名必须在工具调用循环的同一轮中回传。
当思想签名变得重要
重要:思考签名验证仅适用于当前轮次——具体而言,是在模型进行函数调用(包括并行调用和顺序调用)的工具调用循环期间。API 不会验证对话历史中先前轮次的思考签名。
根据谷歌的文档:
-
仅对当前回合内的函数调用执行验证
-
无需保留之前回合的签名
-
对于 Gemini 3 Pro,当前回合的函数调用中缺失签名将导致 HTTP 400 错误
-
对于并行函数调用,仅第一个
functionCall部分携带签名
对于 Gemini 2.5 Pro 及更早版本的模型,thought signatures 是可选的,且 API 较为宽松。
配置
使用配置属性启用思想签名:
spring.ai.google.genai.chat.model=gemini-3.1-pro-preview
spring.ai.google.genai.chat.include-thoughts=true
或通过在运行时以编程方式进行:
ChatResponse response = chatModel.call(
new Prompt(
"Your question here",
GoogleGenAiChatOptions.builder()
.model("gemini-3.1-pro-preview")
.includeThoughts(true)
.toolCallbacks(callbacks)
.build()
));
通过 ChatClient 自动处理(推荐)
在使用 ChatClient 搭配 ToolCallingAdvisor(推荐方式)时,Spring AI 会自动处理思维签名:
-
Extracts 模型响应中的思考签名
-
Attaches 在回传函数响应时将其正确附加到对应的
functionCall部分 -
Propagates 在单轮内的函数调用(包括并行和串行)中正确传播
@Bean
ToolCallback weatherFunction() {
return FunctionToolCallback.builder("weatherFunction", new WeatherService())
.description("Get the weather in a location")
.inputType(WeatherRequest.class)
.build();
}
// Enable includeThoughts for Gemini 3 Pro with function calling
String response = ChatClient.create(this.chatModel)
.prompt("What's the weather like in Boston?")
.options(GoogleGenAiChatOptions.builder()
.model("gemini-3.1-pro-preview")
.includeThoughts(true)
.build())
.tools(weatherFunction)
.call()
.content();
用户控制的工具执行与思考签名
在使用手动工具执行循环时,必须在对话历史中保留思考签名,即保留带有元数据的原始 AssistantMessage。Spring AI 在转换消息时会自动将签名附加到正确的 functionCall 部分。
手动执行工具并要求思考签名时的要求:
-
从响应元数据中提取思维签名(thought signatures):
AssistantMessage assistantMessage = response.getResult().getOutput();
Map<String, Object> metadata = assistantMessage.getMetadata();
List<byte[]> thoughtSignatures = (List<byte[]>) metadata.get("thoughtSignatures"); -
在回传函数响应时,请在消息历史中保留包含完整元数据的原始
AssistantMessage。Spring AI 会自动将思维签名附加到正确的functionCall部分。 -
对于 Gemini 3 Pro,如果未能保留当前轮次的思维签名,将导致 API 返回 HTTP 400 错误。
仅需对当前回合的函数调用保留思考签名。当开启新的对话回合(在完成一轮函数调用后)时,无需保留上一回合的签名。
启用 includeThoughts 会增加令牌使用量,因为思考过程将被包含在响应中。这会直接影响 API 成本,但能提供更好的推理透明度。
多模态
多模态是指模型能够同时理解和处理来自多种(输入)源的信息,包括 text、pdf、images、audio 以及其他数据格式。
图像、音频、视频
Google 的 Gemini AI 模型通过理解和整合文本、代码、音频、图像和视频来支持此功能。更多详情,请参见博客文章 Introducing Gemini。
Spring AI 的 Message 接口通过引入 Media 类型来支持多模态 AI 模型。该类型包含消息中媒体附件的数据和相关信息,使用 Spring 的 org.springframework.util.MimeType 以及用于原始媒体数据的 java.lang.Object。
以下是一个简单的代码示例,摘自 GoogleGenAiChatModelIT.java,展示了如何将用户文本与图像组合使用。
byte[] data = new ClassPathResource("/vertex-test.png").getContentAsByteArray();
var userMessage = UserMessage.builder()
.text("Explain what do you see o this picture?")
.media(List.of(new Media(MimeTypeUtils.IMAGE_PNG, data)))
.build();
ChatResponse response = chatModel.call(new Prompt(List.of(this.userMessage)));
PDF
Google GenAI 支持 PDF 输入类型。使用 application/pdf 媒体类型将 PDF 文件附加到消息中:
var pdfData = new ClassPathResource("/spring-ai-reference-overview.pdf");
var userMessage = UserMessage.builder()
.text("You are a very professional document summarization specialist. Please summarize the given document.")
.media(List.of(new Media(new MimeType("application", "pdf"), pdfData)))
.build();
var response = this.chatModel.call(new Prompt(List.of(userMessage)));
缓存内容
Google GenAI 的 Context Caching 允许你缓存大量内容(例如长文档、代码仓库或媒体),并在多次请求中复用它们。这可以显著降低 API 成本,并提升针对相同内容的重复查询的响应速度。
优势
- 成本降低:缓存 token 的计费远低于常规输入 token(通常便宜 75-90%)
- 性能提升:复用缓存内容可减少大上下文的处理时间
- 一致性:相同的缓存上下文可确保多次请求之间获得一致的响应
缓存要求
- 最小缓存大小:32,768 tokens(约 25,000 个单词)
- 最大缓存时长:默认 1 小时(可通过 TTL 配置)
- 缓存内容必须包含系统指令或对话历史
使用缓存内容服务
Spring AI 提供了 GoogleGenAiCachedContentService 以支持编程式缓存管理。在使用 Spring Boot 自动配置时,该服务会自动完成配置。
创建缓存内容
@Autowired
private GoogleGenAiCachedContentService cachedContentService;
// Create cached content with a large document
String largeDocument = "... your large context here (>32k tokens) ...";
CachedContentRequest request = CachedContentRequest.builder()
.model("gemini-2.5-flash")
.contents(List.of(
Content.builder()
.role("user")
.parts(List.of(Part.fromText(largeDocument)))
.build()
))
.displayName("My Large Document Cache")
.ttl(Duration.ofHours(1))
.build();
GoogleGenAiCachedContent cachedContent = cachedContentService.create(request);
String cacheName = cachedContent.getName(); // Save this for reuse
在聊天请求中使用缓存内容
创建缓存内容后,在聊天请求中引用它:
ChatResponse response = chatModel.call(
new Prompt(
"Summarize the key points from the document",
GoogleGenAiChatOptions.builder()
.useCachedContent(true)
.cachedContentName(cacheName) // Use the cached content name
.build()
));
或者通过配置属性:
spring.ai.google.genai.chat.use-cached-content=true
spring.ai.google.genai.chat.cached-content-name=cachedContent/your-cache-name
管理缓存内容
GoogleGenAiCachedContentService 提供全面的缓存管理:
// Retrieve cached content
GoogleGenAiCachedContent content = cachedContentService.get(cacheName);
// Update cache TTL
CachedContentUpdateRequest updateRequest = CachedContentUpdateRequest.builder()
.ttl(Duration.ofHours(2))
.build();
GoogleGenAiCachedContent updated = cachedContentService.update(cacheName, updateRequest);
// List all cached content
List<GoogleGenAiCachedContent> allCaches = cachedContentService.listAll();
// Delete cached content
boolean deleted = cachedContentService.delete(cacheName);
// Extend cache TTL
GoogleGenAiCachedContent extended = cachedContentService.extendTtl(cacheName, Duration.ofMinutes(30));
// Cleanup expired caches
int removedCount = cachedContentService.cleanupExpired();
异步操作
所有操作都有异步变体:
CompletableFuture<GoogleGenAiCachedContent> futureCache =
cachedContentService.createAsync(request);
CompletableFuture<GoogleGenAiCachedContent> futureGet =
cachedContentService.getAsync(cacheName);
CompletableFuture<Boolean> futureDelete =
cachedContentService.deleteAsync(cacheName);
自动缓存
当大型提示词超过指定的 token 阈值时,Spring AI 可以自动对其进行缓存:
# Automatically cache prompts larger than 100,000 tokens
spring.ai.google.genai.chat.auto-cache-threshold=100000
# Set auto-cache TTL to 1 hour
spring.ai.google.genai.chat.auto-cache-ttl=PT1H
或者通过编程方式:
ChatResponse response = chatModel.call(
new Prompt(
largePrompt,
GoogleGenAiChatOptions.builder()
.autoCacheThreshold(100000)
.autoCacheTtl(Duration.ofHours(1))
.build()
));
自动缓存适用于一次性的大上下文场景。对于重复使用相同上下文的情况,手动创建并引用缓存内容会更高效。
监控缓存使用情况
缓存内容包括可通过该服务访问的使用元数据:
GoogleGenAiCachedContent content = cachedContentService.get(cacheName);
// Check if cache is expired
boolean expired = content.isExpired();
// Get remaining TTL
Duration remaining = content.getRemainingTtl();
// Get usage metadata
CachedContentUsageMetadata metadata = content.getUsageMetadata();
if (metadata != null) {
System.out.println("Total tokens: " + metadata.totalTokenCount().orElse(0));
}
最佳实践
-
缓存生命周期:根据实际使用场景设置合适的 TTL(生存时间)。对于频繁变化的内容,建议使用较短的 TTL;对于静态内容,可使用较长的 TTL。
-
缓存命名:使用具有描述性的显示名称,以便轻松识别已缓存的内容。
-
清理:定期清理已过期的缓存,以保持系统整洁有序。
-
Token 阈值:仅缓存超过最低阈值(32,768 tokens)的内容。
-
成本优化:在多次请求中复用已缓存的内容,以最大化节约成本。
配置示例
完整配置示例:
# Enable cached content service (enabled by default)
spring.ai.google.genai.chat.enable-cached-content=true
# Use a specific cached content
spring.ai.google.genai.chat.use-cached-content=true
spring.ai.google.genai.chat.cached-content-name=cachedContent/my-cache-123
# Auto-caching configuration
spring.ai.google.genai.chat.auto-cache-threshold=50000
spring.ai.google.genai.chat.auto-cache-ttl=PT30M
示例控制器
创建 一个新的 Spring Boot 项目,并将 spring-ai-starter-model-google-genai 添加到你的 pom(或 gradle)依赖中。
在 src/main/resources 目录下添加 application.properties 文件,以启用并配置 Google GenAI 聊天模型:
使用 Gemini 开发者 API(API 密钥)
spring.ai.google.genai.api-key=YOUR_API_KEY
spring.ai.google.genai.chat.model=gemini-2.5-flash
spring.ai.google.genai.chat.temperature=0.5
使用 Vertex AI
spring.ai.google.genai.project-id=PROJECT_ID
spring.ai.google.genai.location=LOCATION
spring.ai.google.genai.chat.model=gemini-2.5-flash
spring.ai.google.genai.chat.temperature=0.5
将 project-id 替换为您的 Google Cloud 项目 ID,location 为 Google Cloud 区域,例如 us-central1、europe-west1 等…
每个模型都有各自支持的区域列表,你可以在模型页面查看支持的区域。
这将创建一个 GoogleGenAiChatModel 实现,您可以将其注入到类中。以下是一个简单的 @Controller 类示例,它使用聊天模型进行文本生成。
@RestController
public class ChatController {
private final GoogleGenAiChatModel chatModel;
@Autowired
public ChatController(GoogleGenAiChatModel chatModel) {
this.chatModel = chatModel;
}
@GetMapping("/ai/generate")
public Map generate(@RequestParam(value = "message", defaultValue = "Tell me a joke") String message) {
return Map.of("generation", this.chatModel.call(message));
}
@GetMapping("/ai/generateStream")
public Flux<ChatResponse> generateStream(@RequestParam(value = "message", defaultValue = "Tell me a joke") String message) {
Prompt prompt = new Prompt(new UserMessage(message));
return this.chatModel.stream(prompt);
}
}
手动配置
GoogleGenAiChatModel 实现了 ChatModel,并使用 com.google.genai.Client 连接 Google GenAI 服务。
在项目 Maven 的 pom.xml 文件中添加 spring-ai-google-genai 依赖:
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-google-genai</artifactId>
</dependency>
或添加到您的 Gradle build.gradle 构建文件中。
dependencies {
implementation 'org.springframework.ai:spring-ai-google-genai'
}
有关如何将 Spring AI BOM 添加到构建文件,请参阅依赖管理部分。
接下来,创建一个 GoogleGenAiChatModel 实例,并使用它进行文本生成:
使用 API 密钥
Client genAiClient = Client.builder()
.apiKey(System.getenv("GOOGLE_API_KEY"))
.build();
var chatModel = new GoogleGenAiChatModel(genAiClient,
GoogleGenAiChatOptions.builder()
.model(ChatModel.GEMINI_2_0_FLASH)
.temperature(0.4)
.build());
ChatResponse response = this.chatModel.call(
new Prompt("Generate the names of 5 famous pirates."));
使用 Vertex AI
Client genAiClient = Client.builder()
.project(System.getenv("GOOGLE_CLOUD_PROJECT"))
.location(System.getenv("GOOGLE_CLOUD_LOCATION"))
.vertexAI(true)
.build();
var chatModel = new GoogleGenAiChatModel(genAiClient,
GoogleGenAiChatOptions.builder()
.model(ChatModel.GEMINI_2_0_FLASH)
.temperature(0.4)
.build());
ChatResponse response = this.chatModel.call(
new Prompt("Generate the names of 5 famous pirates."));
GoogleGenAiChatOptions 提供聊天请求的配置信息。GoogleGenAiChatOptions.Builder 是一个流畅的配置构建器。
从 Vertex AI Gemini 迁移
如果您之前使用的是已被移除的 Vertex AI Gemini 实现(spring-ai-vertex-ai-gemini),请迁移到 Google GenAI:
主要区别:
-
SDK:Google GenAI 使用新的
com.google.genai.Client,而不是com.google.cloud.vertexai.VertexAI -
Authentication:同时支持 API key 和 Google Cloud 凭证(Vertex AI 模式)
-
Package Names:类位于
org.springframework.ai.google.genai中,而不是org.springframework.ai.vertexai.gemini -
Property Prefix:使用
spring.ai.google.genai前缀,而不是spring.ai.vertex.ai.gemini
Google GenAI 同时支持通过 API 密钥进行快速原型开发,以及使用 Google Cloud 凭据通过 Vertex AI 进行生产环境部署。
低层 Java 客户端
Google GenAI 实现基于全新的 Google GenAI Java SDK 构建,该 SDK 为访问 Gemini 模型提供了现代且简化的 API。