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

1. 简介

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

什么是生成式 AI

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

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

生成式 AI 如何运作?

生成式 AI 的工作原理是利用机器学习 (ML) 模型,学习人工创建的内容数据集中的模式和关系。然后,它会利用学到的模式生成新内容。

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

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

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

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

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

借助 Vertex AI,您可以自定义基础模型、与其交互、将其嵌入到应用中,而无需具备机器学习专业知识。在 Model Garden 上访问基础模型,通过 生成式 AI Studio 上的简单界面微调模型,或者在数据科学笔记本中使用模型。

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

Duet AI 是依托 AI 技术的协作工具,可在 Google Cloud 和 IDE 中使用,帮助您更快地完成更多工作。

本 Codelab 重点介绍哪些内容?

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

您将使用 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.png

37d264871000675d.png

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.png

这个虚拟机已加载了所需的所有开发工具。它提供了一个持久的 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,然后按 Return 键。
  4. 在搜索结果中,点击 Vertex AI 系统会显示 Vertex AI 信息中心。
  5. 在 Vertex AI 信息中心内,点击启用所有推荐的 API

这会启用多个 API,但对于此 Codelab 而言,最重要的 API 是 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)构建应用(选项 2),不使用子项目(选项 1),使用构建文件的 Groovy 语法(选项 1),不使用新的 build 功能(选项否),使用 JUnit Jupiter(选项 4)生成测试,项目名称可以使用 palm-workshop,同样,源软件包可以使用 palm.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 有 2 个依赖项:

  • 一个位于核心项目上,
  • 一个用于专用 Vertex AI 模块。

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

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

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

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 目录(与默认的 App.java 类并列)中创建一个名为 TextPrompts.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 类和 Vertex AI PaLM 语言模型。

接下来,在 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 个 token(3 个 token 大致相当于 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 等大语言模型非常擅长回答问题,但您还可以将它们用于更多任务!例如,您可以在 生成式 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 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 应用!您在学习过程中发现,大语言模型非常强大,能够处理各种任务,例如问答、数据提取、总结、文本分类、情感分析等。

后续操作

如需进一步了解如何在 Java 中使用 PaLM,请查看以下 Codelab:

深入阅读

参考文档