当前位置:Java -> 使用Spring AI和PostgreSQL PGVector入门
Spring AI 是 Spring 生态系统的一个新项目,它简化了在Java中创建AI应用程序的过程。通过将Spring AI与PostgreSQL pgvector一起使用,您可以构建生成AI应用程序,从中获取数据洞察。
首先,本文将为您介绍使用OpenAI GPT-4模型生成用户提示推荐的Spring AI ChatClient。接下来,文章将展示如何使用Spring AI EmbeddingClient和Spring JdbcClient,部署 PostgreSQL 以及执行向量相似性搜索。
Spring AI支持许多大型语言模型 (LLM) 提供商,每个LLM都有其自己的Spring AI依赖项。
假设您更喜欢使用OpenAI模型和API。那么,您需要将以下依赖项添加到项目中:
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-openai-spring-boot-starter</artifactId>
<version>{latest.version}</version>
</dependency>
此外,在撰写本文时,Spring AI正在积极开发中,框架构件发布在Spring Milestone和/或Snapshot存储库中。因此,如果您在https://start.spring.io/上仍然找不到Spring AI,那么请将存储库添加到pom.xml
文件中:
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<releases>
<enabled>false</enabled>
</releases>
</repository>
</repositories>
OpenAI模块带有几个配置属性,允许管理连接相关设置并微调OpenAI模型的行为。
最少需要提供您的OpenAI API密钥,Spring AI将使用该密钥来访问GPT和嵌入模型。创建密钥后,请将其添加到application.properties
文件中:
spring.ai.openai.api-key=sk-...
然后,如有必要,您可以选择特定的GPT和嵌入模型:
spring.ai.openai.chat.model=gpt-4
spring.ai.openai.embedding.model=text-embedding-ada-002
最后,您可以通过实现一个使用Spring AI的ChatClient
的简单助手来测试OpenAI模块是否配置正确:
// Inject the ChatClient bean
@Autowired
private ChatClient aiClient;
// Create a system message for ChatGPT explaining the task
private static final SystemMessage SYSTEM_MESSAGE = new SystemMessage(
"""
You're an assistant who helps to find lodging in San Francisco.
Suggest three options. Send back a JSON object in the format below.
[{\"name\": \"<hotel name>\", \"description\": \"<hotel description>\", \"price\": <hotel price>}]
Don't add any other text to the response. Don't add the new line or any other symbols to the response. Send back the raw JSON.
""");
public void searchPlaces(String prompt) {
// Create a Spring AI prompt with the system message and the user message
Prompt chatPrompt = new Prompt(List.of(SYSTEM_MESSAGE, new UserMessage(prompt)));
// Send the prompt to ChatGPT and get the response
ChatResponse response = aiClient.generate(chatPrompt);
// Get the raw JSON from the response and print it
String rawJson = response.getGenerations().get(0).getContent();
System.out.println(rawJson);
}
为了进行实验,如果您传递"我想留在金门大桥附近" 提示,那么searchPlaces
方法可能会提供住宿建议,如下所示:
[
{"name": "Cavallo Point", "description": "Historic hotel offering refined rooms, some with views of the Golden Gate Bridge, plus a spa & dining.", "price": 450},
{"name": "Argonaut Hotel", "description": "Upscale, nautical-themed hotel offering Golden Gate Bridge views, plus a seafood restaurant.", "price": 300},
{"name": "Hotel Del Sol", "description": "Colorful, retro hotel with a pool, offering complimentary breakfast & an afternoon cookies reception.", "price": 200}
]
如果您运行前面的代码片段与ChatClient
,您会注意到OpenAI GPT模型通常需要超过10秒来生成响应。该模型具有广泛的深度知识库,需要时间来产生相关的响应。
除了高延迟外,GPT模型可能没有接受对您的应用工作负载相关的数据训练。因此,它可能会生成远非用户满意的响应。
然而,您可以始终加快搜索速度,并在数据的子集上生成嵌入,然后让Postgres处理这些嵌入,从而提供准确的响应给用户。
pgvector扩展允许在Postgres中存储和查询向量嵌入。使用PGVector的最简单方法是在Docker中启动带有此扩展的Postgres实例:
mkdir ~/postgres-volume/
docker run --name postgres \
-e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=password \
-p 5432:5432 \
-v ~/postgres-volume/:/var/lib/postgresql/data -d ankane/pgvector:latest
一旦启动,您可以连接到容器并通过执行CREATE EXTENSION
向量语句启用该扩展:
docker exec -it postgres psql -U postgres -c 'CREATE EXTENSION vector'
最后,将PostgresJDBC驱动程序依赖项添加到pom.xml
文件中:
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>{latest.version}</version>
</dependency>
通过将以下设置添加到application.properties
文件中,配置Spring DataSource:
spring.datasource.url = jdbc:postgresql://127.0.0.1:5432/postgres
spring.datasource.username = postgres
spring.datasource.password = password
最少需要两个步骤才能进行向量相似性搜索。
首先,您需要使用嵌入模型为提供的用户提示或其它文本生成一个向量/嵌入。Spring AI支持连接到OpenAI或其他提供商的嵌入模型和为文本输入生成矢量化表示的EmbeddingClient
:
// Inject the Spring AI Embedding client
@Autowired
private EmbeddingClient aiClient;
public List<Place> searchPlaces(String prompt) {
// Use the Embedding client to generate a vector for the user prompt
List<Double> promptEmbedding = aiClient.embed(prompt);
...
}
其次,您可以使用生成的嵌入在Postgres数据库中执行相似性搜索。例如,您可以使用Spring的JdbcClient
执行此任务:
@Autowired
private JdbcClient jdbcClient;
// Inject the Spring AI Embedding client
@Autowired
private EmbeddingClient aiClient;
public List<Place> searchPlaces(String prompt) {
// Use the Embedding client to generate a vector for the user prompt
List<Double> promptEmbedding = aiClient.embed(prompt);
// Perform the vector similarity search
StatementSpec query = jdbcClient.sql(
"SELECT name, description, price " +
"FROM airbnb_listing WHERE 1 - (description_embedding <=> :user_promt::vector) > 0.7 " +
"ORDER BY description_embedding <=> :user_promt::vector LIMIT 3")
.param("user_promt", promptEmbedding.toString());
// Return the recommended places
return query.query(Place.class).list();
}
description_embedding
列存储了为Airbnb列表概述预先生成的嵌入,网址:来源于description
列。这些Airbnb嵌入是由Spring AI的EmbeddingClient用于用户提示的相同模型产生的。<=>
),然后仅返回那些其描述与所提供的用户提示相似度> 0.7
的Airbnb列表。相似性以0到1的范围内的值进行度量。与1的相似性越接近,向量之间的关系越相关。Spring AI和PostgreSQL的PGVector提供了构建Java中生成式AI应用所需的所有基本功能。如果您想了解更多,请观看这个实用教程。它将指导您通过从头开始创建Java中的住宿推荐服务的过程,利用专门的索引进行相似性搜索优化,并且通过分布式Postgres(YugabyteDB)进行扩展:
推荐阅读: 32. Java的内部类
本文链接: 使用Spring AI和PostgreSQL PGVector入门