向量数据库经常充当 AI 应用的内存。对于那些由大型语言模型(LLM)驱动的应用来说尤其如此。向量数据库允许您执行语义搜索,这为提示 LLM 提供了相关的上下文。
直到最近,使用 Spring 和 Redis 构建 AI 应用的选择还不多。现在,Redis 作为高性能向量数据库越来越受欢迎。而 Spring 社区推出了一个名为 Spring AI 的新项目,旨在简化 AI 驱动应用(包括那些利用向量数据库的应用)的开发。
让我们看看如何构建一个使用 Redis 作为其向量数据库的 Spring AI 应用,重点是实现检索增强生成(RAG)工作流程。
检索增强生成(RAG)是一种用于将数据与 AI 模型集成起来的技术。在 RAG 工作流程中,第一步是将数据加载到向量数据库(例如 Redis)中。当接收到用户查询时,向量数据库检索一组与查询相似的文档。然后,这些文档作为用户问题的上下文,并与用户查询结合使用,通常通过 AI 模型生成响应。
在此示例中,我们将使用一个包含啤酒信息的数据集,其中包括每种啤酒的名称、酒精度(ABV)、国际苦度单位(IBU)以及描述等属性。该数据集将加载到 Redis 中以演示 RAG 工作流程。
您可以在 Github 上找到 Spring AI 和 Redis 演示的所有代码。
本项目使用了 Web 应用常用的 Spring Boot starter 依赖项,以及 Azure OpenAI 和 Spring AI Redis。
我们将用于应用的数据由提供啤酒信息的 JSON 文档组成。每个文档具有以下结构
{
"id": "00gkb9",
"name": "Smoked Porter Ale",
"description": "The Porter Pounder Smoked Porter is a dark rich flavored ale that is made with 5 malts that include smoked and chocolate roasted malts. It has coffee and mocha notes that create a long finish that ends clean with the use of just a bit of dry hopping",
"abv": 8,
"ibu": 36
}
要将此啤酒数据集加载到 Redis 中,我们将使用 RagDataLoader 类。此类包含一个在应用启动时执行的 run 方法。在该方法中,我们使用 JsonReader 解析数据集,然后使用自动注入的 VectorStore 将文档插入到 Redis 中。
// Create a JSON reader with fields relevant to our use case
JsonReader loader = new JsonReader(file, "name", "abv", "ibu", "description");
// Use the autowired VectorStore to insert the documents into Redis
vectorStore.add(loader.get());
此时,我们拥有大约 22,000 种啤酒及其对应嵌入的数据集。
RagService 类实现了 RAG 工作流程。当收到用户提示时,会调用 retrieve 方法,该方法执行以下步骤
public Generation retrieve(String message) {
SearchRequest request = SearchRequest.query(message).withTopK(topK);
// Query Redis for the top K documents most relevant to the input message
List<Document> docs = store.similaritySearch(request);
Message systemMessage = getSystemMessage(docs);
UserMessage userMessage = new UserMessage(message);
// Assemble the complete prompt using a template
Prompt prompt = new Prompt(List.of(systemMessage, userMessage));
// Call the autowired chat client with the prompt
ChatResponse response = client.call(prompt);
return response.getResult();
}
现在我们已经实现了 RAG 服务,我们可以将其封装在一个 HTTP 端点中。
RagController 类将服务暴露为 POST 端点
@PostMapping("/chat/{chatId}")
@ResponseBody
public Message chatMessage(@PathVariable("chatId") String chatId, @RequestBody Prompt prompt) {
// Extract the user prompt from the body and pass it to the autowired RagService
Generation generation = ragService.retrieve(prompt.getPrompt());
// Reply with the generated message
return Message.of(generation.getOutput().getContent());
}
对于用户界面,我们创建了一个简单的 React 前端,允许用户询问有关啤酒的问题。前端通过向 /chat/{chatId} 端点发送 HTTP 请求并显示响应来与 Spring 后端交互。
就这样——只需几个类,我们就使用 Spring AI 和 Redis 实现了一个 RAG 应用。
下一步,我们鼓励您查看 Github 上的示例代码。如果您有任何问题或疑问,请随时提交工单。将 Redis 的速度和易用性与 Spring AI 提供的便捷抽象相结合,使得 Java 开发人员更容易使用 Spring 构建响应式 AI 应用。我们迫不及待地想看看您会构建出什么。