SpringBoot + LangChain4j + Ollama:本地大模型接入 Java 应用,智能客服快速落地

今天咱们聊聊一个最近特别火的话题:大模型接入Java应用。

传统客服的痛点

在我们的日常开发中,经常遇到这样的需求:

  • 客服每天重复回答同样的问题:"我的订单怎么还没到?"
  • 客服人手不够,高峰期响应慢
  • 人工客服培训成本高,服务质量参差不齐
  • 节假日人力成本高,但业务不能停

传统的人工客服不仅成本高,而且效率低下。现在有了大模型,我们能不能让AI来当客服呢?

解决方案思路

今天我们要解决的,就是如何用LangChain4j + Ollama构建一个本地智能客服系统。

核心思路是:

  1. 本地部署:使用Ollama在本地运行大模型,保护数据安全
  2. Java集成:通过LangChain4j框架集成大模型功能
  3. 对话管理:实现多轮对话和上下文管理
  4. 业务适配:结合具体业务场景进行定制

技术选型

  • SpringBoot:快速搭建应用
  • LangChain4j:Java友好的大模型集成框架
  • Ollama:本地大模型运行环境
  • Llama 2/3 或者其他开源模型:大模型选择

核心实现思路

1. 环境准备

首先安装Ollama并下载模型:

# 安装Ollama
curl -fsSL https://ollama.ai/install.sh | sh

# 下载模型
ollama pull llama3
# 或者其他模型
ollama pull mistral

2. 项目依赖配置

在pom.xml中添加LangChain4j依赖:

<dependency>
    <groupId>dev.langchain4j</groupId>
    <artifactId>langchain4j</artifactId>
    <version>0.28.0</version>
</dependency>
<dependency>
    <groupId>dev.langchain4j</groupId>
    <artifactId>langchain4j-ollama</artifactId>
    <version>0.28.0</version>
</dependency>

3. 大模型配置

配置Ollama模型连接:

@Configuration
public class AIConfig {
    
    @Bean
    public ChatLanguageModel chatLanguageModel() {
        return OllamaChatModel.builder()
                .baseUrl("http://localhost:11434")  // Ollama默认端口
                .modelName("llama3")  // 使用的模型
                .temperature(0.7)     // 控制输出随机性
                .timeout(Duration.ofSeconds(60))
                .build();
    }
    
    @Bean
    public MessageWindowChatMemory chatMemory() {
        // 创建聊天记忆,用于多轮对话
        return MessageWindowChatMemory.withMaxMessages(10);
    }
}

4. 智能客服服务

创建核心的客服服务:

@Service
public class CustomerServiceAI {
    
    private final ChatLanguageModel model;
    private final ChatMemory chatMemory;
    private final PromptTemplate promptTemplate;
    
    public CustomerServiceAI(ChatLanguageModel model, 
                           @Qualifier("chatMemory") ChatMemory chatMemory) {
        this.model = model;
        this.chatMemory = chatMemory;
        
        // 定义客服提示词模板
        this.promptTemplate = PromptTemplate.from(
            "你是我们公司的智能客服助手。请根据以下信息回答用户问题:\n" +
            "公司政策:{{policy}}\n" +
            "常见问题:{{faq}}\n" +
            "用户问题:{{question}}\n" +
            "请提供友好、专业且准确的回答:"
        );
    }
    
    public String answerCustomerQuestion(String question, String context) {
        // 准备提示词变量
        Map<String, Object> variables = Map.of(
            "policy", getCompanyPolicy(),
            "faq", getCommonFAQ(),
            "question", question
        );
        
        Prompt prompt = promptTemplate.apply(variables);
        
        // 发送给大模型并获取响应
        Response<AiMessage> response = model.generate(
            ChatMessage.user(prompt.toSystemMessage()),
            ChatMessage.user(question)
        );
        
        return response.content().text();
    }
    
    public String chatWithMemory(String userInput) {
        // 使用记忆的对话
        TokenStreamResponse response = model.generate(userInput, chatMemory);
        return response.content();
    }
    
    private String getCompanyPolicy() {
        // 返回公司政策信息
        return "退换货政策:7天无理由退货,质量问题30天内免费换新";
    }
    
    private String getCommonFAQ() {
        // 返回常见问题
        return "订单查询:提供订单号即可查询;物流跟踪:提供快递单号;售后电话:400-xxx-xxxx";
    }
}

5. 嵌入式知识库

为了提供更准确的回答,我们可以集成向量数据库:

@Service
public class KnowledgeBasedCustomerService {
    
    private final EmbeddingModel embeddingModel;
    private final EmbeddingStore<TextSegment> embeddingStore;
    
    public KnowledgeBasedCustomerService() {
        // 初始化嵌入模型
        this.embeddingModel = OllamaEmbeddingModel.builder()
                .baseUrl("http://localhost:11434")
                .modelName("nomic-embed-text")  // 用于嵌入的模型
                .build();
        
        // 初始化嵌入存储(这里使用内存存储,生产环境建议用Milvus等)
        this.embeddingStore = new InMemoryEmbeddingStore<>();
        
        // 加载FAQ知识库
        loadKnowledgeBase();
    }
    
