使用 PaLM 和 LangChain4J 以 Java 语言生成生成式 AI 文本

1. 简介

上次更新日期:2023 年 11 月 27 日

什么是生成式 AI

生成式 AI(生成式人工智能)是指使用 AI 来创作新内容,例如文本、图片、音乐、音频和视频。

生成式 AI 基于可以执行多任务处理和执行开箱即用任务(包括摘要、问答、分类等)的基础模型(大型 AI 模型)。此外,基础模型只需极少的训练即可针对目标应用场景进行调整,而且只需要非常少量的示例数据。

生成式 AI 的工作原理是什么?

生成式 AI 使用机器学习 (ML) 模型来学习包含人类创建内容的数据集中的模式和关系。然后,它会使用学到的模式生成新内容。

训练生成式 AI 模型的最常用方法是使用监督式学习,即为模型提供一组人类创建的内容及相应的标签。然后,它会学习如何生成类似于人工创建的内容,并使用相同的标签进行标记。

常见的生成式 AI 应用有哪些?

生成式 AI 可处理大量内容,并通过文本、图片和方便用户使用的格式提供数据洞见和答案。生成式 AI 可用于:

  • 通过增强的聊天和搜索体验改善客户互动
  • 通过对话界面和摘要探索大量非结构化数据
  • 协助处理重复性任务,例如回复提案请求 (RFP)、将营销内容本地化为五种语言,以及检查客户合同是否合规等

Google Cloud 提供哪些生成式 AI 产品?

借助 Vertex AI,您可以与基础模型进行交互、自定义基础模型并将其嵌入您的应用 - 几乎不需要机器学习专业知识。在 Model Garden 上访问基础模型,通过 Generative AI Studio 中的简单界面对模型进行调参,或者在数据科学笔记本中使用模型。

Vertex AI Search and Conversation 为开发者提供了构建生成式 AI 赋能的搜索引擎和聊天机器人的最快方法。

Duet AI 是 AI 赋能的协作工具,可在 Google Cloud 和 IDE 中使用,帮助您更快地完成更多任务。

此 Codelab 侧重于哪些内容?

此 Codelab 重点介绍了托管在 Google Cloud Vertex AI 上的 PaLM 2 大语言模型 (LLM),其中包括所有机器学习产品和服务。

您将使用 Java 与 PaLM API 进行交互,并结合使用 LangChain4J LLM 框架编排系统。您将通过不同的具体示例,利用 LLM 进行问答、生成想法、提取实体和结构化内容,以及生成摘要。

请详细讲讲 LangChain4J 框架!

LangChain4J 框架是一个开源库,通过编排各种组件(例如 LLM 本身),以及矢量数据库(用于语义搜索)、文档加载器和拆分器(用于分析文档并从中学习)、输出解析器等,将大型语言模型集成到 Java 应用中。

c6d7f7c3fd0d2951.png

学习内容

  • 如何设置 Java 项目以使用 PaLM 和 LangChain4J
  • 如何首次调用 PaLM 文本模型以生成内容并回答问题
  • 如何从非结构化内容中提取有用信息(实体或关键字提取,JSON 输出)
  • 如何通过少量提示进行内容分类或情感分析

所需条件

  • 了解 Java 编程语言
  • Google Cloud 项目
  • 浏览器,例如 Chrome 或 Firefox

2. 设置和要求

自定进度的环境设置

  1. 登录 Google Cloud 控制台,然后创建一个新项目或重复使用现有项目。如果您还没有 Gmail 或 Google Workspace 账号,则必须创建一个

295004821bab6a87

37d264871000675d

