Spring AI 01:使用 Redis 和 Spring AI 构建 RAG 应用

1 概述

这里将基于 Spring AI 框架与 RAG(检索增强生成) 技术实现一个聊天机器人。借助 Spring AI,接入 Redis 向量数据库,完成数据的存储与检索,用来给大模型的提示词补充上下文信息。 当大模型拿到附带相关资料的提示词之后,就可以基于最新数据,用自然语言生成对用户问题的回答。

2 什么是 RAG

大语言模型是基于互联网海量数据集预训练得到的机器学习模型。如果要让大模型适配企业内部业务场景,通常需要使用企业专属知识库对模型做微调。 但微调非常耗费时间,需要大量算力资源;并且经过微调后的大模型依然很可能输出无关、误导性内容,该现象就是大模型幻觉(hallucinations)。

面对这类问题,RAG 是非常优秀的方案,可以约束大模型输出,给回答补充业务上下文。 向量数据库在RAG架构中扮演关键角色,负责为大模型提供上下文资料。但在投入RAG使用前,需要通过 ETL(抽取‑转换‑加载) 流程完成数据入库:

  1. 读取器(Reader):从各类来源读取企业知识库文档;
  2. 转换器(Transformer):把文档切分成小块(分片chunk),调用嵌入模型把文本转为向量;
  3. 写入器(Writer):将向量(嵌入向量)存入向量数据库。

向量数据库是专门用于在多维空间存储向量数据的专用数据库。

只要向量数据库定期从企业知识库同步更新数据,RAG架构下大模型就可以近乎实时地使用最新业务数据回答问题。

向量数据库准备好数据之后,应用就可以针对用户提问检索上下文资料:

流程简述:

  1. 应用接收用户查询,向向量数据库发起语义检索;
  2. 获取语义检索返回的相关文档;
  3. 将用户提问 + 检索得到的上下文拼接为完整提示词发给大模型;
  4. 大模型严格基于提供的上下文生成回答,返回给应用。

大模型会在给定上下文资料的范围内生成自然语言回答,再把结果返回应用程序。

3 使用 Spring AI + Redis 实现RAG

Redis Stack 提供向量检索能力。我们将通过 Spring AI 对接该能力,开发基于RAG的聊天机器人;同时选用 OpenAI 的 GPT‑3.5‑Turbo 作为生成回答的大模型。

3.1 环境准备

要调用OpenAI服务,需要API密钥。注册OpenAI账号后,即可创建密钥。

还需要注册 Redis Cloud 账号,获取免费可用的Redis向量数据库实例。

引入Maven依赖,接入Redis向量库与OpenAI:

3.2 向Redis加载数据的核心类

在Spring Boot项目中,我们需要编写组件,完成Redis向量库的数据写入与读取。示例场景:把一份员工手册PDF文档加载进Redis向量库。

类关系说明:

  1. DocumentReader:Spring AI 读取文档的接口;示例使用内置实现 PagePdfDocumentReader 读取PDF;
  2. DocumentWriter:文档写入接口;
  3. VectorStore:向量存储读写接口,提供保存、删除、相似度搜索;
  4. RedisVectorStore:VectorStore 的Redis实现,用于Redis向量库的写入和检索;
  5. DataLoaderService:业务服务,组合上述组件,完成PDF文档导入。

3.3 实现数据加载服务 DataLoaderService

load() 方法完整实现:

Spring AI 会读取 spring.ai.vectorstore 命名空间下配置,自动装配VectorStore接口,实际注入的实现是RedisVectorStore。

application.yml Redis向量库配置:

TokenTextSplitter 负责把文档切分为文本块(chunk),再交由VectorStore存入Redis向量数据库。

3.4 生成最终回答的核心类

Redis向量库数据就绪之后,就可以根据用户提问检索相关上下文;再把上下文拼入提示词交给大模型生成回答。

类关系说明:

  1. DataRetrievalService:数据检索服务,调用VectorStore.similaritySearch(),根据用户query检索相关Document文档列表;
  2. PromptTemplate:提示词模板,把用户提问和检索出来的上下文拼装成完整prompt;
  3. ChatBotService:聊天机器人业务服务,调用检索服务,拼装提示词,调用大模型;
  4. ChatModel:大模型调用接口,OpenAiChatModel为OpenAI的实现。

Spring Boot读取配置文件,自动装配OpenAiChatModelBean。本示例激活Spring profile为airag。

3.5 实现聊天机器人服务 ChatBotService

OpenAI相关配置(application.yml):

最佳实践:API密钥优先使用环境变量SPRING_AI_OPENAI_API_KEY,更加安全。 开启embedding开头的配置项,会自动创建OpenAiEmbeddingModel,用于文档文本生成向量。

提示词模板做了严格约束:回答必须严格基于传入的上下文资料,不能使用模型内部知识编造答案。

chat()方法执行流程:

  1. 根据用户提问,从Redis向量库检索匹配的文档;
  2. createPrompt()把检索结果+用户问题拼装完整提示词;
  3. 调用ChatModel.call(),请求OpenAI获取回答。

单元测试:提问知识库范围内的问题(员工着装规范)

输出结果:

回答完全来自导入的员工手册PDF文档。

单元测试:提问知识库不存在的问题

输出:

当上下文找不到相关资料,模型直接返回预设话术,拒绝编造答案。

4 总结

本文演示了如何基于Spring AI实现RAG架构应用。将检索得到的上下文和用户提问拼装提示词,是获得准确大模型回答的关键。 Redis向量数据库非常适合存储文档向量并执行相似度检索。

同时文档分片(chunking)也至关重要:既能够检索到精准的参考片段,又可以控制提示词Token开销,避免成本过高。

原文:Create a RAG Application with Redis and Spring AI