feat:移除表达方式上限,优化replyer prompt

pull/1348/head
SengokuCola 2025-11-07 15:27:04 +08:00
parent a8f4863d2f
commit 605eb636c8
5 changed files with 70 additions and 18 deletions

View File

@ -5,8 +5,6 @@ from src.chat.utils.prompt_builder import Prompt
def init_replyer_prompt():
Prompt("你正在qq群里聊天下面是群里正在聊的内容:", "chat_target_group1")
Prompt("你正在和{sender_name}聊天,这是你们之前聊的内容:", "chat_target_private1")
Prompt("正在群里聊天", "chat_target_group2")
Prompt("{sender_name}聊天", "chat_target_private2")
@ -15,7 +13,7 @@ def init_replyer_prompt():
"""{knowledge_prompt}{tool_info_block}{extra_info_block}
{expression_habits_block}{memory_block}{question_block}
你正在qq群里聊天下面是群里正在聊的内容:
你正在qq群里聊天下面是群里正在聊的内容其中包含聊天记录和聊天中的图片:
{time_block}
{dialogue_prompt}
@ -25,7 +23,7 @@ def init_replyer_prompt():
尽量简短一些{keywords_reaction_prompt}请注意把握聊天内容不要回复的太有条理可以有个性
{reply_style}
请注意不要输出多余内容(包括前后缀冒号和引号括号表情等)只输出一句回复内容就好
{moderation_prompt}不要输出多余内容(包括前后缀冒号和引号括号表情包at或 @等 )请不要思考太长
不要输出多余内容(包括前后缀冒号和引号括号表情包at或 @等 )请不要思考太长
现在你说""",
"replyer_prompt",
)

View File

@ -55,7 +55,7 @@ TEMPLATE_DIR = os.path.join(PROJECT_ROOT, "template")
# 考虑到实际上配置文件中的mai_version是不会自动更新的,所以采用硬编码
# 对该字段的更新请严格参照语义化版本规范https://semver.org/lang/zh-CN/
MMC_VERSION = "0.11.1-snapshot.1"
MMC_VERSION = "0.11.2-snapshot.1"
def get_key_comment(toml_table, key):

View File

@ -20,7 +20,7 @@ class StyleLearner:
"""
单个聊天室的表达风格学习器
学习从up_content到style的映射关系
支持动态管理风格集合最多2000个
支持动态管理风格集合无数量上限
"""
def __init__(self, chat_id: str, model_config: Optional[Dict] = None):
@ -37,7 +37,6 @@ class StyleLearner:
self.expressor = ExpressorModel(**self.model_config)
# 动态风格管理
self.max_styles = 2000 # 每个chat_id最多2000个风格
self.style_to_id: Dict[str, str] = {} # style文本 -> style_id
self.id_to_style: Dict[str, str] = {} # style_id -> style文本
self.id_to_situation: Dict[str, str] = {} # style_id -> situation文本
@ -68,11 +67,6 @@ class StyleLearner:
logger.debug(f"[{self.chat_id}] 风格 '{style}' 已存在")
return True
# 检查是否超过最大限制
if len(self.style_to_id) >= self.max_styles:
logger.warning(f"[{self.chat_id}] 已达到最大风格数量限制 ({self.max_styles})")
return False
# 生成新的style_id
style_id = f"style_{self.next_style_id}"
self.next_style_id += 1
@ -344,7 +338,6 @@ class StyleLearner:
"chat_id": self.chat_id,
"total_samples": self.learning_stats["total_samples"],
"style_count": len(self.style_to_id),
"max_styles": self.max_styles,
"style_counts": dict(self.learning_stats["style_counts"]),
"style_usage_frequency": dict(self.learning_stats["style_usage_frequency"]),
"last_update": self.learning_stats["last_update"],
@ -369,7 +362,6 @@ class StyleLearner:
"id_to_style": self.id_to_style,
"id_to_situation": self.id_to_situation,
"next_style_id": self.next_style_id,
"max_styles": self.max_styles,
"learning_stats": self.learning_stats
}
@ -413,7 +405,6 @@ class StyleLearner:
self.id_to_style = save_data["id_to_style"]
self.id_to_situation = save_data.get("id_to_situation", {}) # 兼容旧版本
self.next_style_id = save_data["next_style_id"]
self.max_styles = save_data.get("max_styles", 2000)
self.learning_stats = save_data["learning_stats"]
# 重新创建expressor并加载
@ -432,7 +423,7 @@ class StyleLearnerManager:
"""
多聊天室表达风格学习管理器
为每个chat_id维护独立的StyleLearner实例
每个chat_id可以动态管理自己的风格集合最多2000个
每个chat_id可以动态管理自己的风格集合无数量上限
"""
def __init__(self, model_save_path: str = "data/style_models"):