96d86d3d5655cdbe.png

  • 项目名称是此项目参与者的显示名称。它是 Google API 尚未使用的字符串。您可以随时对其进行更新。
  • 项目 ID 在所有 Google Cloud 项目中是唯一的,并且是不可变的(一经设置便无法更改)。Cloud 控制台会自动生成一个唯一字符串;通常情况下,您无需关注该字符串。在大多数 Codelab 中,您都需要引用项目 ID(通常用 PROJECT_ID 标识)。如果您不喜欢生成的 ID,可以再随机生成一个 ID。或者,您也可以尝试自己的项目 ID,看看是否可用。完成此步骤后便无法更改该 ID,并且此 ID 在项目期间会一直保留。
  • 此外,还有第三个值,即部分 API 使用的项目编号,供您参考。如需详细了解所有这三个值,请参阅文档
  1. 接下来,您需要在 Cloud 控制台中启用结算功能,以便使用 Cloud 资源/API。运行此 Codelab 应该不会产生太多的费用(如果有的话)。若要关闭资源以避免产生超出本教程范围的结算费用,您可以删除自己创建的资源或删除项目。Google Cloud 新用户符合参与 300 美元免费试用计划的条件。

启动 Cloud Shell

虽然 Google Cloud 可以通过笔记本电脑远程操作,但在此 Codelab 中,您将使用 Cloud Shell,这是一个在云端运行的命令行环境。

激活 Cloud Shell

  1. 在 Cloud Console 中,点击激活 Cloud Shelld1264ca30785e435.png

cb81e7c8e34bc8d.png

如果这是您第一次启动 Cloud Shell,系统会显示一个中间屏幕,说明它是什么。如果您看到中间屏幕,请点击继续

d95252b003979716.png

预配和连接到 Cloud Shell 只需花几分钟时间。

7833d5e1c5d18f54

这个虚拟机装有所需的所有开发工具。它提供了一个持久的 5 GB 主目录,并在 Google Cloud 中运行,大大增强了网络性能和身份验证功能。您在此 Codelab 中的大部分(即使不是全部)工作都可以通过浏览器完成。

在连接到 Cloud Shell 后,您应该会看到自己已通过身份验证,并且相关项目已设为您的项目 ID。

  1. 在 Cloud Shell 中运行以下命令以确认您已通过身份验证:
gcloud auth list

命令输出

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. 在 Cloud Shell 中运行以下命令,以确认 gcloud 命令了解您的项目:
gcloud config list project

命令输出

[core]
project = <PROJECT_ID>

如果不是上述结果,您可以使用以下命令进行设置:

gcloud config set project <PROJECT_ID>

命令输出

Updated property [core/project].

3. 准备开发环境

在此 Codelab 中,您将使用 Cloud Shell 终端和代码编辑器来开发 Java 程序。

启用 Vertex AI API

  1. 在 Google Cloud 控制台中,确保您的项目名称显示在 Google Cloud 控制台的顶部。如果不是,请点击选择项目以打开项目选择器,然后选择所需的项目。
  2. 如果您没有进入 Google Cloud 控制台的 Vertex AI 部分,请执行以下操作:
  3. 搜索中,输入 Vertex AI,然后返回
  4. 在搜索结果中,点击 Vertex AI。系统随即会显示 Vertex AI 信息中心。
  5. 点击 Vertex AI 信息中心内的启用所有推荐的 API

这将启用多个 API,但对于此 Codelab,最重要的一个是 aiplatform.googleapis.com,您也可以在命令行上、在 Cloud Shell 终端中运行以下命令来启用该 API:

$ gcloud services enable aiplatform.googleapis.com

使用 Gradle 创建项目结构

为了构建 Java 代码示例,您将使用 Gradle 构建工具和 Java 版本 17。如需使用 Gradle 设置项目,请在 Cloud Shell 终端中创建一个目录(此处为 palm-workshop),然后在该目录中运行 gradle init 命令:

$ mkdir palm-workshop
$ cd palm-workshop

$ gradle init

Select type of project to generate:
  1: basic
  2: application
  3: library
  4: Gradle plugin
Enter selection (default: basic) [1..4] 2

Select implementation language:
  1: C++
  2: Groovy
  3: Java
  4: Kotlin
  5: Scala
  6: Swift
Enter selection (default: Java) [1..6] 3

