fix:优化禁言插件,优化表达参数

This commit is contained in:
SengokuCola
2025-06-25 23:14:05 +08:00
parent a0d714334a
commit f3f8efb07e
8 changed files with 101 additions and 10 deletions

View File

@@ -1,7 +1,7 @@
# Changelog # Changelog
## [0.8.0] - 2025-1-6 ## [0.8.0] - 2025-1-6
重大升级!插件系统全面重构,表达方式系统大幅优化 重大升级!插件系统全面重构,表达方式系统大幅优化focus大幅降低token花费和反应速度加入了人物印象系统麦麦可以记住群友的特点。支持更精细的分群聊天频率控制normal模式可以使用planner和action
MaiBot 0.8.0 重磅升级插件系统全面重构支持更强大的扩展能力表达方式系统大幅优化支持智能学习和衰减机制聊天频率控制更加精细支持时段化管理HFC系统性能大幅提升处理器后置化减少消耗关系系统升级支持即时构建和人物侧写日志系统重构使用structlog大量稳定性修复和性能优化。 MaiBot 0.8.0 重磅升级插件系统全面重构支持更强大的扩展能力表达方式系统大幅优化支持智能学习和衰减机制聊天频率控制更加精细支持时段化管理HFC系统性能大幅提升处理器后置化减少消耗关系系统升级支持即时构建和人物侧写日志系统重构使用structlog大量稳定性修复和性能优化。

View File

@@ -213,3 +213,4 @@ def analyze_expressions():
if __name__ == "__main__": if __name__ == "__main__":
analyze_expressions() analyze_expressions()

View File

@@ -194,3 +194,4 @@ def analyze_group_similarity():
if __name__ == "__main__": if __name__ == "__main__":
analyze_group_similarity() analyze_group_similarity()

View File

@@ -148,7 +148,7 @@ class ExpressionSelector:
expr["count"] = new_count expr["count"] = new_count
expr["last_active_time"] = time.time() expr["last_active_time"] = time.time()
# logger.info(f"表达方式激活: 原count={current_count:.2f}, 增量={increment}, 新count={new_count:.2f}") logger.info(f"表达方式激活: 原count={current_count:.3f}, 增量={increment}, 新count={new_count:.3f}")
break break
# 保存更新后的文件 # 保存更新后的文件
@@ -238,7 +238,7 @@ class ExpressionSelector:
valid_expressions.append(expression) valid_expressions.append(expression)
# 对选中的表达方式count数+0.1 # 对选中的表达方式count数+0.1
self.update_expression_count(chat_id, expression, 0.0001) self.update_expression_count(chat_id, expression, 0.001)
# logger.info(f"LLM从{len(all_expressions)}个情境中选择了{len(valid_expressions)}个") # logger.info(f"LLM从{len(all_expressions)}个情境中选择了{len(valid_expressions)}个")
return valid_expressions return valid_expressions

View File

