天天看点

在 Java 中创建可扩展的 OpenAI GPT 应用程序

作者:科技狠活与软件技术

关注留言点赞,带你了解最流行的软件开发知识与最新科技行业趋势。

在本教程中,了解如何通过仅在必要时向引擎发送提示,以可扩展的方式将 ChatGPT 引擎集成到您的 Java 应用程序中。

ChatGPT 更值得注意的方面之一是它的引擎,它不仅为基于 Web 的聊天机器人提供动力,还可以集成到您的Java应用程序中。

无论您喜欢阅读还是观看,让我们回顾一下如何通过仅在必要时向引擎发送提示,以可扩展的方式在您的 Java 项目中开始使用 OpenAI GPT 引擎:

预算之旅应用程序

想象一下,您想参观一个城市并且有一个特定的预算。您应该如何花钱并让您的旅行难忘?这是委托给 OpenAI 引擎的一个很好的问题。

让我们通过构建一个名为BudgetJourney的简单 Java 应用程序来帮助用户充分利用他们的旅行。该应用程序可以建议城市内的多个兴趣点,以适应特定的预算限制。

BudgetJourney 应用程序的架构如下所示:

在 Java 中创建可扩展的 OpenAI GPT 应用程序

BudgetJourney 应用程式

用户打开在Vaadin上运行的 BudgetJourney Web UI 。

当用户想要获得针对特定城市和预算的建议时,Vaadin 会连接到Spring Boot后端。

Spring Boot 连接到一个YugabyteDB 数据库实例,以检查是否已经有任何关于请求的城市和预算的建议。如果数据已经在数据库中,则将响应发送回给用户。

否则,Spring Boot 连接到 OpenAI API 以从神经网络获取建议。响应存储在 YugabyteDB 中以备将来参考并发回给用户。

现在,让我们看看应用程序如何与 Open AI 引擎通信(第 4 步),以及如何使用数据库(第 3 步)使解决方案具有可扩展性和成本效益。

OpenAI Java 库

可以通过HTTP API查询 OpenAI 引擎。您需要创建一个帐户,获取您的令牌(即 API 密钥)并在向其中一个 OpenAI 模型发送请求时使用该令牌。

OpenAI 上下文中的模型是一种在大型数据集上训练的计算结构,用于识别模式、进行预测或根据输入数据执行特定任务。目前,该服务支持多种模型,可以理解和生成自然语言、代码、图像,或将音频转换为文本。

我们的 BudgetJourney 应用程序使用GPT-3.5 模型,该模型可以理解并生成自然语言或代码。该应用程序要求模型在考虑预算限制的同时建议城市内的几个兴趣点。该模型然后以 JSON 格式返回建议。

开源OpenAI Java 库实现了 GPT-3.5 HTTP API,可以通过定义明确的 Java 抽象轻松地与服务进行通信。以下是您如何开始使用该库:

将最新的 OpenAI Java 工件添加到您的pom.xml文件中。

XML

<dependency>

<groupId>com.theokanning.openai-gpt3-java</groupId>

<artifactId>service</artifactId>

<version>${version}</version>

</dependency>

OpenAiService通过为应用程序和 OpenAI 引擎之间的请求提供令牌和超时来创建该类的实例。

OpenAiService openAiService = new OpenAiService(

apiKey, Duration.ofSeconds(apiTimeout));

简单的!接下来,让我们看看如何通过实例使用 GPT-3.5 模型OpenAiService。

向 GPT-3.5 模型发送提示

您可以通过发送文本提示来与 OpenAI 模型进行通信,这些文本提示告诉您期望模型做什么。当您的说明清晰并包含示例时,模型表现最佳。

要为 GPT-3.5 模型构建提示,您可以使用ChatCompletionRequestOpenAI Java 库的 API:

ChatCompletionRequest chatCompletionRequest = ChatCompletionRequest

.builder()

.model(“gpt-3.5-turbo”)

.temperature(0.8)

.messages(

List.of(

new ChatMessage("system", SYSTEM_TASK_MESSAGE),

new ChatMessage("user", String.format("I want to visit %s and have a budget of %d dollars", city, budget))))

.build();

model(“gpt-3.5-turbo”)是 GPT-3.5 模型的优化版本。

temperature(...)控制模型响应中预期的随机性和创造性。例如,较高的值(如 0.8)将使输出更加随机,而较低的值(如 0.2)将使输出更具确定性。

messages(...)是对模型的实际说明或提示。有“system”指示模型以某种方式运行的消息,“assistant”存储以前响应的消息,以及“user”携带用户请求和询问的消息。

BudgetJourney 应用程序SYSTEM_TASK_MESSAGE的外观如下所示:

你是一个以 JSON 格式响应的 API 服务器。别说别的了。仅响应 JSON。

用户将为您提供城市名称和可用预算。在考虑该预算时,您必须建议一个参观地点列表。

将 30% 的预算分配给餐厅和酒吧。再分配 30% 用于表演、游乐园和其他观光活动。将剩余的预算用于购物。请记住,用户必须花费预算的 90-100%。

以 JSON 格式响应,包括名为“places”的数组。数组的每一项都是另一个 JSON 对象,其中包括作为文本的“place_name”、作为文本的“place_short_info”和作为数字的“place_visit_cost”。

使用 JSON 响应后不要添加任何其他内容。

