跳到主要内容

Google Vertex AI Gemini

Vertex AI 是 Google Cloud 的全托管 AI 开发平台,可访问 Google 的大型生成式模型,包括旧一代(PaLM2)和新一代(Gemini)。

要使用 Vertex AI,必须先创建 Google Cloud Platform 账户。

开始使用

创建 Google Cloud 账户

如果您是 Google Cloud 新用户,可以在以下页面的 Get set up on Google Cloud 下拉菜单下点击 [create an account] 按钮创建新账户:

创建账户

在 Google Cloud Platform 账户中创建项目

在您的 Google Cloud 账户中创建新项目并启用 Vertex AI API,请按以下步骤操作:

创建新项目

请记下您的 PROJECT_ID,后续 API 调用会用到。

选择 Google Cloud 身份验证策略

应用程序向 Google Cloud 服务和 API 进行身份验证有多种方式。例如,您可以创建服务账号,并将环境变量 GOOGLE_APPLICATION_CREDENTIALS 设置为包含凭据的 JSON 文件路径。

您可以在此处了解所有身份验证策略。但为简化本地测试,我们将使用通过 gcloud 工具进行身份验证。

安装 Google Cloud CLI(可选)

要在本地访问云项目,可按照安装说明安装 gcloud 工具。对于 GNU/Linux 操作系统,安装步骤如下:

  1. 下载 SDK:
curl -O https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/google-cloud-cli-467.0.0-linux-x86_64.tar.gz
  1. 解压归档文件:
tar -xf google-cloud-cli-467.0.0-linux-x86_64.tar.gz
  1. 运行安装脚本:
cd google-cloud-sdk/
./install.sh
  1. 运行以下命令设置默认项目和身份验证凭据:
gcloud auth application-default login

此身份验证方法同时兼容 vertex-ai(嵌入模型、PaLM2)和 vertex-ai-gemini(Gemini)包。

添加依赖

要开始使用,请将以下依赖添加到项目的 pom.xml

<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-vertex-ai-gemini</artifactId>
<version>1.18.1-beta28</version>
</dependency>

或项目的 build.gradle

implementation 'dev.langchain4j:langchain4j-vertex-ai-gemini:1.18.1-beta28'

试用示例代码:

用于文本预测的聊天模型示例

带图像输入的 Gemini Pro Vision

PROJECT_ID 字段表示您在创建新 Google Cloud 项目时设置的变量。

import dev.langchain4j.data.message.AiMessage;
import dev.langchain4j.data.message.ImageContent;
import dev.langchain4j.data.message.TextContent;
import dev.langchain4j.data.message.UserMessage;
import dev.langchain4j.model.chat.ChatModel;
import dev.langchain4j.model.output.Response;
import dev.langchain4j.model.vertexai.gemini.VertexAiGeminiChatModel;

public class GeminiProVisionWithImageInput {

private static final String PROJECT_ID = "YOUR-PROJECT-ID";
private static final String LOCATION = "us-central1";
private static final String MODEL_NAME = "gemini-1.5-flash";
private static final String CAT_IMAGE_URL = "https://upload.wikimedia.org/" +
"wikipedia/commons/e/e9/" +
"Felis_silvestris_silvestris_small_gradual_decrease_of_quality.png";

public static void main(String[] args) {
ChatModel visionModel = VertexAiGeminiChatModel.builder()
.project(PROJECT_ID)
.location(LOCATION)
.modelName(MODEL_NAME)
.build();

ChatResponse response = visionModel.chat(
UserMessage.from(
ImageContent.from(CAT_IMAGE_URL),
TextContent.from("What do you see?")
)
);

System.out.println(response.aiMessage().text());
}
}

借助 VertexAiGeminiStreamingChatModel 类也支持流式输出:

var model = VertexAiGeminiStreamingChatModel.builder()
.project(PROJECT_ID)
.location(LOCATION)
.modelName(GEMINI_1_5_PRO)
.build();

