Skip to main content
版权归属于 LangChat Team
官网:https://langchat.cn

06 - ChatMemory 对话记忆管理

版本说明

本文档基于 LangChain4j 1.10.0 版本编写。

学习目标

通过本章节学习,你将能够:
  • 理解为什么需要 ChatMemory
  • 掌握 MessageWindowChatMemory 的使用
  • 了解 TokenWindowChatMemory 的区别
  • 学会管理多用户场景的对话记忆
  • 理解 ChatMemoryProvider 的作用
  • 实现对话记忆的持久化存储

前置知识

  • 完成《01 - LangChain4j 简介》章节
  • 完成《02 - 你的第一个 Chat 应用》章节
  • 完成《03 - 深入理解 ChatModel》章节
  • 完成《04 - 模型参数配置》章节
  • 完成《05 - ChatMessage 类型详解》章节

核心概念

为什么需要 ChatMemory?

问题: LLM(大语言模型)本身是无状态的,它不会”记住”之前的对话内容。 示例:
原因:
  • LLM 每次请求都是独立的
  • 没有内置的机制在多个请求之间共享状态
  • 这就是为什么多轮对话需要手动传递历史
解决方案: ChatMemory 是 LangChain4j 提供的机制,用于管理对话历史,使 LLM 能够”记住”之前的对话。 类比理解: 如果把 LLM 比作一个健忘的人,那么 ChatMemory 就像是他的笔记本,记录了他说过的所有话。

ChatMemory 接口

ChatMemory 实现类型

LangChain4j 提供了多种 ChatMemory 实现:

MessageWindowChatMemory

基本用法

MessageWindowChatMemory 保留最近固定数量的消息,超过限制时会自动删除最旧的消息。

完整示例

运行示例

注意: 当记忆超过 10 条时,最旧的消息会被自动删除。

配置选项

消息保留策略

输出:

TokenWindowChatMemory

与 MessageWindowChatMemory 的区别

TokenWindowChatMemory 根据而不是消息数量来管理记忆。 为什么使用 TokenWindow?
  • 更精确的成本控制
  • 确保 Token 数量不超模型限制
  • 适应不同长度的消息

基本用法

完整示例

Token 估算

TokenWindowChatMemory 需要一个 TokenCountEstimator 来估算每条消息的 Token 数量。LangChain4j 提供了 OpenAiTokenCountEstimator
TokenCountEstimator 说明:
  • OpenAiTokenCountEstimator - 使用OpenAI的算法精确估算Token数
  • 构造函数参数指定模型名称(如 “gpt-4”, “gpt-3.5-turbo”)
  • 不同模型的Token计算方式可能略有不同
为什么需要TokenCountEstimator?
  • 消息是不可分割的整体(indivisible)
  • 如果一条消息超过Token限制,会被完全删除
  • 准确的Token估算可以避免意外删除重要消息

多用户场景

ChatMemoryProvider

对于多用户应用(如聊天机器人服务),每个用户需要独立的记忆。 ChatMemoryProvider 接口用于为每个用户创建独立的 ChatMemory 实例。

多用户完整示例

持久化 ChatMemory

为什么需要持久化?

内存中的 ChatMemory 在应用重启后会丢失。对于生产环境,需要将对话历史持久化存储到数据库。

持久化策略

常用方案:
  1. 数据库存储 - MySQL、PostgreSQL、MongoDB 等
  2. Redis 缓存 - 高性能,适合会话数据
  3. 文件存储 - JSON、序列化对象

使用数据库持久化

使用 Redis 持久化

完整示例:智能记忆管理器

测试代码示例

实践练习

练习 1:实现对话清理器

创建一个智能的对话历史清理器:

练习 2:实现带过期时间的记忆

创建一个会话有过期时间的记忆系统:

练习 3:实现记忆压缩

创建一个可以压缩旧对话历史的系统:

总结

本章要点

  1. ChatMemory 的必要性
    • LLM 本身是无状态的
    • 需要手动传递对话历史
    • ChatMemory 自动管理对话历史
  2. MessageWindowChatMemory
    • 基于消息数量的管理
    • 简单直接,易于使用
    • 适合大多数场景
  3. TokenWindowChatMemory
    • 基于 Token 数量的管理
    • 更精确的成本控制
    • 适合需要 Token 限制的场景
  4. 多用户场景
    • 使用 ChatMemoryProvider 为每个用户创建独立记忆
    • 确保用户间的对话隔离
    • 适合聊天机器人等应用
  5. 持久化
    • 数据库存储(MySQL、PostgreSQL)
    • Redis 缓存(高性能)
    • 文件存储(简单直接)
  6. 记忆管理最佳实践
    • 定期清理和压缩旧消息
    • 实现会话过期机制
    • 合理设置记忆大小限制

下一步

在下一章节中,我们将学习:
  • EmbeddingModel 和向量化
  • 如何将文本转换为向量
  • 向量相似度计算
  • EmbeddingStore 向量存储

常见问题

Q1:MessageWindowChatMemory 和 TokenWindowChatMemory 应该选择哪个? A:
  • MessageWindowChatMemory:简单场景,不需要精确的 Token 控制
  • TokenWindowChatMemory:需要精确控制成本,或消息长度差异较大的场景
Q2:ChatMemory 中的系统消息会被删除吗? A:取决于实现。通常 MessageWindowChatMemory 会保留系统消息,即使超过限制。但可以通过自定义配置改变此行为。 Q3:如何实现多用户的对话隔离? A:使用 ChatMemoryProvider,为每个用户 ID 返回独立的 ChatMemory 实例。 Q4:持久化 ChatMemory 有什么好的方案? A:
  • Redis:适合实时会话,高性能
  • 数据库:适合长期存储,便于查询和分析
  • 组合方案:Redis 用于会话期间,数据库用于归档
Q5:如何避免记忆泄漏? A:
  • 实现会话过期机制
  • 定期清理不活跃用户的记忆
  • 限制每个用户的记忆大小
  • 使用滑动窗口策略

参考资料


版权归属于 LangChat Team
官网:https://langchat.cn