微信扫码
添加专属顾问
我要投稿
告别低效搜索!Spring AI + Milvus强强联手,教你打造能"理解"问题的智能问答系统。 核心内容: 1. RAG技术原理:从语义搜索到检索增强生成的完整流程解析 2. 实战搭建:Spring Boot整合Spring AI与Milvus向量数据库的关键步骤 3. 效果对比:传统搜索与智能问答系统的性能差异实测
引言
“公司的文档太多,查找信息太慢!”、“客服回答总是千篇一律,不能精准解答用户问题!” —— 这些痛点背后,是传统关键词搜索和规则引擎的局限。如今,语义搜索(Semantic Search) 和 检索增强生成(Retrieval-Augmented Generation, RAG) 正成为解决这些问题的利器。它们能让应用“理解”用户问题的真正意图,并从海量资料中精准找出相关信息,甚至生成自然流畅的答案。
作为 Java 开发者,如何快速构建这样的智能应用?好消息是:Spring AI 为 Java 生态带来了便捷的 AI 集成能力!本文将手把手带你使用 Spring Boot + Spring AI + Milvus(向量数据库),构建一个基于 RAG 架构 的智能问答系统。我们将实现:将本地知识库文档转化为向量存储,根据用户问题语义检索最相关的文档片段,并驱动大语言模型(如 OpenAI GPT)生成精准、有据可依的回答。
一、核心概念扫盲
二、技术栈与环境准备
三、实战步骤
步骤 1:启动 Milvus 向量数据库
docker pull milvusdb/milvus:latest
docker run -d --name milvus-standalone \
-p 19530:19530 \
-p 9091:9091 \
milvusdb/milvus:latest
访问 http://localhost:9091
可查看 Milvus 管理界面。
步骤 2:创建 Spring Boot 项目 & 添加依赖
使用 start.spring.io 创建项目,添加依赖:
org.springframework.boot:spring-boot-starter-web
org.springframework.ai:spring-ai-openai-spring-boot-starter # 使用 OpenAI
// 或者本地模型 (例如使用 Ollama)
// org.springframework.ai:spring-ai-ollama-spring-boot-starter
org.springframework.ai:spring-ai-milvus-store-spring-boot-starter # Milvus 集成
步骤 3:配置 application.properties
# Spring AI - OpenAI 配置 (替换 your-api-key)
spring.ai.openai.api-key=YOUR_OPENAI_API_KEY
# 使用 Embedding 模型
spring.ai.openai.embedding.model=text-embedding-ada-002
# 使用 Chat 模型
spring.ai.openai.chat.model=gpt-3.5-turbo
# Milvus 向量存储配置
spring.ai.vectorstore.milvus.uri=http://localhost:19530
spring.ai.vectorstore.milvus.collection-name=my_knowledge_base # 自定义集合名
spring.ai.vectorstore.milvus.embedding-dimension=1536 # text-embedding-ada-002 输出维度
spring.ai.vectorstore.milvus.drop-collection-on-startup=false # 启动时是否删除重建集合 (首次可设 true)
步骤 4:构建知识库(文档向量化入库)
创建 VectorStoreInitializer
服务,在应用启动时将本地文档(如 TXT, PDF)加载到 Milvus:
import org.springframework.ai.document.Document;
import org.springframework.ai.reader.TextReader;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Service;
import jakarta.annotation.PostConstruct;
import java.util.List;
@Service
public class VectorStoreInitializer {
private final VectorStore vectorStore;
@Value("classpath:/docs/*.txt") // 假设知识库文档放在 resources/docs 下
private Resource[] documentResources;
@Autowired
public VectorStoreInitializer(VectorStore vectorStore) {
this.vectorStore = vectorStore;
}
@PostConstruct
public void init() {
// 遍历文档资源
for (Resource resource : documentResources) {
try {
// 使用 Spring AI 的 TextReader 读取文本文件
TextReader textReader = new TextReader(resource);
List<Document> documents = textReader.get();
// 将文档内容分割成更小的块 (可选,Spring AI 未来会提供 Splitter)
// ... 这里简化处理,直接将整个文件作为一个 Document
// 将文档块添加到向量库
vectorStore.add(documents);
System.out.println("Loaded documents from: " + resource.getFilename());
} catch (Exception e) {
System.err.println("Error loading document: " + resource.getFilename() + ", " + e.getMessage());
}
}
System.out.println("Knowledge base initialization complete!");
}
}
步骤 5:实现 RAG 智能问答服务
创建 RagService
:
import org.springframework.ai.chat.ChatClient;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.chat.prompt.SystemPromptTemplate;
import org.springframework.ai.document.Document;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Service
public class RagService {
private final ChatClient chatClient;
private final VectorStore vectorStore;
// 系统提示词模板 (定义 AI 的角色和回答规则)
@Value("classpath:/prompts/system-qa.st")
private Resource systemPromptResource;
@Autowired
public RagService(ChatClient chatClient, VectorStore vectorStore) {
this.chatClient = chatClient;
this.vectorStore = vectorStore;
}
public String answerQuestion(String userQuestion) {
// 1. 检索 (Retrieve):根据用户问题语义查找最相关的文档片段
List<Document> relevantDocuments = vectorStore.similaritySearch(userQuestion);
// 2. 构建上下文 (Context):将相关文档内容拼接起来
String context = relevantDocuments.stream()
.map(Document::getContent)
.collect(Collectors.joining("\n\n"));
// 3. 构建系统提示词 (System Prompt):将上下文注入预设模板
SystemPromptTemplate systemPromptTemplate = new SystemPromptTemplate(systemPromptResource);
String systemMessage = systemPromptTemplate.createMessage(Map.of("context", context));
// 4. 构建完整 Prompt:系统提示词 + 用户问题
Prompt prompt = new Prompt(List.of(
new org.springframework.ai.chat.messages.SystemMessage(systemMessage),
new UserMessage(userQuestion)
));
// 5. 调用 Chat 模型生成答案 (Generate)
return chatClient.call(prompt).getResult().getOutput().getContent();
}
}
系统提示词模板 (resources/prompts/system-qa.st
):
你是一个专业的智能问答助手。请严格根据以下提供的上下文信息来回答用户的问题。
如果上下文信息不足以回答用户的问题,请直接告知用户“根据我掌握的知识,暂时无法回答这个问题”,不要编造答案。
上下文信息如下:
{{context}}
步骤 6:创建 REST 控制器
创建 RagController
提供问答接口:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class RagController {
private final RagService ragService;
@Autowired
public RagController(RagService ragService) {
this.ragService = ragService;
}
@PostMapping("/ask")
public String askQuestion(@RequestBody String question) {
return ragService.answerQuestion(question);
}
}
四、运行与测试
docker run ...
)。product_manual.txt
, company_policy.txt
)放入 src/main/resources/docs/
。VectorStoreInitializer
会将文档内容通过 OpenAI Embedding API 转换为向量,并存储到 Milvus 的 my_knowledge_base
集合中。curl
或 Postman 测试智能问答接口:POST http://localhost:8080/ask
Content-Type: text/plain
公司今年的年假政策是怎样的?
company_policy.txt
中关于年假的部分)。五、关键点解析
VectorStore
和 ChatClient
接口屏蔽底层细节(Milvus/Pinecone/Redis, OpenAI/Azure/Ollama 等),代码简洁且可移植。text-embedding-ada-002
性价比高,也可考虑更新更强的模型。TextSplitter
。手动实现时需注意块边界语义。all-MiniLM-L6-v2
),避免 OpenAI API 调用费用。六、总结
通过 Spring Boot + Spring AI + Milvus 的组合,可以轻松构建强大的、基于 RAG 架构 的智能语义搜索和问答应用。Spring AI 极大地简化了 AI 能力集成,让 Java 后端也能快速拥抱大语言模型和向量数据库技术。
53AI,企业落地大模型首选服务商
产品:场景落地咨询+大模型应用平台+行业解决方案
承诺:免费POC验证,效果达标后再合作。零风险落地应用大模型,已交付160+中大型企业
2025-06-06
2025-05-30
2025-06-05
2025-05-19
2025-05-08
2025-05-10
2025-06-05
2025-05-20
2025-06-05
2025-05-09
2025-07-28
2025-07-09
2025-07-04
2025-07-01
2025-07-01
2025-07-01
2025-07-01
2025-06-30