SpringBoot + Ollama + RAG:本地大模型 + 知识库问答系统,私有化部署智能客服
引言
最近AI技术火得一塌糊涂,各种大模型层出不穷。但你知道吗?现在我们可以在本地部署大模型,搭建自己的智能客服系统,而且完全私有化,不用担心数据泄露问题。今天就来给大家分享一个超实用的技术方案:SpringBoot + Ollama + RAG,让你的智能客服系统既聪明又安全。
什么是Ollama和RAG?
Ollama:本地大模型运行神器
Ollama是一个轻量级框架,可以让我们在本地运行各种流行的LLM(大语言模型),比如Llama 3、Mistral等。相比调用云端API,Ollama有以下优势:
- 数据安全:所有数据都在本地处理,不用担心敏感信息泄露
- 成本控制:无需支付API调用费用,适合企业级应用
- 响应速度:本地运行,响应更快,延迟更低
- 可定制性:可以根据业务需求选择合适的模型
RAG:检索增强生成技术
RAG(Retrieval-Augmented Generation)是一种结合信息检索和文本生成的技术。简单来说,就是当用户提问时,系统会先从知识库中检索相关信息,然后结合这些信息生成准确的回答。
RAG的核心优势:
- 知识更新:可以随时更新知识库,模型无需重新训练
- 准确性提升:基于真实数据生成回答,减少幻觉问题
- 领域适应:可以针对特定领域构建专业知识库
系统架构设计
我们的智能客服系统架构如下:
用户提问 → SpringBoot Web API → RAG检索 → Ollama模型 → 生成回答
主要组件:
- SpringBoot:提供REST API接口,处理用户请求
- Ollama:运行本地大语言模型
- 向量数据库:存储知识库的向量表示
- 文档处理器:将原始文档转换为向量
具体实现步骤
1. 环境准备
首先,我们需要安装Ollama。在macOS上,可以通过以下命令安装:
curl -fsSL https://ollama.ai/install.sh | sh
启动Ollama服务:
ollama serve
拉取需要的模型(以Llama 3为例):
ollama pull llama3
2. SpringBoot项目搭建
创建SpringBoot项目,添加必要的依赖:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring AI Ollama 依赖 -->
<dependency>
<groupId>org.springframework.experimental.ai</groupId>
<artifactId>spring-ai-ollama-spring-boot-starter</artifactId>
<version>0.8.1</version>
</dependency>
<!-- 向量存储 -->
<dependency>
<groupId>org.springframework.experimental.ai</groupId>
<artifactId>spring-ai-redis-spring-boot-starter</artifactId>
<version>0.8.1</version>
</dependency>
<!-- LangChain4J -->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j</artifactId>
<version>0.29.0</version>
</dependency>
</dependencies>
3. 配置文件设置
在application.yml中配置Ollama和向量存储:
spring:
ai:
ollama:
base-url: http://localhost:11434
chat:
options:
model: llama3
temperature: 0.7
vectorstore:
redis:
index-name: knowledge_base
distance-metric: COSINE
server:
port: 8080
4. 核心代码实现
创建智能客服服务类:
@Service
public class IntelligentCustomerService {
private final ChatModel chatModel;
private final EmbeddingModel embeddingModel;
private final RedisVectorStore vectorStore;
public IntelligentCustomerService(ChatModel chatModel,
EmbeddingModel embeddingModel,
RedisVectorStore vectorStore) {
this.chatModel = chatModel;
this.embeddingModel = embeddingModel;
this.vectorStore = vectorStore;
}
/**
* 根据用户问题生成回答
*/
public String getAnswer(String question) {
// 1. 使用向量存储检索相关信息
List<Document> relevantDocuments = vectorStore.search(
EmbeddingSearchRequest.builder()
.queryTexts(question)
.maxResults(3)
.minScore(0.7)
.build()
).getContents();
// 2. 构建提示词,包含检索到的上下文
String context = relevantDocuments.stream()
.map(Document::getText)
.collect(Collectors.joining("\n"));
String prompt = String.format(
"基于以下上下文信息回答问题:\n\n上下文:%s\n\n问题:%s\n\n请根据上下文提供准确的回答,如果上下文信息不足,请说明信息不足。",
context, question
);
// 3. 使用Ollama模型生成回答
return chatModel.generate(prompt);
}
/**
* 向知识库添加文档
*/
public void addDocument(String content, Map<String, Object> metadata) {
Document document = Document.builder()
.text(content)
.metadata(metadata)
.build();
vectorStore.add(List.of(document));
}
}
创建REST控制器:
@RestController
@RequestMapping("/api/customer-service")
public class CustomerServiceController {
private final IntelligentCustomerService customerService;
public CustomerServiceController(IntelligentCustomerService customerService) {
this.customerService = customerService;
}
@PostMapping("/ask")
public ResponseEntity<String> askQuestion(@RequestBody QuestionRequest request) {
try {
String answer = customerService.getAnswer(request.getQuestion());
return ResponseEntity.ok(answer);
} catch (Exception e) {
return ResponseEntity.status(500).body("处理问题时发生错误:" + e.getMessage());
}
}
@PostMapping("/knowledge-base/add")
public ResponseEntity<String> addKnowledge(@RequestBody KnowledgeRequest request) {
try {
Map<String, Object> metadata = Map.of(
"source", request.getSource(),
"category", request.getCategory(),
"timestamp", System.currentTimeMillis()
);
customerService.addDocument(request.getContent(), metadata);
return ResponseEntity.ok("知识库更新成功");
} catch (Exception e) {
return ResponseEntity.status(500).body("添加知识时发生错误:" + e.getMessage());
}
}
}
// 请求对象
class QuestionRequest {
private String question;
// getter and setter
public String getQuestion() {
return question;
}
public void setQuestion(String question) {
this.question = question;
}
}
class KnowledgeRequest {
private String content;
private String source;
private String category;
// getters and setters
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getSource() {
return source;
}
public void setSource(String source) {
this.source = source;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
}
5. 知识库初始化
创建一个初始化服务,用于加载初始知识库:
@Component
public class KnowledgeBaseInitializer {
private final IntelligentCustomerService customerService;
public KnowledgeBaseInitializer(IntelligentCustomerService customerService) {
this.customerService = customerService;
}
@EventListener(ApplicationReadyEvent.class)
public void initializeKnowledgeBase() {
// 示例:添加常见问题到知识库
addFaqToKnowledgeBase();
}
private void addFaqToKnowledgeBase() {
// 示例FAQ数据
List<String> faqData = Arrays.asList(
"Q: 你们的产品支持退款吗?\nA: 我们提供7天无理由退款服务,详情请查看退款政策。",
"Q: 如何联系客服?\nA: 您可以通过在线客服、邮件或电话联系我们的客服团队。",
"Q: 产品有哪些功能?\nA: 我们的产品包含功能A、功能B和功能C,具体请查看产品介绍页面。"
);
for (int i = 0; i < faqData.size(); i++) {
String content = faqData.get(i);
Map<String, Object> metadata = Map.of(
"type", "faq",
"priority", i
);
customerService.addDocument(content, metadata);
}
System.out.println("知识库初始化完成,共添加 " + faqData.size() + " 条FAQ");
}
}
私有化部署方案
1. Docker化部署
创建Dockerfile:
FROM openjdk:17-jdk-slim
# 安装Ollama
RUN apt-get update && \
apt-get install -y curl && \
curl -fsSL https://ollama.ai/install.sh | sh
# 复制应用jar文件
COPY target/customer-service-app.jar app.jar
# 创建模型目录
RUN mkdir -p /usr/src/app/models
# 设置工作目录
WORKDIR /usr/src/app
# 暴露端口
EXPOSE 8080 11434
# 启动脚本
COPY start.sh .
RUN chmod +x start.sh
ENTRYPOINT ["./start.sh"]
创建启动脚本start.sh:
#!/bin/bash
# 启动Ollama服务
ollama serve &
# 等待Ollama启动
sleep 10
# 拉取模型
ollama pull llama3
# 启动SpringBoot应用
java -jar app.jar
2. Docker Compose配置
创建docker-compose.yml:
version: '3.8'
services:
redis:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
- redis_data:/data
ollama:
image: ollama/ollama:latest
ports:
- "11434:11434"
volumes:
- ollama_models:/root/.ollama
environment:
- CUDA_VISIBLE_DEVICES=all # 如果有GPU支持
customer-service:
build: .
ports:
- "8080:8080"
depends_on:
- redis
- ollama
environment:
- SPRING_REDIS_HOST=redis
- SPRING_REDIS_PORT=6379
- SPRING_AI_OLLAMA_BASE_URL=http://ollama:11434
volumes:
redis_data:
ollama_models:
3. 性能优化建议
- 模型选择:根据硬件资源选择合适的模型大小
- 向量数据库:使用Redis或Milvus等高性能向量数据库
- 缓存策略:对常见问题的回答进行缓存
- 负载均衡:使用Nginx等工具实现负载均衡
总结
通过SpringBoot + Ollama + RAG技术栈,我们可以轻松构建一个功能强大的私有化智能客服系统。这种方案不仅能够保证数据安全,还能根据业务需求灵活定制,是企业级AI应用的理想选择。
随着大模型技术的不断发展,本地部署AI应用将成为趋势。掌握这项技术,不仅能提升用户体验,还能为企业节省大量成本。赶紧试试吧!
本文由服务端技术精选原创,转载请注明出处。关注我们,获取更多后端技术干货!
标题:SpringBoot + Ollama + RAG:本地大模型 + 知识库问答系统,私有化部署智能客服
作者:jiangyi
地址:http://jiangyi.space/articles/2026/01/07/1767781136483.html