fix:解耦海马体,莲藕促销

This commit is contained in:
SengokuCola
2025-03-27 20:07:01 +08:00
parent dce1fdd9fd
commit 2812b0df3c
8 changed files with 116 additions and 37 deletions

View File

@@ -14,7 +14,8 @@ from .emoji_manager import emoji_manager
from .relationship_manager import relationship_manager from .relationship_manager import relationship_manager
from ..willing.willing_manager import willing_manager from ..willing.willing_manager import willing_manager
from .chat_stream import chat_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 .message_sender import message_manager, message_sender
from .storage import MessageStorage from .storage import MessageStorage
from src.common.logger import get_module_logger from src.common.logger import get_module_logger
@@ -59,6 +60,22 @@ async def start_think_flow():
logger.error(f"启动大脑和外部世界失败: {e}") logger.error(f"启动大脑和外部世界失败: {e}")
raise 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 @driver.on_startup
async def start_background_tasks(): async def start_background_tasks():
@@ -80,6 +97,8 @@ async def start_background_tasks():
# 只启动表情包管理任务 # 只启动表情包管理任务
asyncio.create_task(emoji_manager.start_periodic_check()) asyncio.create_task(emoji_manager.start_periodic_check())
asyncio.create_task(start_memory())
@driver.on_startup @driver.on_startup
async def init_schedule(): async def init_schedule():
@@ -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") @scheduler.scheduled_job("interval", seconds=global_config.build_memory_interval, id="build_memory")
async def build_memory_task(): async def build_memory_task():
"""每build_memory_interval秒执行一次记忆构建""" """每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") @scheduler.scheduled_job("interval", seconds=global_config.forget_memory_interval, id="forget_memory")
async def forget_memory_task(): async def forget_memory_task():
"""每30秒执行一次记忆构建""" """每30秒执行一次记忆构建"""
print("\033[1;32m[记忆遗忘]\033[0m 开始遗忘记忆...") 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 记忆遗忘完成") print("\033[1;32m[记忆遗忘]\033[0m 记忆遗忘完成")

View File

@@ -12,7 +12,7 @@ from nonebot.adapters.onebot.v11 import (
FriendRecallNoticeEvent, FriendRecallNoticeEvent,
) )
from ..memory_system.memory import hippocampus from ..memory_system.Hippocampus import HippocampusManager
from ..moods.moods import MoodManager # 导入情绪管理器 from ..moods.moods import MoodManager # 导入情绪管理器
from .config import global_config from .config import global_config
from .emoji_manager import emoji_manager # 导入表情包管理器 from .emoji_manager import emoji_manager # 导入表情包管理器
@@ -129,7 +129,8 @@ class ChatBot:
# 根据话题计算激活度 # 根据话题计算激活度
topic = "" 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.debug(f"{message.processed_plain_text}的激活度:{interested_rate}")
# logger.info(f"\033[1;32m[主题识别]\033[0m 使用{global_config.topic_extract}主题: {topic}") # logger.info(f"\033[1;32m[主题识别]\033[0m 使用{global_config.topic_extract}主题: {topic}")

View File

@@ -3,7 +3,7 @@ import time
from typing import Optional from typing import Optional
from ...common.database import db 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 ..moods.moods import MoodManager
from ..schedule.schedule_generator import bot_schedule from ..schedule.schedule_generator import bot_schedule
from .config import global_config from .config import global_config
@@ -79,19 +79,20 @@ class PromptBuilder:
start_time = time.time() start_time = time.time()
# 调用 hippocampus 的 get_relevant_memories 方法 # 调用 hippocampus 的 get_relevant_memories 方法
relevant_memories = await hippocampus.get_relevant_memories( relevant_memories = await HippocampusManager.get_instance().get_memory_from_text(
text=message_txt, max_topics=3, similarity_threshold=0.5, max_memory_num=4 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: if relevant_memories:
# 格式化记忆内容 # 格式化记忆内容
memory_str = "\n".join(m["content"] for m in relevant_memories)
memory_prompt = f"你回忆起:\n{memory_str}\n" memory_prompt = f"你回忆起:\n{memory_str}\n"
# 打印调试信息 # 打印调试信息
logger.debug("[记忆检索]找到以下相关记忆:") logger.debug("[记忆检索]找到以下相关记忆:")
for memory in relevant_memories: # for topic, memory_items, similarity in relevant_memories:
logger.debug(f"- 主题「{memory['topic']}」[相似度: {memory['similarity']:.2f}]: {memory['content']}") # logger.debug(f"- 主题「{topic}」[相似度: {similarity:.2f}]: {memory_items}")
end_time = time.time() end_time = time.time()
logger.info(f"回忆耗时: {(end_time - start_time):.3f}") 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}") # 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) all_nodes = filter(lambda dot: len(dot[1]["memory_items"]) > 3, all_nodes)
nodes_for_select = random.sample(all_nodes, 5) nodes_for_select = random.sample(all_nodes, 5)
topics = [info[0] for info in nodes_for_select] topics = [info[0] for info in nodes_for_select]
@@ -245,7 +246,7 @@ class PromptBuilder:
related_info = "" related_info = ""
logger.debug(f"获取知识库内容,元消息:{message[:30]}...,消息长度: {len(message)}") logger.debug(f"获取知识库内容,元消息:{message[:30]}...,消息长度: {len(message)}")
embedding = await get_embedding(message, request_type="prompt_build") 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 return related_info

View File

@@ -4,7 +4,6 @@ import math
import random import random
import time import time
import re import re
import jieba import jieba
import networkx as nx import networkx as nx
@@ -15,7 +14,6 @@ from ..chat.utils import (
calculate_information_content, calculate_information_content,
cosine_similarity, cosine_similarity,
get_closest_chat_from_db, get_closest_chat_from_db,
text_to_vector,
) )
from ..models.utils_model import LLM_request from ..models.utils_model import LLM_request
from src.common.logger import get_module_logger, LogConfig, MEMORY_STYLE_CONFIG from src.common.logger import get_module_logger, LogConfig, MEMORY_STYLE_CONFIG
@@ -180,7 +178,7 @@ class EntorhinalCortex:
max_memorized_time_per_msg = 3 max_memorized_time_per_msg = 3
# 创建双峰分布的记忆调度器 # 创建双峰分布的记忆调度器
scheduler = MemoryBuildScheduler( sample_scheduler = MemoryBuildScheduler(
n_hours1=self.config.memory_build_distribution[0], n_hours1=self.config.memory_build_distribution[0],
std_hours1=self.config.memory_build_distribution[1], std_hours1=self.config.memory_build_distribution[1],
weight1=self.config.memory_build_distribution[2], weight1=self.config.memory_build_distribution[2],
@@ -190,7 +188,7 @@ class EntorhinalCortex:
total_samples=self.config.build_memory_sample_num 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]}") logger.info(f"回忆往事: {[time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(ts)) for ts in timestamps]}")
chat_samples = [] chat_samples = []
for timestamp in timestamps: for timestamp in timestamps:
@@ -674,8 +672,8 @@ class Hippocampus:
self.parahippocampal_gyrus = ParahippocampalGyrus(self) self.parahippocampal_gyrus = ParahippocampalGyrus(self)
# 从数据库加载记忆图 # 从数据库加载记忆图
self.entorhinal_cortex.sync_memory_from_db() self.entorhinal_cortex.sync_memory_from_db()
self.llm_topic_judge = self.config.llm_topic_judge self.llm_topic_judge = LLM_request(self.config.llm_topic_judge)
self.llm_summary_by_topic = self.config.llm_summary_by_topic self.llm_summary_by_topic = LLM_request(self.config.llm_summary_by_topic)
def get_all_node_names(self) -> list: def get_all_node_names(self) -> list:
"""获取记忆图中所有节点的名字列表""" """获取记忆图中所有节点的名字列表"""
@@ -831,19 +829,79 @@ class Hippocampus:
unique_memories.sort(key=lambda x: x[2], reverse=True) unique_memories.sort(key=lambda x: x[2], reverse=True)
return unique_memories[:num] return unique_memories[:num]
# driver = get_driver() class HippocampusManager:
# config = driver.config _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
# 创建记忆图 @classmethod
memory_graph = Memory_graph() def get_hippocampus(cls):
# 创建海马体 if not cls._initialized:
hippocampus = Hippocampus() 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}")

View File

@@ -29,6 +29,6 @@ class MemoryConfig:
memory_compress_rate=global_config.memory_compress_rate, memory_compress_rate=global_config.memory_compress_rate,
memory_forget_time=global_config.memory_forget_time, memory_forget_time=global_config.memory_forget_time,
memory_ban_words=global_config.memory_ban_words, memory_ban_words=global_config.memory_ban_words,
llm_topic_judge=global_config.topic_judge_model, llm_topic_judge=global_config.llm_topic_judge,
llm_summary_by_topic=global_config.summary_by_topic_model llm_summary_by_topic=global_config.llm_summary_by_topic
) )

View File

@@ -227,7 +227,7 @@ class Hippocampus:
max_memorized_time_per_msg = 3 max_memorized_time_per_msg = 3
# 创建双峰分布的记忆调度器 # 创建双峰分布的记忆调度器
scheduler = MemoryBuildScheduler( sample_scheduler = MemoryBuildScheduler(
n_hours1=global_config.memory_build_distribution[0], # 第一个分布均值4小时前 n_hours1=global_config.memory_build_distribution[0], # 第一个分布均值4小时前
std_hours1=global_config.memory_build_distribution[1], # 第一个分布标准差 std_hours1=global_config.memory_build_distribution[1], # 第一个分布标准差
weight1=global_config.memory_build_distribution[2], # 第一个分布权重 60% 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}") # logger.debug(f"生成的时间戳数组: {timestamps}")
# print(f"生成的时间戳数组: {timestamps}") # print(f"生成的时间戳数组: {timestamps}")
# print(f"时间戳的实际时间: {[time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(ts)) for ts in timestamps]}") # print(f"时间戳的实际时间: {[time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(ts)) for ts in timestamps]}")

View File

@@ -140,8 +140,8 @@ class ScheduleGenerator:
if mind_thinking: if mind_thinking:
prompt += f"你脑子里在想:{mind_thinking}\n" prompt += f"你脑子里在想:{mind_thinking}\n"
prompt += f"现在是{now_time},结合你的个人特点和行为习惯,注意关注你今天的日程安排和想法,这很重要," prompt += f"现在是{now_time},结合你的个人特点和行为习惯,注意关注你今天的日程安排和想法,这很重要,"
prompt += "推测你现在和之后做什么,具体一些,详细一些\n" prompt += "推测你现在做什么,具体一些,详细一些\n"
prompt += "直接返回你在做的事情,不要输出其他内容:" prompt += "直接返回你在做的事情,注意是当前时间,不要输出其他内容:"
return prompt return prompt
async def generate_daily_schedule( async def generate_daily_schedule(