Loading [MathJax]/jax/output/CommonHTML/config.js
部署DeepSeek模型,进群交流最in玩法!
立即加群
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >基于Spring Ai + Ollama + Qwen2.5/Deepseek+Milvus实现RAG

基于Spring Ai + Ollama + Qwen2.5/Deepseek+Milvus实现RAG

原创
作者头像
用户11572955
发布于 2025-03-21 00:40:07
发布于 2025-03-21 00:40:07
44902
代码可运行
举报
运行总次数:2
代码可运行

安装mivus

参考官网的步骤就可以实现,作者使用docker实现

https://milvus.io/docs/zh/install_standalone-docker.md

安装Ollama

参考官网的步骤就可以实现,同事可在ollama下载文生文、文生图、ocr、embbeding、deepseek、Qwen系列等模型

https://ollama.com/search

前端Vue

vue3、element plus等

后端

spring boot 3.4.3、Java17

关键代码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.sb.rag;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.common.ConsistencyLevel;
import io.milvus.v2.common.IndexParam;
import io.milvus.v2.service.collection.request.CreateCollectionReq;
import io.milvus.v2.service.collection.request.HasCollectionReq;
import io.milvus.v2.service.database.request.CreateDatabaseReq;
import io.milvus.v2.service.vector.request.SearchReq;
import io.milvus.v2.service.vector.request.UpsertReq;
import io.milvus.v2.service.vector.request.data.FloatVec;
import io.milvus.v2.service.vector.response.SearchResp;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.messages.SystemMessage;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.model.ChatResponse;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.chat.prompt.TemplateFormat;
import org.springframework.ai.embedding.EmbeddingRequest;
import org.springframework.ai.embedding.EmbeddingResponse;
import org.springframework.ai.ollama.OllamaChatModel;
import org.springframework.ai.ollama.OllamaEmbeddingModel;
import org.springframework.ai.ollama.api.OllamaOptions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.constraints.NotNull;
import java.io.File;
import java.io.FileFilter;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.*;

@RestController
@RequestMapping("/ai/rag")
public class RAGController {

    @Autowired
    private MilvusClientV2 vectorStore;
    @Autowired
    private OllamaEmbeddingModel embeddingModel;
    @Autowired
    private OllamaChatModel chatModel;
    @Autowired
    private ChatClient chatClient;

    /**
     * 用户导入文件构建rag知识库
     * @return
     */
    @CrossOrigin
    @PostMapping("/import")
    public String importData(@RequestParam("file") MultipartFile files) {
        ArrayList<String> textLineList = new ArrayList<>();
        // 1.1、可以是用户的文件
        if (ObjectUtil.isNotEmpty(files)){
            String content = null;
            try {
                // 使用 Hutool 读取文件内容
                content = IoUtil.read(files.getInputStream(), CharsetUtil.UTF_8);
            } catch (Exception e) {
                return "文件读取失败:" + e.getMessage();
            }
            textLineList.add(content);
        }
        // 1.2、可以是公司的私有数据文件或数据湖中数据
        /*String directoryPath = "E:/workspace/idea/wanyuanhui/src/main/resources/milvus_docs/en/faq";
        // 使用 Hutool 的 FileUtil 获取目录下所有 .md 文件
        List<File> mdFiles = FileUtil.loopFiles(directoryPath, new FileFilter() {
            @Override
            public boolean accept(File file) {
                return file.getName().endsWith(".md");  // 过滤出所有 .md 文件
            }
        });

        // 遍历并读取所有 .md 文件的内容
        for (File file : mdFiles) {
            // 读取文件内容(文件内容是字符串)
            String cont = FileUtil.readUtf8String(file);  // 默认以 UTF-8 编码读取文件

            String[] text = cont.split("#");
            for (String line : text) {
                textLineList.add(line);
            }
        }*/
        // 2、嵌入
        int dimension = 0;
        List<JsonObject> jsonObjects = new ArrayList<>();
        for (int i = 0; i < textLineList.size(); i++) {
            String text = textLineList.get(i);
            EmbeddingResponse call = embeddingModel.call(new EmbeddingRequest(
                    List.of(text),
                    OllamaOptions.builder()
                            .model("mxbai-embed-large:latest")
                            .build()
            ));
            float[] vectorArr = call.getResult().getOutput();
            dimension = vectorArr.length;
            String replaceText = text.replace("\"", "\'");
            String format = StrUtil.format("{\"id\": {}, \"vector\": {}, \"text\": \"{}\"}", i, Arrays.toString(vectorArr), replaceText);
            Gson gson = new Gson();
            JsonObject entries = gson.fromJson(format, JsonObject.class);
            jsonObjects.add(entries);
        }

        // 3、加入企业私域知识向量库
        Boolean rag = vectorStore.hasCollection(HasCollectionReq.builder()
                .collectionName("rag")
                .build());
        if (Boolean.FALSE.equals(rag)) {
            vectorStore.createCollection(CreateCollectionReq.builder()
                    .collectionName("rag")
                    .dimension(dimension)
                    .metricType(IndexParam.MetricType.IP.name())
                    .consistencyLevel(ConsistencyLevel.STRONG)
                    .build());
        }

        vectorStore.upsert(UpsertReq.builder()
                .collectionName("rag")
                .data(jsonObjects)
                .build());

        return "上传成功";
    }

