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

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

相关推荐
fthux5 小时前
装闭 RenoPit 源码解析(07):装修闭坑知识库与AI Prompt构建
人工智能·ai·开源·github·open source·renopit
zyplayer-doc7 小时前
VuePress类静态文档站和动态知识库怎么选:两种技术路线的适用场景
javascript·人工智能·后端·安全·智能手机
KKKlucifer7 小时前
拨开接口黑盒迷雾:运营商第三方合作接口安全审计与准入管控落地实践
网络·人工智能·安全
梦梦代码精7 小时前
连锁品牌数字化:从门店扩张到用户资产运营的技术底座
大数据·人工智能·低代码·docker·开源·代码规范
咕噜咕噜啦啦7 小时前
vLLM框架
人工智能·qwen·vllm
启雀AI8 小时前
AI 驱动的视频课程自动摘要与知识点提取:ASR + LLM 流水线工程实践
人工智能·阿里云·华为云·音视频·培训saas平台
Mac的实验室8 小时前
2026年8月最新实操:谷歌Gmail邮箱手机号注册扫码发短信提示“无法验证”怎么办?(附100%成功绕过指南)
人工智能
MindUp8 小时前
AI辅助PPT生成工具的内容组织能力实测:8款产品的文档解析与排版效果对比
人工智能
寒草8 小时前
【寒草呈献】当巴菲特走进 AI 投研助手
人工智能·架构