✨ feat(content): 新增智能选题引擎、批量创作和图文协同优化
- 新增智能选题引擎 `TopicEngine`,整合热点数据与历史权重,提供多维度评分和创作角度建议 - 新增内容模板系统 `ContentTemplate`,支持从 JSON 文件加载模板并应用于文案生成 - 新增批量创作功能 `batch_generate_copy`,支持串行生成多篇文案并自动入草稿队列 - 升级文案质量流水线:实现 Prompt 分层架构(基础层 + 风格层 + 人设层)、LLM 自检与改写机制、深度去 AI 化后处理 - 优化图文协同:新增封面图策略选择、SD prompt 与文案语义联动、图文匹配度评估 - 集成数据闭环:在文案生成中自动注入 `AnalyticsService` 权重数据,实现发布 → 数据回收 → 优化创作的完整循环 - 更新 UI 组件:新增选题推荐展示区、批量创作折叠面板、封面图策略选择器和图文匹配度评分展示 ♻️ refactor(llm): 重构 Prompt 架构并增强去 AI 化处理 - 将 `PROMPT_COPYWRITING` 拆分为分层架构(基础层 + 风格层 + 人设层),提高维护性和灵活性 - 增强 `_humanize_content` 方法:新增语气词注入、标点不规范化、段落节奏打散和 emoji 密度控制 - 新增 `_self_check` 和 `_self_check_rewrite` 方法,实现文案 AI 痕迹自检与自动改写 - 新增 `evaluate_image_text_match` 方法,支持文案与 SD prompt 的语义匹配度评估(可选,失败不阻塞) - 新增封面图策略配置 `COVER_STRATEGIES` 和情感基调映射 `EMOTION_SD_MAP` 📝 docs(openspec): 归档内容创作优化提案和详细规格 - 新增 `openspec/changes/archive/2026-02-28-optimize-content-creation/` 目录,包含设计文档、提案、规格说明和任务清单 - 新增 `openspec/specs/` 下的批量创作、文案质量流水线、图文协同、服务内容和智能选题引擎规格文档 - 更新 `openspec/specs/services-content/spec.md`,反映新增的批量创作和智能选题入口函数 🔧 chore(config): 更新服务配置和 UI 集成 - 在 `services/content.py` 中集成权重数据自动注入逻辑,实现数据驱动创作 - 在 `ui/app.py` 中新增选题推荐、批量生成和图文匹配度评估的回调函数 - 在 `ui/tab_create.py` 中新增智能选题推荐区、批量创作面板和图文匹配度评估组件 - 修复 `services/sd_service.py` 中的头像文件路径问题,确保目录存在
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
## Requirements
|
||||
|
||||
### Requirement: 内容模板系统
|
||||
系统 SHALL 提供 `ContentTemplate` 类(`services/content_template.py`),支持从 JSON 文件加载和管理内容模板。每个模板包含 `name`、`description`、`topic_pattern`、`style`、`prompt_override`(可选)、`tags_preset`(可选)字段。
|
||||
|
||||
#### Scenario: 模板文件加载
|
||||
- **WHEN** `ContentTemplate` 初始化时
|
||||
- **THEN** SHALL 从 `xhs_workspace/templates.json` 加载模板列表;文件不存在时 SHALL 使用内置默认模板(至少包含"好物种草""日常分享""攻略教程"三个模板)
|
||||
|
||||
#### Scenario: 模板应用于文案生成
|
||||
- **WHEN** 用户选择模板后点击生成
|
||||
- **THEN** 系统 SHALL 将模板的 `prompt_override` 附加到 LLM 系统 prompt 中,`tags_preset` 作为标签默认值
|
||||
|
||||
### Requirement: 批量主题生成
|
||||
系统 SHALL 支持一次生成多个主题的文案内容,通过 `batch_generate(topics: list, style, template=None)` 方法实现。
|
||||
|
||||
#### Scenario: 批量生成返回结果
|
||||
- **WHEN** 调用 `batch_generate(["主题A", "主题B", "主题C"], "好物种草")`
|
||||
- **THEN** SHALL 返回包含 3 个文案结果的列表,每个结果与 `generate_copy()` 返回结构一致,新增 `batch_index` 字段标识序号
|
||||
|
||||
#### Scenario: 批量生成部分失败
|
||||
- **WHEN** 批量生成中某篇文案生成失败
|
||||
- **THEN** 系统 SHALL 记录该篇的错误信息(`error` 字段),继续生成剩余主题,不中断整个批次
|
||||
|
||||
#### Scenario: 批量生成数量限制
|
||||
- **WHEN** `topics` 列表长度超过 10
|
||||
- **THEN** 系统 SHALL 返回错误提示,拒绝执行(防止 LLM 配额消耗过大)
|
||||
|
||||
### Requirement: 草稿队列管理
|
||||
批量生成的结果 SHALL 自动存入 `PublishQueue`,状态为 `draft`,用户可在发布队列 UI 中逐篇审核、编辑、排期。
|
||||
|
||||
#### Scenario: 批量结果入队
|
||||
- **WHEN** `batch_generate()` 成功返回 N 篇文案
|
||||
- **THEN** 系统 SHALL 将每篇文案以 `draft` 状态插入 `PublishQueue`,包含 title、content、tags、sd_prompt 字段
|
||||
|
||||
#### Scenario: 草稿可独立操作
|
||||
- **WHEN** 用户在 UI 中选中某篇草稿
|
||||
- **THEN** SHALL 支持编辑标题/正文/标签、单独发布、丢弃等操作,不影响同批次其他草稿
|
||||
|
||||
### Requirement: 一键批量导出
|
||||
系统 SHALL 支持将多篇文案一次性导出到本地,每篇创建独立文件夹(复用 `one_click_export` 逻辑)。
|
||||
|
||||
#### Scenario: 批量导出目录结构
|
||||
- **WHEN** 用户点击批量导出并选中 3 篇文案
|
||||
- **THEN** 系统 SHALL 在 `xhs_workspace/` 下为每篇创建独立的 `{timestamp}_{title}/` 文件夹,各含 `文案.txt`
|
||||
@@ -0,0 +1,52 @@
|
||||
## Requirements
|
||||
|
||||
### Requirement: Prompt 分层架构
|
||||
系统 SHALL 将文案生成 Prompt 拆分为三个独立层,按顺序拼接后发送给 LLM:
|
||||
1. **基础层**(`PROMPT_BASE`):通用的小红书写作规则和反 AI 检测规则
|
||||
2. **风格层**(`PROMPT_STYLE_{name}`):按风格类型(好物种草、日常分享、攻略教程等)定制的写作指导
|
||||
3. **人设层**:基于用户选择的人设动态注入视角和语气约束
|
||||
|
||||
#### Scenario: 分层 Prompt 拼接
|
||||
- **WHEN** 调用 `generate_copy(topic, style, persona=...)` 时
|
||||
- **THEN** 系统 SHALL 按 基础层 → 风格层 → 人设层 的顺序拼接 system prompt,各层之间用分隔标记区分
|
||||
|
||||
#### Scenario: 风格层缺失时退回基础层
|
||||
- **WHEN** 指定的 `style` 没有对应的风格层 Prompt 模板
|
||||
- **THEN** 系统 SHALL 仅使用基础层 + 人设层,不报错
|
||||
|
||||
### Requirement: LLM 多轮自检机制
|
||||
系统 SHALL 在文案生成后调用一次自检 LLM 请求,检查文案的 AI 痕迹程度和质量评分,根据评分决定是否触发改写。
|
||||
|
||||
#### Scenario: 自检触发改写
|
||||
- **WHEN** 自检返回的 `ai_score`(AI 痕迹评分,0-100)≥ 60
|
||||
- **THEN** 系统 SHALL 将原始文案连同自检反馈一起发送给 LLM 进行改写,最多改写 1 次
|
||||
|
||||
#### Scenario: 自检通过直接返回
|
||||
- **WHEN** 自检返回的 `ai_score` < 60
|
||||
- **THEN** 系统 SHALL 直接返回原始文案,不触发改写
|
||||
|
||||
#### Scenario: 自检超时不阻塞
|
||||
- **WHEN** 自检 LLM 请求超时或失败
|
||||
- **THEN** 系统 SHALL 跳过自检,直接返回原始文案并记录警告日志
|
||||
|
||||
### Requirement: 深度去 AI 化后处理管线
|
||||
系统 SHALL 在 `_humanize_content()` 方法中新增以下后处理步骤:
|
||||
1. **语气词注入**:在合适位置随机添加"嘿""诶""啊"等真人语气词
|
||||
2. **标点不规范化**:随机删除部分逗号/句号,模拟手机打字习惯
|
||||
3. **段落节奏打散**:确保连续段落字数差异 ≥ 30%
|
||||
4. **emoji 密度控制**:全文 emoji 数量控制在 6-12 个,分布不均匀
|
||||
|
||||
#### Scenario: 后处理不改变语义
|
||||
- **WHEN** 对文案进行后处理
|
||||
- **THEN** 处理后的文案 SHALL 保留原始语义和关键信息(标签、核心观点),仅改变表达风格
|
||||
|
||||
#### Scenario: 段落节奏检测
|
||||
- **WHEN** 后处理完成后
|
||||
- **THEN** 相邻段落的字数差异 SHALL 至少有 30% 的概率满足 ≥ 30% 的差异要求(基于随机化)
|
||||
|
||||
### Requirement: 文案质量评分输出
|
||||
`generate_copy()` 方法 SHALL 在返回的 JSON 中新增 `quality_meta` 字段,包含 `ai_score`(AI 痕迹评分)、`self_check_passed`(是否通过自检)、`rewritten`(是否经过改写)。
|
||||
|
||||
#### Scenario: 质量元数据完整
|
||||
- **WHEN** 文案生成成功返回
|
||||
- **THEN** 返回的字典 SHALL 包含 `quality_meta` 字段,其中 `ai_score` 为 0-100 整数,`self_check_passed` 和 `rewritten` 为布尔值
|
||||
@@ -0,0 +1,42 @@
|
||||
## Requirements
|
||||
|
||||
### Requirement: SD Prompt 与文案语义联动
|
||||
系统 SHALL 在生成 SD Image Prompt 时,解析文案中的核心视觉元素(场景词、物品词、情绪词),并将其映射为 SD Prompt 的画面描述词,确保图片内容与文案主题语义一致。
|
||||
|
||||
#### Scenario: 文案关键词提取
|
||||
- **WHEN** 传入文案文本至图片生成流程
|
||||
- **THEN** 系统 SHALL 使用 LLM 提取文案中的视觉关键词(不超过 5 个),并将其注入 SD Prompt 的主体描述段
|
||||
|
||||
#### Scenario: 视觉关键词映射失败
|
||||
- **WHEN** LLM 提取视觉关键词失败或超时
|
||||
- **THEN** 系统 SHALL 退回使用 `style_tag + topic` 拼接的默认 Prompt,不中断图片生成流程
|
||||
|
||||
### Requirement: 封面图策略选择
|
||||
系统 SHALL 支持 4 种封面图策略,用户可在创作时选择:
|
||||
1. **AI 写真**(`ai_portrait`):生成人物写真封面
|
||||
2. **产品特写**(`product_close`):生成产品/物品近景
|
||||
3. **场景氛围**(`scene_mood`):生成场景氛围图
|
||||
4. **文字海报**(`text_poster`):生成带有文字排版的海报图
|
||||
|
||||
#### Scenario: 策略路由
|
||||
- **WHEN** 用户选择封面策略 `strategy` 并调用图片生成
|
||||
- **THEN** 系统 SHALL 根据 `strategy` 值路由至对应的 Prompt 模板和 SD 参数配置,不使用其他策略的模板
|
||||
|
||||
#### Scenario: 策略参数默认值
|
||||
- **WHEN** 用户未指定封面策略时
|
||||
- **THEN** 系统 SHALL 默认使用 `ai_portrait` 策略
|
||||
|
||||
### Requirement: 图文匹配度评估
|
||||
系统 SHALL 提供 `evaluate_image_text_match(copy_text, image_path)` 方法,使用 VL 模型(vision-language)分析图片内容与文案之间的语义匹配程度,返回 0-100 的匹配度评分和改进建议。
|
||||
|
||||
#### Scenario: 匹配度评估成功
|
||||
- **WHEN** 传入有效的文案文本和图片路径
|
||||
- **THEN** 系统 SHALL 返回包含 `match_score`(0-100 整数)和 `suggestions`(字符串列表,可为空)的字典
|
||||
|
||||
#### Scenario: VL 模型不可用
|
||||
- **WHEN** VL 模型调用失败或未配置
|
||||
- **THEN** 系统 SHALL 返回 `{"match_score": -1, "suggestions": [], "error": "VL model unavailable"}`,不抛出异常
|
||||
|
||||
#### Scenario: 低匹配度触发建议
|
||||
- **WHEN** `match_score` < 60
|
||||
- **THEN** `suggestions` 字段 SHALL 包含至少 1 条具体的图片改进建议文本
|
||||
@@ -1,10 +1,10 @@
|
||||
## ADDED Requirements
|
||||
## Requirements
|
||||
|
||||
### Requirement: 内容生成函数迁移至独立模块
|
||||
系统 SHALL 将内容生成、图片生成、发布及导出相关函数从 `main.py` 提取至 `services/content.py`,包括:`generate_copy`、`generate_images`、`one_click_export`、`publish_to_xhs`。
|
||||
系统 SHALL 将内容生成、图片生成、发布及导出相关函数从 `main.py` 提取至 `services/content.py`,包括:`generate_copy`、`generate_images`、`one_click_export`、`publish_to_xhs`、`batch_generate_copy`、`generate_copy_with_topic_engine`。
|
||||
|
||||
#### Scenario: 模块导入成功
|
||||
- **WHEN** `main.py` 执行 `from services.content import generate_copy, generate_images, publish_to_xhs, one_click_export`
|
||||
- **WHEN** `main.py` 执行 `from services.content import generate_copy, generate_images, publish_to_xhs, one_click_export, batch_generate_copy, generate_copy_with_topic_engine`
|
||||
- **THEN** 所有函数可正常调用,行为与迁移前完全一致
|
||||
|
||||
#### Scenario: 内容生成保留现有验证逻辑
|
||||
@@ -14,3 +14,11 @@
|
||||
#### Scenario: 临时文件清理逻辑保留
|
||||
- **WHEN** `publish_to_xhs` 执行完毕(成功或失败)
|
||||
- **THEN** `finally` 块中的 AI 临时文件清理逻辑 SHALL 正常执行
|
||||
|
||||
#### Scenario: 智能选题创作入口
|
||||
- **WHEN** 调用 `generate_copy_with_topic_engine(count=N)` 时
|
||||
- **THEN** 系统 SHALL 先通过 `TopicEngine().recommend(count=N)` 获取推荐选题,再对排名第一的选题自动调用 `generate_copy()`,返回文案结果和使用的选题信息
|
||||
|
||||
#### Scenario: 批量创作入口
|
||||
- **WHEN** 调用 `batch_generate_copy(topics: list, style: str, persona=None)` 时
|
||||
- **THEN** 系统 SHALL 对列表中的每个 `topic` 依次调用 `generate_copy(topic, style, persona)`,并将所有结果以列表形式返回,单个 topic 失败时记录错误并继续处理后续项,不中断整体流程
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
## Requirements
|
||||
|
||||
### Requirement: 智能选题推荐入口
|
||||
系统 SHALL 提供 `TopicEngine` 类,封装选题推荐的完整逻辑,通过 `recommend(count=5)` 方法返回推荐选题列表。
|
||||
|
||||
#### Scenario: 推荐选题返回
|
||||
- **WHEN** 调用 `TopicEngine().recommend(count=N)` 时
|
||||
- **THEN** 系统 SHALL 返回包含 N 个选题字典的列表,每个字典包含 `topic`(选题名称)、`score`(综合评分)、`angles`(创作角度列表)字段
|
||||
|
||||
#### Scenario: 推荐数量边界
|
||||
- **WHEN** `count` 小于 1 或大于 20
|
||||
- **THEN** 系统 SHALL 将 `count` 强制修正至合法范围 [1, 20],不抛出异常
|
||||
|
||||
### Requirement: 多维度选题评分
|
||||
每个候选选题 SHALL 从 4 个维度进行评分,各维度满分如下,合计 100 分:
|
||||
1. **热点相关度**(`hotspot_relevance`):满分 30 分,与当前热点话题的关联程度
|
||||
2. **账号契合度**(`account_fit`):满分 30 分,与账号人设和内容风格的契合程度
|
||||
3. **内容稀缺度**(`content_scarcity`):满分 20 分,在账号历史内容中的稀缺程度(越少发过越高)
|
||||
4. **互动潜力**(`engagement_potential`):满分 20 分,预估点赞/评论/收藏的综合表现
|
||||
|
||||
#### Scenario: 评分维度完整
|
||||
- **WHEN** 选题推荐返回结果
|
||||
- **THEN** 每个选题字典 SHALL 包含 `score_detail` 字段,其中包含上述 4 个子维度的分值
|
||||
|
||||
#### Scenario: 账号历史影响稀缺度评分
|
||||
- **WHEN** 账号近 30 天内已发布过相同或极相似选题(语义相似度 ≥ 80%)
|
||||
- **THEN** 该选题的 `content_scarcity` 评分 SHALL 不超过 5 分
|
||||
|
||||
### Requirement: 选题附带创作角度
|
||||
每个推荐选题 SHALL 附带 2-4 个差异化的创作角度(`angles`),每个角度包含`angle_name`(角度名称)和 `hook`(开头 hook 句)。
|
||||
|
||||
#### Scenario: 创作角度多样性
|
||||
- **WHEN** 同一选题返回多个创作角度
|
||||
- **THEN** 每个角度 SHALL 采用不同的叙事视角(如:亲身体验 vs 对比测评 vs 干货攻略)
|
||||
|
||||
#### Scenario: Hook 句格式
|
||||
- **WHEN** 返回 `hook` 字段
|
||||
- **THEN** hook 句 SHALL 为 15-30 字的小红书风格开头,包含至少一个情绪词或疑问词
|
||||
|
||||
### Requirement: 热点数据整合
|
||||
`TopicEngine` SHALL 调用 `HotspotService` 获取当日热点数据,并将热点话题权重纳入选题评分的 `hotspot_relevance` 维度。
|
||||
|
||||
#### Scenario: 热点服务可用
|
||||
- **WHEN** `HotspotService` 正常返回热点数据
|
||||
- **THEN** 系统 SHALL 将热点话题与候选选题做语义匹配,高匹配选题的 `hotspot_relevance` 评分加成不低于 10 分
|
||||
|
||||
#### Scenario: 热点服务不可用
|
||||
- **WHEN** `HotspotService` 调用失败或返回空数据
|
||||
- **THEN** 系统 SHALL `hotspot_relevance` 维度评分统一设为 15 分(满分 50%),不因热点数据缺失而中断选题推荐流程
|
||||
Reference in New Issue
Block a user