Split functionality across multiple subprojects?:
  1: no - only one application project
  2: yes - application and library projects
Enter selection (default: no - only one application project) [1..2] 1

Select build script DSL:
  1: Groovy
  2: Kotlin
Enter selection (default: Groovy) [1..2] 1

Generate build using new APIs and behavior (some features may change in the next minor release)? (default: no) [yes, no] 

Select test framework:
  1: JUnit 4
  2: TestNG
  3: Spock
  4: JUnit Jupiter
Enter selection (default: JUnit Jupiter) [1..4] 4

Project name (default: palm-workshop): 
Source package (default: palm.workshop): 

> Task :init
Get more help with your project: https://docs.gradle.org/7.4/samples/sample_building_java_applications.html

BUILD SUCCESSFUL in 51s
2 actionable tasks: 2 executed

您将使用 Java 语言(选项 3)构建应用(选项 3),不使用子项目(选项 1),使用构建文件的 Groovy 语法(选项 1),不使用新的构建功能(选项 4),使用 JUnit Jupiter(选项 4)生成测试,对于项目名称,您可以使用 palmSimilar-workshoppalmSimilar-workshop

项目结构将如下所示:

├── gradle 
│   └── ...
├── gradlew 
├── gradlew.bat 
├── settings.gradle 
└── app
    ├── build.gradle 
    └── src
        ├── main
        │   └── java 
        │       └── palm
        │           └── workshop
        │               └── App.java
        └── test
            └── ...

我们来更新 app/build.gradle 文件,以添加一些所需的依赖项。您可以移除 guava 依赖项(如果存在),并将其替换为 LangChain4J 项目和日志记录库的依赖项,以免在记录器消息缺失时产生烦恼:

dependencies {
    // Use JUnit Jupiter for testing.
    testImplementation 'org.junit.jupiter:junit-jupiter:5.8.1'

    // Logging library
    implementation 'org.slf4j:slf4j-jdk14:2.0.9'

    // This dependency is used by the application.
    implementation 'dev.langchain4j:langchain4j-vertex-ai:0.24.0'
    implementation 'dev.langchain4j:langchain4j:0.24.0'
}

LangChain4J 有两个依赖项:

  • 一个是核心项目
  • 另一个用于专用 Vertex AI 模块。

为了使用 Java 17 来编译和运行程序,请在 plugins {} 代码块下方添加以下代码块:

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(17)
    }
}

还需要进行一项更改:更新 app/build.gradleapplication 代码块,让用户能够在调用构建工具时替换要在命令行上运行的主类:

application {
    mainClass = providers.systemProperty('javaMainClass')
                         .orElse('palm.workshop.App')
}

如需检查 build 文件是否已准备好运行您的应用,您可以运行默认主类,该类会输出一条简单的 Hello World! 消息:

$ ./gradlew run -DjavaMainClass=palm.workshop.App

> Task :app:run
Hello World!

BUILD SUCCESSFUL in 3s
2 actionable tasks: 2 executed

现在,您可以使用 LangChain4J 项目来使用 PaLM 大语言文本模型进行编程了!

以下是完整的 app/build.gradle build 文件现在应如下所示,供您参考:

plugins {
    // Apply the application plugin to add support for building a CLI application in Java.
    id 'application'
}

java {
    toolchain {
        // Ensure we compile and run on Java 17
        languageVersion = JavaLanguageVersion.of(17)
    }
}

repositories {
    // Use Maven Central for resolving dependencies.
    mavenCentral()
}

dependencies {
    // Use JUnit Jupiter for testing.
    testImplementation 'org.junit.jupiter:junit-jupiter:5.8.1'

    // This dependency is used by the application.
    implementation 'dev.langchain4j:langchain4j-vertex-ai:0.24.0'
    implementation 'dev.langchain4j:langchain4j:0.24.0'
    implementation 'org.slf4j:slf4j-jdk14:2.0.9'
}

