
主要作用是用来管理和维护ChatMessage。负责对话消息的记忆与淘汰
额外功能:
注意:LangChain4j 目前只提供“记忆”,而不是“历史记录”。如果需要保留整个历史记录,需要开发者自行处理。
使用示例:
@AiService
interface Assistant {
@SystemMessage("You are a polite assistant")
String chat(String userMessage);
}
public void chatMeme() {
ChatMemory chatMemory = MessageWindowChatMemory.withMaxMessages(10);
Assistant assistant = AiServices.builder(Assistant.class)
.chatModel(qwenChatModel)
.chatMemory(chatMemory)
.build();
String answer = assistant.chat("Hello! My name is Klaus.");
System.out.println(answer); // Hello Klaus! How can I assist you today?
String answerWithName = assistant.chat("What is my name?");
System.out.println(answerWithName); // Your name is Klaus.
}通过memoryId隔离会话:
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import dev.langchain4j.model.chat.ChatModel;
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.service.AiServices;
import dev.langchain4j.service.MemoryId;
import dev.langchain4j.service.UserMessage;
import static dev.langchain4j.model.openai.OpenAiChatModelName.GPT_4_O_MINI;
public class ServiceWithMemoryForEachUserExample {
/**
* See also {@link ServiceWithPersistentMemoryForEachUserExample}.
*/
interface Assistant {
String chat(@MemoryId int memoryId, @UserMessage String userMessage);
}
public static void main(String[] args) {
ChatModel model = OpenAiChatModel.builder()
.apiKey(ApiKeys.OPENAI_API_KEY)
.modelName(GPT_4_O_MINI)
.build();
Assistant assistant = AiServices.builder(Assistant.class)
.chatModel(model)
.chatMemoryProvider(memoryId -> MessageWindowChatMemory.withMaxMessages(10))
.build();
System.out.println(assistant.chat(1, "Hello, my name is Klaus"));
// Hi Klaus! How can I assist you today?
System.out.println(assistant.chat(2, "Hello, my name is Francine"));
// Hello Francine! How can I assist you today?
System.out.println(assistant.chat(1, "What is my name?"));
// Your name is Klaus.
System.out.println(assistant.chat(2, "What is my name?"));
// Your name is Francine.
}
}为了适应 LLM 的上下文窗口。LLM 一次可以处理的token数量是有限的。在某个时刻,对话可能会超过这个限制。在这种情况下,应该驱逐一些消息。通常,最旧的消息会被驱逐,但如果需要,可以实施更复杂的算法。
同时,驱逐旧的消息,可以节约token成本,提供响应效率。
目前,LangChain4j 提供了 2 种开箱即用的实现:
N 条消息,并淘汰不再适合的旧消息N个token,并在需要时淘汰旧消息。注意按token来淘汰可能会导致语义不完整,消息是不可分割的。如果消息不合适,它将被完全淘汰。 所以TokenWindowChatMemory 需要一个 TokenCountEstimator 来计算每个 ChatMessage 中的token数量。Persistence 持久化默认情况下, ChatMemory 实现将 ChatMessage 存储在内存中(服务重启数据丢失)。
如果需要持久化,可以实现一个自定义的 ChatMemoryStore 来将 ChatMessage 存储在任何持久存储中:使用示例:
class PersistentChatMemoryStore implements ChatMemoryStore {
@Override
public List<ChatMessage> getMessages(Object memoryId) {
// TODO: Implement getting all messages from the persistent store by memory ID.
// ChatMessageDeserializer.messageFromJson(String) and
// ChatMessageDeserializer.messagesFromJson(String) helper methods can be used to
// easily deserialize chat messages from JSON.
}
@Override
public void updateMessages(Object memoryId, List<ChatMessage> messages) {
// TODO: Implement updating all messages in the persistent store by memory ID.
// ChatMessageSerializer.messageToJson(ChatMessage) and
// ChatMessageSerializer.messagesToJson(List<ChatMessage>) helper methods can be used to
// easily serialize chat messages into JSON.
}
@Override
public void deleteMessages(Object memoryId) {
// TODO: Implement deleting all messages in the persistent store by memory ID.
}
}
ChatMemory chatMemory = MessageWindowChatMemory.builder()
.id("12345")
.maxMessages(10)
.chatMemoryStore(new PersistentChatMemoryStore())
.build();updateMessages() 方法在每次向 ChatMemory 添加新的 ChatMessage 时都会被调用。这通常在每次与 LLM 的交互中发生两次:一次是在添加新的 UserMessage 时,另一次是在添加新的 AiMessage 时。预期 updateMessages() 方法会更新与给定内存 ID 相关的所有消息。 ChatMessage 可以分别存储(例如,每条消息一个记录/行/对象)或一起存储(例如,整个 ChatMemory 一个记录/行/对象)。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。