@@ -112,6 +112,13 @@ class HeartFChatting:
self.memory_activator = MemoryActivator() self.memory_activator = MemoryActivator()
# 新增:消息计数器和疲惫阈值
self._message_count = 0 # 发送的消息计数
# 基于exit_focus_threshold动态计算疲惫阈值
# 基础值30条通过exit_focus_threshold调节threshold越小越容易疲惫
self._message_threshold = max(10, int(30 * global_config.chat.exit_focus_threshold))
self._fatigue_triggered = False # 是否已触发疲惫退出
# 初始化观察器 # 初始化观察器
self.observations: List[Observation] = [] self.observations: List[Observation] = []
self._register_observations() self._register_observations()
@@ -177,6 +184,8 @@ class HeartFChatting:
actual_version = performance_version or get_hfc_version() actual_version = performance_version or get_hfc_version()
self.performance_logger = HFCPerformanceLogger(chat_id, actual_version) self.performance_logger = HFCPerformanceLogger(chat_id, actual_version)
logger.info(f"{self.log_prefix} HeartFChatting 初始化完成,消息疲惫阈值: {self._message_threshold}基于exit_focus_threshold={global_config.chat.exit_focus_threshold}计算仅在auto模式下生效")
def _register_observations(self): def _register_observations(self):
"""注册所有观察器""" """注册所有观察器"""
self.observations = [] # 清空已有的 self.observations = [] # 清空已有的
@@ -289,6 +298,9 @@ class HeartFChatting:
return return
try: try:
# 重置消息计数器开始新的focus会话
self.reset_message_count()
# 标记为活动状态,防止重复启动 # 标记为活动状态,防止重复启动
self._loop_active = True self._loop_active = True
@@ -1164,6 +1176,24 @@ class HeartFChatting:
command = action_data["_system_command"] command = action_data["_system_command"]
logger.debug(f"{self.log_prefix} 从action_data中获取系统命令: {command}") logger.debug(f"{self.log_prefix} 从action_data中获取系统命令: {command}")
# 新增:消息计数和疲惫检查
if action == "reply" and success:
self._message_count += 1
current_threshold = self._get_current_fatigue_threshold()
logger.info(f"{self.log_prefix} 已发送第 {self._message_count} 条消息(动态阈值: {current_threshold}, exit_focus_threshold: {global_config.chat.exit_focus_threshold}")
# 检查是否达到疲惫阈值只有在auto模式下才会自动退出
if (global_config.chat.chat_mode == "auto" and
self._message_count >= current_threshold and
not self._fatigue_triggered):
self._fatigue_triggered = True
logger.info(f"{self.log_prefix} [auto模式] 已发送 {self._message_count} 条消息,达到疲惫阈值 {current_threshold},麦麦感到疲惫了,准备退出专注聊天模式")
# 设置系统命令,在下次循环检查时触发退出
command = "stop_focus_chat"
elif (self._message_count >= current_threshold and
global_config.chat.chat_mode != "auto"):
logger.info(f"{self.log_prefix} [非auto模式] 已发送 {self._message_count} 条消息,达到疲惫阈值 {current_threshold}但非auto模式不会自动退出")
logger.debug(f"{self.log_prefix} 麦麦执行了'{action}', 返回结果'{success}', '{reply_text}', '{command}'") logger.debug(f"{self.log_prefix} 麦麦执行了'{action}', 返回结果'{success}', '{reply_text}', '{command}'")
return success, reply_text, command return success, reply_text, command
@@ -1173,11 +1203,45 @@ class HeartFChatting:
traceback.print_exc() traceback.print_exc()
return False, "", "" return False, "", ""
def _get_current_fatigue_threshold(self) -> int:
"""动态获取当前的疲惫阈值基于exit_focus_threshold配置
Returns:
int: 当前的疲惫阈值
"""
return max(10, int(30 / global_config.chat.exit_focus_threshold))
def get_message_count_info(self) -> dict:
"""获取消息计数信息
Returns:
dict: 包含消息计数信息的字典
"""
current_threshold = self._get_current_fatigue_threshold()
return {
"current_count": self._message_count,
"threshold": current_threshold,
"fatigue_triggered": self._fatigue_triggered,
"remaining": max(0, current_threshold - self._message_count)
}
def reset_message_count(self):
"""重置消息计数器用于重新启动focus模式时"""
self._message_count = 0
self._fatigue_triggered = False
logger.info(f"{self.log_prefix} 消息计数器已重置")
async def shutdown(self): async def shutdown(self):
"""优雅关闭HeartFChatting实例取消活动循环任务""" """优雅关闭HeartFChatting实例取消活动循环任务"""
logger.info(f"{self.log_prefix} 正在关闭HeartFChatting...") logger.info(f"{self.log_prefix} 正在关闭HeartFChatting...")
self._shutting_down = True # <-- 在开始关闭时设置标志位 self._shutting_down = True # <-- 在开始关闭时设置标志位
# 记录最终的消息统计
if self._message_count > 0:
logger.info(f"{self.log_prefix} 本次focus会话共发送了 {self._message_count} 条消息")
if self._fatigue_triggered:
logger.info(f"{self.log_prefix} 因疲惫而退出focus模式")
# 取消循环任务 # 取消循环任务
if self._loop_task and not self._loop_task.done(): if self._loop_task and not self._loop_task.done():
logger.info(f"{self.log_prefix} 正在取消HeartFChatting循环任务") logger.info(f"{self.log_prefix} 正在取消HeartFChatting循环任务")
@@ -1206,6 +1270,9 @@ class HeartFChatting:
except Exception as e: except Exception as e:
logger.warning(f"{self.log_prefix} 完成性能统计时出错: {e}") logger.warning(f"{self.log_prefix} 完成性能统计时出错: {e}")
# 重置消息计数器,为下次启动做准备
self.reset_message_count()
logger.info(f"{self.log_prefix} HeartFChatting关闭完成") logger.info(f"{self.log_prefix} HeartFChatting关闭完成")
def get_cycle_history(self, last_n: Optional[int] = None) -> List[Dict[str, Any]]: def get_cycle_history(self, last_n: Optional[int] = None) -> List[Dict[str, Any]]:

