SpringAi-memory

1.基于memory对话记忆

SpringAI 基于 ChatMemory 实现对话的记忆,也就是上下⽂内容的存储、发送请求时候附带。 ChatMemory 表示聊天对话记忆的存储,它提供添加消息到对话、从对话中检索消息以及清除对话历 史的⽅法。

java 复制代码
public interface ChatMemory {
    default void add(String conversationId, Message message) {
        this.add(conversationId, List.of(message));
   }
 // 添加消息到记忆
    void add(String conversationId, List<Message> messages);
 // 获取对话历史
    List<Message> get(String conversationId, int lastN);
 // 清除对话记忆
    void clear(String conversationId);
}

Spring AI 提供了 ChatMemory 的实例⽤于存储聊天上下⽂,默认使⽤内存的⽅式进⾏实现,将对 话直接存储在内存中。

2.什么是会话 ID

SpringAI 中, conversationId 是⽤于标识和隔离不同对话会话的核⼼参数,通过该 ID 实现对 话上下⽂的持久化与连续性管理。它有如下的⼀些核⼼作⽤:

  • 会话隔离:为每个对话分配唯⼀ ID ,确保不同会话的数据独⽴存储和读取。
  • 上下⽂持久化:通过 ChatMemoryRepository 接⼝,将过滤后的消息(如⽤户输⼊、 AI 回 复)按 conversationId 存储,⽀持本地内存或 JDBC 数据库等存储⽅式。

3.具体实现(基于内存)

3.1. 书写 ChatMemoryConfig 配置类

java 复制代码
@Configuration
public class ChatMemoryConfig {
    @Bean("inMemoryChatMemory")
    public ChatMemory chatMemory() {
        return MessageWindowChatMemory.builder()
               .chatMemoryRepository(new 
InMemoryChatMemoryRepository()) // 对话记忆默认使⽤内存⽅式
               .maxMessages(3) // 保存最近的三条历史记录
               .build();
   }
}

注意: 其实内存⽅式就是默认的⽅式,如果不⾃定义 ChatMemory 对象,默认的 ChatMemory 对象已经实现了内存记忆功能。 保存的历史记录⾄少三条,因为会保存多个⻆⾊信息。

3.2修改ChatClientConfig控制类

java 复制代码
@Bean("openAiChatClient")
    public ChatClient openAiChatClient(OpenAiChatModel openAiChatModel){
        return ChatClient.builder(openAiChatModel).build();
    } 
@Bean("openAiChatClient2")
    public ChatClient openAiChatClient2(OpenAiChatModel openAiChatModel){
        return ChatClient.builder(openAiChatModel)
                //引入chatMemory in
                .defaultAdvisors(MessageChatMemoryAdvisor.builder(inMemoryChatMemory).build())
                .build();
    }

3.3控制层类

分别为入门版、提升版以及手撕版

java 复制代码
//入门版写法
    @GetMapping(value = "/stream",produces = "text/html;charset=utf-8")
    public Flux<String> stream(@RequestParam("question") String question){
        history+=question+"/n";
        return openAiChatClient.prompt()
                .user(history)
                .stream().content();
    }
    //提升版
    @GetMapping(value = "/history1",produces = "text/html;charset=utf-8")
    public Flux<String> history1(@RequestParam("question") String question){
        return openAiChatClient2.prompt()
                .user(question)
                .stream().content();
    }
    //手撕版
    @GetMapping(value = "/history2",produces = "text/html;charset=utf-8")
    public String history2(@RequestParam("question") String question,@RequestParam("id") String id){
        //1.获取到原来的消息
        List<Message> historyMessages=chatMemory.get(id);
        log.info("历史记录:{}",historyMessages);
        if (historyMessages==null || historyMessages.size()==0){
            historyMessages =new ArrayList<>();
        }
        //2.将当用户的消息组装后存放到历史中
        Message userMessage=new UserMessage(question);
        historyMessages.add(userMessage);
        chatMemory.add(id,historyMessages);
        //3.获取到大模型的回答
        Prompt prompt=new Prompt(historyMessages);
        String result=openAiChatClient.prompt(prompt).call().content();
        Message assistantMessage = new AssistantMessage(result);
        //4.将大模型回答的消息存放到历史记录中
        historyMessages.add(assistantMessage);
        chatMemory.add(id,historyMessages);
        //5.返回结果
        return result;
    }

