feat(chat): 重构消息打断系统为线性概率模型

将复杂的指数衰减概率模型简化为线性概率模型,提高可预测性和可配置性

- 新增最低打断概率配置,确保始终有打断机会
- 移除复杂的概率因子计算,改用简单的线性递减公式
- 增加最大打断次数默认值从3提升到10
- 保留废弃配置项以确保向后兼容
- 更新配置模板和文档说明新的概率计算方式
This commit is contained in:
Windpicker-owo
2025-10-07 13:21:33 +08:00
parent 150c026434
commit 76713bf727
4 changed files with 46 additions and 23 deletions

View File

@@ -339,9 +339,9 @@ class MessageManager:
processing_task = self.chatter_manager.get_processing_task(chat_stream.stream_id) processing_task = self.chatter_manager.get_processing_task(chat_stream.stream_id)
if processing_task and not processing_task.done(): if processing_task and not processing_task.done():
# 计算打断概率 # 计算打断概率 - 使用新的线性概率模型
interruption_probability = chat_stream.context_manager.context.calculate_interruption_probability( interruption_probability = chat_stream.context_manager.context.calculate_interruption_probability(
global_config.chat.interruption_max_limit, global_config.chat.interruption_probability_factor global_config.chat.interruption_max_limit
) )
# 检查是否已达到最大打断次数 # 检查是否已达到最大打断次数

View File

@@ -92,26 +92,37 @@ class StreamContext(BaseDataModel):
recent_history = self.history_messages[-limit:] if len(self.history_messages) > limit else self.history_messages recent_history = self.history_messages[-limit:] if len(self.history_messages) > limit else self.history_messages
return recent_history return recent_history
def calculate_interruption_probability(self, max_limit: int, probability_factor: float) -> float: def calculate_interruption_probability(self, max_limit: int, min_probability: float = 0.1, probability_factor: float | None = None) -> float:
"""计算打断概率""" """计算打断概率 - 使用简单线性概率模型
Args:
max_limit: 最大打断次数
min_probability: 最低打断概率
probability_factor: 已废弃的参数,保留是为了向后兼容,不再使用
Returns:
float: 打断概率 (0.0 - 1.0)
"""
if max_limit <= 0: if max_limit <= 0:
return 0.0 return 0.0
# 计算打断比例
interruption_ratio = self.interruption_count / max_limit
# 如果已达到或超过最大次数,完全禁止打断 # 如果已达到或超过最大次数,完全禁止打断
if self.interruption_count >= max_limit: if self.interruption_count >= max_limit:
return 0.0 return 0.0
# 如果超过概率因子,概率下降 # 线性概率计算:次数越多,概率越低
if interruption_ratio > probability_factor: # 公式:概率 = max(min_probability, 1.0 - (当前打断次数 / 最大打断次数))
# 使用指数衰减,超过限制越多,概率越低 # 这确保了:
excess_ratio = interruption_ratio - probability_factor # - 第1次打断90% 概率 (如果min_probability=0.1, max_limit=10)
probability = 0.8 * (0.5**excess_ratio) # 基础概率0.8,指数衰减 # - 第2次打断80% 概率
else: # - ...
# 在限制内,保持较高概率 # - 第9次打断10% 概率 (等于min_probability)
probability = 0.8 # - 第10次打断0% 概率 (达到上限)
probability = 1.0 - (self.interruption_count / max_limit)
# 设置最低概率,确保始终有打断的可能性
probability = max(min_probability, probability)
return max(0.0, min(1.0, probability)) return max(0.0, min(1.0, probability))

View File

