HoRain云--SpringBoot构建RAG应用:AI问答新体验
本文介绍了基于SpringBoot、SpringAI、MongoDB Atlas和OpenAI构建RAG(检索增强生成)应用的完整指南。RAG技术通过检索外部知识库增强大语言模型的回答准确性。文章详细讲解了环境准备、项目搭建、核心代码实现(包括文档模型、检索服务、REST API)以及部署运行流程,并提供了进阶优化建议。该方案整合了企业知识库与大语言模型,能有效解决AI模型的"幻觉&qu

🎬 HoRain云小助手:个人主页
🔥 个人专栏: 《Linux 系列教程》《c语言教程》
⛺️生活的理想,就是为了理想的生活!
⛳️ 推荐
前些天发现了一个超棒的服务器购买网站,性价比超高,大内存超划算!忍不住分享一下给大家。点击跳转到网站。
专栏介绍
|
专栏名称 |
专栏介绍 |
|
本专栏主要撰写C干货内容和编程技巧,让大家从底层了解C,把更多的知识由抽象到简单通俗易懂。 |
|
|
本专栏主要是注重从底层来给大家一步步剖析网络协议的奥秘,一起解密网络协议在运行中协议的基本运行机制! |
|
|
全面深入解析 docker 容器,从基础到进阶,涵盖原理、操作、实践案例,助您精通 docker。 |
|
|
本专栏主要撰写Linux干货内容,从基础到进阶,知识由抽象到简单通俗易懂,帮你从新手小白到扫地僧。 |
|
|
本专栏着重撰写Python相关的干货内容与编程技巧,助力大家从底层去认识Python,将更多复杂的知识由抽象转化为简单易懂的内容。 |
|
|
本专栏主要是发布一些考试和练习题库(涵盖软考、HCIE、HRCE、CCNA等) |
目录

基于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-turbo或gpt-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.yml或application.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;
}
四、部署与运行
-
启动应用:运行Spring Boot主类。
-
首次运行:Spring AI会根据配置(
initialize-schema: true)在MongoDB Atlas中自动创建集合和向量搜索索引。 -
数据灌入:调用
POST /api/rag/ingest?filePath=/path/to/your/doc.txt上传您的知识文档(支持TXT、PDF等格式,需自行实现文件解析)。 -
智能问答:调用
POST /api/rag/ask传入问题,即可获得基于知识库的答案。
五、进阶优化与注意事项
-
文档分块策略:根据文档类型(如技术文档、合同)调整分块大小和重叠区,以保持语义完整性。
-
元数据过滤:在
SearchRequest中使用.filterExpression()进行元数据过滤,实现更精确的检索。 -
重排序(Reranking):如LyricMind示例所示,可以先检索更多文档(如
topK(10)),再用一个更小的模型对结果重排序,提升精度。 -
性能与成本:注意OpenAI API的调用成本和速率限制。对于大量文档,考虑异步批处理嵌入任务。
-
错误处理:增加对API调用失败、文档解析异常等的处理。
这个架构为您提供了一个坚实的企业级RAG应用基础。您可以根据业务需求,在此基础上增加用户认证、对话历史、多轮问答等高级功能。
❤️❤️❤️本人水平有限,如有纰漏,欢迎各位大佬评论批评指正!😄😄😄
💘💘💘如果觉得这篇文对你有帮助的话,也请给个点赞、收藏下吧,非常感谢!👍 👍 👍
🔥🔥🔥Stay Hungry Stay Foolish 道阻且长,行则将至,让我们一起加油吧!🌙🌙🌙
更多推荐



所有评论(0)