Java 版本 RAG 示例(Spring AI + Milvus)

Java RAG 示例:Spring AI + Milvus

Spring‑AI 0.8.1,Milvus 2.4+,JDK17,SpringBoot3.x 整体流程:文档加载 → 文本分块 → Embedding 向量化 → 存入 Milvus 向量库 → 检索向量 → 组装上下文 Prompt → LLM 生成回答。 依赖:SpringAI Milvus 向量存储、OpenAI 兼容大模型(Qwen/DeepSeek 均可)、BGE embedding(本地或 API)。

1. pom.xml 核心依赖

xml

复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.0</version>
        <relativePath/>
    </parent>

    <groupId>com.demo</groupId>
    <artifactId>spring‑ai‑rag‑milvus</artifactId>
    <version>0.0.1‑SNAPSHOT</version>

    <properties>
        <java.version>17</java.version>
        <spring-ai.version>0.8.1</spring-ai.version>
    </properties>

    <dependencies>
        <!-- SpringBoot Web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- Spring AI Milvus 向量库 -->
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring‑ai‑milvus‑store‑spring‑boot‑starter</artifactId>
            <version>${spring-ai.version}</version>
        </dependency>

        <!-- SpringAI OpenAI兼容 LLM (通义千问/DeepSeek都兼容openai接口) -->
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring‑ai‑openai‑spring‑boot‑starter</artifactId>
            <version>${spring-ai.version}</version>
        </dependency>

        <!-- PDF文档解析 -->
        <dependency>
            <groupId>org.apache.pdfbox</groupId>
            <artifactId>pdfbox</artifactId>
        </dependency>

        <!-- lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.ai</groupId>
                <artifactId>spring‑ai‑bom</artifactId>
                <version>${spring-ai.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

2. application.yml 配置

Milvus 先 docker 启动,默认端口19530;示例使用通义千问兼容 OpenAI 接口,也可以换成 DeepSeek。

yaml

复制代码
spring:
  ai:
    # LLM大模型配置,openai兼容接口
    openai:
      api-key: sk‑xxxx你的key
      base-url: https://dashscope.aliyuncs.com/compatible-mode/v1
      chat:
        options:
          model: qwen-plus
          temperature: 0.0

    # Milvus向量数据库配置
    vectorstore:
      milvus:
        client:
          host: 127.0.0.1
          port: 19530
        database-name: default
        collection-name: spring_ai_kb
        # bge‑small‑zh 向量维度为512,务必和embedding模型保持一致!
        embedding-dimension: 512
        # 检索返回topN
        top-k: 4
        # 是否自动创建表
        auto-create-collection: true

⚠️重要:embedding‑dimension必须和 Embedding 模型输出维度完全匹配。

  • bge‑small‑zh‑v1.5 → 512 维
  • bge‑m3 → 1024 维
    SpringAI 内置 Embedding 默认调用 OpenAI 的 text‑embedding,中文效果差;实际项目建议替换为 BGE 本地 Embedding。下面示例先用 API 快速跑通,后面给 BGE 自定义 Embedding 扩展代码。

3. 核心 RAG 服务类

java

运行

复制代码
package com.demo.rag.service;

import lombok.RequiredArgsConstructor;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.document.Document;
import org.springframework.ai.reader.pdf.PagePdfDocumentReader;
import org.springframework.ai.transformer.splitter.TokenTextSplitter;
import org.springframework.ai.vectorstore.SearchRequest;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
@RequiredArgsConstructor
public class RagService {

    private final VectorStore vectorStore;
    private final ChatClient chatClient;

    /**
     * 1、加载PDF文档,分块,写入Milvus知识库(离线构建,执行一次)
     */
    public void loadPdfToVectorStore(String pdfFilePath) {
        // 读取PDF
        PagePdfDocumentReader pdfReader = new PagePdfDocumentReader(pdfFilePath);
        List<Document> originDocs = pdfReader.get();

        // 文本分块 TokenTextSplitter
        // 中文经验:chunkSize=500‑700,overlap=120‑150
        TokenTextSplitter splitter = new TokenTextSplitter(700, 150, 10, 1000, true);
        List<Document> splitDocs = splitter.apply(originDocs);

        // 写入Milvus向量库,自动embedding
        vectorStore.add(splitDocs);
        System.out.println("✅文档入库完成,分块数量:" + splitDocs.size());
    }

    /**
     * 2、RAG问答:检索Milvus + LLM生成答案
     */
    public String chat(String userQuestion) {
        // 向量检索,top‑k=4
        List<Document> recallDocs = vectorStore.similaritySearch(
                SearchRequest.builder()
                        .query(userQuestion)
                        .topK(4)
                        .build()
        );

        // 拼接检索到的知识库上下文
        StringBuilder contextSb = new StringBuilder();
        for (Document doc : recallDocs) {
            contextSb.append(doc.getContent()).append("\n");
        }

        // RAG固定Prompt模板,约束不要幻觉
        String promptTemplate = """
                你是内部知识库问答助手,请严格依据【参考上下文】回答用户的问题。
                如果参考上下文中没有相关信息,直接回复:知识库未查询到相关内容,禁止编造任何信息。
                
                【参考上下文】
                {context}
                
                【用户问题】
                {question}
                """;

        return chatClient.prompt()
                .user(u -> u.text(promptTemplate)
                        .param("context", contextSb.toString())
                        .param("question", userQuestion))
                .call()
                .content();
    }

    /**
     * 清空Milvus当前collection全部数据(测试用)
     */
    public void clearKb() {
        vectorStore.delete(List.of("*"));
    }
}

4. 测试 Controller

java

运行

复制代码
package com.demo.rag.controller;

import com.demo.rag.service.RagService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/rag")
@RequiredArgsConstructor
public class RagController {

    private final RagService ragService;

    // 上传PDF构建知识库,本地文件路径
    @GetMapping("/load")
    public String loadKb(@RequestParam String filePath) {
        ragService.loadPdfToVectorStore(filePath);
        return "load success";
    }

    // RAG问答接口
    @GetMapping("/chat")
    public String chat(@RequestParam String q) {
        return ragService.chat(q);
    }

    // 清空知识库
    @GetMapping("/clear")
    public String clear() {
        ragService.clearKb();
        return "clear ok";
    }
}

5. 启动类

java

运行

复制代码
package com.demo.rag;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class RagMilvusApplication {
    public static void main(String[] args) {
        SpringApplication.run(RagMilvusApplication.class, args);
    }
}

6. Milvus 快速 Docker 启动

bash

复制代码
docker run -d --name milvus‑standalone \
  -p 19530:19530 \
  -p 9091:9091 \
  milvusdb/milvus:v2.4.15‑standalone

替换为中文 BGE Embedding(生产必做)

SpringAI 默认是 OpenAI embedding,中文效果很差。 两种方案:

  1. 部署 bge‑small‑zh OpenAI 兼容 Embedding 服务,修改 yml 的 embedding base‑url。
  2. 实现EmbeddingModel接口接入本地 BGE 模型。
相关推荐
小马过河R1 小时前
AI Coding应用上线安全实践指南
人工智能·安全·安全架构·engineering·ai coding·harness
@Mr_LiuYang1 小时前
《深入理解 AI Agent:设计原理与工程实践 》实验2-1 本地大模型服务部署与工具调用
人工智能·大模型·本地化部署·深入理解ai agent
C++、Java和Python的菜鸟1 小时前
第14章 项目部署(Linux)
java
Zkaisen1 小时前
第三章 · 大语言模型基础(详尽展开版)
人工智能·语言模型·自然语言处理
todoitbo1 小时前
MongoDB迁移:从烟囱式部署走向 KES-AI 时代融合数据库架构
人工智能·mongodb·数据库架构·国产数据库·kingbasees
意图共鸣1 小时前
意图共鸣科技8月6日正式发布《交互等效原理》——大模型下半场的工程哲学纲领
人工智能
nuoxin1141 小时前
BL-M8812CU3 无线 WiFi 模块-富利威
人工智能·嵌入式硬件·fpga开发·硬件工程·dsp开发
想会飞的蒲公英1 小时前
PyTorch 学习率实战:从零理解衰减策略与调度器
人工智能·pytorch·python·深度学习·机器学习
cxr8281 小时前
第四章 查询与推理能力
人工智能·架构·知识图谱·智能体