ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Redisson Spring AI Vector Store 实战指南:基于 Redis Stack 构建 RAG、语义搜索与 AI Agent 记忆层

Redisson Spring AI Vector Store 实战指南:基于 Redis Stack 构建 RAG、语义搜索与 AI Agent 记忆层 Redisson Spring AI Vector Store 实战指南基于 Redis Stack 构建 RAG、语义搜索与 AI Agent 记忆层【免费下载链接】redissonRedisson: Valkey Redis Java Client and Real-Time Data Platform. Sync/Async/RxJava/Reactive API. Over 50 Valkey and Redis based Java objects and services: Set, Multimap, SortedSet, Map, List, Queue, Deque, Semaphore, Lock, AtomicLong, Map Reduce, Bloom filter, Spring, Tomcat, Scheduler, JCache API, Hibernate, RPC, local cache..项目地址: https://gitcode.com/GitHub_Trending/re/redisson导读本文以 Redisson 提供的 Spring AI Vector Store 实现为主线讲解如何在 Spring Boot 应用中把向量嵌入Embedding、文档内容与元数据持久化到 Redis基于 RediSearch 与 RedisJSON 模块并利用 KNN 相似度索引完成检索增强生成RAG、语义搜索、内容推荐与 AI Agent 长期记忆等场景。读完本文你将掌握该 Vector Store 的依赖引入、自动/手动配置、向量索引参数调优、元数据过滤语法以及四个可直接落地的业务示例。说明该功能仅随Redisson PRO版提供。Community开源版不包含 Spring AI Vector Store 实现。概述Redisson 如何实现 Spring AI Vector StoreRedisson 提供了 Spring AI 官方VectorStore接口的完整实现用于构建 AI 驱动的应用。它覆盖的核心场景包括检索增强生成RAG把业务文档向量化后作为 LLM 回答的上下文来源语义搜索基于含义而非关键词匹配的搜索适配文档检索、知识库、商品目录等文档相似度与内容推荐找出与给定文档或用户行为语义相近的内容AI Agent 记忆把对话轮次、事实与偏好持久化为向量为多轮对话提供长期记忆。从存储机制看该实现使用Redis JSON 文档持久化向量嵌入及其关联的文档内容与元数据并借助RediSearch创建与查询向量相似度索引Vector Similarity Index。核心特性一览基于 KNNK-Nearest Neighbors的向量相似度检索支持 HNSW 与 FLAT 两种向量索引算法支持 COSINE、L2欧氏距离、Inner Product 三种距离度量可配置的元数据字段TEXT / TAG / NUMERIC支持高级过滤自动 schema 初始化需显式开启可移植的过滤表达式自动翻译为 Redis 查询语法批量处理支持面向自然语言语料的语义搜索、文档相似度与推荐、AI Agent 持久化记忆。前置条件使用前需要准备两样东西Redis 实例需要Redis Stack或Redis 8.4且必须启用RediSearch与RedisJSON两个模块向量索引由 RediSearch 提供JSON 文档存储由 RedisJSON 提供。EmbeddingModel 实例用于计算文档的向量嵌入。Spring AI 官方提供了多种实现可选OpenAI通过OpenAiEmbeddingModel接入Ollama本地模型如OllamaEmbeddingModelSpring AI 支持的其他 Embedding 提供方如 Azure OpenAI、HuggingFace、Mistral 等可参考 Spring AI 官方 Embedding 实现清单。Redisson PRO 许可证由于该功能属于 PRO 版本能力还需要按 License key configuration 配置许可证。Redisson PRO 支持多种许可证配置方式按优先级从高到低程序化 / YAML 配置Config config new Config(); config.setRegistrationKey(YOUR_LICENSE_KEY);或在 Redisson YAML 配置文件中设置registrationKey: YOUR_LICENSE_KEYJVM 系统属性-Dredisson.pro.keyYOUR_LICENSE_KEYRedis/Valkey 存储redis-cli SET redisson.pro.key YOUR_LICENSE_KEY支持动态更新无需重启。快速开始第 1 步添加依赖Spring Boot Starter推荐——适用于需要自动配置auto-configuration的 Spring Boot 应用Mavendependency groupIdpro.redisson/groupId artifactIdredisson-spring-ai-store-starter-10/artifactId versionxVERSIONx/version /dependencyGradlecompile pro.redisson:redisson-spring-ai-store-starter-10:xVERSIONx仅 Store 实现——适用于手动配置或非 Spring Boot 应用Mavendependency groupIdpro.redisson/groupId artifactIdredisson-spring-ai-store-10/artifactId versionxVERSIONx/version /dependencyGradlecompile pro.redisson:redisson-spring-ai-store-10:xVERSIONxxVERSIONx为版本占位符请替换为你实际使用的 Redisson 版本号。同时记得配置 License key configuration。第 2 步在application.yaml中添加配置spring: ai: vectorstore: redisson: index-name: my-index prefix: doc: initialize-schema: true vector-algorithm: HNSW distance-metric: COSINE hnsw: m: 16 ef-construction: 200 ef-runtime: 10 metadata-fields: - name: category type: TAG - name: year type: NUMERIC第 3 步在应用中注入并使用 VectorStoreAutowired VectorStore vectorStore; // ... ListDocument documents List.of( new Document(Spring AI rocks!! Spring AI rocks!!, Map.of(category, framework, year, 2024)), new Document(The World is Big and Salvation Lurks Around the Corner), new Document(You walk forward facing the past and you turn back toward the future., Map.of(category, philosophy, year, 2023))); // 将文档写入 Redis vectorStore.add(documents); // 检索与查询相似的文档 ListDocument results vectorStore.similaritySearch( SearchRequest.builder() .query(Spring) .topK(5) .build());vectorStore.add()会为每个Document调用EmbeddingModel生成向量嵌入连同文本内容与元数据一起以 JSON 文档形式写入 RedissimilaritySearch()则在 RediSearch 向量索引上执行 KNN 查询并返回按相似度排序的文档列表。配置详解所有以spring.ai.vectorstore.redisson.*开头的属性都用于配置 Vector StorePropertyDescriptionDefault Valuespring.ai.vectorstore.redisson.index-nameRedis 搜索索引的名称spring-ai-indexspring.ai.vectorstore.redisson.prefixRedis key 的前缀embedding:spring.ai.vectorstore.redisson.initialize-schema是否初始化所需 schema自动建索引falsespring.ai.vectorstore.redisson.vector-algorithm向量索引算法HNSW或FLATHNSWspring.ai.vectorstore.redisson.distance-metric距离度量COSINE、L2或IPCOSINE特别提醒initialize-schema必须显式设置为true才能自动创建索引。这是相对早期 Spring AI 版本的破坏性变更——旧版本默认自动初始化 schema新版本改为了默认关闭升级时需要注意。向量索引算法HNSWHierarchical Navigable Small World——默认算法以略高的内存占用换取更好的搜索性能适用于大多数场景。其核心参数m控制每个节点创建的双向连接数。取值越大召回率越高但内存占用越大。推荐范围 12–48。ef-construction决定索引构建期间的搜索宽度。取值越大索引质量越高但构建时间越长。取值应至少为2 * m推荐范围 100–500。ef-runtime控制查询时的搜索精度。取值越大召回率越高但查询延迟越高。推荐范围 10–100。HNSW 参数配置项PropertyDescriptionDefault Valuespring.ai.vectorstore.redisson.hnsw.m每个节点的最大连接数16spring.ai.vectorstore.redisson.hnsw.ef-construction索引构建期间搜索宽度200spring.ai.vectorstore.redisson.hnsw.ef-runtime查询执行期间搜索宽度10FLAT——暴力brute force算法结果精确但数据集较大时性能较慢。仅在需要绝对精确且数据集规模较小时使用。元数据字段Metadata Fields元数据字段让相似度搜索具备过滤能力。任何在过滤表达式中使用的元数据字段都必须先在配置中显式声明字段名与类型。支持的字段类型TypeDescriptionUse CaseTAG精确匹配过滤分类数据、标签、状态值TEXT全文搜索描述、内容字段NUMERIC范围查询年份、价格、数量、分数完整配置示例spring: ai: vectorstore: redisson: index-name: my-index prefix: doc: initialize-schema: true vector-algorithm: HNSW distance-metric: COSINE hnsw: m: 16 ef-construction: 200 ef-runtime: 10 metadata-fields: - name: category type: TAG - name: description type: TEXT - name: year type: NUMERIC - name: price type: NUMERIC距离度量Distance MetricsMetricDescriptionBest ForCOSINE余弦相似度默认文本嵌入、语义相似度L2欧氏距离图像嵌入、空间数据IP内积Inner Product已归一化的嵌入向量每种度量都会被自动归一化为 0–1 的相似度分数其中 1 表示最大相似度便于在应用中用统一的similarityThreshold进行阈值过滤。元数据过滤Redisson Vector Store 支持 Spring AI 通用的元数据过滤器metadata filters有两种写法。方式一文本表达式语言text expression languagevectorStore.similaritySearch(SearchRequest.builder() .query(The World) .topK(5) .similarityThreshold(0.7) .filterExpression(country in [UK, NL] year 2020) .build());方式二编程式 Filter.Expression DSLFilterExpressionBuilder b new FilterExpressionBuilder(); vectorStore.similaritySearch(SearchRequest.builder() .query(The World) .topK(5) .similarityThreshold(0.7) .filterExpression(b.and( b.in(country, UK, NL), b.gte(year, 2020)).build()) .build());两种写法的过滤表达式都会被自动转换为 Redis 搜索查询。例如可移植过滤表达式country in [UK, NL] year 2020会被转换为 Redis 过滤格式country:{UK | NL} year:[2020 inf]也就是说TAG类型字段会落入field:{value1 | value2}精确匹配语法NUMERIC类型字段会落入field:[min max]范围语法这也是为什么使用过滤的元数据字段必须预先声明类型。手动配置非自动配置方式如果不使用 Spring Boot 自动配置可以手动装配RedissonVectorStore。RedissonVectorStore.builder()提供了与 YAML 配置一一对应的链式方法Configuration public class VectorStoreConfig { Bean(destroyMethod shutdown) public RedissonClient redisson() { Config config new Config(); config.useSingleServer() .setAddress(redis://127.0.0.1:6379); return Redisson.create(config); } Bean public VectorStore vectorStore(RedissonClient redissonClient, EmbeddingModel embeddingModel) { return RedissonVectorStore.builder(redissonClient, embeddingModel) .indexName(custom-index) .prefix(custom-prefix) .vectorAlgorithm(Algorithm.HNSW) .distanceMetric(DistanceMetric.COSINE) .hnswM(16) .hnswEfConstruction(200) .hnswEfRuntime(10) .metadataFields( MetadataField.tag(category), MetadataField.numeric(year), MetadataField.text(description)) .initializeSchema(true) .build(); } Bean public EmbeddingModel embeddingModel() { // 配置你的嵌入模型OpenAI、Ollama 等 return new OpenAiEmbeddingModel(new OpenAiApi(System.getenv(OPENAI_API_KEY))); } }可以看到builder中indexName、prefix、vectorAlgorithm、distanceMetric、hnswM/hnswEfConstruction/hnswEfRuntime、metadataFields、initializeSchema等选项与application.yaml中的spring.ai.vectorstore.redisson.*属性一一对应两者可自由选择。源码级实现佐证在深入业务示例前先从源码层面印证一下 Redisson 的向量能力底座。Redisson 核心模块redisson本身提供了基于 Redis 8.0 原生向量命令的RVectorSet接口其实现位于 RedissonVectorSet.javaSpring AI Vector Store 正是构建在这一类向量能力之上的高层封装。写入add()通过VADD命令写入向量支持FP32/VALUES两种向量入参、REDUCE降维、CAS原子写入、SETATTR附加属性、EF查询精度、M最大连接数等参数见 RedissonVectorSet.java检索getSimilar()/getSimilarEntries()分别通过VSIM、VSIM WITHSCORES、VSIM WITHSCORESATTRIBS命令返回相似元素及分数见 RedissonVectorSet.java维度与容量size()通过VCARD获取元素数量dimensions()返回向量维度测试佐证仓库在 RedissonVectorSetTest.java 中通过redisson.getVectorSet(name)VectorAddArgs.element(...).vector(...)完成向量集的写入与相似度断言可作为理解底层 API 用法的参考功能发布记录CHANGELOG 中记录了 Spring AI Vector Store implemented 这一功能项。Spring AI Vector Store 在这些底层向量命令之上进一步负责EmbeddingModel调用、JSON 文档建模RedisJSON、RediSearch 索引定义与过滤表达式翻译屏蔽了底层细节。实战示例一RAG 集成将 Vector Store 与 Spring AI 的ChatClient组合即可实现完整的检索增强生成流程先按问题检索相关文档作为上下文再让 LLM 基于上下文作答。Service public class RagService { private final ChatClient chatClient; private final VectorStore vectorStore; public RagService(ChatClient.Builder chatClientBuilder, VectorStore vectorStore) { this.chatClient chatClientBuilder.build(); this.vectorStore vectorStore; } public String askQuestion(String question) { // 检索相关文档 ListDocument relevantDocs vectorStore.similaritySearch( SearchRequest.builder() .query(question) .topK(3) .similarityThreshold(0.7) .build() ); // 从检索结果构建上下文 String context relevantDocs.stream() .map(Document::getContent) .collect(Collectors.joining(\n\n)); // 携带上下文生成回答 return chatClient.prompt() .user(u - u.text( Based on the following context, answer the question. Context: {context} Question: {question} ) .param(context, context) .param(question, question)) .call() .content(); } }关键点similarityThreshold(0.7)过滤掉相似度低于 0.7 的文档避免把不相关内容喂给 LLMtopK(3)控制上下文规模在回答质量与 token 成本之间取得平衡。实战示例二语义搜索与关键词搜索不同语义搜索基于含义而非精确词匹配返回结果特别适合文档搜索、支持知识库、商品目录以及用户提问措辞不可预期的语料场景。在application.yaml中配置用于过滤的元数据字段spring: ai: vectorstore: redisson: index-name: semantic-search-index prefix: doc: initialize-schema: true metadata-fields: - name: source type: TAG - name: category type: TAG索引文档并执行语义查询Service public class SemanticSearchService { private final VectorStore vectorStore; public SemanticSearchService(VectorStore vectorStore) { this.vectorStore vectorStore; } // 索引文档 public void indexDocuments(ListString texts, String source) { ListDocument documents texts.stream() .map(text - new Document(text, Map.of(source, source))) .toList(); vectorStore.add(documents); } // 按自然语言查询 public ListDocument search(String query, int topK) { return vectorStore.similaritySearch( SearchRequest.builder() .query(query) .topK(topK) .similarityThreshold(0.7) .build()); } // 限定来源的元数据过滤搜索 public ListDocument searchBySource(String query, String source) { return vectorStore.similaritySearch( SearchRequest.builder() .query(query) .topK(5) .similarityThreshold(0.7) .filterExpression(source source ) .build()); } }使用示例// 索引来自已知来源的文档 searchService.indexDocuments(List.of( Spring Boot simplifies Java application development, Docker containers enable consistent deployments, Kubernetes orchestrates containerized workloads, PostgreSQL is a powerful open-source relational database ), knowledge-base); // 跨全部索引文档搜索——返回与容器、编排相关的结果 ListDocument results searchService.search(how do I deploy my app reliably, 5); // 仅在某来源范围内搜索 ListDocument scoped searchService.searchBySource(relational database options, knowledge-base);注意searchBySource中使用的source xxx过滤表达式依赖source字段被声明为TAG类型这正体现了过滤表达式自动转换为 Redis 查询的设计。实战示例三文档相似度与内容推荐向量嵌入可以为基于内容的推荐引擎提供动力——找出与指定条目或用户近期行为语义相近的文章、产品或文档。配置元数据字段spring: ai: vectorstore: redisson: index-name: recommendations-index prefix: article: initialize-schema: true metadata-fields: - name: articleId type: TAG - name: title type: TEXT - name: category type: TAG存储文章并获取推荐Service public class RecommendationService { private final VectorStore vectorStore; public RecommendationService(VectorStore vectorStore) { this.vectorStore vectorStore; } // 存储带元数据的文章 public void addArticle(String id, String title, String content, String category) { vectorStore.add(List.of(new Document( content, Map.of(articleId, id, title, title, category, category) ))); } // 找出与给定文章内容相似的文章 public ListMapString, Object findSimilarArticles(String articleContent, int topK) { return vectorStore.similaritySearch( SearchRequest.builder() .query(articleContent) .topK(topK 1) // 1 用于排除文章自身 .similarityThreshold(0.75) .build()) .stream() .map(doc - Map.of( id, doc.getMetadata().get(articleId), title, doc.getMetadata().get(title), category, doc.getMetadata().get(category), score, doc.getScore() )) .toList(); } // 基于用户阅读历史推荐 public ListMapString, Object recommendFromHistory(ListString readArticleContents) { // 将近期阅读历史合并为单一语义查询 String combinedContext String.join( , readArticleContents); return vectorStore.similaritySearch( SearchRequest.builder() .query(combinedContext) .topK(10) .similarityThreshold(0.65) .build()) .stream() .map(doc - Map.of( id, doc.getMetadata().get(articleId), title, doc.getMetadata().get(title), category, doc.getMetadata().get(category), score, doc.getScore() )) .toList(); } }使用示例// 索引一些文章 recommendationService.addArticle(1, Intro to Spring AI, Spring AI intro content..., AI); recommendationService.addArticle(2, LangChain vs Spring AI, Comparison article content..., AI); recommendationService.addArticle(3, Docker Best Practices, Container content..., DevOps); // 获取与文章 1 相似的文章——文章 2 会被判定为高度相似 ListMapString, Object similar recommendationService.findSimilarArticles(Spring AI intro content..., 3); // 基于最近读过文章 1、2 的用户进行推荐 ListMapString, Object recommended recommendationService.recommendFromHistory( List.of(Spring AI intro content..., Comparison article content...));两个值得留意的实现细节findSimilarArticles用topK 1把被查询文章自身排除在外doc.getScore()直接读取归一化后的 0–1 相似度分数对应前述自动归一化到 0-1的设计可直接作为推荐排序依据展示给用户。实战示例四AI Agent 持久化记忆Agent 与多轮对话应用可以把 Vector Store 当作长期记忆层把对话轮次、事实与观察持久化为嵌入向量在每一步检索与当前输入最相关的记忆。配置元数据字段spring: ai: vectorstore: redisson: index-name: agent-memory-index prefix: memory: initialize-schema: true metadata-fields: - name: sessionId type: TAG - name: type type: TAG - name: timestamp type: TEXT存储与召回记忆并用记忆增强对话回复Service public class AgentMemoryService { private final VectorStore vectorStore; private final ChatClient chatClient; public AgentMemoryService(VectorStore vectorStore, ChatClient.Builder chatClientBuilder) { this.vectorStore vectorStore; this.chatClient chatClientBuilder.build(); } // 持久化一条记忆对话轮次、事实或观察 public void remember(String sessionId, String memoryText, String type) { vectorStore.add(List.of(new Document( memoryText, Map.of( sessionId, sessionId, type, type, // conversation, fact, preference timestamp, Instant.now().toString() ) ))); } // 召回与当前输入相关的记忆限定在某个会话内 public ListDocument recall(String sessionId, String currentInput, int topK) { return vectorStore.similaritySearch( SearchRequest.builder() .query(currentInput) .topK(topK) .similarityThreshold(0.6) .filterExpression(sessionId sessionId ) .build()); } // 带记忆增强上下文的对话 public String chat(String sessionId, String userMessage) { // 1. 召回本会话相关的历史记忆 ListDocument memories recall(sessionId, userMessage, 5); String memoryContext memories.isEmpty() ? No relevant memories. : memories.stream() .map(Document::getContent) .collect(Collectors.joining(\n- , - , )); // 2. 构建注入已召回上下文的系统提示词 String systemPrompt You are a helpful assistant with memory of past interactions. Relevant context from memory: %s Use this context to personalize your response where appropriate. .formatted(memoryContext); // 3. 使用增强后的提示词调用 LLM String response chatClient.prompt() .system(systemPrompt) .user(userMessage) .call() .content(); // 4. 持久化本次交互供将来召回 remember(sessionId, User asked: userMessage, conversation); remember(sessionId, Assistant responded: response, conversation); return response; } }使用示例// 教给 Agent 关于用户的事实 memoryService.remember(user-42, User prefers concise answers, fact); memoryService.remember(user-42, User is a Java developer, fact); memoryService.remember(user-42, User dislikes verbose responses, preference); // 开始对话——相关事实与历史轮次会被自动召回 String reply1 memoryService.chat(user-42, What is Spring AI?); // 后续轮次——Agent 记得之前的交流与用户偏好 String reply2 memoryService.chat(user-42, How do I add a vector store to it?); // 仅召回某用户存储的事实并按 type 过滤 ListDocument facts memoryService.recall(user-42, communication style, 5) .stream() .filter(doc - fact.equals(doc.getMetadata().get(type))) .toList();这里的记忆方案有几个值得借鉴的设计用sessionId作为TAG元数据做会话隔离filterExpression(sessionId sessionId )用type区分记忆类型conversation / fact / preference并把对话轮次本身也作为记忆写入从而让 Agent 在多轮对话中保持连贯的上下文。小结与适用前提Redisson Spring AI Vector Store 把 Spring AI 的上层抽象与 Redis Stack 的向量检索能力衔接起来JSON 文档负责承载向量、内容与元数据RediSearch 负责 KNN 索引与过滤查询EmbeddingModel 负责文本向量化。本文覆盖了从依赖引入、配置调优到 RAG、语义搜索、内容推荐、Agent 记忆四个完整业务场景的落地代码。最后再次强调适用前提该实现要求 Redis Stack 或 Redis 8.4含 RediSearch 与 RedisJSON 模块、Spring AI 提供的任意EmbeddingModel实例以及 Redisson PRO 许可证initialize-schema必须显式开启才能自动建索引任何用于过滤的元数据字段都必须预先在配置中声明其类型TAG / TEXT / NUMERIC。【免费下载链接】redissonRedisson: Valkey Redis Java Client and Real-Time Data Platform. Sync/Async/RxJava/Reactive API. Over 50 Valkey and Redis based Java objects and services: Set, Multimap, SortedSet, Map, List, Queue, Deque, Semaphore, Lock, AtomicLong, Map Reduce, Bloom filter, Spring, Tomcat, Scheduler, JCache API, Hibernate, RPC, local cache..项目地址: https://gitcode.com/GitHub_Trending/re/redisson创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表