    private void loadKnowledgeBase() {
        // 加载常见问题到知识库
        List<String> faqs = Arrays.asList(
            "如何查询订单?答:登录账户后在'我的订单'中查询。",
            "支持哪些支付方式?答:支持支付宝、微信支付、银行卡转账。",
            "退换货政策是什么?答:7天无理由退货,质量问题30天内免费换新。"
        );
        
        for (String faq : faqs) {
            TextSegment segment = TextSegment.from(faq);
            Embedding embedding = embeddingModel.embed(segment).content();
            embeddingStore.add(embedding, segment);
        }
    }
    
    public String answerWithKnowledge(String question) {
        // 搜索相关知识
        Embedding questionEmbedding = embeddingModel.embed(question).content();
        List<EmbeddingMatch<TextSegment>> relevantFragments = 
            embeddingStore.findRelevant(questionEmbedding, 3);
        
        // 构建上下文
        String context = relevantFragments.stream()
            .map(match -> match.embedded().text())
            .collect(Collectors.joining("\n"));
        
        // 使用上下文回答问题
        String prompt = String.format(
            "根据以下知识库信息回答用户问题:\n%s\n\n用户问题:%s",
            context, question
        );
        
        Response<AiMessage> response = model.generate(ChatMessage.user(prompt));
        return response.content().text();
    }
}

6. 客服API接口

提供RESTful API供前端调用:

@RestController
@RequestMapping("/api/customer-service")
public class CustomerServiceController {
    
    @Autowired
    private CustomerServiceAI customerServiceAI;
    
    @Autowired
    private KnowledgeBasedCustomerService knowledgeService;
    
    @PostMapping("/ask")
    public Result<String> askQuestion(@RequestBody QuestionRequest request) {
        String answer = knowledgeService.answerWithKnowledge(request.getQuestion());
        return Result.success(answer);
    }
    
    @PostMapping("/chat")
    public Result<String> chat(@RequestBody ChatRequest request) {
        String response = customerServiceAI.chatWithMemory(request.getMessage());
        return Result.success(response);
    }
    
    @PostMapping("/reset-chat")
    public Result<Void> resetChat() {
        // 重置聊天记忆
        return Result.success();
    }
}

7. 客服机器人管理

提供客服机器人的管理功能:

@Service
public class CustomerBotManager {
    
    private final Map<String, CustomerServiceAI> botSessions = new ConcurrentHashMap<>();
    
    public String processCustomerRequest(String sessionId, String question) {
        CustomerServiceAI bot = botSessions.computeIfAbsent(sessionId, 
            k -> new CustomerServiceAI(getModel(), createSessionMemory(k)));
        
        return bot.answerCustomerQuestion(question, getSessionContext(sessionId));
    }
    
    private ChatMemory createSessionMemory(String sessionId) {
        return MessageWindowChatMemory.builder()
            .id(sessionId)
            .maxMessages(10)
            .build();
    }
    
    public void closeSession(String sessionId) {
        botSessions.remove(sessionId);
    }
}

性能优化策略

1. 缓存机制

@Service
public class CachedCustomerService {
    
    @Cacheable(value = "customerAnswers", key = "#question")
    public String getCachedAnswer(String question) {
        return knowledgeService.answerWithKnowledge(question);
    }
}

2. 流式响应

@GetMapping(value = "/stream-chat", produces = MediaType.TEXT_PLAIN_VALUE)
public SseEmitter streamChat(@RequestParam String question) {
    SseEmitter emitter = new SseEmitter(60000L);
    
    CompletableFuture.runAsync(() -> {
        try {
            TokenStreamResponse response = model.generate(question);
            response.onPartialResponse(partialResponse -> {
                try {
                    emitter.send(SseEmitter.event().data(partialResponse));
                } catch (IOException e) {
                    emitter.completeWithError(e);
                }
            }).onComplete(response1 -> emitter.complete())
              .onError(error -> emitter.completeWithError(error));
        } catch (Exception e) {
            emitter.completeWithError(e);
        }
    });
    
    return emitter;
}

优势分析

相比传统客服系统,这种方式的优势明显:

  1. 成本效益:大幅降低人工客服成本
  2. 7×24小时服务:不受时间和节假日限制
  3. 快速响应:秒级回复,提升用户体验
  4. 个性化服务:基于历史对话提供个性化建议
  5. 数据安全:本地部署,数据不出域

注意事项

  1. 模型选择:根据业务需求选择合适的模型大小
  2. 硬件要求:大模型运行需要充足的GPU或CPU资源
  3. 响应质量:需要持续训练和优化模型
  4. 异常处理:处理模型无法回答的情况
  5. 人工接管:复杂问题需要人工客服介入

总结

通过SpringBoot + LangChain4j + Ollama的技术组合,我们可以快速构建一个功能强大的智能客服系统。这种方式不仅降低了运营成本,还提升了用户体验。

在实际项目中,建议先从小范围试点开始,逐步优化模型和业务逻辑,最终实现智能客服的全面应用。


服务端技术精选,专注分享后端开发实战技术,助力你的技术成长!


标题:SpringBoot + LangChain4j + Ollama:本地大模型接入 Java 应用,智能客服快速落地
作者:jiangyi
地址:http://www.jiangyi.space/articles/2026/01/09/1767938185314.html

    0 评论
avatar