model.chat("Why is the sky blue?", new StreamingChatResponseHandler() {

@Override
public void onPartialResponse(String partialResponse) {
System.print(partialResponse);
}

@Override
public void onCompleteResponse(ChatResponse completeResponse){
System.print(completeResponse);
}

@Override
public void onError(Throwable error) {
error.printStackTrace();
}
});

您可以使用 LambdaStreamingResponseHandler 中的快捷工具函数 onPartialResponse()onPartialResponseAndError()

model.chat("Why is the sky blue?", onPartialResponse(System.out::print));
model.chat("Why is the sky blue?", onPartialResponseAndError(System.out::print, Throwable::printStackTrace));

可用模型

模型名称描述输入属性
gemini-1.5-flash为高容量、高质量、高性价比的应用提供速度与效率。文本、代码、图像、音频、视频、带音频的视频、PDF最大输入 token:1,048,576,最大输出 token:8,192
gemini-1.5-pro支持文本或聊天提示以获得文本或代码响应。支持长达最大输入 token 限制的长上下文理解。文本、代码、图像、音频、视频、带音频的视频、PDF最大输入 token:2,097,152,最大输出 token:8,192
gemini-1.0-pro面向广泛纯文本任务的最佳性能模型。文本最大输入 token:32,760,最大输出 token:8,192
gemini-1.0-pro-vision处理广泛应用的最佳图像和视频理解模型。文本、图像、音频、视频、带音频的视频、PDF最大输入 token:16,384,最大输出 token:2,048
gemini-1.0-ultra最强大的文本模型,针对复杂任务优化,包括指令、代码和推理。文本最大输入 token:8,192,最大输出 token:2,048
gemini-1.0-ultra-vision最强大的多模态视觉模型。针对联合文本、图像和视频输入进行了优化。文本、代码、图像、音频、视频、带音频的视频、PDF最大输入 token:8,192,最大输出 token:2,048

您可以在 Gemini 模型文档页面 了解更多关于这些模型的信息。

请注意,2024 年 3 月,Ultra 版本为允许名单私有访问。因此,您可能会收到类似如下的异常:

Caused by: io.grpc.StatusRuntimeException:
FAILED_PRECONDITION: Project `1234567890` is not allowed to use Publisher Model
`projects/{YOUR_PROJECT_ID}/locations/us-central1/publishers/google/models/gemini-ultra`

配置

ChatModel model = VertexAiGeminiChatModel.builder()
.project(PROJECT_ID) // your Google Cloud project ID
.location(LOCATION) // the region where AI inference should take place
.modelName(MODEL_NAME) // the model used
.logRequests(true) // log input requests
.logResponses(true) // log output responses
.maxOutputTokens(8192) // the maximum number of tokens to generate (up to 8192)
.temperature(0.7) // temperature (between 0 and 2)
.topP(0.95) // topP (between 0 and 1) — cumulative probability of the most probable tokens
.topK(3) // topK (positive integer) — pick a token among the most probable ones
.seed(1234) // seed for the random number generator
.maxRetries(2) // maximum number of retries
.responseMimeType("application/json") // to get JSON structured outputs
.responseSchema(/*...*/) // structured output following the provided schema
.safetySettings(/*...*/) // specify safety settings to filter inappropriate content
.useGoogleSearch(true) // to ground responses with Google Search results
.vertexSearchDatastore(name)// to ground responses with data backed documents
// from a custom Vertex AI Search datastore
.toolCallingMode(/*...*/) // AUTO (automatic), ANY (from a list of functions), NONE
.allowedFunctionNames(/*...*/) // when using ANY tool calling mode,
// specify the allowed function names to be called
.listeners(/*...*/) // list of listeners to receive model events
.credentials(credentials) // custom Google Cloud credentials
.build();

流式聊天模型也提供相同的参数。

更多示例

Gemini 是一个 multimodal(多模态)模型,输入可接受文本,也可接受图像、音频和视频文件以及 PDF。

描述图像内容

ChatModel model = VertexAiGeminiChatModel.builder()
.project(PROJECT_ID)
.location(LOCATION)
.modelName(GEMINI_1_5_PRO)
.build();

UserMessage userMessage = UserMessage.from(
ImageContent.from(CAT_IMAGE_URL),
TextContent.from("What do you see? Reply in one word.")
);

