Spring AI Alibaba 集成 Redis 向量数据库实现 RAG 与记忆功能
Spring AI Alibaba 集成 Redis 向量数据库实现 RAG 与记忆功能
概述
本文基于一个完整的 Spring Boot 项目示例,详细讲解如何使用 Spring AI Alibaba 框架集成 Redis 向量数据库,实现检索增强生成(RAG)和对话记忆功能。项目包含向量存储、文档加载、多模型配置、记忆管理等核心模块,适用于构建具备知识库检索和上下文记忆的 AI 应用。
项目架构概览
整个项目采用分层架构设计,主要包含以下核心组件:
- 配置层:Redis 连接配置、AI 模型配置、向量存储配置
- 数据层:文档加载器、向量存储实现
- 业务层:RAG 检索、对话记忆管理
- 控制层:RESTful API 接口
一、环境准备与依赖配置
1.1 Maven 依赖配置
在 pom.xml 中配置 Spring AI Alibaba 相关依赖:
<properties><spring-ai.version>1.0.0</spring-ai.version><spring-ai-alibaba.version>1.0.0.2</spring-ai-alibaba.version><spring-boot.version>3.4.5</spring-boot.version><java.version>17</java.version></properties><dependencies><!-- Spring AI Alibaba BOM --><dependency><groupId>com.alibaba.cloud.ai</groupId><artifactId>spring-ai-alibaba-bom</artifactId><version>${spring-ai-alibaba.version}</version><type>pom</type><scope>import</scope></dependency><!-- DashScope 模型支持 --><dependency><groupId>com.alibaba.cloud.ai</groupId><artifactId>spring-ai-alibaba-starter-dashscope</artifactId><version>${spring-ai-alibaba.version}</version></dependency><!-- Redis 记忆存储 --><dependency><groupId>com.alibaba.cloud.ai</groupId><artifactId>spring-ai-alibaba-starter-memory-redis</artifactId><version>${spring-ai-alibaba.version}</version></dependency><!-- 向量存储核心 --><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-vector-store</artifactId><version>${spring-ai.version}</version></dependency><!-- Redis 客户端 --><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId></dependency><!-- 其他基础依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency></dependencies>1.2 配置文件(application.yml)
spring:data:redis:host: localhost port:6379password:123456lettuce:pool:max-active:16max-idle:8min-idle:4timeout: 2000ms servlet:multipart:max-file-size: 100MB max-request-size: 100MB application:name: Roadnetworktraffic ai:vectorstore:redis:initialize-schema:trueindex-name: custom-index prefix: custom-prefix dashscope:embedding:baseUrl: https://dashscope.aliyuncs.com # 向量模型api-key: your-api-key-here options:model: text-embedding-v4 api-key: your-api-key-here base-url: https://dashscope.aliyuncs.com/compatible-mode/v1 chat:options:model: qwen-flash 关键配置说明:
spring.data.redis:Redis 连接配置,用于向量存储和记忆存储spring.ai.vectorstore.redis:向量存储的 Redis 索引配置spring.ai.dashscope:通义千问模型配置,包括嵌入模型和对话模型
二、核心组件实现
2.1 Redis 记忆存储配置
@ConfigurationpublicclassRedisMemoryConfig{@Value("${spring.data.redis.host}")privateString host;@Value("${spring.data.redis.port}")privateint port;@Value("${spring.data.redis.password}")privateString password;@BeanpublicRedisChatMemoryRepositoryredisChatMemoryRepository(){returnRedisChatMemoryRepository.builder().host(host).password(password).port(port).build();}}功能说明:
- 通过
@Value注入配置文件中的 Redis 连接参数 - 创建
RedisChatMemoryRepositoryBean,用于存储对话历史 - 支持多会话隔离,每个会话 ID 对应独立的记忆存储
2.2 多模型配置(DeepSeek + Qwen)
@ConfigurationpublicclassSaaLLMConfig{@Value("${spring.ai.dashscope.api-key}")privateString apiKey;// 模型名称常量privatefinalString DEEPSEEK_MODEL ="deepseek-v3.2";privatefinalString QWEN_MODEL ="qwen-flash";@Bean(name ="deepseek")publicChatClientdeepSeek(RedisChatMemoryRepository redisChatMemoryRepository){DashScopeChatModel dashScopeChatModel =DashScopeChatModel.builder().dashScopeApi(DashScopeApi.builder().apiKey(apiKey).build()).defaultOptions(DashScopeChatOptions.builder().withModel(DEEPSEEK_MODEL).build()).build();returnChatClient.builder(dashScopeChatModel).defaultAdvisors(MessageChatMemoryAdvisor.builder(MessageWindowChatMemory.builder().chatMemoryRepository(redisChatMemoryRepository).maxMessages(10).build()).build()).defaultOptions(ChatOptions.builder().model(DEEPSEEK_MODEL).build()).build();}@Bean(name ="qwen")publicChatClientqwen(RedisChatMemoryRepository redisChatMemoryRepository){DashScopeChatModel dashScopeChatModel =DashScopeChatModel.builder().dashScopeApi(DashScopeApi.builder().apiKey(apiKey).build()).defaultOptions(DashScopeChatOptions.builder().withModel(QWEN_MODEL).build()).build();returnChatClient.builder(dashScopeChatModel).defaultAdvisors(MessageChatMemoryAdvisor.builder(MessageWindowChatMemory.builder().chatMemoryRepository(redisChatMemoryRepository).maxMessages(10).build()).build()).defaultOptions(ChatOptions.builder().model(QWEN_MODEL).build()).build();}}核心特性:
- 多模型支持:通过
@Qualifier和@Bean(name)实现多模型注入 - 记忆集成:每个模型都配置了
MessageChatMemoryAdvisor,自动管理对话历史 - 记忆窗口:
maxMessages(10)限制每个会话最多保留 10 条消息,避免内存溢出
2.3 文档加载与向量存储
2.3.1 文档加载器
@Slf4j@ComponentpublicclassAppDocumentLoader{@Value("classpath:/prompt/Gompt.txt")privateResource opsFile;publicList<Document>loadMarkdowns(){TextReader textReader =newTextReader(opsFile); textReader.setCharset(Charset.defaultCharset());// 使用 TokenTextSplitter 进行文本分割List<Document> list =newTokenTextSplitter().transform(textReader.read());return list;}}关键点:
- 使用
TextReader读取本地文档(支持多种格式) TokenTextSplitter对长文本进行分块,便于向量化- 返回
Document列表,每个文档包含内容和元数据
2.3.2 向量存储 Bean
@ConfigurationpublicclassVectorStoreBean{@ResourceprivateAppDocumentLoader appDocumentLoader;@ResourceprivateEmbeddingModel embeddingModel;@BeanpublicVectorStorevectorStore(){// 创建 SimpleVectorStore(底层使用 Redis)VectorStore build =SimpleVectorStore.builder(embeddingModel).build();// 加载文档并添加到向量库List<Document> documents = appDocumentLoader.loadMarkdowns(); build.add(documents);return build;}}RAG 核心流程:
- 通过
SimpleVectorStore.builder()创建向量存储实例 - 调用
appDocumentLoader.loadMarkdowns()加载本地文档 - 使用
build.add(documents)将文档向量化并存储到 Redis - 应用启动时自动完成知识库构建
三、RESTful API 实现
3.1 控制器层
@RestController@RequestMapping("/aichat/stream")@Slf4jpublicclassAiController{@Qualifier("deepseek")@AutowiredprivateChatClient deepseekModel;@Qualifier("qwen")@AutowiredprivateChatClient qwenModel;@AutowiredprivateVectorStore vectorStore;@Value("classpath:/prompt/story-prompt.txt")privateResource storyPrompt;@GetMapping(value ="/deepseek")publicFlux<String>chatDeepseek(@RequestParamString sessionId,@RequestParamString userContent){return deepseekModel.prompt().system(storyPrompt)// 系统提示词.user(userContent)// 用户输入.advisors(message ->{// 设置会话 ID,用于记忆隔离if(message !=null){ message.param(CONVERSATION_ID, sessionId);}}).advisors(RetrievalAugmentationAdvisor.builder().documentRetriever(VectorStoreDocumentRetriever.builder().vectorStore(vectorStore).build()).build()).stream()// 流式输出.content().doOnError(e -> log.error("Stream error: "+ e.getMessage()));}@GetMapping("/qwen")publicFlux<String>chatQwen(@RequestParamString sessionId,@RequestParamString userContent){return qwenModel.prompt().system(storyPrompt).user(userContent).advisors(message ->{if(message !=null){ message.param(CONVERSATION_ID, sessionId);}}).stream().content().doOnError(e -> log.error("Stream error: "+ e.getMessage()));}}API 特性:
| 接口路径 | 方法 | 参数 | 功能 |
|---|---|---|---|
/aichat/stream/deepseek | GET | sessionId, userContent | DeepSeek 模型流式对话(带 RAG) |
/aichat/stream/qwen | GET | sessionId, userContent | Qwen 模型流式对话 |
核心功能实现:
- RAG 检索增强:
- 通过
RetrievalAugmentationAdvisor集成向量检索 - 用户提问时,自动从向量库检索相关文档片段
- 将检索结果作为上下文注入到模型提示词中
- 通过
- 记忆管理:
message.param(CONVERSATION_ID, sessionId)设置会话标识- 同一会话 ID 的对话会共享历史上下文
- 支持多用户、多会话并行处理
- 流式响应:
- 使用
.stream()返回Flux<String>实现流式输出 - 支持 SSE(Server-Sent Events)协议,前端可实时接收
- 使用
四、RAG 与记忆功能原理解析
4.1 检索增强生成(RAG)工作流程
用户提问 → 向量化查询 → Redis 向量库相似度检索 → 获取 top-k 相关文档 ↓ 构建提示词(系统提示 + 检索文档 + 历史对话 + 用户问题) ↓ 调用 AI 模型生成 → 返回响应 检索过程:
- 用户输入的问题被
text-embedding-v4模型向量化 - 在 Redis 向量索引中执行相似度搜索(默认使用余弦相似度)
- 返回最相关的文档片段作为上下文
4.2 对话记忆实现机制
Spring AI 通过 ChatMemory 抽象层管理对话状态:
// 记忆存储接口publicinterfaceChatMemory{voidadd(ChatMessage message);List<ChatMessage>getMessages();voidclear();}// Redis 实现publicclassRedisChatMemoryimplementsChatMemory{// 使用 Redis 存储,key 格式:memory:sessionId}记忆存储结构:
- 每个会话 ID 对应一个独立的 Redis key
- 使用 List 结构存储消息序列
- 支持 LRU 淘汰策略(通过
maxMessages控制)
4.3 向量存储底层实现
SimpleVectorStore 底层使用 Redis 作为存储引擎:
publicclassRedisVectorStoreimplementsVectorStore{// 使用 RedisSearch 模块创建向量索引publicvoidcreateIndex(String indexName,VectorFieldSchema fieldSchema){// 创建 HNSW 索引 FT.CREATE indexName ...}publicvoidadd(List<Document> documents){// 调用 embeddingModel 生成向量List<Float> vector = embeddingModel.embed(document.getContent());// 存储到 Redis Hash redis.hset(key,"vector", vector,"content", content);}}技术栈:
- Redis 7.0+ 支持向量搜索(需启用 RedisSearch 模块)
- HNSW(Hierarchical Navigable Small World)索引算法
- 支持余弦相似度、欧氏距离等多种相似度计算
五、部署与测试
5.1 环境要求
- JDK 17+
- Redis 7.0+(需启用 RedisSearch 模块)
- Maven 3.6+
- 通义千问 API Key(用于模型调用)
5.2 Redis 配置
启动 Redis 时需启用模块:
redis-server --loadmodule /path/to/redisearch.so 或使用 Docker:
docker run -p 6379:6379 redislabs/redisearch:latest 5.3 应用启动
mvn clean package java -jar target/your-app.jar 5.4 API 测试
测试 RAG 功能:
# 测试 DeepSeek 模型(带 RAG)curl"http://localhost:8080/aichat/stream/deepseek?sessionId=test123&userContent=什么是GIS?"# 测试 Qwen 模型(不带 RAG)curl"http://localhost:8080/aichat/stream/qwen?sessionId=test123&userContent=你好"测试记忆功能:
# 第一次对话curl"http://localhost:8080/aichat/stream/deepseek?sessionId=user1&userContent=我叫张三"# 第二次对话(会记住上下文)curl"http://localhost:8080/aichat/stream/deepseek?sessionId=user1&userContent=我的名字是什么?"六、常见问题与优化建议
6.1 性能优化
向量检索优化:
- 调整 HNSW 索引参数(M、ef_construction)
- 使用 GPU 加速嵌入模型计算
- 对文档进行预处理(去重、关键信息提取)
内存优化:
- 合理设置
maxMessages,避免内存泄漏 - 使用 Redis 集群分担存储压力
- 定期清理过期会话
6.2 功能扩展
多知识库支持:
@Bean(name ="vectorStoreA")publicVectorStorevectorStoreA(){...}@Bean(name ="vectorStoreB")publicVectorStorevectorStoreB(){...}// 根据业务场景选择不同的向量库混合检索策略:
- 结合关键词检索 + 向量检索
- 实现多路召回 + 重排序
- 支持元数据过滤(文档来源、时间范围等)
6.3 监控与日志
- 集成 Spring Boot Actuator 监控指标
- 记录向量检索耗时、模型调用延迟
- 设置告警阈值(如响应时间 > 3s)
七、总结
本文通过完整可运行的代码示例,详细介绍了 Spring AI Alibaba 集成 Redis 向量数据库实现 RAG 和记忆功能的完整方案。核心要点包括:
- 配置简化:Spring AI 提供了声明式配置,大幅降低集成复杂度
- 开箱即用:向量存储、记忆管理、模型调用等组件可快速集成
- 生产就绪:支持流式响应、多会话隔离、性能优化等生产特性
- 扩展性强:支持多模型、多知识库、自定义检索策略
该方案适用于智能客服、知识问答、文档检索等多种 AI 应用场景,具备良好的可维护性和扩展性。
源码地址:本文示例代码已整理到 GitHub,可访问 [项目地址] 获取完整可运行项目。
注意事项:
- 确保 Redis 已安装并启用 RedisSearch 模块
- 替换配置文件中的 API Key 为实际值
- 根据业务需求调整向量索引参数和记忆窗口大小
通过本文的实践,您可以快速构建具备 RAG 和记忆能力的 AI 应用,提升用户体验和回答准确性。