請看文檔,流程不再贅述:官網及其示例
簡易聊天
環境變量
引入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;