refactor: 移除兴趣计算器相关代码和配置,优化系统管理插件

This commit is contained in:
Windpicker-owo
2025-12-12 14:38:15 +08:00
parent e6a4f855a2
commit 0193913841
11 changed files with 5 additions and 249 deletions

View File

@@ -34,7 +34,6 @@ MoFox_Bot 是基于 MaiCore 的增强型 QQ 聊天机器人,集成了 LLM、
- `PLUS_COMMAND`: 增强命令(支持参数解析、权限检查)
- `TOOL`: LLM 工具调用(函数调用集成)
- `EVENT_HANDLER`: 事件订阅处理器
- `INTEREST_CALCULATOR`: 兴趣值计算器
- `PROMPT`: 自定义提示词注入
**插件开发流程**:

View File

@@ -804,11 +804,6 @@ class AffinityFlowConfig(ValidatedConfigBase):
reply_action_interest_threshold: float = Field(default=0.4, description="回复动作兴趣阈值")
non_reply_action_interest_threshold: float = Field(default=0.2, description="非回复动作兴趣阈值")
# 语义兴趣度评分优化参数
use_batch_scoring: bool = Field(default=False, description="是否启用批处理评分模式,适合高频群聊场景")
batch_size: int = Field(default=8, ge=1, le=64, description="批处理大小,达到后立即处理")
batch_flush_interval_ms: float = Field(default=30.0, ge=10.0, le=200.0, description="批处理刷新间隔(毫秒),超过后强制处理")
# 回复决策系统参数
no_reply_threshold_adjustment: float = Field(default=0.1, description="不回复兴趣阈值调整值")
reply_cooldown_reduction: int = Field(default=2, description="回复后减少的不回复计数")

View File

@@ -33,7 +33,6 @@ from src.config.config import global_config
from src.individuality.individuality import Individuality, get_individuality
from src.manager.async_task_manager import async_task_manager
from src.mood.mood_manager import mood_manager
from src.plugin_system.base.base_interest_calculator import BaseInterestCalculator
from src.plugin_system.base.component_types import EventType
from src.plugin_system.core.event_manager import event_manager
from src.plugin_system.core.plugin_manager import plugin_manager
@@ -120,93 +119,6 @@ class MainSystem:
signal.signal(signal.SIGINT, signal_handler)
signal.signal(signal.SIGTERM, signal_handler)
async def _initialize_interest_calculator(self) -> None:
"""初始化兴趣值计算组件 - 通过插件系统自动发现和加载"""
try:
logger.debug("开始自动发现兴趣值计算组件...")
# 使用组件注册表自动发现兴趣计算器组件
interest_calculators = {}
try:
from src.plugin_system.apis.component_manage_api import get_components_info_by_type
from src.plugin_system.base.component_types import ComponentType
interest_calculators = get_components_info_by_type(ComponentType.INTEREST_CALCULATOR)
logger.debug(f"通过组件注册表发现 {len(interest_calculators)} 个兴趣计算器组件")
except Exception as e:
logger.error(f"从组件注册表获取兴趣计算器失败: {e}")
if not interest_calculators:
logger.warning("未发现任何兴趣计算器组件")
return
# 初始化兴趣度管理器
from src.chat.interest_system.interest_manager import get_interest_manager
interest_manager = get_interest_manager()
await interest_manager.initialize()
# 尝试注册所有可用的计算器
registered_calculators = []
for calc_name, calc_info in interest_calculators.items():
enabled = getattr(calc_info, "enabled", True)
default_enabled = getattr(calc_info, "enabled_by_default", True)
if not enabled or not default_enabled:
logger.debug(f"兴趣计算器 {calc_name} 未启用,跳过")
continue
try:
from src.plugin_system.base.component_types import ComponentType as CT
from src.plugin_system.core.component_registry import component_registry
component_class = component_registry.get_component_class(
calc_name, CT.INTEREST_CALCULATOR
)
if not component_class:
logger.warning(f"无法找到 {calc_name} 的组件类")
continue
logger.debug(f"成功获取 {calc_name} 的组件类: {component_class.__name__}")
# 确保组件是 BaseInterestCalculator 的子类
if not issubclass(component_class, BaseInterestCalculator):
logger.warning(f"{calc_name} 不是 BaseInterestCalculator 的有效子类")
continue
# 显式转换类型以修复 Pyright 错误
component_class = cast(type[BaseInterestCalculator], component_class)
# 创建组件实例
calculator_instance = component_class()
# 初始化组件
if not await calculator_instance.initialize():
logger.error(f"兴趣计算器 {calc_name} 初始化失败")
continue
# 注册到兴趣管理器
if await interest_manager.register_calculator(calculator_instance):
registered_calculators.append(calculator_instance)
logger.debug(f"成功注册兴趣计算器: {calc_name}")
else:
logger.error(f"兴趣计算器 {calc_name} 注册失败")
except Exception as e:
logger.error(f"处理兴趣计算器 {calc_name} 时出错: {e}")
if registered_calculators:
logger.debug(f"成功注册了 {len(registered_calculators)} 个兴趣计算器")
for calc in registered_calculators:
logger.debug(f" - {calc.component_name} v{calc.component_version}")
else:
logger.error("未能成功注册任何兴趣计算器")
except Exception as e:
logger.error(f"初始化兴趣度计算器失败: {e}")
async def _async_cleanup(self) -> None:
"""异步清理资源"""
if self._cleanup_started:
@@ -499,9 +411,6 @@ class MainSystem:
except Exception as e:
logger.error(f"三层记忆系统初始化失败: {e}")
# 初始化消息兴趣值计算组件
await self._initialize_interest_calculator()
# 初始化LPMM知识库
try:
from src.chat.knowledge.knowledge_lib import initialize_lpmm_knowledge

