From 968b82cd5bf2e85d355d53a20069a12841e8c016 Mon Sep 17 00:00:00 2001 From: SengokuCola <1026294844@qq.com> Date: Mon, 9 Jun 2025 22:33:04 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E6=B7=BB=E5=8A=A0=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E9=A1=B9=E4=BB=A5=E5=85=B3=E9=97=AD=E8=AE=B0=E5=BF=86=E5=92=8C?= =?UTF-8?q?=E5=85=B3=E7=B3=BB=E7=B3=BB=E7=BB=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/chat/focus_chat/heartFC_chat.py | 18 +++++-- .../focus_chat/heartflow_message_processor.py | 31 +++++------ .../info_processors/mind_processor.py | 5 +- src/chat/focus_chat/memory_activator.py | 10 ++-- .../focus_chat/planners/planner_simple.py | 2 +- src/chat/memory_system/Hippocampus.py | 27 +++++----- src/chat/normal_chat/normal_prompt.py | 28 +++++----- src/config/official_configs.py | 4 ++ src/experimental/PFC/pfc_KnowledgeFetcher.py | 4 +- src/main.py | 54 ++++++++++++------- template/bot_config_template.toml | 5 +- 11 files changed, 112 insertions(+), 76 deletions(-) diff --git a/src/chat/focus_chat/heartFC_chat.py b/src/chat/focus_chat/heartFC_chat.py index 1651fd884..3137c1f23 100644 --- a/src/chat/focus_chat/heartFC_chat.py +++ b/src/chat/focus_chat/heartFC_chat.py @@ -51,7 +51,7 @@ PROCESSOR_CLASSES = { "ToolProcessor": (ToolProcessor, "tool_use_processor"), "WorkingMemoryProcessor": (WorkingMemoryProcessor, "working_memory_processor"), "SelfProcessor": (SelfProcessor, "self_identify_processor"), - "RelationshipProcessor": (RelationshipProcessor, "relationship_processor"), + "RelationshipProcessor": (RelationshipProcessor, "relation_processor"), } logger = get_logger("hfc") # Logger Name Changed @@ -108,10 +108,18 @@ class HeartFChatting: # 根据配置文件和默认规则确定启用的处理器 config_processor_settings = global_config.focus_chat_processor - self.enabled_processor_names = [ - proc_name for proc_name, (_proc_class, config_key) in PROCESSOR_CLASSES.items() - if not config_key or getattr(config_processor_settings, config_key, True) - ] + self.enabled_processor_names = [] + + for proc_name, (_proc_class, config_key) in PROCESSOR_CLASSES.items(): + # 对于关系处理器,需要同时检查两个配置项 + if proc_name == "RelationshipProcessor": + if (global_config.relationship.enable_relationship and + getattr(config_processor_settings, config_key, True)): + self.enabled_processor_names.append(proc_name) + else: + # 其他处理器的原有逻辑 + if not config_key or getattr(config_processor_settings, config_key, True): + self.enabled_processor_names.append(proc_name) # logger.info(f"{self.log_prefix} 将启用的处理器: {self.enabled_processor_names}") diff --git a/src/chat/focus_chat/heartflow_message_processor.py b/src/chat/focus_chat/heartflow_message_processor.py index ea0004278..c20f29a13 100644 --- a/src/chat/focus_chat/heartflow_message_processor.py +++ b/src/chat/focus_chat/heartflow_message_processor.py @@ -1,4 +1,4 @@ -from src.chat.memory_system.Hippocampus import HippocampusManager +from src.chat.memory_system.Hippocampus import hippocampus_manager from src.config.config import global_config from src.chat.message_receive.message import MessageRecv from src.chat.message_receive.storage import MessageStorage @@ -67,21 +67,22 @@ async def _calculate_interest(message: MessageRecv) -> Tuple[float, bool]: is_mentioned, _ = is_mentioned_bot_in_message(message) interested_rate = 0.0 - with Timer("记忆激活"): - interested_rate = await HippocampusManager.get_instance().get_activate_from_text( - message.processed_plain_text, - fast_retrieval=True, - ) - text_len = len(message.processed_plain_text) - # 根据文本长度调整兴趣度,长度越大兴趣度越高,但增长率递减,最低0.01,最高0.05 - # 采用对数函数实现递减增长 + if global_config.memory.enable_memory: + with Timer("记忆激活"): + interested_rate = await hippocampus_manager.get_activate_from_text( + message.processed_plain_text, + fast_retrieval=True, + ) + logger.trace(f"记忆激活率: {interested_rate:.2f}") + + text_len = len(message.processed_plain_text) + # 根据文本长度调整兴趣度,长度越大兴趣度越高,但增长率递减,最低0.01,最高0.05 + # 采用对数函数实现递减增长 - base_interest = 0.01 + (0.05 - 0.01) * (math.log10(text_len + 1) / math.log10(1000 + 1)) - base_interest = min(max(base_interest, 0.01), 0.05) + base_interest = 0.01 + (0.05 - 0.01) * (math.log10(text_len + 1) / math.log10(1000 + 1)) + base_interest = min(max(base_interest, 0.01), 0.05) - interested_rate += base_interest - - logger.trace(f"记忆激活率: {interested_rate:.2f}") + interested_rate += base_interest if is_mentioned: interest_increase_on_mention = 1 @@ -210,7 +211,7 @@ class HeartFCMessageReceiver: logger.info(f"[{mes_name}]{userinfo.user_nickname}:{message.processed_plain_text}") # 8. 关系处理 - if global_config.relationship.give_name: + if global_config.relationship.enable_relationship and global_config.relationship.give_name: await _process_relationship(message) except Exception as e: diff --git a/src/chat/focus_chat/info_processors/mind_processor.py b/src/chat/focus_chat/info_processors/mind_processor.py index fb3cb757a..9392ed324 100644 --- a/src/chat/focus_chat/info_processors/mind_processor.py +++ b/src/chat/focus_chat/info_processors/mind_processor.py @@ -193,8 +193,9 @@ class MindProcessor(BaseProcessor): # 获取个性化信息 relation_prompt = "" - for person in person_list: - relation_prompt += await relationship_manager.build_relationship_info(person, is_id=True) + if global_config.relationship.enable_relationship: + for person in person_list: + relation_prompt += await relationship_manager.build_relationship_info(person, is_id=True) template_name = "sub_heartflow_prompt_before" if is_group_chat else "sub_heartflow_prompt_private_before" logger.debug(f"{self.log_prefix} 使用{'群聊' if is_group_chat else '私聊'}思考模板") diff --git a/src/chat/focus_chat/memory_activator.py b/src/chat/focus_chat/memory_activator.py index de0833879..4f57286b8 100644 --- a/src/chat/focus_chat/memory_activator.py +++ b/src/chat/focus_chat/memory_activator.py @@ -6,7 +6,7 @@ from src.config.config import global_config from src.common.logger_manager import get_logger from src.chat.utils.prompt_builder import Prompt, global_prompt_manager from datetime import datetime -from src.chat.memory_system.Hippocampus import HippocampusManager +from src.chat.memory_system.Hippocampus import hippocampus_manager from typing import List, Dict import difflib import json @@ -87,6 +87,10 @@ class MemoryActivator: Returns: List[Dict]: 激活的记忆列表 """ + # 如果记忆系统被禁用,直接返回空列表 + if not global_config.memory.enable_memory: + return [] + obs_info_text = "" for observation in observations: if isinstance(observation, ChattingObservation): @@ -128,10 +132,10 @@ class MemoryActivator: logger.debug(f"当前激活的记忆关键词: {self.cached_keywords}") # 调用记忆系统获取相关记忆 - related_memory = await HippocampusManager.get_instance().get_memory_from_topic( + related_memory = await hippocampus_manager.get_memory_from_topic( valid_keywords=keywords, max_memory_num=3, max_memory_length=2, max_depth=3 ) - # related_memory = await HippocampusManager.get_instance().get_memory_from_text( + # related_memory = await hippocampus_manager.get_memory_from_text( # text=obs_info_text, max_memory_num=5, max_memory_length=2, max_depth=3, fast_retrieval=False # ) diff --git a/src/chat/focus_chat/planners/planner_simple.py b/src/chat/focus_chat/planners/planner_simple.py index 590c80c2b..bfb0420fa 100644 --- a/src/chat/focus_chat/planners/planner_simple.py +++ b/src/chat/focus_chat/planners/planner_simple.py @@ -193,7 +193,7 @@ class ActionPlanner(BasePlanner): prompt = f"{prompt}" llm_content, (reasoning_content, _) = await self.planner_llm.generate_response_async(prompt=prompt) - # logger.info(f"{self.log_prefix}规划器原始提示词: {prompt}") + logger.info(f"{self.log_prefix}规划器原始提示词: {prompt}") logger.info(f"{self.log_prefix}规划器原始响应: {llm_content}") logger.info(f"{self.log_prefix}规划器推理: {reasoning_content}") diff --git a/src/chat/memory_system/Hippocampus.py b/src/chat/memory_system/Hippocampus.py index 4bcaa6f21..2638649ce 100644 --- a/src/chat/memory_system/Hippocampus.py +++ b/src/chat/memory_system/Hippocampus.py @@ -1655,21 +1655,9 @@ class ParahippocampalGyrus: class HippocampusManager: - _instance = None - _hippocampus = None - _initialized = False - - @classmethod - def get_instance(cls): - if cls._instance is None: - cls._instance = cls() - return cls._instance - - @classmethod - def get_hippocampus(cls): - if not cls._initialized: - raise RuntimeError("HippocampusManager 尚未初始化,请先调用 initialize 方法") - return cls._hippocampus + def __init__(self): + self._hippocampus = None + self._initialized = False def initialize(self): """初始化海马体实例""" @@ -1695,6 +1683,11 @@ class HippocampusManager: return self._hippocampus + def get_hippocampus(self): + if not self._initialized: + raise RuntimeError("HippocampusManager 尚未初始化,请先调用 initialize 方法") + return self._hippocampus + async def build_memory(self): """构建记忆的公共接口""" if not self._initialized: @@ -1772,3 +1765,7 @@ class HippocampusManager: if not self._initialized: raise RuntimeError("HippocampusManager 尚未初始化,请先调用 initialize 方法") return self._hippocampus.get_all_node_names() + + +# 创建全局实例 +hippocampus_manager = HippocampusManager() diff --git a/src/chat/normal_chat/normal_prompt.py b/src/chat/normal_chat/normal_prompt.py index eda165c46..8b835951b 100644 --- a/src/chat/normal_chat/normal_prompt.py +++ b/src/chat/normal_chat/normal_prompt.py @@ -7,7 +7,7 @@ from src.person_info.relationship_manager import relationship_manager import time from src.chat.utils.utils import get_recent_group_speaker from src.manager.mood_manager import mood_manager -from src.chat.memory_system.Hippocampus import HippocampusManager +from src.chat.memory_system.Hippocampus import hippocampus_manager from src.chat.knowledge.knowledge_lib import qa_manager from src.chat.focus_chat.expressors.exprssion_learner import expression_learner import random @@ -112,8 +112,9 @@ class PromptBuilder: ) relation_prompt = "" - for person in who_chat_in_group: - relation_prompt += await relationship_manager.build_relationship_info(person) + if global_config.relationship.enable_relationship: + for person in who_chat_in_group: + relation_prompt += await relationship_manager.build_relationship_info(person) mood_prompt = mood_manager.get_mood_prompt() @@ -159,18 +160,19 @@ class PromptBuilder: )[0] memory_prompt = "" - related_memory = await HippocampusManager.get_instance().get_memory_from_text( - text=message_txt, max_memory_num=2, max_memory_length=2, max_depth=3, fast_retrieval=False - ) - - related_memory_info = "" - if related_memory: - for memory in related_memory: - related_memory_info += memory[1] - memory_prompt = await global_prompt_manager.format_prompt( - "memory_prompt", related_memory_info=related_memory_info + if global_config.memory.enable_memory: + related_memory = await hippocampus_manager.get_memory_from_text( + text=message_txt, max_memory_num=2, max_memory_length=2, max_depth=3, fast_retrieval=False ) + related_memory_info = "" + if related_memory: + for memory in related_memory: + related_memory_info += memory[1] + memory_prompt = await global_prompt_manager.format_prompt( + "memory_prompt", related_memory_info=related_memory_info + ) + message_list_before_now = get_raw_msg_before_timestamp_with_chat( chat_id=chat_stream.stream_id, timestamp=time.time(), diff --git a/src/config/official_configs.py b/src/config/official_configs.py index 1b9bbae67..1019c77dc 100644 --- a/src/config/official_configs.py +++ b/src/config/official_configs.py @@ -49,6 +49,8 @@ class IdentityConfig(ConfigBase): @dataclass class RelationshipConfig(ConfigBase): """关系配置类""" + + enable_relationship: bool = True give_name: bool = False """是否给其他人取名""" @@ -220,6 +222,8 @@ class EmojiConfig(ConfigBase): @dataclass class MemoryConfig(ConfigBase): """记忆配置类""" + + enable_memory: bool = True memory_build_interval: int = 600 """记忆构建间隔(秒)""" diff --git a/src/experimental/PFC/pfc_KnowledgeFetcher.py b/src/experimental/PFC/pfc_KnowledgeFetcher.py index 82eb2618f..f48ce2013 100644 --- a/src/experimental/PFC/pfc_KnowledgeFetcher.py +++ b/src/experimental/PFC/pfc_KnowledgeFetcher.py @@ -1,6 +1,6 @@ from typing import List, Tuple from src.common.logger import get_module_logger -from src.chat.memory_system.Hippocampus import HippocampusManager +from src.chat.memory_system.Hippocampus import hippocampus_manager from src.llm_models.utils_model import LLMRequest from src.config.config import global_config from src.chat.message_receive.message import Message @@ -62,7 +62,7 @@ class KnowledgeFetcher: ) # 从记忆中获取相关知识 - related_memory = await HippocampusManager.get_instance().get_memory_from_text( + related_memory = await hippocampus_manager.get_memory_from_text( text=f"{query}\n{chat_history_text}", max_memory_num=3, max_memory_length=2, diff --git a/src/main.py b/src/main.py index c793a1a62..ba35ce64c 100644 --- a/src/main.py +++ b/src/main.py @@ -9,7 +9,6 @@ from .chat.emoji_system.emoji_manager import emoji_manager from .chat.normal_chat.willing.willing_manager import willing_manager from .chat.message_receive.chat_stream import chat_manager from src.chat.heart_flow.heartflow import heartflow -from .chat.memory_system.Hippocampus import HippocampusManager from .chat.message_receive.message_sender import message_manager from .chat.message_receive.storage import MessageStorage from .config.config import global_config @@ -23,6 +22,10 @@ from .api.main import start_api_server # 导入actions模块,确保装饰器被执行 import src.chat.actions.default_actions # noqa +# 条件导入记忆系统 +if global_config.memory.enable_memory: + from .chat.memory_system.Hippocampus import hippocampus_manager + # 加载插件actions import importlib import pkgutil @@ -35,7 +38,12 @@ logger = get_logger("main") class MainSystem: def __init__(self): - self.hippocampus_manager: HippocampusManager = HippocampusManager.get_instance() + # 根据配置条件性地初始化记忆系统 + if global_config.memory.enable_memory: + self.hippocampus_manager = hippocampus_manager + else: + self.hippocampus_manager = None + self.individuality: Individuality = individuality # 使用消息API替代直接的FastAPI实例 @@ -90,8 +98,14 @@ class MainSystem: await chat_manager._initialize() asyncio.create_task(chat_manager._auto_save_task()) - # 使用HippocampusManager初始化海马体 - self.hippocampus_manager.initialize() + # 根据配置条件性地初始化记忆系统 + if global_config.memory.enable_memory: + if self.hippocampus_manager: + self.hippocampus_manager.initialize() + logger.success("记忆系统初始化成功") + else: + logger.info("记忆系统已禁用,跳过初始化") + # await asyncio.sleep(0.5) #防止logger输出飞了 # 将bot.py中的chat_bot.message_process消息处理函数注册到api.py的消息处理基类中 @@ -201,43 +215,47 @@ class MainSystem: """调度定时任务""" while True: tasks = [ - self.build_memory_task(), - self.forget_memory_task(), - self.consolidate_memory_task(), - self.learn_and_store_expression_task(), - self.remove_recalled_message_task(), emoji_manager.start_periodic_check_register(), + self.remove_recalled_message_task(), self.app.run(), self.server.run(), ] + + # 根据配置条件性地添加记忆系统相关任务 + if global_config.memory.enable_memory and self.hippocampus_manager: + tasks.extend([ + self.build_memory_task(), + self.forget_memory_task(), + self.consolidate_memory_task(), + ]) + + tasks.append(self.learn_and_store_expression_task()) + await asyncio.gather(*tasks) - @staticmethod - async def build_memory_task(): + async def build_memory_task(self): """记忆构建任务""" while True: await asyncio.sleep(global_config.memory.memory_build_interval) logger.info("正在进行记忆构建") - await HippocampusManager.get_instance().build_memory() + await self.hippocampus_manager.build_memory() - @staticmethod - async def forget_memory_task(): + async def forget_memory_task(self): """记忆遗忘任务""" while True: await asyncio.sleep(global_config.memory.forget_memory_interval) logger.info("[记忆遗忘] 开始遗忘记忆...") - await HippocampusManager.get_instance().forget_memory( + await self.hippocampus_manager.forget_memory( percentage=global_config.memory.memory_forget_percentage ) logger.info("[记忆遗忘] 记忆遗忘完成") - @staticmethod - async def consolidate_memory_task(): + async def consolidate_memory_task(self): """记忆整合任务""" while True: await asyncio.sleep(global_config.memory.consolidate_memory_interval) logger.info("[记忆整合] 开始整合记忆...") - await HippocampusManager.get_instance().consolidate_memory() + await self.hippocampus_manager.consolidate_memory() logger.info("[记忆整合] 记忆整合完成") @staticmethod diff --git a/template/bot_config_template.toml b/template/bot_config_template.toml index 9e15dbfea..ab585450e 100644 --- a/template/bot_config_template.toml +++ b/template/bot_config_template.toml @@ -1,5 +1,5 @@ [inner] -version = "2.16.0" +version = "2.17.0" #----以下是给开发人员阅读的,如果你只是部署了麦麦,不需要阅读---- #如果你想要修改配置文件,请在修改后将version的值进行变更 @@ -45,7 +45,7 @@ enable_expression_learning = false # 是否启用表达学习,麦麦会学习 learning_interval = 600 # 学习间隔 单位秒 [relationship] -give_name = true # 麦麦是否给其他人取名 +enable_relationship = true # 是否启用关系系统 [chat] #麦麦的聊天通用设置 chat_mode = "normal" # 聊天模式 —— 普通模式:normal,专注模式:focus,在普通模式和专注模式之间自动切换 @@ -114,6 +114,7 @@ content_filtration = false # 是否启用表情包过滤,只有符合该要 filtration_prompt = "符合公序良俗" # 表情包过滤要求,只有符合该要求的表情包才会被保存 [memory] +enable_memory = true # 是否启用记忆系统 memory_build_interval = 1000 # 记忆构建间隔 单位秒 间隔越低,麦麦学习越多,但是冗余信息也会增多 memory_build_distribution = [6.0, 3.0, 0.6, 32.0, 12.0, 0.4] # 记忆构建分布,参数:分布1均值,标准差,权重,分布2均值,标准差,权重 memory_build_sample_num = 4 # 采样数量,数值越高记忆采样次数越多