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. 性能优化建议

  1. 模型选择:根据硬件资源选择合适的模型大小
  2. 向量数据库:使用Redis或Milvus等高性能向量数据库
  3. 缓存策略:对常见问题的回答进行缓存
  4. 负载均衡:使用Nginx等工具实现负载均衡

总结

通过SpringBoot + Ollama + RAG技术栈,我们可以轻松构建一个功能强大的私有化智能客服系统。这种方案不仅能够保证数据安全,还能根据业务需求灵活定制,是企业级AI应用的理想选择。

随着大模型技术的不断发展,本地部署AI应用将成为趋势。掌握这项技术,不仅能提升用户体验,还能为企业节省大量成本。赶紧试试吧!


本文由服务端技术精选原创,转载请注明出处。关注我们,获取更多后端技术干货!


标题:SpringBoot + Ollama + RAG:本地大模型 + 知识库问答系统,私有化部署智能客服
作者:jiangyi
地址:http://jiangyi.space/articles/2026/01/07/1767781136483.html

    0 评论
avatar