SpringAI框架搭建连续对话聊天

SpringAI框架实现连续对话聊天

  • 什么是SpringAI
  • 如何实现SpringAI的连续聊天。
    • 依赖jar包的选择
    • 配置文件
    • spring的自动配置
    • 实现聊天功能的WEB接口

什么是SpringAI

此处纯属我个人理解,从刚开始ChatGPT爆红网络,到现在各大AI模型百花齐放,AI在训练和使用上似乎一直是python的特权。现在spring终于放大招了,出了一个SpringAI框架,我们使用的Java语言也可以实现AI的使用了。并且SpringAI框架的出现,定义了一套标准接口,我们不用去学各个大模型厂商提供的SDK怎么用了,只需要学习SpringAI就可以适配所有已接入的大模型。
本次先记录下如何实现连续聊天(AI可以通过聊天记录的上下文,给出最合适的答案),MCP服务及客户端的实现、文转图的实现,我们随后就发布。有兴趣的同学可以订阅专栏或者关注我。

如何实现SpringAI的连续聊天。

本次的功能实现,用的是阿里的通义大模型,需要提前申请好大模型的密钥。密钥创建的传送门:https://bailian.console.aliyun.com/?tab=model#/api-key

依赖jar包的选择

spring boot的版本使用3.5.0以上,我使用的是3.5.5

<dependencyManagement>
  <dependencies>
    <dependency>
    <groupId>com.alibaba.cloud.ai</groupId>
    <artifactId>spring-ai-alibaba-bom</artifactId>
    <version>1.0.0.3</version>
    <type>pom</type>
    <scope>import</scope>
    </dependency>
    <dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-bom</artifactId>
    <version>1.0.1</version>
    <type>pom</type>
    <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>
<!-- 阿里云通义集成模块 -->
  <dependency>
  <groupId>com.alibaba.cloud.ai</groupId>
  <artifactId>spring-ai-alibaba-starter-dashscope</artifactId>
  </dependency>
  <!-- 提供web服务 -->
    <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>

配置文件

使用application.yml进行配置

server:
port: 8080
spring:
application:
name: chat-gpt
ai:
dashscope:
api-key: sk-xxxxxxxxxxxxxxxxxxxxxxxxx

spring的自动配置

SpringAI框架在对象创建、方法调用,大量用了链式调用去实现,一定得习惯这种方式。很多类是没有公共的构造方法的。

package com.zhangzz.ai.core.config;
import com.alibaba.cloud.ai.dashscope.chat.DashScopeChatModel;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.memory.MessageWindowChatMemory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* SpringAI配置类,用于配置ChatClient和ChatMemory。
*/
@Configuration
public class SpringAIConfig
{
/**
* 保存历史聊天记录的Bean对象,使用的是线程安全的Map保存,也可自己实现接口ChatMemory,持久化到数据库等。
* @return ChatMemory
*/
@Bean
public ChatMemory getChatMemory() {
return MessageWindowChatMemory.builder().maxMessages(100).build();
}
/**
* 将通义大模型接入ChatClient
* @param model 阿里通义模型
* @return ChatClient
*/
@Bean
public ChatClient getChatClient(DashScopeChatModel model) {
return ChatClient.builder(model).build();
}
}
  1. ChatMemory接口,该接口是用来记录与AI大模型每次的聊天记录的,便于AI大模型每次生成的内容是基于之前的聊天历史问的,不会出现答非所问的情况。Spring默认提供了一个实现类,基于线程安全的Map去做存储的。相当于存储在内存里,个人比较推荐重新实现ChatMemory接口,使用Mongdb去做存储,大数据量检索速度还快。
  2. ChatClient 接口,是文本生成的重要接口,我们的文本聊天基本上都是用这个接口实现的。

实现聊天功能的WEB接口

import com.alibaba.cloud.ai.dashscope.chat.DashScopeChatModel;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.model.ChatResponse;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
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;
import java.util.Map;
import java.util.Objects;
@RestController
@RequestMapping("/ai")
public class ChatController
{
@Autowired
private ChatClient chatClient;
@Autowired
private DashScopeChatModel model;
@Autowired
private ChatMemory chatMemory;
@PostMapping("/tongYiChat")
public Map<
String,Object> tongYiChat(@RequestParam(value="message")String message){
String tabId = "newTab1";
//例如此处用户新开的聊天窗口ID。以此ID作为标识,将每次的聊天记录保存
MessageChatMemoryAdvisor chatMemoryAdvisor = MessageChatMemoryAdvisor.builder(chatMemory).conversationId(tabId).build();
ChatResponse response = chatClient.
prompt(new Prompt(message)).//用户的提问信息
advisors(chatMemoryAdvisor).//聊天记录保存器,此处为保存聊天记录到内存中。
call().chatResponse();
return Map.of("result", Objects.requireNonNullElse(response, "error"));
}
/**
* 响应式输出,避免客户端等待时间太长
* @param message 用户输入的消息
* @return 聊天流
*/
@PostMapping("/chatStream")
public Flux<
String> chatStream(@RequestParam(value="message")String message){
return chatClient.prompt(new Prompt(message)).stream().content();
}

Controller的Advisor,类似于springAOP,会在调用AI大模型的前、后,或环绕通知里,做一些业务。例如下面实现的连续对话的MessageChatMemoryAdvisor ,会在发起AI大模型请求前,将历史聊天读取出来,一起发送给AI大模型。
如下图:
MessageChatMemoryAdvisor的before方法实现
启动服务,使用postman进行测试
1.接口“/tongYiChat”的结果
聊天接口测试
2.接口“/chatStream”的结果
此处若想实现响应式的流,还需要去前端实现,通过和后端建议长连接来进行持续输出(就和文言一心一样,AI的结果是一点一点输出的页面的,而不是一下子全部显示在页面,那样用户会等待的太久)
流式响应

posted on 2025-09-12 16:37  ljbguanli  阅读(31)  评论(0)    收藏  举报