[7]. SpringAI Alibaba RAG增强检索生成


RAG



RAG过程
RAG的索引建立

RAG的检索

编码
向量化
package com.atguigu.study.config;import cn.hutool.crypto.SecureUtil;
import jakarta.annotation.PostConstruct;
import org.springframework.ai.document.Document;
import org.springframework.ai.reader.TextReader;
import org.springframework.ai.transformer.splitter.TokenTextSplitter;
import org.springframework.ai.vectorstore.AbstractVectorStoreBuilder;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.data.redis.core.RedisTemplate;import java.nio.charset.Charset;
import java.util.List;@Configuration
public class InitVectorDatabaseConfig {@Autowiredprivate VectorStore vectorStore;@Autowiredprivate RedisTemplate<String, String> redisTemplate;@Value("classpath:ops.txt")private Resource opsFile;@PostConstructpublic void init() {//1 读取文件TextReader textReader = new TextReader(opsFile);textReader.setCharset(Charset.defaultCharset());//2 文件转换为向量(开启分词)List<Document> list = new TokenTextSplitter().transform(textReader.read());//3 写入向量数据库RedisStack//vectorStore.add(list);// 解决上面第3步,向量数据重复问题,使用redis setnx命令处理//4 去重复版本String sourceMetadata = (String) textReader.getCustomMetadata().get("source");String textHash = SecureUtil.md5(sourceMetadata);String redisKey = "vector-xxx:" + textHash;// 判断是否存入过,redisKey如果可以成功插入表示以前没有过,可以假如向量数据Boolean retFlag = redisTemplate.opsForValue().setIfAbsent(redisKey, "1");System.out.println("****retFlag : " + retFlag);if (Boolean.TRUE.equals(retFlag)) {//键不存在,首次插入,可以保存进向量数据库vectorStore.add(list);} else {//键已存在,跳过或者报错//throw new RuntimeException("---重复操作");System.out.println("------向量初始化数据已经加载过,请不要重复操作");}}}
检索
package com.atguigu.study.controller;import jakarta.annotation.Resource;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.rag.advisor.RetrievalAugmentationAdvisor;
import org.springframework.ai.rag.retrieval.search.VectorStoreDocumentRetriever;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;/*** @auther zzyybs@126.com* @create 2025-07-30 12:21* @Description 知识出处:* https://docs.spring.io/spring-ai/reference/api/retrieval-augmented-generation.html#_advanced_rag*/
@RestController
public class RagController {@Resource(name = "qwenChatClient")private ChatClient chatClient;@Resourceprivate VectorStore vectorStore;/*** http://localhost:8012/rag4aiops?msg=00000* http://localhost:8012/rag4aiops?msg=C2222** @param msg* @return*/@GetMapping("/rag4aiops")public Flux<String> rag(String msg) {String systemInfo = """你是一个运维工程师,按照给出的编码给出对应故障解释,否则回复找不到信息。""";RetrievalAugmentationAdvisor advisor = RetrievalAugmentationAdvisor.builder().documentRetriever(VectorStoreDocumentRetriever.builder().vectorStore(vectorStore).build()).build();return chatClient.prompt().system(systemInfo).user(msg).advisors(advisor).stream().content();}
}