    /**
     * rag对话
     * @param question
     * @return
     * @throws InterruptedException
     */
    @CrossOrigin
    @GetMapping("/dialog")
    public String dialog(@NotNull(message = "不能为空") String question) throws InterruptedException {
        // 1、embedding
        float[] embed = embeddingModel.embed(question);
        // 2、similar search
        String rag = "rag";
        FloatVec floatVec = new FloatVec(embed);
        HashMap<String, Object> searchParams = new HashMap<>();
        searchParams.put("metric_type", "IP");
        SearchResp text = vectorStore.search(SearchReq.builder()
                .collectionName(rag)
                .data(Collections.singletonList(floatVec))
                .limit(3L)
                .topK(10)
                .searchParams(searchParams)
                .outputFields(Arrays.asList("text"))
                .build());
        List<List<SearchResp.SearchResult>> searchResults = text.getSearchResults();

        ArrayList<String> similarSearchResults = new ArrayList<>();
        for (List<SearchResp.SearchResult> searchResult : searchResults) {
            String content = (String) searchResult.get(0).getEntity().get("text");
            similarSearchResults.add(content);
        }
        String context = String.join("\n", similarSearchResults);
        // 3、llm
//        ChatClient chatClient = ChatClient.builder(chatModel)
//                .defaultSystem("Human: You are an AI assistant. You are able to find answers to the questions from the contextual passage snippets provided.")
//                .build();
        // 为 Lanage 模型定义系统和用户提示。该提示与从 Milvus 检索到的文档作为上下文实现RAG。
        ChatClient.CallResponseSpec responseSpec = chatClient.prompt(
                        new Prompt(StrUtil.format("Use the following pieces of information enclosed in <context> tags to provide an answer to the question enclosed in <question> tags.\n" +
                                "<context>{}</context>\n" +
                                "<question>{}</question>", context, question),
                                OllamaOptions.builder()
                                        .model("qwen2.5:3b")
                                        .build())
                ).system(sys -> sys.param("voice", "parameter customization"))
                .call();
        // 4、response
        String responseText = responseSpec.chatResponse().getResult().getOutput().getText();
        return responseText;
    }

}

