- 新增小红书前端模块(启动服务、内容分析、爆款创作、发布记录、技能卡片、拟人设置、AI 助手) - 新增 xhs-agent-desktop 独立桌面 Agent,对接 OMS 任务调度 - 登录页重构,整合微信登录与 OMS JWT 认证 - 订单、渠道、用户中心等页面与 API 增强 Co-authored-by: Cursor <cursoragent@cursor.com>
95 lines
3.2 KiB
Python
95 lines
3.2 KiB
Python
from __future__ import annotations
|
||
|
||
from xhs_bridge.skill_catalog import SkillRecipe, compose_prompt_brief
|
||
|
||
_ANALYSIS_INSTRUCTION = """
|
||
请根据上方爆款技能配方,对下方笔记做拆解分析。输出使用 Markdown,建议包含:
|
||
1. 爆款公式匹配(情绪/实用/视觉/社交)
|
||
2. 标题与开头钩子
|
||
3. 正文结构与信息密度
|
||
4. 互动数据解读
|
||
5. 评论区亮点(如有)
|
||
6. 可借鉴的 3~5 条 actionable 建议
|
||
|
||
直接输出分析正文,不要 JSON,不要重复粘贴整篇原文。
|
||
"""
|
||
|
||
|
||
def extract_feed_image_urls(payload: dict, *, max_images: int = 6) -> list[str]:
|
||
"""从笔记详情中提取配图 URL(供图文模型使用)。"""
|
||
note = payload.get("note") or {}
|
||
images = note.get("images") or []
|
||
urls: list[str] = []
|
||
for img in images:
|
||
if not isinstance(img, dict):
|
||
continue
|
||
url = str(img.get("url") or "").strip()
|
||
if url.startswith("http"):
|
||
urls.append(url)
|
||
if len(urls) >= max_images:
|
||
break
|
||
return urls
|
||
|
||
|
||
def format_feed_for_analysis(payload: dict, *, max_comments: int = 20) -> str:
|
||
"""将详情数据整理为 AI 可读文本。"""
|
||
note = payload.get("note") or {}
|
||
user = note.get("user") or {}
|
||
interact = note.get("interact") or {}
|
||
lines = [
|
||
"【笔记信息】",
|
||
f"标题:{note.get('title') or '(无)'}",
|
||
f"作者:{user.get('nickname') or '—'}",
|
||
f"发布时间:{note.get('time') or '—'}",
|
||
f"位置:{note.get('ip_location') or '—'}",
|
||
f"类型:{'视频' if note.get('is_video') else '图文'}",
|
||
"",
|
||
"【互动数据】",
|
||
f"点赞 {interact.get('liked_count', '0')} · "
|
||
f"收藏 {interact.get('collected_count', '0')} · "
|
||
f"评论 {interact.get('comment_count', '0')} · "
|
||
f"分享 {interact.get('shared_count', '0')}",
|
||
"",
|
||
"【正文】",
|
||
note.get("desc") or "(无正文)",
|
||
]
|
||
|
||
comments = payload.get("comments") or []
|
||
if comments:
|
||
lines.append("")
|
||
lines.append(f"【评论摘录(最多 {max_comments} 条)】")
|
||
for i, c in enumerate(comments[:max_comments]):
|
||
cu = c.get("user") or {}
|
||
lines.append(
|
||
f"- {cu.get('nickname', '匿名')}:{c.get('content', '')}"
|
||
+ (f"(赞 {c['like_count']})" if c.get("like_count") else "")
|
||
)
|
||
return "\n".join(lines)
|
||
|
||
|
||
def build_analysis_prompt(recipe: SkillRecipe, feed_payload: dict) -> str:
|
||
return (
|
||
compose_prompt_brief(recipe)
|
||
+ "\n"
|
||
+ _ANALYSIS_INSTRUCTION
|
||
+ "\n\n"
|
||
+ format_feed_for_analysis(feed_payload)
|
||
)
|
||
|
||
|
||
_COMMENT_INSTRUCTION = """
|
||
请根据笔记内容与上方技能配方,生成 1 条适合发布在小红书评论区的中文短评。
|
||
要求:口语自然、不超过 80 字、不要 hashtag、不要引号包裹、不要解释分析过程。
|
||
只输出评论正文一行。
|
||
"""
|
||
|
||
|
||
def build_comment_prompt(recipe: SkillRecipe, feed_payload: dict) -> str:
|
||
return (
|
||
compose_prompt_brief(recipe)
|
||
+ "\n"
|
||
+ _COMMENT_INSTRUCTION
|
||
+ "\n\n"
|
||
+ format_feed_for_analysis(feed_payload, max_comments=8)
|
||
)
|