一、简介
知识库。
二、代码
pom.xml
<!-- pdf解析 --><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-pdf-document-reader</artifactId></dependency>application.yml
spring:servlet:multipart:max-file-size:10MBmax-request-size:20MButil
@ComponentpublicclassRagDocumentLoader{@AutowiredprivateVectorStorevectorStore;privatefinalTokenTextSplittertextSplitter=newTokenTextSplitter(800,150,5,10000);/** * 上传文件入库:支持 txt / pdf */publicvoidloadMultipartFile(MultipartFilefile)throwsIOException{Resourceresource=newByteArrayResource(file.getBytes());Stringfilename=file.getOriginalFilename();List<Document>documentList;if(filename!=null&&filename.endsWith(".pdf")){//PDF读取PagePdfDocumentReaderpdfReader=newPagePdfDocumentReader(resource);documentList=pdfReader.get();}else{//默认当作txt文本TextReadertextReader=newTextReader(resource);documentList=textReader.get();}//分片List<Document>splitDocs=textSplitter.apply(documentList);//写入向量库vectorStore.add(splitDocs);}publicvoidloadTxt(Resourceresource){List<Document>docs=newTextReader(resource).get();List<Document>splitDocs=textSplitter.apply(docs);vectorStore.add(splitDocs);}publicvoidloadText(Stringcontent){Documentdoc=newDocument(content);vectorStore.add(textSplitter.apply(List.of(doc)));}}Configuration
/** * 内存向量库 SimpleVectorStore * 注意:重启丢失,仅用于开发测试;生产替换为Milvus等 * 依赖注入EmbeddingModel,使用阿里云百炼的Embedding */@BeanpublicVectorStoresimpleVectorStore(EmbeddingModelembeddingModel){returnSimpleVectorStore.builder(embeddingModel).build();}/** * RAG 问答Advisor,自定义prompt模板 */@BeanpublicQuestionAnswerAdvisorquestionAnswerAdvisor(VectorStorevectorStore){StringragSystemPrompt=""" 你是知识库助手,严格依据【参考资料】回答用户问题。 参考资料没有的信息,直接回复不知道,禁止编造。 【参考资料】 {question_answer_context} """;SearchRequestsearchRequest=SearchRequest.builder().topK(1).similarityThreshold(0.6).build();returnnewQuestionAnswerAdvisor(vectorStore,searchRequest,ragSystemPrompt);}@BeanpublicChatClientchatClient(ChatClient.Builderbuilder,QuestionAnswerAdvisorquestionAnswerAdvisor,ChatMemorychatMemory){// spring‑ai‑alibaba 环境,默认使用的是DashScopeChatModel(阿里云百炼聊天模型)returnbuilder.builder().defaultAdvisors(questionAnswerAdvisor).build();}Controller
也可以删掉 ChatClient 里面的.defaultAdvisors(questionAnswerAdvisor),在接口处手动添加 advisor:
@AutowiredprivateRagDocumentLoaderragDocumentLoader;/** * 文件上传,解析并存入向量库 * postman测试:POST form‑data key=file,选择txt或者pdf文件 */@PostMapping("/upload")publicResponseEntity<String>uploadFile(@RequestParam("file")MultipartFilefile){if(file.isEmpty()){returnResponseEntity.badRequest().body("文件不能为空");}try{ragDocumentLoader.loadMultipartFile(file);returnResponseEntity.ok("上传成功,已加载到向量库");}catch(Exceptione){e.printStackTrace();returnResponseEntity.internalServerError().body("解析失败:"+e.getMessage());}}@GetMapping("/chat")publicStringchat(@RequestParamStringsid,@RequestParamStringquestion){returnchatClient.prompt().user(question).advisors(a->a.param(ChatMemory.CONVERSATION_ID,sid).add(questionAnswerAdvisor)//仅本次请求启用RAG).call().content();}