Spring AI 对话记忆

devtools/2025/1/17 13:42:24/

对话记忆功能是一种技术,使得应用程序或智能助手能够在一段时间内“记住”用户提供的信息,以便在后续对话中参考和使用。这种记忆可以让对话更加连贯,并使助手能够理解用户的背景和偏好,从而提供更加个性化和精准的回复。

对话记忆功能的用途

  1. 用户信息的持久化:记录用户提供的背景信息或个人偏好。
  2. 上下文跟踪:在多轮对话中保持上下文一致性。
  3. 更好地回答追问:在复杂的多轮对话中,当用户询问更详细的问题或追问之前提到的内容时,记忆功能使助手能更好地理解用户的意图。

Spring AI 记忆功能

  1. ChatMemory
    ChatMemory作为一个内存管理容器,存储和管理多轮对话中的ChatMessage。它不仅允许开发者保存消息,还提供了消息驱逐策略(Eviction Policy)、持久化存储(Persistence)以及特殊消息处理(如SystemMessage和ToolExecutionMessage)等功能。此外,ChatMemory还与high-level组件(如AI服务)集成,便于开发者更方便地管理对话历史。
    在Spring AI中,ChatMemory接口定义了用于存储和检索聊天对话历史记录的方法。以下是ChatMemory接口的主要方法:

    1. add(String conversationId, Message message):将单个消息添加到指定会话的对话中。
    2. add(String conversationId, List<Message> messages):将消息列表添加到指定会话的对话中。
    3. get(String conversationId, int lastN):从指定会话的对话中检索最新的N条消息。
    4. clear(String conversationId):清除指定会话的对话历史记录。
public interface ChatMemory {// TODO: consider a non-blocking interface for streaming usagesdefault 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);
}

2、内存记忆InMemoryChatMemory
InMemoryChatMemory是Spring AI框架提供的一种ChatMemory实现,它将对话历史记录存储在内存中。这种实现方式具有快速访问和检索消息的优点,适用于快速原型开发和测试场景。由于内存是易失性存储介质,因此InMemoryChatMemory不适用于需要长期保存聊天记录的应用场景。

代码:

public class InMemoryChatMemory implements ChatMemory {Map<String, List<Message>> conversationHistory = new ConcurrentHashMap<>();@Overridepublic void add(String conversationId, List<Message> messages) {this.conversationHistory.putIfAbsent(conversationId, new ArrayList<>());this.conversationHistory.get(conversationId).addAll(messages);}@Overridepublic List<Message> get(String conversationId, int lastN) {List<Message> all = this.conversationHistory.get(conversationId);return all != null ? all.stream().skip(Math.max(0, all.size() - lastN)).toList() : List.of();}@Overridepublic void clear(String conversationId) {this.conversationHistory.remove(conversationId);}
}

样例:

