This repository was archived by the owner on Jul 6, 2026. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 84
Expand file tree
/
Copy pathoptimize_api.py
More file actions
124 lines (101 loc) · 4.11 KB
/
Copy pathoptimize_api.py
File metadata and controls
124 lines (101 loc) · 4.11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
"""
迭代优化接口:根据原始诊断结果生成2-3个高分优化方案,自动评分排序。
"""
from __future__ import annotations
import json
import logging
from typing import Optional
from fastapi import APIRouter, Form
from pydantic import BaseModel
from app.agents.base_agent import BaseAgent, MODEL_PRO, MODEL_FAST
from app.agents.research_data import pre_score
router = APIRouter()
logger = logging.getLogger("noterx.optimize")
OPTIMIZE_PROMPT = """你是小红书爆款内容优化专家。根据用户笔记的诊断结果(扣分原因),生成3个不同策略的优化方案。
## 每个方案包含
- strategy: 策略名称(如"情绪向""数据向""悬念向")
- optimized_title: 完整可发布标题(12-20字,至少2个钩子元素)
- optimized_content: 完整可发布正文(小红书排版,300字内,emoji分段,口语化)
- key_changes: 关键改动说明(2-3句话)
## 3个方案必须风格不同
方案A: 情绪驱动(感叹号、共鸣、夸张)
方案B: 数据驱动(数字、对比、干货)
方案C: 悬念驱动(提问、反转、好奇心)
## 正文排版规范
- 每段2-3句,段间空行
- 关键信息前用emoji(🔥💡✨📌❗)
- 口语化(姐妹们、绝了、真的)
- 结尾互动引导句
- 300字内
输出严格JSON:
{"plans":[{"strategy":"策略名","optimized_title":"标题","optimized_content":"正文","key_changes":"改动说明"},...]}\n"""
class OptimizeRequest(BaseModel):
title: str
content: str = ""
category: str = "food"
issues: str = "" # JSON string of issues array
suggestions: str = "" # JSON string of suggestions array
overall_score: float = 50
@router.post("/optimize")
async def optimize(req: OptimizeRequest):
"""生成2-3个优化方案并自动评分"""
if len(req.title) > 200:
req.title = req.title[:200]
if len(req.content) > 10000:
req.content = req.content[:10000]
if len(req.category) > 50:
req.category = req.category[:50]
issues_text = req.issues[:500] if req.issues else "无具体扣分项"
suggestions_text = req.suggestions[:500] if req.suggestions else ""
user_msg = f"""原始笔记:
- 标题:{req.title}
- 正文:{req.content[:400] if req.content else '(无正文)'}
- 品类:{req.category}
- 当前评分:{req.overall_score}分
主要问题:{issues_text}
优化方向:{suggestions_text}
请生成3个不同策略的高分优化方案。"""
agent = BaseAgent(model=MODEL_PRO)
agent.system_prompt = OPTIMIZE_PROMPT
result = await agent.call_llm(user_msg, max_tokens=3000)
result.pop("_meta", None)
plans = result.get("plans", [])
if not isinstance(plans, list):
plans = []
# Score original with pre_score first (same system as plans)
tag_count = 0
try:
orig_result = pre_score(req.title, req.content, req.category, tag_count, 0)
orig_score = orig_result["total_score"]
except Exception:
orig_score = req.overall_score
# Auto-score each plan with pre_score
scored_plans = []
for plan in plans[:3]:
if not isinstance(plan, dict):
continue
title = plan.get("optimized_title", req.title)
content = plan.get("optimized_content", req.content)
try:
score_result = pre_score(title, content, req.category, tag_count, 0)
plan_score = score_result["total_score"]
except Exception:
plan_score = orig_score + 5 # fallback
delta = round(plan_score - orig_score)
scored_plans.append({
"strategy": plan.get("strategy", "优化方案"),
"optimized_title": title,
"optimized_content": content,
"key_changes": plan.get("key_changes", ""),
"score": round(plan_score),
"score_delta": max(delta, 0), # 不显示负数
})
# Sort by score descending
scored_plans.sort(key=lambda x: x["score"], reverse=True)
# Mark the best one
if scored_plans:
scored_plans[0]["recommended"] = True
return {
"original_score": round(orig_score),
"plans": scored_plans,
}