application {
    mainClass = providers.systemProperty('javaMainClass').orElse('palm.workshop.App')
}

tasks.named('test') {
    // Use JUnit Platform for unit tests.
    useJUnitPlatform()
}

4. 首次调用 PaLM 的文本模型

现在项目已正确设置,可以调用 PaLM API 了。

app/src/main/java/palm/workshop 目录中创建一个名为 TextPrompts.java 的新类(在默认的 App.java 类旁边),然后输入以下内容:

package palm.workshop;

import dev.langchain4j.model.output.Response;
import dev.langchain4j.model.vertexai.VertexAiLanguageModel;

public class TextPrompts {
    public static void main(String[] args) {
        VertexAiLanguageModel model = VertexAiLanguageModel.builder()
            .endpoint("us-central1-aiplatform.googleapis.com:443")
            .project("YOUR_PROJECT_ID")
            .location("us-central1")
            .publisher("google")
            .modelName("text-bison@001")
            .maxOutputTokens(500)
            .build();

        Response<String> response = model.generate("What are large language models?");

        System.out.println(response.content());
    }
}

在第一个示例中,您需要导入 Response 类以及 PaLM 的 Vertex AI 语言模型。

接下来,在 main 方法中,使用 VertexAiLanguageModel 的构建器来配置语言模型,以指定以下内容:

  • 端点
  • 项目
  • 区域
  • 发布商
  • 和模型名称 (text-bison@001)。

现在,语言模型已准备就绪,您可以调用 generate() 方法并传递“提示”(即您要发送给 LLM 的问题或说明)。在这里,你会问一个简单的问题,了解 LLM 是什么。不过,您可以随意更改此提示,以尝试不同的问题或任务。

如需运行此类,请在 Cloud Shell 终端中运行以下命令:

./gradlew run -DjavaMainClass=palm.workshop.TextPrompts

您应该会看到类似于以下内容的输出:

Large language models (LLMs) are artificial intelligence systems that can understand and generate human language. They are trained on massive datasets of text and code, and can learn to perform a wide variety of tasks, such as translating languages, writing different kinds of creative content, and answering your questions in an informative way.

LLMs are still under development, but they have the potential to revolutionize many industries. For example, they could be used to create more accurate and personalized customer service experiences, to help doctors diagnose and treat diseases, and to develop new forms of creative expression.

However, LLMs also raise a number of ethical concerns. For example, they could be used to create fake news and propaganda, to manipulate people's behavior, and to invade people's privacy. It is important to carefully consider the potential risks and benefits of LLMs before they are widely used.

Here are some of the key features of LLMs:

* They are trained on massive datasets of text and code.
* They can learn to perform a wide variety of tasks, such as translating languages, writing different kinds of creative content, and answering your questions in an informative way.
* They are still under development, but they have the potential to revolutionize many industries.
* They raise a number of ethical concerns, such as the potential for fake news, propaganda, and invasion of privacy.

借助 VertexAILanguageModel 构建器,您可以定义可选参数,这些参数已包含一些可以替换的默认值。下面是一些示例:

  • .temperature(0.2) - 定义您希望响应的广告素材(0 表示广告素材不足,通常更符合实际情况,而 1 表示更多广告素材输出)
  • .maxOutputTokens(50) - 在本例中,请求了 500 个词元(3 个词元大致相当于 4 个字词),具体取决于您希望生成的答案多长时间
  • .topK(20) - 从最多可能的字词数中随机选择一个字词来完成文本补全(从 1 到 40)
  • .topP(0.95) - 用于选择总概率相加等于该浮点数(介于 0 和 1 之间)的可能字词
  • .maxRetries(3) - 例如,如果您跳过了每次请求配额,您可以让模型重试调用 3 次。

大语言模型功能非常强大,能够为复杂问题提供答案,并能够处理各种有趣的任务。在下一部分中,我们将了解一项有用的任务:从文本中提取结构化数据

5. 从非结构化文本中提取信息

