🎬 HoRain云小助手个人主页

 🔥 个人专栏: 《Linux 系列教程》《c语言教程

⛺️生活的理想,就是为了理想的生活!


⛳️ 推荐

前些天发现了一个超棒的服务器购买网站,性价比超高,大内存超划算!忍不住分享一下给大家。点击跳转到网站。

专栏介绍

专栏名称

专栏介绍

《C语言》

本专栏主要撰写C干货内容和编程技巧,让大家从底层了解C,把更多的知识由抽象到简单通俗易懂。

《网络协议》

本专栏主要是注重从底层来给大家一步步剖析网络协议的奥秘,一起解密网络协议在运行中协议的基本运行机制!

《docker容器精解篇》

全面深入解析 docker 容器,从基础到进阶,涵盖原理、操作、实践案例,助您精通 docker。

《linux系列》

本专栏主要撰写Linux干货内容,从基础到进阶,知识由抽象到简单通俗易懂,帮你从新手小白到扫地僧。

《python 系列》

本专栏着重撰写Python相关的干货内容与编程技巧,助力大家从底层去认识Python,将更多复杂的知识由抽象转化为简单易懂的内容。

《试题库》

本专栏主要是发布一些考试和练习题库(涵盖软考、HCIE、HRCE、CCNA等)

目录

⛳️ 推荐

专栏介绍

一、核心概念与优势

二、环境准备与项目搭建

1. 前置条件

2. 创建Spring Boot项目并添加依赖

3. 应用配置

三、核心代码实现

1. 文档模型与存储

2. 检索与问答服务

3. 提供REST API

四、部署与运行

五、进阶优化与注意事项


img

基于Spring Boot、Spring AI、MongoDB Atlas向量搜索和OpenAI构建RAG(检索增强生成)应用,是现代AI应用开发的热门实践。这种组合能高效整合企业知识库与大语言模型,提升回答的准确性和时效性。下面为您提供一个从零开始的完整构建指南。

一、核心概念与优势

  • RAG是什么:在生成回答前,先从外部知识库(向量数据库)中检索相关文档片段作为上下文,再交给大模型生成答案。这能有效解决大模型的“幻觉”和知识陈旧问题。

  • 技术栈优势

    • Spring Boot:简化企业级Java应用开发。

    • Spring AI:提供统一的AI模型和向量存储抽象,可轻松切换提供商。

    • MongoDB Atlas:完全托管的云数据库,原生支持向量搜索,无需维护独立向量数据库。

    • OpenAI:提供高质量的嵌入模型(如text-embedding-ada-002)和聊天模型(如gpt-3.5-turbogpt-4)。

二、环境准备与项目搭建

1. 前置条件
  • JDK 17+​ 和 Maven​ 或 Gradle

  • MongoDB Atlas集群:需为M10或更高规格,或Serverless实例,因为免费层不支持向量搜索。确保在Atlas控制台为集群启用了“Vector Search”并配置了IP访问列表。

  • OpenAI API密钥

2. 创建Spring Boot项目并添加依赖

pom.xml中添加以下核心依赖:

<dependencies>
    <!-- Spring Boot Web -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- Spring AI OpenAI 集成 -->
    <dependency>
        <groupId>org.springframework.ai</groupId>
        <artifactId>spring-ai-openai-spring-boot-starter</artifactId>
    </dependency>
    <!-- Spring AI MongoDB Atlas 向量存储 -->
    <dependency>
        <groupId>org.springframework.ai</groupId>
        <artifactId>spring-ai-mongodb-atlas-store-spring-boot-starter</artifactId>
    </dependency>
    <!-- Spring Data MongoDB -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-mongodb</artifactId>
    </dependency>
</dependencies>
3. 应用配置

application.ymlapplication.properties中配置:

spring:
  data:
    mongodb:
      uri: mongodb+srv://<username>:<password>@<cluster>.mongodb.net/ # 替换为您的Atlas连接字符串
      database: rag_demo # 数据库名
  ai:
    openai:
      api-key: ${OPENAI_API_KEY} # 您的OpenAI API密钥
      embedding:
        options:
          model: text-embedding-ada-002 # 嵌入模型
      chat:
        options:
          model: gpt-3.5-turbo # 聊天模型
    vectorstore:
      mongodb:
        collection-name: document_vectors # 向量存储集合名
        initialize-schema: true # 自动初始化集合和索引
        index-name: vector_index # 向量索引名
        path-name: embedding # 向量字段名

三、核心代码实现

1. 文档模型与存储

定义一个简单的文档模型,并实现文档入库逻辑。

// 1. 文档实体(可选,用于业务逻辑)
@Data
public class WikiDocument {
    private String filePath;
    private String content;
}

