Skip to content

---#299

Open
yangzhen233 wants to merge 3 commits intoageerle:mainfrom
yangzhen233:feature/context-window-management
Open

---#299
yangzhen233 wants to merge 3 commits intoageerle:mainfrom
yangzhen233:feature/context-window-management

Conversation

@yangzhen233
Copy link
Copy Markdown
Contributor

● Summary

基于 LangChain4j 的 ChatMemory 机制,实现智能的聊天上下文管理,支持三种策略模式,可根据不同场景灵活选择。

Features

三种顶层策略

  • message - 固定消息数量(原生滑动窗口),适用于简单对话、固定轮次
  • token - Token 超限时截断旧消息,适用于通用场景、成本敏感
  • hybrid - Token 达到阈值时摘要压缩,超限时截断,适用于长对话、保留语义

两种压缩策略

  • SummarizationStrategy - 摘要压缩,优先级 50,Token 达到比例阈值时触发(仅 hybrid)
  • TruncationStrategy - Token 截断,优先级 100,Token 超限时触发

核心组件

  • ChatMemoryFactory - 内存工厂,根据配置创建 ChatMemory 实例
  • TokenBasedChatMemory - Token 窗口内存核心实现
  • CompressionStrategyManager - 策略管理器,按优先级执行压缩策略
  • ModelTokenLimits - 100+ 主流 AI 模型的 Token 限制映射
  • TokenCounter - Token 计数器,估算文本和消息的 Token 数量
  • PersistentChatMemoryStore - 持久化存储,将消息存储到数据库

核心功能

  • 100+ 模型支持 - 自动识别主流 AI 模型的 Token 限制(OpenAI、DeepSeek、智谱、通义千问、Claude、Gemini 等)
  • 策略框架 - 按优先级执行,支持策略组合(摘要 → 截断)
  • 多层降级保障 - 策略失败时强制截断兜底,确保消息永不超限
  • 摘要模型策略 - current(当前模型)/ smart(智能映射)/ custom(自定义)
  • 系统消息保护 - 所有策略保留系统消息,确保 AI 角色设定不丢失
  • 未知模型回退 - 自动回退到固定消息数量策略
  • API 地址修正 - 智谱 GLM、千问 Qwen 等需要特殊路径的自动处理

Architecture

请求流程:

  1. 用户消息 -> ChatServiceFacade -> ChatMemoryFactory
  2. ChatMemoryFactory 根据 strategy 配置创建对应的 ChatMemory 实例:
    • strategy=message -> MessageWindowChatMemory (LangChain4j原生,固定消息数量)
    • strategy=token -> TokenBasedChatMemory (仅截断)
    • strategy=hybrid -> TokenBasedChatMemory (摘要+截断)
  3. TokenBasedChatMemory 从数据库查询历史消息,进行 Token 计数检查
  4. 如果 Token 超限,通过 CompressionStrategyManager 执行压缩策略

● Configuration

新增 application.yml 配置:

   
  chat:                                                                                                                                                                          
    memory:                                                 
      enabled: true
      strategy: message
      max-messages: 20
      max-tokens: null
      reserved-for-reply: 2000
      preserve-system-messages: true
      summarize-token-ratio: 0.7
      summarize-threshold: 10
      summarizer-strategy: current

详情见文档:ruoyi-modules/ruoyi-chat/docs/聊天上下文管理实现文档.md


Test Plan

  • Message策略测试:滑动窗口自动移除旧消息
  • Token策略测试:Token超限时触发截断
  • Hybrid策略测试:达到阈值触发摘要压缩
  • 边界情况测试:空消息、系统消息保护等

Files Changed

  • ChatMemoryFactory.java - 内存工厂,创建 ChatMemory 实例
  • ChatMemoryProperties.java - 配置属性类
  • TokenBasedChatMemory.java - Token 窗口内存核心实现
  • ModelTokenLimits.java - 模型 Token 限制映射
  • TokenCounter.java - Token 计数器
  • PersistentChatMemoryStore.java - 持久化存储
  • CompressionStrategyManager.java - 策略管理器
  • MemoryCompressionStrategy.java - 压缩策略接口
  • SummarizationStrategy.java - 摘要策略
  • TruncationStrategy.java - 截断策略
  • CompressionContext.java - 压缩上下文
  • CompressionResult.java - 压缩结果
  • application.yml - 新增 chat.memory 配置项
  • 聊天上下文管理实现文档.md - 实现文档

  feat(chat): 优化上下文管理 - 实现内存管理策略

  基于 LangChain4j 的 ChatMemory 机制,实现智能的 Token 窗口内存管理,
  支持策略模式的压缩机制,包括摘要压缩、Token 截断和滑动窗口三种策略。

  主要功能:
  - 支持三种顶层策略:message(固定消息数)、token(Token窗口)、hybrid(Token+摘要)
  - 支持 100+ 主流 AI 模型的 Token 限制自动识别
  - 策略框架按优先级执行:摘要(50) → 截断(100) → 滑动窗口(150)
  - 多层降级保障:策略失败时强制截断兜底
  - 摘要模型策略:current/smart/custom 三种选择
  - 系统消息保护:所有策略保留系统消息

  核心组件:
  - ChatMemoryFactory: 内存工厂,根据配置创建 ChatMemory 实例
  - TokenBasedChatMemory: Token 窗口内存核心实现
  - CompressionStrategyManager: 策略管理器
  - ModelTokenLimits: 模型 Token 限制映射
  - TokenCounter: Token 计数器

  修复问题:
  - SlidingWindowStrategy 不保留系统消息 → 分离系统消息处理
  - effectiveMaxTokens 边界检查 → 确保返回值 >= 1
  - 策略执行后仍超限 → 添加 forceTruncate() 强制截断兜底

  配置优化:
  - 清理无效配置参数,保留有效配置项
  - 添加策略配置注释说明,区分通用配置和策略专属配置
  - 明确 message 策略下不生效的配置列表
  重命名文档名称,优化策略描述为表格形式,修复模型Token限制映射中的重复key问题,
  删除废弃的 SlidingWindowStrategy 类,新增 message 策略测试用例。

  文档优化:
  - 重命名:Token窗口内存管理实现文档.md → 聊天上下文管理实现文档.md
  - 概述部分策略描述改为表格形式,更清晰易懂
  - 压缩策略描述改为表格形式,展示功能与触发条件

  代码修复:
  - 删除废弃的 SlidingWindowStrategy 类
  - 默认策略改为 message(固定消息数量)

  测试验证:
  - 新增 message 策略测试用例,验证滑动窗口功能
  - 三种策略(message/token/hybrid)均测试通过
  - message: 固定消息数量,滑动窗口移除旧消息
  - token: Token超限时截断(15→7条, 1184→764 tokens)
  - hybrid: Token达到阈值时摘要压缩,保留语义
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant