Skip to content

记忆 (Memory) 管理

会话记忆

会话记忆用于存储当前会话的历史记录,使对话更加连贯:

基本会话记忆

java
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.model.chat.ChatLanguageModelWithMemory;

// 创建会话记忆
MessageWindowChatMemory chatMemory = MessageWindowChatMemory.builder()
        .maxMessages(10) // 最大消息数量
        .build();

// 创建模型
ChatLanguageModel chatModel = OpenAiChatModel.builder()
        .apiKey(System.getenv("OPENAI_API_KEY"))
        .build();

// 创建带记忆的模型
ChatLanguageModelWithMemory modelWithMemory = ChatLanguageModelWithMemory.builder()
        .chatLanguageModel(chatModel)
        .chatMemory(chatMemory)
        .build();

// 发送消息
String response1 = modelWithMemory.generate("你好,我叫张三");
System.out.println("响应1:" + response1);

// 发送后续消息(模型应该记住之前的对话)
String response2 = modelWithMemory.generate("我叫什么名字?");
System.out.println("响应2:" + response2);

高级会话记忆

java
// 高级会话记忆配置
MessageWindowChatMemory chatMemory = MessageWindowChatMemory.builder()
        .maxMessages(10)
        .id("session-1") // 会话 ID
        .build();

// 创建带记忆的模型
ChatLanguageModelWithMemory modelWithMemory = ChatLanguageModelWithMemory.builder()
        .chatLanguageModel(chatModel)
        .chatMemory(chatMemory)
        .build();

长期记忆

长期记忆用于存储和检索长期信息,超越单个会话的范围:

基本长期记忆

java
import dev.langchain4j.memory.chat.ChatMemory;
import dev.langchain4j.memory.chat.TokenWindowChatMemory;
import dev.langchain4j.model.chat.ChatLanguageModelWithMemory;

// 创建基于令牌的记忆
TokenWindowChatMemory tokenMemory = TokenWindowChatMemory.builder()
        .maxTokens(1000) // 最大令牌数
        .build();

// 创建带记忆的模型
ChatLanguageModelWithMemory modelWithMemory = ChatLanguageModelWithMemory.builder()
        .chatLanguageModel(chatModel)
        .chatMemory(tokenMemory)
        .build();

持久化记忆

java
import dev.langchain4j.memory.chat.PersistentChatMemory;
import dev.langchain4j.memory.chat.ChatMemory;

// 创建持久化记忆
ChatMemory persistentMemory = PersistentChatMemory.builder()
        .id("user-1")
        .storage(new FileSystemStorage("path/to/storage"))
        .build();

// 创建带持久化记忆的模型
ChatLanguageModelWithMemory modelWithMemory = ChatLanguageModelWithMemory.builder()
        .chatLanguageModel(chatModel)
        .chatMemory(persistentMemory)
        .build();

记忆类型与应用

消息窗口记忆

特点:存储最近的 N 条消息 适用场景:短期对话,需要保持上下文连续性

java
MessageWindowChatMemory chatMemory = MessageWindowChatMemory.builder()
        .maxMessages(10)
        .build();

令牌窗口记忆

特点:存储最近的 N 个令牌 适用场景:需要控制上下文长度的场景

java
TokenWindowChatMemory chatMemory = TokenWindowChatMemory.builder()
        .maxTokens(1000)
        .build();

摘要记忆

特点:存储对话摘要,节省空间 适用场景:长对话,需要保持关键信息

java
import dev.langchain4j.memory.chat.SummarizingChatMemory;

SummarizingChatMemory summarizingMemory = SummarizingChatMemory.builder()
        .chatLanguageModel(chatModel)
        .maxSummaryLength(500)
        .build();

组合记忆

特点:结合多种记忆策略 适用场景:复杂对话场景

java
import dev.langchain4j.memory.chat.CompositeChatMemory;

CompositeChatMemory compositeMemory = CompositeChatMemory.builder()
        .addChatMemory(MessageWindowChatMemory.builder().maxMessages(10).build())
        .addChatMemory(SummarizingChatMemory.builder()
                .chatLanguageModel(chatModel)
                .maxSummaryLength(500)
                .build())
        .build();

自定义记忆

您可以通过实现 ChatMemory 接口来创建自定义记忆:

基本自定义记忆

