spring boot + langchain4j +milvus实现向量存储

我在gitee上有整体的项目示例,有兴趣的可以拉下来看看:https://gitee.com/JR542784/langchain4j-test,如果不知道怎么部署milvus可以从我的主页走索milvus有相关的说明

POM相关依赖

<properties><java.version>21</java.version><junit.platform.version>1.9.2</junit.platform.version><junit.jupiter.version>5.9.2</junit.jupiter.version><langchain4j.version>0.36.2</langchain4j.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webmvc</artifactId></dependency><dependency><groupId>dev.langchain4j</groupId><artifactId>langchain4j-spring-boot-starter</artifactId><version>${langchain4j.version}</version></dependency><dependency><groupId>dev.langchain4j</groupId><artifactId>langchain4j-milvus-spring-boot-starter</artifactId><version>${langchain4j.version}</version></dependency><!-- Source: https://mvnrepository.com/artifact/dev.langchain4j/langchain4j-spring-boot-starter --><dependency><groupId>dev.langchain4j</groupId><artifactId>langchain4j-open-ai-spring-boot-starter</artifactId><version>${langchain4j.version}</version></dependency><dependency><groupId>dev.langchain4j</groupId><artifactId>langchain4j-open-ai</artifactId><version>${langchain4j.version}</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope><!-- 4.0.x 已经没有 vintage,可省略 exclusion --></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency></dependencies>

配置AiService

importcom.ai.langchain.langchain4jtest.service.AiHelperService;importdev.langchain4j.memory.ChatMemory;importdev.langchain4j.memory.chat.MessageWindowChatMemory;importdev.langchain4j.model.chat.ChatLanguageModel;importdev.langchain4j.rag.content.retriever.ContentRetriever;importdev.langchain4j.service.AiServices;importjakarta.annotation.Resource;importorg.springframework.beans.factory.annotation.Configurable;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;/** * @author JR * @version 1.0 * @description: * @date 2026年05月25日 17:39 */@ConfigurationpublicclassAiServiceConfig{@ResourceprivateChatLanguageModelqwenChatModel;@ResourceprivateContentRetrievercontentRetriever;/** * 加入RAG检索增强生成 * @return */@BeanpublicAiHelperServiceaiHelperService(){ChatMemorymessageWindowChatMemory=MessageWindowChatMemory.withMaxMessages(10);returnAiServices.builder(AiHelperService.class).chatLanguageModel(qwenChatModel).chatMemory(messageWindowChatMemory).chatMemoryProvider(memoryId->messageWindowChatMemory).contentRetriever(contentRetriever).tools().build();}}

RAG的相关配置