import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.memory.InMemoryChatMemory;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.UserMessage;
import java.util.List;public class ChatMemoryExample {public static void main(String[] args) {// 创建InMemoryChatMemory实例ChatMemory chatMemory = new InMemoryChatMemory();// 创建用户消息Message userMessage1 = new UserMessage("Hello, how are you?");Message userMessage2 = new UserMessage("I'm fine, thank you. How about you?");// 将会话ID和消息添加到ChatMemory中String conversationId = "12345";chatMemory.add(conversationId, List.of(userMessage1));chatMemory.add(conversationId, List.of(userMessage2));// 检索最新的N条消息List<Message> messages = chatMemory.get(conversationId, 2);// 输出消息内容for (Message message : messages) {System.out.println(message.getContent());}}
}

Advisor应用

  1. PromptChatMemoryAdvisor
    PromptChatMemoryAdvisor是Spring AI框架中的一个组件,它实现了Advisor接口,并提供了特定的逻辑来处理聊天记忆中的消息。当使用Spring AI与LLM进行交互时,PromptChatMemoryAdvisor可以自动地将与当前会话相关的历史消息添加到提示中,从而增强LLM对上下文的理解。
    原理:
  2. 检索历史消息:PromptChatMemoryAdvisor会从配置的ChatMemory(如InMemoryChatMemory)中检索与当前会话相关的历史消息。
  3. 构建提示:检索到的历史消息会被添加到提示的系统文本中。系统文本通常用于指定LLM的角色或提供额外的上下文信息。
  4. 发送提示:增强后的提示会被发送到LLM,LLM基于这个提示生成回复。

应用:
在Spring AI应用中,开发者可以通过以下步骤使用PromptChatMemoryAdvisor:

1. **配置ChatMemory**:首先,需要配置一个ChatMemory实现来存储和管理对话历史记录。
2. **创建PromptChatMemoryAdvisor实例**:然后,创建一个PromptChatMemoryAdvisor实例,并将其与配置的ChatMemory关联起来。
3. **注册Advisor**:将PromptChatMemoryAdvisor实例注册到Spring AI的Advisor链中。这通常是在构建ChatClient时通过调用defaultAdvisors或advisors方法完成的。
4. **发送提示并接收回复**:在发送提示到LLM之前,PromptChatMemoryAdvisor会自动地将历史消息添加到提示中。然后,可以像平常一样发送提示并接收LLM的回复。

示例:

// 假设已经有一个配置好的ChatMemory实例chatMemory
PromptChatMemoryAdvisor promptChatMemoryAdvisor = new PromptChatMemoryAdvisor(chatMemory);
// 创建ChatClient并注册PromptChatMemoryAdvisor
ChatClient chatClient = ChatClient.builder(chatModel).defaultAdvisors(promptChatMemoryAdvisor).build();
// 发送提示并接收回复
String userText = "What did we talk about last time?";
String response = chatClient.prompt().user(userText).call().content();
// 输出回复内容
System.out.println(response);
  1. VectorStoreChatMemoryAdvisor

VectorStoreChatMemoryAdvisor 是 Spring AI 框架中的一个组件,它结合了向量存储(VectorStore)技术来增强聊天机器人的记忆能力。这个 Advisor 利用向量数据库存储用户与聊天机器人的交互历史,包括用户提出的问题和模型的回答。在生成新的回复时,VectorStoreChatMemoryAdvisor 会检索与当前问题相关的历史记录,并将其作为上下文信息添加到提示中,从而帮助大型语言模型(LLM)生成更连贯和准确的回复。

原理:

  1. 存储交互历史:当用户与聊天机器人进行交互时,VectorStoreChatMemoryAdvisor 会将每次交互的信息(包括用户问题和模型回答)存储到向量数据库中。这些信息会被转换为向量表示,以便进行高效的检索和匹配。
  2. 检索相关历史:当用户提出新的问题时,VectorStoreChatMemoryAdvisor 会在向量数据库中检索与当前问题相关的历史记录。这通常是通过计算当前问题与历史记录之间的向量相似度来实现的。
  3. 增强提示信息:检索到的相关历史记录会被添加到提示的系统文本中,从而增强大型语言模型对上下文的理解。这有助于模型生成更连贯和准确的回复。
  4. 发送提示并接收回复:增强后的提示会被发送到大型语言模型,模型基于这个提示生成回复。回复随后会通过 VectorStoreChatMemoryAdvisor 和其他可能的 Advisor 链传递,最终返回给用户。

配置和使用
在 Spring AI 应用中,配置和使用 VectorStoreChatMemoryAdvisor 通常涉及以下步骤:
5. 设置向量数据库:首先需要配置一个向量数据库来存储交互历史。Spring AI 框架支持多种向量数据库实现,如 AzureVectorStore、ChromaVectorStore、PgVectorStore 等。
6. 创建 VectorStoreChatMemoryAdvisor 实例:使用配置好的向量数据库创建一个 VectorStoreChatMemoryAdvisor 实例。
7. 注册 Advisor:将 VectorStoreChatMemoryAdvisor 实例注册到 Spring AI 的 Advisor 链中。这通常是在构建 ChatClient 时通过调用 defaultAdvisors 或 advisors 方法完成的。
8. 发送提示并接收回复:在发送提示到大型语言模型之前,VectorStoreChatMemoryAdvisor 会自动检索并增强提示信息。然后,可以像平常一样发送提示并接收回复。

示例:

// 假设已经有一个配置好的 VectorStore 实例 vectorStore
VectorStoreChatMemoryAdvisor vectorStoreChatMemoryAdvisor = new VectorStoreChatMemoryAdvisor(vectorStore);// 将 VectorStoreChatMemoryAdvisor 注册到 ChatClient 中
chatClient.registerAdvisor(vectorStoreChatMemoryAdvisor);// 发送提示并接收回复(示例代码,具体实现可能因框架版本和配置而异)
String userText = "What did we discuss last time about this topic?";
String response = chatClient.prompt(userText).call().getContent();
System.out.println(response);

http://www.ppmy.cn/devtools/151285.html

相关文章

springboot基于Java的任务管理系统

Springboot基于Java的任务管理系统是一种高效、灵活且易于维护的项目管理工具&#xff0c;它结合了Springboot框架的强大功能和Java语言的稳定性与安全性。 一、系统概述 任务管理系统是一种用于跟踪和管理项目中各种任务和工作的应用程序&#xff0c;它可以帮助团队成员更好…

android T 建立文件夹及文件的记录

第一&#xff1a;AndroidManifest.xml 中整体给予apk权限&#xff0c;如此加入后&#xff0c;在android的settings中&#xff0c;可以找到app.手动给予静态的权限&#xff0c;但是app不一定能使用&#xff0c;请大神指导为什么&#xff1f; <uses-permission android:name&q…

抖音ip属地没有手机卡会显示吗

在数字时代&#xff0c;社交媒体平台如抖音已成为人们日常生活的重要组成部分。随着抖音等应用对用户体验和隐私保护的不断优化&#xff0c;IP属地显示功能逐渐走进大众视野。这一功能旨在提高网络环境的透明度&#xff0c;打击虚假信息和恶意行为。然而&#xff0c;对于没有手…

学员答疑:安卓分屏窗口的TouchableRegion设置流程追踪

背景&#xff1a; vip学员在群里问到了一个分屏触摸区域设置的问题&#xff0c;开始以为就是和普通Activity设置区域没啥差别,都是在InputMonitor中进行的设置&#xff0c;但是仔细研究下来其实并不是哈。本文就带大家来手把手分析一下分屏情况下的触摸区域是怎么设置的。 d…

数据仓库的复用性:模型层面通用指标体系、参数化模型、版本化管理

在数据仓库设计中&#xff0c;复用性 是一个关键原则&#xff0c;它不仅能提升数据资产的使用效率&#xff0c;还能降低开发成本、优化系统运维。下面将从 模型层面的复用性、通用指标体系、参数化模型、版本化管理 四个方面进行详细介绍&#xff0c;并提供可落地的设计方案。 …

算法竞赛(蓝桥杯)贪心算法1——数塔问题

题目描述 有如下所示的数塔&#xff0c;要求从底层走到顶层&#xff0c;若每一步只能走到相邻的结点&#xff0c;则经过的结点的数字之和最大是多少&#xff1f; 输入 输入数据首先包括一个整数整数 N (1≤N≤100)&#xff0c;表示数塔的高度&#xff0c;接下来用 N 行数字表示…

【Linux探索学习】第二十六弹——进程通信:深入理解Linux中的进程通信

Linux探索学习&#xff1a; https://blog.csdn.net/2301_80220607/category_12805278.html?spm1001.2014.3001.5482 前言&#xff1a; 在Linux操作系统中&#xff0c;进程通信&#xff08;IPC&#xff09;是操作系统的一项核心功能&#xff0c;用于在不同进程之间交换数据或…

(01)STM32—GPIO

1. GPIO简介 GPIO&#xff08;General Purpose Input Output&#xff09;通用输入输出端口。可配置为8种输入输出模式。引脚电平&#xff1a;0V~3.3V&#xff0c;部分引脚可容忍5V。输出模式下可控制端口输出高低电平&#xff0c;用以驱动LED、控制蜂鸣器、模拟通信协议输出时…