配置全面迁移数据库:PromptConfig、TaskConfig动态调度、敏感词/清洗规则/趋势映射/平台标签/痛点模板全部可编辑

- 新增 PromptConfig 模型 + API,支持提示词在线编辑(16条默认)
- 调度器动态读取 TaskConfig.schedule,admin 可调执行时间
- 新增 KeywordDomainMap、SensitiveWord、ContentCleanRule、TrendFieldMapping 表
- DOMAINS、TREND_DOMAIN_MAP、PLATFORM_TAGS、china_pains、RSS关键词、priority_weights 全部迁移到 DB
- tasks.html 重构:卡片网格+配置/产出/历史/提示词四个Tab,折叠显示
- 清理冗余代码:DEFAULT_PROMPTS死代码、collector.py unreachable代码、compliance_checker bug
- strip_thinking_html 改用 DB 规则优先
This commit is contained in:
Yuzhiran Dev
2026-05-22 11:18:23 +08:00
parent a8e0a76e07
commit 1855f190f5
31 changed files with 2927 additions and 1127 deletions
+46 -29
View File
@@ -20,6 +20,8 @@ except ImportError:
HAVE_LLM = False
from db_helper import get_topic_by_id, update_topic_status, get_active_llm_config, get_articles_by_topic, save_article
from content_cleaner import strip_thinking, strip_ai_preface, strip_thinking_html, clean_html_content
from prompt_loader import get_prompt, get_prompt_params
DATA_DIR = PROJECT_ROOT / "automation" / "data"
DRAFTS_DIR = DATA_DIR / "drafts"
@@ -30,11 +32,42 @@ logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(
handlers=[logging.FileHandler(LOGS_DIR / f"optimizer_{TODAY}.log"), logging.StreamHandler()])
logger = logging.getLogger(__name__)
PLATFORM_TAGS = {
DEFAULT_PLATFORM_TAGS = {
"zhihu": ["科技", "职场"],
"xiaohongshu": ["AI", "可持续", "生活方式"]
}
_cached_platform_tags = None
def _load_platform_tags():
global _cached_platform_tags
if _cached_platform_tags is not None:
return _cached_platform_tags
try:
from app.database import SessionLocal
from app.models import PlatformConfig
db = SessionLocal()
try:
configs = db.query(PlatformConfig).filter(PlatformConfig.is_active == True).all()
if configs:
_cached_platform_tags = {}
for c in configs:
tags = c.to_dict().get("allowed_tags", [])
if tags:
_cached_platform_tags[c.platform] = tags
if _cached_platform_tags:
logger.info(f"从DB加载 {len(_cached_platform_tags)} 个平台的标签")
return _cached_platform_tags
finally:
db.close()
except Exception as e:
logger.warning(f"从DB加载 platform_tags 失败: {e}")
_cached_platform_tags = DEFAULT_PLATFORM_TAGS
return _cached_platform_tags
def get_platform_tags():
return _load_platform_tags()
_llm_config_cache = None
def get_llm_config():
@@ -110,13 +143,14 @@ def fix_wechat_title(html: str, title: str) -> str:
return html
def fix_tags(html: str, platform: str) -> str:
tags_map = get_platform_tags()
if platform == "zhihu":
tags_str = " ".join(f"#{t}" for t in PLATFORM_TAGS["zhihu"])
tags_str = " ".join(f"#{t}" for t in tags_map.get("zhihu", []))
if '<div class="tags">' in html:
old = html.split('<div class="tags">')[1].split('</div>')[0]
html = html.replace(f'<div class="tags">{old}</div>', f'<div class="tags">{tags_str}</div>')
elif platform == "xiaohongshu":
tags_str = " ".join(f"#{t}" for t in PLATFORM_TAGS["xiaohongshu"])
tags_str = " ".join(f"#{t}" for t in tags_map.get("xiaohongshu", []))
if '<div class="hashtags">' in html:
old = html.split('<div class="hashtags">')[1].split('</div>')[0]
html = html.replace(f'<div class="hashtags">{old}</div>', f'<div class="hashtags">{tags_str}</div>')
@@ -140,32 +174,13 @@ def polish_with_llm(html: str, platform: str, remaining_issues: Optional[List[Di
f"- [{i['type']}] {i.get('category','')}: {i.get('detail','')} (建议: {i.get('suggestion','')})"
for i in remaining_issues
)
polish_prompt = f"""你是一个专业的内容合规优化助手。以下文章存在合规问题,请逐一修复并输出完整HTML。
需修复的问题:
{issues_desc}
原文:
{html}
要求:
- 只修复上述问题,不改变文章结构和核心内容
- 保持<h2>, <h3>, <p>等标签结构不变
- 修复后内容依然保持可读性和自然语感(不要因为合规变成生硬的表达)
- 替换敏感词时选择意思相近的替代词,不删节重要信息"""
prompt = get_prompt("compliance_fix", issues_desc=issues_desc, html=html)
else:
polish_prompt = f"""你是一个专业的内容润色助手。请润色以下文章,提升表达的自然感和可读性。
原文:
{html}
要求:
- 保持原文事实、数据、章节结构不变
- 输出相同的HTML格式(保留<h2>, <h3>, <p>标签)
- 提升表达的自然感,让它更像是人写的
- 避免AI常见表达模式(「首先其次最后」「总的来说」「值得注意的是」等)
- 短句化,读起来更流畅"""
polished = call_llm(polish_prompt, model=model, temperature=temperature, max_tokens=max_tokens, system_prompt=system_prompt)
prompt = get_prompt("compliance_polish", html=html)
polished = call_llm(prompt, model=model, temperature=temperature, max_tokens=max_tokens, system_prompt=system_prompt)
polished = clean_html_content(polished)
polished = strip_ai_preface(polished)
polished = strip_thinking_html(polished)
if '<h2' in polished or '<p>' in polished:
if len(polished) > len(html) * 0.3 and len(polished) > 100:
if not any(kw in polished[:100] for kw in ['保留', '建议', '可以', '应该', '推荐']):
@@ -178,6 +193,7 @@ def polish_with_llm(html: str, platform: str, remaining_issues: Optional[List[Di
def optimize_article(html: str, platform: str, topic_data: Dict, remaining_issues: Optional[List[Dict]] = None) -> Tuple[str, List[str]]:
logs = []
html = strip_thinking_html(html)
if platform == "wechat":
html = fix_wechat_title(html, topic_data.get("title", ""))
logs.append("标题截断(含后缀)")
@@ -185,7 +201,8 @@ def optimize_article(html: str, platform: str, topic_data: Dict, remaining_issue
before = html
html = fix_tags(html, platform)
if html != before:
logs.append(f"标签标准化为{PLATFORM_TAGS[platform]}")
tags_map = get_platform_tags()
logs.append(f"标签标准化为{tags_map.get(platform, [])}")
polished, pol_log = polish_with_llm(html, platform, remaining_issues)
if pol_log:
html = polished