06-05 LangChain4J中实现持久化记忆
✅LangChain4J中实现持久化记忆
我们之前也介绍过LangChain4j中的记忆,但是也是介绍的基于内存短期记忆,利用LangChain4j也能做持久化的记忆,但是官方没给现成的实现,只能靠我们自己实现。
在LangChain4j中,有一个内置的ChatMemoryStore接口,可以用它来扩展实现内存记忆。
这个接口中定义了删、改、查等接口:
1 | public interface ChatMemoryStore { |
有了它之后,就可以自己扩展,使用MySQL或者Redis等其他数据库来做保存了。如:
1 |
|
使用方法同样是构造一个MessageWindowChatMemory,把这个RedisChatMemoryStore设置进去就行了。和Spring AI差不多。(应该是Spring AI参考了LangChain4j,只不过自己做了些实现的扩展,更好用了)
1 | langChainMemoryAiService = AiServices.builder(LangChainMemoryAiService.class) |
总的来说,就是LangChain4j 通过三层抽象实现多轮对话记忆:
1 | ┌───────────────────────────────────────────────────────┐│ AiServices ││ (代理层:自动管理消息的 add / messages 生命周期) │└────────────────────────┬──────────────────────────────┘ │ 使用┌────────────────────────▼──────────────────────────────┐│ ChatMemory (接口) ││ 实现类:MessageWindowChatMemory ││ 职责:控制记忆窗口大小、消息淘汰策略 ││ 核心方法:add(message) / messages() │└────────────────────────┬──────────────────────────────┘ │ 委托持久化┌────────────────────────▼──────────────────────────────┐│ ChatMemoryStore (接口) ││ 职责:消息的存储和读取(持久化层) ││ 核心方法:getMessages() / updateMessages() │└───────────────────────────────────────────────────────┘ |
LangChain4j 的 AiServices 在每次 LLM 调用时,内部执行以下流程:
1 | // 伪代码:AiServices 内部对 ChatMemory 的操作List<ChatMessage> history = chatMemoryStore.getMessages(memoryId); // 1. 加载历史history.add(systemMessage); // 2. 加入 SystemMessagehistory.add(userMessage); // 3. 加入当前用户消息chatMemoryStore.updateMessages(memoryId, history); // 4. 持久化(含新用户消息) |
这意味着 ChatMemoryStore 的实现必须保证:
getMessages() 返回的列表在同一次调用内可变且一致
updateMessages() 需要真正保存状态,否则下一次请求会丢失历史
通过 chatMemoryProvider 可以实现多会话隔离:
1 | .chatMemoryProvider(memoryId -> MessageWindowChatMemory.builder() .id(memoryId) // memoryId = conversationId .maxMessages(10) // 滑动窗口:最多保留10条 .chatMemoryStore(databaseChatMemoryStore) // 持久化委托 .build()) |
配合 AiService 接口上的 @MemoryId 注解:
1 |
|
LangChain4j 会自动将 conversationId 作为 memoryId 传递给 ChatMemoryStore,实现每个会话独立记忆。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Southblock'Blog!
