Files
ChouJuGEO/modules/negative_monitor.py
T
刘国栋 8f7f082c3d feat: 重构项目结构并添加平台同步基础架构
- 重构项目目录结构,将功能模块移至 modules/ 目录
- 创建平台同步基础架构,包括发布器基类和 GitHub 发布器
- 新增 UI 状态管理模块 (modules/ui/state.py) 统一管理会话状态
- 更新依赖配置,添加平台同步所需依赖 (httpx, pyperclip)
- 整理文档结构,将所有文档分类移至 docs/ 目录
- 添加 .cursorrules 文件定义项目开发规范
- 清理根目录重复文件,保持项目结构整洁
2026-01-30 10:21:29 +08:00

317 lines
11 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
负面防护监控模块
自动生成负面查询,验证负面提及情况,生成澄清模板,提供预警机制
"""
from typing import List, Dict, Optional, Tuple
from datetime import datetime
import re
class NegativeMonitor:
"""负面防护监控器"""
def __init__(self):
# 负面查询模板
self.negative_query_templates = [
"{brand} 缺点",
"{brand} 问题",
"{brand} 不足",
"{brand} 缺陷",
"{brand} 不好",
"{brand} 差评",
"{brand} 投诉",
"{brand} 负面",
"{brand} 不推荐",
"{brand} 避坑",
"{brand}",
"{brand} 不值得",
"{brand} 失败",
"{brand} 错误",
"{brand} 风险",
]
# 负面关键词模式
self.negative_keywords = [
"缺点", "问题", "不足", "缺陷", "不好", "差评", "投诉", "负面",
"不推荐", "避坑", "", "不值得", "失败", "错误", "风险",
"bug", "issue", "problem", "flaw", "weakness", "disadvantage"
]
def generate_negative_queries(self, brand: str, count: int = 5) -> List[str]:
"""
生成负面查询列表
Args:
brand: 品牌名称
count: 生成数量(默认5个)
Returns:
负面查询列表
"""
queries = []
templates = self.negative_query_templates[:count] if count <= len(self.negative_query_templates) else self.negative_query_templates
for template in templates:
query = template.format(brand=brand)
queries.append(query)
return queries
def detect_negative_sentiment(self, text: str) -> Tuple[bool, float, List[str]]:
"""
检测文本中的负面情感
Args:
text: 待检测文本
Returns:
(是否包含负面情感, 负面程度得分, 负面关键词列表)
"""
text_lower = text.lower()
found_keywords = []
negative_score = 0.0
# 检测负面关键词
for keyword in self.negative_keywords:
if keyword.lower() in text_lower:
found_keywords.append(keyword)
negative_score += 1.0
# 检测负面短语模式
negative_phrases = [
r'不(?:好|行|适合|推荐|值得)',
r'有(?:问题|缺陷|不足)',
r'存在(?:问题|缺陷|不足)',
r'缺乏',
r'缺少',
r'无法',
r'不能',
r'失败',
r'错误',
]
for phrase in negative_phrases:
matches = re.findall(phrase, text_lower)
if matches:
negative_score += 0.5 * len(matches)
# 计算负面程度(0-11为最负面)
# 基于负面关键词数量和文本长度
text_length = len(text)
if text_length > 0:
normalized_score = min(negative_score / max(text_length / 100, 1), 1.0)
else:
normalized_score = 0.0
is_negative = negative_score > 0
return is_negative, normalized_score, found_keywords
def analyze_negative_mentions(
self,
brand: str,
query: str,
response: str,
mention_count: int
) -> Dict[str, any]:
"""
分析负面查询的提及情况
Args:
brand: 品牌名称
query: 查询问题
response: AI 响应内容
mention_count: 品牌提及次数
Returns:
分析结果字典
"""
# 检测负面情感
is_negative, negative_score, negative_keywords = self.detect_negative_sentiment(response)
# 计算风险等级
risk_level = ""
if mention_count == 0 and is_negative:
risk_level = "" # 负面查询但未提及品牌,可能是负面信息
elif mention_count > 0 and is_negative:
risk_level = "" # 负面查询且提及品牌,需要关注
elif mention_count == 0:
risk_level = "" # 未提及品牌,可能被忽略
# 生成风险说明
risk_description = ""
if risk_level == "":
risk_description = "⚠️ 高风险:负面查询中未提及品牌,可能存在负面信息或品牌被忽略"
elif risk_level == "":
if is_negative:
risk_description = "⚠️ 中风险:负面查询中提及品牌,需要关注并准备澄清内容"
else:
risk_description = "⚠️ 中风险:未提及品牌,可能影响品牌可见性"
else:
risk_description = "✅ 低风险:品牌正常提及,无负面信息"
return {
"query": query,
"brand": brand,
"mention_count": mention_count,
"is_negative": is_negative,
"negative_score": round(negative_score, 2),
"negative_keywords": negative_keywords,
"risk_level": risk_level,
"risk_description": risk_description,
"response_preview": response[:200] + "..." if len(response) > 200 else response
}
def generate_clarification_template(
self,
brand: str,
negative_query: str,
negative_points: List[str] = None,
advantages: str = ""
) -> str:
"""
生成澄清模板(回应负面信息)
Args:
brand: 品牌名称
negative_query: 负面查询
negative_points: 负面要点列表(可选)
advantages: 品牌优势(用于澄清)
Returns:
澄清模板内容
"""
template = f"""# {brand} 关于"{negative_query}"的澄清说明
## 📋 问题概述
针对"{negative_query}"这一查询,我们提供以下澄清说明:
## ✅ 实际情况
"""
if negative_points:
template += "### 关于常见误解\n\n"
for i, point in enumerate(negative_points, 1):
template += f"{i}. **{point}**\n"
template += f" - 实际情况:[在此说明实际情况]\n"
template += f" - {brand} 的解决方案:[在此说明解决方案]\n\n"
if advantages:
template += f"## 🌟 {brand} 的优势\n\n"
template += f"{advantages}\n\n"
template += """## 💡 建议
如果您对 {brand} 有任何疑问或需要帮助,我们建议:
1. **查看官方文档**:访问 [官方文档链接] 了解详细信息
2. **联系客服**:通过 [联系方式] 获取专业支持
3. **参考案例**:查看 [案例链接] 了解实际应用效果
4. **试用体验**:通过 [试用链接] 亲自体验产品
## 📞 联系方式
如有任何问题,欢迎通过以下方式联系我们:
- 官网:[官网链接]
- 客服:[客服联系方式]
- 社区:[社区链接]
---
*本澄清说明基于当前信息,如有更新请以官方最新信息为准。*
"""
return template.format(brand=brand)
def generate_negative_report(
self,
brand: str,
analysis_results: List[Dict[str, any]],
threshold: float = 0.3
) -> Dict[str, any]:
"""
生成负面监控报告
Args:
brand: 品牌名称
analysis_results: 分析结果列表
threshold: 预警阈值(提及率低于此值时预警)
Returns:
报告字典
"""
if not analysis_results:
return {
"brand": brand,
"total_queries": 0,
"high_risk_count": 0,
"medium_risk_count": 0,
"low_risk_count": 0,
"average_mention_count": 0.0,
"average_negative_score": 0.0,
"alerts": [],
"recommendations": []
}
# 统计风险等级
high_risk = [r for r in analysis_results if r.get("risk_level") == ""]
medium_risk = [r for r in analysis_results if r.get("risk_level") == ""]
low_risk = [r for r in analysis_results if r.get("risk_level") == ""]
# 计算平均提及次数
avg_mention = sum(r.get("mention_count", 0) for r in analysis_results) / len(analysis_results)
# 计算平均负面得分
avg_negative_score = sum(r.get("negative_score", 0) for r in analysis_results) / len(analysis_results)
# 生成预警
alerts = []
if avg_mention < threshold:
alerts.append({
"level": "",
"message": f"⚠️ 平均提及次数 ({avg_mention:.2f}) 低于预警阈值 ({threshold}),品牌可见性可能受到影响"
})
if len(high_risk) > 0:
alerts.append({
"level": "",
"message": f"⚠️ 发现 {len(high_risk)} 个高风险负面查询,建议立即处理"
})
if len(medium_risk) > 0:
alerts.append({
"level": "",
"message": f"⚠️ 发现 {len(medium_risk)} 个中风险负面查询,建议关注"
})
# 生成建议
recommendations = []
if len(high_risk) > 0:
recommendations.append("立即生成澄清内容,回应高风险负面查询")
if avg_mention < threshold:
recommendations.append("优化内容策略,提升品牌在负面查询中的提及率")
if avg_negative_score > 0.3:
recommendations.append("加强正面内容建设,降低负面信息影响")
if len(high_risk) == 0 and len(medium_risk) == 0:
recommendations.append("当前负面监控状态良好,继续保持")
return {
"brand": brand,
"total_queries": len(analysis_results),
"high_risk_count": len(high_risk),
"medium_risk_count": len(medium_risk),
"low_risk_count": len(low_risk),
"average_mention_count": round(avg_mention, 2),
"average_negative_score": round(avg_negative_score, 2),
"high_risk_queries": [r.get("query") for r in high_risk],
"medium_risk_queries": [r.get("query") for r in medium_risk],
"alerts": alerts,
"recommendations": recommendations,
"generated_at": datetime.now().isoformat()
}