在 Java 中创建可扩展的 OpenAI GPT 应用程序

尽管冗长且需要优化,但此系统消息传达了所需的操作:以最大预算利用率建议多个兴趣点并以 JSON 格式提供响应,这对于应用程序的其余部分至关重要。

ChatCompletionRequest创建提供系统和用户消息以及其他参数的提示 ( ) 后,您可以通过OpenAiService实例发送它:

OpenAiService openAiService = … //created earlier

StringBuilder builder = new StringBuilder();

openAiService.createChatCompletion(chatCompletionRequest)

.getChoices().forEach(choice -> {

builder.append(choice.getMessage().getContent());

});

String jsonResponse = builder.toString();

然后该jsonResponse对象由其余的应用程序逻辑进一步处理,这些逻辑准备兴趣点列表并在 Vaadin 的帮助下显示它们。

例如,假设用户正在访问东京并希望在该市花费最多 900 美元。该模型将严格按照我们从系统消息中获取的指令进行响应,并使用以下 JSON 进行响应:

{

"places": [

{

"place_name": "Tsukiji Fish Market",

"place_short_info": "Famous fish market where you can eat fresh sushi",

"place_visit_cost": 50

},

{

"place_name": "Meiji Shrine",

"place_short_info": "Beautiful Shinto shrine in the heart of Tokyo",

"place_visit_cost": 0

},

{

"place_name": "Shibuya Crossing",

"place_short_info": "Iconic pedestrian crossing with bright lights and giant video screens",

"place_visit_cost": 0

},

{

"place_name": "Tokyo Skytree",

"place_short_info": "Tallest tower in the world, offering stunning views of Tokyo",

"place_visit_cost": 30

},

{

"place_name": "Robot Restaurant",

"place_short_info": "Unique blend of futuristic robots, dancers, and neon lights",

"place_visit_cost": 80

},

// More places

]}

然后将此 JSON 转换为不同兴趣点的列表。然后显示给用户:

不同的兴趣点

注意: GPT-3.5 模型是在 2021 年 9 月的数据集上训练的。因此,它无法提供 100% 准确且相关的旅行推荐。然而,这种不准确性可以在 OpenAI 插件的帮助下得到改善,这些插件使模型能够访问实时数据。例如,一旦OpenAI 的 Expedia 插件作为 API 公开可用,您就可以进一步改进此 BudgetJourney 应用程序。

使用数据库扩展

如您所见,将神经网络集成到您的 Java 应用程序中并以类似于其他第 3 方 API 的方式与其通信非常简单。您还可以调整 API 行为,例如添加所需的输出格式。

但是,这仍然是一个 3rd 方 API,它会为每个请求向您收费。您发送的提示越多,提示时间越长,您支付的费用就越多。没有什么是免费的。

另外,模型需要时间来处理您的提示。例如,BudgetJourney 应用程序可能需要 10-30 秒才能收到来自 OpenAI 的完整推荐列表。这可能有点矫枉过正,尤其是当不同的用户发送相似的提示时。

为了使 OpenAI GPT 应用程序具有可扩展性,值得将模型响应存储在数据库中。该数据库允许您:

减少对 OpenAI API 的请求量,从而减少相关成本。

通过从数据库返回先前处理(或预加载)的建议,以低延迟服务用户请求。

BudgetJourney 应用程序使用 YugabyteDB 数据库,因为它能够在全球范围内扩展并将模型响应存储在靠近用户位置的位置。使用地理分区部署模式,您可以拥有一个单一的数据库集群,数据自动固定到不同的地理位置并以低延迟提供服务。

在 Java 中创建可扩展的 OpenAI GPT 应用程序

地理分区的 YugabyteDB 集群

自定义地理分区列(“region”上图中的列)让数据库决定目标行位置。例如,来自欧洲的数据库节点已经存储了预算为 1500 美元的迈阿密旅行的建议。接下来,假设来自欧洲的用户想要去迈阿密并花费该金额。在这种情况下,应用程序可以通过直接从同一地理位置的数据库节点获取建议,在几毫秒内做出响应。

BudgetJourney 应用程序使用以下 JPA 存储库从 YugabyteDB 集群获取推荐:

@Repository

public interface CityTripRepository extends JpaRepository<CityTrip, Integer> {

@Query("SELECT pointsOfInterest FROM CityTrip WHERE cityName=?1 and budget=?2 and region=?3")

String findPointsOfInterest(String cityName, Integer budget, String region);

}

类Entity如下所示:

@Entity

public class CityTrip {

@Id

@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "landmark_generator")

@SequenceGenerator(name = "landmark_generator", sequenceName = "landmark_sequence", allocationSize = 5)

int id;

@NotEmpty

String cityName;

@NotNull

Integer budget;

@NotEmpty

@Column(columnDefinition = "text")

String pointsOfInterest;

@NotEmpty

String region;

//The rest of the logic

}

因此,您需要做的就是先调用数据库,如果相关建议在数据库中尚不可用,则返回到 OpenAI API。随着您的应用程序越来越受欢迎,越来越多的本地推荐将可用,随着时间的推移,这种方法将变得更具成本效益。

总结

ChatGPT 基于 Web 的聊天机器人是展示 OpenAI 引擎功能的绝佳方式。探索引擎的强大模型并开始构建新型 Java 应用程序。只要确保您以可扩展的方式进行即可!