ChatGPT 值得深入使用的方面之一是它的引擎,它不仅为基于Web的聊天机器人提供动力,还可以集成到Java应用程序中。
▌Budget Journey App
想象一下,你想去一个城市旅行并且设置好了预算,你应该如何分配你的钱并让你的旅行难忘?这是可以委托给 OpenAI 引擎的一个很好的问题。
我们通过构建一个名为 BudgetJourney 的简单Java应用程序来帮助用户充分享受他们的旅行。
这个APP可以推荐多个城市内的观光点并附上相应的预算规划。
BudgetJourney 应用程序的架构如下所示:
1. 用户打开在Vaadin上运行的 BudgetJourney 页面;
2. 当用户想要获得针对特定城市和预算的建议时,Vaadin 会连接到 Spring Boot 后端;
3. Spring Boot 连接到一个 YugabyteDB 数据库实例,以检查是否已经有任何关于请求的城市和预算的建议。如果数据已经在数据库中,则将响应发送回给用户;
4. 否则,Spring Boot 连接到 OpenAI API 以从神经网络获取建议。响应存储在 YugabyteDB 中以备将来参考并发回给用户。
现在,让我们看看应用程序如何与 Open AI 引擎通信(第 4 步),以及如何使用数据库(第 3 步)使解决方案具有可扩展性和成本效益。
▌OpenAI Java 库
OpenAI 引擎通过 HTTP API 进行查询。你需要创建一个帐户,获取你的令牌(即API密钥),并在向其中一个 OpenAI 模型发送请求时使用该令牌。
OpenAI 背景下的模型是在大型数据集上训练的计算结构,用于识别模式、做出预测或根据输入数据执行特定任务。目前,该服务支持多种模型,这些模型可以理解并生成自然语言、代码、图像或将音频转换为文本。
我们的 BudgetJourney 应用程序使用 GPT-3.5 模型,该模型可以理解并生成自然语言或代码。该应用程序要求模型在考虑预算限制的同时,提出城市内的几个观光点建议。然后,模型以 JSON 格式返回建议。
开源的 OpenAI Java 库实现了 GPT-3.5 HTTP API ,可以通过定义明确的 Java 轻松地与服务进行通信。
以下是您如何开始使用该库:
-
将最新的 OpenAI Java 工件添加到您的 pom.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));
简单的!接下来,让我们看看如何通过 OpenAiService 实例使用 GPT-3.5 模型。
▌向 GPT-3.5 模型发送提示
你可以通过发送文本提示来与 OpenAI 模型进行通信,告诉模型你期望得到什么结果。当你的说明清晰并包含示例时,模型表现最佳。
要为 GPT-3.5 模型构建提示,你可以使用 OpenAI Java 库的 ChatCompletionRequest 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进行响应后,不要添加任何其他内容。
尽管冗长且需要优化,但此系统消息传达了所需的操作:以最大的预算利用率建议多个兴趣点,并以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 应用程序中并以类似于其他第三方 API 的方式与之通信是很简单的。你还可以调整 API 行为,例如添加所需的输出格式。
但是,这仍然是一个第三方 API ,它会对你的每个请求收取费用。你发送的提示越多,时间越长,你支付的费用就越多。
此外,模型处理你的提示需要时间。例如,BudgetJourney 应用程序可能需要10-30秒才能从 OpenAI 收到完整的推荐列表。这可能有些过头了,尤其是当不同的用户发送类似的提示时。
为了使 OpenAI GPT 应用程序具有可扩展性,值得将模型响应存储在数据库中,需要数据库:
1. 减少对OpenAI API的请求量,从而降低相关成本;
2. 通过从数据库返回以前处理过(或预加载过)的推荐,以降低为用户请求提供服务的延迟。
BudgetJourney 应用程序使用的是 YugabyteDB 数据库,因为它能够在全球范围内扩展并将模型响应存储在用户位置附近。
使用地理分区部署模式,你可以拥有一个单一的数据库集群,其中数据自动固定到不同的地理位置,并从不同的地理区域以低延迟提供服务。
自定义地理分区列(上图中的“region”列)允许数据库决定目标行的位置。
例如,来自欧洲的数据库节点已经存储了预算为1500美元的迈阿密旅行的建议。接下来,假设来自欧洲的用户想要去迈阿密并花费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
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 的聊天机器人是展示 OpenAI 引擎功能的绝佳方式。探索引擎强大的模型,并开始构建新型Java应用程序。只要确保以可扩展的方式进行即可!
作者:Denis Magda
更多内容请关注公号“云原生数据库”