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

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

POM相关依赖

xml 复制代码
<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

java 复制代码
import com.ai.langchain.langchain4jtest.service.AiHelperService;
import dev.langchain4j.memory.ChatMemory;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.rag.content.retriever.ContentRetriever;
import dev.langchain4j.service.AiServices;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author JR
 * @version 1.0
 * @description:
 * @date 2026年05月25日 17:39
 */
@Configuration
public class AiServiceConfig {

    @Resource
    private ChatLanguageModel qwenChatModel;

    @Resource
    private ContentRetriever contentRetriever;

    /**
     * 加入RAG检索增强生成
     * @return
     */
    @Bean
    public AiHelperService aiHelperService() {
        ChatMemory messageWindowChatMemory = MessageWindowChatMemory.withMaxMessages(10);
        return AiServices.builder(AiHelperService.class)
                .chatLanguageModel(qwenChatModel)
                .chatMemory(messageWindowChatMemory)
                .chatMemoryProvider(memoryId -> messageWindowChatMemory)
                .contentRetriever(contentRetriever)
                .tools()
                .build();
    }
}

RAG的相关配置

java 复制代码
import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.model.embedding.EmbeddingModel;
import dev.langchain4j.rag.content.retriever.ContentRetriever;
import dev.langchain4j.rag.content.retriever.EmbeddingStoreContentRetriever;
import dev.langchain4j.store.embedding.EmbeddingStore;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author JR
 * @version 1.0
 * @description:
 * @date 2026年05月25日 18:45
 */
@Configuration
public class AiRagConfig {

    @Resource
    private EmbeddingModel qwenEmbeddingModel;

    // EmbeddingStore 的作用是什么?
    @Resource(name = "milvusEmbeddingStore")
    private EmbeddingStore<TextSegment> embeddingStore;

    /**
     * 检索器Bean:用于问答时从Milvus检索向量,不负责入库
     */
    @Bean
    public ContentRetriever contentRetriever() {
        return EmbeddingStoreContentRetriever.builder()
                .embeddingStore(embeddingStore)
                .embeddingModel(qwenEmbeddingModel)
                .maxResults(5)      // 召回top5
                .minScore(0.75)     // 相似度阈值过滤低相关
                .build();
    }
}

AiService的接口

java 复制代码
/**
 * @author JR
 * @version 1.0
 * @description:
 * @date 2026年05月25日 17:35
 */
public interface AiHelperService {

    @SystemMessage(fromResource = "Prompt.txt")
    String chat(String userMessage);

    @SystemMessage(fromResource = "Prompt.txt")
    Report chatReport(String userMessage);

    record Report(String name, List<String> suggetionList){}
}

不同调用方式的调用

java 复制代码
import com.ai.langchain.langchain4jtest.service.ChatService;
import dev.langchain4j.data.message.AiMessage;
import dev.langchain4j.data.message.SystemMessage;
import dev.langchain4j.data.message.UserMessage;
import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.chat.request.ChatRequest;
import dev.langchain4j.model.chat.response.ChatResponse;
import dev.langchain4j.store.embedding.EmbeddingStore;
import io.milvus.client.MilvusClient;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @author JR
 * @version 1.0
 * @description:
 * @date 2026年05月25日 10:09
 */
@Slf4j
@Service
public class ChatServiceImpl implements ChatService {

    private static final String COLLECTION_NAME = "test_collection";
    @Resource
    private ChatLanguageModel qwenChatModel;

    private String SYSTEM_MESSAGE= """
            你是AI面试助手**小光**,专注面试题库检索、答案整理与分类工作。
            1. 接收用户面试相关提问,精准检索对应面试题目、标准答案与解题思路
            2. 按**技术方向、难度等级、题型类别**规整划分内容
            3. 排版清晰简洁,题目与答案分区展示,冗余信息剔除
            4. 主动区分基础题、进阶题、实操题、问答论述题,按需归类输出
            5. 严格围绕面试考点作答,不偏离求职面试场景
            """;

    @Override
    public String chat(String messageChat) {
        // 1. 组装消息
        UserMessage userMsg = UserMessage.from("你的提问内容");
        ChatRequest chatRequest = ChatRequest.builder().messages(userMsg).build();
        ChatResponse response = qwenChatModel.chat(chatRequest);
        AiMessage aiMessage = response.aiMessage();
        log.info("ai message:{}",aiMessage.toString());
        return aiMessage.text();
    }

    @Override
    public String chatUserMessage(UserMessage userMessage) {
        ChatRequest chatRequest = ChatRequest.builder().messages(userMessage).build();
        ChatResponse response = qwenChatModel.chat(chatRequest);
        AiMessage aiMessage = response.aiMessage();
        log.info("ai message:{}",aiMessage.toString());
        return aiMessage.text();
    }

    @Override
    public String chatPrompt(String message) {
        SystemMessage systemMessage = new SystemMessage(SYSTEM_MESSAGE);
        UserMessage userMessage = UserMessage.from(message);
        ChatRequest chatRequest = ChatRequest.builder().messages(systemMessage,userMessage).build();
        ChatResponse response = qwenChatModel.chat(chatRequest);
        AiMessage aiMessage = response.aiMessage();
        log.info("ai message:{}",aiMessage.toString());

        return aiMessage.text();
    }

}