View File

@@ -327,7 +327,7 @@ class NoReplyAction(BaseAction):
# 使用 utils_small 模型 # 使用 utils_small 模型
small_model = getattr(available_models, "utils_small", None) small_model = getattr(available_models, "utils_small", None)
print(judge_prompt) logger.debug(judge_prompt)
if small_model: if small_model:
# 使用小模型进行判断 # 使用小模型进行判断

View File

@@ -117,7 +117,7 @@ class EmojiAction(BaseAction):
normal_activation_type = ActionActivationType.RANDOM normal_activation_type = ActionActivationType.RANDOM
mode_enable = ChatMode.ALL mode_enable = ChatMode.ALL
parallel_action = True parallel_action = True
random_activation_probability = 0.1 # 默认值,可通过配置覆盖 random_activation_probability = 0.2 # 默认值,可通过配置覆盖
# 动作基本信息 # 动作基本信息
action_name = "emoji" action_name = "emoji"

View File

@@ -125,10 +125,6 @@ class MuteAction(BaseAction):
# 首先检查群组权限 # 首先检查群组权限
has_permission, permission_error = self._check_group_permission() has_permission, permission_error = self._check_group_permission()
if not has_permission:
logger.error(f"{self.log_prefix} 权限检查失败: {permission_error}")
# 不发送错误消息,静默拒绝
return False, permission_error
# 获取参数 # 获取参数
target = self.action_data.get("target") target = self.action_data.get("target")
@@ -191,6 +187,32 @@ class MuteAction(BaseAction):
# 获取模板化消息 # 获取模板化消息
message = self._get_template_message(target, time_str, reason) message = self._get_template_message(target, time_str, reason)
if not has_permission:
logger.warning(f"{self.log_prefix} 权限检查失败: {permission_error}")
result_status, result_message = await generator_api.rewrite_reply(
chat_stream=self.chat_stream,
reply_data={
"raw_reply": "我想禁言{target},但是我没有权限",
"reason": "表达自己没有在这个群禁言的能力",
},
)
if result_status:
for reply_seg in result_message:
data = reply_seg[1]
await self.send_text(data)
await self.store_action_info(
action_build_into_prompt=True,
action_prompt_display=f"尝试禁言了用户 {target},但是没有权限,无法禁言",
action_done=True,
)
# 不发送错误消息,静默拒绝
return False, permission_error
result_status, result_message = await generator_api.rewrite_reply( result_status, result_message = await generator_api.rewrite_reply(
chat_stream=self.chat_stream, chat_stream=self.chat_stream,
reply_data={ reply_data={