diff --git a/src/plugins/chat/__init__.py b/src/plugins/chat/__init__.py index 55b83e889..7c3629f41 100644 --- a/src/plugins/chat/__init__.py +++ b/src/plugins/chat/__init__.py @@ -14,7 +14,8 @@ from .emoji_manager import emoji_manager from .relationship_manager import relationship_manager from ..willing.willing_manager import willing_manager from .chat_stream import chat_manager -from ..memory_system.memory import hippocampus +# from ..memory_system.memory import hippocampus +from src.plugins.memory_system.Hippocampus import HippocampusManager from .message_sender import message_manager, message_sender from .storage import MessageStorage from src.common.logger import get_module_logger @@ -59,6 +60,22 @@ async def start_think_flow(): logger.error(f"启动大脑和外部世界失败: {e}") raise +async def start_memory(): + """启动记忆系统""" + try: + start_time = time.time() + logger.info("开始初始化记忆系统...") + + # 使用HippocampusManager初始化海马体 + hippocampus_manager = HippocampusManager.get_instance() + hippocampus_manager.initialize(global_config=global_config) + + end_time = time.time() + logger.success(f"记忆系统初始化完成,耗时: {end_time - start_time:.2f} 秒") + except Exception as e: + logger.error(f"记忆系统初始化失败: {e}") + raise + @driver.on_startup async def start_background_tasks(): @@ -79,6 +96,8 @@ async def start_background_tasks(): # 只启动表情包管理任务 asyncio.create_task(emoji_manager.start_periodic_check()) + + asyncio.create_task(start_memory()) @driver.on_startup @@ -139,14 +158,14 @@ async def _(bot: Bot, event: NoticeEvent, state: T_State): @scheduler.scheduled_job("interval", seconds=global_config.build_memory_interval, id="build_memory") async def build_memory_task(): """每build_memory_interval秒执行一次记忆构建""" - await hippocampus.operation_build_memory() + await HippocampusManager.get_instance().build_memory() @scheduler.scheduled_job("interval", seconds=global_config.forget_memory_interval, id="forget_memory") async def forget_memory_task(): """每30秒执行一次记忆构建""" print("\033[1;32m[记忆遗忘]\033[0m 开始遗忘记忆...") - await hippocampus.operation_forget_topic(percentage=global_config.memory_forget_percentage) + await HippocampusManager.get_instance().forget_memory(percentage=global_config.memory_forget_percentage) print("\033[1;32m[记忆遗忘]\033[0m 记忆遗忘完成") diff --git a/src/plugins/chat/bot.py b/src/plugins/chat/bot.py index e89375217..21557ef60 100644 --- a/src/plugins/chat/bot.py +++ b/src/plugins/chat/bot.py @@ -12,7 +12,7 @@ from nonebot.adapters.onebot.v11 import ( FriendRecallNoticeEvent, ) -from ..memory_system.memory import hippocampus +from ..memory_system.Hippocampus import HippocampusManager from ..moods.moods import MoodManager # 导入情绪管理器 from .config import global_config from .emoji_manager import emoji_manager # 导入表情包管理器 @@ -129,7 +129,8 @@ class ChatBot: # 根据话题计算激活度 topic = "" - interested_rate = await hippocampus.memory_activate_value(message.processed_plain_text) / 100 + # interested_rate = await HippocampusManager.get_instance().memory_activate_value(message.processed_plain_text) / 100 + interested_rate = 0.1 logger.debug(f"对{message.processed_plain_text}的激活度:{interested_rate}") # logger.info(f"\033[1;32m[主题识别]\033[0m 使用{global_config.topic_extract}主题: {topic}") diff --git a/src/plugins/chat/prompt_builder.py b/src/plugins/chat/prompt_builder.py index dc2e5930e..672471d74 100644 --- a/src/plugins/chat/prompt_builder.py +++ b/src/plugins/chat/prompt_builder.py @@ -3,7 +3,7 @@ import time from typing import Optional from ...common.database import db -from ..memory_system.memory import hippocampus, memory_graph +from ..memory_system.Hippocampus import HippocampusManager from ..moods.moods import MoodManager from ..schedule.schedule_generator import bot_schedule from .config import global_config @@ -79,19 +79,20 @@ class PromptBuilder: start_time = time.time() # 调用 hippocampus 的 get_relevant_memories 方法 - relevant_memories = await hippocampus.get_relevant_memories( - text=message_txt, max_topics=3, similarity_threshold=0.5, max_memory_num=4 + relevant_memories = await HippocampusManager.get_instance().get_memory_from_text( + text=message_txt, num=3, max_depth=2, fast_retrieval=True ) + memory_str = "\n".join(memory for topic, memories, _ in relevant_memories for memory in memories) + print(f"memory_str: {memory_str}") if relevant_memories: # 格式化记忆内容 - memory_str = "\n".join(m["content"] for m in relevant_memories) memory_prompt = f"你回忆起:\n{memory_str}\n" # 打印调试信息 logger.debug("[记忆检索]找到以下相关记忆:") - for memory in relevant_memories: - logger.debug(f"- 主题「{memory['topic']}」[相似度: {memory['similarity']:.2f}]: {memory['content']}") + # for topic, memory_items, similarity in relevant_memories: + # logger.debug(f"- 主题「{topic}」[相似度: {similarity:.2f}]: {memory_items}") end_time = time.time() logger.info(f"回忆耗时: {(end_time - start_time):.3f}秒") @@ -192,7 +193,7 @@ class PromptBuilder: # print(f"\033[1;34m[调试]\033[0m 已从数据库获取群 {group_id} 的消息记录:{chat_talking_prompt}") # 获取主动发言的话题 - all_nodes = memory_graph.dots + all_nodes = HippocampusManager.get_instance().memory_graph.dots all_nodes = filter(lambda dot: len(dot[1]["memory_items"]) > 3, all_nodes) nodes_for_select = random.sample(all_nodes, 5) topics = [info[0] for info in nodes_for_select] @@ -245,7 +246,7 @@ class PromptBuilder: related_info = "" logger.debug(f"获取知识库内容,元消息:{message[:30]}...,消息长度: {len(message)}") embedding = await get_embedding(message, request_type="prompt_build") - related_info += self.get_info_from_db(embedding, threshold=threshold) + related_info += self.get_info_from_db(embedding, limit=1, threshold=threshold) return related_info diff --git a/src/plugins/memory_system/Hippocampus.py b/src/plugins/memory_system/Hippocampus.py index 67363e95e..d8f976fc4 100644 --- a/src/plugins/memory_system/Hippocampus.py +++ b/src/plugins/memory_system/Hippocampus.py @@ -4,7 +4,6 @@ import math import random import time import re - import jieba import networkx as nx @@ -15,7 +14,6 @@ from ..chat.utils import ( calculate_information_content, cosine_similarity, get_closest_chat_from_db, - text_to_vector, ) from ..models.utils_model import LLM_request from src.common.logger import get_module_logger, LogConfig, MEMORY_STYLE_CONFIG @@ -180,7 +178,7 @@ class EntorhinalCortex: max_memorized_time_per_msg = 3 # 创建双峰分布的记忆调度器 - scheduler = MemoryBuildScheduler( + sample_scheduler = MemoryBuildScheduler( n_hours1=self.config.memory_build_distribution[0], std_hours1=self.config.memory_build_distribution[1], weight1=self.config.memory_build_distribution[2], @@ -190,7 +188,7 @@ class EntorhinalCortex: total_samples=self.config.build_memory_sample_num ) - timestamps = scheduler.get_timestamp_array() + timestamps = sample_scheduler.get_timestamp_array() logger.info(f"回忆往事: {[time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(ts)) for ts in timestamps]}") chat_samples = [] for timestamp in timestamps: @@ -674,8 +672,8 @@ class Hippocampus: self.parahippocampal_gyrus = ParahippocampalGyrus(self) # 从数据库加载记忆图 self.entorhinal_cortex.sync_memory_from_db() - self.llm_topic_judge = self.config.llm_topic_judge - self.llm_summary_by_topic = self.config.llm_summary_by_topic + self.llm_topic_judge = LLM_request(self.config.llm_topic_judge) + self.llm_summary_by_topic = LLM_request(self.config.llm_summary_by_topic) def get_all_node_names(self) -> list: """获取记忆图中所有节点的名字列表""" @@ -831,19 +829,79 @@ class Hippocampus: unique_memories.sort(key=lambda x: x[2], reverse=True) return unique_memories[:num] -# driver = get_driver() -# config = driver.config +class HippocampusManager: + _instance = None + _hippocampus = None + _global_config = None + _initialized = False -start_time = time.time() + @classmethod + def get_instance(cls): + if cls._instance is None: + cls._instance = cls() + return cls._instance -# 创建记忆图 -memory_graph = Memory_graph() -# 创建海马体 -hippocampus = Hippocampus() + @classmethod + def get_hippocampus(cls): + if not cls._initialized: + raise RuntimeError("HippocampusManager 尚未初始化,请先调用 initialize 方法") + return cls._hippocampus + + def initialize(self, global_config): + """初始化海马体实例""" + if self._initialized: + return self._hippocampus + + self._global_config = global_config + self._hippocampus = Hippocampus() + self._hippocampus.initialize(global_config) + self._initialized = True + + # 输出记忆系统参数信息 + config = self._hippocampus.config + logger.success("--------------------------------") + logger.success("记忆系统参数配置:") + logger.success(f"记忆构建间隔: {global_config.build_memory_interval}秒") + logger.success(f"记忆遗忘间隔: {global_config.forget_memory_interval}秒") + logger.success(f"记忆遗忘比例: {global_config.memory_forget_percentage}") + logger.success(f"记忆压缩率: {config.memory_compress_rate}") + logger.success(f"记忆构建样本数: {config.build_memory_sample_num}") + logger.success(f"记忆构建样本长度: {config.build_memory_sample_length}") + logger.success(f"记忆遗忘时间: {config.memory_forget_time}小时") + logger.success(f"记忆构建分布: {config.memory_build_distribution}") + logger.success("--------------------------------") + + return self._hippocampus + + async def build_memory(self): + """构建记忆的公共接口""" + if not self._initialized: + raise RuntimeError("HippocampusManager 尚未初始化,请先调用 initialize 方法") + return await self._hippocampus.parahippocampal_gyrus.operation_build_memory() + + async def forget_memory(self, percentage: float = 0.1): + """遗忘记忆的公共接口""" + if not self._initialized: + raise RuntimeError("HippocampusManager 尚未初始化,请先调用 initialize 方法") + return await self._hippocampus.parahippocampal_gyrus.operation_forget_topic(percentage) + + async def get_memory_from_text(self, text: str, num: int = 5, max_depth: int = 2, + fast_retrieval: bool = False) -> list: + """从文本中获取相关记忆的公共接口""" + if not self._initialized: + raise RuntimeError("HippocampusManager 尚未初始化,请先调用 initialize 方法") + return await self._hippocampus.get_memory_from_text(text, num, max_depth, fast_retrieval) + + def get_memory_from_keyword(self, keyword: str, max_depth: int = 2) -> list: + """从关键词获取相关记忆的公共接口""" + if not self._initialized: + raise RuntimeError("HippocampusManager 尚未初始化,请先调用 initialize 方法") + return self._hippocampus.get_memory_from_keyword(keyword, max_depth) + + def get_all_node_names(self) -> list: + """获取所有节点名称的公共接口""" + if not self._initialized: + raise RuntimeError("HippocampusManager 尚未初始化,请先调用 initialize 方法") + return self._hippocampus.get_all_node_names() -# 从全局配置初始化记忆系统 -from ..chat.config import global_config -hippocampus.initialize(global_config=global_config) -end_time = time.time() -logger.success(f"加载海马体耗时: {end_time - start_time:.2f} 秒") diff --git a/src/plugins/memory_system/__init__.py b/src/plugins/memory_system/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/plugins/memory_system/config.py b/src/plugins/memory_system/config.py index fe688372f..6c49d15fc 100644 --- a/src/plugins/memory_system/config.py +++ b/src/plugins/memory_system/config.py @@ -29,6 +29,6 @@ class MemoryConfig: memory_compress_rate=global_config.memory_compress_rate, memory_forget_time=global_config.memory_forget_time, memory_ban_words=global_config.memory_ban_words, - llm_topic_judge=global_config.topic_judge_model, - llm_summary_by_topic=global_config.summary_by_topic_model + llm_topic_judge=global_config.llm_topic_judge, + llm_summary_by_topic=global_config.llm_summary_by_topic ) \ No newline at end of file diff --git a/src/plugins/memory_system/memory.py b/src/plugins/memory_system/memory_deprecated.py similarity index 99% rename from src/plugins/memory_system/memory.py rename to src/plugins/memory_system/memory_deprecated.py index e0151c04c..3760b2ac9 100644 --- a/src/plugins/memory_system/memory.py +++ b/src/plugins/memory_system/memory_deprecated.py @@ -227,7 +227,7 @@ class Hippocampus: max_memorized_time_per_msg = 3 # 创建双峰分布的记忆调度器 - scheduler = MemoryBuildScheduler( + sample_scheduler = MemoryBuildScheduler( n_hours1=global_config.memory_build_distribution[0], # 第一个分布均值(4小时前) std_hours1=global_config.memory_build_distribution[1], # 第一个分布标准差 weight1=global_config.memory_build_distribution[2], # 第一个分布权重 60% @@ -238,7 +238,7 @@ class Hippocampus: ) # 生成时间戳数组 - timestamps = scheduler.get_timestamp_array() + timestamps = sample_scheduler.get_timestamp_array() # logger.debug(f"生成的时间戳数组: {timestamps}") # print(f"生成的时间戳数组: {timestamps}") # print(f"时间戳的实际时间: {[time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(ts)) for ts in timestamps]}") diff --git a/src/plugins/schedule/schedule_generator.py b/src/plugins/schedule/schedule_generator.py index f4bbb42b0..fb79216d5 100644 --- a/src/plugins/schedule/schedule_generator.py +++ b/src/plugins/schedule/schedule_generator.py @@ -140,8 +140,8 @@ class ScheduleGenerator: if mind_thinking: prompt += f"你脑子里在想:{mind_thinking}\n" prompt += f"现在是{now_time},结合你的个人特点和行为习惯,注意关注你今天的日程安排和想法,这很重要," - prompt += "推测你现在和之后做什么,具体一些,详细一些\n" - prompt += "直接返回你在做的事情,不要输出其他内容:" + prompt += "推测你现在在做什么,具体一些,详细一些\n" + prompt += "直接返回你在做的事情,注意是当前时间,不要输出其他内容:" return prompt async def generate_daily_schedule(