前言

持续更新SpringAI

一、SpringAi

Spring AI 是一个用于 AI 工程的应用程序框架。 其目标是将 Spring 生态系统设计原则(如可移植性和模块化设计)应用于 AI 领域,并将使用 POJO 作为应用程序的构建块推广到 AI 领域。

二、SpringAi特性

在这里插入图片描述

三、引入依赖

3.1 SpringAi整合DeepSeek示例

需要Jdk17+
Spring AI 最低支持Spring Boot 3.4.x

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-model-openai</artifactId>
</dependency>

3.2 yml配置文件

spring:
  ai:
    openai:
      base-url: https://api.deepseek.com
      api-key: 自己在deepseek创建的api key
      chat:
        options:
          model: deepseek-chat 聊天模型,可以更换

3.3 配置类

@Configuration
public class AiConfiguration {
    @Bean
    public ChatClient chatClient(OpenAiChatModel model, ChatMemory chatMemory) {
        return ChatClient.builder(model)
                .defaultSystem("你是一个热心的、可爱的智能助手,你的名字叫小团团,用小团团的语气来实现对话")
                .defaultAdvisors(new SimpleLoggerAdvisor(),new MessageChatMemoryAdvisor(chatMemory)) //可以记录对话的输出日志
                .build();
    }
}

3.4 聊天代码示例

@Data
public class Dto {
    private String message;
    private String timestamp;
    private String type;
    private String id;
}

Controller

@RestController
@RequestMapping("/api")
@RequiredArgsConstructor
public class ChatController {
    private final ChatClient chatClient;
    @PostMapping(value = "/chat", produces = "text/event-stream;charset=utf-8")
    public Flux<String> chat(@RequestBody Dto dto) {
        return chatClient.prompt()
                .user(dto.getMessage()) //前端用户输入的文字,与大模型进行沟通
                .stream()//使用流式输出,可以配合前端 实现打字机效果
                .content();//得到大模型响应的内容
    }
}

3.5 实现回话记忆功能

在SpringAi中,有一个接口ChatMemory,默认实现类为InMemoryChatMemory,如果每次的id都相同,那么SpringAi会在内存中记录我们这个id对应的对话历史记录(可以将本次页面的唯一标识id传输过来),可以实现历史记忆功能和历史对话联动功能。

如果想把历史回话存储到redis或者其他方案存储,那么我们需要自定义一个类来实现ChatMemory接口,重写方法即可。

话不多说,上实现代码

import lombok.RequiredArgsConstructor;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;

import static org.springframework.ai.chat.client.advisor.AbstractChatMemoryAdvisor.CHAT_MEMORY_CONVERSATION_ID_KEY;

@RestController
@RequestMapping("/api")
@RequiredArgsConstructor
public class ChatController {
    private final ChatClient chatClient;
    @PostMapping(value = "/chat", produces = "text/event-stream;charset=utf-8")
    public Flux<String> chat(@RequestBody Dto dto) {
        return chatClient.prompt()
                .user(dto.getMessage())
                .advisors(advisorSpec -> advisorSpec.param(CHAT_MEMORY_CONVERSATION_ID_KEY,dto.getId()))//此处将id相同的数据都会存储到内存中
                .stream().content();
    }
}

实现效果

  1. 当我们第一次访问时,我们定义dto中的id为1,我们问AI知道我是谁吗?SpringAI默认的内存存储容器为空,所以联想不到我们是谁
    在这里插入图片描述

在这里插入图片描述
2. 当我们给AI进行对话后,透露我们的名字,我们来看一看容器大小
在这里插入图片描述
id为1的value中有一个list集合,一次访问对话,一次请求内容,一次响应内容,都会被记录到这个id为1下的list集合中存储一次对话会在list集合中存储两条记录
在这里插入图片描述
3. 我们再次询问AI知道我们是谁吗,我们来看看AI如何回答
在这里插入图片描述

在这里插入图片描述
4. 那么当我们把传入的id设置为2再尝试问一下AI知道我们是谁吗
在这里插入图片描述
在这里插入图片描述

debug发现id为2的容器中没有之前的历史记录存储,AI回答时就不能检索到id为1的历史回话数据
在这里插入图片描述


总结

Logo

助力广东及东莞地区开发者,代码托管、在线学习与竞赛、技术交流与分享、资源共享、职业发展,成为松山湖开发者首选的工作与学习平台

更多推荐