// 2. 文档存储服务
@Service
public class DocumentService {
    private final VectorStore vectorStore;
    private final EmbeddingModel embeddingModel;

    public DocumentService(VectorStore vectorStore, EmbeddingModel embeddingModel) {
        this.vectorStore = vectorStore;
        this.embeddingModel = embeddingModel;
    }

    public void ingestDocument(String filePath) throws IOException {
        String content = Files.readString(Path.of(filePath));
        // 创建Spring AI的Document对象,可附加元数据
        Map<String, Object> metadata = new HashMap<>();
        metadata.put("source", filePath);
        metadata.put("ingestedAt", Instant.now().toString());

        Document document = new Document(content, metadata);
        // 使用分词器将长文档切分为块(避免超出模型上下文长度)
        TextSplitter splitter = new TokenTextSplitter(500, 50); // 块大小500 token,重叠50 token
        List<Document> chunks = splitter.split(document);
        // 存储到向量数据库(会自动调用EmbeddingModel生成向量)
        vectorStore.add(chunks);
    }
}
2. 检索与问答服务

实现RAG的核心检索与生成逻辑。

@Service
public class RagService {
    private final ChatClient chatClient;
    private final VectorStore vectorStore;

    public RagService(ChatClient.Builder chatClientBuilder, VectorStore vectorStore) {
        this.chatClient = chatClientBuilder.build();
        this.vectorStore = vectorStore;
    }

    public String ask(String question) {
        // 1. 检索:在向量库中查找与问题最相关的文档块
        SearchRequest searchRequest = SearchRequest.builder()
                .query(question)
                .topK(5) // 返回最相关的5个块
                .similarityThreshold(0.6) // 相似度阈值,过滤低相关性结果
                .build();
        List<Document> relevantDocs = vectorStore.similaritySearch(searchRequest);

        // 2. 构建提示词(Prompt),将检索到的上下文与问题结合
        String context = relevantDocs.stream()
                .map(Document::getContent)
                .collect(Collectors.joining("\n\n"));
        String prompt = String.format("""
                请基于以下上下文回答问题。如果上下文不包含答案,请说“根据已知信息无法回答”。
                上下文:
                %s
                问题:%s
                答案:
                """, context, question);

        // 3. 调用大模型生成答案
        return chatClient.prompt()
                .user(prompt)
                .call()
                .content();
    }
}
3. 提供REST API
@RestController
@RequestMapping("/api/rag")
public class RagController {
    private final RagService ragService;
    private final DocumentService documentService;

    @PostMapping("/ingest")
    public ResponseEntity<String> ingestDocument(@RequestParam String filePath) throws IOException {
        documentService.ingestDocument(filePath);
        return ResponseEntity.ok("文档已成功入库并向量化。");
    }

    @PostMapping("/ask")
    public ResponseEntity<String> askQuestion(@RequestBody QuestionRequest request) {
        String answer = ragService.ask(request.getQuestion());
        return ResponseEntity.ok(answer);
    }
}
// 请求体
@Data
class QuestionRequest {
    private String question;
}

四、部署与运行

  1. 启动应用:运行Spring Boot主类。

  2. 首次运行:Spring AI会根据配置(initialize-schema: true)在MongoDB Atlas中自动创建集合和向量搜索索引。

  3. 数据灌入:调用POST /api/rag/ingest?filePath=/path/to/your/doc.txt上传您的知识文档(支持TXT、PDF等格式,需自行实现文件解析)。

  4. 智能问答:调用POST /api/rag/ask传入问题,即可获得基于知识库的答案。

五、进阶优化与注意事项

  • 文档分块策略:根据文档类型(如技术文档、合同)调整分块大小和重叠区,以保持语义完整性。

  • 元数据过滤:在SearchRequest中使用.filterExpression()进行元数据过滤,实现更精确的检索。

  • 重排序(Reranking):如LyricMind示例所示,可以先检索更多文档(如topK(10)),再用一个更小的模型对结果重排序,提升精度。

  • 性能与成本:注意OpenAI API的调用成本和速率限制。对于大量文档,考虑异步批处理嵌入任务。

  • 错误处理:增加对API调用失败、文档解析异常等的处理。

这个架构为您提供了一个坚实的企业级RAG应用基础。您可以根据业务需求,在此基础上增加用户认证、对话历史、多轮问答等高级功能。

❤️❤️❤️本人水平有限,如有纰漏,欢迎各位大佬评论批评指正!😄😄😄

💘💘💘如果觉得这篇文对你有帮助的话,也请给个点赞、收藏下吧,非常感谢!👍 👍 👍

🔥🔥🔥Stay Hungry Stay Foolish 道阻且长,行则将至,让我们一起加油吧!🌙🌙🌙

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