View File

@@ -11,7 +11,6 @@ if TYPE_CHECKING:
from src.common.data_models.database_data_model import DatabaseMessages
from src.common.logger import get_logger
from src.plugin_system.base.component_types import ComponentType, InterestCalculatorInfo
logger = get_logger("base_interest_calculator")
@@ -210,26 +209,6 @@ class BaseInterestCalculator(ABC):
return default
return current
@classmethod
def get_interest_calculator_info(cls) -> "InterestCalculatorInfo":
"""从类属性生成InterestCalculatorInfo
遵循BaseCommand和BaseAction的设计模式从类属性自动生成组件信息
Returns:
InterestCalculatorInfo: 生成的兴趣计算器信息对象
"""
name = getattr(cls, "component_name", cls.__name__.lower().replace("calculator", ""))
if "." in name:
logger.error(f"InterestCalculator名称 '{name}' 包含非法字符 '.',请使用下划线替代")
raise ValueError(f"InterestCalculator名称 '{name}' 包含非法字符 '.',请使用下划线替代")
return InterestCalculatorInfo(
name=name,
component_type=ComponentType.INTEREST_CALCULATOR,
description=getattr(cls, "component_description", cls.__doc__ or "兴趣度计算器"),
enabled_by_default=getattr(cls, "enabled_by_default", True),
)
def __repr__(self) -> str:
return (

View File

@@ -7,7 +7,6 @@ from src.plugin_system.base.component_types import (
CommandInfo,
ComponentType,
EventHandlerInfo,
InterestCalculatorInfo,
PlusCommandInfo,
PromptInfo,
ToolInfo,
@@ -17,7 +16,6 @@ from .base_action import BaseAction
from .base_adapter import BaseAdapter
from .base_command import BaseCommand
from .base_events_handler import BaseEventHandler
from .base_interest_calculator import BaseInterestCalculator
from .base_prompt import BasePrompt
from .base_tool import BaseTool
from .plugin_base import PluginBase
@@ -59,15 +57,6 @@ class BasePlugin(PluginBase):
logger.warning(f"Action组件 {component_class.__name__} 缺少 get_action_info 方法")
return None
elif component_type == ComponentType.INTEREST_CALCULATOR:
if hasattr(component_class, "get_interest_calculator_info"):
return component_class.get_interest_calculator_info()
else:
logger.warning(
f"InterestCalculator组件 {component_class.__name__} 缺少 get_interest_calculator_info 方法"
)
return None
elif component_type == ComponentType.PLUS_COMMAND:
# PlusCommand组件的get_info方法尚未实现
logger.warning("PlusCommand组件的get_info方法尚未实现")
@@ -123,7 +112,6 @@ class BasePlugin(PluginBase):
| tuple[PlusCommandInfo, type[PlusCommand]]
| tuple[EventHandlerInfo, type[BaseEventHandler]]
| tuple[ToolInfo, type[BaseTool]]
| tuple[InterestCalculatorInfo, type[BaseInterestCalculator]]
| tuple[PromptInfo, type[BasePrompt]]
]:
"""获取插件包含的组件列表

View File

@@ -48,7 +48,6 @@ class ComponentType(Enum):
SCHEDULER = "scheduler" # 定时任务组件(预留)
EVENT_HANDLER = "event_handler" # 事件处理组件
CHATTER = "chatter" # 聊天处理器组件
INTEREST_CALCULATOR = "interest_calculator" # 兴趣度计算组件
PROMPT = "prompt" # Prompt组件
ROUTER = "router" # 路由组件
ADAPTER = "adapter" # 适配器组件
@@ -298,17 +297,6 @@ class ChatterInfo(ComponentInfo):
self.component_type = ComponentType.CHATTER
@dataclass
class InterestCalculatorInfo(ComponentInfo):
"""兴趣度计算组件信息(单例模式)"""
enabled_by_default: bool = True # 是否默认启用
def __post_init__(self):
super().__post_init__()
self.component_type = ComponentType.INTEREST_CALCULATOR
@dataclass
class EventInfo(ComponentInfo):
"""事件组件信息"""

View File

@@ -17,7 +17,6 @@ from src.plugin_system.base.base_chatter import BaseChatter
from src.plugin_system.base.base_command import BaseCommand
from src.plugin_system.base.base_events_handler import BaseEventHandler
from src.plugin_system.base.base_http_component import BaseRouterComponent
from src.plugin_system.base.base_interest_calculator import BaseInterestCalculator
from src.plugin_system.base.base_prompt import BasePrompt
from src.plugin_system.base.base_tool import BaseTool
from src.plugin_system.base.component_types import (
@@ -28,7 +27,6 @@ from src.plugin_system.base.component_types import (
ComponentInfo,
ComponentType,
EventHandlerInfo,
InterestCalculatorInfo,
PluginInfo,
PlusCommandInfo,
PromptInfo,
@@ -48,7 +46,6 @@ ComponentClassType = (
| type[BaseEventHandler]
| type[PlusCommand]
| type[BaseChatter]
| type[BaseInterestCalculator]
| type[BasePrompt]
| type[BaseRouterComponent]
| type[BaseAdapter]
@@ -144,10 +141,6 @@ class ComponentRegistry:
self._chatter_registry: dict[str, type[BaseChatter]] = {}
self._enabled_chatter_registry: dict[str, type[BaseChatter]] = {}
# InterestCalculator 相关
self._interest_calculator_registry: dict[str, type[BaseInterestCalculator]] = {}
self._enabled_interest_calculator_registry: dict[str, type[BaseInterestCalculator]] = {}
# Prompt 相关
self._prompt_registry: dict[str, type[BasePrompt]] = {}
self._enabled_prompt_registry: dict[str, type[BasePrompt]] = {}
@@ -283,7 +276,6 @@ class ComponentRegistry:
ComponentType.TOOL: self._register_tool,
ComponentType.EVENT_HANDLER: self._register_event_handler,
ComponentType.CHATTER: self._register_chatter,
ComponentType.INTEREST_CALCULATOR: self._register_interest_calculator,
ComponentType.PROMPT: self._register_prompt,
ComponentType.ROUTER: self._register_router,
ComponentType.ADAPTER: self._register_adapter,
@@ -344,9 +336,6 @@ class ComponentRegistry:
case ComponentType.CHATTER:
self._chatter_registry.pop(component_name, None)
self._enabled_chatter_registry.pop(component_name, None)
case ComponentType.INTEREST_CALCULATOR:
self._interest_calculator_registry.pop(component_name, None)
self._enabled_interest_calculator_registry.pop(component_name, None)
case ComponentType.PROMPT:
self._prompt_registry.pop(component_name, None)
self._enabled_prompt_registry.pop(component_name, None)
@@ -497,25 +486,6 @@ class ComponentRegistry:
self._enabled_chatter_registry[info.name] = chatter_class
return True
def _register_interest_calculator(self, info: ComponentInfo, cls: ComponentClassType) -> bool:
"""
注册 InterestCalculator 组件到特定注册表。
Args:
info: InterestCalculator 组件的元数据信息
cls: InterestCalculator 组件的类定义
Returns:
注册成功返回 True
"""
calc_info = cast(InterestCalculatorInfo, info)
calc_class = cast(type[BaseInterestCalculator], cls)
_assign_plugin_attrs(calc_class, info.plugin_name, self.get_plugin_config(info.plugin_name) or {})
self._interest_calculator_registry[info.name] = calc_class
if calc_info.enabled:
self._enabled_interest_calculator_registry[info.name] = calc_class
return True
def _register_prompt(self, info: ComponentInfo, cls: ComponentClassType) -> bool:
"""
注册 Prompt 组件到 Prompt 特定注册表。
@@ -950,26 +920,6 @@ class ComponentRegistry:
info = self.get_component_info(chatter_name, ComponentType.CHATTER)
return info if isinstance(info, ChatterInfo) else None
# --- InterestCalculator ---
def get_interest_calculator_registry(self) -> dict[str, type[BaseInterestCalculator]]:
"""获取所有已注册的 InterestCalculator 类。"""
return self._interest_calculator_registry.copy()
def get_enabled_interest_calculator_registry(self) -> dict[str, type[BaseInterestCalculator]]:
"""
获取所有已启用的 InterestCalculator 类。
会检查组件的全局启用状态。
Returns:
可用的 InterestCalculator 名称到类的字典
"""
return {
name: cls
for name, cls in self._interest_calculator_registry.items()
if self.is_component_available(name, ComponentType.INTEREST_CALCULATOR)
}
# --- Prompt ---
def get_prompt_registry(self) -> dict[str, type[BasePrompt]]:
"""获取所有已注册的 Prompt 类。"""

View File

@@ -110,8 +110,6 @@ class ComponentStateManager:
)
case ComponentType.CHATTER:
self._registry._enabled_chatter_registry[component_name] = target_class # type: ignore
case ComponentType.INTEREST_CALCULATOR:
self._registry._enabled_interest_calculator_registry[component_name] = target_class # type: ignore
case ComponentType.PROMPT:
self._registry._enabled_prompt_registry[component_name] = target_class # type: ignore
case ComponentType.ADAPTER:
@@ -161,8 +159,6 @@ class ComponentStateManager:
event_manager.remove_event_handler(component_name)
case ComponentType.CHATTER:
self._registry._enabled_chatter_registry.pop(component_name, None)
case ComponentType.INTEREST_CALCULATOR:
self._registry._enabled_interest_calculator_registry.pop(component_name, None)
case ComponentType.PROMPT:
self._registry._enabled_prompt_registry.pop(component_name, None)
case ComponentType.ADAPTER:

View File

@@ -54,12 +54,6 @@ class AffinityInterestCalculator(BaseInterestCalculator):
self._semantic_initialized = False # 防止重复初始化
self.model_manager = None
# 批处理队列(高频场景优化)
self._batch_queue = None
self._use_batch_queue = getattr(global_config.affinity_flow, 'use_batch_scoring', False)
self._batch_size = getattr(global_config.affinity_flow, 'batch_size', 8)
self._batch_flush_interval_ms = getattr(global_config.affinity_flow, 'batch_flush_interval_ms', 30.0)
# 评分阈值
self.reply_threshold = affinity_config.reply_action_interest_threshold # 回复动作兴趣阈值
self.mention_threshold = affinity_config.mention_bot_adjustment_threshold # 提及bot后的调整阈值
@@ -89,7 +83,6 @@ class AffinityInterestCalculator(BaseInterestCalculator):
logger.info(f" - 权重配置: {self.score_weights}")
logger.info(f" - 回复阈值: {self.reply_threshold}")
logger.info(f" - 语义评分: {self.use_semantic_scoring} (TF-IDF + Logistic Regression + FastScorer优化)")
logger.info(f" - 批处理队列: {self._use_batch_queue}")
logger.info(f" - 回复后连续对话: {self.enable_post_reply_boost}")
logger.info(f" - 回复冷却减少: {self.reply_cooldown_reduction}")
logger.info(f" - 最大不回复计数: {self.max_no_reply_count}")
@@ -345,21 +338,7 @@ class AffinityInterestCalculator(BaseInterestCalculator):
)
self.semantic_scorer = scorer
# 如果启用批处理队列模式
if self._use_batch_queue:
from src.chat.semantic_interest.optimized_scorer import BatchScoringQueue
# 确保 scorer 有 FastScorer
if scorer._fast_scorer is not None:
self._batch_queue = BatchScoringQueue(
scorer=scorer._fast_scorer,
batch_size=self._batch_size,
flush_interval_ms=self._batch_flush_interval_ms
)
await self._batch_queue.start()
logger.info(f"[语义评分] 批处理队列已启动 (batch_size={self._batch_size}, interval={self._batch_flush_interval_ms}ms)")
logger.info("[语义评分] 语义兴趣度评分器初始化成功FastScorer优化 + 单例)")
# 设置初始化标志
@@ -467,12 +446,7 @@ class AffinityInterestCalculator(BaseInterestCalculator):
return 0.0
try:
# 优先使用批处理队列(高频场景优化)
if self._batch_queue is not None:
score = await self._batch_queue.score(content)
else:
# 使用优化后的异步评分方法FastScorer + 超时保护)
score = await self.semantic_scorer.score_async(content, timeout=2.0)
score = await self.semantic_scorer.score_async(content, timeout=2.0)
logger.debug(f"[语义评分] 内容: '{content[:50]}...' -> 分数: {score:.3f}")
return score
@@ -489,28 +463,13 @@ class AffinityInterestCalculator(BaseInterestCalculator):
logger.info("[语义评分] 开始重新加载模型...")
# 停止旧的批处理队列
if self._batch_queue is not None:
await self._batch_queue.stop()
self._batch_queue = None
# 检查人设是否变化
if hasattr(self, 'model_manager') and self.model_manager:
persona_info = self._get_current_persona_info()
reloaded = await self.model_manager.check_and_reload_for_persona(persona_info)
if reloaded:
self.semantic_scorer = self.model_manager.get_scorer()
# 重新创建批处理队列
if self._use_batch_queue and self.semantic_scorer._fast_scorer is not None:
from src.chat.semantic_interest.optimized_scorer import BatchScoringQueue
self._batch_queue = BatchScoringQueue(
scorer=self.semantic_scorer._fast_scorer,
batch_size=self._batch_size,
flush_interval_ms=self._batch_flush_interval_ms
)
await self._batch_queue.start()
logger.info("[语义评分] 模型重载完成(人设已更新)")
else:
logger.info("[语义评分] 人设未变化,无需重载")

