mirror of https://github.com/Mai-with-u/MaiBot.git
224 lines
8.0 KiB
Python
224 lines
8.0 KiB
Python
from typing import Tuple
|
||
|
||
from src.common.logger import get_logger
|
||
from src.config.config import global_config
|
||
from src.chat.utils.prompt_builder import Prompt
|
||
from src.llm_models.payload_content.tool_option import ToolParamType
|
||
from src.plugin_system import BaseAction, ActionActivationType
|
||
from src.chat.memory_system.Hippocampus import hippocampus_manager
|
||
from src.chat.utils.utils import cut_key_words
|
||
from src.chat.memory_system.Memory_chest import global_memory_chest
|
||
from src.plugin_system.base.base_tool import BaseTool
|
||
from typing import Any
|
||
|
||
logger = get_logger("memory")
|
||
|
||
|
||
def init_prompt():
|
||
Prompt(
|
||
"""
|
||
以下是一些记忆条目的分类:
|
||
----------------------
|
||
{category_list}
|
||
----------------------
|
||
每一个分类条目类型代表了你对用户:"{person_name}"的印象的一个类别
|
||
|
||
现在,你有一条对 {person_name} 的新记忆内容:
|
||
{memory_point}
|
||
|
||
请判断该记忆内容是否属于上述分类,请给出分类的名称。
|
||
如果不属于上述分类,请输出一个合适的分类名称,对新记忆内容进行概括。要求分类名具有概括性。
|
||
注意分类数一般不超过5个
|
||
请严格用json格式输出,不要输出任何其他内容:
|
||
{{
|
||
"category": "分类名称"
|
||
}} """,
|
||
"relation_category",
|
||
)
|
||
|
||
Prompt(
|
||
"""
|
||
以下是有关{category}的现有记忆:
|
||
----------------------
|
||
{memory_list}
|
||
----------------------
|
||
|
||
现在,你有一条对 {person_name} 的新记忆内容:
|
||
{memory_point}
|
||
|
||
请判断该新记忆内容是否已经存在于现有记忆中,你可以对现有进行进行以下修改:
|
||
注意,一般来说记忆内容不超过5个,且记忆文本不应太长
|
||
|
||
1.新增:当记忆内容不存在于现有记忆,且不存在矛盾,请用json格式输出:
|
||
{{
|
||
"new_memory": "需要新增的记忆内容"
|
||
}}
|
||
2.加深印象:如果这个新记忆已经存在于现有记忆中,在内容上与现有记忆类似,请用json格式输出:
|
||
{{
|
||
"memory_id": 1, #请输出你认为需要加深印象的,与新记忆内容类似的,已经存在的记忆的序号
|
||
"integrate_memory": "加深后的记忆内容,合并内容类似的新记忆和旧记忆"
|
||
}}
|
||
3.整合:如果这个新记忆与现有记忆产生矛盾,请你结合其他记忆进行整合,用json格式输出:
|
||
{{
|
||
"memory_id": 1, #请输出你认为需要整合的,与新记忆存在矛盾的,已经存在的记忆的序号
|
||
"integrate_memory": "整合后的记忆内容,合并内容矛盾的新记忆和旧记忆"
|
||
}}
|
||
|
||
现在,请你根据情况选出合适的修改方式,并输出json,不要输出其他内容:
|
||
""",
|
||
"relation_category_update",
|
||
)
|
||
|
||
|
||
# class BuildMemoryAction(BaseAction):
|
||
# """关系动作 - 构建关系"""
|
||
|
||
# activation_type = ActionActivationType.LLM_JUDGE
|
||
# parallel_action = True
|
||
|
||
# # 动作基本信息
|
||
# action_name = "build_memory"
|
||
# action_description = (
|
||
# "了解对于某个概念或者某件事的记忆,并存储下来,在之后的聊天中,你可以根据这条记忆来获取相关信息"
|
||
# )
|
||
|
||
# # 动作参数定义
|
||
# action_parameters = {
|
||
# "concept_name": "需要了解或记忆的概念或事件的名称",
|
||
# "concept_description": "需要了解或记忆的概念或事件的描述,需要具体且明确",
|
||
# }
|
||
|
||
# # 动作使用场景
|
||
# action_require = [
|
||
# "了解对于某个概念或者某件事的记忆,并存储下来,在之后的聊天中,你可以根据这条记忆来获取相关信息",
|
||
# "有你不了解的概念",
|
||
# "有人要求你记住某个概念或者事件",
|
||
# "你对某件事或概念有新的理解,或产生了兴趣",
|
||
# ]
|
||
|
||
# # 关联类型
|
||
# associated_types = ["text"]
|
||
|
||
# async def execute(self) -> Tuple[bool, str]:
|
||
# """执行关系动作"""
|
||
|
||
# try:
|
||
# # 1. 获取构建关系的原因
|
||
# concept_description = self.action_data.get("concept_description", "")
|
||
# logger.info(f"{self.log_prefix} 添加记忆原因: {self.reasoning}")
|
||
# concept_name = self.action_data.get("concept_name", "")
|
||
# # 2. 获取目标用户信息
|
||
|
||
# # 对 concept_name 进行jieba分词
|
||
# concept_name_tokens = cut_key_words(concept_name)
|
||
# # logger.info(f"{self.log_prefix} 对 concept_name 进行分词结果: {concept_name_tokens}")
|
||
|
||
# filtered_concept_name_tokens = [
|
||
# token
|
||
# for token in concept_name_tokens
|
||
# if all(keyword not in token for keyword in global_config.memory.memory_ban_words)
|
||
# ]
|
||
|
||
# if not filtered_concept_name_tokens:
|
||
# logger.warning(f"{self.log_prefix} 过滤后的概念名称列表为空,跳过添加记忆")
|
||
# return False, "过滤后的概念名称列表为空,跳过添加记忆"
|
||
|
||
# similar_topics_dict = (
|
||
# hippocampus_manager.get_hippocampus().parahippocampal_gyrus.get_similar_topics_from_keywords(
|
||
# filtered_concept_name_tokens
|
||
# )
|
||
# )
|
||
# await hippocampus_manager.get_hippocampus().parahippocampal_gyrus.add_memory_with_similar(
|
||
# concept_description, similar_topics_dict
|
||
# )
|
||
|
||
# return True, f"成功添加记忆: {concept_name}"
|
||
|
||
# except Exception as e:
|
||
# logger.error(f"{self.log_prefix} 构建记忆时出错: {e}")
|
||
# return False, f"构建记忆时出错: {e}"
|
||
|
||
class GetMemoryTool(BaseTool):
|
||
"""获取用户信息"""
|
||
|
||
name = "get_memory"
|
||
description = "在记忆中搜索,获取某个问题的答案"
|
||
parameters = [
|
||
("question", ToolParamType.STRING, "需要获取答案的问题", True, None)
|
||
]
|
||
|
||
available_for_llm = True
|
||
|
||
async def execute(self, function_args: dict[str, Any]) -> dict[str, Any]:
|
||
"""执行比较两个数的大小
|
||
|
||
Args:
|
||
function_args: 工具参数
|
||
|
||
Returns:
|
||
dict: 工具执行结果
|
||
"""
|
||
question: str = function_args.get("question") # type: ignore
|
||
|
||
answer = await global_memory_chest.get_answer_by_question(question=question)
|
||
if not answer:
|
||
return {"content": f"没有找到相关记忆"}
|
||
|
||
return {"content": f"问题:{question},答案:{answer}"}
|
||
|
||
|
||
|
||
class GetMemoryAction(BaseAction):
|
||
"""关系动作 - 获取记忆"""
|
||
|
||
activation_type = ActionActivationType.LLM_JUDGE
|
||
parallel_action = True
|
||
|
||
# 动作基本信息
|
||
action_name = "get_memory"
|
||
action_description = (
|
||
"在记忆中搜寻某个问题的答案"
|
||
)
|
||
|
||
# 动作参数定义
|
||
action_parameters = {
|
||
"question": "需要搜寻或回答的问题",
|
||
}
|
||
|
||
# 动作使用场景
|
||
action_require = [
|
||
"在记忆中搜寻某个问题的答案",
|
||
"有你不了解的概念",
|
||
"有人提问关于过去的事情"
|
||
"你需要根据记忆回答某个问题",
|
||
]
|
||
|
||
# 关联类型
|
||
associated_types = ["text"]
|
||
|
||
async def execute(self) -> Tuple[bool, str]:
|
||
"""执行关系动作"""
|
||
|
||
question = self.action_data.get("question", "")
|
||
answer = await global_memory_chest.get_answer_by_question(self.chat_id, question)
|
||
if not answer:
|
||
await self.store_action_info(
|
||
action_build_into_prompt=True,
|
||
action_prompt_display=f"你回忆了有关问题:{question}的记忆,但是没有找到相关记忆",
|
||
action_done=True,
|
||
)
|
||
|
||
return False, f"没有找到相关记忆"
|
||
|
||
await self.store_action_info(
|
||
action_build_into_prompt=True,
|
||
action_prompt_display=f"你回忆了有关问题:{question}的记忆,答案是:{answer}",
|
||
action_done=True,
|
||
)
|
||
|
||
return True, f"成功获取记忆: {answer}"
|
||
|
||
|
||
# 还缺一个关系的太多遗忘和对应的提取
|
||
init_prompt()
|