importdev.langchain4j.data.segment.TextSegment;importdev.langchain4j.model.embedding.EmbeddingModel;importdev.langchain4j.rag.content.retriever.ContentRetriever;importdev.langchain4j.rag.content.retriever.EmbeddingStoreContentRetriever;importdev.langchain4j.store.embedding.EmbeddingStore;importjakarta.annotation.Resource;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;/** * @author JR * @version 1.0 * @description: * @date 2026年05月25日 18:45 */@ConfigurationpublicclassAiRagConfig{@ResourceprivateEmbeddingModelqwenEmbeddingModel;// EmbeddingStore 的作用是什么?@Resource(name="milvusEmbeddingStore")privateEmbeddingStore<TextSegment>embeddingStore;/** * 检索器Bean:用于问答时从Milvus检索向量,不负责入库 */@BeanpublicContentRetrievercontentRetriever(){returnEmbeddingStoreContentRetriever.builder().embeddingStore(embeddingStore).embeddingModel(qwenEmbeddingModel).maxResults(5)// 召回top5.minScore(0.75)// 相似度阈值过滤低相关.build();}}

AiService的接口

/** * @author JR * @version 1.0 * @description: * @date 2026年05月25日 17:35 */publicinterfaceAiHelperService{@SystemMessage(fromResource="Prompt.txt")Stringchat(StringuserMessage);@SystemMessage(fromResource="Prompt.txt")ReportchatReport(StringuserMessage);recordReport(Stringname,List<String>suggetionList){}}

不同调用方式的调用

importcom.ai.langchain.langchain4jtest.service.ChatService;importdev.langchain4j.data.message.AiMessage;importdev.langchain4j.data.message.SystemMessage;importdev.langchain4j.data.message.UserMessage;importdev.langchain4j.data.segment.TextSegment;importdev.langchain4j.model.chat.ChatLanguageModel;importdev.langchain4j.model.chat.request.ChatRequest;importdev.langchain4j.model.chat.response.ChatResponse;importdev.langchain4j.store.embedding.EmbeddingStore;importio.milvus.client.MilvusClient;importjakarta.annotation.Resource;importlombok.extern.slf4j.Slf4j;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Service;/** * @author JR * @version 1.0 * @description: * @date 2026年05月25日 10:09 */@Slf4j@ServicepublicclassChatServiceImplimplementsChatService{privatestaticfinalStringCOLLECTION_NAME="test_collection";@ResourceprivateChatLanguageModelqwenChatModel;privateStringSYSTEM_MESSAGE=""" 你是AI面试助手**小光**,专注面试题库检索、答案整理与分类工作。 1. 接收用户面试相关提问,精准检索对应面试题目、标准答案与解题思路 2. 按**技术方向、难度等级、题型类别**规整划分内容 3. 排版清晰简洁,题目与答案分区展示,冗余信息剔除 4. 主动区分基础题、进阶题、实操题、问答论述题,按需归类输出 5. 严格围绕面试考点作答,不偏离求职面试场景 """;@OverridepublicStringchat(StringmessageChat){// 1. 组装消息UserMessageuserMsg=UserMessage.from("你的提问内容");ChatRequestchatRequest=ChatRequest.builder().messages(userMsg).build();ChatResponseresponse=qwenChatModel.chat(chatRequest);AiMessageaiMessage=response.aiMessage();log.info("ai message:{}",aiMessage.toString());returnaiMessage.text();}@OverridepublicStringchatUserMessage(UserMessageuserMessage){ChatRequestchatRequest=ChatRequest.builder().messages(userMessage).build();ChatResponseresponse=qwenChatModel.chat(chatRequest);AiMessageaiMessage=response.aiMessage();log.info("ai message:{}",aiMessage.toString());returnaiMessage.text();}@OverridepublicStringchatPrompt(Stringmessage){SystemMessagesystemMessage=newSystemMessage(SYSTEM_MESSAGE);UserMessageuserMessage=UserMessage.from(message);ChatRequestchatRequest=ChatRequest.builder().messages(systemMessage,userMessage).build();ChatResponseresponse=qwenChatModel.chat(chatRequest);AiMessageaiMessage=response.aiMessage();log.info("ai message:{}",aiMessage.toString());returnaiMessage.text();}}

单元测试

importcom.ai.langchain.langchain4jtest.service.AiHelperService;importcom.ai.langchain.langchain4jtest.service.ChatService;importcom.ai.langchain.langchain4jtest.service.MilvusVectorIngestService;importdev.langchain4j.data.message.ImageContent;importdev.langchain4j.data.message.TextContent;importdev.langchain4j.data.message.UserMessage;importjakarta.annotation.Resource;importorg.junit.jupiter.api.Test;importorg.springframework.boot.test.context.SpringBootTest;@SpringBootTestclassLangchain4jTestApplicationTests{@ResourceprivateChatServicechatService;@ResourceprivateAiHelperServiceaiHelperService;@TestpublicvoidbaseChat(){// 普通文本处理模型,在yml中进行配置StringresponseMessage=chatService.chat("你好,我是安多尼");System.out.println(responseMessage);}@TestpublicvoidchatImageHandel(){// 需要使用多模态的模型,在yml中进行配置// 还可以处理其他文件,相关的对象有:// AudioContent VideoContent PdfFileContent TextContent ImageContent// 音频,视频,pdf,文本,图片UserMessageuserMessage=newUserMessage(TextContent.from("这张图片的内容是什么"),ImageContent.from("https://tse4.mm.bing.net/th/id/OIP.bl-kQplMxE9HV27SrrmekAHaLn?r=0&rs=1&pid=ImgDetMain&o=7&rm=3"));StringresponseMessage=chatService.chatUserMessage(userMessage);System.out.println(responseMessage);}/** * 系统预设提示词,可以指定ai的身份作用等等 */@TestpublicvoidchatPrompt(){// 需要使用多模态的模型,在yml中进行配置// 还可以处理其他文件,相关的对象有:// AudioContent VideoContent PdfFileContent TextContent ImageContent// 音频,视频,pdf,文本,图片StringresponseMessage=chatService.chatPrompt("你是谁?你的功能是什么?");System.out.println(responseMessage);}/** * 通过aiService实现ai的调用(无会话记忆) */@TestpublicvoidchatPromptAiService(){// 需要使用多模态的模型,在yml中进行配置// 还可以处理其他文件,相关的对象有:// AudioContent VideoContent PdfFileContent TextContent ImageContent// 音频,视频,pdf,文本,图片StringresponseMessage=aiHelperService.chat("你是谁?你的功能是什么?");System.out.println(responseMessage);}@TestpublicvoidchatPromptMemoryAiService(){StringresponseMessage=aiHelperService.chat("现在是那年哪月那日,星期几");System.out.println("AI第一次回答:"+responseMessage);responseMessage=aiHelperService.chat("我刚刚问了你什么问题,你怎么回答的");System.out.println("AI第二次回答:"+responseMessage);}/** * 以Json scheam的方式返回数据 */@TestpublicvoidchatJsonScheam(){AiHelperService.Reportreport=aiHelperService.chatReport("给我几条学习建议,规划一些学习目标");System.out.println(report);System.out.println(report.suggetionList().size());}@ResourceprivateMilvusVectorIngestServicemilvusVectorIngestService;@TestpublicvoidchatRag(){// RAG相关配置需要查看AiRagConfig中的contentRetrieverStringresponseMessage=aiHelperService.chat("JDK命令行工具有哪些");System.out.println(responseMessage);}/** * 加载文档并向量化后存入milvus(向量数据库)中 */@TestpublicvoidloadDocsToMilvus(){milvusVectorIngestService.loadDocsToMilvus();}}