4.基于JDBC实现

4.1引入依赖

XML 复制代码
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-starter-model-chat-memory-repository-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
        </dependency>

4.2修改yml文件

XML 复制代码
spring:
    ai:
       chat:
          memory:
            repository:
              jdbc:
                initialize-schema: always(第二次运行需修改为never)
                schema: classpath:schema-mysql.sql
  datasource:
    password: 123456
    username: root
    url: jdbc:mysql://localhost:3306/sys
    driver-class-name: com.mysql.cj.jdbc.Driver

4.3在resources目录下新建schema-mysql.sql

sql 复制代码
CREATE TABLE IF NOT EXISTS SPRING_AI_CHAT_MEMORY
(
    conversation_id VARCHAR(36) NOT NULL,
    content         TEXT        NOT NULL,
    type            VARCHAR(10) NOT NULL,
    `timestamp`     TIMESTAMP   NOT NULL,
    CONSTRAINT TYPE_CHECK CHECK (type IN ('USER', 'ASSISTANT', 'SYSTEM', 'TOOL'))
    );

会在yml文件所写的数据库中新建SPRING_AI_CHAT_MEMORY表,会将对话记录存到该表中

4.4写ChatMemoryConfig类

java 复制代码
@Bean("jdbcMemoryChatMemory")
    public ChatMemory jdbcChatMemory(JdbcChatMemoryRepository jdbcChatMemoryRepository) {
        return MessageWindowChatMemory.builder()
                .chatMemoryRepository(jdbcChatMemoryRepository)
                .build();
    }

4.5写ChatClientConfig类

java 复制代码
@Bean("openAiChatClient3")
    public ChatClient openAiChatClient3(OpenAiChatModel openAiChatModel) {
        return ChatClient.builder(openAiChatModel)
                // 引入chatMemory  jdbc
                .defaultAdvisors(MessageChatMemoryAdvisor.builder(jdbcMemoryChatMemory).build())
                .build();
    }

4.6写controller类

java 复制代码
@GetMapping(value = "/history3", produces = "text/html;charset=utf-8")
    public Flux<String> history3(@RequestParam("question") String question, @RequestParam("id") String id) {
        return openAiChatClient3.prompt()
                .advisors(a -> a.param("chat_memory_conversation_id", id))
                .user(question)
                .stream().content();
    }

4.7编写启动类

java 复制代码
package com.jiazhong.mingxing.ai.siliconflow.memory.glm;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class AiSiliconflowMemoryGlmApplication {
    public static void main(String[] args) {
        SpringApplication.run(AiSiliconflowMemoryGlmApplication.class);
    }
}

启动后在浏览器中写入具体路径即可实现。

相关推荐
乐橙开放平台2 分钟前
离岗检测怎么实现?通过客流相机或 AI 摄像头识别岗位区域无人状态,再推送告警消息
人工智能·笔记·后端·数码相机·物联网·自动化·音视频
2301_776045233 分钟前
山寨币与比特币之间的关系
大数据·人工智能·区块链
ahccqw2 小时前
OpenCV 缩放 与 位移
人工智能·opencv·计算机视觉
长不大的杨瑞杰2 小时前
OpenCode v2 GitLab 集成实战:Issue 驱动开发、MR 审查与 CI/CD 最小权限
人工智能·ci/cd·gitlab·ai编程·opencode
深蓝AI3 小时前
美团 LongCat-2.5 拆解:1.6T 参数只激活 3%,1M 上下文卖 0.3 美元,Agent 模型的账变了
人工智能·llm
小和尚同志7 小时前
54.6k star 的 Multica: 集多 Agent 和看板于一体的 AI 平台
人工智能·aigc·three.js
一枕槐安4878 小时前
少样本提示(Few-shot)在业务场景的落地实践
大数据·人工智能·意图分类·mmr多样性·knn检索·动态示例选择
王中阳Go9 小时前
后端转 Agent 岗面试怎么答:8 个高频问题与应答口径
人工智能·后端·python·大语言模型
海宇AI9 小时前
零信任架构实战:基于海宇个人风险报告构建自动化分期商城信用额度初审网关
运维·人工智能·架构·自动化
tellmewhoisi9 小时前
深度学习32:卷积神经网络:卷积层(卷积运算,填充,步幅)
人工智能·深度学习·cnn