请看文档,流程不再赘述:官网及其示例
简易聊天
环境变量
引入Spring AI Alibaba
记忆对话还需要我们有数据库进行存储,mysql:mysql-connector-java
<?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 https://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.5.3</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.dd.ai</groupId><artifactId>spring-ai-alibaba-demo</artifactId><version>0.0.1-SNAPSHOT</version><name>spring-ai-alibaba-demo</name><description>spring-ai-alibaba-demo</description><properties><java.version>17</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!-- 引入Spring AI Alibaba相关依赖--><dependency><groupId>com.alibaba.cloud.ai</groupId><artifactId>spring-ai-alibaba-starter-dashscope</artifactId><version>1.0.0.2</version></dependency>
<!--Spring AI Alibaba 提供了 jdbc、redis、elasticsearch 插件可以让聊天机器人拥有“记忆”。下面以 MySQL 为例,演示如何快速编写一个带有记忆的聊天机器人。--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.32</version></dependency><dependency><groupId>com.alibaba.cloud.ai</groupId><artifactId>spring-ai-alibaba-starter-memory-jdbc</artifactId><version>1.0.0.2</version></dependency></dependencies><dependencyManagement><dependencies><dependency><groupId>com.alibaba.cloud.ai</groupId><artifactId>spring-ai-alibaba-bom</artifactId><version>1.0.0.2</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>
配置文件
AI_DASHSCOPE_API_KEY: zz
#APP_ID: zzzserver:port: 8080spring:application:name: spring-ai-demoai:dashscope:agent:api-key: ${AI_DASHSCOPE_API_KEY} # 百炼API Key,如未配置环境变量,请在这里替换为实际的值#app-id: ${APP_ID} # 大模型应用ID,,非必须#workspace-id: ${WORKSPACE_ID} # 业务空间ID,可选,未配置时使用主账号空间datasource:username: rootpassword: 123456url: jdbc:mysql://localhost:3306/ai?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=truejpa:hibernate:ddl-auto: update # 自动更新数据库表结构show-sql: true # 显示 SQL 语句
controller
package com.dd.ai.springaialibabademo.controller;import com.alibaba.cloud.ai.dashscope.chat.DashScopeChatOptions;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;@RestController
@RequestMapping("/helloworld")
public class HelloworldController {private static final String DEFAULT_PROMPT = "你是一个博学的智能聊天助手,请根据用户提问回答!";private final ChatClient dashScopeChatClient;public HelloworldController(ChatClient.Builder chatClientBuilder) {this.dashScopeChatClient = chatClientBuilder.defaultSystem(DEFAULT_PROMPT)// 实现 Logger 的 Advisor.defaultAdvisors(new SimpleLoggerAdvisor())// 设置 ChatClient 中 ChatModel 的 Options 参数.defaultOptions(DashScopeChatOptions.builder().withTopP(0.7).build()).build();}/*** ChatClient 简单调用*/@GetMapping("/simple/chat")public String simpleChat(@RequestParam(value = "query", defaultValue = "你好,很高兴认识你,能简单介绍一下自己吗?")String query) {return dashScopeChatClient.prompt(query).call().content();}/*** ChatClient 流式调用*/@GetMapping("/stream/chat")public Flux<String> streamChat(@RequestParam(value = "query", defaultValue = "你好,很高兴认识你,能简单介绍一下自己吗?")String query, HttpServletResponse response) {response.setCharacterEncoding("UTF-8");return dashScopeChatClient.prompt(query).stream().content();}}
记忆聊天
Spring AI Alibaba 提供了 jdbc、redis、elasticsearch 插件可以让聊天机器人拥有“记忆”。环境变量和配置文件都在上一步加入了,也就是以 MySQL 为例
需要修改的地方
- HelloworldController的构造函数
public HelloworldController(JdbcTemplate jdbcTemplate, ChatClient.Builder chatClientBuilder) {// 构造 ChatMemoryRepository 和 ChatMemory// 创建基于 MySQL 的聊天记忆仓库,用于持久化存储对话历史记录ChatMemoryRepository chatMemoryRepository = MysqlChatMemoryRepository.mysqlBuilder().jdbcTemplate(jdbcTemplate).build();// 创建消息窗口形式的聊天记忆模块,使用上述仓库进行持久化存储ChatMemory chatMemory = MessageWindowChatMemory.builder().chatMemoryRepository(chatMemoryRepository).build();// 构建 DashScopeChatClient 实例this.dashScopeChatClient = chatClientBuilder// 设置默认系统提示语.defaultSystem(DEFAULT_PROMPT)// 添加日志记录顾问,用于调试时查看输入输出内容.defaultAdvisors(new SimpleLoggerAdvisor())// 注册记忆管理顾问,用于自动加载和保存会话历史.defaultAdvisors(MessageChatMemoryAdvisor.builder(chatMemory).build())// 配置模型参数:设置 TopP 采样策略为 0.7.defaultOptions(DashScopeChatOptions.builder().withTopP(0.7).build())// 完成客户端构建.build();}
- 方法参数
@RequestParam(value = “chat-id”, defaultValue = “1”) String chatId
/*** ChatClient 简单调用*/@GetMapping("/simple/chat")public String simpleChat(@RequestParam(value = "query", defaultValue = "你好,很高兴认识你,能简单介绍一下自己吗?")String query,@RequestParam(value = "chat-id", defaultValue = "1") String chatId) {return dashScopeChatClient.prompt(query).advisors(a -> a.param(ChatMemory.CONVERSATION_ID, chatId)).call().content();}/*** ChatClient 流式调用*/@GetMapping("/stream/chat")public Flux<String> streamChat(@RequestParam(value = "query", defaultValue = "你好,很高兴认识你,能简单介绍一下自己吗?")String query, HttpServletResponse response,@RequestParam(value = "chat-id", defaultValue = "1") String chatId) {response.setCharacterEncoding("UTF-8");return dashScopeChatClient.prompt(query).advisors(a -> a.param(ChatMemory.CONVERSATION_ID, chatId)).stream().content();}
运行报错
原因:由于 MySQL 表的字符集不支持存储 Unicode 表情符号导致的。表情符号😊的 UTF-8 编码为F0 9F 98 8A(4 字节),超出了utf8字符集的 3 字节限制
不知道改了啥,又可以了,可能是这个,把数据库的字符集改了一下
-- 将chat_db数据库的字符集改为utf8mb4
ALTER DATABASE chat_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;