SpringBoot + LangChain4j + Ollama:本地大模型接入 Java 应用,智能客服快速落地
今天咱们聊聊一个最近特别火的话题:大模型接入Java应用。
传统客服的痛点
在我们的日常开发中,经常遇到这样的需求:
- 客服每天重复回答同样的问题:"我的订单怎么还没到?"
- 客服人手不够,高峰期响应慢
- 人工客服培训成本高,服务质量参差不齐
- 节假日人力成本高,但业务不能停
传统的人工客服不仅成本高,而且效率低下。现在有了大模型,我们能不能让AI来当客服呢?
解决方案思路
今天我们要解决的,就是如何用LangChain4j + Ollama构建一个本地智能客服系统。
核心思路是:
- 本地部署:使用Ollama在本地运行大模型,保护数据安全
- Java集成:通过LangChain4j框架集成大模型功能
- 对话管理:实现多轮对话和上下文管理
- 业务适配:结合具体业务场景进行定制
技术选型
- 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;
}
优势分析
相比传统客服系统,这种方式的优势明显:
- 成本效益:大幅降低人工客服成本
- 7×24小时服务:不受时间和节假日限制
- 快速响应:秒级回复,提升用户体验
- 个性化服务:基于历史对话提供个性化建议
- 数据安全:本地部署,数据不出域
注意事项
- 模型选择:根据业务需求选择合适的模型大小
- 硬件要求:大模型运行需要充足的GPU或CPU资源
- 响应质量:需要持续训练和优化模型
- 异常处理:处理模型无法回答的情况
- 人工接管:复杂问题需要人工客服介入
总结
通过SpringBoot + LangChain4j + Ollama的技术组合,我们可以快速构建一个功能强大的智能客服系统。这种方式不仅降低了运营成本,还提升了用户体验。
在实际项目中,建议先从小范围试点开始,逐步优化模型和业务逻辑,最终实现智能客服的全面应用。
服务端技术精选,专注分享后端开发实战技术,助力你的技术成长!
标题:SpringBoot + LangChain4j + Ollama:本地大模型接入 Java 应用,智能客服快速落地
作者:jiangyi
地址:http://www.jiangyi.space/articles/2026/01/09/1767938185314.html
0 评论