在上一部分中,您生成了一些文本输出。如果您想直接向最终用户显示此输出,这没有问题。但是,如果您想检索此输出中提及的数据,如何从非结构化文本中提取该信息?

假设您想根据某人的生平简介或描述提取其姓名和年龄。您可以通过按如下方式调整提示,指示大语言模型生成 JSON 数据结构(这通常称为“提示工程”)

Extract the name and age of the person described below.

Return a JSON document with a "name" and an "age" property, 
following this structure: {"name": "John Doe", "age": 34}
Return only JSON, without any markdown markup surrounding it.

Here is the document describing the person:
---
Anna is a 23 year old artist based in Brooklyn, New York. She was 
born and raised in the suburbs of Chicago, where she developed a 
love for art at a young age. She attended the School of the Art 
Institute of Chicago, where she studied painting and drawing. 
After graduating, she moved to New York City to pursue her art career. 
Anna's work is inspired by her personal experiences and observations 
of the world around her. She often uses bright colors and bold lines 
to create vibrant and energetic paintings. Her work has been 
exhibited in galleries and museums in New York City and Chicago.
---

JSON: 

修改 TextPrompts 类中的 model.generate() 调用,以向其传递上面的完整文本提示:

Response<String> response = model.generate("""
    Extract the name and age of the person described below.
    Return a JSON document with a "name" and an "age" property, \
    following this structure: {"name": "John Doe", "age": 34}
    Return only JSON, without any markdown markup surrounding it.
    Here is the document describing the person:
    ---
    Anna is a 23 year old artist based in Brooklyn, New York. She was born and 
    raised in the suburbs of Chicago, where she developed a love for art at a 
    young age. She attended the School of the Art Institute of Chicago, where 
    she studied painting and drawing. After graduating, she moved to New York 
    City to pursue her art career. Anna's work is inspired by her personal 
    experiences and observations of the world around her. She often uses bright 
    colors and bold lines to create vibrant and energetic paintings. Her work 
    has been exhibited in galleries and museums in New York City and Chicago.    
    ---
    JSON: 
    """
);

如果您在 TextPrompts 类中运行此提示,它应该会返回以下 JSON 字符串,您可以使用 GSON 库等 JSON 解析器解析该字符串:

$ ./gradlew run -DjavaMainClass=palm.workshop.TextPrompts

> Task :app:run
{"name": "Anna", "age": 23}

BUILD SUCCESSFUL in 24s
2 actionable tasks: 1 executed, 1 up-to-date

是的!Anna 23 岁了!

6. 提示模板和结构化提示

不止解答问题

PaLM 等大语言模型在回答问题方面十分强大,但您可以将其用于更多任务!例如,在 Generative AI Studio 中尝试以下提示(或修改 TextPrompts 类)。用您自己的想法更改大写单词,并检查其输出:

  • 翻译 —“将以下句子翻译成法语:YOUR_SENTENCE_HERE
  • 摘要 -“提供以下文档的摘要:PASTE_YOUR_DOC”
  • 广告素材生成 -“写一首关于 TOPIC_OF_THE_POEM 的诗歌”
  • 编程 —“如何用 PROGRAMMING_LANGUAGE 写斐波那契函数?”

提示模板

如果您针对翻译、摘要、创意生成或编程任务尝试了上述提示,那么您已用自己的想法替换占位值。不过,除了对字符串进行一些改动,您还可以利用“提示模板”,定义这些占位值,然后在空白处填写您的数据。

我们来看一个生动有趣且富有创意的提示,将 main() 方法的所有内容替换为以下代码:

VertexAiLanguageModel model = VertexAiLanguageModel.builder()
            .endpoint("us-central1-aiplatform.googleapis.com:443")
            .project("YOUR_PROJECT_ID")
            .location("us-central1")
            .publisher("google")
            .modelName("text-bison@001")
            .maxOutputTokens(300)
            .build();

