Backup before system reinstall
This commit is contained in:
@@ -0,0 +1,929 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Human干预系统
|
||||
监控辩论健康度并在必要时触发人工干预
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
import json
|
||||
import logging
|
||||
from typing import Dict, List, Any, Optional, Callable, Tuple
|
||||
from dataclasses import dataclass, field
|
||||
from enum import Enum
|
||||
from datetime import datetime, timedelta
|
||||
import statistics
|
||||
import re
|
||||
|
||||
class HealthStatus(Enum):
|
||||
"""健康状态"""
|
||||
EXCELLENT = "优秀" # 90-100分
|
||||
GOOD = "良好" # 70-89分
|
||||
FAIR = "一般" # 50-69分
|
||||
POOR = "较差" # 30-49分
|
||||
CRITICAL = "危险" # 0-29分
|
||||
|
||||
class InterventionLevel(Enum):
|
||||
"""干预级别"""
|
||||
NONE = (0, "无需干预")
|
||||
GENTLE_REMINDER = (1, "温和提醒")
|
||||
MODERATE_GUIDANCE = (2, "适度引导")
|
||||
STRONG_INTERVENTION = (3, "强力干预")
|
||||
EMERGENCY_STOP = (4, "紧急停止")
|
||||
|
||||
def __init__(self, level, description):
|
||||
self.level = level
|
||||
self.description = description
|
||||
|
||||
@property
|
||||
def value(self):
|
||||
return self.description
|
||||
|
||||
def __ge__(self, other):
|
||||
if isinstance(other, InterventionLevel):
|
||||
return self.level >= other.level
|
||||
return NotImplemented
|
||||
|
||||
def __gt__(self, other):
|
||||
if isinstance(other, InterventionLevel):
|
||||
return self.level > other.level
|
||||
return NotImplemented
|
||||
|
||||
def __le__(self, other):
|
||||
if isinstance(other, InterventionLevel):
|
||||
return self.level <= other.level
|
||||
return NotImplemented
|
||||
|
||||
def __lt__(self, other):
|
||||
if isinstance(other, InterventionLevel):
|
||||
return self.level < other.level
|
||||
return NotImplemented
|
||||
|
||||
class AlertType(Enum):
|
||||
"""警报类型"""
|
||||
QUALITY_DECLINE = "质量下降"
|
||||
TOXIC_BEHAVIOR = "有害行为"
|
||||
REPETITIVE_CONTENT = "重复内容"
|
||||
OFF_TOPIC = "偏离主题"
|
||||
EMOTIONAL_ESCALATION = "情绪升级"
|
||||
PARTICIPATION_IMBALANCE = "参与不平衡"
|
||||
TECHNICAL_ERROR = "技术错误"
|
||||
TIME_VIOLATION = "时间违规"
|
||||
|
||||
@dataclass
|
||||
class HealthMetric:
|
||||
"""健康指标"""
|
||||
name: str
|
||||
value: float
|
||||
weight: float
|
||||
threshold_critical: float
|
||||
threshold_poor: float
|
||||
threshold_fair: float
|
||||
threshold_good: float
|
||||
description: str
|
||||
last_updated: datetime = field(default_factory=datetime.now)
|
||||
|
||||
@dataclass
|
||||
class InterventionAlert:
|
||||
"""干预警报"""
|
||||
id: str
|
||||
alert_type: AlertType
|
||||
severity: InterventionLevel
|
||||
message: str
|
||||
affected_participants: List[str]
|
||||
metrics: Dict[str, float]
|
||||
timestamp: datetime
|
||||
resolved: bool = False
|
||||
resolution_notes: str = ""
|
||||
human_notified: bool = False
|
||||
|
||||
@dataclass
|
||||
class InterventionAction:
|
||||
"""干预动作"""
|
||||
id: str
|
||||
action_type: str
|
||||
description: str
|
||||
target_participants: List[str]
|
||||
parameters: Dict[str, Any]
|
||||
executed_at: datetime
|
||||
success: bool = False
|
||||
result_message: str = ""
|
||||
|
||||
class DebateHealthMonitor:
|
||||
"""辩论健康度监控器"""
|
||||
|
||||
def __init__(self):
|
||||
self.health_metrics: Dict[str, HealthMetric] = {}
|
||||
self.active_alerts: List[InterventionAlert] = []
|
||||
self.intervention_history: List[InterventionAction] = []
|
||||
self.monitoring_enabled = True
|
||||
self.logger = logging.getLogger(__name__)
|
||||
|
||||
# 初始化健康指标
|
||||
self._initialize_health_metrics()
|
||||
|
||||
# 事件处理器
|
||||
self.event_handlers: Dict[str, List[Callable]] = {}
|
||||
|
||||
# 监控配置
|
||||
self.monitoring_config = {
|
||||
"check_interval_seconds": 30,
|
||||
"alert_cooldown_minutes": 5,
|
||||
"auto_intervention_enabled": True,
|
||||
"human_notification_threshold": InterventionLevel.STRONG_INTERVENTION
|
||||
}
|
||||
|
||||
def _initialize_health_metrics(self):
|
||||
"""初始化健康指标"""
|
||||
metrics_config = [
|
||||
{
|
||||
"name": "content_quality",
|
||||
"weight": 0.25,
|
||||
"thresholds": {"critical": 20, "poor": 40, "fair": 60, "good": 80},
|
||||
"description": "内容质量评分"
|
||||
},
|
||||
{
|
||||
"name": "participation_balance",
|
||||
"weight": 0.20,
|
||||
"thresholds": {"critical": 30, "poor": 50, "fair": 70, "good": 85},
|
||||
"description": "参与平衡度"
|
||||
},
|
||||
{
|
||||
"name": "emotional_stability",
|
||||
"weight": 0.20,
|
||||
"thresholds": {"critical": 25, "poor": 45, "fair": 65, "good": 80},
|
||||
"description": "情绪稳定性"
|
||||
},
|
||||
{
|
||||
"name": "topic_relevance",
|
||||
"weight": 0.15,
|
||||
"thresholds": {"critical": 35, "poor": 55, "fair": 70, "good": 85},
|
||||
"description": "主题相关性"
|
||||
},
|
||||
{
|
||||
"name": "interaction_civility",
|
||||
"weight": 0.10,
|
||||
"thresholds": {"critical": 20, "poor": 40, "fair": 60, "good": 80},
|
||||
"description": "互动文明度"
|
||||
},
|
||||
{
|
||||
"name": "technical_stability",
|
||||
"weight": 0.10,
|
||||
"thresholds": {"critical": 40, "poor": 60, "fair": 75, "good": 90},
|
||||
"description": "技术稳定性"
|
||||
}
|
||||
]
|
||||
|
||||
for config in metrics_config:
|
||||
metric = HealthMetric(
|
||||
name=config["name"],
|
||||
value=100.0, # 初始值
|
||||
weight=config["weight"],
|
||||
threshold_critical=config["thresholds"]["critical"],
|
||||
threshold_poor=config["thresholds"]["poor"],
|
||||
threshold_fair=config["thresholds"]["fair"],
|
||||
threshold_good=config["thresholds"]["good"],
|
||||
description=config["description"]
|
||||
)
|
||||
self.health_metrics[config["name"]] = metric
|
||||
|
||||
async def analyze_debate_health(self, debate_data: Dict[str, Any]) -> Tuple[float, HealthStatus]:
|
||||
"""分析辩论健康度"""
|
||||
if not self.monitoring_enabled:
|
||||
return 100.0, HealthStatus.EXCELLENT
|
||||
|
||||
# 更新各项健康指标
|
||||
await self._update_content_quality(debate_data)
|
||||
await self._update_participation_balance(debate_data)
|
||||
await self._update_emotional_stability(debate_data)
|
||||
await self._update_topic_relevance(debate_data)
|
||||
await self._update_interaction_civility(debate_data)
|
||||
await self._update_technical_stability(debate_data)
|
||||
|
||||
# 计算综合健康分数
|
||||
total_score = 0.0
|
||||
total_weight = 0.0
|
||||
|
||||
for metric in self.health_metrics.values():
|
||||
total_score += metric.value * metric.weight
|
||||
total_weight += metric.weight
|
||||
|
||||
overall_score = total_score / total_weight if total_weight > 0 else 0.0
|
||||
|
||||
# 确定健康状态
|
||||
if overall_score >= 90:
|
||||
status = HealthStatus.EXCELLENT
|
||||
elif overall_score >= 70:
|
||||
status = HealthStatus.GOOD
|
||||
elif overall_score >= 50:
|
||||
status = HealthStatus.FAIR
|
||||
elif overall_score >= 30:
|
||||
status = HealthStatus.POOR
|
||||
else:
|
||||
status = HealthStatus.CRITICAL
|
||||
|
||||
# 检查是否需要发出警报
|
||||
await self._check_for_alerts(overall_score, status)
|
||||
|
||||
self.logger.info(f"辩论健康度分析完成: {overall_score:.1f}分 ({status.value})")
|
||||
|
||||
return overall_score, status
|
||||
|
||||
async def _update_content_quality(self, debate_data: Dict[str, Any]):
|
||||
"""更新内容质量指标"""
|
||||
messages = debate_data.get("recent_messages", [])
|
||||
if not messages:
|
||||
return
|
||||
|
||||
quality_scores = []
|
||||
|
||||
for message in messages[-10:]: # 分析最近10条消息
|
||||
content = message.get("content", "")
|
||||
|
||||
# 内容长度评分
|
||||
length_score = min(len(content) / 100 * 50, 50) # 最多50分
|
||||
|
||||
# 词汇丰富度评分
|
||||
words = content.split()
|
||||
unique_words = len(set(words))
|
||||
vocabulary_score = min(unique_words / len(words) * 30, 30) if words else 0
|
||||
|
||||
# 逻辑结构评分(简单检测)
|
||||
logic_indicators = ["因为", "所以", "但是", "然而", "首先", "其次", "最后", "总之"]
|
||||
logic_score = min(sum(1 for indicator in logic_indicators if indicator in content) * 5, 20)
|
||||
|
||||
total_score = length_score + vocabulary_score + logic_score
|
||||
quality_scores.append(total_score)
|
||||
|
||||
avg_quality = statistics.mean(quality_scores) if quality_scores else 50
|
||||
self.health_metrics["content_quality"].value = avg_quality
|
||||
self.health_metrics["content_quality"].last_updated = datetime.now()
|
||||
|
||||
async def _update_participation_balance(self, debate_data: Dict[str, Any]):
|
||||
"""更新参与平衡度指标"""
|
||||
messages = debate_data.get("recent_messages", [])
|
||||
if not messages:
|
||||
return
|
||||
|
||||
# 统计各参与者的发言次数
|
||||
speaker_counts = {}
|
||||
for message in messages[-20:]: # 分析最近20条消息
|
||||
speaker = message.get("sender", "")
|
||||
speaker_counts[speaker] = speaker_counts.get(speaker, 0) + 1
|
||||
|
||||
if not speaker_counts:
|
||||
return
|
||||
|
||||
# 计算参与平衡度
|
||||
counts = list(speaker_counts.values())
|
||||
if len(counts) <= 1:
|
||||
balance_score = 100
|
||||
else:
|
||||
# 使用标准差来衡量平衡度
|
||||
mean_count = statistics.mean(counts)
|
||||
std_dev = statistics.stdev(counts)
|
||||
|
||||
# 标准差越小,平衡度越高
|
||||
balance_score = max(0, 100 - (std_dev / mean_count * 100))
|
||||
|
||||
self.health_metrics["participation_balance"].value = balance_score
|
||||
self.health_metrics["participation_balance"].last_updated = datetime.now()
|
||||
|
||||
async def _update_emotional_stability(self, debate_data: Dict[str, Any]):
|
||||
"""更新情绪稳定性指标"""
|
||||
messages = debate_data.get("recent_messages", [])
|
||||
if not messages:
|
||||
return
|
||||
|
||||
emotional_scores = []
|
||||
|
||||
# 情绪关键词
|
||||
negative_emotions = ["愤怒", "生气", "讨厌", "恶心", "愚蠢", "白痴", "垃圾"]
|
||||
positive_emotions = ["赞同", "支持", "优秀", "精彩", "同意", "认可"]
|
||||
|
||||
for message in messages[-15:]:
|
||||
content = message.get("content", "")
|
||||
|
||||
# 检测负面情绪
|
||||
negative_count = sum(1 for word in negative_emotions if word in content)
|
||||
positive_count = sum(1 for word in positive_emotions if word in content)
|
||||
|
||||
# 检测大写字母比例(可能表示情绪激动)
|
||||
if content:
|
||||
caps_ratio = sum(1 for c in content if c.isupper()) / len(content)
|
||||
else:
|
||||
caps_ratio = 0
|
||||
|
||||
# 检测感叹号数量
|
||||
exclamation_count = content.count("!")
|
||||
|
||||
# 计算情绪稳定性分数
|
||||
emotion_score = 100
|
||||
emotion_score -= negative_count * 15 # 负面情绪扣分
|
||||
emotion_score += positive_count * 5 # 正面情绪加分
|
||||
emotion_score -= caps_ratio * 30 # 大写字母扣分
|
||||
emotion_score -= min(exclamation_count * 5, 20) # 感叹号扣分
|
||||
|
||||
emotional_scores.append(max(0, emotion_score))
|
||||
|
||||
avg_emotional_stability = statistics.mean(emotional_scores) if emotional_scores else 80
|
||||
self.health_metrics["emotional_stability"].value = avg_emotional_stability
|
||||
self.health_metrics["emotional_stability"].last_updated = datetime.now()
|
||||
|
||||
async def _update_topic_relevance(self, debate_data: Dict[str, Any]):
|
||||
"""更新主题相关性指标"""
|
||||
messages = debate_data.get("recent_messages", [])
|
||||
topic_keywords = debate_data.get("topic_keywords", [])
|
||||
|
||||
if not messages or not topic_keywords:
|
||||
return
|
||||
|
||||
relevance_scores = []
|
||||
|
||||
for message in messages[-10:]:
|
||||
content = message.get("content", "")
|
||||
|
||||
# 计算主题关键词匹配度
|
||||
keyword_matches = sum(1 for keyword in topic_keywords if keyword in content)
|
||||
relevance_score = min(keyword_matches / len(topic_keywords) * 100, 100) if topic_keywords else 50
|
||||
|
||||
relevance_scores.append(relevance_score)
|
||||
|
||||
avg_relevance = statistics.mean(relevance_scores) if relevance_scores else 70
|
||||
self.health_metrics["topic_relevance"].value = avg_relevance
|
||||
self.health_metrics["topic_relevance"].last_updated = datetime.now()
|
||||
|
||||
async def _update_interaction_civility(self, debate_data: Dict[str, Any]):
|
||||
"""更新互动文明度指标"""
|
||||
messages = debate_data.get("recent_messages", [])
|
||||
if not messages:
|
||||
return
|
||||
|
||||
civility_scores = []
|
||||
|
||||
# 不文明行为关键词
|
||||
uncivil_patterns = [
|
||||
r"你.*蠢", r".*白痴.*", r".*垃圾.*", r"闭嘴", r"滚.*",
|
||||
r".*傻.*", r".*笨.*", r".*废物.*"
|
||||
]
|
||||
|
||||
# 文明行为关键词
|
||||
civil_patterns = [
|
||||
r"请.*", r"谢谢", r"不好意思", r"抱歉", r"尊重", r"理解"
|
||||
]
|
||||
|
||||
for message in messages[-15:]:
|
||||
content = message.get("content", "")
|
||||
|
||||
civility_score = 100
|
||||
|
||||
# 检测不文明行为
|
||||
for pattern in uncivil_patterns:
|
||||
if re.search(pattern, content):
|
||||
civility_score -= 20
|
||||
|
||||
# 检测文明行为
|
||||
for pattern in civil_patterns:
|
||||
if re.search(pattern, content):
|
||||
civility_score += 5
|
||||
|
||||
civility_scores.append(max(0, min(100, civility_score)))
|
||||
|
||||
avg_civility = statistics.mean(civility_scores) if civility_scores else 85
|
||||
self.health_metrics["interaction_civility"].value = avg_civility
|
||||
self.health_metrics["interaction_civility"].last_updated = datetime.now()
|
||||
|
||||
async def _update_technical_stability(self, debate_data: Dict[str, Any]):
|
||||
"""更新技术稳定性指标"""
|
||||
system_status = debate_data.get("system_status", {})
|
||||
|
||||
stability_score = 100
|
||||
|
||||
# 检查错误率
|
||||
error_rate = system_status.get("error_rate", 0)
|
||||
stability_score -= error_rate * 100
|
||||
|
||||
# 检查响应时间
|
||||
response_time = system_status.get("avg_response_time", 0)
|
||||
if response_time > 2.0: # 超过2秒
|
||||
stability_score -= (response_time - 2.0) * 10
|
||||
|
||||
# 检查系统负载
|
||||
system_load = system_status.get("system_load", 0)
|
||||
if system_load > 0.8: # 负载超过80%
|
||||
stability_score -= (system_load - 0.8) * 50
|
||||
|
||||
self.health_metrics["technical_stability"].value = max(0, stability_score)
|
||||
self.health_metrics["technical_stability"].last_updated = datetime.now()
|
||||
|
||||
async def _check_for_alerts(self, overall_score: float, status: HealthStatus):
|
||||
"""检查是否需要发出警报"""
|
||||
current_time = datetime.now()
|
||||
|
||||
# 检查各项指标是否触发警报
|
||||
for metric_name, metric in self.health_metrics.items():
|
||||
alert_level = self._determine_alert_level(metric)
|
||||
|
||||
if alert_level != InterventionLevel.NONE:
|
||||
# 检查是否在冷却期内
|
||||
recent_alerts = [
|
||||
alert for alert in self.active_alerts
|
||||
if alert.alert_type.value == metric_name and
|
||||
(current_time - alert.timestamp).total_seconds() <
|
||||
self.monitoring_config["alert_cooldown_minutes"] * 60
|
||||
]
|
||||
|
||||
if not recent_alerts:
|
||||
await self._create_alert(metric_name, metric, alert_level)
|
||||
|
||||
# 检查整体健康状态
|
||||
if status in [HealthStatus.POOR, HealthStatus.CRITICAL]:
|
||||
await self._create_system_alert(overall_score, status)
|
||||
|
||||
def _determine_alert_level(self, metric: HealthMetric) -> InterventionLevel:
|
||||
"""确定警报级别"""
|
||||
if metric.value <= metric.threshold_critical:
|
||||
return InterventionLevel.EMERGENCY_STOP
|
||||
elif metric.value <= metric.threshold_poor:
|
||||
return InterventionLevel.STRONG_INTERVENTION
|
||||
elif metric.value <= metric.threshold_fair:
|
||||
return InterventionLevel.MODERATE_GUIDANCE
|
||||
elif metric.value <= metric.threshold_good:
|
||||
return InterventionLevel.GENTLE_REMINDER
|
||||
else:
|
||||
return InterventionLevel.NONE
|
||||
|
||||
async def _create_alert(self, metric_name: str, metric: HealthMetric, level: InterventionLevel):
|
||||
"""创建警报"""
|
||||
alert_type_map = {
|
||||
"content_quality": AlertType.QUALITY_DECLINE,
|
||||
"participation_balance": AlertType.PARTICIPATION_IMBALANCE,
|
||||
"emotional_stability": AlertType.EMOTIONAL_ESCALATION,
|
||||
"topic_relevance": AlertType.OFF_TOPIC,
|
||||
"interaction_civility": AlertType.TOXIC_BEHAVIOR,
|
||||
"technical_stability": AlertType.TECHNICAL_ERROR
|
||||
}
|
||||
|
||||
alert = InterventionAlert(
|
||||
id=f"alert_{datetime.now().timestamp()}",
|
||||
alert_type=alert_type_map.get(metric_name, AlertType.QUALITY_DECLINE),
|
||||
severity=level,
|
||||
message=f"{metric.description}指标异常: {metric.value:.1f}分",
|
||||
affected_participants=[],
|
||||
metrics={metric_name: metric.value},
|
||||
timestamp=datetime.now()
|
||||
)
|
||||
|
||||
self.active_alerts.append(alert)
|
||||
|
||||
# 触发事件处理
|
||||
await self._trigger_event_handlers("alert_created", alert)
|
||||
|
||||
# 检查是否需要自动干预
|
||||
if self.monitoring_config["auto_intervention_enabled"]:
|
||||
await self._execute_auto_intervention(alert)
|
||||
|
||||
# 检查是否需要通知Human
|
||||
if level >= self.monitoring_config["human_notification_threshold"]:
|
||||
await self._notify_human(alert)
|
||||
|
||||
self.logger.warning(f"创建警报: {alert.alert_type.value} - {alert.message}")
|
||||
|
||||
async def _create_system_alert(self, score: float, status: HealthStatus):
|
||||
"""创建系统级警报"""
|
||||
level = InterventionLevel.STRONG_INTERVENTION if status == HealthStatus.POOR else InterventionLevel.EMERGENCY_STOP
|
||||
|
||||
alert = InterventionAlert(
|
||||
id=f"system_alert_{datetime.now().timestamp()}",
|
||||
alert_type=AlertType.QUALITY_DECLINE,
|
||||
severity=level,
|
||||
message=f"系统整体健康度异常: {score:.1f}分 ({status.value})",
|
||||
affected_participants=[],
|
||||
metrics={"overall_score": score},
|
||||
timestamp=datetime.now()
|
||||
)
|
||||
|
||||
self.active_alerts.append(alert)
|
||||
await self._trigger_event_handlers("system_alert_created", alert)
|
||||
|
||||
if self.monitoring_config["auto_intervention_enabled"]:
|
||||
await self._execute_auto_intervention(alert)
|
||||
|
||||
await self._notify_human(alert)
|
||||
|
||||
self.logger.critical(f"系统级警报: {alert.message}")
|
||||
|
||||
async def _execute_auto_intervention(self, alert: InterventionAlert):
|
||||
"""执行自动干预"""
|
||||
intervention_strategies = {
|
||||
AlertType.QUALITY_DECLINE: self._intervene_quality_decline,
|
||||
AlertType.TOXIC_BEHAVIOR: self._intervene_toxic_behavior,
|
||||
AlertType.EMOTIONAL_ESCALATION: self._intervene_emotional_escalation,
|
||||
AlertType.PARTICIPATION_IMBALANCE: self._intervene_participation_imbalance,
|
||||
AlertType.OFF_TOPIC: self._intervene_off_topic,
|
||||
AlertType.TECHNICAL_ERROR: self._intervene_technical_error
|
||||
}
|
||||
|
||||
strategy = intervention_strategies.get(alert.alert_type)
|
||||
if strategy:
|
||||
action = await strategy(alert)
|
||||
if action:
|
||||
self.intervention_history.append(action)
|
||||
await self._trigger_event_handlers("intervention_executed", action)
|
||||
|
||||
async def _intervene_quality_decline(self, alert: InterventionAlert) -> Optional[InterventionAction]:
|
||||
"""干预质量下降"""
|
||||
action = InterventionAction(
|
||||
id=f"quality_intervention_{datetime.now().timestamp()}",
|
||||
action_type="quality_guidance",
|
||||
description="发送质量提升指导",
|
||||
target_participants=["all"],
|
||||
parameters={
|
||||
"message": "💡 建议:请提供更详细的论证和具体的例证来支持您的观点。",
|
||||
"guidance_type": "quality_improvement"
|
||||
},
|
||||
executed_at=datetime.now(),
|
||||
success=True,
|
||||
result_message="质量提升指导已发送"
|
||||
)
|
||||
|
||||
self.logger.info(f"执行质量干预: {action.description}")
|
||||
return action
|
||||
|
||||
async def _intervene_toxic_behavior(self, alert: InterventionAlert) -> Optional[InterventionAction]:
|
||||
"""干预有害行为"""
|
||||
action = InterventionAction(
|
||||
id=f"toxicity_intervention_{datetime.now().timestamp()}",
|
||||
action_type="behavior_warning",
|
||||
description="发送行为规范提醒",
|
||||
target_participants=["all"],
|
||||
parameters={
|
||||
"message": "⚠️ 请保持文明讨论,避免使用攻击性语言。让我们专注于观点的交流。",
|
||||
"warning_level": "moderate"
|
||||
},
|
||||
executed_at=datetime.now(),
|
||||
success=True,
|
||||
result_message="行为规范提醒已发送"
|
||||
)
|
||||
|
||||
self.logger.warning(f"执行行为干预: {action.description}")
|
||||
return action
|
||||
|
||||
async def _intervene_emotional_escalation(self, alert: InterventionAlert) -> Optional[InterventionAction]:
|
||||
"""干预情绪升级"""
|
||||
action = InterventionAction(
|
||||
id=f"emotion_intervention_{datetime.now().timestamp()}",
|
||||
action_type="emotion_cooling",
|
||||
description="发送情绪缓解建议",
|
||||
target_participants=["all"],
|
||||
parameters={
|
||||
"message": "🧘 让我们暂停一下,深呼吸。理性的讨论更有助于达成共识。",
|
||||
"cooling_period": 60 # 秒
|
||||
},
|
||||
executed_at=datetime.now(),
|
||||
success=True,
|
||||
result_message="情绪缓解建议已发送"
|
||||
)
|
||||
|
||||
self.logger.info(f"执行情绪干预: {action.description}")
|
||||
return action
|
||||
|
||||
async def _intervene_participation_imbalance(self, alert: InterventionAlert) -> Optional[InterventionAction]:
|
||||
"""干预参与不平衡"""
|
||||
action = InterventionAction(
|
||||
id=f"balance_intervention_{datetime.now().timestamp()}",
|
||||
action_type="participation_encouragement",
|
||||
description="鼓励平衡参与",
|
||||
target_participants=["all"],
|
||||
parameters={
|
||||
"message": "🤝 鼓励所有参与者分享观点,让讨论更加丰富多元。",
|
||||
"encouragement_type": "participation_balance"
|
||||
},
|
||||
executed_at=datetime.now(),
|
||||
success=True,
|
||||
result_message="参与鼓励消息已发送"
|
||||
)
|
||||
|
||||
self.logger.info(f"执行参与平衡干预: {action.description}")
|
||||
return action
|
||||
|
||||
async def _intervene_off_topic(self, alert: InterventionAlert) -> Optional[InterventionAction]:
|
||||
"""干预偏离主题"""
|
||||
action = InterventionAction(
|
||||
id=f"topic_intervention_{datetime.now().timestamp()}",
|
||||
action_type="topic_redirect",
|
||||
description="引导回归主题",
|
||||
target_participants=["all"],
|
||||
parameters={
|
||||
"message": "🎯 让我们回到主要讨论话题,保持讨论的焦点和深度。",
|
||||
"redirect_type": "topic_focus"
|
||||
},
|
||||
executed_at=datetime.now(),
|
||||
success=True,
|
||||
result_message="主题引导消息已发送"
|
||||
)
|
||||
|
||||
self.logger.info(f"执行主题干预: {action.description}")
|
||||
return action
|
||||
|
||||
async def _intervene_technical_error(self, alert: InterventionAlert) -> Optional[InterventionAction]:
|
||||
"""干预技术错误"""
|
||||
action = InterventionAction(
|
||||
id=f"tech_intervention_{datetime.now().timestamp()}",
|
||||
action_type="technical_support",
|
||||
description="提供技术支持",
|
||||
target_participants=["system"],
|
||||
parameters={
|
||||
"message": "🔧 检测到技术问题,正在进行系统优化...",
|
||||
"support_type": "system_optimization"
|
||||
},
|
||||
executed_at=datetime.now(),
|
||||
success=True,
|
||||
result_message="技术支持已启动"
|
||||
)
|
||||
|
||||
self.logger.error(f"执行技术干预: {action.description}")
|
||||
return action
|
||||
|
||||
async def _notify_human(self, alert: InterventionAlert):
|
||||
"""通知Human"""
|
||||
if alert.human_notified:
|
||||
return
|
||||
|
||||
notification = {
|
||||
"type": "human_intervention_required",
|
||||
"alert_id": alert.id,
|
||||
"severity": alert.severity.value,
|
||||
"message": alert.message,
|
||||
"timestamp": alert.timestamp.isoformat(),
|
||||
"metrics": alert.metrics,
|
||||
"recommended_actions": self._get_recommended_actions(alert)
|
||||
}
|
||||
|
||||
# 触发Human通知事件
|
||||
await self._trigger_event_handlers("human_notification", notification)
|
||||
|
||||
alert.human_notified = True
|
||||
|
||||
self.logger.critical(f"Human通知已发送: {alert.message}")
|
||||
|
||||
def _get_recommended_actions(self, alert: InterventionAlert) -> List[str]:
|
||||
"""获取推荐的干预动作"""
|
||||
recommendations = {
|
||||
AlertType.QUALITY_DECLINE: [
|
||||
"提供写作指导",
|
||||
"分享优秀案例",
|
||||
"调整讨论节奏"
|
||||
],
|
||||
AlertType.TOXIC_BEHAVIOR: [
|
||||
"发出警告",
|
||||
"暂时禁言",
|
||||
"私下沟通"
|
||||
],
|
||||
AlertType.EMOTIONAL_ESCALATION: [
|
||||
"暂停讨论",
|
||||
"引导冷静",
|
||||
"转移话题"
|
||||
],
|
||||
AlertType.PARTICIPATION_IMBALANCE: [
|
||||
"邀请发言",
|
||||
"限制发言频率",
|
||||
"分组讨论"
|
||||
],
|
||||
AlertType.OFF_TOPIC: [
|
||||
"重申主题",
|
||||
"引导回归",
|
||||
"设置议程"
|
||||
],
|
||||
AlertType.TECHNICAL_ERROR: [
|
||||
"重启系统",
|
||||
"检查日志",
|
||||
"联系技术支持"
|
||||
]
|
||||
}
|
||||
|
||||
return recommendations.get(alert.alert_type, ["人工评估", "采取适当措施"])
|
||||
|
||||
async def _trigger_event_handlers(self, event_type: str, data: Any):
|
||||
"""触发事件处理器"""
|
||||
if event_type in self.event_handlers:
|
||||
for handler in self.event_handlers[event_type]:
|
||||
try:
|
||||
await handler(data)
|
||||
except Exception as e:
|
||||
self.logger.error(f"事件处理器错误: {e}")
|
||||
|
||||
def add_event_handler(self, event_type: str, handler: Callable):
|
||||
"""添加事件处理器"""
|
||||
if event_type not in self.event_handlers:
|
||||
self.event_handlers[event_type] = []
|
||||
self.event_handlers[event_type].append(handler)
|
||||
|
||||
def update_metrics(self, metrics_data: Dict[str, float]):
|
||||
"""更新健康指标(兼容性方法)"""
|
||||
for metric_name, value in metrics_data.items():
|
||||
if metric_name in self.health_metrics:
|
||||
self.health_metrics[metric_name].value = value
|
||||
self.health_metrics[metric_name].last_updated = datetime.now()
|
||||
|
||||
def get_health_status(self) -> HealthStatus:
|
||||
"""获取当前健康状态(兼容性方法)"""
|
||||
# 计算整体分数
|
||||
total_score = 0.0
|
||||
total_weight = 0.0
|
||||
|
||||
for metric in self.health_metrics.values():
|
||||
total_score += metric.value * metric.weight
|
||||
total_weight += metric.weight
|
||||
|
||||
overall_score = total_score / total_weight if total_weight > 0 else 0.0
|
||||
|
||||
# 确定状态
|
||||
if overall_score >= 90:
|
||||
return HealthStatus.EXCELLENT
|
||||
elif overall_score >= 70:
|
||||
return HealthStatus.GOOD
|
||||
elif overall_score >= 50:
|
||||
return HealthStatus.FAIR
|
||||
elif overall_score >= 30:
|
||||
return HealthStatus.POOR
|
||||
else:
|
||||
return HealthStatus.CRITICAL
|
||||
|
||||
def get_health_report(self) -> Dict[str, Any]:
|
||||
"""获取健康报告"""
|
||||
# 计算整体分数
|
||||
total_score = 0.0
|
||||
total_weight = 0.0
|
||||
|
||||
for metric in self.health_metrics.values():
|
||||
total_score += metric.value * metric.weight
|
||||
total_weight += metric.weight
|
||||
|
||||
overall_score = total_score / total_weight if total_weight > 0 else 0.0
|
||||
|
||||
# 确定状态
|
||||
if overall_score >= 90:
|
||||
status = HealthStatus.EXCELLENT
|
||||
elif overall_score >= 70:
|
||||
status = HealthStatus.GOOD
|
||||
elif overall_score >= 50:
|
||||
status = HealthStatus.FAIR
|
||||
elif overall_score >= 30:
|
||||
status = HealthStatus.POOR
|
||||
else:
|
||||
status = HealthStatus.CRITICAL
|
||||
|
||||
report = {
|
||||
"overall_score": round(overall_score, 1),
|
||||
"health_status": status.value,
|
||||
"metrics": {
|
||||
name: {
|
||||
"value": round(metric.value, 1),
|
||||
"weight": metric.weight,
|
||||
"description": metric.description,
|
||||
"last_updated": metric.last_updated.isoformat()
|
||||
}
|
||||
for name, metric in self.health_metrics.items()
|
||||
},
|
||||
"active_alerts": len(self.active_alerts),
|
||||
"recent_interventions": len([a for a in self.intervention_history
|
||||
if (datetime.now() - a.executed_at).total_seconds() < 3600]),
|
||||
"monitoring_enabled": self.monitoring_enabled,
|
||||
"last_check": datetime.now().isoformat()
|
||||
}
|
||||
|
||||
return report
|
||||
|
||||
def resolve_alert(self, alert_id: str, resolution_notes: str = ""):
|
||||
"""解决警报"""
|
||||
for alert in self.active_alerts:
|
||||
if alert.id == alert_id:
|
||||
alert.resolved = True
|
||||
alert.resolution_notes = resolution_notes
|
||||
self.logger.info(f"警报已解决: {alert_id} - {resolution_notes}")
|
||||
return True
|
||||
return False
|
||||
|
||||
def clear_resolved_alerts(self):
|
||||
"""清理已解决的警报"""
|
||||
before_count = len(self.active_alerts)
|
||||
self.active_alerts = [alert for alert in self.active_alerts if not alert.resolved]
|
||||
after_count = len(self.active_alerts)
|
||||
|
||||
cleared_count = before_count - after_count
|
||||
if cleared_count > 0:
|
||||
self.logger.info(f"清理了 {cleared_count} 个已解决的警报")
|
||||
|
||||
def enable_monitoring(self):
|
||||
"""启用监控"""
|
||||
self.monitoring_enabled = True
|
||||
self.logger.info("健康监控已启用")
|
||||
|
||||
def disable_monitoring(self):
|
||||
"""禁用监控"""
|
||||
self.monitoring_enabled = False
|
||||
self.logger.info("健康监控已禁用")
|
||||
|
||||
def save_monitoring_data(self, filename: str = "monitoring_data.json"):
|
||||
"""保存监控数据"""
|
||||
# 序列化监控配置,处理InterventionLevel枚举
|
||||
serialized_config = self.monitoring_config.copy()
|
||||
serialized_config["human_notification_threshold"] = self.monitoring_config["human_notification_threshold"].value
|
||||
|
||||
data = {
|
||||
"health_metrics": {
|
||||
name: {
|
||||
"name": metric.name,
|
||||
"value": metric.value,
|
||||
"weight": metric.weight,
|
||||
"threshold_critical": metric.threshold_critical,
|
||||
"threshold_poor": metric.threshold_poor,
|
||||
"threshold_fair": metric.threshold_fair,
|
||||
"threshold_good": metric.threshold_good,
|
||||
"description": metric.description,
|
||||
"last_updated": metric.last_updated.isoformat()
|
||||
}
|
||||
for name, metric in self.health_metrics.items()
|
||||
},
|
||||
"active_alerts": [
|
||||
{
|
||||
"id": alert.id,
|
||||
"alert_type": alert.alert_type.value,
|
||||
"severity": alert.severity.value,
|
||||
"message": alert.message,
|
||||
"affected_participants": alert.affected_participants,
|
||||
"metrics": alert.metrics,
|
||||
"timestamp": alert.timestamp.isoformat(),
|
||||
"resolved": alert.resolved,
|
||||
"resolution_notes": alert.resolution_notes,
|
||||
"human_notified": alert.human_notified
|
||||
}
|
||||
for alert in self.active_alerts
|
||||
],
|
||||
"intervention_history": [
|
||||
{
|
||||
"id": action.id,
|
||||
"action_type": action.action_type,
|
||||
"description": action.description,
|
||||
"target_participants": action.target_participants,
|
||||
"parameters": action.parameters,
|
||||
"executed_at": action.executed_at.isoformat(),
|
||||
"success": action.success,
|
||||
"result_message": action.result_message
|
||||
}
|
||||
for action in self.intervention_history
|
||||
],
|
||||
"monitoring_config": serialized_config,
|
||||
"monitoring_enabled": self.monitoring_enabled,
|
||||
"export_time": datetime.now().isoformat()
|
||||
}
|
||||
|
||||
with open(filename, 'w', encoding='utf-8') as f:
|
||||
json.dump(data, f, ensure_ascii=False, indent=2)
|
||||
|
||||
self.logger.info(f"监控数据已保存到 {filename}")
|
||||
|
||||
# 使用示例
|
||||
async def main():
|
||||
"""使用示例"""
|
||||
monitor = DebateHealthMonitor()
|
||||
|
||||
# 模拟辩论数据
|
||||
debate_data = {
|
||||
"recent_messages": [
|
||||
{"sender": "正1", "content": "AI投资确实具有巨大潜力,我们可以从以下几个方面来分析..."},
|
||||
{"sender": "反1", "content": "但是风险也不容忽视!!!这些投资可能导致泡沫!"},
|
||||
{"sender": "正2", "content": "好的"},
|
||||
{"sender": "反2", "content": "你们这些观点太愚蠢了,完全没有逻辑!"},
|
||||
],
|
||||
"topic_keywords": ["AI", "投资", "风险", "收益", "技术"],
|
||||
"system_status": {
|
||||
"error_rate": 0.02,
|
||||
"avg_response_time": 1.5,
|
||||
"system_load": 0.6
|
||||
}
|
||||
}
|
||||
|
||||
# 分析健康度
|
||||
score, status = await monitor.analyze_debate_health(debate_data)
|
||||
|
||||
print(f"\n📊 辩论健康度分析结果:")
|
||||
print(f"综合得分: {score:.1f}分")
|
||||
print(f"健康状态: {status.value}")
|
||||
|
||||
# 获取详细报告
|
||||
report = monitor.get_health_report()
|
||||
print(f"\n📋 详细健康报告:")
|
||||
print(f"活跃警报数: {report['active_alerts']}")
|
||||
print(f"近期干预数: {report['recent_interventions']}")
|
||||
|
||||
print(f"\n📈 各项指标:")
|
||||
for name, metric in report['metrics'].items():
|
||||
print(f" {metric['description']}: {metric['value']}分 (权重: {metric['weight']})")
|
||||
|
||||
# 保存数据
|
||||
monitor.save_monitoring_data()
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
Reference in New Issue
Block a user