单元测试

java 复制代码
import com.ai.langchain.langchain4jtest.service.AiHelperService;
import com.ai.langchain.langchain4jtest.service.ChatService;
import com.ai.langchain.langchain4jtest.service.MilvusVectorIngestService;
import dev.langchain4j.data.message.ImageContent;
import dev.langchain4j.data.message.TextContent;
import dev.langchain4j.data.message.UserMessage;
import jakarta.annotation.Resource;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class Langchain4jTestApplicationTests {

    @Resource
    private ChatService chatService;

    @Resource
    private AiHelperService aiHelperService;

    @Test
    public void baseChat() {
        // 普通文本处理模型,在yml中进行配置
        String responseMessage = chatService.chat("你好,我是安多尼");
        System.out.println(responseMessage);
    }

    @Test
    public void chatImageHandel() {
        // 需要使用多模态的模型,在yml中进行配置
        // 还可以处理其他文件,相关的对象有:
        // AudioContent VideoContent PdfFileContent TextContent ImageContent
        // 音频,视频,pdf,文本,图片
        UserMessage userMessage = new UserMessage(
                TextContent.from("这张图片的内容是什么"),
                ImageContent.from("https://tse4.mm.bing.net/th/id/OIP.bl-kQplMxE9HV27SrrmekAHaLn?r=0&rs=1&pid=ImgDetMain&o=7&rm=3")
        );
        String responseMessage = chatService.chatUserMessage(userMessage);
        System.out.println(responseMessage);
    }


    /**
     * 系统预设提示词,可以指定ai的身份作用等等
     */
    @Test
    public void chatPrompt() {
        // 需要使用多模态的模型,在yml中进行配置
        // 还可以处理其他文件,相关的对象有:
        // AudioContent VideoContent PdfFileContent TextContent ImageContent
        // 音频,视频,pdf,文本,图片
        String responseMessage = chatService.chatPrompt("你是谁?你的功能是什么?");
        System.out.println(responseMessage);
    }

    /**
     * 通过aiService实现ai的调用(无会话记忆)
     */
    @Test
    public void chatPromptAiService() {
        // 需要使用多模态的模型,在yml中进行配置
        // 还可以处理其他文件,相关的对象有:
        // AudioContent VideoContent PdfFileContent TextContent ImageContent
        // 音频,视频,pdf,文本,图片
        String responseMessage = aiHelperService.chat("你是谁?你的功能是什么?");
        System.out.println(responseMessage);
    }


    @Test
    public void chatPromptMemoryAiService() {
        String responseMessage = aiHelperService.chat("现在是那年哪月那日,星期几");
        System.out.println("AI第一次回答:"+responseMessage);
        responseMessage = aiHelperService.chat("我刚刚问了你什么问题,你怎么回答的");
        System.out.println("AI第二次回答:"+responseMessage);
    }


    /**
     * 以Json scheam的方式返回数据
     */
    @Test
    public void chatJsonScheam() {
        AiHelperService.Report report = aiHelperService.chatReport("给我几条学习建议,规划一些学习目标");
        System.out.println(report);
        System.out.println(report.suggetionList().size());
    }

    @Resource
    private MilvusVectorIngestService milvusVectorIngestService;

    @Test
    public void chatRag() {
        // RAG相关配置需要查看AiRagConfig中的contentRetriever
        String responseMessage = aiHelperService.chat("JDK命令行工具有哪些");
        System.out.println(responseMessage);
    }

    /**
     *  加载文档并向量化后存入milvus(向量数据库)中
     */
    @Test
    public void loadDocsToMilvus() {
        milvusVectorIngestService.loadDocsToMilvus();
    }

}
相关推荐
王木风1 小时前
Spring Boot + LLM 工程化:把短视频流水线拆成 16 个独立角色的踩坑记录
人工智能·spring boot·后端·开源·新媒体运营·音视频·agent
武子康1 小时前
Java-27 深入浅出 Spring - 实现简易Ioc-03 在上节的业务下手动实现IoC 从 XML 配置到 BeanFactory 反射注入
java·后端·mybatis
智海观潮1 小时前
UniScientist:30B开源科研大模型突破,重构AI自主研究范式
人工智能·ai·大模型
二哈赛车手1 小时前
新人笔记---idea索引失效问题解决方案
java·笔记·spring·elasticsearch·intellij-idea
月光刺眼1 小时前
Bun + TypeScript 后端入门:从类型约束到 LLM API 调用
后端·typescript
万岳科技1 小时前
教育培训系统开发流程详解:平台建设关键环节解析
数据库·后端·学习
Java编程爱好者1 小时前
服务里的 Redis 锁惊群问题:一次本地合流优化实践
后端
Nturmoils1 小时前
线上修一批脏数据,先别急着全量重来
数据库·后端
飞天狗1111 小时前
零基础JavaWeb入门——第五课第一小节:九大内置对象 · 第1个:request(请求对象)
java·开发语言·前端·后端·servlet