PromptTemplate promptTemplate = PromptTemplate.from("""
    Create a recipe for a {{dish}} with the following ingredients: \
    {{ingredients}}, and give it a name.
    """
);

Map<String, Object> variables = new HashMap<>();
variables.put("dish", "dessert");
variables.put("ingredients", "strawberries, chocolate, whipped cream");

Prompt prompt = promptTemplate.apply(variables);

Response<String> response = model.generate(prompt);

System.out.println(response.content());

通过添加以下 import 语句:

import dev.langchain4j.model.input.Prompt;
import dev.langchain4j.model.input.PromptTemplate;

import java.util.HashMap;
import java.util.Map;

然后再次运行应用。输出应如下所示:

$ ./gradlew run -DjavaMainClass=palm.workshop.TextPrompts

> Task :app:run
**Strawberry Shortcake**

Ingredients:

* 1 pint strawberries, hulled and sliced
* 1/2 cup sugar
* 1/4 cup cornstarch
* 1/4 cup water
* 1 tablespoon lemon juice
* 1/2 cup heavy cream, whipped
* 1/4 cup confectioners' sugar
* 1/4 teaspoon vanilla extract
* 6 graham cracker squares, crushed

Instructions:

1. In a medium saucepan, combine the strawberries, sugar, cornstarch, water, and lemon juice. Bring to a boil over medium heat, stirring constantly. Reduce heat and simmer for 5 minutes, or until the sauce has thickened.
2. Remove from heat and let cool slightly.
3. In a large bowl, combine the whipped cream, confectioners' sugar, and vanilla extract. Beat until soft peaks form.
4. To assemble the shortcakes, place a graham cracker square on each of 6 dessert plates. Top with a scoop of whipped cream, then a spoonful of strawberry sauce. Repeat layers, ending with a graham cracker square.
5. Serve immediately.

**Tips:**

* For a more elegant presentation, you can use fresh strawberries instead of sliced strawberries.
* If you don't have time to make your own whipped cream, you can use store-bought whipped cream.

太美味了!

通过提示模板,您可以在调用文本生成方法之前馈送所需参数。这是传递数据和针对用户提供的不同值自定义提示的好方法。

顾名思义,PromptTemplate 类会创建一个模板提示,您可以通过应用占位符名称和值的映射来为占位符元素分配值。

结构化提示(可选)

如果您想使用更丰富的面向对象的方法,还可以使用 @StructuredPrompt 注解构建提示。您可以使用此注解为类添加注解,并且其字段对应于提示中定义的占位符。我们来看看实际用例。

首先,我们需要一些新的导入:

import java.util.Arrays;
import java.util.List;
import dev.langchain4j.model.input.structured.StructuredPrompt;
import dev.langchain4j.model.input.structured.StructuredPromptProcessor;

然后,我们可以在 TextPrompts 类中创建一个内部静态类,用于收集在 @StructuredPrompt 注解所述的提示中传入占位符所需的数据:

@StructuredPrompt("Create a recipe of a {{dish}} that can be prepared using only {{ingredients}}")
static class RecipeCreationPrompt {
    String dish;
    List<String> ingredients;
}

然后实例化这个新类,并为其提供食谱中的菜肴和食材,创建提示并将其传递给 generate() 方法,就像之前一样:

RecipeCreationPrompt createRecipePrompt = new RecipeCreationPrompt();
createRecipePrompt.dish = "salad";
createRecipePrompt.ingredients = Arrays.asList("cucumber", "tomato", "feta", "onion", "olives");
Prompt prompt = StructuredPromptProcessor.toPrompt(createRecipePrompt);

Response<String> response = model.generate(prompt);

您可以不通过映射来填补缺口,而是使用 Java 对象,并以更类型安全的方式由 IDE 自动填充这些字段。

如果您想更轻松地将这些更改粘贴到 TextPrompts 类中,请参考以下完整代码:

package palm.workshop;