View File

@@ -619,7 +619,6 @@ class SystemCommand(PlusCommand):
# 禁用保护
if not enabled:
protected_types = [
ComponentType.INTEREST_CALCULATOR,
ComponentType.PROMPT,
ComponentType.ROUTER,
]
@@ -736,7 +735,6 @@ class SystemCommand(PlusCommand):
if not enabled: # 如果是禁用操作
# 定义不可禁用的核心组件类型
protected_types = [
ComponentType.INTEREST_CALCULATOR,
ComponentType.PROMPT,
ComponentType.ROUTER,
]

View File

@@ -537,13 +537,8 @@ s4u_blacklist_chats = []
[affinity_flow]
enable_normal_mode = true # 是否启用 Normal 聊天模式。启用后,在专注模式回复后会自动切换,并根据兴趣度决定是否回复,以实现更快速的回复。
# 兴趣评分系统参数
reply_action_interest_threshold = 0.75 # 回复动作兴趣阈值
non_reply_action_interest_threshold = 0.65 # 非回复动作兴趣阈值
# 语义兴趣度评分优化参数
use_batch_scoring = true # 是否启用批处理评分模式,适合高频群聊场景
batch_size = 3 # 批处理大小,达到后立即处理
batch_flush_interval_ms = 30.0 # 批处理刷新间隔(毫秒),超过后强制处理
reply_action_interest_threshold = 0.7 # 回复动作兴趣阈值
non_reply_action_interest_threshold = 0.6 # 非回复动作兴趣阈值
# 回复决策系统参数
no_reply_threshold_adjustment = 0.02 # 不回复兴趣阈值调整值