refactor(memory): 重构瞬时记忆为全量向量化存储模型

新系统采用“全量存储,定时清理”的设计理念,将所有聊天消息向量化并存入ChromaDB。通过后台线程定时清理过期消息,取代了之前基于“重要性模式”判断是否记忆的复杂逻辑。

主要变更:
- **全量存储**: 不再进行前置判断,所有消息均被向量化存储,简化了记忆创建流程。
- **定时清理**: 引入基于`threading`的后台任务,根据设定的`retention_hours`自动清理过期记忆,确保系统轻量高效。
- **简化检索**: 检索逻辑更新为直接查询相似消息,并增加了相似度阈值过滤和时间差格式化,提高了上下文的准确性和可读性。

在 `DefaultReplyer` 中,已切换至新的 `HybridInstantMemory`(其底层实现为V2),并优化了记忆上下文的构建逻辑,使其能更稳定地处理不同类型的记忆返回结果。
This commit is contained in:
minecraft1024a
2025-08-19 19:56:56 +08:00
committed by Windpicker-owo
parent 1b81694373
commit f2e82cf82f
7 changed files with 929 additions and 266 deletions

View File

@@ -24,7 +24,7 @@ from src.chat.utils.chat_message_builder import (
)
from src.chat.express.expression_selector import expression_selector
from src.chat.memory_system.memory_activator import MemoryActivator
from src.chat.memory_system.vector_instant_memory import VectorInstantMemory
from src.chat.memory_system.hybrid_instant_memory import HybridInstantMemory
from src.mood.mood_manager import mood_manager
from src.person_info.person_info import Person, is_person_known
from src.plugin_system.base.component_types import ActionInfo, EventType
@@ -190,7 +190,11 @@ class DefaultReplyer:
self.is_group_chat, self.chat_target_info = get_chat_type_and_target_info(self.chat_stream.stream_id)
self.heart_fc_sender = HeartFCSender()
self.memory_activator = MemoryActivator()
self.instant_memory = VectorInstantMemory(chat_id=self.chat_stream.stream_id)
# 使用混合瞬时记忆系统V2支持自定义保留时间
self.instant_memory = HybridInstantMemory(
chat_id=self.chat_stream.stream_id,
retention_hours=1
)
from src.plugin_system.core.tool_use import ToolExecutor # 延迟导入ToolExecutor不然会循环依赖
@@ -421,25 +425,42 @@ class DefaultReplyer:
if global_config.memory.enable_instant_memory:
# 异步存储聊天历史到混合记忆系统
asyncio.create_task(self.instant_memory.create_and_store_memory(chat_history))
instant_memory_list = await self.instant_memory.get_memory(target)
instant_memory = instant_memory_list[0] if instant_memory_list else None
logger.info(f"即时记忆:{instant_memory}")
# 从混合记忆系统获取相关记忆
instant_memory_result = await self.instant_memory.get_memory(target)
# 处理不同类型的返回结果
instant_memory = None
if isinstance(instant_memory_result, list) and instant_memory_result:
instant_memory = instant_memory_result[0]
elif isinstance(instant_memory_result, str) and instant_memory_result:
instant_memory = instant_memory_result
logger.info(f"混合瞬时记忆:{instant_memory}")
if not running_memories:
return ""
# 构建记忆字符串,即使某种记忆为空也要继续
memory_str = ""
has_any_memory = False
# 添加长期记忆
if running_memories:
if not memory_str:
memory_str = "以下是当前在聊天中,你回忆起的记忆:\n"
for running_memory in running_memories:
memory_str += f"- {running_memory['content']}\n"
has_any_memory = True
memory_str = "以下是当前在聊天中,你回忆起的记忆:\n"
for running_memory in running_memories:
keywords,content = running_memory
memory_str += f"- {keywords}{content}\n"
# 添加瞬时记忆
if instant_memory:
if not memory_str:
memory_str = "以下是当前在聊天中,你回忆起的记忆:\n"
memory_str += f"- {instant_memory}\n"
has_any_memory = True
return memory_str
# 只有当完全没有任何记忆时才返回空字符串
return memory_str if has_any_memory else ""
async def build_tool_info(self, chat_history: str, sender: str, target: str, enable_tool: bool = True) -> str:
"""构建工具信息块
@@ -1089,7 +1110,7 @@ class DefaultReplyer:
"""构建单个发送消息"""
bot_user_info = UserInfo(
user_id=global_config.bot.qq_account,
user_id=str(global_config.bot.qq_account),
user_nickname=global_config.bot.nickname,
platform=self.chat_stream.platform,
)