java
import dev.langchain4j.memory.chat.ChatMemory;
import dev.langchain4j.data.message.Message;
import dev.langchain4j.data.message.AiMessage;
import dev.langchain4j.data.message.UserMessage;

public class CustomChatMemory implements ChatMemory {
    private final List<Message> messages = new ArrayList<>();
    private final int maxMessages;
    
    public CustomChatMemory(int maxMessages) {
        this.maxMessages = maxMessages;
    }
    
    @Override
    public void add(UserMessage userMessage, AiMessage aiMessage) {
        // 添加消息
        messages.add(userMessage);
        messages.add(aiMessage);
        
        // 保持消息数量在限制范围内
        while (messages.size() > maxMessages * 2) {
            messages.remove(0);
            messages.remove(0);
        }
    }
    
    @Override
    public List<Message> messages() {
        return new ArrayList<>(messages);
    }
    
    @Override
    public void clear() {
        messages.clear();
    }
}

高级自定义记忆

java
public class EnhancedChatMemory implements ChatMemory {
    private final List<Message> messages = new ArrayList<>();
    private final int maxMessages;
    private final String userId;
    private final Storage storage;
    
    public EnhancedChatMemory(int maxMessages, String userId, Storage storage) {
        this.maxMessages = maxMessages;
        this.userId = userId;
        this.storage = storage;
        // 从存储加载历史消息
        loadMessages();
    }
    
    @Override
    public void add(UserMessage userMessage, AiMessage aiMessage) {
        messages.add(userMessage);
        messages.add(aiMessage);
        
        // 保持消息数量在限制范围内
        while (messages.size() > maxMessages * 2) {
            messages.remove(0);
            messages.remove(0);
        }
        
        // 持久化消息
        saveMessages();
    }
    
    @Override
    public List<Message> messages() {
        return new ArrayList<>(messages);
    }
    
    @Override
    public void clear() {
        messages.clear();
        saveMessages();
    }
    
    private void loadMessages() {
        // 从存储加载消息
    }
    
    private void saveMessages() {
        // 保存消息到存储
    }
}

记忆管理最佳实践

会话管理

java
// 为每个用户创建独立的记忆
Map<String, ChatMemory> userMemories = new HashMap<>();

// 获取或创建用户记忆
ChatMemory getOrCreateMemory(String userId) {
    return userMemories.computeIfAbsent(userId, id -> 
        MessageWindowChatMemory.builder()
            .maxMessages(10)
            .id(id)
            .build()
    );
}

// 使用用户记忆
String userId = "user-123";
ChatMemory userMemory = getOrCreateMemory(userId);

ChatLanguageModelWithMemory modelWithMemory = ChatLanguageModelWithMemory.builder()
        .chatLanguageModel(chatModel)
        .chatMemory(userMemory)
        .build();

记忆优化

java
// 定期清理过期记忆
void cleanupMemories() {
    long cutoffTime = System.currentTimeMillis() - 24 * 60 * 60 * 1000; // 24小时
    userMemories.entrySet().removeIf(entry -> {
        // 检查记忆是否过期
        return isMemoryExpired(entry.getValue(), cutoffTime);
    });
}

// 优化记忆大小
void optimizeMemory(ChatMemory memory) {
    if (memory instanceof MessageWindowChatMemory) {
        // 调整消息窗口大小
    }
}

最佳实践

  1. 选择合适的记忆类型

    • 根据对话长度选择记忆类型
    • 考虑内存使用和性能
    • 平衡上下文连续性和资源消耗
  2. 合理配置记忆参数

    • 设置适当的消息数量或令牌限制
    • 考虑模型的上下文窗口大小
    • 避免记忆过大导致性能下降
  3. 持久化记忆

    • 对于需要长期保存的对话,使用持久化记忆
    • 定期备份记忆数据
    • 实现记忆的导入导出功能
  4. 记忆管理

    • 为每个用户创建独立的记忆
    • 定期清理过期记忆
    • 监控记忆使用情况
  5. 错误处理

    • 处理记忆加载和保存错误
    • 实现记忆恢复机制
    • 防止记忆损坏
  6. 安全性

    • 保护用户记忆数据
    • 实现访问控制
    • 加密敏感信息
  7. 性能优化

    • 缓存频繁访问的记忆
    • 使用异步操作处理记忆
    • 优化记忆存储结构