import java.util.Arrays;
import java.util.List;
import dev.langchain4j.model.input.Prompt;
import dev.langchain4j.model.output.Response;
import dev.langchain4j.model.vertexai.VertexAiLanguageModel;
import dev.langchain4j.model.input.structured.StructuredPrompt;
import dev.langchain4j.model.input.structured.StructuredPromptProcessor;

public class TextPrompts {

    @StructuredPrompt("Create a recipe of a {{dish}} that can be prepared using only {{ingredients}}")
    static class RecipeCreationPrompt {
        String dish;
        List<String> ingredients;
    }
    public static void main(String[] args) {
        VertexAiLanguageModel model = VertexAiLanguageModel.builder()
            .endpoint("us-central1-aiplatform.googleapis.com:443")
            .project("YOUR_PROJECT_ID")
            .location("us-central1")
            .publisher("google")
            .modelName("text-bison@001")
            .maxOutputTokens(300)
            .build();

        RecipeCreationPrompt createRecipePrompt = new RecipeCreationPrompt();
        createRecipePrompt.dish = "salad";
        createRecipePrompt.ingredients = Arrays.asList("cucumber", "tomato", "feta", "onion", "olives");
        Prompt prompt = StructuredPromptProcessor.toPrompt(createRecipePrompt);

        Response<String> response = model.generate(prompt);
        
        System.out.println(response.content());
    }
}

7. 文本分类和分析情感

与上一部分所学的内容类似,您将发现另一种“提示工程”技术,使 PaLM 模型能够对文本进行分类或分析情感。我们来介绍一下“少样本提示”。这是一种通过一些示例来增强提示的方法,有助于引导语言模型朝着您期望的方向前进,以便更好地了解您的意图。

我们来重新编写 TextPrompts 类,以充分利用提示模板:

package palm.workshop;

import java.util.Map;

import dev.langchain4j.model.output.Response;
import dev.langchain4j.model.vertexai.VertexAiLanguageModel;
import dev.langchain4j.model.input.Prompt;
import dev.langchain4j.model.input.PromptTemplate;

public class TextPrompts {
    public static void main(String[] args) {
        VertexAiLanguageModel model = VertexAiLanguageModel.builder()
            .endpoint("us-central1-aiplatform.googleapis.com:443")
            .project("YOUR_PROJECT_ID")
            .location("us-central1")
            .publisher("google")
            .modelName("text-bison@001")
            .maxOutputTokens(10)
            .build();

        PromptTemplate promptTemplate = PromptTemplate.from("""
            Analyze the sentiment of the text below. Respond only with one word to describe the sentiment.

            INPUT: This is fantastic news!
            OUTPUT: POSITIVE

            INPUT: Pi is roughly equal to 3.14
            OUTPUT: NEUTRAL

            INPUT: I really disliked the pizza. Who would use pineapples as a pizza topping?
            OUTPUT: NEGATIVE

            INPUT: {{text}}
            OUTPUT: 
            """);

        Prompt prompt = promptTemplate.apply(
            Map.of("text", "I love strawberries!"));

        Response<String> response = model.generate(prompt);

        System.out.println(response.content());
    }
}

请注意在提示中提供几个输入和输出示例的方法。这些都是“少量镜头”帮助 LLM 遵循相同的结构。当模型获得输入后,需要返回与输入/输出模式匹配的输出。

运行此程序应该只会返回单词 POSITIVE,因为草莓也很美味!

$ ./gradlew run -DjavaMainClass=palm.workshop.TextPrompts

> Task :app:run
POSITIVE

情感分析也是一种内容分类场景。您可以使用相同的“少样本提示”方法,将不同的文档分类到不同的类别中。

8. 恭喜

恭喜!您已成功使用 LangChain4J 和 PaLM API 以 Java 构建了自己的第一个生成式 AI 应用!在此过程中,您发现大语言模型非常强大,能够处理各种任务,例如问答、数据提取、摘要、文本分类、情感分析等。

后续操作

查看以下 Codelab,进一步在 Java 中使用 PaLM:

深入阅读

参考文档