对话记忆功能是一种技术,使得应用程序或智能助手能够在一段时间内“记住”用户提供的信息,以便在后续对话中参考和使用。这种记忆可以让对话更加连贯,并使助手能够理解用户的背景和偏好,从而提供更加个性化和精准的回复。
对话记忆功能的用途
- 用户信息的持久化:记录用户提供的背景信息或个人偏好。
- 上下文跟踪:在多轮对话中保持上下文一致性。
- 更好地回答追问:在复杂的多轮对话中,当用户询问更详细的问题或追问之前提到的内容时,记忆功能使助手能更好地理解用户的意图。
Spring AI 记忆功能
-
ChatMemory
ChatMemory作为一个内存管理容器,存储和管理多轮对话中的ChatMessage。它不仅允许开发者保存消息,还提供了消息驱逐策略(Eviction Policy)、持久化存储(Persistence)以及特殊消息处理(如SystemMessage和ToolExecutionMessage)等功能。此外,ChatMemory还与high-level组件(如AI服务)集成,便于开发者更方便地管理对话历史。
在Spring AI中,ChatMemory接口定义了用于存储和检索聊天对话历史记录的方法。以下是ChatMemory接口的主要方法:add(String conversationId, Message message)
:将单个消息添加到指定会话的对话中。add(String conversationId, List<Message> messages)
:将消息列表添加到指定会话的对话中。get(String conversationId, int lastN)
:从指定会话的对话中检索最新的N条消息。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应用
- PromptChatMemoryAdvisor
PromptChatMemoryAdvisor是Spring AI框架中的一个组件,它实现了Advisor接口,并提供了特定的逻辑来处理聊天记忆中的消息。当使用Spring AI与LLM进行交互时,PromptChatMemoryAdvisor可以自动地将与当前会话相关的历史消息添加到提示中,从而增强LLM对上下文的理解。
原理: - 检索历史消息:PromptChatMemoryAdvisor会从配置的ChatMemory(如InMemoryChatMemory)中检索与当前会话相关的历史消息。
- 构建提示:检索到的历史消息会被添加到提示的系统文本中。系统文本通常用于指定LLM的角色或提供额外的上下文信息。
- 发送提示:增强后的提示会被发送到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);
- VectorStoreChatMemoryAdvisor
VectorStoreChatMemoryAdvisor 是 Spring AI 框架中的一个组件,它结合了向量存储(VectorStore)技术来增强聊天机器人的记忆能力。这个 Advisor 利用向量数据库存储用户与聊天机器人的交互历史,包括用户提出的问题和模型的回答。在生成新的回复时,VectorStoreChatMemoryAdvisor 会检索与当前问题相关的历史记录,并将其作为上下文信息添加到提示中,从而帮助大型语言模型(LLM)生成更连贯和准确的回复。
原理:
- 存储交互历史:当用户与聊天机器人进行交互时,VectorStoreChatMemoryAdvisor 会将每次交互的信息(包括用户问题和模型回答)存储到向量数据库中。这些信息会被转换为向量表示,以便进行高效的检索和匹配。
- 检索相关历史:当用户提出新的问题时,VectorStoreChatMemoryAdvisor 会在向量数据库中检索与当前问题相关的历史记录。这通常是通过计算当前问题与历史记录之间的向量相似度来实现的。
- 增强提示信息:检索到的相关历史记录会被添加到提示的系统文本中,从而增强大型语言模型对上下文的理解。这有助于模型生成更连贯和准确的回复。
- 发送提示并接收回复:增强后的提示会被发送到大型语言模型,模型基于这个提示生成回复。回复随后会通过 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);