Spring Boot + LangChain4j 集成通义千问实现智能对话系统
·
Spring Boot + LangChain4j 集成通义千问实现智能对话系统
1. 项目概述
本文介绍如何使用 Spring Boot 框架集成 LangChain4j,结合通义千问大模型,构建一个具备对话记忆和工具调用能力的智能对话系统。系统支持普通对话和流式对话两种模式。
2. 项目依赖配置
2.1 Maven Pom.xml 配置
首先,在项目的 pom.xml 文件中添加必要的依赖:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.0</version>
<relativePath/>
</parent>
<groupId>com.example</groupId>
<artifactId>lost-system</artifactId>
<version>1.0.0</version>
<name>lostSystem</name>
<description>基于LangChain4j的智能对话系统</description>
<properties>
<java.version>17</java.version>
<langchain4j.version>1.0.0-beta3</langchain4j.version>
<mybatis-plus.version>3.5.11</mybatis-plus.version>
</properties>
<dependencies>
<!-- Spring Boot Starters -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- 数据库相关 -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<!-- MyBatis-Plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot-3-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
<!-- LangChain4j 核心依赖 -->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-spring-boot-starter</artifactId>
<version>${langchain4j.version}</version>
</dependency>
<!-- LangChain4j 通义千问集成 -->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-community-dashscope-spring-boot-starter</artifactId>
<version>${langchain4j.version}</version>
</dependency>
<!-- LangChain4j Reactor支持 -->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-reactor</artifactId>
<version>${langchain4j.version}</version>
</dependency>
<!-- 工具类 -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.16</version>
</dependency>
<!-- 开发工具 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- 测试依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
2.2 配置文件说明
创建 application.yml 配置文件:
spring:
application:
name: lostSystem
# 数据源配置
datasource:
url: jdbc:mysql://localhost:3306/langchain4j?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useSSL=false
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
# JPA配置
jpa:
show-sql: true
properties:
hibernate:
format_sql: true
dialect: org.hibernate.dialect.MySQL8Dialect
server:
port: 8090
# LangChain4j 通义千问配置
langchain4j:
community:
dashscope:
# 流式聊天模型配置
streaming-chat-model:
api-key: sk-你的API密钥
model-name: qwen-max
temperature: 0.7
max-tokens: 2000
# 普通聊天模型配置
chat-model:
api-key: sk-你的API密钥
model-name: qwen-max
temperature: 0.7
max-tokens: 2000
# 日志配置
logging:
level:
org.hibernate.type.descriptor.sql: TRACE
org.hibernate.SQL: DEBUG
com.example.lostsystem: DEBUG
# MyBatis-Plus SQL日志配置
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
3. 核心组件实现
3.1 AI服务接口定义
创建AI助手接口,支持普通对话和流式对话:
package com.example.lostsystem.service;
import dev.langchain4j.service.AiService;
import dev.langchain4j.service.AiServiceWiringMode;
import dev.langchain4j.service.MemoryId;
import dev.langchain4j.service.UserMessage;
import reactor.core.publisher.Flux;
/**
* AI助手服务接口
* wiringMode = EXPLICIT: 显式指定依赖注入
*/
@AiService(
wiringMode = AiServiceWiringMode.EXPLICIT,
chatModel = "qwenChatModel", // 普通聊天模型Bean名称
streamingChatModel = "qwenStreamingChatModel", // 流式聊天模型Bean名称
chatMemoryProvider = "chatMemoryProvider", // 对话记忆提供者
tools = {"testTools"} // 工具类列表
)
public interface AiAssistant {
/**
* 普通对话接口
* @param id 用户ID,用于对话记忆
* @param message 用户消息
* @return AI回复
*/
String chat(@MemoryId String id, @UserMessage String message);
/**
* 流式对话接口
* @param id 用户ID,用于对话记忆
* @param message 用户消息
* @return 流式回复
*/
Flux<String> chatStream(@MemoryId String id, @UserMessage String message);
}
3.2 对话记忆配置
配置对话记忆,支持多轮对话上下文:
package com.example.lostsystem.config;
import dev.langchain4j.memory.ChatMemory;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import dev.langchain4j.memory.chat.ChatMemoryProvider;
import dev.langchain4j.store.memory.chat.ChatMemoryStore;
import dev.langchain4j.store.memory.chat.InMemoryChatMemoryStore;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 对话记忆配置类
*/
@Configuration
public class ChatMemoryConfig {
/**
* 配置对话记忆提供者
* @return ChatMemoryProvider
*/
@Bean
public ChatMemoryProvider chatMemoryProvider() {
return memoryId -> MessageWindowChatMemory.builder()
.id(memoryId)
.maxMessages(20) // 保留最近20条消息
.chatMemoryStore(chatMemoryStore())
.build();
}
/**
* 配置对话记忆存储(内存存储)
* @return ChatMemoryStore
*/
@Bean
public ChatMemoryStore chatMemoryStore() {
return new InMemoryChatMemoryStore();
}
/**
* 全局对话记忆(可选)
* @return ChatMemory
*/
@Bean
public ChatMemory globalChatMemory() {
return MessageWindowChatMemory.withMaxMessages(10);
}
}
3.3 工具类实现
创建AI可以调用的工具函数:
package com.example.lostsystem.tools;
import dev.langchain4j.agent.tool.Tool;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
/**
* 测试工具类
* AI可以通过这些工具获取外部信息
*/
@Slf4j
@Component
public class TestTools {
/**
* 获取用户所在班级
* @Tool注解让AI知道这是一个可调用的工具
*/
@Tool("根据用户ID获取用户所在的班级信息")
public String getUserClass(String userId) {
log.info("获取用户 {} 所在的班级", userId);
// 这里可以连接数据库查询真实数据
// 示例:根据用户ID返回班级
if ("111".equals(userId)) {
return "计算机科学与技术1班";
} else if ("222".equals(userId)) {
return "软件工程2班";
}
return "未分配班级";
}
/**
* 获取今天的天气信息
*/
@Tool("获取指定城市的今日天气情况")
public String getCurrentWeather(String city) {
log.info("获取 {} 的天气信息", city);
// 这里可以调用天气API
// 示例返回
if ("北京".equals(city)) {
return "北京今天晴,温度15-25℃,空气质量良";
} else if ("上海".equals(city)) {
return "上海今天多云,温度18-26℃,空气质量优";
}
return city + "今天天气信息暂不可用";
}
/**
* 获取当前日期
*/
@Tool("获取当前系统日期")
public String getCurrentDate() {
return LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy年MM月dd日"));
}
/**
* 计算两个数字的和
*/
@Tool("计算两个数字的和")
public String calculateSum(int a, int b) {
int result = a + b;
return a + " + " + b + " = " + result;
}
}
3.4 控制器实现
创建RESTful API接口:
package com.example.lostsystem.controller;
import com.example.lostsystem.service.AiAssistant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
/**
* AI对话控制器
*/
@Slf4j
@RestController
@RequestMapping("/api/ai")
public class AiController {
@Autowired
private AiAssistant aiAssistant;
/**
* 普通对话接口
* GET /api/ai/chat?userId=123&message=你好
*/
@GetMapping("/chat")
public String chat(
@RequestParam(value = "userId", defaultValue = "default_user") String userId,
@RequestParam(value = "message", defaultValue = "你好") String message) {
log.info("收到普通对话请求 - 用户ID: {}, 消息: {}", userId, message);
try {
String response = aiAssistant.chat(userId, message);
log.info("AI回复: {}", response);
return response;
} catch (Exception e) {
log.error("对话处理失败", e);
return "抱歉,AI服务暂时不可用,请稍后重试。";
}
}
/**
* 流式对话接口
* GET /api/ai/chat/stream?userId=123&message=你好
*/
@GetMapping(value = "/chat/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<String> chatStream(
@RequestParam(value = "userId", defaultValue = "default_user") String userId,
@RequestParam(value = "message", defaultValue = "你好") String message) {
log.info("收到流式对话请求 - 用户ID: {}, 消息: {}", userId, message);
return aiAssistant.chatStream(userId, message)
.doOnNext(chunk -> log.debug("流式响应片段: {}", chunk))
.doOnError(error -> log.error("流式对话失败", error))
.onErrorReturn("流式对话中断,请重试。");
}
/**
* POST方式对话接口
*/
@PostMapping("/chat")
public String chatPost(@RequestBody ChatRequest request) {
return chat(request.getUserId(), request.getMessage());
}
/**
* 对话请求DTO
*/
public static class ChatRequest {
private String userId;
private String message;
// getters and setters
public String getUserId() { return userId; }
public void setUserId(String userId) { this.userId = userId; }
public String getMessage() { return message; }
public void setMessage(String message) { this.message = message; }
}
}
3.5 应用启动类
package com.example.lostsystem;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
/**
* 应用启动类
*/
@SpringBootApplication
@EnableJpaAuditing
public class LostSystemApplication {
public static void main(String[] args) {
SpringApplication.run(LostSystemApplication.class, args);
System.out.println("""
========================================
LostSystem 智能对话系统启动成功!
访问地址:http://localhost:8090
接口文档:
普通对话:GET /api/ai/chat?userId=xxx&message=xxx
流式对话:GET /api/ai/chat/stream?userId=xxx&message=xxx
========================================
""");
}
}
4. 使用示例
4.1 启动应用
- 确保MySQL数据库已启动,并创建
langchain4j数据库 - 在
application.yml中配置正确的数据库连接信息和通义千问API密钥 - 运行
LostSystemApplication启动应用
4.2 测试接口
普通对话测试
# 使用curl测试
curl "http://localhost:8090/api/ai/chat?userId=123&message=你好,我是张三"
# 或使用浏览器访问
http://localhost:8090/api/ai/chat?userId=123&message=今天天气怎么样?
流式对话测试
# 使用curl测试流式响应
curl -N "http://localhost:8090/api/ai/chat/stream?userId=123&message=介绍一下Java"
# 或使用支持SSE的客户端
4.3 工具调用示例
AI会自动识别何时需要调用工具:
用户:我在哪个班级?
AI:正在为您查询班级信息...(调用getUserClass工具)
回复:您所在的班级是计算机科学与技术1班。
用户:今天北京天气如何?
AI:正在查询北京天气...(调用getCurrentWeather工具)
回复:北京今天晴,温度15-25℃,空气质量良。
5. 项目结构说明
lost-system/
├── src/main/java/com/example/lostsystem/
│ ├── LostSystemApplication.java # 启动类
│ ├── config/
│ │ └── ChatMemoryConfig.java # 对话记忆配置
│ ├── controller/
│ │ └── AiController.java # 控制器
│ ├── service/
│ │ └── AiAssistant.java # AI服务接口
│ ├── tools/
│ │ └── TestTools.java # 工具类
│ └── entity/ # 实体类(可选)
├── src/main/resources/
│ ├── application.yml # 配置文件
│ └── static/ # 静态资源
└── pom.xml # Maven配置
6. 常见问题解决
6.1 API密钥配置
确保在 application.yml 中正确配置通义千问API密钥:
langchain4j:
community:
dashscope:
chat-model:
api-key: sk-你的真实API密钥
6.2 数据库连接失败
检查MySQL服务是否启动,数据库是否存在:
-- 创建数据库
CREATE DATABASE langchain4j CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
更多推荐



所有评论(0)