ChatResponse response = model.chat(userMessage);

URL 可以是 Web URL,也可以指向存储在 Google Cloud Storage 存储桶中的文件, 例如 gs://my-bucket/my-image.png

您也可以将图像内容作为 Base64 编码字符串传入:

String base64Data = Base64.getEncoder().encodeToString(readBytes(CAT_IMAGE_URL));
UserMessage userMessage = UserMessage.from(
ImageContent.from(base64Data, "image/png"),
TextContent.from("What do you see? Reply in one word.")
);

就 PDF 文档提问

var model = VertexAiGeminiChatModel.builder()
.project(PROJECT_ID)
.location(LOCATION)
.modelName(GEMINI_1_5_PRO)
.logRequests(true)
.logResponses(true)
.build();

UserMessage message = UserMessage.from(
PdfFileContent.from(Paths.get("src/test/resources/gemini-doc-snapshot.pdf").toUri()),
TextContent.from("Provide a summary of the document")
);

ChatResponse response = model.chat(message);

工具调用

ChatModel model = VertexAiGeminiChatModel.builder()
.project(PROJECT_ID)
.location(LOCATION)
.modelName(GEMINI_1_5_PRO)
.build();

ToolSpecification weatherToolSpec = ToolSpecification.builder()
.name("getWeatherForecast")
.description("Get the weather forecast for a location")
.parameters(JsonObjectSchema.builder()
.addStringProperty("location", "the location to get the weather forecast for")
.required("location")
.build())
.build();

ChatRequest request = ChatRequest.builder()
.messages(UserMessage.from("What is the weather in Paris?"))
.toolSpecifications(weatherToolSpec)
.build();

ChatResponse response = model.chat(request);

模型将以工具执行请求而非文本消息进行回复。 您的责任是通过向模型发送 ToolExecutionResultMessage,向模型提供该执行请求的响应。 然后模型才能以文本响应进行回复。

当模型在单个响应中请求进行多个工具执行时,也支持并行函数调用。

使用 AiServices 的工具支持

您可以使用 AiServices 创建由工具驱动的自定义助手。 以下示例展示了一个用于数学计算的 Calculator 工具、 一个用于指定助手契约的 Assistant 接口, 然后我们配置 AiServices 使用 Gemini、聊天记忆以及计算器工具。

static class Calculator {
@Tool("Adds two given numbers")
double add(double a, double b) {
return a + b;
}

@Tool("Multiplies two given numbers")
String multiply(double a, double b) {
return String.valueOf(a * b);
}
}

interface Assistant {
String chat(String userMessage);
}

Calculator calculator = new Calculator();

Assistant assistant = AiServices.builder(Assistant.class)
.chatModel(model)
.chatMemory(MessageWindowChatMemory.withMaxMessages(10))
.tools(calculator)
.build();

String answer = assistant.chat("How much is 74589613588 + 4786521789?");

使用 Google 搜索结果为回答提供依据

LLM 不一定知道所有可能问题的答案! 对于近期事件或训练截止日期之后发生的信息尤其如此。 可以用 Google 搜索的最新结果来为 Gemini 的回答提供 grounding(依据):

var modelWithSearch = VertexAiGeminiChatModel.builder()
.project(PROJECT_ID)
.location(LOCATION)
.modelName("gemini-1.5-flash-001")
.useGoogleSearch(true)
.build();

String resp = modelWithSearch.chat("What is the score of yesterday's football match from Paris Saint Germain?");

使用 Vertex AI Search 结果为回答提供依据

在处理私有内部信息、文档、数据时,您可以使用 Vertex AI Search 数据存储 来保存这些文档。 然后可以用这些文档为 Gemini 的回答提供依据:

var modelWithSearch = VertexAiGeminiChatModel.builder()
.project(PROJECT_ID)
.location(LOCATION)
.modelName("gemini-1.5-flash-001")
.vertexSearchDatastore("name_of_the_datastore")
.build();

JSON 结构化输出

您可以要求 Gemini 仅返回有效的 JSON 输出:

