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);
    }
}

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

相关推荐
一切尽在,你来5 小时前
1.2 LangChain 1.2.7 版本核心特性与升级点
人工智能·langchain
LYFlied5 小时前
AI大时代下前端跨端解决方案的现状与演进路径
前端·人工智能
深蓝电商API5 小时前
图片验证码识别:pytesseract+opencv入门
人工智能·opencv·计算机视觉·pytesseract
.Katherine௰5 小时前
AI数字人模拟面试机器人
人工智能
光影少年5 小时前
AI 前端 / 高级前端
前端·人工智能·状态模式
zhangshuang-peta5 小时前
OpenCode vs Claude Code vs OpenAI Codex:AI编程助手全面对比
人工智能·ai agent·mcp·peta
Bruk.Liu5 小时前
(LangChain 实战14):基于 ChatMessageHistory 自定义实现对话记忆功能
人工智能·python·langchain·agent
代码改善世界5 小时前
CANN中的AI算子开发:ops-nn仓库深度解读
人工智能
大江东去浪淘尽千古风流人物5 小时前
【VLN】VLN(Vision-and-Language Navigation视觉语言导航)算法本质,范式难点及解决方向(1)
人工智能·python·算法
云飞云共享云桌面5 小时前
高性能图形工作站的资源如何共享给10个SolidWorks研发设计用
linux·运维·服务器·前端·网络·数据库·人工智能