实现效果

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Spring AI 1.0 正式发布!核心内容和智能体详解
在经历了八个里程碑式的版本之后(M1~M8),Spring AI 1.0 正式版本,终于在 2025 年 5 月 20 日正式发布了,这是另一个新高度的里程碑式的版本,标志着 Spring 生态系统正式全面拥抱人工智能技术,并且意味着 Spring AI 将会给企业带来稳定 API 支持。
磊哥
2025/05/22
2080
Spring AI 1.0 正式发布!核心内容和智能体详解
聊聊Spring AI的RAG
Spring AI受Modular RAG: Transforming RAG Systems into LEGO-like Reconfigurable Frameworks启发实现了Modular RAG,主要分为如下几个阶段:Pre-Retrieval、Retrieval、Post-Retrieval、Generation
code4it
2025/04/08
2141
聊聊Spring AI的RAG
聊聊Spring AI的ChromaVectorStore
org/springframework/ai/vectorstore/chroma/autoconfigure/ChromaVectorStoreAutoConfiguration.java
code4it
2025/04/05
1090
聊聊Spring AI的ChromaVectorStore
spring-ai ollama小试牛刀
spring-ai-ollama-spring-boot-starter-1.0.0-M5.jar!/META-INF/maven/org.springframework.ai/spring-ai-ollama-spring-boot-starter/pom.xml
code4it
2025/03/27
1130
spring-ai ollama小试牛刀
Spring AI应用:利用DeepSeek+嵌入模型+Milvus向量数据库实现检索增强生成--RAG应用(超详细)
在当今数字化时代,人工智能(AI)技术的快速发展为各行业带来了前所未有的机遇。其中,检索增强生成(RAG)技术作为一种结合了检索和生成的混合模型,已经在自然语言处理领域取得了显著的成果。本文将详细介绍如何利用Spring AI框架、DeepSeek大模型、嵌入模型以及Milvus向量数据库实现一个高效的RAG应用。通过这一实践,读者将能够构建一个能够处理复杂查询并生成高质量答案的智能系统。
全干程序员demo
2025/04/10
6310
Spring AI应用:利用DeepSeek+嵌入模型+Milvus向量数据库实现检索增强生成--RAG应用(超详细)
聊聊Spring AI的ChromaVectorStore
org/springframework/ai/vectorstore/chroma/autoconfigure/ChromaVectorStoreAutoConfiguration.java
code4it
2025/04/06
790
聊聊Spring AI的ChromaVectorStore
深入Spring AI:6大核心概念带你入门AI开发
前面我们快速了解了Spring AI的基础使用,以及他的分层体系。今天我们来了解一下他的几个核心概念,能够帮我们快速了解Spring AI的实现机制。
有一只柴犬
2025/03/31
4160
深入Spring AI:6大核心概念带你入门AI开发
AI实战篇:Spring AI + 混元 手把手带你实现企业级稳定可部署的AI业务智能体
在之前的内容中,我们详细讲解了Spring AI的基础用法及其底层原理。如果还有小伙伴对此感到困惑,欢迎参考下面这篇文章,深入学习并进一步掌握相关知识:https://cloud.tencent.com/developer/article/2454827
努力的小雨
2024/10/09
2.6K0
聊聊Spring AI的MilvusVectorStore
org/springframework/ai/vectorstore/milvus/autoconfigure/MilvusVectorStoreAutoConfiguration.java
code4it
2025/04/04
1210
聊聊Spring AI的MilvusVectorStore
【微服务】SpringBoot整合LangChain4j 操作AI大模型实战详解
随着人工智能技术的飞速发展,AI大模型已经在众多领域展现出强大的能力,为业务拓展和商业价值提升带来了新的机遇。SpringBoot作为一款广受欢迎的Java微服务框架,以其简洁、高效的特点深受开发者喜爱。而LangChain4j作为一款专注于AI大模型集成的开源库,为Java开发者提供了一种简单且高效的方式来接入和利用各种AI大模型。本文将详细介绍如何在SpringBoot中整合LangChain4j,实现对AI大模型的操作,帮助读者快速上手并应用到实际项目中。
全干程序员demo
2025/04/09
9810
【微服务】SpringBoot整合LangChain4j 操作AI大模型实战详解
SpringAI+Ollama三部曲之二:细说开发
程序员欣宸
2024/05/26
2.1K0
SpringAI+Ollama三部曲之二:细说开发
聊聊Spring AI的EmbeddingModel
spring-ai-core/src/main/java/org/springframework/ai/embedding/EmbeddingModel.java
code4it
2025/04/02
1140
聊聊Spring AI的EmbeddingModel
如何用Spring AI构建MCP Client-Server架构
现代 Web 应用正加速与大语言模型(LLMs)深度融合,构建超越传统问答场景的智能解决方案。为突破模型知识边界,增强上下文理解能力,开发者普遍采用多源数据集成策略,将 LLM 与搜索引擎、数据库、文件系统等外部资源互联。然而,异构数据源的协议差异与格式壁垒,往往导致集成复杂度激增,成为制约 AI 应用规模化落地的关键瓶颈。因此,Anthropic公司推出了模型上下文协议(Model Context Protocol, MCP),通过标准化接口为 AI 应用与外部数据源建立统一交互通道。这一协议体系不仅实现了数据获取与操作的规范化,更构建起可扩展的智能体开发框架,使开发者能够基于原生 LLM 能力快速构建复杂工作流。
程序猿DD
2025/03/27
1.9K0
如何用Spring AI构建MCP Client-Server架构
使用RAGAs评估基于Milvus的RAG应用
现在,我们很容易构建一个基于检索增强生成(RAG)的应用,但将其投入生产却非常困难,因为RAG的性能很难达到令人满意的状态。
Zilliz RDS
2024/07/10
5230
使用RAGAs评估基于Milvus的RAG应用
动手做一个最小RAG——TinyRAG
接下来我会带领大家一步一步地实现一个简单的RAG模型,这个模型是基于RAG的一个简化版本,我们称之为Tiny-RAG。Tiny-RAG是一个基于RAG的简化版本,它只包含了RAG的核心功能,即Retrieval和Generation。Tiny-RAG的目的是为了帮助大家更好地理解RAG模型的原理和实现。
Datawhale
2024/04/24
3560
动手做一个最小RAG——TinyRAG
基于Microsoft.Extensions.AI核心库实现RAG应用
之前我们了解 Microsoft.Extensions.AI 和 Microsoft.Extensions.VectorData 两个重要的AI应用核心库。基于对他们的了解,今天我们就可以来实战一个RAG问答应用,把之前所学的串起来。如果你觉得对你有帮助,可以V我50,毕竟今天是Crazy星期四。
郑子铭
2025/04/14
820
基于Microsoft.Extensions.AI核心库实现RAG应用
聊聊Spring AI的RedisVectorStore
org/springframework/ai/vectorstore/redis/autoconfigure/RedisVectorStoreAutoConfiguration.java
code4it
2025/04/06
1230
聊聊Spring AI的RedisVectorStore
聊聊Spring AI的PgVectorStore
脚本源码: org/springframework/ai/vectorstore/pgvector/PgVectorStore.java
code4it
2025/04/07
1110
JeecgBoot 低代码平台快速集成 Spring AI
JeecgBoot 是一款基于代码生成器的低代码开发平台!前后端分离架构 SpringBoot2.x 和 3.x,SpringCloud,Ant Design Vue3,Mybatis-plus,Shiro,JWT,支持微服务。强大的代码生成器让前后端代码一键生成,实现低代码开发!JeecgBoot 引领新的低代码开发模式 (OnlineCoding-> 代码生成器 -> 手工 MERGE), 帮助解决 Java 项目 70% 的重复工作,让开发更多关注业务。既能快速提高效率,节省研发成本,同时又不失灵活性!
JEECG
2024/08/05
2980
JeecgBoot 低代码平台快速集成 Spring AI
聊聊Spring AI的ETL Pipeline
org/springframework/ai/document/DocumentReader.java
code4it
2025/04/09
770
聊聊Spring AI的ETL Pipeline
相关推荐
Spring AI 1.0 正式发布!核心内容和智能体详解
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验