Merge pull request #1248 from xinnan-tech/manager-local-mem

增加智控台管理【本地记忆】功能
This commit is contained in:
欣南科技
2025-05-14 22:29:59 +08:00
committed by GitHub
24 changed files with 311 additions and 100 deletions
+8 -1
View File
@@ -405,6 +405,8 @@ class ConnectionHandler:
]["Intent"]
if private_config.get("prompt", None) is not None:
self.config["prompt"] = private_config["prompt"]
if private_config.get("summaryMemory", None) is not None:
self.config["summaryMemory"] = private_config["summaryMemory"]
if private_config.get("device_max_output_size", None) is not None:
self.max_output_size = int(private_config["device_max_output_size"])
if private_config.get("chat_history_conf", None) is not None:
@@ -438,7 +440,12 @@ class ConnectionHandler:
def _initialize_memory(self):
"""初始化记忆模块"""
self.memory.init_memory(self.device_id, self.llm)
self.memory.init_memory(
self.device_id,
self.llm,
self.config["summaryMemory"],
not self.read_config_from_api,
)
def _initialize_intent(self):
self.intent_type = self.config["Intent"][
@@ -4,6 +4,7 @@ from config.logger import setup_logging
TAG = __name__
logger = setup_logging()
class MemoryProviderBase(ABC):
def __init__(self, config):
self.config = config
@@ -20,6 +21,6 @@ class MemoryProviderBase(ABC):
"""Query memories for specific role based on similarity"""
return "please implement query method"
def init_memory(self, role_id, llm):
self.role_id = role_id
def init_memory(self, role_id, llm, summary_memory=None):
self.role_id = role_id
self.llm = llm
@@ -8,7 +8,7 @@ TAG = __name__
class MemoryProvider(MemoryProviderBase):
def __init__(self, config):
def __init__(self, config, summary_memory=None):
super().__init__(config)
self.api_key = config.get("api_key", "")
self.api_version = config.get("api_version", "v1.1")
@@ -4,6 +4,7 @@ import json
import os
import yaml
from config.config_loader import get_project_dir
from config.manage_api_client import save_mem_local_short
short_term_memory_prompt = """
@@ -72,6 +73,17 @@ short_term_memory_prompt = """
```
"""
short_term_memory_prompt_only_content = """
你是一个经验丰富的记忆总结者,擅长将对话内容进行总结摘要,遵循以下规则:
1、总结user的重要信息,以便在未来的对话中提供更个性化的服务
2、不要重复总结,不要遗忘之前记忆,除非原来的记忆超过了1800字内,否则不要遗忘、不要压缩用户的历史记忆
3、用户操控的设备音量、播放音乐、天气、退出、不想对话等和用户本身无关的内容,这些信息不需要加入到总结中
4、不要把设备操控的成果结果和失败结果加入到总结中,也不要把用户的一些废话加入到总结中
5、不要为了总结而总结,如果用户的聊天没有意义,请返回原来的历史记录也是可以的
6、只需要返回总结摘要,严格控制在1800字内
7、不要包含代码、xml,不需要解释、注释和说明,保存记忆时仅从对话提取信息,不要混入示例内容
"""
def extract_json_data(json_code):
start = json_code.find("```json")
@@ -93,17 +105,24 @@ TAG = __name__
class MemoryProvider(MemoryProviderBase):
def __init__(self, config):
def __init__(self, config, summary_memory):
super().__init__(config)
self.short_momery = ""
self.save_to_file = True
self.memory_path = get_project_dir() + "data/.memory.yaml"
self.load_memory()
self.load_memory(summary_memory)
def init_memory(self, role_id, llm):
def init_memory(self, role_id, llm, summary_memory=None, save_to_file=True):
super().init_memory(role_id, llm)
self.load_memory()
self.save_to_file = save_to_file
self.load_memory(summary_memory)
def load_memory(self, summary_memory):
# api获取到总结记忆后直接返回
if summary_memory or not self.save_to_file:
self.short_momery = summary_memory
return
def load_memory(self):
all_memory = {}
if os.path.exists(self.memory_path):
with open(self.memory_path, "r", encoding="utf-8") as f:
@@ -142,16 +161,20 @@ class MemoryProvider(MemoryProviderBase):
time_str = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
msgStr += f"当前时间:{time_str}"
result = self.llm.response_no_stream(short_term_memory_prompt, msgStr)
json_str = extract_json_data(result)
try:
json_data = json.loads(json_str) # 检查json格式是否正确
self.short_momery = json_str
except Exception as e:
print("Error:", e)
self.save_memory_to_file()
if self.save_to_file:
result = self.llm.response_no_stream(short_term_memory_prompt, msgStr)
json_str = extract_json_data(result)
try:
json.loads(json_str) # 检查json格式是否正确
self.short_momery = json_str
self.save_memory_to_file()
except Exception as e:
print("Error:", e)
else:
result = self.llm.response_no_stream(
short_term_memory_prompt_only_content, msgStr
)
save_mem_local_short(self.role_id, result)
logger.bind(tag=TAG).info(f"Save memory successful - Role: {self.role_id}")
return self.short_momery
@@ -1,18 +1,20 @@
'''
"""
不使用记忆,可以选择此模块
'''
"""
from ..base import MemoryProviderBase, logger
TAG = __name__
class MemoryProvider(MemoryProviderBase):
def __init__(self, config):
def __init__(self, config, summary_memory=None):
super().__init__(config)
async def save_memory(self, msgs):
logger.bind(tag=TAG).debug("nomem mode: No memory saving is performed.")
return None
async def query_memory(self, query: str)-> str:
async def query_memory(self, query: str) -> str:
logger.bind(tag=TAG).debug("nomem mode: No memory query is performed.")
return ""
return ""
+2 -1
View File
@@ -75,7 +75,8 @@ class Dialogue:
if system_message:
enhanced_system_prompt = (
f"{system_message.content}\n\n" f"相关记忆:\n{memory_str}"
f"{system_message.content}\n\n"
f"以下是用户的历史记忆:\n```\n{memory_str}\n```"
)
dialogue.append({"role": "system", "content": enhanced_system_prompt})
+1
View File
@@ -319,6 +319,7 @@ def initialize_modules(
modules["memory"] = memory.create_instance(
memory_type,
config["Memory"][select_memory_module],
config['summaryMemory'],
)
logger.bind(tag=TAG).info(f"初始化组件: memory成功 {select_memory_module}")