@@ -126,14 +126,21 @@ class ChatConfig(ValidatedConfigBase):
timestamp_display_mode: Literal["normal", "normal_no_YMD", "relative"] = Field( timestamp_display_mode: Literal["normal", "normal_no_YMD", "relative"] = Field(
default="normal_no_YMD", description="时间戳显示模式" default="normal_no_YMD", description="时间戳显示模式"
) )
# 消息打断系统配置 # 消息打断系统配置 - 线性概率模型
interruption_enabled: bool = Field(default=True, description="是否启用消息打断系统") interruption_enabled: bool = Field(default=True, description="是否启用消息打断系统")
interruption_max_limit: int = Field(default=3, ge=0, description="每个聊天流的最大打断次数") interruption_max_limit: int = Field(default=10, ge=0, description="每个聊天流的最大打断次数")
interruption_probability_factor: float = Field( interruption_min_probability: float = Field(
default=0.8, ge=0.0, le=1.0, description="打断概率因子,当前打断次数/最大打断次数超过此值时触发概率下降" default=0.1, ge=0.0, le=1.0, description="最低打断概率(即使达到较高打断次数,也保证有此概率的打断机会)"
) )
interruption_afc_reduction: float = Field(default=0.05, ge=0.0, le=1.0, description="每次连续打断降低的afc阈值数值") interruption_afc_reduction: float = Field(default=0.05, ge=0.0, le=1.0, description="每次连续打断降低的afc阈值数值")
# DEPRECATED: interruption_probability_factor (已废弃的配置项)
# 新的线性概率模型不再需要复杂的概率因子
# 保留此字段是为了向后兼容,现有配置文件不会报错
interruption_probability_factor: float = Field(
default=0.8, ge=0.0, le=1.0, description="[已废弃] 打断概率因子,新线性概率模型不再使用此参数"
)
# 动态消息分发系统配置 # 动态消息分发系统配置
dynamic_distribution_enabled: bool = Field(default=True, description="是否启用动态消息分发周期调整") dynamic_distribution_enabled: bool = Field(default=True, description="是否启用动态消息分发周期调整")
dynamic_distribution_base_interval: float = Field(default=5.0, ge=1.0, le=60.0, description="基础分发间隔(秒)") dynamic_distribution_base_interval: float = Field(default=5.0, ge=1.0, le=60.0, description="基础分发间隔(秒)")

View File

@@ -1,5 +1,5 @@
[inner] [inner]
version = "7.2.3" version = "7.2.4"
#----以下是给开发人员阅读的如果你只是部署了MoFox-Bot不需要阅读---- #----以下是给开发人员阅读的如果你只是部署了MoFox-Bot不需要阅读----
#如果你想要修改配置文件请递增version的值 #如果你想要修改配置文件请递增version的值
@@ -122,12 +122,17 @@ allow_reply_self = false # 是否允许回复自己说的话
max_context_size = 25 # 上下文长度 max_context_size = 25 # 上下文长度
thinking_timeout = 40 # MoFox-Bot一次回复最长思考规划时间超过这个时间的思考会放弃往往是api反应太慢 thinking_timeout = 40 # MoFox-Bot一次回复最长思考规划时间超过这个时间的思考会放弃往往是api反应太慢
# 消息打断系统配置 # 消息打断系统配置 - 线性概率模型
interruption_enabled = true # 是否启用消息打断系统 interruption_enabled = true # 是否启用消息打断系统
interruption_max_limit = 3 # 每个聊天流的最大打断次数 interruption_max_limit = 10 # 每个聊天流的最大打断次数
interruption_probability_factor = 0.8 # 打断概率因子,当前打断次数/最大打断次数超过此值时触发概率下降 interruption_min_probability = 0.1 # 最低打断概率(即使达到较高打断次数,也保证有此概率的打断机会)
interruption_afc_reduction = 0.05 # 每次连续打断降低的afc阈值数值 interruption_afc_reduction = 0.05 # 每次连续打断降低的afc阈值数值
# DEPRECATED: interruption_probability_factor (已废弃的配置项)
# 新的线性概率模型不再需要复杂的概率因子
# 公式:打断概率 = max(最低概率, 1.0 - (当前打断次数 / 最大打断次数))
# interruption_probability_factor = 0.8 # 此配置已废弃,请删除
# 动态消息分发系统配置 # 动态消息分发系统配置
dynamic_distribution_enabled = true # 是否启用动态消息分发周期调整 dynamic_distribution_enabled = true # 是否启用动态消息分发周期调整
dynamic_distribution_base_interval = 5.0 # 基础分发间隔(秒) dynamic_distribution_base_interval = 5.0 # 基础分发间隔(秒)