ad-guardian / app_ai.py
Nanny7's picture
Implement real AI-powered content audit with Hanyu Xinxie style cards
8a9039a
"""
ContentGuardian - AI-Powered Content Audit Agent
China · Simplified Chinese · Hanyu Xinxie Style · AI-Driven Version
Real AI content analysis with SVG visualization
"""
import gradio as gr
import asyncio
import aiohttp
import json
import os
import datetime
from typing import Dict, List
# AI Client for content analysis
class AIContentAnalyzer:
def __init__(self):
self.api_key = os.getenv("SILICONFLOW_API_KEY", "sk-your-api-key-here")
self.base_url = "https://api.siliconflow.cn/v1/chat/completions"
self.model = "Qwen/Qwen2.5-7B-Instruct"
async def analyze_content(self, text: str, keywords: List[str] = None) -> Dict:
"""AI-powered content analysis"""
keywords_str = ", ".join(keywords) if keywords else "无"
prompt = f"""
你是专业的内容审核专家,请对以下文本进行全面审核分析:
文本内容:{text}
关键词:{keywords_str}
请从以下维度进行分析:
1. 错别字检测:识别文本中的拼写错误和用词不当
2. 违规内容:检测不当言论、违法违规表述
3. 虚假内容:识别可能的虚假信息和夸大宣传
4. 不当广告用语:检测违反广告法的用词
5. 关键词分析:分析指定关键词的使用情况
请以JSON格式返回分析结果:
{{
"typos": [
{{"original": "错误词", "correct": "正确词", "reason": "错误原因"}}
],
"violations": [
{{"content": "违规内容", "type": "违规类型", "suggestion": "修改建议"}}
],
"fake_content": [
{{"content": "虚假内容", "type": "虚假类型", "suggestion": "修改建议"}}
],
"inappropriate_ads": [
{{"word": "不当用词", "reason": "违规原因", "suggestion": "替代建议"}}
],
"keywords_analysis": [
{{"keyword": "关键词", "frequency": 次数, "context": "使用语境", "assessment": "使用评价"}}
],
"overall_assessment": {{
"risk_level": "低/中/高",
"total_issues": 问题总数,
"main_concerns": ["主要问题1", "主要问题2"],
"recommendations": ["建议1", "建议2"]
}}
}}
"""
try:
headers = {
"Authorization": f"Bearer {self.api_key}",
"Content-Type": "application/json"
}
data = {
"model": self.model,
"messages": [
{"role": "system", "content": "你是专业的内容审核专家,擅长识别各类内容问题并提供专业建议。"},
{"role": "user", "content": prompt}
],
"temperature": 0.1,
"max_tokens": 2000
}
async with aiohttp.ClientSession() as session:
async with session.post(self.base_url, headers=headers, json=data) as response:
if response.status == 200:
result = await response.json()
ai_response = result["choices"][0]["message"]["content"]
# 尝试解析JSON
try:
# 清理AI返回的内容
if "```json" in ai_response:
ai_response = ai_response.split("```json")[1].split("```")[0]
elif "```" in ai_response:
ai_response = ai_response.split("```")[1].split("```")[0]
analysis_result = json.loads(ai_response.strip())
return analysis_result
except json.JSONDecodeError:
# 如果JSON解析失败,返回基础分析
return self._create_fallback_analysis(text, keywords)
else:
return self._create_fallback_analysis(text, keywords)
except Exception as e:
print(f"AI analysis error: {e}")
return self._create_fallback_analysis(text, keywords)
def _create_fallback_analysis(self, text: str, keywords: List[str] = None) -> Dict:
"""备用分析方法"""
# 简单的关键词检测作为备用
inappropriate_words = ["绝对", "完全", "100%", "第一", "最好", "立即", "马上"]
found_inappropriate = [word for word in inappropriate_words if word in text]
return {
"typos": [],
"violations": [],
"fake_content": [],
"inappropriate_ads": [{"word": word, "reason": "可能违反广告法", "suggestion": "使用相对性表述"} for word in found_inappropriate],
"keywords_analysis": [{"keyword": kw, "frequency": text.count(kw), "context": "文本中", "assessment": "正常使用"} for kw in (keywords or []) if kw in text],
"overall_assessment": {
"risk_level": "中" if found_inappropriate else "低",
"total_issues": len(found_inappropriate),
"main_concerns": ["广告用语不当"] if found_inappropriate else [],
"recommendations": ["修改绝对化表述"] if found_inappropriate else ["内容表述规范"]
}
}
# 全局AI分析器
ai_analyzer = AIContentAnalyzer()
def generate_hanyu_xinxie_cards(analysis_result: Dict, original_text: str) -> str:
"""生成汉语新解风格的SVG卡片"""
overall = analysis_result.get("overall_assessment", {})
total_issues = overall.get("total_issues", 0)
risk_level = overall.get("risk_level", "低")
# 莫兰迪色系配色
colors = {
"primary": "#B6B5A7", # 莫兰迪灰褐色
"secondary": "#9A8F8F", # 莫兰迪灰棕色
"accent": "#C5B4A0", # 莫兰迪淡棕色
"background": "#F2EDE9", # 莫兰迪浅米色
"text": "#5B5B5B", # 莫兰迪深灰色
"light_text": "#8C8C8C", # 莫兰迪中灰色
"divider": "#D1CBC3" # 莫兰迪浅灰色
}
# 根据风险等级调整颜色
if risk_level == "高":
colors["secondary"] = "#B85450" # 深红色
colors["accent"] = "#D4776B" # 浅红色
elif risk_level == "中":
colors["secondary"] = "#C4965A" # 橙色
colors["accent"] = "#D4A574" # 浅橙色
# 生成主要摘要卡片
main_card = f"""
<div style="
display: flex;
justify-content: center;
padding: 20px;
background: linear-gradient(135deg, #E8E3DE 0%, #F2EDE9 100%);
border-radius: 15px;
font-family: 'Microsoft YaHei', 'Noto Sans SC', sans-serif;
margin-bottom: 20px;
">
<div style="
width: 350px;
background-color: {colors['background']};
border-radius: 20px;
box-shadow: 0 20px 40px rgba(0,0,0,0.1);
overflow: hidden;
position: relative;
">
<!-- 标题区域 -->
<div style="
background-color: {colors['secondary']};
color: {colors['background']};
padding: 20px;
text-align: left;
">
<h1 style="font-size: 20px; margin: 0; font-weight: 700;">🛡️ AI内容审核报告</h1>
<p style="font-size: 12px; margin: 5px 0 0 0; opacity: 0.9;">中国·简体中文·汉语新解风格</p>
</div>
<!-- 内容区域 -->
<div style="padding: 25px 20px;">
<!-- 主要统计 -->
<div style="text-align: left; margin-bottom: 20px;">
<div style="
font-size: 36px;
color: {colors['text']};
margin-bottom: 8px;
font-weight: bold;
position: relative;
">
{total_issues} 处问题
<div style="
position: absolute;
left: 0;
bottom: -4px;
width: 60px;
height: 3px;
background-color: {colors['accent']};
"></div>
</div>
<div style="
font-size: 16px;
color: {colors['light_text']};
margin: 12px 0;
">风险等级: {risk_level}</div>
</div>
<!-- 分隔线 -->
<div style="
width: 100%;
height: 1px;
background-color: {colors['divider']};
margin: 20px 0;
"></div>
<!-- AI分析结果 -->
<div style="
font-size: 14px;
line-height: 1.6;
text-align: left;
">
<div style="
padding-left: 15px;
border-left: 3px solid {colors['accent']};
">"""
# 添加具体问题类型
if analysis_result.get("typos"):
main_card += f'<p style="margin: 8px 0; color: {colors["text"]};">• 错别字问题: {len(analysis_result["typos"])} 处</p>'
if analysis_result.get("violations"):
main_card += f'<p style="margin: 8px 0; color: {colors["text"]};">• 违规内容: {len(analysis_result["violations"])} 处</p>'
if analysis_result.get("fake_content"):
main_card += f'<p style="margin: 8px 0; color: {colors["text"]};">• 虚假内容: {len(analysis_result["fake_content"])} 处</p>'
if analysis_result.get("inappropriate_ads"):
main_card += f'<p style="margin: 8px 0; color: {colors["text"]};">• 不当广告用语: {len(analysis_result["inappropriate_ads"])} 处</p>'
if analysis_result.get("keywords_analysis"):
main_card += f'<p style="margin: 8px 0; color: {colors["text"]};">• 关键词分析: {len(analysis_result["keywords_analysis"])} 个</p>'
if total_issues == 0:
main_card += f'<p style="margin: 8px 0; color: {colors["light_text"]};">✅ 未发现明显问题</p>'
main_card += f"""
</div>
</div>
<!-- AI建议 -->
<div style="
margin-top: 20px;
padding: 15px;
background-color: rgba(255,255,255,0.5);
border-radius: 10px;
border-left: 4px solid {colors['accent']};
">
<h4 style="margin: 0 0 10px 0; color: {colors['text']}; font-size: 14px;">🤖 AI建议</h4>"""
recommendations = overall.get("recommendations", ["内容表述规范"])
for rec in recommendations[:2]: # 最多显示2个建议
main_card += f'<p style="margin: 5px 0; color: {colors["light_text"]}; font-size: 13px;">• {rec}</p>'
main_card += f"""
</div>
<!-- 中式印章风格装饰 -->
<div style="
text-align: center;
margin-top: 25px;
padding: 10px;
border: 2px solid {colors['accent']};
border-radius: 50%;
width: 70px;
height: 70px;
margin-left: auto;
margin-right: auto;
display: flex;
align-items: center;
justify-content: center;
">
<span style="
font-size: 18px;
color: {colors['secondary']};
font-weight: bold;
">AI审核</span>
</div>
</div>
<!-- 背景装饰文字 -->
<div style="
position: absolute;
font-size: 120px;
color: rgba(182, 181, 167, 0.05);
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-weight: bold;
pointer-events: none;
z-index: 0;
">AI</div>
</div>
</div>
"""
return main_card
def generate_error_card(error_msg: str) -> str:
"""生成错误信息卡片"""
return f"""
<div style="
display: flex;
justify-content: center;
padding: 20px;
background: linear-gradient(135deg, #E8E3DE 0%, #F2EDE9 100%);
border-radius: 15px;
font-family: 'Microsoft YaHei', sans-serif;
">
<div style="
width: 350px;
background-color: #F2EDE9;
border-radius: 20px;
box-shadow: 0 20px 40px rgba(0,0,0,0.1);
padding: 30px;
text-align: center;
">
<h2 style="color: #B85450; margin-bottom: 15px;">⚠️ 分析出错</h2>
<p style="color: #5B5B5B; margin-bottom: 20px;">AI分析过程中遇到问题:</p>
<div style="
background-color: rgba(184, 84, 80, 0.1);
padding: 15px;
border-radius: 10px;
border-left: 4px solid #B85450;
text-align: left;
">
<code style="color: #B85450; font-size: 12px;">{error_msg}</code>
</div>
<p style="color: #8C8C8C; margin-top: 15px; font-size: 14px;">请稍后重试或检查网络连接</p>
</div>
</div>
"""
def comprehensive_text_audit(text, keywords=""):
"""
AI-powered comprehensive text audit with SVG visualization
"""
if not text.strip():
return "❌ Please enter text content"
# Parse keywords
keyword_list = [k.strip() for k in keywords.split(",") if k.strip()] if keywords else []
try:
# 使用异步事件循环进行AI分析
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
try:
# 执行AI分析
analysis_result = loop.run_until_complete(
ai_analyzer.analyze_content(text, keyword_list)
)
finally:
loop.close()
# 生成汉语新解风格的SVG卡片
svg_cards = generate_hanyu_xinxie_cards(analysis_result, text)
return svg_cards
except Exception as e:
print(f"Analysis error: {e}")
# 返回错误信息的SVG卡片
return generate_error_card(str(e))
# Create Gradio interface optimized for HF Spaces
demo = gr.Interface(
fn=comprehensive_text_audit,
inputs=[
gr.Textbox(
label="Text to Audit",
placeholder="Please enter the text content to be audited...",
lines=8
),
gr.Textbox(
label="Keywords (Optional)",
placeholder="Please enter keywords to mark, separated by commas",
lines=2
)
],
outputs=gr.HTML(
label="AI Audit Report"
),
title="🛡️ ContentGuardian - AI Content Audit Agent",
description="""
**China · Simplified Chinese · Hanyu Xinxie Style · AI-Driven Version**
This system uses real AI analysis to detect content issues and generates beautiful Hanyu Xinxie style cards.
Powered by advanced language models for intelligent content understanding.
**Key Features:**
- 🤖 AI-Powered Content Analysis
- 🔍 Intelligent Error Detection
- 📊 Beautiful SVG Card Visualization
- 🎨 Hanyu Xinxie Aesthetic Style
""",
examples=[
["This product is absolutely effective, completely side-effect free, the first brand! Buy immediately, instant results!", "product,effect"],
["Our product quality is very good, trustworthy, welcome to purchase.", "product,quality"],
["这款产品效果绝对好,完全无副作用,第一品牌!立即购买,马上见效!", "产品,效果"],
["Buy now, instant effect, 100% effective, absolutely satisfying!", "buy,effect"]
],
theme=gr.themes.Soft(),
allow_flagging="never"
)
if __name__ == "__main__":
demo.launch()