var modelWithResponseMimeType = VertexAiGeminiChatModel.builder()
.project(PROJECT_ID)
.location(LOCATION)
.modelName("gemini-1.5-flash-001")
.responseMimeType("application/json")
.build();

String userMessage = "Return JSON with two fields: name and surname of Klaus Heisler.";
String jsonResponse = modelWithResponseMimeType.chat(userMessage).content().text();
// {"name": "Klaus", "surname": "Heisler"}

使用 JSON schema 的严格 JSON 结构化输出

使用 responseMimeType("application/json) 时,如果提示没有精确描述期望的 JSON 输出, 模型在响应方式上仍可能有些“创意”。 为确保更严格的 JSON 结构化输出,可以为响应指定 JSON schema:

Schema schema = Schema.newBuilder()
.setType(Type.OBJECT)
.putProperties("name", Schema.newBuilder()
.setType(Type.STRING)
.build())
.putProperties("address", Schema.newBuilder()
.setType(Type.OBJECT)
.putProperties("street",
Schema.newBuilder().setType(Type.STRING).build())
.putProperties("zipcode",
Schema.newBuilder().setType(Type.STRING).build())
.build())
.build();

var model = VertexAiGeminiChatModel.builder()
.project(PROJECT_ID)
.location(LOCATION)
.modelName(GEMINI_1_5_PRO)
.responseMimeType("application/json")
.responseSchema(Schema)
.build();

一个便捷方法允许您为 Java 类生成 schema:

class Artist {
public String artistName;
int artistAge;
protected boolean artistAdult;
private String artistAddress;
public Pet[] pets;
}

class Pet {
public String name;
}

Schema schema = SchemaHelper.fromClass(Artist.class);

var model = VertexAiGeminiChatModel.builder()
.project(PROJECT_ID)
.location(LOCATION)
.modelName(GEMINI_1_5_PRO)
.responseMimeType("application/json")
.responseSchema(schema)
.build();

另一个方法允许您从 JSON schema 字符串创建 schema: SchemaHelper.fromJson(...)

Gemini 支持将 JSON 对象和数组作为结构化输出, 但也有一个特殊情况:以 JSON 字符串枚举作为输出, 这在要求 Gemini 做分类任务(如情感分析)时特别有用:

var model = VertexAiGeminiChatModel.builder()
.project(PROJECT_ID)
.location(LOCATION)
.modelName(GEMINI_1_5_PRO)
.logRequests(true)
.logResponses(true)
.responseSchema(Schema.newBuilder()
.setType(Type.STRING)
.addAllEnum(Arrays.asList("POSITIVE", "NEUTRAL", "NEGATIVE"))
.build())
.build();

在这种情况下,隐式响应 MIME 类型被设置为 text/x.enum (这不是官方注册的 MIME 类型)。

指定安全设置

如果要过滤或阻止有害内容,可以设置不同阈值级别的安全设置:

HashMap<HarmCategory, SafetyThreshold> safetySettings = new HashMap<>();
safetySettings.put(HARM_CATEGORY_HARASSMENT, BLOCK_LOW_AND_ABOVE);
safetySettings.put(HARM_CATEGORY_DANGEROUS_CONTENT, BLOCK_ONLY_HIGH);
safetySettings.put(HARM_CATEGORY_SEXUALLY_EXPLICIT, BLOCK_MEDIUM_AND_ABOVE);

var model = VertexAiGeminiChatModel.builder()
.project(PROJECT_ID)
.location(LOCATION)
.modelName("gemini-1.5-flash-001")
.safetySettings(safetySettings)
.logRequests(true)
.logResponses(true)
.build();

自定义身份验证

您可以提供自定义 Google Cloud 凭据:

import com.google.auth.oauth2.GoogleCredentials;
import java.io.FileInputStream;

GoogleCredentials credentials = GoogleCredentials.fromStream(
new FileInputStream("path/to/service-account-key.json"));

var model = VertexAiGeminiChatModel.builder()
.project(PROJECT_ID)
.location(LOCATION)
.modelName("gemini-1.5-flash-001")
.credentials(credentials)
.build();

参考资料

可用位置

多模态能力

示例