View File

@ -13,7 +13,7 @@ from src.common.logger import get_logger
from src.common.server import get_global_server, Server
from src.mood.mood_manager import mood_manager
from src.chat.knowledge import lpmm_start_up
from src.memory_system.memory_management_task import MemoryManagementTask
from src.memory_system.memory_management_task import MemoryManagementTask, MemoryConflictCleanupTask
from rich.traceback import install
# from src.api.main import start_api_server
@ -96,6 +96,10 @@ class MainSystem:
# 添加记忆管理任务
await async_task_manager.add_task(MemoryManagementTask())
logger.info("记忆管理任务已启动")
# 添加记忆冲突清理任务
await async_task_manager.add_task(MemoryConflictCleanupTask())
logger.info("记忆冲突清理任务已启动")
# await asyncio.sleep(0.5) #防止logger输出飞了

View File

@ -1,12 +1,13 @@
# -*- coding: utf-8 -*-
import asyncio
import random
import time
from typing import List
from src.manager.async_task_manager import AsyncTask
from src.memory_system.Memory_chest import global_memory_chest
from src.common.logger import get_logger
from src.common.database.database_model import MemoryChest as MemoryChestModel
from src.common.database.database_model import MemoryChest as MemoryChestModel, MemoryConflict
from src.config.config import global_config
logger = get_logger("memory")
@ -180,3 +181,61 @@ class MemoryManagementTask(AsyncTask):
except Exception as e:
logger.error(f"[记忆管理] 删除原始记忆时发生错误: {e}")
return 0
class MemoryConflictCleanupTask(AsyncTask):
"""记忆冲突清理定时任务
定期清理 memory_conflicts 表中 create_time 较早7天前 answer 为空的项目
默认每小时执行一次
"""
def __init__(self, cleanup_days: int = 7, run_interval: int = 3600):
"""
初始化清理任务
Args:
cleanup_days: 清理多少天前的记录默认7天
run_interval: 执行间隔默认3600秒1小时
"""
super().__init__(
task_name="Memory Conflict Cleanup Task",
wait_before_start=60, # 启动后等待60秒再开始
run_interval=run_interval
)
self.cleanup_days = cleanup_days
async def run(self):
"""执行清理任务"""
try:
current_time = time.time()
# 计算7天前的时间戳
cutoff_time = current_time - (self.cleanup_days * 24 * 60 * 60)
logger.info(f"[冲突清理] 开始清理 {self.cleanup_days} 天前且 answer 为空的冲突记录(截止时间: {cutoff_time}")
# 查询需要清理的记录create_time < cutoff_time 且 answer 为空
# answer 为空的条件answer IS NULL 或 answer == ''
query = MemoryConflict.select().where(
(MemoryConflict.create_time < cutoff_time) &
((MemoryConflict.answer.is_null()) | (MemoryConflict.answer == ''))
)
# 先统计要删除的数量
deleted_count = query.count()
# 批量删除
if deleted_count > 0:
deleted = MemoryConflict.delete().where(
(MemoryConflict.create_time < cutoff_time) &
((MemoryConflict.answer.is_null()) | (MemoryConflict.answer == ''))
).execute()
deleted_count = deleted
if deleted_count > 0:
logger.info(f"[冲突清理] 成功清理 {deleted_count} 条过期且未回答的冲突记录")
else:
logger.debug("[冲突清理] 没有需要清理的记录")
except Exception as e:
logger.error(f"[冲突清理] 执行清理任务时发生错误: {e}", exc_info=True)