baseline: Clover 独立仓库首次基线提交

将 Clover 从上层产品包旧仓库中独立出来,建立专属版本控制。
当前状态=纵切片端到端已打通(登录→选品→出文出图→审核→下载包),
M1文案质量去套路化已验收。此提交作为后续按核销清单逐条修复的基线。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
yangqianqian
2026-06-16 11:30:22 +08:00
commit 6a2632da70
253 changed files with 27467 additions and 0 deletions

View File

@@ -0,0 +1,124 @@
# Clover 13环目标导向 · 修改+验收总纲
> 倩倩姐2026-06-12定调以**13环目标为导向**做交叉验证Ralph loop循环真质量达标、流程完整不假性验证。
> 13环出处`北哥回填解读与落点.md:33-49`。banana本给最硬4环引擎(找竞品/写文案/配图/裂变),本轮补全缺失的引擎环。
---
## 、模型与通道2026-06-12拍板先改这个
- Claude 系 → **claude-opus-4-8**(现 `gemini_factory.py:44` 写死 claude-sonnet-4-5要改
- GPT 系 → **gpt-5.5**(生图 gpt-image-2 不变)
- 通道:**仍只用 apiports 一套**,文案不补 codeproxy 第二路径推翻上一版修7
- 落点:`gemini_factory.py:44 _model_text``:166 MODEL_TEXT` 默认值、`.env` 的 MODEL_TEXT
> ⚠️先确认 apiports 是否真有 claude-opus-4-8 / gpt-5.5(记忆 clover-apiports-real-config 记的是 claude系+gpt5.4/5.5)。改前我会先打一个探活请求验证模型可用,不可用立即回报,不偷偷降级。
---
## 一、13环 × 现状 × 本轮动作(全景对照)
| 环 | 名称 | 现状 | 本轮 | 说明 |
|---|---|---|---|---|
| 1 | 选题 | ❌ | 不做(人工) | 热搜+爆款词库,人工环节,非系统功能 |
| 2 | **竞品爆款分析** | ❌ | **本轮补·引擎环** | =标杆8特征。banana有Invariants骨架需北哥给8维定义 |
| 3 | 关键词 | 🟡隐含 | 随2环 | 长尾词,并入标杆分析产出 |
| 4 | 卖点 | 🟡手填 | 随2环 | 竞品评价提炼,并入标杆分析 |
| 5 | 写文案 | ✅ | 修bug | 90分过滤/品牌词/客户prompt录入/模型升级 |
| 6 | 配图 | ⚠️乱码 | 修bug+3套 | 瓶身叠字/3套差异/强制3:4 |
| 7 | 排版 | ❌空白 | 二期 | 字体模板,原始就缺,非阻断 |
| 8 | 组长审核 | ✅ | 验收 | 一票否决清单已实现,核对完整度 |
| 9 | 发布 | ✅人工 | 不变 | 不自动发,交付包人工发 |
| 10 | 复盘 | ❌ | 不做(人工) | 看数据增量,人工环节 |
| 11 | **裂变** | ❌ | **本轮补·引擎环** | 1爆款→N套完整笔记包工作台内独立页 |
| 12 | 归档 | 🟡history | 完善 | 日期品类分类 |
| 13 | 达人 | ❌ | 不做(人工) | 蒲公英对接,人工环节 |
**本轮系统要补的引擎环 = 第2环(标杆分析) + 第11环(裂变)。**
**本轮要修真bug的环 = 第5环(文案) + 第6环(配图)。**
**核对完整的环 = 第8环(审核) + 第12环(归档)。**
---
## 二、按环组织的修改清单替代旧三批分法以13环为纲
### 引擎环·第5环 写文案 — 修bug
- 修5a 90分过滤生效pipeline_io.py:96+ 0条回退兜底
- 修5b 品牌词字段(客户输入,产品级)→ 文案每条植入
- 修5c custom_prompt 前端录入框现表单只有name/category客户填不进prompt
- 修5d 模型升级 claude-opus-4-8
- 修5e 文案网络退避重试text_variants.py:49
### 引擎环·第6环 配图 — 修bug+3套
- 修6a 生图3套角度×风格×叙事结构三正交维度
- 修6b 品牌词进特写图第2/6张
- 修6c 瓶身中文叠字(先最小版:只叠品牌词一处)
- 修6d 强制3:4比例image_postprocessor.py
- 修6e 生图 ai_call_logs 留痕
### 引擎环·第2环 竞品爆款分析标杆8特征— 新建【需北哥给8维定义】
- 建2a 标杆笔记加 features_json 字段+迁移
- 建2b 标杆分析service截图/文本→AI出8特征
- 建2c 前端标杆展示8特征
- ⏸️ 阻塞8个维度具体定义北哥不给做不了
### 引擎环·第11环 裂变 — 新建·XL【工作台内呈现】
- 建11a 裂变表+迁移(裂变记录/参考度/维度)
- 建11b 裂变service1爆款→N套笔记包文案+图全重做复用image引擎
- 建11c 裂变router
- 建11d 前端裂变页选爆款→参考度档位→裂变维度→看N套结果挂工作台导航
- ⏸️ 部分阻塞:参考度档位/裂变维度具体值,参考产品包扒包落盘.md:77-84 已有方案骨架
### 配套·第8环审核 / 第12环归档 — 核对+完善
- 修8 导航404删死链+补/review入口
- 修10 无key置灰引导
- 建7 图片lightbox放大
- 修12a 归档按日期/品类分类现history是平铺
### 工程底座(贯穿所有环)
- 修底1 每用户5并发上限
- 修底2 上传magic number校验
- 修底3 开任务选标杆入口benchmark_ids现固定空数组第2环要用
---
## 三、验收标准(目标导向·可勾门禁·禁假性验证)
> 每项验收=**可观测的真实结果**,不是"代码写完"。带"怎么验"的具体操作。
`13环验收清单.md`(独立文件,逐项可勾)。
---
## 四、Ralph loop 循环验证机制(防假性验证)
每个环改完,走固定循环,不通过不进下一环:
1. **改** — 按本环清单改代码
2. **跑** — 真实跑一次端到端不是单测mock是真调apiports出真文案真图
3. **验** — 对照验收清单逐项勾,**截图/贴输出为证**
4. **交叉验** — 另起agent独立读改后代码+独立跑一次,核对结论是否一致
5. **不过则回1** — 任一验收项没真勾上,回到改,不允许"差不多了"进下一环
6. **门禁** — 每环结束自问:"13环里这一环真勾上了吗还是只是码更多了"
**禁止的假性验证**(倩倩姐红线):
- ❌ 只跑单元测试就说"通过"(要真端到端)
- ❌ mock掉apiports返回假数据说"能跑"(要真出图真出文案)
- ❌ "代码逻辑上应该没问题"(要真观测到结果)
- ❌ 跳过验收清单某项说"这个应该OK"(每项都要勾,勾不上如实说)
---
## 五、执行顺序建议(纵切片优先)
**P0 先把第5环+第6环修到真质量达标**(这是已能跑的主链,先让它过关):
修5a→5b→5c→5d→5e → 6d→6e→6a→6b → 6c最小版
每步走Ralph loop。
**P1 补第2环标杆分析**等北哥给8维定义+ 配套修8/10/12/底1-3。
**P2 补第11环裂变**XL参考扒包落盘方案工作台内独立页
**待北哥给的定义卡住P1/P2先要**
1. 标杆8特征具体哪8维
2. 裂变参考度档位(高/中/低)各意味多大改动、裂变维度可选哪些

View File

@@ -0,0 +1,93 @@
# Clover 13环验收清单逐项可勾·禁假性验证
> 每项=可观测真实结果。验收必须真跑端到端+贴输出/截图为证。
> 勾选规则:□未做 / ◐做了没验 / ✅真验过(附证据)。报"✅"必附证据,无证据=没完成。
---
## 第5环 写文案 验收
| # | 验收项(怎么验) | 状态 |
|---|---|---|
| 5-1 | 跑真任务文案列表只出现≥90分的查DB text_candidates 无<90分入库除回退场景 | □ |
| 5-2 | 人为造全低分场景确认回退展示TopN且带"未达90分"标记,不空屏 | □ |
| 5-3 | hard_block违禁词的文案永不出现在列表查DB+查前端) | □ |
| 5-4 | 产品填品牌词"龙石",跑任务,**每条文案正文+标题都含"龙石"**(逐条数) | □ |
| 5-5 | 产品填custom_prompt"主打油皮",前端能录入,且生成文案体现该指向 | □ |
| 5-6 | 确认实际调用模型是 claude-opus-4-8查ai_call_logs.model字段或抓请求 | □ |
| 5-7 | 模拟apiports 503确认文案自动退避重试而非直接掉本地兜底查日志 | □ |
| 5-8 | 文案符合北哥方法论:佛系人设/无AI味词/5步框架/350-400字北哥抽看3条认可 | □ |
## 第6环 配图 验收
| # | 验收项(怎么验) | 状态 |
|---|---|---|
| 6-1 | 跑真任务,确认出**3套**图每套6张前端能按套切换选择 | □ |
| 6-2 | 3套确实不同套1痛点先行/套2场景先行/套3成分背书先行角度+风格也不同(肉眼比对不雷同) | □ |
| 6-3 | 第2张(特写)、第6张(closer)画面真带品牌词"龙石"(看图) | □ |
| 6-4 | 瓶身品牌词清晰不乱码(最小版:代码叠的字清楚)——北哥看图认可 | □ |
| 6-5 | 所有输出图严格3:41080×1440查图片实际尺寸 | □ |
| 6-6 | 跑完查ai_call_logs有生图条provider/model/success/latency齐 | □ |
| 6-7 | 产品入镜但无参考图时硬失败不降级纯文生图(验铁律未被绕过) | □ |
## 第2环 竞品爆款分析标杆8特征验收【待北哥给8维】
| # | 验收项 | 状态 |
|---|---|---|
| 2-1 | 录标杆截图+文本触发分析DB features_json 写入8个维度值 | □ |
| 2-2 | 前端标杆卡展示8特征 | □ |
| 2-3 | 开任务选了标杆,文案/图生成确实参考了标杆特征(对比有无标杆的差异) | □ |
| 2-4 | 8维度是北哥确认的定义不是开发猜的 | □ |
## 第11环 裂变 验收【XL·工作台内呈现】
| # | 验收项 | 状态 |
|---|---|---|
| 11-1 | 工作台有裂变入口(导航/页面可达) | □ |
| 11-2 | 选1条爆款→选参考度档位→选裂变维度→生成N套 | □ |
| 11-3 | 每套是**完整笔记包**(文案+图+标签+分镜),不只换文案 | □ |
| 11-4 | 高参考度学结构但替换表达防抄袭;低参考度只学骨架(对比验证档位真有差异) | □ |
| 11-5 | 裂变锁定卖点/标签/人群不变(验证锁定生效) | □ |
| 11-6 | 裂变结果可进审核→打包交付(串通主链) | □ |
## 第8环 审核 验收
| # | 验收项 | 状态 |
|---|---|---|
| 8-1 | 所有侧边栏导航点击无404逐个点 | □ |
| 8-2 | 组长能看到待审队列、通过/打回带原因 | □ |
| 8-3 | 打回后operator能感知并重选验证回路闭环现在是缺口 | □ |
## 第12环 归档 验收
| # | 验收项 | 状态 |
|---|---|---|
| 12-1 | history按日期/品类可分类筛选(现是平铺) | □ |
| 12-2 | approved任务能下载交付包zip结构完整笔记夹+命名+文案.txt+清单+合规说明) | □ |
| 12-3 | 客户输入物(产品/标杆)可导出(数据归属红线) | □ |
## 工程底座 验收
| # | 验收项 | 状态 |
|---|---|---|
| 底-1 | 同一用户开第6个任务被拒/排队验5并发上限 | □ |
| 底-2 | .exe改名.jpg+伪造content-type上传被拒验magic number | □ |
| 底-3 | 开任务页能选标杆benchmark_ids不再固定空 | □ |
| 底-4 | 无key时开任务按钮置灰+引导去配置 | □ |
| 底-5 | 图片可点击放大看细节lightbox | □ |
| 底-6 | 前端无任何token余额/用量展示(红线,全页扫) | □ |
| 底-7 | SSE用一次性ticketURL无JWT抓connection验证 | □ |
---
## 一条龙总验收(纵切片,最高门禁)
**唯一的"真完成"定义**:一个新用户,从零走通——
登录 → 建产品(填品牌词+custom_prompt+传图) → 录标杆 → 开任务(选标杆) → 出≥90分文案(含品牌词) → 出3套不雷同的图(3:4,特写带品牌词) → 确认 → 提审 → 组长过 → 下载到结构完整的交付包。
**全程不报错、不假数据、北哥抽检文案+图认可质量。**
□ 一条龙真跑通(录屏为证)
□ 北哥抽检认可(北哥确认)
> 这两项不勾上其余全勾也不算完CLAUDE.md验收线质量过关才算完最终北哥认可

View File

@@ -0,0 +1,107 @@
# Clover 前端逻辑诊断 · 数据流与交互(第一次扒·另一窗口改完需重扒)
> 你的直觉对了:"功能呈现和数据流转交互太弱"——但弱在**数据流架构**,不只在界面长相。
> 扒的是3个zustand store(generation/task/preference) + api.ts + useSse + sse.ts。
> ⚠️ 另一窗口正在改前端,本次结论是当前快照,改完重扒对比。
---
## 一、先画出前端真实的数据流
```
┌─ 进任务页 ─────────────────────────────────────────────┐
│ useSse(taskId) 启动 │
│ ① 立即 GET /tasks/{id} → hydrateFromTask (回填历史候选) │
│ ② 建 SSE: 先POST换ticket → EventSource连stream │
│ ③ SSE事件 → handleEvent → 写 generationStore │
└──────────────────────────────────────────────────────┘
↓ 组件从 store 订阅渲染
text/images页 读 generationStore.textCandidates 等
↓ 用户选择
taskStore.selectedTextIds (纯本地数组)
↓ 点"下一步"
for循环逐个 POST select → router.push 下一页
```
**三个store各管一摊**
- `generationStore`SSE进度+候选+飞轮注入(生成态)
- `taskStore`当前任务id+已选id数组选择态
- `preferenceStore`:飞轮偏好摘要(注入态)
<!-- 后续Edit补充二、数据流的7个弱点 / 三、交互弱的根因 / 四、对照俊达该补什么 / 五、待重扒清单 -->
---
## 二、数据流的7个弱点每条带代码证据
### 弱点1策略维度A/B/C在前端被彻底抹平 🔴最关键
- 后端生图按3套策略各N张`pipeline_io.py:201`SSE的`image_candidate`事件**带了strategy字段**(`useSse.ts:104`接收了)。
-`generationStore.imageCandidates` 是**一维平铺数组**(store注释明写"image_candidate无batch字段所以平铺")images页直接`grid`铺开。
- **后果**:后端辛苦做的"3个叙事方向×N张给你对比挑选"前端变成一堆看不出分组的散图。用户不知道哪些是同一策略、为什么有18张。这是"交互弱"最硬的证据——**信息结构在展示层塌掉了**。
### 弱点2文案五维分要二次请求补全且每条都重拉整个task 🔴
- `useSse.ts:75-94`SSE的`text_candidate`只推total分五维明细**靠再次 GET /tasks/{id} 补全**。
- 致命:**每来一条文案候选就GET一次整个task**(line88)8条文案=8次全量请求每次返回所有候选。N条候选→N次重复拉全量越往后越浪费。
- **后果**五维分有延迟跳变先0后补且网络浪费。交互上是"分数闪一下才出来"。
### 弱点3选择态是纯本地数组不落后端、刷新即丢 🟡
- `taskStore.selectedTextIds/selectedImageIds` 只在内存(line13)。
- 选文案时`toggleTextSelection`只改本地数组,**点"下一步"才 for循环逐个POST select**(`text/page.tsx:29-32`)。
- **后果**:①选到一半刷新页面,选择全没了 ②多选N条就发N个请求(不是批量) ③选中状态和后端`is_selected`字段不实时同步。
### 弱点4跳转用 router.push候选数据靠"重新拉" 🟡
- 每个环节(text→images→confirm)是独立页面,靠`router.push`跳转。
- 进每页 `useSse``store.reset()``hydrateFromTask`重新GET(`useSse.ts:21,30`)。
- **后果**:环节间无"连续流"感,每跳一页是一次重新加载+重连SSE。confirm页要的已选数据`generationStore`里还留着的候选`filter`出来(`confirm/page.tsx:22-23`)——**万一store被reset就空了**。
### 弱点5confirm页数据来源脆弱 🟡
- `confirm/page.tsx:22``textCandidates.filter(selectedTextIds.includes)`拿已选内容。
-`selectedTextIds`在taskStore、`textCandidates`在generationStore**两个store没绑定**。SSE的reset只清generationStoreselectedTextIds还在taskStore——两者生命周期不一致容易错位。
### 弱点6错误处理静默吞掉 🟡
- `useSse.ts:37,93` 多处`.catch(() => {})`空吞错误;`preferenceStore:31`无偏好"不阻塞流程"也静默。
- **后果**:数据没拉到时用户无感知,界面就是"空着",不知道是没数据还是出错了。这放大了"空"的感受。
### 弱点7SSE的task_done/error事件没驱动UI 🟡
- `useSse.ts:123-127``error`/`task_done`/`analyze_done`/`heartbeat`全部`break`空处理。
- **后果**:生成完成了(task_done)前端不弹提示、不自动跳转;出错了(error)也不显式告诉用户。状态机的关键节点在前端是哑的。
---
## 三、为什么"交互弱"——根因归纳
| 表象 | 数据流根因 |
|---|---|
| 图一堆看不出门道 | 策略维度被平铺抹平(弱点1) |
| 分数闪一下才出 | 五维分二次请求补全(弱点2) |
| 选着选着没了 | 选择态纯本地不持久(弱点3) |
| 翻页像重新加载 | 页面级跳转+每页重连重拉(弱点4) |
| 完成/出错没反馈 | 关键SSE事件空处理(弱点7)+错误静默(弱点6) |
> **本质**:前端是"**被动渲染后端推什么显示什么**"的薄层,没有自己的"数据组织能力"。后端给的多维数据(策略/评分/角色/理由),前端要么拍平、要么二次拉、要么不展示。**不是界面不好看,是数据进了前端没被'组织'成有结构的交互。**
---
## 四、对照俊达:他的前端为什么"饱满流畅"
俊达界面给人"饱满"感,本质是**数据被组织出了层次**
- 同一组图按策略/角色分组对比 → Clover平铺(弱点1)
- 每个产出带可见的评分/理由/标签 → Clover评分要补拉、理由没全显(弱点2)
- 操作即时反馈、状态流转有动效 → Clover关键事件空处理(弱点7)
- 进化页/复盘页是"数据看板" → Clover dashboard是3个按钮
> 借鉴点(不抄原文)**把"后端已有的多维数据"在前端组织成有结构的呈现**——分组、即时反馈、状态可见。这是纯前端重构不依赖后端加功能也不碰俊达的knowhow。
---
## 五、待重扒清单(另一窗口改完后)
本次基于当前快照。另一窗口改完前端后,重点复查这几项有没有变:
1. `generationStore` 的 imageCandidates 有没有改成按strategy分组
2. `useSse` 的五维分补全有没有改掉"每条拉全量task"
3. taskStore 选择态有没有改成持久化/批量提交
4. 关键SSE事件(task_done/error)有没有接UI反馈
5. dashboard 有没有加数据看板
6. images页有没有按A/B/C分组展示
> 重扒方法对这6个文件做 diff对照本文档逐条核实改了没。本文档是"改之前"的基线。

View File

@@ -0,0 +1,172 @@
# Clover 完整修改清单 + 方案(基于全量代码扒解)
> 来源:汇总《链路缺失诊断》《真实能力盘点》《前端逻辑诊断》三份扒解结论,去重去错判后的可执行清单。
> 口径:每条带【问题】【位置】【改法】【冲突】【工作量】。冲突=与另一窗口改前端的碰撞风险。
> ⚠️ 另一窗口在改前端,🔴冲突项落地前必须先 git status + 与那边对齐。
> 日期2026-06-12
---
## 总览:四类问题
| 类 | 条数 | 性质 |
|---|---|---|
| A. Bug类必修 | 1 | 死链404立刻劝退用户 |
| B. 前端数据流(交互弱根因) | 7 | 后端数据进了前端没组织好 |
| C. 前端展示薄(能力没露) | 4 | 后端算了前端没显示 |
| D. 后端真缺口从0做 | 3 | 改稿信号/数据复盘/爆款拆解AI |
> 关键认知:**A+B+C 共12条都是"前端接线/重构",不依赖后端加功能**。D类3条才是真·新功能。**先做A/B/C投入产出比最高**——把后端已有能力露出来,界面立刻"饱满"。
<!-- 后续Edit补充A类详情 / B类详情 / C类详情 / D类详情 / 执行顺序建议 -->
---
## A 类 · Bug必修
### A1. Sidebar 导航死链 404 🔴必修
- **问题**侧边栏4个入口指向不存在的路由一点就404。
- **位置**`frontend/src/components/layout/Sidebar.tsx:22-25`,写死 `/tasks``/images``/tasks/build``/tasks/list`,真实只有 `/tasks/[id]/text``/tasks/[id]/images`且需taskId。
- **改法**:导航语义改成"任务流"——侧栏只放真实可达的全局页(工作台/开新任务/审核台/历史/配置),删掉"选择文案/选择图片/建立任务/任务列表"这类需taskId的环节级入口环节入口由"当前任务"动态带id跳转dashboard已有RecentTasksBar可复用
- **冲突**🟢低Sidebar是导航文件另一窗口大概率没动先 git status 确认)
- **工作量**0.5天
---
## B 类 · 前端数据流交互弱的根因7条
### B1. 生图策略 A/B/C 维度被前端抹平 🔴最关键
- **问题**后端按3套叙事策略各N张生图要6张→生18张SSE带strategy字段、前端也收到了但存成一维平铺数组images页一堆散图看不出分组。
- **位置**`stores/generationStore.ts`(imageCandidates平铺) + `app/tasks/[id]/images/page.tsx:55-68`(grid平铺) + `useSse.ts:101-108`(收了strategy没用来分组)。
- **改法**generationStore 的 imageCandidates 改成**按 strategy 分组**`{A:[], B:[], C:[]}` 或 groupByimages页改成**3列/3段分策略展示**,每套标注"方向A/B/C"让用户在3个叙事方向间对比挑选。这正是俊达"多方向选优"的呈现。
- **冲突**🔴高直接改前端核心store+页面,另一窗口最可能在这一带)
- **工作量**1-2天
### B2. 五维分二次请求 + 每条重拉全量task 🔴
- **问题**SSE只推总分五维明细靠再GET整个task补全且每来一条候选就GET一次全量(8条=8次重复全量请求)分数先0后跳变。
- **位置**`useSse.ts:75-94`
- **改法(二选一)**①推荐——让后端SSE的`text_candidate`事件**直接带五维明细**(score_detail)前端一次到位不用补拉要后端配合改sse事件payload碰后端②纯前端——补拉改成**全部候选生成完后只GET一次**批量补分,不要每条拉。
- **冲突**🟡中改useSse方案①还要碰后端sse_utils
- **工作量**0.5-1天
### B3. 选择态纯本地、刷新即丢、不批量 🟡
- **问题**selectedTextIds/selectedImageIds只在内存刷新全没点下一步才for循环逐个POST(N条N请求)。
- **位置**`stores/taskStore.ts:13` + `app/tasks/[id]/text/page.tsx:29-32`
- **改法**:①选择即时 POST select或localStorage暂存刷新可恢复②或保留本地但提供**批量select接口**一次提交要后端加批量端点。最低成本选择态存localStorage按taskId隔离进页面恢复。
- **冲突**🟡中改taskStore
- **工作量**0.5天
### B4. 页面级跳转,每页 reset+重连SSE 🟡
- **问题**text→images→confirm独立页每进一页useSse都reset再重新GET+重建SSE无连续流感。
- **位置**`useSse.ts:21,30`(每次reset+hydrate) + 各页independent。
- **改法**①已完成阶段的候选不必重连SSE只生成中才连——按task.status判断要不要建SSE连接已selection/review态只拉一次数据不连流②或用单一任务容器布局保留store不reset跨环节。
- **冲突**:🟡中
- **工作量**1天
### B5. confirm页数据来源脆弱跨store错位🟡
- **问题**confirm用 generationStore.textCandidates.filter(taskStore.selectedTextIds) 拼已选两store生命周期不一致reset一边另一边错位就显空。
- **位置**`app/tasks/[id]/confirm/page.tsx:22-23`
- **改法**confirm页**独立GET /tasks/{id}** 拿权威的is_selected候选不依赖两个store的内存拼接。后端get_task已返is_selected直接用。
- **冲突**:🟡中
- **工作量**0.5天
### B6. 错误静默吞掉,放大"空"感 🟡
- **问题**:多处 `.catch(()=>{})` 空吞,数据没拉到用户只见空白,不知是没数据还是出错。
- **位置**`useSse.ts:37,93``preferenceStore.ts:31` 等。
- **改法**catch里至少 set一个error态页面区分"加载中/空数据/出错可重试"三态,给空状态配文案+重试按钮review页已有空态范例可抄
- **冲突**:🟢低(加错误态,不动主逻辑)
- **工作量**0.5天
### B7. 关键SSE事件(task_done/error)空处理 🟡
- **问题**task_done生成完不提示不跳转、error出错不告知状态机关键节点前端是哑的。
- **位置**`useSse.ts:123-127`(全部break)。
- **改法**task_done→toast"生成完成"+按钮去挑选/自动滚动error→显式错误条+重试入口heartbeat可继续忽略。
- **冲突**:🟢低
- **工作量**0.5天
---
## C 类 · 前端展示薄后端算了没露4条
### C1. dashboard 门面空 🔴
- **问题**工作台只有1句问候+3个按钮后端那么多能力(今日生成/待审/飞轮进度/近期任务)一个没露。第一眼就"空"。
- **位置**`app/dashboard/page.tsx`
- **改法**:加数据看板——今日生成任务数/待审数/已通过数(GET /tasks?status=统计)、近期任务流(RecentTasksBar已有)、飞轮已学信号数(GET preference/context)。把后端有的数字摆出来。
- **冲突**🟢低dashboard另一窗口少碰新增展示
- **工作量**1天
### C2. 审核卡不显示七维分 🔴
- **问题**:审核员通过/打回时**看不到AI评委打分**盲拍。后端有score但review队列没返、卡没显。
- **位置**`components/review/ReviewCard.tsx`(只显product/theme/正文2行) + `api/v1/review.py:_fmt_queue_item`(没返score_json)。
- **改法**`_fmt_queue_item`补返已选文案的score_json+verdict+summaryReviewCard复用ScoreDimBars组件显分。让审核基于分数。
- **冲突**🟡中碰review.py但approve/reject逻辑不动只加返回字段
- **工作量**0.5天
### C3. 图片候选只显url+role 🟡
- **问题**后端storyboard算了每张图的goal/卖点/视觉策略/角色,`_fmt_image`只返role/url/strategy/seq前端只显url+role。
- **位置**`api/v1/tasks.py:_fmt_image` + images页/ImageProgressCard。
- **改法**先定要不要把分镜role中文化(hook→"封面钩子")+显示该图承担的叙事角色进阶可让后端存storyboard的overlay_text等供前端显示"这张图要表达什么"。
- **冲突**:🟡中
- **工作量**0.5-1天
### C4. ConfigPreviewPanel 注释与实现不符 🟢
- **问题**:注释说"显示成分/质地/参考图3张",实际代码只渲染名称/品类/卖点/风格/角度,没参考图没成分。
- **位置**`components/tasks/ConfigPreviewPanel.tsx`
- **改法**:要么补上参考图缩略(product.image_path后端有)+目标人群target_audience/brand_keyword(后端012字段已有),要么改注释对齐实现。建议补字段,产品档案信息更全。
- **冲突**:🟢低
- **工作量**0.5天
---
## D 类 · 后端真缺口从0做3条
### D1. 改稿→飞轮信号(最强信号)🔴价值最高
- **问题**:俊达最强飞轮信号是"人改AI稿"Clover完全没有。enums无text_edit、TextCandidate无edited字段。
- **位置**`constants/enums.py:57`(SignalType)+`ai_engine/constants.py`(FLYWHEEL_WEIGHTS两处)、`models/task.py:TextCandidate`、新端点、`preference_aggregator.py`(注入改稿示范)、`TextCandidateCard.tsx`(加可编辑)。
- **改法**:已有独立细案《俊达增量①-改稿diff-实施细案.md》S1-S5全拆好+并发避让(走task_actions不碰review.py)。直接按那份做。
- **冲突**:🔴高(碰enums两处权重要手工merge细案已设计绕开review.py)
- **工作量**2-3天
### D2. 数据复盘——发布后数据回收 🔴真缺
- **问题**:链路止于下载交付包,发出去的赞藏评/转化完全不回收,飞轮缺"结果反馈"闭环。全后端无此模块。
- **位置**:全新——新表(note_performance)+录入入口(手填或导入)+复盘页+回灌飞轮。
- **改法**:一期可极简——人工回填"这篇发布后数据如何"(赞藏评/是否爆),进库当强信号回灌。不必自动抓小红书(合规+反爬风险高)。
- **冲突**:🟢低(全新模块)
- **工作量**3-5天含UI
### D3. 爆款拆解 AI 解析逻辑 🟡
- **问题**BenchmarkNote有features_json+analyze_status字段、fission.py有裂变引擎但**爆款8特征的AI解析逻辑+UI没接**。
- **位置**`models/product.py:BenchmarkNote`(字段已建)、`fission.py`(引擎已建)、缺service+缺UI入口。
- **改法**:补"标杆笔记→AI拆8特征→写features_json"的service+触发按钮;裂变引擎接前端入口(选爆款→设套数→生成)。字段和引擎都在,主要是接线+AI prompt。
- **冲突**:🟢低(基本全新接线)
- **工作量**2-3天
---
## 执行顺序建议按ROI + 并发安全)
> 原则先低冲突高收益、把后端已有能力露出来再碰高冲突和从0做的。具体哪些交AI、哪些你亲自看你拍。
**第一波·低冲突立竿见影(可立刻做,避开另一窗口热区):**
- A1死链(0.5d) + B6错误态(0.5d) + B7关键事件(0.5d) + C4配置面板(0.5d) + C1 dashboard看板(1d)
- 小计~3天界面立刻不报错+变饱满,几乎不碰另一窗口核心文件
**第二波·数据流重构(需与另一窗口对齐后做):**
- B1策略分组(1-2d最关键) + B2五维分(0.5-1d) + C2审核显分(0.5d) + B5 confirm独立拉(0.5d)
- 小计~3-4天解决"交互弱"主因
**第三波·收尾前端:**
- B3选择持久(0.5d) + B4跳转优化(1d) + C3图片信息(0.5-1d)
**第四波·后端新功能从0做独立推进**
- D1改稿diff(2-3d价值最高) → D3爆款拆解接线(2-3d) → D2数据复盘(3-5d)
> ⚠️ 三条铁律:①🔴冲突项动手前必 git status + 跟另一窗口对齐 ②D1严格按已有细案走(绕开review.py) ③每波做完先验证(build+跑通)再下一波。
---
## 一句话给倩倩姐
**12条前端问题(A+B+C)本质是"接线/重构"把后端已经做好的能力露出来界面立刻饱满、交互立刻顺——这是性价比最高的。3条后端缺口(D)才是真新功能其中改稿diff价值最高、细案已就绪。**
> 待另一窗口改完B/C类要按《前端逻辑诊断》第五节6项重扒对比确认哪些那边已经改了避免重复劳动。

View File

@@ -0,0 +1,143 @@
# Clover 真实能力盘点 + 对照修正读完6365行后端后的诚实版
> ⚠️ 重要:本文档**修正**我之前《俊达vsClover-逐界面对照缺陷清单》里的多处错判。
> 之前只读了前端8页+零星后端就下结论冤枉了好几处。这次读完后端全部API+核心services+workers后重写。
> 倩倩姐在另一窗口"看到功能挺多"是对的——很多能力**在后端实现了,只是前端没接/没可视化**。
---
## 一、先认错:我之前判错的地方
| 我之前的判断 | 真实情况(代码为证) | 性质 |
|---|---|---|
| "改稿环节缺失" | ✅确实没有改稿。但我没说清:选优/重生成/导入轨都有(`task_actions.py`) | 判断对,但描述把整体说薄了 |
| "图片卡信息薄=只有url+role" | 后端 `ImageCandidate` 确实只存role/url/strategy/seq**但生图引擎极丰富**(见下) | 🔴**冤枉**:薄的是展示,不是能力 |
| "拆解中心只能录入不能拆配方" | `fission.py`是**第11环裂变引擎**(1爆款→N套笔记包),不是"只录入" | 🔴**判错**裂变能力建了表是没接UI |
| "平台对抗待确认Clover做到哪" | `image_postprocessor.py`**已实现**:去元数据+削像素水印+SynthID破除+Gemini重绘兜底 | 🔴**漏看**:对抗层早做了 |
| "双通道生图待确认" | `image_gen.py`**已实现**主备通道(gpt-image-2主/Gemini备)+多中转站(apiports/codeproxy)切换+重试退避 | 🔴**漏看**:双通道在 |
| "模板库藏代码里" | storyboard有完整分镜模板体系(`storyboard_templates.py`174行) | 部分对,但低估了成熟度 |
> 教训:我拿"前端没显示"当"功能不存在",这是硬伤。**Clover后端比前端展示出来的强得多。**
<!-- 后续Edit补充二、后端真实能力全景 / 三、真正的缺口(修正版) / 四、前后端能力落差 / 五、对照俊达的真实差距 -->
---
## 二、后端真实能力全景(读完代码确证·这些都已实现)
**文案生成链(强):**
- `_text_prompt.py`:人设/随机变量池ABC/5步框架/四段结构/5类标题公式/反AI味/emoji规则方法层vs数据层分离
- `text_variants.py`:双轨(AI生成+导入)、分批生成(避60s网关超时)、三层兜底、可选优化轮、本地草稿兜底
- `llm_scorer.py`**AI评委打分**——模型真读文案给6维分+理由+verdict+summary合规第7维机械硬拦失败回退机械打分
- `replenish_task.py`:合格数不足时**后台异步补充**到目标条数(先展示后台补铁律)
**生图链(很强,我之前严重低估):**
- `storyboard.py`**分镜引擎**——按图数排叙事角色(3/6/8张不同链路)、品牌词第2/6张植入、逐图差异化9字段prompt、成组视觉统一
- `image_gen.py`**主备双通道**(gpt-image-2带产品图edits / Gemini备)、多中转站切换、限并发、指数退避重试
- `image_postprocessor.py`**去AI化对抗**——去C2PA元数据+轻/重采样削像素水印+SynthID破除(可选)+Gemini重绘兜底
**飞轮链(已转):**
- `preference_aggregator.py`聚合最近50条信号→偏好角度+打回原因→注入prompt冷启动用产品档案按product_id隔离防串货三层继承(L1品牌>L2矩阵>L3个人)
- `task_actions.py`:选文案+3/选图+3/重生成-1 信号都记录
- `flywheel_service.py`record_signal + get_preference_context
**裂变链(建了表+引擎待接UI**
- `fission.py`第11环裂变引擎1爆款→N套完整笔记包带reference_level/fanout_count/status状态机
**交付链(完整):**
- `delivery.py`:打包→一次性下载令牌(60s)→FileResponse下载双认证(token/JWT)
---
## 三、真正的缺口(修正版·只留确证的)
读完后端后,真正站得住的缺口收敛到这几条:
| 缺口 | 性质 | 确证依据 |
|---|---|---|
| **1. 改稿→飞轮信号** | 真缺 | `SignalType`(enums.py:57)无text_edit`TextCandidate`无edited字段。这条仍成立 |
| **2. 裂变引擎没接前端UI** | 真缺UI | `fission.py`引擎在,但前端无裂变页、无入口 |
| **3. 数据复盘(发布后回收)** | 真缺 | 全后端无"发布后赞藏评回收"模块,链路止于交付包 |
| **4. dashboard门面空** | 真缺 | `dashboard/page.tsx`只有3按钮后端那么多能力一个没露 |
| **5. Sidebar死链404** | 真bug | `Sidebar.tsx:22-25`指向不存在路由 |
| **6. 图片候选展示薄** | 展示缺,非能力缺 | 后端storyboard算了role/goal/卖点/视觉策略,但`_fmt_image`只返role/url/strategy/seq前端只显示url+role |
| **7. AI评委理由没充分展示** | 展示缺 | 后端有verdict/summary/6维note前端TextCandidateCard展示了但confirm页等只显示总分 |
> **关键转变**:之前我列的"素材库缺失/拆解缺失/对抗缺失/双通道缺失"大半是错的——**对抗、双通道、分镜、裂变引擎后端都有**。真缺口收敛到:①改稿信号 ②裂变没接UI ③数据复盘 ④门面空 ⑤死链 + 两处展示薄。
---
## 四、前后端能力落差(这才是"空"的真因)
**这是核心洞察**Clover 的问题不是"功能少",是**后端能力没在前端露出来**。
| 后端有的能力 | 前端露出了吗 |
|---|---|
| 分镜引擎(每张图有role/goal/卖点/视觉策略/依据) | 🔴只显示url+role两字段 |
| 主备双通道+对抗去AI化 | 🔴用户完全无感(后台默默跑) |
| AI评委6维分+理由+verdict | 🟡文案卡露了,其他页只剩总分 |
| 后台补充合格文案 | 🔴用户不知道在补 |
| 裂变引擎 | 🔴无入口 |
| 飞轮偏好注入 | 🟡只一条banner |
> 俊达"界面饱满"的感觉,本质是**他把后台算的每一步都可视化了**。Clover后台算得不比他少但**前端只露了冰山一角**,所以显得"空"。这跟"功能缺失"是两个完全不同的问题——**前者是接线/可视化工作量后者是从0造功能。Clover大多属前者。**
---
## 五、对照俊达的真实差距(收敛后)
| 维度 | 真实结论 |
|---|---|
| 文案生成 | **不弱于俊达**AI评委+飞轮+反AI味都有 |
| 生图质量工程 | **可能不弱**,双通道+分镜+对抗去AI化都有 |
| 飞轮 | 骨架在,**缺最强信号(改稿diff)**,且可视化弱 |
| 资产化/裂变 | **引擎在缺UI接线** |
| 数据复盘 | **真缺**俊达有发布后回收Clover止于交付 |
| SCRM销售线 | 整块没做(商业决策,待倩倩姐判) |
| **呈现/可视化** | **这是最大差距**——后端能力强,前端露太少,所以"显空" |
> 一句话修正:**不是Clover功能比俊达少很多是Clover把做好的能力藏在后端没给用户看。** 你那个窗口看到"功能挺多",看到的就是这些后端实现。我之前只扫前端,所以误判成"空、缺失"。
---
## 六、仍未读、不装看到的
- `products.py`(308行,最大文件) — 产品档案完整能力未读
- `pipeline_io.py`(298行) — 文案/图片生成存储编排未读
- `gemini_factory.py`(225行) — AI客户端构造未读
- `storyboard_templates.py`/`_score_prompt.py`/`_scoring_dims.py` — 模板和评分维度细节未读
- 前端:`ImageProgressCard`/`ReviewCard`/`ConfigPreviewPanel`等组件本体未读
- 数据库迁移到011011/010之后有无新增未确认
> 要补到100%确证,这几个还得读。但**主干结论后端强、前端露得少、真缺口5条已经站得住**。
---
## 七、补读完成(已清零未读区)— 又发现3处关键事实
读完 `products.py`/`pipeline_io.py`/`review.py` + 前端剩余组件后,新增确证:
### 新发现1生图实际跑「3套正交策略 × N张」前端拍平丢了策略维度 🔴
- `pipeline_io.py:201` 明写 `for strategy in ("A","B","C")`,每套各生 image_count 张。**用户要6张→后端实际生18张候选**。
- `ImageProgressCard.tsx` 本是为"批次/策略"设计的(有BatchState)**但 images 页(line55-68)是平铺所有图、没按A/B/C分组**`_fmt_image` 返回了strategy字段但前端没用来分组。
- 结论:**后端做了"3种叙事方向给你挑",前端拍平成一堆散图**。这是俊达"双通道选优"思路Clover其实有雏形(3策略),但展示层没体现。
### 新发现2产品图 vision 智能分析已实现 🟢(我完全没提过)
- `products.py:254` `analyze-image` 接口上传产品图→GPT vision 读图→自动产出卖点/人群/场景/关键词/违禁词/拍摄方向 JSON。
- 这等于俊达"拆解"能力的一种——**只是用在产品建档,不是用在爆款逆向**。Clover有读图理解能力我之前一字未提。
### 新发现3爆款8特征分析字段已建 🟡
- `BenchmarkNote.features_json` + `analyze_status`(pending/analyzing/done/failed):标杆笔记预留了"AI解析8特征"的字段和状态机。
- 说明"爆款拆解"在数据层已开口子差AI解析逻辑+UI。比我之前说的"只能录入"更进一步。
### 复核确认的展示薄(确证):
- `ReviewCard`:审核卡只显示 product/operator/theme/正文2行+图,**不显示七维分**——审核员看不到AI评委打分就要拍板通过/打回。这是确证的展示缺失。
- `ConfigPreviewPanel`:注释说"显示成分/质地/参考图3张"**实际代码没渲染参考图、没成分**,只有名称/品类/卖点/风格/角度。注释与实现不符。
- `ScoreDimBars`✅做得好数据驱动渲染AI评委dims+note有hover理由。
- `FlywheelBanner`:✅但确实只是一条横幅,飞轮存在感弱。
### 最终未读(已很次要,不影响结论):
- `gemini_factory.py`/`storyboard_templates.py`/`_score_prompt.py`/`_scoring_dims.py`:都是"已确证存在能力"的实现细节,读不读不改变结论。
- `pipeline_io` 已读到生图主循环,确认无遗漏大功能。
> **补读后主干结论不变,反而更强**Clover后端能力比前端展示的多得多生图3策略18张→前端拍平、vision分析→没UI入口体现、爆款8特征→留了字段。**"空"的根因100%确证是"前后端能力落差",不是功能缺失。** 真缺口仍是那几条:①改稿信号 ②裂变/爆款拆解的AI逻辑+UI ③数据复盘 ④门面空 ⑤死链,外加多处"后端算了前端没露"。

View File

@@ -0,0 +1,113 @@
# Clover 链路缺失诊断 + 代码层/Prompt层开工清单
> 对照俊达"完整闭环",逐行扒 Clover 真实代码后的诊断。每条都标了**文件:行号**和**改法**。
> ⚠️ 并发backend/frontend 另一窗口在改15:34时间戳本清单只诊断+给改法,落地前先看冲突列。
---
## 一、定性结论(先看这个)
你说的三个症状,根因各不相同,别一锅炖:
| 你的感受 | 真实根因 | 性质 |
|---|---|---|
| "点文案按钮404" | Sidebar导航写死了4个不存在的路由 | **死链bug**,半天能修 |
| "界面比较空" | prompt产出丰富但前端没把"五维分/角度/飞轮/资产"可视化出来 | **呈现层缺失** |
| "逻辑链路有缺失" | 能跑通,但是"断点式8孤岛",不是俊达的"一个任务流过的闭环" | **链路编排缺失** |
> 反常识发现:**prompt层不空反而饱满**。`_text_prompt.py` 已有人设/变量池ABC/5步框架/四段结构/5类标题公式/反AI味/emoji规则做了方法层vs数据层分离。空的是"产出之后怎么呈现、怎么串环、怎么沉淀"。
<!-- 后续Edit补充二、404死链详情 / 三、链路缺失 / 四、呈现层缺失 / 五、prompt层缺什么 / 六、开工优先级 / 七、并发冲突列 -->
---
## 二、404死链详情最急先修这个
**`frontend/src/components/layout/Sidebar.tsx:19-28` NAV_ITEMS 写死了占位路径:**
| Sidebar标签 | 写的href | 真实路由 | 现状 |
|---|---|---|---|
| 选择文案 | `/tasks` | 只有 `/tasks/[id]/text` | 🔴404 |
| 选择图片 | `/images` | 只有 `/tasks/[id]/images` | 🔴404 |
| 建立任务 | `/tasks/build` | 不存在 | 🔴404 |
| 任务列表 | `/tasks/list` | 不存在 | 🔴404 |
**根因**:文案/图片页是挂在具体任务下的(路由含 `[id]`,见 `app/tasks/[id]/text/page.tsx`),但侧边栏把它们做成了**无taskId的全局入口**。没有"当前任务"时点击→跳无id路由→404。
**改法二选一推荐B**
- A临时止血把这4个死项从NAV_ITEMS删掉/置灰,只留真实可达的(工作台/开新任务/审核台/历史/配置)。
- **B正解**:导航改成"任务流"语义——侧边栏不再放"选择文案"这种环节级入口,环节入口由"当前进行中的任务"动态带 taskId 跳转dashboard已有 `RecentTasksBar` 组件可复用)。这正是俊达"一个任务流过所有环"的呈现方式。
---
## 三、逻辑链路缺失(你说的"链路不完整"
**真实可跑通的链路**(从代码反推):
```
dashboard → tasks/new → [id]/text → [id]/images → [id]/confirm → review → history
✅ ✅ ✅ ✅ ✅ ✅ ✅
```
单条链路是通的。但对照俊达**缺3个闭环回路**
| 缺的回路 | 俊达有 | Clover现状 | 触达文件 |
|---|---|---|---|
| **改稿→飞轮** | 人改AI草稿diff喂回去最强信号 | `SignalType`(enums.py:57-63)只有5种**无text_edit**TextCandidate(task.py:73)**无edited字段** | 见配套《增量①改稿diff细案》 |
| **审核→爆款库** | 过审的爆款拆解进资产库复用 | `fission`表已建有`reference_level`,但**无service/api接线** | 配套映射文档②|
| **任务列表回看** | 全局看所有任务状态流转 | **页面根本不存在**Sidebar指向的`/tasks/list`是空的)| 需新建 `app/tasks/list/page.tsx` |
> 链路不是"断",是"只有一条单向流,没有俊达那种'产出→沉淀→回灌'的回路"。这跟底层逻辑逆向文档§2飞轮四动作完全对应——Clover的飞轮①捕获缺最强信号、资产库②没接线。
---
## 四、呈现层缺失(你说的"界面空")—— 已逐组件核实,需修正
**核实后修正:文案卡 `TextCandidateCard.tsx` 其实很饱满**,渲染了:角度标签(55)、正文+展开收起(56-67)、违禁词状态(70-78)、**七维分数条ScoreDimBars(81)**、AI评委总评verdict+summary(84-93)。这张卡不空。
所以"界面空"不在文案卡。真正可能空的位置,重新定位:
| 怀疑位置 | 待核实文件 | 为什么怀疑 |
|---|---|---|
| **工作台dashboard** | `app/dashboard/page.tsx`(已读) | 🔴**确证空**只有3个DashCard+一句问候无数据看板、无近期任务、无飞轮进度。俊达进系统是仪表盘Clover是3个按钮 |
| 图片卡 | `ImageProgressCard.tsx` | 未核,存疑 |
| 审核卡 | `ReviewCard.tsx` | 未核,存疑 |
| 历史/归档页 | `app/history/page.tsx` | 未核,可能只是列表无成品预览 |
| 任务列表页 | 不存在 | 🔴确证缺失 |
> **修正结论**:不是"卡片空",是"**着陆页和全局视图空**"。用户一进来是dashboard3个按钮缺俊达那种"今天生成X条/待审Y条/飞轮已学Z条"的仪表盘感。空的是**框**,不是**卡**。这个判断比之前准。
---
## 五、Prompt层到底缺什么其实缺得不多
`_text_prompt.py` 已很饱满。对照俊达**只缺2块**
1. **改稿示范注入**:俊达把"人改过的好稿"当few-shot塞进prompt。Clover的 `build_prompt`(line126) 现在只注入产品数据+随机变量,**没有"参考这些人工修订过的范本"这一段**。← 配套改稿diff细案S4要补的就是这个。
2. **图片prompt的资产复用**文案prompt成熟但生图prompt(`storyboard.py`)有没有复用"历史选中的好图风格"待查。俊达双通道+后台选优Clover是否只是单通道一次性生图待确认。
> 结论:**prompt层不需要大改只需把飞轮的"改稿范本"接进 `build_prompt` 的注入段**。这跟"界面空"是两码事,别混。
---
## 六、开工优先级按ROI和并发安全排序
| 序 | 干什么 | 工作量 | 并发风险 | 价值 |
|---|---|---|---|---|
| **P0** | 修Sidebar死链404 | 半天 | 🟢低(纯前端导航) | 立刻不404 |
| **P1** | 核查并补全卡片字段渲染(五维分/角度/违禁词) | 1-2天 | 🟡中(动卡片组件) | 界面立刻"饱满" |
| **P2** | 改稿diff飞轮(见独立细案) | 已拆好 | 🔴高(碰enums/review) | 最强飞轮信号 |
| **P3** | 新建任务列表页 + 导航改任务流语义 | 1-2天 | 🟡中 | 链路闭环呈现 |
| **P4** | 爆款库接线 | 二期 | 🟢低(新模块) | 资产化 |
---
## 七、并发冲突列(另一窗口在改,落地前必看)
| 文件 | 冲突等级 | 说明 |
|---|---|---|
| `api/v1/review.py` | 🔴最高 | 改稿diff细案已确认绕开它走task_actions |
| `constants/enums.py` | 🟡 | 加text_edit信号要动这里**仅此处需手工merge** |
| `components/tasks/*.tsx` | 🟡 | 补字段渲染会动卡片先git status看另一窗口动没动 |
| `Sidebar.tsx` | 🟢 | 导航文件另一窗口大概率没碰P0可先动 |
> 落地任何一条前:先 `git status` + `git log --oneline -5` 看另一窗口提交到哪了,再动手。

View File

@@ -0,0 +1,59 @@
# 实施方案:生图带产品参考图 + 禁止降级 + 产品库
> 倩倩姐 2026-06-08 拍板:①上传产品图按钮做必填项(需产品图场景)②建任务时用户选"本次要不要产品入镜"③这轮一起做产品库(内置+上传)
## 一、现状(已查清)
**已存在、能用的**
- 产品图上传接口 `POST /products/{id}/upload-image`
- 前端上传组件 `ProductImageUpload`(在配置页产品管理里)✅
- worker 读参考图 → 传 generate_storyboard_images 的链路 ✅
- 产品表已有 `source enum('preset','custom')` 字段(产品库内置/自建早有预留)✅
- 主备生图通道本轮已修apiports 503 自动切 codeproxy
**缺口/坑**
1. 无图时 worker 默默降级纯文生图,无任何阻断(核心要堵)
2. 产品图存/读用**相对路径**api 容器 cwd 与 worker cwd=`/` 不一致 → worker 可能读不到(隐患,需改绝对路径)
3. 建任务时用户看不到"产品有没有图"、也没有"要不要产品入镜"的选择
4. 产品库目前只有 1 个 preset 产品、无图;没有产品库浏览/选择 UI
5. `ProductCreate` DTO 无 image_path建产品时无法带图
## 二、产品决策落地(按倩倩姐拍板)
- 建任务页加开关 **「本次产品是否入镜」**need_product_image默认"是"
- 选"是" → 该产品**必须有参考图**才能点"生成",否则按钮置灰提示"请先上传产品图"
- 选"否" → 允许纯文生图(氛围/科普/话题类内容)
- 产品来源:**内置产品库 + 上传**,靠 `source` 字段区分
## 三、改动清单(分纵切片,逐块可验收)
### 切片 A路径修稳最高优先不修后面全是空中楼阁
- `products.py` upload-image存**绝对路径**`/app/uploads/...`)进 image_path不存相对路径
- `pipeline_io.py` 读参考图:用绝对路径校验 + 读取
- 验收:上传一张图 → worker 日志出现"产品参考图已加载 N bytes"
### 切片 B后端禁降级 + 建任务字段
- `task.py` 模型 + migrationGenerationTask 加 `need_product_image: bool default True`
- `CreateTaskRequest` DTO 加 `need_product_image: bool = True`
- `task_service` 建任务时:若 need_product_image=True 且产品无 image_path → 直接拒绝422"该产品未上传参考图"
- `image_gen.py``ALLOW_TEXT_ONLY_IMAGE` 改由任务的 need_product_image 驱动need=True 时无参考图**硬报错**不降级
- 验收:无图产品 + 需入镜 → 建任务被拒;有图 → 生图带参考图
### 切片 C前端建任务页
- NewTaskForm 加「产品是否入镜」开关 + 展示当前产品图缩略图/未上传状态
- 需入镜且无图 → "生成"按钮置灰 + 提示"请先到产品库上传参考图"
- 验收:浏览器走一遍,无图拦住、有图放行
### 切片 D产品库内置+上传)
- 后端:`GET /products` 支持按 source 筛选;预置 2-3 个常用内置产品(带图)入库 seed
- 前端:配置页产品管理区分"内置库/我的产品",支持从内置库选用、上传自己的
- `ProductCreate` DTO 加 image_path建产品即可带图
- 验收:产品库能看到内置产品、能上传新产品、建任务能选到
## 四、风险/待北哥确认
- **内置产品库放哪些产品+图**:需北哥给真实产品图素材,否则内置库是空壳。先搭框架+占位,图等北哥给。
- 合规产品图入镜后gpt-image-2 仍可能把功效词画进图([[clover-image-gen-compliance-risk]]),需北哥合规 prompt 方案。
## 五、建议执行顺序
A路径→ B后端禁降级→ C前端建任务→ D产品库
每切片做完即验收A+B+C 通了"禁降级"主线就闭环D 是产品库增强。

View File

@@ -0,0 +1,118 @@
# 俊达 vs Clover 逐界面/逐功能对照 · 缺陷清单
> 目的:拿俊达完整产品当标尺,逐个功能、逐个界面比,**只找 Clover 不完整/缺失/单薄的地方**。怎么改是后面的事,这里只列问题。
> 已读全貌Clover前端8页面+25组件全部读完俊达13功能模块系统A内容中台7 + 系统B SCRM 6
> 对照口径:✅有且饱满 / 🟡有但薄 / 🔴缺失 / ⚪不适用(北哥不做这块业务)
---
## 零、先说一个总判断
Clover ≈ **只实现了俊达「系统A内容中台」里"单条内容生产线"那一段**(开任务→挑文案→挑图→确认→审核→归档下载)。
俊达的 **系统B SCRM 整块、系统A的"进化页/数据复盘/拆解中心/素材库/关键词"几乎全缺或很薄**
换句话说:**Clover 是一条"生成流水线",俊达是一个"会进化、能复盘、带资产库、还接销售"的运营操作系统。** 你感觉"空、不完整",根子在这。
<!-- 后续Edit补充一、系统A逐功能对照 / 二、系统B逐功能对照 / 三、UI呈现层对照 / 四、链路完整性对照 / 五、缺陷汇总分级 -->
---
## 一、系统A内容中台逐功能对照
| # | 俊达功能 | 俊达怎么做 | Clover对应 | 状态 | 缺什么/薄在哪 |
|---|---|---|---|---|---|
| A1 | **AI助手中心/进化页** | 每个环节是一张agent卡能看到"这个环学了多少、进化到第几代",是系统的脸 | 只有 `FlywheelBanner` 一个横幅条new/text/images页顶 | 🔴**几乎缺失** | 没有"agent进化"的可视化主页。飞轮只在生成页闪一条banner平时看不见"系统在变聪明"。俊达的魂在Clover是个配角 |
| A2 | **内容创作工作流** | 选题→生成→选优→改稿→成稿,一条可视流水线 | text→images→confirm 三页 | 🟡**有但断**| ①无"选题"环节(直接填theme) ②**无"改稿"环节**(选了就走不能改AI稿) ③三页之间是跳转,不是一条能回看的流水线 |
| A3 | **素材库(资产化+评级)** | 图/压字/标题/卖点/评论分门别类入库,每条打参考等级,下次直接调 | `fission`表有`reference_level`字段,但**无页面无service** | 🔴**缺失** | 完全没有"素材库"这个界面。产出用完即弃,不沉淀、不能复用、不能调库生成 |
| A4 | **拆解中心(爆款逆向)** | 贴竞品爆款→拆出标题公式/结构/卖点/配图节奏→进库 | `benchmarks`(标杆笔记)只能录入,`fission`表建了没接线 | 🟡**只录入不拆解** | 能存标杆笔记,但**没有"自动拆解出配方"的功能**。俊达是拆完进库复用Clover只是存了个参考 |
| A5 | **数据复盘** | 发布后回收数据(赞藏评/转化)→反哺哪种内容好 | `history`只有任务列表,**无发布后数据回收** | 🔴**缺失** | 链路在"下载交付包"就断了。发出去之后的效果完全没回来,飞轮缺了"结果反馈"这一环 |
| A6 | **关键词分析** | 关键词→聚光词包打通,指导选题 | 无 | 🔴**缺失** | 没有关键词/选题指导运营靠自己拍脑袋填theme |
| A7 | **模板库** | 沉淀可复用的内容模板 | `_text_prompt.py`有内置模板,但用户**不可见不可管** | 🟡**藏在代码里** | 模板写死在后端,运营看不到、改不了、存不了自己的 |
---
## 二、系统BSCRM运营逐功能对照
> ⚠️ 先判断北哥业务是否要做SCRM这块大部分可能是 ⚪不适用。但**列出来让倩倩姐自己判**,不替你砍。
| # | 俊达功能 | 俊达怎么做 | Clover对应 | 状态 |
|---|---|---|---|---|
| B1 | AI销售/追单Agent | 线上自动追单、每天成交 | 无 | ⚪/🔴 看北哥要不要做销售转化 |
| B2 | AI企微客服 | 自动接待答疑 | 无 | ⚪ 北哥若无私域则不适用 |
| B3 | 采集定制 | 定制内容生产线 | 无 | ⚪ |
| B4 | 收款单/支付 | 订单收款管理 | 无 | ⚪ |
| B5 | 投放复盘Agent | 每日诊断投放ROI | 无 | 🔴 若北哥投流则强相关 |
| B6 | 乘风账户财务 | 账户资金管理 | 无 | ⚪ |
> 系统B的意义俊达是"内容→销售→复盘"全闭环,**Clover只到"内容产出"就停了**,后面的转化和钱完全没接。这是"工具"和"经营系统"的分水岭——但要不要走这步是商业决策,得倩倩姐拍。
---
## 三、UI呈现层逐页对照基于真实代码逐页核实
> 这节回答"界面为什么空"。逐页看了真实代码,分清哪页饱满、哪页空。
| Clover页面 | 文件 | 内容丰富度 | 对照俊达的差距 |
|---|---|---|---|
| **工作台 dashboard** | `dashboard/page.tsx` | 🔴**确证空** | 只有1句问候+3个DashCard按钮。**无任何数据**今天生成多少、待审多少、飞轮进度、近期任务全没有。俊达进门是仪表盘Clover进门是3个按钮 |
| 挑文案 text | `[id]/text/page.tsx` + `TextCandidateCard` | ✅**饱满** | 卡片有角度/正文/违禁词/七维分条/AI评委总评。这页不空反而是全站最好的 |
| 挑图 images | `[id]/images/page.tsx` | 🟡**偏薄** | 图只显示 url+role 两个信息(line65-66)**无评分、无策略、无为什么选它**。对比文案卡的七维分,图卡信息量差一大截 |
| 确认 confirm | `[id]/confirm/page.tsx` | 🟡 一般 | 左文案右图预览,文案只显示角度+正文+总分。能用但朴素 |
| 审核台 review | `review/page.tsx` + `ReviewCard` | 🟡 待核ReviewCard | 队列+通过/打回+toast框架在。ReviewCard内容丰富度未核 |
| 历史归档 history | `history/page.tsx` + `components.tsx` | ✅ 较好 | 有筛选/表格/分页/下载交付包。是个正经表格页 |
| 配置台 config | `config/page.tsx` | ✅ 较好 | 4个tab(产品/标杆/违禁词/key),结构清晰 |
| 开新任务 new | `tasks/new/page.tsx` | ✅ 饱满 | 表单+产品选择+配置预览面板+近期任务+飞轮banner信息量足 |
> **"空"的真相修正**:不是全站空,是**门面空**——用户第一眼看到的 dashboard 是3个按钮没有"操作系统"的感觉。加上 images 页偏薄。其余页面其实都不错。
---
## 四、链路完整性对照
**Clover 真实链路**(已验证可跑通):
```
登录 → dashboard → 开新任务 → 挑文案 → 挑图 → 确认 → 提交审核 → 审核台 → 通过 → 历史归档 → 下载交付包
```
**对照俊达链路有4处断点**
| 断点 | Clover现状 | 俊达有 |
|---|---|---|
| ①**入口断**Sidebar导航 | `Sidebar.tsx:22-25`指向`/tasks`等4个不存在路由→404 | 导航即任务流,不会点空 |
| ②**改稿断**:选文案后不能改 | text页选了直接`select`走人(line29-32),无改稿入口 | 人改AI稿→喂回飞轮(最强信号) |
| ③**反馈断**:下载即终点 | history下载交付包后链路结束 | 发布后数据回收→复盘→反哺 |
| ④**回看断**:无任务全局视图 | 无`/tasks/list`,进行中的任务无处统一看 | 任务看板,所有任务状态一目了然 |
> 链路不是"坏",是"**只有一条单向直线,没有俊达的两个回路**":改稿回路(②)、数据反馈回路(③)。这俩正是飞轮转起来的关键。
---
## 五、缺陷汇总分级(只列问题,不谈怎么改)
**🔴 一级缺失让Clover像"半成品"的):**
1. dashboard门面空——无操作系统仪表盘感
2. 进化页/飞轮主视图缺失——系统的"魂"是个配角banner
3. 素材库缺失——产出不沉淀、不能复用
4. 改稿环节缺失——飞轮最强信号没接
5. 数据复盘缺失——链路下载即断,效果不回收
6. Sidebar死链404——入口就劝退
**🟡 二级单薄(能用但不饱满的):**
7. 图片卡信息量薄(只有url+role)
8. 拆解中心只能录入不能拆配方
9. 模板库藏在代码里用户不可见
10. 关键词/选题指导缺失
11. 任务全局看板缺失
**⚪ 待商业决策系统B整块**
12. 销售追单/客服/投放复盘/收款——要不要做SCRM倩倩姐拍
---
## 六、还需核实的(我没看到的,不装看到)
- `ReviewCard.tsx` 审核卡到底多丰富——未读
- `ImageProgressCard.tsx` 完整内容——只看了images页内联渲染组件本身未读
- 后端 `benchmarks.py`/`delivery.py` 接口完整度——未读
- 俊达视频里"进化页/数据复盘"的具体界面长相——摩尔纹,只能辨认大概
> 这几项我标明"未核"不纳入确证缺陷。要不要我继续把这几个也读了把清单补到100%确证?

View File

@@ -0,0 +1,223 @@
# 俊达产品 · 完整逐功能拆解
> 2026-06-15 重做上一版扒得太粗只啃了PPT标题层。本版榨干三类素材PPT 31页 + 俊达口述全文稿(说话人C) + 现场演示视频2段密集抽帧(92帧)。
> 定位:先把俊达这套东西**扒透**(是什么、有哪些功能、怎么实现、什么参数),映射到北哥/大卫是下一步的事,不在本文。
> ⚠️ 视频是手机拍投影(有摩尔纹),界面文字属辨认+口述/URL交叉验证标注了把握度【确证】=口述或PPT明说 /【辨认】=视频可读 /【推断】=据上下文推。
---
## §0 最重要的澄清:俊达有「两套系统」,不是一套
上一版把它当成"一个内容中台 + 一堆外围"**错了**。视频里 URL 和左侧导航证实是**两个独立部署**
| 系统 | 地址 | 性质 | 左侧导航主题 |
|---|---|---|---|
| **小红书内容中台**Content OS | `localhost:3000/xhs/...` | 开发环境PPT演示主体 | 围绕"小红书内容生产" |
| **心声时刻 SCRM**(全平台运营) | `scrm.xinshengshike.com/...` | 线上生产环境,每天在跑 | 围绕"全平台运营/销售/客服/定制生产" |
> 两套都是俊达**一个人**用 Claude Code/Codex 开发的(口述【确证】:"之前有几个技术,后来变成我一个了")。
> 公司主体疑似"心声时刻",主营**定制歌曲 + 定制冰箱贴**(把照片/歌做成实体卖AI生成内容
下面 §2 内容中台、§3 SCRM 分别逐功能拆。
---
## §1 业务本体(先懂生意,才懂系统为什么这么设计)
【确证·口述】
- **主营**:定制歌曲、定制冰箱贴(垂直定制类目)。产品本身=AI生成歌AI写、图AI做打印成实体冰箱贴/标签)卖。
- **客单**:定制歌曲类约 ¥450成本几十~100电商类约 ¥100成本~十几毛利高。PPT原话"AI让成本趋近于零于是能规模化卖"——关键不是降本,是"凭空造出一门生意"。
- **打法**:小红书打线索 + 打聚光(投放驱动),纯千川式。本质"卖图/卖歌",把内容打到标签/链接上。
- **场景词**(选题方向,来自笔记复盘饼图【辨认】):新婚送礼·新人夫妻(占比最大54%/270条)、亲子纪念·宝妈、出生纪念、闺蜜生日、情侣纪念、结婚纪念、毕业季·学生闺蜜等。**强情感/纪念向**。
- **账号体量**心声纪歌曲定制礼物号≈1.9w粉/136篇/4.7w赞PPT关键词页【辨认】。自有号+代发号,不做大量素人。
> 这块决定了俊达系统的灵魂:**高情感定制 + 投放驱动 + 重内容质量**,所以他才需要"飞轮"把"运营手感"沉淀进系统——同质化内容在他这个品类是致命的。
---
## §2 系统A小红书内容中台Content OS逐功能
> 地址 `localhost:3000/xhs/...`PPT演示主体。左侧导航【辨认】今日待办 / 内容中心 / 素材库 / 模板库 / 拆解中心 / 数据复盘(账号笔记·笔记复盘) / 商品管理 / 不投流量? / 新计划? / 关联授权 / 管理中心。
### 2.1 AI 助手中心 / 进化页(魂) 【确证+辨认】
- **URL**`/xhs/manage/evolution`"evolution=进化"证实这是飞轮UI
- **是什么**:把每个内容生产环节做成一个"AI员工(agent)",集中管理+可进化。
- **流程agent列表**PPT第10页+视频f009①推选题 ②写标题 ③写正文 ④配图压字 ⑤写评论;**辅助能力**:图片打标 / 文本打标 / 拆解爆款。
- **每个agent卡片字段**【辨认】:熟练度(暂无/学习中1/3、"学了你X次·记住X个范例"、状态(还没开始学/有升级待你确认)。
- **关键交互**"『写正文』助手升级——它根据你近期的改稿,琢磨出更好的写法,等你拍板"→ 按钮"看它学到什么"。**这就是俊达说的"改稿→AI进化→人点采纳"飞轮做成了UI。**
- **认知**:口述"提示词没那么重要,重要的是动态生成"——所有提示词结合产品+场景+参考图动态拼。
### 2.2 内容创作工作流(生产线) 【辨认·视频f069】
- **URL**`/xhs/manage/workspace`,示例任务"520礼物"。
- **6步收起式步骤栏**:①模板 ②正文 ③标题 ④配图 ⑤评论 ⑥发布(左侧带✅进度勾)。
- **分STAGE呈现**STAGE A 发布前审核 / STAGE B 套模板 / STAGE C 发布中心交付。
- **AI发布前审核**PPT第10页右3项待改逐条检查 title_length/placeholders_filled/body_quality/cta_present/topic_tags给"重新审核"按钮。**=发布前质检100%覆盖。**
- 右侧实时显示生成结果(标题/正文/标签/评论区话术示范)。
### 2.3 素材库(资产化+评级) 【确证+辨认·视频f005/f060】
- **URL**`/xhs/manage/materials`。分类tab【辨认】定制证书 / 情侣 / 歌曲定制 / 生日祝福。
- **搜索**:文字描述搜图(**向量搜图**【辨认"向量检索"】)+ 以图搜图 + 最新创建。
- **颗粒度**PPT第11页+口述【确证】):图片 / 视频 / 图片压字 / 评论 / 标题 / 文案结构 / 关键词——**各成一库**进库即AI打标。
- **每个素材卡字段**【辨认f005右栏】出图提示词、拍摄要点、来源、压字、评论、标题、文案结构、关键词。
- **评级**PPT第11页【确证】进库即打标按真实互动评 **S/A/B/C/D 级**。"颗粒越细,大模型调用/拆解越准"。
- **入库流**AI先拆解→人工校正→入库逆向(爆款)也走这条:粘链接→拆→该入库的入库。
- **结果**:素材积累 5/月 → 50+/月×10
### 2.4 拆解中心(爆款逆向) 【确证·PPT第14页+短视频v2】
- **URL**`scrm...com/pc-maker/upload-backfile`注意在SCRM域名下叫"以图搜单·回纸管理/采集定制",与内容中台打通)。
- **流**:粘小红书爆款链接 → AI拆 → 一键存入素材库当下次生成样例。
- **拆出的配方维度**PPT第14页【确证】标题公式、句子类型、正文结构、卖点、配图节奏、emoji用法、话题标签、目标人群。
- **示例**PPT原文标题公式"把某人的某种照片[做成定制产品名][捕捉场景]礼物";正文骨架同步拆出。
- **口号**72小时把竞品爆款变成你的可复用配方。
### 2.5 数据复盘 【辨认·视频f020/f024】
- **账号笔记/选题分析**`/xhs/...compilation`PPT第10页+f020把账号笔记标题+正文交AI归纳选题方向统计各方向**笔记数/占比/平均阅读/平均点赞/平均互动率/平均单条变现价值**。带"增量分析""全量重判"按钮。
- **笔记复盘**`/xhs/manage/notes`f024单条笔记拉**内容数据+复盘数据**(曝光/阅读/点赞/收藏/评论/分享/互动率/点击率/涨粉/商品转化一键AI复盘+人工校准。
- **竞品监控**:竞品笔记数据全监控,反推关键词、分析选题类型,回写素材库。
### 2.6 关键词分析 【确证·PPT第18页】
- 大量抓候选词 → AI批量判断是否贴合业务 → 筛出真正有用的。
- **和小红书聚光关键词词包打通**:显示搜索量/竞争度/建议出价截图共639条上游=聚光付费接口)。词包类型:笔记词包/黑马词包/高点击包。
- 跑出的词植入笔记;竞品笔记反推关键词。
### 2.7 模板库 【辨认】
- 图片模板(四宫格 /xhs/manage/x-content f048、大字报等定义文字摆放位置+生成样式。生成时"这张套四宫格、那张套大字报"。
## §3 系统B心声时刻 SCRM全平台运营逐功能
> 地址 `scrm.xinshengshike.com/...`,线上生产环境(**每天在跑、现场都在成交**·口述【确证】。左侧导航【辨认f003/f006/f022】公众号管理 / 城市管理 / 简域管理 / 消息中心 / CMS管理 / 客户端管理 / 歌词制作 / 音乐制作 / 音乐发布 / 客户信息管理 / **采集定制** / **AI销售** / **企微自动化** / 客户SOP / 群发SOP / SOP执行管理 / 追单任务 / 退单SOP / 订单执行 / 定制客户管理 / 营销内容管理 / 智能体 / 知识库 / 模型管理 / AI生成 / 列表配置 / 多语言客服 / **支付管理**。
### 3.1 AI 销售 / 追单 Agent线上每天成交 【确证+辨认·视频f003】
- **URL**`scrm...com/automation/aaa-edition`(自动化)。是配置完整的**追单Agent**。
- **左栏=Agent系统指令全文**【辨认f003】"定制歌曲未付费追单",结构:
- 系统角色定义
- 触发条件(用户消息进来)
- **判断规则约7条**:如客户没回复不主动发;客户说在忙→发祝福语,不硬追;客户问价→走专属付费链接报价;客户嫌贵→发优惠/案例;客户明确拒绝→停止;调用 submit_chase_decision 决策;输出结果按格式不能自创字段。
- 输出动作枚举(继续追/停止/转人工)。
- **右栏=配置面板**【辨认】:模型选 **doubao-2.0**GA预估值发送阶段首次/第N次自动触发开关工具调用已配置客户产品维度。
- **口述价值**【确证】:"人解决过一次的问题下次为什么还要人该AI解决"→任务包模式;追单"人工追不好就AI追"企微AI客服转化率比人工高1-3%。
### 3.2 AI 企微客服 【确证·PPT(企微页)】
- 多账号会话共19201位客户【辨认】左侧切账号、中间会话、右侧客户档案。
- 右栏AI自动回复开关、客户备注、客户标签(小红书/未付费)、添加时间/方式、**客户记忆**(更新日期)、副驾(资料/话术/素材/音乐 tab)。
- **AI接管/我来接管**切换PPT客服页【辨认】人机协作。
### 3.3 采集定制(定制生产线) 【辨认·短视频v2】
- 子菜单:粉图技能初验 / 配置 / 生成链路 / 任务管理 / 快速过图 / 我的作图任务 / 模板广场 / 设计师设计 / 快速生成PSD。
- "以图搜单·回纸管理":打到工人/纸张层面(冰箱贴是实体印刷品)。**这是把"内容生成"接到"实体生产"的环节**——对应口述"AI优化生产流程冰箱贴成本8块→4块"。
### 3.4 收款单 / 支付管理 【辨认·视频f022】
- "收款单管理":统一生成专属付款链接,定向/限金额收款,付完后台人工确认。列表显示客户/专属付款链接/金额/状态/付款时间。示例待支付总额 ¥3759.91。
### 3.5 每日投放复盘 Agent 【辨认·视频f068/f066/f016】
- **URL**`/xhs/manage/ad-review-daily`此页URL在内容中台域但与投放数据打通
- 左栏=投放复盘Agent指令全文【辨认】账户概览、今日花费/今日销售额/今日转化成本(CPL)、计划诊断("已停推/未达量等→是否要调"),输出动作卡。
- **数据打通**【确证】:聚光 + 千川 + 乘风 + 专业号 + 小红书后台 + 电商带货 + 线索,全怼进去喂模型。能看单条笔记实际卖多少货、点击率。
- **价值**【确证】投手从每天泡6小时报表→自动出动作卡DNT投放 ROI 1:4→1:8618回稳1:6+)。
### 3.6 乘风账户财务 【辨认·视频f036】
- "乘风账户财务"页:账户余额(¥6,274.30)、消耗、按日期明细表。投放平台资金侧打通。
---
## §4 技术栈 / 模型 / 成本 / 选型理由 【确证·口述问答】
| 项 | 内容 | 出处 |
|---|---|---|
| **后端** | **纯代码开发**,自建数据库。明确**不用扣子/Dify** | 口述 |
| 不用扣子理由 | 扣子只能调国内几个模型、生成质量差;放生产级要接一堆插件/节点,没人维护就不稳定 | 口述【确证】 |
| **文案拆解模型** | GPT-5.5(口述说"GPT5.5",指拆解/文案) | 口述 |
| **生图模型** | GPT Image2中转站的image2+ 官方双通道 | 口述 |
| 生图双通道设计 | 通道1=中转站(便宜~¥0.18/张)通道2=官方(质量稳)。后台跑评分机制选优,所以生图偏慢 | 口述【确证】 |
| 追单/客服模型 | **doubao-2.0**(成本低,关键词分析"豆包就能分析得很好" | 视频f003+口述 |
| 统一模型底座 | 豆包/Claude 可切换;生图接 nano banana / GPT Image | PPT第28页 |
| 单张生图成本 | 中转站约 **¥0.18/张** | 口述【确证】 |
| 消水印 | 生图自带两层水印(浅色日期+OpenAI像素级隐写),出图后处理转码消除 | 口述【确证】 |
| 查重对抗 | 提示词全动态生成→重复度极低,过小红书查重+AI检测 | 口述 |
| 开发工具 | Claude Code / Codex"配满CC/Codex一个月1000-1600/号" | PPT第24页+口述 |
| 开发速度 | 拉需求2-3天聊明白系统2天全跑出来 | 口述【确证】 |
## §5 业务成果数据(俊达给的真实数字) 【确证·PPT第30页+口述】
| 指标 | 数字 | 备注 |
|---|---|---|
| 单篇内容产能 | **×20** | 一篇内容20倍增长 |
| 周报/复盘工时 | **90%** | 90%+ 让AI干掉 |
| 投放日常重复劳动 | **95%** | 投手只剩充钱+看AI计划对不对 |
| 素材积累速度 | **×100** | PPT写×100口述×10取PPT |
| 发布前质检覆盖 | **100%** | AI发布前审核 |
| AI内容质量 | 越用越强 | 进化 |
| 单篇笔记制作 | 60分钟 → **5分钟** | 且不被平台识别为AI |
| 投放ROI | 1:4 → **1:8**618回1:6+ | DNT项目 |
| 冰箱贴成本 | 8块 → **4块** | AI优化生产流程一个人工环节 |
| 单条爆款笔记 | 卖8000元货 | "凑合"状态 |
| 公司AI化程度 | 自评**约10%** | 还有90%路要走 |
| 开发人力 | **1人**原几个技术→现1人 | 内容中台+SCRM+ERP+客服+企微+定制全是他一人 |
> ⚠️ PPT第30页诚实标注"以上为测算/目标值"——不全是已达成实测部分是目标。引用时别当成100%落地实绩。
---
## §6 组织与方法论(产品背后的打法) 【确证】
### 6.1 三个认知转变(俊达原创框架核心)
1. **工具 → 系统**AI不是工具是组织成员/员工24h无休、稳定
2. **生成 → 流水线**不让AI一口气写完拆工序、每步AI出活、人审一眼对应prompt→context→harness工程师演进
3. **定型 → 进化**AI买来不该定型每天因真实反馈进化提到Hermes自进化概念
### 6.2 任务包模式(原创框架)
AI先解决→自动评估(分数不够/疑难标记)→升级为"任务包"交专家→专家解法反哺训练AI。趋势任务包越来越少人从"处理任务"退到"定策略"。
### 6.3 角色重构
- 运营从"打螺丝(作图/找模板)"→"审批专家":招的不是小红书运营,是**设计师**(懂美感/风格,基础逻辑都写进系统了)。
- 交给AI选题初筛/标题初稿/正文骨架/配图打标/数据聚合复盘。
- 必须人来:定调品牌把关/创意情绪判断/终审发布/投放要不要拍板。
### 6.4 落地三铁律
1. **一把手工程**AI账号谁买、预算谁出、进不进绩效、人事财务绩效要不要进——只有一把手能拍板否则死在每一关。
2. **小公司1+1起步**1个老技术(外包出身、技术面广、懂沟通需求杭州成本1.5-2w)+1-2个新人(985应届/实习)配满CC/Codex。
3. **一条标准线**只要环节用脑子→先交给AI人是护栏和协同。
### 6.5 关键判断(俊达原话提炼)
- "AI不是抢生意的是做好产品的"——他不卖软件,自己做电商。
- "未来出现怪兽级电商公司",产能把人工部分全吃掉,甚至返推工厂降本。
- "比模型更难的,是让一家公司真的用起来"(全员用得上+团队重组)。
- 终极目标 AI native / OPCOne Person Company自评还差90%路。
---
## §7 一句话总评(给倩倩姐的判断锚)
俊达的强不在某个功能炫,而在**两件事**①一个人用CC/Codex把"全链路"(内容+投放+客服+销售+定制生产+收款)全做成了能跑的系统,验证了"AI给一个人的杠杆";②每个能动脑的环节都做成了"会进化的agent",且坚持"人审拍板+诚实克制"(评分选优、不盲目自动发)。
**他比北哥Clover强在广度全链路+ 进化UI的成熟度Clover比他可能强在单点深度生图锁产品工程化** 具体逐条映射见配套《俊达对标-增量落地映射.md》。
---
## §8 可信度与使用边界(拿去用之前必读)
> 素材限制:视频是**手机拍投影+摩尔纹**,没法问俊达要原图/录屏(人家花时间做的成果,明着要不合适)。所以这份拆解**能借鉴"思路和形态",不能当"复刻原文和参数"的依据**。三档可信度划清:
### 🟢 地基级——可直接当借鉴依据(来源:口述【确证】+PPT明示
- 俊达有两套系统(内容中台 + SCRM这个事实
- 5条认知 / 任务包模式 / 角色重构 / 落地三铁律§6 全部)
- 飞轮"进化页"的**产品形态**每环节做成会进化的agent、人改稿→AI学→人点采纳
- 技术选型**理由**:不用扣子/Dify的原因、生图双通道(便宜+稳)+后台评分选优、消两层水印、提示词全动态防查重
- 素材资产化的**分类思路**(图/压字/评论/标题/文案结构/关键词各成库、进库打标评级)
- 爆款拆解的**配方维度**(标题公式/正文结构/卖点/配图节奏…)
- 关键词与聚光词包打通的**逻辑**
- 业务成果数字(但俊达自己标了"测算/目标值",非全实测)
### 🟡 线索级——只用来"确认功能存在/大概长啥样",不照搬(来源:视频【辨认】)
- 具体界面字段名、URL路径、agent卡片文案
- **两个Agent指令的逐条规则**追单7条、投放复盘诊断逻辑——方向对但个别字词我可能辨认错
- 模型版本号doubao-2.0等是辨认值、¥0.18/张等数字
### 🔴 不可获取——别试图还原也不该问他要核心knowhow
- 两个Agent的系统提示词**原文**、素材库打标的prompt、评分机制的维度与权重、双通道选优的具体算法
### 使用三原则
1. **借思路、形态,不抄原文、参数**。前者是俊达公开分享的方法论借鉴正当后者是他的knowhow我们辨认不全也不该抄
2. **凡要落进 Clover 代码的设计,依据只取 🟢 级**;🟡 级仅用于"确认该功能值得做、界面大概什么样",绝不照搬字段/规则原文。
3. **我们的 prompt / 字段 / 算法全部自研**——俊达做素颜霜定制歌曲我们做北哥的品类prompt 本就不可能通用,重新设计是对的、不是偷懒。
> 一句话:这份文档是**"看人家做到了什么、用什么思路做的"的参考**,不是**"照着抄的图纸"**。映射到 Clover 的每条增量(见配套映射文档),依据都已对齐 🟢 级 + Clover 自己的代码现状,没有一条是"照抄俊达原文"。

View File

@@ -0,0 +1,190 @@
# 俊达产品 · 底层逻辑逆向
> 目的:抛开界面/字段/提示词原文(那些辨认不全也不该抄),**只逆向"这套系统为什么这么转、内核机理是什么、能抽象出什么可迁移的底层模型"**。
> 素材:口述【确证】+ PPT明示 为主——底层逻辑恰好是俊达大方分享的方法论层,是现有资料里最可靠的部分。
> 定位:这是"原理图",不是"原文图纸"。可直接用来指导北哥 Clover 的设计取舍。
---
## §0 一句话内核
**把"靠人、且经验留不住"的小红书电商内容生产,重构成"靠系统、且系统随用随聪明"的复利机器。**
拆成两个动词:
- **重构**:人做的每一步(选题/生成/选优/改稿/审核/追单/复盘)都拆成系统里一个"会进化的环",而不是一次性工具。
- **复利**:人干活时产生的每一个决策,都被捕获成数据、沉淀成资产、回灌进下一次生成——用得越多,系统越聪明,人越省力。
---
## §1 第一性:他到底在解决什么本质问题
小红书电商有三个结构性矛盾,俊达整套系统每一块都对着其中之一:
| 本质矛盾 | 通俗说 | 俊达用什么对它 |
|---|---|---|
| **产能 vs 质量** | 要量大(铺笔记),又要篇篇能转化,人手不够 | 流水线生成 + 飞轮选优§2§3 |
| **经验 vs 流失** | 高手知道怎么写爆款,但经验在脑子里,人走了就没了 | 资产化沉淀§4把经验变成库 |
| **跑量 vs 平台规则** | 量一大就判重/限流/封 | 平台对抗工程化§5 |
> 关键洞察:**别人把 AI 当"生成器",俊达把 AI 当"会积累的生产系统"。** 生成只是表面,积累才是内核。这是他和"套个GPT写文案"的根本区别。
<!-- 后续章节由 Edit 补充§3 流水线 / §4 资产化 / §5 平台对抗 / §6 交付商业 / §7 可迁移底层模型 / §8 映射Clover -->
---
## §2 复利内核:数据飞轮怎么转(最重要的一层)
这是整套系统的发动机。逆向出来的机理:
### 2.1 飞轮的四个动作(缺一不转)
```
①捕获信号 → ②聚合偏好 → ③回灌生成 → ④再捕获
↑ │
└──────────────── 闭环 ───────────────────────┘
```
- **①捕获**:人的每个决策都是信号——选了哪条文案、选了哪张图、审核通过/打回(带理由)、**把AI草稿改成了什么**。
- **②聚合**:把一段时间内的信号统计成"偏好画像"(爱什么角度、拒什么理由、改稿往哪个方向改)。
- **③回灌**:下次生成时,把偏好画像拼进 prompt让 AI 一开始就贴着人的口味产出。
- **④再捕获**:新产出又被人决策,信号继续进库。
### 2.2 为什么"改稿diff"是最强信号(俊达的杀手锏)
其他信号是**二选一/打分**信息量低只知道A比B好
**改稿diff 是"人主动写出了正确答案"**(信息量最高:直接告诉系统"应该长这样")。
> 机理:选优信号教系统"别犯错",改稿信号教系统"照这样做"。前者是负反馈,后者是正反馈+监督样本。**一条改稿 ≈ 几十条选优**。这是俊达飞轮转得比别人快的根因。
### 2.3 冷启动怎么破(飞轮的鸡生蛋问题)
飞轮要数据才转,但一开始没数据。逆向出他的解法:
- **种子期靠人**FDE驻场/一把手先用,快速喂前几十条决策(口述里的"1+1起步、任务包"就是在攒种子信号)。
- **够量了才自动**:信号攒过阈值,系统从"等人喂"切到"自动贴偏好生成"。
- → 对应 Clover 代码里已有的 `FLYWHEEL_COLD_START=5` / `FLYWHEEL_LOOKBACK=50`**这俩常量就是冷启动阈值和记忆窗口,方向完全一致**。
### 2.4 飞轮的隐藏前提:信号必须"归属清晰"
多租户/多客户场景A客户的偏好不能污染B客户。
→ 对应 Clover 的 `workspace_id` 逻辑隔离 + 飞轮事件带 `data_ownership` 字段。**俊达必然也有这层否则SCRM多客户会串味。**
---
## §3 流水线引擎:为什么每个环节都做成"会进化的agent"
### 3.1 工具 vs 流水线 vs 进化体(三级跳)
俊达口述的"工具→系统、生成→流水线、定型→进化",逆向成机理就是:
| 阶段 | 形态 | 问题 |
|---|---|---|
| 工具 | 一次性生成,用完即弃 | 经验不沉淀,每次从零 |
| 流水线 | 多环节串成自动流 | 能跑量,但不会变好 |
| **进化体** | **每环节是个会被飞轮喂养的agent** | **跑得越多,每环越聪明** |
> 内核:俊达把"流水线"和"飞轮"**焊死在一起**——流水线负责"跑量",飞轮负责"每跑一轮都进化"。单有流水线 = 量大但平庸;单有飞轮 = 聪明但产能低。**两者咬合才是他的护城河。**
### 3.2 "环"的统一结构(可复用的抽象)
逆向出他每个环节(选题/生成/选优/改稿/追单/复盘)都是同一个模子:
```
输入 → agent生成 → 人决策(产生信号) → 信号进飞轮 → 喂养这个环的下一次
```
**所以"加一个新能力" = "加一个符合这个模子的新环"**而不是重写系统。这解释了他为什么能从内容中台长出SCRM——同一个模子复制到销售场景。
<!-- 后续章节由 Edit 补充§5 平台对抗 / §6 交付商业 / §7 可迁移底层模型 / §8 映射Clover -->
---
## §4 资产化引擎:经验为什么不会随人流失
### 4.1 核心动作:把"一次性产出"变成"可复用资产"
普通玩法:写完一篇笔记 → 发出去 → 结束。
俊达玩法:写完一篇 → **拆成零件入库**(标题进标题库、配图进图库、卖点进卖点库、结构进结构库、关键词进词库)→ 每个零件打标评级 → 下次生成直接调库。
> 机理:他把"内容"拆成**可组合的最小单元**,每个单元独立沉淀、独立进化。这样高手的经验不是存在某个人脑子里,而是**长在库里**——人走了,库还在,新人调库就能产出接近高手的东西。
### 4.2 爆款拆解 = 给资产库"喂外部养料"
自己产的内容是"内循环",会越来越同质。
爆款拆解(逆向别人的爆款 → 拆出配方 → 进库)是"外循环"**持续从市场吸收新配方**,防止资产库近亲繁殖。
> 内核:内循环保证"稳定复用",外循环保证"不断进化"。资产库要两条腿走路。
### 4.3 评级是资产化的灵魂
入库不打标 = 垃圾场。俊达给每个资产打"参考等级"(爆款级/可用级/淘汰级)。
→ 对应 Clover `fission.py` 里已有的 `reference_level` 字段。**这个字段就是资产评级的载体,表已建好,只是还没接线。**
---
## §5 平台对抗引擎:为什么"跑量"能持续不被封
俊达系统能持续跑量,背后是一整套对抗工程,逆向出三个动作:
| 对抗动作 | 解决什么 | 机理 |
|---|---|---|
| **提示词全动态** | 防文案查重/同质判定 | 每次prompt都变 → 产出天然不同,不触发平台判重 |
| **消两层水印 + 锐化/去摩尔纹** | 防图片溯源/判搬运 | 图片指纹被打散 |
| **双通道生图+后台选优** | 防单一模型风格被识别 + 保质量 | 便宜通道走量、官方通道保底,后台评分选最优 |
> 内核:**跑量的天敌是平台规则,所以"对抗"必须工程化、自动化**——不能靠人工每次改。俊达把对抗做进了流水线,所以能无人化跑量。这是"能跑量"和"敢跑量"的区别。
---
## §6 交付与商业逻辑:为什么是"驻场陪跑"而不是"卖软件"
逆向他的商业模式内核:
- **不卖工具,卖"长进客户业务里的系统"**:任务包模式 + FDE驻场 + 1+1起步——本质是降低客户"用起来"的门槛,因为飞轮要客户真用才转得起来。
- **一把手工程**:必须老板亲自推,否则一线不喂信号,飞轮空转。
- **商业飞轮 = 产品飞轮的镜像**:客户用得越深 → 数据越多 → 系统越聪明 → 客户越离不开 → 续费/扩单。**产品的复利和商业的复利是同一个飞轮。**
> 内核:他卖的不是"AI能写文案",是"一套会跟着你公司一起变聪明的生产系统"——这东西越用越值钱,所以能驻场收费、能续费。
---
## §7 可迁移底层模型(抽象出来,套到北哥任何品类)
把俊达整套抽象成一个**与品类无关**的模型——这才是真正能借鉴的东西:
```
┌─────────────────────────────┐
│ 会进化的内容生产系统 │
└─────────────────────────────┘
[流水线] [飞轮] [资产库]
把人做的每步 捕获人的每个决策 把产出拆成
拆成agent环 ←→ 聚合成偏好回灌 ←→ 可复用零件入库
(负责跑量) (负责进化) (负责不流失)
│ │ │
└──────────────────┼──────────────────┘
[平台对抗层]
(动态化/去指纹,保证能持续跑量)
[交付:驻场陪跑]
(一把手+FDE保证飞轮被真正喂养)
```
**四条可迁移定律:**
1. **任何重复的人工决策,都是飞轮信号**——能捕获就别浪费尤其改稿diff
2. **任何一次性产出,都该拆成可复用资产**——入库、打标、评级。
3. **流水线和飞轮必须咬合**——光跑量不进化=平庸,光进化不跑量=没产能。
4. **能无人化跑量的前提是对抗工程化**——对抗不能靠人工。
> 这个模型和品类无关。素颜霜能套,北哥的品类也能套——**只需要换掉每个环里的prompt和资产维度骨架不变**。
---
## §8 落到北哥 Clover底层逻辑层面我们缺什么
| 底层引擎 | Clover现状 | 缺口 |
|---|---|---|
| 流水线 | ✅ 13环目标导向已是流水线 | 基本到位 |
| 飞轮-捕获 | 🟡 有选优/审核信号 | **缺改稿diff信号最强那条← 一期就补** |
| 飞轮-聚合回灌 | ✅ preference_aggregator已有 | 改稿样本要接进来 |
| 资产库 | 🟡 fission表已建(reference_level在) | **没接线,经验还没真正资产化** |
| 平台对抗 | ❓ 待确认Clover做到哪 | 需排查动态prompt/去指纹 |
| 交付 | — | 商业层,非代码 |
> 结论:**底层逻辑上Clover的"流水线"和"飞轮回灌"骨架已对齐俊达,差的是两块——①飞轮少了最强信号(改稿diff),②资产库建了表没接线。这两块恰好就是配套映射文档里定的一期/二期增量,方向完全自洽。**
---
## §9 这份逆向的可信度声明
- §1-§7 的**底层逻辑/机理/可迁移模型**:来源是口述【确证】+PPT明示**是俊达大方分享的方法论层,可信、可直接借鉴**。
- §2.3 / §4.3 / §8 里凡提到 Clover 具体常量/字段FLYWHEEL_COLD_START、reference_level等来源是**我们自己的代码**,确证。
- 全程**不含**俊达的prompt原文、评分权重、界面字段——那些辨认不全也不该抄逆向底层逻辑根本不需要它们。
- 一句话:**逆向的是"他为什么这么设计",不是"他具体写了什么"。前者是原理能借后者是knowhow不抄。**

View File

@@ -0,0 +1,223 @@
# 俊达增量① · 改稿 diff 飞轮信号 — 实施细案
> 配套 `俊达对标-增量落地映射.md` §二。本文是可直接交给开发窗口执行的细案。
> 代码勘验2026-06-15迁移已到 011。**所有定位用函数名/类名,不用行号**(另一窗口在改 P0行号会漂
> 一句话:飞轮当前只有"选/审"弱信号,本增量加"运营改稿"强信号——AI 不只学到"这条不好",还学到"该改成什么样"。
---
## §0 并发窗口避让总则(最重要,先读)
另一个窗口正在改 **P0第5环文案 / 第6环配图 / 第8环审核**(见 `plans/总核销表.md` M1/M2/M3。本增量挂点与之**部分重叠**,按下表避让:
| 本增量要动的文件 | P0 是否在动 | 冲突等级 | 避让策略 |
|---|---|---|---|
| `constants/enums.py` | 可能(改模型/枚举) | 🟡中 | 只**追加**枚举值和权重项,不改存量行;合并时手动 review 这一处 |
| `ai_engine/constants.py` | 可能FLYWHEEL_WEIGHTS | 🟡中 | 同上,只追加 `text_edit` 一行 |
| `models/task.py` `TextCandidate` | M1文案可能动 | 🟠高 | **只加2个新字段**nullable不碰现有字段新迁移012独立 |
| `api/v1/task_actions.py` | 选文案在此 | 🟠高 | **新增独立端点函数**,不改 `select_text`;放文件末尾减少 diff 碰撞 |
| `ai_engine/preference_aggregator.py` | 第5环可能动 | 🟠高 | 新增独立 helper 函数 `_extract_edit_samples`,主函数只插一行调用 |
| `review.py` | M3审核**正在改** | 🔴最高 | **本增量不碰 review.py**(改稿入口走 task_actions不走审核 |
| 前端 `TextCandidateCard.tsx` | 可能 | 🟡中 | 加可编辑态用新 prop默认关闭不影响现有只读渲染 |
**总原则**:能新增就不修改;新增函数/端点/字段集中放,减少与 P0 的 diff 行重叠;`enums.py` 两处权重是唯一必须手动合并点,开工前跟那个窗口对一句"我要往 SignalType 加 text_edit"。
**落库顺序建议**:等 P0 的 M1/M3 合并完,再起本增量分支,避免 rebase 地狱。后端 S1-S4 先上线(飞轮真变强),前端 S5 随后。
---
## §1 五步细化(每步:动什么·代码骨架·验证)
### S1 加信号类型 `text_edit`(⚠️两处权重都要加)
**1a. `backend/app/constants/enums.py` → `class SignalType`**
追加一个枚举值(放 REGENERATE 后):
```python
TEXT_EDIT = "text_edit" # 运营改稿(强信号,俊达"改稿diff最值钱"
```
同文件 `SIGNAL_WEIGHTS` 字典追加一行:
```python
SignalType.TEXT_EDIT: 4, # 强于普通选择(+3),弱于审过(+5)
```
**1b. `backend/app/services/ai_engine/constants.py` → `FLYWHEEL_WEIGHTS`**
> ⚠️ 这是**第二处权重定义**聚合器用的是这个不是enums那个漏了会导致改稿信号权重算成0。追加
```python
"text_edit": 4,
```
**权重为什么是+4**:选文案=运营从N条挑1条弱监督只说"这条还行");改稿=运营动手写出"正确答案"(强监督,给了方向)。所以高于选择(+3);但单条改稿样本量小、未经组长终审,低于审核通过(+5)。北哥可在调教时校准。
**验证**`python -c "from app.constants.enums import SIGNAL_WEIGHTS, SignalType; print(SIGNAL_WEIGHTS[SignalType.TEXT_EDIT])"` → 4。
---
### S2 存改后内容(`TextCandidate` +2字段 + 迁移012
**2a. `backend/app/models/task.py` → `class TextCandidate`**
`is_selected` 字段后**追加**不动现有字段遵§0🟠避让
```python
edited_content: Mapped[str | None] = mapped_column(Text) # 运营改后正文NULL=没改过
edited_at: Mapped[datetime | None] = mapped_column(DateTime) # 改稿时间
```
**设计取舍:为什么不单建一张 diff 表**
- 存"AI原文 `content` + 改后 `edited_content`"两份即可diff 在聚合时实时算Python `difflib` 或直接把"原→改"两段喂 prompt
- 省一张表、省一次 join且原文已在 `content` 里,天然成对。
**2b. 新迁移 `backend/app/alembic/versions/012_text_edit_flywheel.py`**
> 版本号续 011总核销表已用到011命名避开撞车。
```python
"""012 改稿diff飞轮TextCandidate加edited_content/edited_at"""
def upgrade():
op.add_column('text_candidates', sa.Column('edited_content', sa.Text(), nullable=True))
op.add_column('text_candidates', sa.Column('edited_at', sa.DateTime(), nullable=True))
def downgrade():
op.drop_column('text_candidates', 'edited_at')
op.drop_column('text_candidates', 'edited_content')
```
> down_revision 填当前 head011。先 `alembic heads` 确认 head 是不是011——**若那个窗口已加了012/013顺延改号**。
**验证**`alembic upgrade head``DESC text_candidates;` 见两新列且可空(存量数据不受影响)。
### S3 采集端点(`task_actions.py` 新增独立函数)
> §0🟠**不改 `select_text`**,在 `task_actions.py` **末尾**新增端点,减少与 P0 选文案逻辑的 diff 碰撞。
参照同文件 `select_text` 的写法(已有 `record_signal` import 范式):
```python
from pydantic import BaseModel
class EditTextRequest(BaseModel):
edited_content: str # 运营改后的正文全文
@router.post("/{task_id}/text-candidates/{cid}/edit")
def edit_text(
task_id: int, cid: int, body: EditTextRequest,
current_user: Annotated[CurrentUser, Depends(require_write_permission)] = None,
db: Session = Depends(get_db),
):
"""运营改稿(飞轮信号 text_edit +4强信号"""
from app.services.flywheel_service import record_signal
from datetime import datetime, timezone
task = _check_task_ownership(
db.query(GenerationTask).filter(GenerationTask.id == task_id).first(),
current_user.workspace_id,
)
tc = db.query(TextCandidate).filter(
TextCandidate.id == cid, TextCandidate.task_id == task_id
).first()
if not tc:
raise_not_found("文案候选不存在")
original = tc.content # 留底,给 reason 存"原→改"
tc.edited_content = body.edited_content
tc.edited_at = datetime.now(timezone.utc)
db.commit()
# diff 摘要存 reason复用现成 Text 字段,不新增列)
diff_summary = _build_edit_diff(original, body.edited_content)
record_signal(db, current_user, task, "text_edit",
candidate_id=tc.id, angle_label=tc.angle_label, reason=diff_summary)
return ok({"candidate_id": cid, "edited": True})
```
**`_build_edit_diff` 放哪**:放 `task_actions.py` 末尾或 `flywheel_service.py`。MVP 可极简——直接存"原文→改文"两段拼接(聚合时再让大模型理解差异),不必上 difflib
```python
def _build_edit_diff(original: str, edited: str) -> str:
# MVP原文+改后并存差异交给生成时的大模型理解不做规则diff遵"打回原因不AI归纳"同源克制)
return f"原稿:{(original or '')[:200]}|改后:{edited[:200]}"
```
**为什么不走 review.py**:审核台正被 P0(M3) 改(🔴最高冲突),且改稿是"运营在选择/确认阶段动手"的动作,归 task_actions 更合理——审核是组长的事,改稿是运营的事,职责也对。
**验证**`curl POST /api/v1/tasks/{id}/text-candidates/{cid}/edit -d '{"edited_content":"..."}'` → 查 `preference_events``signal_type=text_edit, signal_weight=4` 行 + `text_candidates.edited_content` 已写。
---
### S4 聚合注入 prompt`preference_aggregator.py`,改稿片段置顶)
> §0🟠主函数 `aggregate_preference_context` 只插一行调用,逻辑放**新增 helper**,减少与 P0 第5环改动的重叠。
**4a. 新增 helper**(放 `preference_aggregator.py``_build_prompt_fragment` 旁):
```python
def _extract_edit_samples(relevant: list[dict], limit: int = 3) -> list[str]:
"""抽改稿信号的 reason'原→改'摘要),最近 limit 条。强信号置顶用。"""
samples = [
str(e.get("reason", "")).strip()
for e in relevant
if e.get("signal_type") == "text_edit" and e.get("reason")
]
return samples[-limit:]
```
**4b. 主函数 `aggregate_preference_context` 里取样**(在已有的 angle/reject 统计循环后加):
```python
edit_samples = _extract_edit_samples(relevant)
```
传给 `_build_prompt_fragment`(给该函数加一个 `edit_samples` 形参)。
**4c. `_build_prompt_fragment` 把改稿片段插到最前**(强信号最高优先):
```python
# 函数开头、top_angles 之前 insert
if edit_samples:
formatted = "".join(f"{s}" for s in edit_samples)
lines.append(f"【改稿示范·最高优先】运营曾这样修改文案:{formatted}。请直接对齐这种写法与措辞。")
# ...原有 top_angles / reject_reasons / custom 逻辑接在后面
```
> 因为 `_build_prompt_fragment` 是 `lines.append` 顺序拼接,把改稿段放在**函数最前面 append**即可天然置顶;返回值同时把 `edit_count` 加进去供前端显示。
**4d. 同步两个调用方**
- `flywheel_service.py:get_preference_context`API侧实时聚合——它是另一套**简化重实现**,也要补 `text_edit` 的取样(否则 API 返回的"已注入"摘要漏算改稿)。两处聚合逻辑重复是现状技术债,本增量先各补各的,**不顺手合并**(避免扩大改动面、撞 P0
- worker 侧 `pipeline_steps.py:load_flywheel_context` → 它调 `aggregate_preference_context`4a-4c 改完自动生效,无需改 worker。
**验证**造3条 text_edit 信号后调生成,看 `flywheel_injected` SSE 事件 + MongoDB debug trace 里 user_prompt 含"【改稿示范】"。
---
### S5 前端改稿框(`TextCandidateCard.tsx`,可编辑态可选开)
> §0🟡现卡片 `content` 是只读 `<p>`。加可编辑用**新 prop 默认关闭**,不影响现有只读渲染与 P0 可能的改动。
**5a. `frontend/src/components/tasks/TextCandidateCard.tsx`**
- props 加 `editable?: boolean`(默认 false`onEdit?: (cid, newContent) => void`
- `editable` 为真时,把 `<p>{candidate.content}</p>` 换成受控 `<textarea>`,失焦(onBlur)且内容有变化时调 `onEdit`
- 默认 false → 现有所有调用方行为不变(零回归)。
**5b. 文案选择页 `frontend/src/app/tasks/[id]/text/page.tsx`**
-`<TextCandidateCard>``editable={true}``onEdit` 回调。
- `onEdit` 里调:`api.post(\`/api/v1/tasks/${taskId}/text-candidates/${cid}/edit\`, { edited_content })`(参照同文件已有的 `select` 调用范式)。
**5c. 注入提示** `frontend/src/components/FlywheelBanner.tsx`
- 已显示"本次已注入:最近偏好/打回原因",加一行 `已注入 N 条改稿示范`(读 S4c 返回的 `edit_count`)。
**前端可延后**:若赶 6/27后端 S1-S4 上线飞轮就已真变强。前端临时兜底:运营把改写后文案当"打回原因"填(走现有 reject先喂信号。但**不推荐长期兜底**——reject 是 -3 负信号,语义和 +4 改稿相反,会污染权重,只能短期应急。
---
## §2 端到端验证脚本(飞轮四点全测)
按架构方案铁律"飞轮必须可测,不靠感觉更准",跑一遍:
```
1. events写入 :改一条文案 → SELECT * FROM preference_events WHERE signal_type='text_edit'
断言有行、signal_weight=4、reason含"原→改"、workspace_id+product_id正确
2. 聚合返片段 同product造≥5条信号(含3条text_edit) → GET /tasks/{id}/preference/context
断言返回含改稿示范摘要、edit_count≥1
3. 下次prompt含 发起同product新生成任务 → 查 MongoDB debug trace 的 user_prompt
断言:含"【改稿示范·最高优先】"且在 top_angles 之前
4. UI显示 FlywheelBanner 显示"已注入 N 条改稿示范"
```
对应已有测试:`backend/tests/test_flywheel_wiring.py``test_text_edit_signal_injected`,仿现有飞轮用例写。
---
## §3 回滚
- DB`alembic downgrade -1`012 down 删两列,存量 content 不动)。
- 代码enums 两处删 text_edit 行、task_actions 删 edit_text 端点、aggregator 删 helper+调用、前端 editable 传 false。
- 因全程"只新增不改存量",回滚=删新增,不留残端。
---
## §4 给北哥/倩倩的拍板点
1. **改稿权重 +4 是否合理**?(建议先 +4 跑,北哥用一周后校准——权重表本就设计成可调)。
2. **改稿样本要不要经组长终审才入飞轮**MVP="运营一改就入",学得快;保守="改稿+该条最终被审核通过"才记 text_edit防学到运营改错的。**建议 MVP 先激进,三期加 outcome 校验**。

View File

@@ -0,0 +1,170 @@
# 俊达产品 → Clover 增量落地映射(对照代码版)
> 2026-06-15 落盘。来源俊达万牛会分享PPT 31页《电商XAI·一家小公司的探索》+ 现场演示视频2段 + 倩倩/俊达口述全文稿)。
> 目的把俊达那套小红书电商全链路AI系统里**值得借鉴的增量**,逐条对照 Clover 现有代码拆到「动哪个文件、加哪张表、改哪个函数」,开工直接照做。
> 对齐基准Clover 走 **13环目标导向**(见 `plans/13环目标导向-修改验收总纲.md`),当前 P0 修第5/6环、P2 等北哥给定义。本文增量**全部挂到 13 环语言下**,不另起炉灶。
> 代码事实底座:勘验于 2026-06-15backend 迁移已到 0116容器可跑通task41 端到端 312s 成功)。
---
## 〇、一句话结论(先看这个)
俊达和 Clover 是**同构但错位**:俊达铺的是**全链路广度**(内容+客服+企微+ERP+投放闭环+AI做产品Clover 扎的是**内容生产单点深度**(尤其生图工程化,比俊达展示的更细)。
所以借鉴 = **用俊达的广度,补 Clover 深度之外的空白**,不是照抄。
**经代码核实后,真正的增量只有 4 个(按 ROI 排序):**
| 优先级 | 增量 | Clover 现状 | 落到 13 环 | 建议窗口 |
|---|---|---|---|---|
| ⭐P0-轻 | **改稿 diff 作飞轮最强信号** | 🔴 缺:飞轮缺这一路信号 | 增强第8环审核回路 | 一期 1B 可补 |
| ⭐P1 | **爆款拆解中心(产品化)** | 🟡 表建了没接线 | 第11环裂变的「前置入口」 | 一期可补 |
| P2 | **素材资产化 + 效果评级库** | 🔴 完全没有 | 第12环归档的「升级版」 | 留二期 |
| P3 | **提示词版本化中台 + 投放数据闭环** | 🔴 没有 | 超出13环范围 | 留二/三期 |
> ⚠️ 两个**伪增量**(看着像缺、其实不缺,别浪费工时)见 §五。
---
## 一、Clover 代码现状基线(落盘锚点,后续每条增量对照这个)
> 增量要挂在已有代码上,先把"已经有什么"钉死,避免重复造或挂错地方。
### 飞轮(已跑通,是 Clover 的魂)
- **信号枚举**`backend/app/constants/enums.py``SignalType` 5个值text_select/image_select/approve/reject_with_reason/regenerate+ `SIGNAL_WEIGHTS` 权重表(选+3/审过+5/打回-3
- **信号写入**`app/services/flywheel_service.py:record_signal()` — 业务接口内部调用,不暴露独立埋点端点(契约红线)。
- **信号采集入口**`app/api/v1/task_actions.py`(选文案/选图)+ `app/api/v1/review.py`(审核 approve/reject
- **聚合注入**`app/services/ai_engine/preference_aggregator.py:aggregate_preference_context()` — 取最近50条 → 最常选角度 + 打回原因近3条原文 → 拼 `prompt_fragment`
- **prompt 组装**`app/services/ai_engine/prompt_composer.py:compose_variants()` — 飞轮片段追加到 user_prompt 末尾(不污染 system 红线)。
- **数据表**`app/models/flywheel.py``preference_events`迁移004+ `ai_call_logs`
- **前端**`frontend/src/components/FlywheelBanner.tsx`"本次已注入"提示)+ `stores/preferenceStore.ts`
### 爆款拆解(地基埋了,没接线)
- **表已建**`app/models/fission.py``fission_tasks`迁移010+ `generation_tasks.source_fission_id`迁移011
- **❌ 缺**:无 fission 的 service / api / worker / 前端(已 grep 确认 `app/api app/services app/workers` 零引用)。
- **关联**13环里这是「第11环裂变」总核销表 M7 状态 = ⏸️等北哥给档位定义。
### 标杆分析第2环等北哥给8维
- `app/models/task.py:GenerationTask.benchmark_ids` + 迁移009 `features_json/analyze_status`;总核销表 M6 = ⏸等北哥给8维。
### 生图(比俊达展示的深)
- `app/services/ai_engine/storyboard.py`(分镜+`overlay_text` 压字)+ `image_gen.py:146-153`AI生图直接把字排图上+ `image_postprocessor.py`去C2PA水印+转JPG+削像素水印,对应俊达"消水印")。
- **关键**:配图与压字**已合一**(生图即排字),不是两道工序。这点影响 §五 伪增量判断。
### 归档第12环
- `frontend/src/app/history/` + `delivery_packages` 表(交付包)。总核销表 M4 含日期/品类筛选+导出。
## 二、增量①:改稿 diff 飞轮信号 ⭐最该补
### 俊达怎么做的
俊达把三类反馈信号分了强弱:**「改稿 diff」标为「强」**,评级 A/B/C/D 和「采纳·重做」标为「中」。他原话:"运营把 AI 写的改了 —— 直接看人怎么改,最值钱。" 因为选/审是**二选一的弱监督**,而人动手改稿是**带具体方向的强监督**——AI 能学到的不只是"这条不好",而是"应该改成什么样"。
### Clover 缺口(对照代码)
- `SignalType` 只有 5 个值,**没有 `text_edit`**。
- `TextCandidate``app/models/task.py:73`)只有 `content`AI原文+ `is_selected`**没有"运营改后内容"字段**,改稿这个动作根本没地方落。
- 现状:运营在审核台看到文案,只能"选/打回写原因",不能直接改——改了也不入飞轮。
### 怎么落(概要,细化执行见配套文档)
> ⚠️ **完整可执行方案(含代码骨架+并发窗口避让)已拆到独立文档:`plans/俊达增量①-改稿diff-实施细案.md`**。
> 因为另一个窗口正在改 P0第5/6/8环改稿diff 恰好挂在审核回路+task_actions是冲突高危区细案里逐处标了避让策略。
五步骨架(详见细案):
1. **加信号类型** `text_edit`(权重+4——注意权重在**两处**定义,都要改。
2. **存改后内容**——`TextCandidate``edited_content`/`edited_at` 两字段,新迁移 012。
3. **采集端点**——`task_actions.py``POST .../text-candidates/{cid}/edit`
4. **聚合注入**——`preference_aggregator.py` 加"改稿示范"片段,置于 prompt_fragment 最前。
5. **前端改稿框**——`TextCandidateCard.tsx` 只读 `<p>` 改可编辑。
### 验收(沿用架构方案"飞轮四点可测"
events写入 `text_edit` ✓ / 聚合返回改稿片段 ✓ / 下次 prompt trace 含该片段 ✓ / UI 显示"已注入改稿示范" ✓。
### 风险与建议
- **工程量**1迁移 + 1端点 + 聚合~15行 + 前端1框**半天到一天**。
- **窗口冲突**见细案§0核心是"加字段/加端点用新增不改存量、enums两处权重等P0改完再合"。
- **窗口判断**KR2飞轮1B截止6/27这条不大且价值最高**这次补**。
## 三、增量②:爆款拆解中心(产品化)⭐
### 俊达怎么做的
独立的「**拆解中心**」功能PPT第14页粘一条小红书爆款链接 → AI 拆成「标题公式 / 句子类型 / 正文结构 / 卖点 / 配图节奏」可复用配方 → **一键存入素材库,变成 AI 下次生成时的样例**。口号"72小时竞品爆款 → 你的可复用配方"。本质是把"人肉总结套路"自动化。
### Clover 缺口(对照代码)
- **地基已埋**`fission_tasks`迁移010+ `generation_tasks.source_fission_id`迁移011都建好了。
- **但完全没接线**:无 service/api/worker/前端(已确认零引用),总核销表 M7 = ⏸️等北哥给档位。
- **现状**Clover 已有 `benchmark_notes`(标杆笔记)+ 第2环标杆8特征分析M6等北哥给8维但那是"录入参考"**不是俊达式"粘链接→自动拆配方→反哺生成"的闭环**。
### 关键对齐:俊达"拆解" vs Clover"裂变"是两件事,别混
- **Clover 第11环裂变** = 1爆款 → **N 套完整笔记包**(输出成品)。
- **俊达拆解中心** = 1爆款 → **1 份可复用配方**(输出方法,存库当样例)。
- **俊达的拆解,正好是 Clover 裂变的「前置入口」**:先拆出配方,配方再喂给裂变/常规生成。两者串起来比单独做裂变更完整。
### 怎么落(复用现有 analyze 能力,不新造模型调用)
**核心思路**Clover 第2环标杆分析`benchmark` 8特征 analyze和俊达"拆配方"是**同一个 AI 能力**,只是出口不同。不要新写一套 AI 调用,**复用 analyze加一个"拆解→存配方→反哺"的产品壳**。
**S1配方落点**:拆出的配方存哪?两个选项——
- 选A推荐一期存进现成的 `benchmark_notes.features_json`迁移009已有字段拆解结果就是结构化特征天然契合。前端加"拆解中心"入口,结果进标杆库。
- 选B新建 `recipe`/配方表。一期不必,留到素材资产库(§四)一起做。
**S2拆解 service**:新建 `app/services/ai_engine/note_decompose.py`,复用 `gemini_factory` + 标杆 analyze 的 prompt输入笔记文本/截图,输出 `{标题公式, 正文结构, 卖点, 配图节奏}` JSON。
**S3采集入口**:链接读取受小红书风控限制——**对齐架构方案已拍板的洞1**:对外主通道 = **截图+手填**(零封号风险),登录态自动采集只作北哥内部插件。所以"拆解中心"输入框 = 粘文本/传截图,不做"系统自动抓链接"。
**S4反哺生成**:拆出的配方进 `benchmark_notes`,生成任务选标杆时即可引用 → 已有链路(`generation_tasks.benchmark_ids`)自动打通,无需改生成侧。
**S5前端**:新增"拆解中心"页仿俊达PPT第14页左右分栏左原笔记、右拆解结果+「一键存入标杆库」)。
### 风险与建议
- **依赖北哥**:和 M6标杆8维、M7裂变档位都等北哥定义。**建议把"拆解中心"和 M6 合并需求一起问北哥**——既然拆解配方=标杆特征,让北哥一次性给"要拆哪几个维度"即可。
- **工程量**选A路径service + api + 前端页,约 1-2 天,但**前置依赖北哥给维度**。
- **窗口**:一期能做,但**别和 P0 修bug 抢工**。建议 M6 标杆分析做完后,顺势加拆解中心入口(复用同一 analyze
## 四、增量③④:素材资产库 / 提示词中台 / 投放闭环(留二三期)
> 这三块价值大、但工程量也大,**明确不进一期**,避免冲乱 6/20-6/27 节奏。先记下口子,二期接。
### 增量③ 素材资产化 + 效果评级库(→ 二期第12环升级版
- **俊达**:图/视频/压字/评论/标题/文案结构/关键词**各成一库**,进库即 AI 打标 + 按真实互动评 **S/A/B/C/D 级**;素材积累 5/月 → 50+/月。
- **Clover 现状**:只有 `delivery_packages`(交付包)+ `history` 归档,**没有"按类型分库 + 效果评级 + 向量搜图"**。
- **落点**:二期在 `history`/归档之上建素材库;评级依赖**真实互动数据回填**(架构方案三期"发布效果回填 outcome_score"),所以**评级必须等投放闭环(增量④)先有数据**,顺序上③依赖④。
- **eval_score 已留 NULL 口子**`TextCandidate.eval_score`/`ImageCandidate.eval_score`),架构方案明确"等真评分再装"——正好接俊达的评级,**别用 banana 假评分88分污染飞轮**,这条铁律不能破。
### 增量④ 投放数据闭环(→ 二/三期,超 13 环范围)
- **俊达**:打通聚光/千川/乘风/专业号 + 电商后台,单条笔记能看"卖多少货/点击率"AI 出**动作卡**评A/B/C+建议停/加投)。投手 6h → 自动。
- **Clover 现状**13环里第10环复盘 = ❌不做(人工)。完全没有数据中心。
- **落点**这是独立大模块要对接小红书各后台API+企业资质),**架构方案三期才提**。俊达验证了 ROI 极高他DNT ROI 1:4→1:8值得做但**是 Clover 二期对外 SaaS 之后的事**。
- **提示词版本化中台**(俊达:每提示词版本历史可回滚、标人工改/AI进化、记为什么改Clover 有 `loader.py PromptLoader 版本alias` 死代码可复活(架构方案§四🟡),但做成俊达那样的"UI可调中台"是二期。一期 prompt 改模板即可,不必上版本管理 UI。
---
## 五、两个伪增量(看着像缺、其实不缺,别做)
### 伪增量1把"配图/压字"拆成两道独立工序 ❌
- 俊达PPT把"配图"和"压字"列成内容流水线里两个独立模块,看着像 Clover 少了一环。
- **但 Clover 已经合一实现**`storyboard.py` 出分镜带 `overlay_text``image_gen.py:146-153` 生图时直接把文字排到图上出成品。这是**更先进的做法**(一次成图 vs 先出图再压字两步)。
- **结论**:不要为了"对齐俊达模块数"去把它拆开。俊达分两步可能正因为他没做到一次成图。**Clover 这里是优势,保持。**
### 伪增量2爆款"逆向工程"当全新功能 ❌(部分)
- 看着 Clover 没有"爆款逆向"其实第2环标杆8特征分析 = 同一个 AI 能力(拆爆款)。
- **结论**:增量②不是"新造逆向引擎",而是"给已有 analyze 加产品化入口+反哺出口"。别重复造 AI 拆解逻辑。
---
## 六、俊达最该抄的 5 条认知(非功能,是方法论)
这 5 条比任何功能都值钱,且和 Clover 设计哲学高度一致,可直接写进北哥项目的产品理念:
1. **AI 当组织成员/员工管,不当工具** —— 拆成"选题员工/标题员工/配图员工",每个都是 agent。对应 Clover 多步流水线。
2. **生成 → 流水线** —— 不让 AI 一口气写完,拆工序、每步 AI 出活、人审一眼。Clover 已是这套。
3. **定型 → 进化** —— AI 不该买来就定型,每天因真实反馈变聪明。= Clover 飞轮(魂)。
4. **任务包模式** —— 人只处理 AI 搞不定的疑难,顺手把解法训练回 AI任务包越来越少。可作为 Clover 飞轮+审核的长期叙事。
5. **颗粒度无限细分 → 素材库索引 → 生成** —— 把经验拆到最细存库,生成时索引。对应增量③素材资产化。
6. **诚实克制**(俊达"冠军-挑战者+人审,绝不盲目自动上线")—— 和 Clover"eval_score留NULL不用假分""飞轮四点可测"完全同源。**这是双方最该互相印证的设计底线。**
---
## 附:俊达全产品模块地图(视频左侧导航补全,供北哥扩展参考)
视频里俊达系统左侧菜单(手机拍投影,已尽力辨认):
内容中台(选题/标题/正文/配图/评论/素材库/拆解中心)· 音乐创作 · 客户管理 · 岸署管理 · AI销售 · 机器人管理 · 微信Agent · Agent工具包 · 发布管理 · 全平台自动化 · 客户SOP · 群发SOP · SOP执行管理 · 数据复盘 · 乘风账户财务(投放数据)· 知识库。
> 这是"一个人开发的全链路"全貌。Clover 一期只对应其中"内容中台"一块,其余是北哥项目二期/三期或独立产品线的想象空间。

View File

@@ -0,0 +1,190 @@
# Clover 修改处理方案 · 第一批(⚠️ 做了不合格)
> 倩倩姐审方案专用。**未拍板不动代码**。每项含:现状代码 / 改后代码 / 改动文件清单 / 风险 / 验收。
> 现状代码均已逐行读核,行号真实。
---
## 修1 · 90分阈值过滤形同虚设
**根因**`pipeline_io.py:96-106` 循环把 `candidates_raw` 全部入库,没看 `passed`
text_variants.py 已给每条算了 `passed``text_variants.py:101`),但 pipeline 没用它过滤。
**现状代码**pipeline_io.py:95-108
```python
seq = seq_start
for i, c in enumerate(candidates_raw):
tc = TextCandidate(
workspace_id=workspace_id, task_id=task.id,
source=CandidateSource.AI,
angle_label=c.get("angle_label") or c.get("angle", ""),
content=json.dumps(c, ensure_ascii=False),
score_json=json.dumps(c.get("score_detail", []), ensure_ascii=False),
banned_word_status=BannedWordStatus(c.get("banned_word_status", "pass")),
)
db.add(tc)
db.flush()
```
**改后代码**
```python
# 90分过滤只入库 passed 的;硬拦截(hard_block)无论分数都剔除
qualified = [c for c in candidates_raw
if c.get("passed") and c.get("banned_word_status") != "hard_block"]
# 回退兜底:全员未达标时不空屏,取分最高的 N 条入库并标记 below_threshold
if not qualified:
fallback = sorted(candidates_raw, key=lambda x: x.get("score", 0), reverse=True)
qualified = [c for c in fallback if c.get("banned_word_status") != "hard_block"][:task.text_count]
for c in qualified:
c["below_threshold"] = True # 前端可标"未达90分,仅供参考"
seq = seq_start
for i, c in enumerate(qualified):
tc = TextCandidate(...) # 同现状circ 改成遍历 qualified
db.add(tc)
db.flush()
...
push_fn(..., "text_candidate", {
..., "below_threshold": c.get("below_threshold", False), # 新增透传
}, seq)
```
**改动文件**
- `backend/app/workers/pipeline_io.py`run_text_generation约改15行
- `frontend/src/components/tasks/TextCandidateCard.tsx`below_threshold时显黄标约5行可选
**风险**阈值90偏严正常出文案可能常触发回退。回退逻辑必须有否则用户看到空列表比现在更糟
**验收**①跑任务列表只剩≥90分 ②人为造全低分确认回退展示TopN且带黄标 ③hard_block的永不出现。
**待拍板**回退要不要我建议要空屏体验更差。below_threshold黄标前端做不做
---
## 修2 · 品牌词字段缺失(文案+生图同根因,一次解两处)
**根因**`products` 表无 `brand_keyword`model:product.py:28-40 无此字段)。
但三处代码都在读它:`_text_prompt.py:137``storyboard.py:133``image_gen.py:140`
`product.get("brand_keyword")` 永远 None → 文案不植入品牌词、生图特写图不带品牌词,静默失效。
**改动分5步**
**① 新建迁移** `backend/alembic/versions/008_product_brand_keyword.py`
```python
"""add brand_keyword to products
Revision ID: 008
Revises: 007
"""
from alembic import op
import sqlalchemy as sa
revision = "008"
down_revision = "007"
branch_labels = None
depends_on = None
def upgrade():
op.add_column("products", sa.Column(
"brand_keyword", sa.String(64), nullable=True,
comment="品牌词,植入文案每条+生图特写图(第2/6张)"))
def downgrade():
op.drop_column("products", "brand_keyword")
```
**② 模型加字段** `models/product.py`image_path 后插一行):
```python
brand_keyword: Mapped[str | None] = mapped_column(String(64)) # 品牌词,植入文案+生图
```
**③ DTO加字段** `api/v1/products.py:24 ProductCreate`
```python
brand_keyword: str | None = None # 品牌词
```
`create_product`(L85) 构造 Product 时加 `brand_keyword=body.brand_keyword`
`_fmt_product`(L49) 返回加 `"brand_keyword": p.brand_keyword`
**④ 前端录入框**:产品表单加"品牌词"输入(`ProductSubComponents.tsx` 或产品创建表单)。
**⑤ 确认读取生效**:三处读取代码已存在,加字段后自动拿到值,无需改。
**改动文件**008迁移(新)、model/product.py、api/v1/products.py、前端产品表单。
**风险**:①北哥环境要 `alembic upgrade head` 跑迁移 ②老产品该列NULL→读到空串三处已用 `or ""` 兜底,不报错。
**验收**:建产品填"龙石"→生成文案每条含"龙石"、生图第2/6张画面带"龙石"。
**待拍板**:品牌词录在**产品级**(随产品固定,方案默认)还是**任务级**(每次任务可改)
---
## 修4 · 侧边栏导航404先放修4修3叠字单列文末
**根因**`Sidebar.tsx:19-28` 的 NAV_ITEMS 8条里4条指向不存在的页
- `/tasks`(无 page`/images`(无 page`/tasks/build`(无 page`/tasks/list`(无 page
实际存在的页:/dashboard /tasks/new /tasks/[id]/text /tasks/[id]/images /tasks/[id]/confirm /review /history /config
**现状代码**Sidebar.tsx:19-28
```tsx
const NAV_ITEMS: NavItem[] = [
{ label: '工作台', href: '/dashboard', icon: '🏠' },
{ label: '开新任务', href: '/tasks/new', icon: '✏️' },
{ label: '选择文案', href: '/tasks', icon: '📝' }, // 404
{ label: '选择图片', href: '/images', icon: '🖼️' }, // 404
{ label: '建立任务', href: '/tasks/build', icon: '⚙️' }, // 404
{ label: '任务列表', href: '/tasks/list', icon: '📋' }, // 404
{ label: '历史归档', href: '/history', icon: '🗂️' },
{ label: '配置中心', href: '/config', roles: ['admin'], icon: '⚙️' },
];
```
**改后代码**删掉4条死链。选文案/选图片是任务流程内的步骤页(/tasks/[id]/text 等),不该做全局导航,进了具体任务才有。审核页`/review`原本漏在导航里,补上。
```tsx
const NAV_ITEMS: NavItem[] = [
{ label: '工作台', href: '/dashboard', icon: '🏠' },
{ label: '开新任务', href: '/tasks/new', icon: '✏️' },
{ label: '审核', href: '/review', roles: ['admin', 'leader'], icon: '✅' },
{ label: '历史归档', href: '/history', icon: '🗂️' },
{ label: '配置中心', href: '/config', roles: ['admin'], icon: '⚙️' },
];
```
**改动文件**`frontend/src/components/layout/Sidebar.tsx`改NAV_ITEMS数组
**风险**:无,纯导航项删改。
**验收**点遍每个导航项都进到真实页无404。
**待拍板**:审核页要不要进侧边栏(现状代码注释提到/review角色守卫但导航里没有建议补上。
---
## 修5 · 文案调用无网络退避重试
**根因**`text_variants.py:49 _generate_one_batch` 只在JSON解析失败时重试2次网络层503/超时不退避。
生图侧已有成熟退避 `_retry`image_gen.py:51-63文案没复用。
**现状代码**text_variants.py:47-56
```python
async def _generate_one_batch(llm_client, product, batch_n, extra) -> list[dict]:
for attempt in range(2):
raw = await _call_llm(llm_client, build_prompt(product, batch_n, extra_rules=extra))
parsed = parse_json_array(raw)
if parsed:
return parsed
logger.warning(...)
return []
```
**改后代码**_call_llm 返回空含503/超时时退避重试。注意退避会拉长耗时须控制总时长不撞60s网关——故退避只1次、间隔短(2s)。
```python
async def _generate_one_batch(llm_client, product, batch_n, extra) -> list[dict]:
for attempt in range(3): # 解析失败/网络空 共最多3次
raw = await _call_llm(llm_client, build_prompt(product, batch_n, extra_rules=extra))
parsed = parse_json_array(raw)
if parsed:
return parsed
if not raw and attempt < 2: # 网络层空响应→短退避再试
await asyncio.sleep(2 * (attempt + 1)) # 2s,4s
logger.warning(...)
return []
```
**改动文件**`backend/app/services/ai_engine/text_variants.py`_generate_one_batch约改5行
**风险**退避叠加可能逼近60s网关上限故只退避2次、间隔短。若仍超时本地兜底(build_local_drafts)已兜底。
**验收**模拟apiports 503确认自动退避重试而非直接掉本地兜底。
---
> 修3瓶身中文叠字技术最不确定与建13套图合并放"第三批·需新建/重构"文件细化避免和无歧义的纯bug混在一起。

View File

@@ -0,0 +1,196 @@
# Clover 修改处理方案 · 第三批(❌ 需新建/重构)+ 修3叠字
> 这批是新建模块或重构,技术不确定性高、且多数需北哥给业务定义。
> 不像第一二批能直接给 before/after这里给现状/改造思路/影响文件/风险/待定义点。
---
## 修3 · 瓶身中文小字乱码叠字兜底【L·技术最不确定】
**根因**gpt-image-2 画中文小字会糊/乱码(记忆 clover-image-gen-mixed-text-rendering 已记)。
现状 storyboard 把所有文字(overlay_text)都塞进prompt让模型画image_gen.py:140附近
**改造思路**(模型出底图 + 代码叠字):
1. storyboard 区分"模型画的"vs"代码叠的":大标题模型画(已清晰),瓶身小字/品牌词/卖点改代码叠。
2. 新建 `image_text_overlay.py`PIL 加载中文字体(思源黑体开源),按坐标叠字到底图。
3. image_gen 生图后、后处理前,调叠字。
4. prompt 负向约束模型"不要在瓶身画文字"。
**影响文件**:新增 `image_text_overlay.py``storyboard.py`(标记哪些字代码叠)、`image_gen.py`(接叠字)、字体资源(assets/fonts/)。
**风险(高)**:①叠字坐标/字号要按每张构图调,模型出图位置不固定→坐标难定 ②哪些字叠/哪些画的边界要试 ③字体版权(用SIL开源思源) ④可能要调好几轮才自然。
**待定义点**:这期做不做?我的建议——**先验证模型把大标题画清楚(已能),瓶身小字这种高不确定项放二期**,一期先用"少画字、关键字代码叠品牌词"最小版本试。
**最小版本(降risk)**:只代码叠"品牌词"一处(位置固定在底部),不碰瓶身小字。工作量降到M。
---
## 建1 · 生图≥3套【L】
**根因**`storyboard.py:119 plan_image_set` 只产1套storyboard`image_gen.py:156 generate_storyboard_images` 只跑1套返回扁平list。无"套"概念。
**现状结构**
```
plan_image_set → {storyboard: [6张item]} # 1套
generate_storyboard_images → gather 6张 → [6个结果] # 扁平
pipeline_io → 存6张 ImageCandidate
```
**改造思路**:外层套循环。
```
for set_idx in range(3): # 3套
plan = plan_image_set(..., variant=set_idx) # 套间差异
套结果 = gather(...)
返回 [[套1的6张],[套2的6张],[套3的6张]]
ImageCandidate 加 set_no 字段;前端按套分组展示选择
```
**影响文件**`storyboard.py`(plan加variant参数做差异)、`image_gen.py`(外层循环)、`pipeline_io.py`(存set_no)、`models/task.py`(ImageCandidate加set_no列+迁移)、前端图片选择页(按套展示)。
**风险**①生图成本×3、apiports限流(记忆:限并发2)→3套18张要控并发别打爆 ②"套间差异"是什么没定 ③前端展示改动较大。
**待定义点(必须北哥/你定)**
- 3套的差异维度候选a)不同文案角度各出一套 b)同角度不同视觉风格 c)不同封面方案
- 套数固定3还是用户可选1/3/5
- 是否每套都6张还是套数×张数用户配
---
## 建2 · 产品图视觉分析 visualIdentity【M】
**根因**banana 有(上传产品图→提主色/字体/风格)Clover 的 `build_visual_system`(storyboard.py:127)只用了文案锚点,没做产品图视觉提取。
**改造思路**:产品图上传后(或生图前)调多模态分析→提主色/包装风格→存产品档案→生图prompt注入"保持与参考图一致的主色/风格"。
**影响文件**:新增 `visual_identity.py`、products上传接口接入分析、product表加 visual_json 列+迁移、storyboard注入。
**风险**:多模态调用成本+延迟;分析准确度。
**待定义点**:一期必要还是二期?我建议二期(现已强制带产品参考图给 /images/edits视觉一致性已有基本保证视觉提取是锦上添花
---
## 建3 · 标杆 AI 出8特征【L·需北哥定义】
**根因**`benchmarks.py` 纯CRUDBenchmarkCreate 只 screenshot_url/highlights/link_url 三字段零AI分析。
**改造思路**:录标杆(截图/文本)→AI分析出8个特征维度→存库→生成时可参考。
**影响文件**`api/v1/benchmarks.py`、新增标杆分析service、BenchmarkNote加 features_json 列+迁移、前端标杆展示。
**风险**与建4(裂变)强耦合——8特征是裂变的输入。
**待定义点(必须北哥给)**8特征具体是哪8个钩子类型/痛点/人设/结构/卖点呈现/情绪/视觉/标题公式?)北哥不给定义,做不了。
---
## 建4 · 爆款裂变全套【XL·最大块·需北哥给完整流程】
**根因**:全栈零代码,整块缺失。
**完整流程(待北哥确认)**:选标杆→选参考度档位(高/中/低)→选裂变维度→基于标杆8特征生成变体→裂变后评分。
**影响文件(大量新增)**:后端 裂变service+router、裂变记录表+迁移、前端裂变页(选标杆/档位/维度/看结果)。强依赖建3的8特征。
**风险****这是独立新功能,不是修补**。工作量远超其他项。依赖建3。
**待定义点(必须北哥给)**
- 完整裂变流程定义
- "参考度档位"高/中/低分别意味着多大改动?
- 裂变维度有哪些可选?
- 裂变后评分用现五维还是另立标准?
**建议****单独立项**与bug修复彻底分开。北哥不给流程定义无法开工。
---
## 建5 · 去水印强制3:4比例【S】
**根因**`image_postprocessor.py process_image` 只重编码+重采样,无比例校验/裁切。
**现状代码**image_postprocessor.py:41-49
```python
img = Image.open(io.BytesIO(image_bytes)).convert("RGB")
original_size = img.size
if resample_strength >= 1:
w, h = original_size
small_w, small_h = int(w * 0.98), int(h * 0.98)
img = img.resize((small_w, small_h), Image.LANCZOS)
img = img.resize(original_size, Image.LANCZOS)
```
**改后**开头加3:4校验+居中裁切。
```python
img = Image.open(io.BytesIO(image_bytes)).convert("RGB")
# 强制3:4(1080×1440):偏差超阈值则居中裁切
w, h = img.size
target_ratio = 3 / 4
cur_ratio = w / h
if abs(cur_ratio - target_ratio) > 0.02:
if cur_ratio > target_ratio: # 太宽→裁宽
new_w = int(h * target_ratio)
left = (w - new_w) // 2
img = img.crop((left, 0, left + new_w, h))
else: # 太高→裁高
new_h = int(w / target_ratio)
top = (h - new_h) // 2
img = img.crop((0, top, w, top + new_h))
original_size = img.size # 裁后尺寸
```
**影响文件**`backend/app/services/ai_engine/image_postprocessor.py`约12行
**风险**居中裁切可能切到边缘内容gpt-image-2 本就按1080×1440出图多数已是3:4裁切是兜底保险。
**验收**故意喂非3:4图→输出严格3:4。
---
## 建6 · 客户输入物整体导出【M】
**根因**:只有产出物打包(package_exporter),无产品/标杆等输入物导出。数据归属红线:客户原始数据可导出。
**改造思路**:加 `GET /products/export``GET /benchmarks/export`导出该workspace全部输入物为zip(含json+上传的图)。
**影响文件**新增导出router+service。
**风险**:导出格式(json/csv/zip)、是否含上传的图要定。
**待定义点**:格式?一期必要还是二期?建议二期(飞轮启动+北哥测试期客户数据导出诉求不急)。
---
## 建7 · 图片 lightbox 放大【S】
**根因**全局无放大逻辑img直接渲染看不清细节。
**改造思路**:图片卡加点击放大遮罩(轻量自写或 yet-another-react-lightbox)。
**影响文件**:前端图片相关组件(images页/confirm页)+新增Lightbox组件。
**风险**:无。
**验收**:点图弹出大图遮罩。
**建议**:直接做,体验刚需且简单。
---
## 建8 · 套版预览(封面+内页拼笔记【M】
**根因**confirm页只网格分开展示图(ConfirmPreviewImages),没拼成"一条小红书笔记长相"。
**改造思路**confirm页加"笔记预览"视图:封面图+内页轮播+文案标题正文,按小红书样式排。
**影响文件**前端confirm页+新增笔记预览组件。
**风险**:还原小红书样式要调。
**待定义点**一期必要还是二期建议二期confirm已能逐个看图+文案,拼版是体验增强非阻断)。
---
## 建9 · 任务级并发上限【M】
**根因**:只有 celery worker_prefetch_multiplier=1worker层无用户/任务级并发限制。用户狂点开任务可能堆爆。
**改造思路**:任务创建时查该用户在跑任务数(DB status查或Redis计数)超N则拒绝/排队。
**影响文件**任务创建router、可能加Redis计数。
**风险**:限制策略要定。
**待定义点**:每用户允许几个并发任务(建议2-3)?超限拒绝还是排队?
---
## 第三批小结
| 项 | 性质 | 建议期次 | 阻塞点 |
|---|---|---|---|
| 修3叠字 | 重构·高不确定 | 一期最小版(只叠品牌词)/二期完整 | 技术验证 |
| 建1 3套图 | 重构 | 看北哥要不要 | 套间差异定义 |
| 建2 视觉分析 | 新建 | 二期 | — |
| 建3 标杆8特征 | 新建 | 看北哥 | **8特征定义** |
| 建4 爆款裂变 | 新建·XL | **单独立项** | **完整流程定义** |
| 建5 强制3:4 | 改造·小 | 一期可做 | — |
| 建6 输入导出 | 新建 | 二期 | 格式 |
| 建7 lightbox | 新建·小 | 一期可做 | — |
| 建8 套版预览 | 新建 | 二期 | — |
| 建9 并发上限 | 改造 | 一期可做 | 并发数 |
**无歧义可直接做**建5(3:4)、建7(lightbox)、建9(并发,定个数即可)。
**需北哥给定义才能动**建3(8特征)、建4(裂变流程)。
**建议二期**建2、建6、建8。
**技术验证后再定**修3叠字。

View File

@@ -0,0 +1,148 @@
# Clover 修改处理方案 · 第二批(🟡 做了一半)
> 现状代码均已逐行读核。每项含现状/改后/文件/风险/验收。
---
## 修6 · ai_call_logs 记录不全
**根因**
- `pipeline_io.py:78-91` 只在文案后写1条`prompt_tokens/completion_tokens` 从不填httpx响应没解析usage
- `run_image_generation`(L122-216) 整个函数**无任何 AiCallLog 写入**——生图调用零留痕。
**现状代码**pipeline_io.py:78-91文案日志
```python
log = AiCallLog(
workspace_id=workspace_id, user_id=task.operator_id, key_id=key_id,
task_id=task.id, provider="apiports", model=clients._model,
call_type="text", success=llm_success, latency_ms=latency_ms,
) # 缺 prompt_tokens / completion_tokens
```
**改后**:分两处。
**① 文案日志补token**依赖_call_llm返回usage需text_variants.py一并改透传usage工作量上升。一期可降级token填None保持现状但**至少把生图日志补上**。
**② 生图日志新增**run_image_generation 末尾db.commit前
```python
# 生图调用留痕(与文案对称)
try:
img_log = AiCallLog(
workspace_id=workspace_id, user_id=task.operator_id, key_id=None,
task_id=task.id, provider=getattr(clients, "_image_provider", "apiports"),
model="gpt-image-2", call_type="image",
success=any(not r.get("error") for r in image_results),
latency_ms=image_latency_ms, # 需在gather前后记时间
)
db.add(img_log)
except Exception as e:
logger.warning("生图 ai_call_logs 写入失败(非阻断): %s", e)
```
gather 前加 `t0 = time.monotonic()`,后算 `image_latency_ms`
**改动文件**`pipeline_io.py`生图日志约12行token数透传需 text_variants.py + 调整_call_llm返回约20行建议二期
**风险**飞轮一期是否强依赖token数若不依赖token降级、只补生图成败/耗时/provider即可。
**验收**跑一次任务ai_call_logs 表里文案+生图各一条,生图条 provider/model/success/latency 齐。
**待拍板**token数这期补不补建议先补生图留痕token二期。
---
## 修7 · 文案 Gemini 兜底层未接
**根因**:现链路 LLM(Claude)→本地模板 两层text_variants.py:89-91`gemini_factory.gemini_generate` 只服务生图文案无Gemini通道。
**现状代码**text_variants.py:89-91
```python
copies: list[dict] = await _generate_in_batches(llm_client, product, count, extra)
if not copies:
copies = list(build_local_drafts(product, count)) # 直接掉本地兜底
```
**改后**Claude失败后、本地兜底前插Gemini文案。需 gemini_factory 加 chat 方法(现只有图)。
```python
copies = await _generate_in_batches(llm_client, product, count, extra)
if not copies:
logger.warning("Claude文案失败,尝试Gemini兜底")
try:
copies = await _generate_via_gemini(product, count, extra) # 新函数
except Exception as e:
logger.error("Gemini文案兜底也失败: %s", e)
if not copies:
copies = list(build_local_drafts(product, count)) # 最终本地兜底
```
新增 `_generate_via_gemini`:调 gemini chat → 复用 parse_json_array。
**改动文件**`text_variants.py`约15行`gemini_factory.py`加chat_complete方法约15行
**风险**①Gemini文案质量/JSON格式遵守度要验可能不如Claude ②Gemini key 是否各operator都配了没配则这层形同虚设。
**验收**停Claude(模拟503)确认走Gemini出文案而非直接本地模板。
**待拍板**一期是否需要三层我建议——若operator普遍没配Gemini key先不接留两层(Claude+本地)即可。
---
## 修8 · 上传只查 content-type 无 magic number
**根因**`products.py:174` 只查 `file.content_type`HTTP header可伪造。无字节头校验。
**现状代码**api/v1/products.py:174-179
```python
if file.content_type not in _ALLOWED_CONTENT_TYPES:
raise_business(f"不支持的文件类型 {file.content_type}...")
data = await file.read()
if len(data) > _MAX_SIZE_BYTES:
raise_business("文件超过 10 MB 限制")
```
**改后**读完data后加真实字节头校验。
```python
data = await file.read()
if len(data) > _MAX_SIZE_BYTES:
raise_business("文件超过 10 MB 限制")
# magic number 校验真实文件类型(防伪造content-type)
if not (data[:3] == b"\xff\xd8\xff" # JPEG
or data[:8] == b"\x89PNG\r\n\x1a\n" # PNG
or (data[:4] == b"RIFF" and data[8:12] == b"WEBP")): # WebP
raise_business("文件内容不是有效的 JPEG/PNG/WebP 图片")
```
**改动文件**`backend/app/api/v1/products.py`约6行
**风险**:无。
**验收**:把 .exe 改名 .jpg + 伪造 content-type 上传 → 被拒。
---
## 修9 · 文案优化轮默认关确认题非bug
**现状**text_variants.py:107-110`TEXT_OPTIMIZE_ENABLED=false` 默认关。
注释写明apiports 60s网关下优化轮的失败要白等60s才503拖慢出文案+100s+。
**这是有意为之的工程权衡不是bug。** 两个选择:
- **A建议保持关**等北哥prompt方案到位再开架构已留位改环境变量即开
- **B 改造绕60s**优化轮也走分批小请求≤4条/批降低单请求触发60s概率。工作量M。
**改动文件**A=0改动B=text_variants.py优化轮分批约20行
**待拍板**A还是B我建议A。
---
## 修10 · 无 key 不置灰引导
**根因**:配置页有"暂无Key请录入"提示ApiKeysTab.tsx:92`/tasks/new` 开任务页不检测key、不置灰入口。用户没录key也能点开始→任务必然失败。
**现状**`NewTaskForm.tsx:38,112-115` 只处理"产品入镜但无参考图"的置灰(blockedByNoImage)无key检测。
**改后**开任务页加载时查当前用户是否有key无则置灰"开始"+引导。
```tsx
// NewTaskForm 加载时
const { data: keys } = useApiKeys(); // 复用配置页的key查询
const noKey = !keys || keys.length === 0;
const blocked = blockedByNoImage || noKey;
// 开始按钮 disabled={blocked}
{noKey && <Banner> API Key <Link href="/config"></Link></Banner>}
```
**改动文件**`frontend/src/components/tasks/NewTaskForm.tsx`约10行、可能复用key查询hook。
**风险**:无。
**验收**清空key→开任务页"开始"置灰+引导文案+跳配置链接。
---
> 第二批小结修8magic number无歧义可直接做修6生图日志建议做、token降级修7/修9需你拍板多半可降级/保持现状修10纯前端体验补强。

View File

@@ -0,0 +1,276 @@
# 北哥/倩倩姐验收反馈 + 功能差距盘点
> 记录时间2026-06-12
> 触发:倩倩姐用 qianqian 账号实跑前端,发现大量问题。要求:①先记录全部问题 ②原始需求 vs 现状做完整对比代码层验证交叉2-3轮列出未实现项。
---
## 一、倩倩姐本次实跑提出的问题(原话拆解,一条不漏)
### A. 产品管理
- A1. 选品/建任务时**不能填写其他产品**,库里只有一个"素颜霜预置样本"。
- A2. **没有产品上传入口**——产品参考图没地方上传。
### B. 文案选择文案页截图1
- B1. 前两个文案卡片83分、66分的**评分明细进度条全是0**标题0/情绪0/买点0/关键词0/合规0但总分却有83/66——评分明细丢失或没渲染。后三个75/59/76有明细。
- B2. **80分以下的文案为什么还放出来**了66/59/76 都<80——评分门槛/过滤逻辑存疑(需确认原始需求是过滤还是全展示)。
- B3. **文案到底用的什么文案方法论**——质疑文案套路(佛系人设 vs 源头小红书7步SOP此前 deferred 未决)。
### C. 图片选择图片页截图2/3/4
- C1. **产品不一致**——生成图里的产品包装和参考图对不上参考图是64字节占位图导致
- C2. **图片没办法自动缩放**——窗口变化时图片不自适应。
- C3. **第一张(hook)字体是错的**——大标题"5符种岜门/熿韵遾愳/扶妢/絹琝诙妢"全是乱码错字gpt-image-2 中文渲染翻车,连大标题都错)。
- C4. **只生成1套6张图应该最少3套不同的供选择**
- C5. **没有一张图能放大**——点击图片无法查看大图。
- C6. **窗口最小化后内容被截断**(响应式布局缺失)。
- C7. **生成的更像电商详情图,跟小红书压根不匹配**——风格定位错误。
### D. 路由/页面
- D1. **任务列表等页面 404**截图4/tasks/40/images 切到任务列表报 404 This page could not be found
### E. 功能缺失
- E1. **没有看到"爆款裂变"功能**——飞轮/裂变板块缺失或没入口。
### F. 流程/进度
- F1. 文案页"前面两个进度条没展示"(同 B1进度/评分条渲染问题)。
---
## 二、原始确认的功能板块(已从 PRD/验收清单/API契约/通关路线图/北哥回填提取)
> 来源PRD-0总纲 §5 全流程5环节 / PRD-前端 / PRD-后端 / 验收清单1A+1B / API契约 / 北哥回填解读
### 一期(1A 生产链)必做的5大环节PRD-0 §5
1. **产品配置**(管理员录):卖点/品牌词/违禁词三级/标签/风格调性/可调prompt/**参考图上传**
2. **生成文案(双轨)**轨A一次出N角度 / 轨B导入外部文案五维评分(标题25/情绪25/买点25/关键词20/合规5)**总分<90不进候选池**
3. **生成图(分镜)**gpt-image-2主+edits带产品参考图+禁纯文生图storyboard N张(1-8)各担角色6图对齐北哥标准序provider主备+重试退避
4. **爆款裂变1爆款→N笔记包**:每包完整(标题+正文+标签+分镜);卖点/标签/人群锁定参考度低30/中/高85可调 ← **一期范围**
5. **存档打包交付**:达人素材包(按笔记分文件夹+01/02命名+文案.txt+发布清单+合规说明);去水印(重编码去C2PA+削像素水印)
### 飞轮四点(1B基石E)
- events写入(选文案+3/选图+3/通过+5/打回-3/重生成-1) / aggregator返片段 / 下次prompt含片段 / UI显"本次已注入"
### 前端页面(PRD-前端)
- 登录 / 工作台 / 开新任务(选品+主题+数量+双轨入口+右侧配置预览3参考图+本次已注入横幅) / 选择文案(N卡+五维分条) / 选择图片(N批+SSE谁好谁先冒+套版预览) / 确认预览 / 组长审核台(/review) / 历史归档(任务列表+导出包) / 配置台(/config, 产品CRUD+参考图上传+标杆+成员+key只录不显余额+违禁词CRUD)
- 角色守卫:/review限组长+管理员, /config限管理员
- SSE先换60s短票再建连, 禁token直传; 5次重连退避; event_seq去重
### 关键细节点(逐条可核)
- D-1 产品参考图上传入口(配置台屏1明确要)
- D-2 文案五维评分展示+总分
- D-3 文案90分门槛后端过滤(<90不进池)
- D-4 图片放大: **PRD未明确要求**(但属基础体验)
- D-5 图片响应式缩放: **PRD未明确**(PC最小1280px)
- D-6 一次生成: 1套N张(N=image_count) ←PRD设计; **倩倩姐要3套选=超出原PRD,待确认**
- D-7 爆款裂变页: 一期范围, 当前**疑似缺失**
- D-8 任务列表页: /history 应有
- D-9 小红书风格(非电商): 无独立定义, 靠 style_tone 字段 + prompt
- D-10 SSE实时进度(谁好谁先冒/单批失败重试/能离开)
- D-11 第1张图中文乱码: gpt-image-2渲染硬伤(记忆已记, 未解)
### 【补全】上一轮盘点遗漏的原始需求(来自北哥回填/洞1-7/扒包萃取/豆包prompt
> 倩倩姐指出"讨论方案时远比这多"。重新通读 北哥回填解读 / test洞1-7 / 官网V1萃取 / 产品包扒包 / banana扒包 后补全,这些是之前漏掉的硬需求:
**北哥文案方法论豆包prompt原话最高优先级**
- N-文1 佛系反推销人设"东西放这了买不买跟我没关系"
- N-文2 随机变量池ABC身份场景5×起因情绪3×小缺点3每条随机抽不撞反同质化命脉
- N-文3 5步框架Hook暴击低价→痛点共鸣→救星登场→卖点罗列(带✅小标题)→逼单(**不是旧7步SOP**
- N-文4 正文四段痛点→实测→种草→引导350-400字3-5段空行
- N-文5 70%场景 30%产品 比例
- N-文6 标题5公式肤质/价格/功效/夸张/标题党,每条不同类型
- N-文7 反AI味负向词禁入正文神器/福音/遮羞布/日常维稳/精简底妆/不仅而且/焕发/守护——是prompt负向约束**不是事后auto_fix替换**
- N-文8 品牌词必植入文案正文(北哥"种品牌词引导天猫搜"核心诉求)
**北哥生图规则豆包prompt+回填原话)**
- N-图1 6张固定套路序①封面痛点大字②单品特写+品牌词③成分④质地⑤上脸对比⑥促单
- N-图2 品牌词出现在第2/6张转化句在第6张对比在第5张
- N-图3 好图标准:高清+构图居中+字粗大+图文匹配
- N-图4 效果对比图AI优先(实拍备),静物图实拍优先(AI备)
- N-图5 排版并入生图(AI直接把字排图上出成品),不做独立排版环
- N-图6 成组视觉统一(buildVisualSystem)一套N张共享主色/字体/贴纸
- N-图7 素材路由:产品图=商品锚点不可改 / 实拍图=肤感场景 / 爆款图=只学版式不用内容
**标杆/爆款分析北哥13环+扒包split.js**
- N-标1 标杆分析出**8特征**(SSE analyze_done带features:[8特征])——提取标题句式/开篇痛点/评论刚需
- N-标2 爆款参考度三档低30(只学结构)/中(学节奏局部替换)/高85(学标题节奏换表达防抄袭)
- N-标3 裂变维度标注:换了哪个维度/目标人群/场景/痛点点位
- N-标4 裂变必须改全文+重拍图,不变卖点/标签/人群N-19北哥死命令
- N-标5 裂变笔记综合评分(scoreCompleteNote=文案五维+图文完整度15分)
**违禁词三级洞5拍板**
- N-违1 三级🟢auto_fix视觉类自动改(前后对比→质地说明) /🟡soft_warn功效词标黄给建议(美白→提亮?) /🔴hard_block高危词必改(医用/药妆)
- N-违2 词库可配置+可批量导入(北哥词远超预置5条)+北哥可调分级
- N-违3 "遮羞布"等AI味词要单独分类入库(北哥最大痛点)
- N-违4 双保险生成时prompt规避 + 发布前检查两道关
**去水印洞3拍板**
- N-水1 出图后**必经工序**重编码去C2PA元数据 + 转JPG/轻重采样削SynthID像素水印 + 压缩
- N-水2 诚实边界C2PA 100%可去,像素水印只能削弱
- N-水3 去水印严守3:4比例不变形
**交付/数据归属洞6+洞7拍板**
- N-交1 素材包结构:发布清单.txt(自解释发几条/配图序/文案/标签) + 笔记N_角色/文件夹(01/02/03命名) + 文案.txt(标题+正文+标签) + 合规说明.txt
- N-交2 数据归属分层:客户输入物+产出物归客户可导出 / 飞轮偏好归平台不随客户走
- N-交3 **数据可导出一期就做**(洞7)全表加workspace_id隔离
- N-交4 下载必须fetch+blob(window.open无法带token会401)
**标杆采集洞1拍板**
- N-采1 一期对外标配=截图上传+手填亮点(零平台风险),系统不碰小红书服务器
- N-采2 登录态采集插件=二期北哥内部自用opt-in不进对外标配
**工程底座(架构方案+banana扒包**
- N-工1 ai_call_logs每次AI调用记谁/用多少token失败归因到个人key**一期必做**
- N-工2 健康检查 GET /health
- N-工3 同用户并发生成任务上限2(可配)
- N-工4 上传安全magic number校验+扩展名白名单+路径穿越防护
- N-工5 三层兜底文案Claude→Gemini→本地模板(buildLocalDrafts永不空手)
- N-工6 去重系统标题相似度≥0.82判重 / 正文开头签名去重
- N-工7 角度槽位机制(每条强制不同角度)做成可迁移数据
- N-工8 product.js产品图视觉分析→visualIdentity(主色/字体/包装风格)供生图用
**前端工程PRD-前端)**
- N-前1 errorCodeMap错误码映射表(9类错误码→文案+处理动作)
- N-前2 骨架屏(文案卡/图卡/审核队列loading)
- N-前3 无key时按钮置灰+首登强制引导配key页
- N-前4 4个Store(authStore/taskStore/generationStore/preferenceStore)
- N-前5 token刷新(JWT失效自动刷新,失败跳登录)
- N-前6 套版预览(选中图+文案→拼成笔记长相)
---
## 三、现状 vs 需求 差距清单(代码层 3 轮交叉验证)
> 验证方式4 个 Explore agent 并行扫码(前端/后端接口/生图文案/DB飞轮关键质疑项倩倩姐亲自复核读码 2 轮。每条附 `文件:行号` 证据。
> 图例:✅已实现 / 🟡半实现 / ❌未实现 / 🐛有bug
### 3.1 倩倩姐质疑项 — 逐条结论
| 编号 | 问题 | 结论 | 代码证据 | 根因 |
|---|---|---|---|---|
| A1 | 不能填别的产品 | 🟡 能建产品但入口只在配置台 | products CRUD全在 `api/v1/products.py:64-131`;新建表单只挂 `/config``NewTaskForm.tsx:47` 任务页只能选不能建 | 任务页缺"快捷新建产品"按钮设计取舍非bug |
| A2 | 没有产品上传入口 | ✅ 入口存在 | 后端 `products.py:150` `POST /products/{id}/upload-image` 写 image_path前端 `ProductSubComponents.tsx:73` file input | 入口在配置台产品卡内,倩倩姐没找到≈可见性问题 |
| B1 | 评分明细进度条全是0 | 🐛 SSE推送时五维占位0靠异步补 | `useSse.ts:83` 推送时填 `{title:0,emotion:0...total:X}`88-93行再异步GET补全 | SSE只推总分(`useSse.ts:77` score是number),五维详情靠后续接口补,慢/缺字段就长期显示0 |
| B2 | 80分以下文案为何放出来 | 🐛 **90分门槛形同虚设** | `text_variants.py:136` 返回含passed=False全部候选`pipeline_io.py:96-106` 无差别写库无`if not passed:continue` | 门槛只算分标记`passed`,存库时根本不按它过滤。低分全进池 |
| B3 | 文案用什么方法论 | ✅ 佛系人设+5步+变量池ABC+反AI味 | `_text_prompt.py:12`(佛系人设)/`:66`(5步框架)/`:19`(变量池ABC)/`:94`(反AI味) | 方法论已落地,是否对北哥胃口=产品决策 |
| C1 | 产品不一致 | 🟡 测试时参考图是64字节占位 | `pipeline_io.py:150` 无参考图硬失败逻辑正确;本次是测试数据问题 | 上真实产品图即可解,非代码缺陷 |
| C2/C6 | 图片不缩放/窗口截断 | ✅ 响应式CSS已有 | `images/page.tsx:55` `grid-cols-3 xl:grid-cols-5``:65` `w-full aspect-square object-cover` | agent判定不会截断需倩倩姐复现确认是否别处 |
| C3 | 第一张字体乱码错字 | 🐛 **纯靠模型画中文字,无叠字兜底** | `image_gen.py:145` prompt只描述文字让模型自画`ai_engine/`无PIL叠字 | gpt-image-2中文渲染弱是已知模型局限缺服务端Pillow叠字方案 |
| C4 | 只1套6张要≥3套 | 🐛 **架构只产1套N张** | `image_gen.py:121-173` 单个storyboard逐张生成返回扁平list调用链只跑一次 | 无"套"概念需加外层循环生N套 |
| C5 | 图片不能放大 | ❌ 无lightbox | 全局搜lightbox/放大/zoom = 0结果`images/page.tsx:60` onClick只做选中 | 功能未做 |
| C7 | 像电商图不像小红书 | 🟡 风格词有但防御弱 | `constants.py:58` 有"小红书种草风"但仅closer角色禁电商风(`storyboard_templates.py:53`),其他角色无负向词 | 缺强负向约束"禁白底产品图/禁电商详情图" |
| D1 | 任务列表404 | 🐛 **导航指向不存在的路由** | `Sidebar.tsx:22-26` `/images``/tasks/build``/tasks/list` 三个href均无对应page.tsx | 导航错配 |
| E | 没看到爆款裂变 | ❌ **全栈零实现** | 前后端+DB+worker全局搜裂变/split/fission = 0业务代码 | PRD一期范围完全没建 |
### 3.2 原始需求模块 — 整体实现度
**后端接口API契约**:核心链路基本齐
- ✅ 认证/工作区切换、API Key(只显后4位)、产品CRUD+图上传、违禁词三级、SSE一次性ticket、审核台approve/reject、打包下载、飞轮三信号+context — 全部有码
- 🐛 90分过滤失效见B2
- 🟡 轨B导入文案`task_actions.py:76` 只存库**不评分不查违禁词**worker版`text_variants.py:139`才完整)
- ❌ 标杆"出8特征"分析:`BenchmarkNote`只存手填highlights无AI结构化分析
- ❌ 爆款裂变接口
**生图/文案核心**
- ✅ 6图角色对齐北哥序(`storyboard.py:75`)、provider主备+退避(`image_gen.py:34-117`)、禁纯文生图硬拦(`pipeline_io.py:150`)、去水印(`image_postprocessor.py`)、文案双轨+方法论、五维评分逻辑(`_scoring_dims.py`)
- 🐛 生图只1套(C4)、中文叠字乱码(C3)、90分不硬拦(B2)
- 🟡 品牌词:注入逻辑在(`storyboard.py:133`)但**products表无brand_keyword列**(`models/product.py:20-54`确认无)运行时永远空第2/6张品牌词静默失效
- 🟡 电商风负向约束弱(C7)
**数据库**15张表齐全有迁移(001-007)。唯一缺口products表缺`brand_keyword`列。eval_score正确留NULL未接假评分。多租户`workspace_id`双层过滤到位。
**飞轮四点**:✅ 全通——写入(`task_actions.py:49`选文案/`review.py:113`通过/`:139`打回)、聚合(`flywheel_service.py:71`)、注入(`pipeline_steps.py:71`+`pipeline_io.py:69`)、UI已注入事件(`tasks.py:94`)、前端横幅(`FlywheelBanner.tsx`挂3页)。
**前端页面**9个核心页在(login/dashboard/tasks.new/text/images/confirm/review/history/config)。缺:`/tasks/list``/tasks/build``/images`、爆款裂变页。
### 3.3 必须修的清单(按优先级)
**P0 阻断验收**
1. 🐛 90分门槛过滤 — `pipeline_io.py:96``if not c.get("passed"): continue`B2
2. 🐛 导航404 — `Sidebar.tsx:22-26` 删/改三个坏链接D1
3. 🐛 生图≥3套 — `image_gen.py` 加外层循环 / 新增 image_sets_countC4
4. 🐛 中文乱码 — `image_postprocessor` 后加 Pillow 中文字体叠标题C3
**P1 核心缺口**
5. 🟡 brand_keyword字段 — ORM加列+迁移008+`build_product_dict`映射+DTO品牌词
6. ❌ 图片放大 lightboxC5
7. 🟡 电商风负向prompt强化C7
8. 🐛 五维分条全0 — SSE直接推score对象 / 前端补全兜底B1
**P2 功能立项**
9. ❌ 爆款裂变1爆款→N笔记— PRD一期范围需从0设计表+worker+前端页E
10. ❌ 标杆8特征分析
11. 🟡 轨B导入补评分+违禁词检测
**产品决策待倩倩姐/北哥拍板**
- 文案方法论代码已落地北哥5步框架(非旧7步)是否对北哥胃口需北哥真看B3
- 3套的"套间差异"策略(不同角度/不同风格/不同封面?)
- brand_keyword 录入在产品级还是任务级
---
## 四、补全需求的代码层验证(本轮新增,对应第二章【补全】项)
> 倩倩姐指出上一轮漏了大量讨论过的需求。这一节对补全项逐条给代码结论。**重大发现:北哥文案方法论此前项目文档标记"只落地25-30%"(BUG-14),本轮亲自读 `_text_prompt.py` 全文确认——已全部落地,那条诊断是过时记录。**
### 4.1 北哥文案方法论 — ✅ 已全部落地(推翻旧诊断)
亲自读 `_text_prompt.py` 逐行确认:
| 需求 | 结论 | 证据 |
|---|---|---|
| N-文1 佛系人设 | ✅ | `_text_prompt.py:12-15` `_PERSONA`原话"东西放这了…" |
| N-文2 变量池ABC | ✅ | `:19-46` 三池+`_pick_combo`每条随机抽;`:140` 按count抽N组 |
| N-文3 5步框架 | ✅ | `:67-73` Hook→痛点→救星→卖点✅→逼单**确是5步非7步** |
| N-文4 四段350-400字 | ✅ | `:75-82` 四段结构+`:81`字数+空行 |
| N-文5 70/30比例 | ✅ | `:15` "70%场景30%产品绝不颠倒" |
| N-文6 标题5公式 | ✅ | `:85-92` 肤质/价格/功效/夸张/标题党各带词例 |
| N-文7 反AI味负向词 | ✅ | `:50-54`+`:94-101` 负向词prompt约束(非事后替换,机制正确) |
| N-文8 品牌词植入文案 | 🟡 | `:147` 注入逻辑在,但读`product.get("brand_keyword")`**products表无此列→永远空→静默失效**(同生图品牌词根因) |
### 4.2 其余补全项 — 代码结论
| 需求 | 结论 | 证据/缺口 |
|---|---|---|
| N-标1 标杆出8特征 | ❌ | `BenchmarkNote`只存手填highlights无AI分析SSE虽定义analyze_done但无8特征产出 |
| N-标2~5 爆款裂变全套 | ❌ | 全栈零实现(参考度/维度/裂变评分都没有) |
| N-违1 违禁词三级 | ✅ | `banned_word_checker.py:71-112` 三级auto_fix/soft_warn/hard_block |
| N-违2 词库可配置 | ✅ | banned_words表+CRUD接口批量导入未见独立接口(可逐条POST) |
| N-违3 遮羞布入库 | ✅ | `_text_prompt.py:51` 负向词含"遮羞布/日常维稳/精简底妆" |
| N-水1 去水印必经工序 | ✅ | `image_postprocessor.py` 重编码去C2PA+转JPG+重采样;`pipeline_io.py:174`已集成 |
| N-水3 严守3:4比例 | 🟡 | 后处理按原尺寸重采样未见强制3:4校验(生图prompt要1080×1440) |
| N-交1 素材包结构 | ✅ | `package_exporter.py` 笔记夹+01/02命名+文案.txt+发布清单+合规说明 |
| N-交3 数据可导出 | 🟡 | 打包下载=产出物导出有;**输入物(产品/标杆)整体导出未见**专门接口 |
| N-交4 下载fetch+blob | ❓ | 需查前端下载实现是否用window.open(待验证) |
| N-采1 截图手填标杆 | ✅ | `benchmarks.py` 截图url+highlights手填 |
| N-工1 ai_call_logs | ✅ | `models/flywheel.py:63` 表在;`pipeline_io.py:80` 有写入 |
| N-工2 GET /health | ❓ | 待确认路由是否注册 |
| N-工3 并发上限2 | ❓ | 环境变量IMAGE_CONCURRENCY=2是生图并发任务级并发限制待确认 |
| N-工4 上传安全 | ❓ | products上传是否做magic number校验待查 |
| N-工5 三层兜底文案 | 🟡 | 本地兜底`build_local_drafts`Claude→Gemini双层兜底待确认是否接 |
| N-工6 去重系统 | ✅ | `dedupe_copies`(text_variants.py:136调用) |
| N-工7 角度槽位 | ✅ | text_angles产品档案字段+`build_prompt:146`注入 |
| N-工8 产品图视觉分析 | ❌ | 无product.js等价的visualIdentity分析(主色/字体提取) |
| N-前1 errorCodeMap | ❓ | 前端错误码映射表待查 |
| N-前2 骨架屏 | ❓ | 待查 |
| N-前3 无key置灰引导 | ❓ | 待查 |
| N-前6 套版预览 | 🟡 | confirm页有预览"封面+内页拼笔记长相"完整度待查 |
### 4.3 本轮新增的"未实现/待查"清单补进第三章P级
**新确认 ❌ 未实现(之前漏列)**
- 标杆8特征分析N-标1
- 爆款裂变全套N-标2~5与E同
- 产品图视觉分析visualIdentityN-工8
- 输入物整体导出N-交3部分
**🟡 半实现/隐患(之前漏列)**
- 文案品牌词植入静默失效N-文8与生图品牌词同根因products表缺brand_keyword列
- 去水印3:4比例无强制校验N-水3
**❓ 需补一轮验证(本轮时间未及,诚实标注未确认)**
- 下载是否fetch+blob还是window.openN-交4影响401
- GET /health、任务并发上限2、上传magic number校验、Claude→Gemini文案兜底
- 前端errorCodeMap、骨架屏、无key置灰引导、套版预览完整度
> ❓项我没有当场全部读码确认,不糊弄、如实标注。倩倩姐若要,我下一轮把❓全部读码坐实。

53
plans/总核销表.md Normal file
View File

@@ -0,0 +1,53 @@
# Clover 总核销表(做完一项勾一项·任务只减不增)
> 孙总方法论载体:总核销表+分模块核销表,每模块小步快跑+高频check门禁硬卡。
> 勾选规则:□未做 / ◐做了没验 / ✅真端到端验过(附证据) / ⏸️阻塞(等北哥定义)。
> **报"✅"必附证据。绝不信第一遍自评,每环必独立交叉核对(孙总:实测AI谎报"都做了"实际20-30%)。**
> 事实底座勘验workflow wf_d4c1dbab-5832026-06-126容器全Uptask41端到端312s成功
## 终点线倩倩姐2026-06-12拍板·全量
KR1链路连通 + KR2质量达标 + KR3自主可验 + KR4引擎补全(第2环+第11环) 全绿 = 全勾完。
---
> 🟢 全部7份模块核销表已细化到90分级(每份含 Ralph修改步骤 + auto/human验收清单 + 已吸收独立交叉验证修正⚠️)。
## P0 主链修真bug第5环文案 + 第6环配图
| ID | 任务 | 模块核销表 | 细化 | 状态 |
|----|------|-----------|------|------|
| M0 | 模型探活(opus-4-8/gpt-5.5)→定模型 | — | — | ✅ 2026-06-12探活:opus-4-8/gpt-5.5/sonnet-4-5全HTTP200真可用,/models已列出。按拍板用opus-4-8(文案) |
| M1 | 第5环 写文案修bug | plans/核销-第5环-写文案.md | 🟢S1-S9/AC1-6 | □ |
| M2 | 第6环 配图修bug+3套 | plans/核销-第6环-配图.md | 🟢S1-S8/A1-A8(含A6b) | ✅ 2026-06-15 task62端到端真跑:3套A/B/C各2张入库,6张全1024×1536,瓶身只印素颜霜不P品牌词,背景干净无杂物,三套真拉开差异(A痛点/B场景/C成分背书),倩倩姐过目认可前后对比图能用。倩倩姐独立核对全绿 |
## P1 配套+底座第8环审核 / 第12环归档 / 工程底座)
| ID | 任务 | 模块核销表 | 细化 | 状态 |
|----|------|-----------|------|------|
| M3 | 第8环 审核(死链/打回回路) | plans/核销-第8环-审核.md | 🟢S1-S6/A1-A8 | □ |
| M4 | 第12环 归档(日期品类筛选/导出) | plans/核销-第12环-归档.md | 🟢S1-S8/A1-A12 | □ |
| M5 | 工程底座(5并发/magic/选标杆/置灰/lightbox) | plans/核销-工程底座.md | 🟢S1-S6/A1-A8 | □ |
## P2 引擎补全第2环标杆 / 第11环裂变
| ID | 任务 | 模块核销表 | 细化 | 状态 |
|----|------|-----------|------|------|
| M6 | 第2环 标杆8特征分析 | plans/核销-第2环-标杆.md | 🟢S1-S12(S12拆a/b)/A1-A12 | ⏸等北哥给8维 |
| M7 | 第11环 裂变(工作台内) | plans/核销-第11环-裂变.md | 🟢S1-S13(含S10.5)/AC1-12 | ⏸️等北哥给档位 |
## 🔴 跨模块迁移版本号统一防三环撞008车
008=brand_keyword(第5环) / 009=features_json+analyze_status(第2环) / 010=fission_tasks表(第11环) / 011=benchmark_ids+source_fission_id(第2环S12+第11环合并)
## 总验收(最高门禁)
| ID | 任务 | 状态 |
|----|------|------|
| Z1 | 一条龙真跑通(录屏为证) | □ |
| Z2 | 北哥抽检文案+图认可 | □ |
---
## 待北哥给的定义卡P2需提前要
1. 标杆8特征具体哪8维
2. 裂变参考度档位(高/中/低)各意味多大改动、裂变维度可选哪些
3. 90分过滤后不足数量展示不足 or 补充生成?

View File

@@ -0,0 +1,58 @@
# 核销表 · P0 卖点三套来源(通用化根基)
> 90分级验收孙总方法论·硬门禁。倩倩姐2026-06-15拍板先打 P0。
> **标绿门槛=北哥真实数据端到端跑通**(倍分子素颜霜膏霜罐真图 + 文案3.txt真卖点占位数据自测只能标🟡。
> **绝不信AI第一遍自评必独立交叉核对。**
## 模块目标(倩倩姐纠偏后的正确方向)
系统是**通用**的,产品靠**上传才有**,不内置写死任何产品。卖点支持**三套来源**产品包本来就有Clover重写时漏了套1、套2字段缺口
- **套1 从产品图片提取**Gemini Vision 读图→卖点/人群/成分/视觉系统)——❌ Clover完全缺失本轮补
- **套2 用户上传填写**北哥文案3.txt就是这套真实输入——⚠ brand_keyword/人群字段没暴露在API本轮补
- **套3 产品库内置**fallback模板——⚠ 留口即可,本轮不重点做
## 🔴 已确认的现状(调研+亲读源码,不是猜)
| 项 | 现状 | 文件:行 |
|---|------|---------|
| 主流程是否写死素颜霜 | **没有**,文案/生图prompt都从products表动态读 | `_text_prompt.py:126` / `pipeline_steps.py:58` |
| brand_keyword 字段 | model有**API全链路没暴露**(DTO/fmt/create/update都没有) | `product.py:41` vs `products.py:24-128` |
| target_audience 人群 | **字段不存在**但storyboard在读(`product.get("target_audience")`恒空) | `storyboard.py:52` |
| 套1图片提取 | **完全没有**gemini_factory只有生图无vision读图 | `gemini_factory.py` 全文 |
| 标题公式 | **已做**(肤质/价格/功效/夸张/标题党5型) | `_text_prompt.py:84-93` |
## 验收清单(做完一个勾一个,先全列再做)
> 状态图例:⬜未开始 / 🟡占位数据自测通过 / ✅北哥真实数据端到端通过
### 套2 字段暴露改APImodel已有brand_keyword无需迁移人群需迁移
-**AC1**auto迁移012:products表加 `target_audience VARCHAR(128)`。**team-lead独立核对容器DB:SHOW COLUMNS确认brand_keyword varchar64/target_audience varchar128alembic current=012(head)**
-**AC2**autoProductCreate DTO 暴露 `brand_keyword` + `target_audience`POST/PUT 写入;`_fmt_product` 返回。**实证INSERT/UPDATE语句含两列**
-**AC3**auto`build_product_dict` 透传 `target_audience`(pipeline_steps.py:68)。**实证dict透传人群='黄黑皮想素颜的女生'品牌='倍分子'非空**
-**AC4**auto建产品→回读三字段都在。**team-lead独立跑通PASS(非采信coder自评)**
> 🔴 交叉验证发现:coder自评"测试产品已清理无残留"是**假的**,DB残留id=3,team-lead已删。印证「绝不信第一遍自评」。
> 附带:已修复product_id=1(真实素颜霜)真实数据:5条真实卖点+人群(黄黑皮想素颜的女生)+品牌(倍分子)为AC9铺路。
### 套1 图片提取新增vision对齐产品包callGeminiVision
-**AC5**autogemini_factory 新增 vision 读图方法(传产品图bytes→返回结构化分析),模型走最强档不降级。**team-lead独立交叉核验签名正确model默认claude-opus-4-8无硬编码sonnetimport无报错**
-**AC6**auto新增 analyze-product 接口:上传产品图 → 返回 {productName,sellingPoints,targetAudience,category,...}。**team-lead独立真跑核验(非采信coder)IMG_9454真图跑通source=vision4条sellingPoints非空结构完整key链路走用户keyfinally有aclosefallback存在。⚠更正coder虚标:coder报conf=0.85实测conf=0.4、productName空——vision诚实承认包装无字未瞎编(prompt'不沿用历史/不默认护肤品'生效,系统通用化方向对)。**
-**AC7**human真实膏霜罐图(IMG_9439)提取:跑analyze → 卖点/人群合理(非乱编),倩倩姐认可。
### 标题公式核对(已做,核对措辞贴北哥)
-**AC8**human核对`_TITLE_FORMULA`5型措辞对齐北哥例"黄皮素颜霜天花板!伪素颜焊在脸上"风格。
### 端到端真绿门槛(最高优先)
-**AC9**human·最小闭环已过真实数据全链路真跑通(task61,team-lead亲眼核对非采信状态码):真膏霜罐图(IMG_9454)+真卖点(烟酰胺/水解珍珠/角鲨烷)+真人群(黄黑皮)+品牌(倍分子) → 出1文1图。**逐项核对**①链路打通登录态→选品→文案→配图→pending_selection ✅ ②产品形态对(白磨砂罐非透明瓶)✅ ③背景无笔记本串味(新加负向约束⑤生效)✅ ④卖点真实(奶油质地/烟酰胺改善暗沉)✅ ⑤文案"倍分子"植入正确+banned_word=pass ✅ ⑥去AI化排版到位(中文标题清晰+emoji+卡点)✅。**认知纠正**:瓶身只印"素颜霜"=正确(瓶身=产品本身忠于参考图,品牌词进文案+图片文字层不P瓶身,倩倩姐2026-06-15拍板)。品牌词进生图特写图(第2/6张)需扩多图才能验,最小闭环只跑hook封面属正常。北哥最终认可待扩3套后整体过目。
## 待倩倩姐批次确认(攒批集中问,不一条条点)
- ✅合格线 80倩倩姐2026-06-15二次拍板coder擅改85已驳回改回80落盘CLAUDE.md
- ✅vision 走 GPT 现有通道最强档,不补 GEMINI_KEY
- ✅成分不单列字段,并入 selling_points
## 🔴 AC9 端到端真绿素材(北哥真实数据,已确认产品形态)
真身=**透明玻璃膏霜罐+白色磨砂拉丝盖+金边**,印"倍分子焕颜沁透水润/素颜霜/SKIN CREAM"。**与之前占位透明长瓶+木盖完全不同task58/60产品形态全错**。
- **生图参考图首选**`客户资料-北哥/素颜霜素材图/原图/IMG_9454.JPG`(单手持单罐,正面文字最清晰,形态完整)
- 质地近景实拍:`原图/IMG_9444.JPG`(手臂白色膏体涂抹,对应北哥"质地近景/涂抹过程"
- 双罐展示IMG_9439/9441
- 套2真实输入(来自文案3.txt):品牌词=倍分子;产品名=素颜霜;卖点(并入selling_points)=烟酰胺改善暗沉提亮/水解珍珠锁水匀肤/角鲨烷裸妆奶油肌不卡纹/伪素颜不假白/洗面奶可卸人群target_audience=黄黑皮;合规红线=禁美白祛斑速效,用提亮/自然/伪素颜

View File

@@ -0,0 +1,33 @@
# 核销表 · 工程底座
> 90分级验收孙总方法论·硬门禁。已吸收独立交叉验证修正。auto=机器判定human=目视。
> 审计结论S1-S6 全部"待执行"(代码现状未改)。行号经核对准确。
## 模块目标
7项底座硬伤①并发上限5 ②上传 magic number ③选标杆 ④无key置灰 ⑤lightbox ⑥前端不显token余额(红线) ⑦SSE一次性ticket(红线)。
## Ralph 修改步骤
| # | 改什么 | 落点 |
|---|--------|------|
| S1 | MAX_CONCURRENT_TASKS_PER_USER 默认 2→5 | config.py:45 |
| S2 | create_generation_task 在 _check_user_has_key 后加并发校验count(status in pending/running) >= MAX 则 raise_business顶部 import get_settings | task_service.py:~44 |
| S3 | await file.read() 后校验 magic numberJPEG `\xff\xd8\xff`/PNG `\x89PNG\r\n\x1a\n`/WebP `RIFF`+data[8:12]==`WEBP`,都不匹配 raise_business('文件内容与扩展名不符') | products.py:~177 |
| S4 | page.tsx 加 loadKeys 调 GET /api/v1/api-keys 存 hasKeyNewTaskForm 按钮 disabled 加 `hasKey===false`false 时 alert 区显示"未配置Key,去配置-API Key录入" | tasks/new/page.tsx:36 + NewTaskForm.tsx:112 |
| S5 | 新建 BenchmarkSelector.tsx(≤80行) 调 GET /products/{id}/benchmarks 多选 checkboxNewTaskForm 引入放"今天主题"后,传 form.benchmark_ids+onFormChange | 新建 + NewTaskForm.tsx |
| S6 | 新建 ImageLightbox.tsx(≤80行) fixed inset-0 z-50 遮罩+居中img点背景/Esc 关闭ImageProgressCard 图片加 onClick 触发 | 新建 + ImageProgressCard.tsx |
## 验收清单(做完一个勾一个)
- [ ] **A1**auto并发默认5`grep MAX_CONCURRENT_TASKS_PER_USER config.py` 含 '= 5'。
- [ ] **A2**auto并发校验在`grep task_service.py` 出现 status.in_ + MAX_CONCURRENT 引用。建议补真跑第6个任务被拒底-1
- [ ] **A3**automagic number 校验:`grep products.py` 出现 ≥2种 magic bytes 字面量。(建议补真跑:.exe改.jpg 上传被拒)
- [ ] **A4**auto无key置灰`grep tasks/new/page.tsx` 含 /api/v1/api-keys + hasKey`grep NewTaskForm.tsx` hasKey 在 disabled 条件中。
- [ ] **A5**auto选标杆`ls BenchmarkSelector.tsx` 存在 + `grep NewTaskForm.tsx` 含 BenchmarkSelector/benchmark_ids。
- [ ] **A6**humanlightbox`ls ImageLightbox.tsx` 存在 + ImageProgressCard 含 onClick人工点图确认放大弹层、Esc 关闭。
- [ ] **A7**auto前端无token余额(红线):⚠️审计修正——`grep -rn '余额\|用量\|balance\|token_usage' frontend/src` 排除 ApiKeysTab 的引导语"余额和用量请到中转站后台查看"(合规用法),其余必须为空。
- [ ] **A8**autoSSE 用 ticket(红线)`grep sse.ts` 含 'ticket=' 不含 'token='`grep stream.py` 含 ticket Query`grep sse_ticket.py` 含 issue_ticket+consume_ticket。
## 待北哥定义(不阻断代码)
- 并发上限 5 是否按客户实跑量调整(改 config.py 一行即可)。
- benchmark_ids 选入后 prompt 如何消费标杆 highlights/screenshot(归入第2环 S10/S11)。

View File

@@ -0,0 +1,49 @@
# 核销表 · 第11环 裂变
> 90分级验收孙总方法论·硬门禁。已吸收独立交叉验证修正。本环是本轮**补全的缺失引擎环**。
## 模块目标
①1个爆款笔记 → 裂变出 N 套**完整笔记包**(非只换文案,含文案+配图整套) ②裂变在工作台内呈现(不是独立页割裂) ③裂变任务可追溯源(source_fission_id) ④参考度档位(高/中/低)控制与原爆款的相似度。
## 🔴 迁移版本号统一
- **010 = fission_tasks 表(本环)**
- 011 = benchmark_ids(第2环) + **source_fission_id(本环合并进011)**
## Ralph 修改步骤
| # | 改什么 | 落点 |
|---|--------|------|
| S1 | 迁移010:新建 fission_tasks 表(id/source_note/reference_level/fanout_count/status/created_at) | 010_*.py(新) |
| S2 | FissionTask ORM 新建 | models/fission_task.py(新) |
| S3 | fission_service.py 新建(≤120行):接收源爆款+参考度+扇出数 → 构造 N 个子生成任务 | services/fission_service.py(新) |
| S4 | 裂变 prompt 模板:按 reference_level(高=贴原爆款结构/中=保卖点换角度/低=只借选题) 调 prompt | prompts/fission.py(新) |
| S5 | POST /fission 触发:写 fission_tasks扇出 N 个 task(每个完整走文案+配图) | fission.py(新) |
| S6 | ⚠️函数名修正:子任务配图调 **image_gen.py:121 generate_storyboard_images**(原清单写 generate_image_set 不存在) | fission_service.py |
| **S7** | ⚠️归并(原 S2+S7 source_fission_id 重复):迁移011 task 表加 `source_fission_id INT NULL`+ORM 字段fission 扇出时回填,标识子任务来源 | 011_*.py + task.py |
| S8 | 异步:扇出走 Celery generation 队列(N 套并发受 MAX_CONCURRENT 限) | fission_task.py(新) |
| S9 | dto.fission.ts 新建 | dto.fission.ts(新) |
| S10 | 工作台内呈现:任务列表区加"裂变"入口(非独立路由)FissionPanel 子组件 | workbench 或 tasks 页内 FissionPanel.tsx(新,≤80行) |
| **S10.5** | ⚠️审计补(AC9 遗漏):dashboard/page.tsx 加裂变任务统计/入口卡片 | dashboard/page.tsx |
| S11 | 参考度选择 UI:高/中/低 单选 + 扇出数 input(1-N受 MAX_CONCURRENT) | FissionPanel.tsx |
| S12 | 进度回流:N 套子任务状态聚合显示(x/N 完成) | FissionPanel.tsx |
| S13 | 源追溯:子任务详情页显"来自裂变 #{fission_id}"角标 | tasks/[id] 页 |
## 验收清单(做完一个勾一个)
- [ ] **AC1**auto迁移010+011:`alembic upgrade head` 成功fission_tasks 表存在task 表含 source_fission_id。
- [ ] **AC2**auto触发裂变:POST /fission(源+参考度=中+扇出=3) → 200返回 fission_id + 3个子 task_id。
- [ ] **AC3**auto完整笔记包:每个子任务跑完后**既有文案又有配图**(非只换文案)——查子 task 既有 TextCandidate 又有 ImageCandidate。
- [ ] **AC4**autosource 回填:`SELECT source_fission_id FROM task WHERE id IN(子)`全==该 fission_id(防链路断)。
- [ ] **AC5**auto参考度生效:高/中/低三档抓 prompt 请求体不同(高含原爆款全文,低只含选题),三档 prompt 互不相同(反向断言)。
- [ ] **AC6**auto配图函数:抓日志/打点确认走 generate_storyboard_images(非报 generate_image_set undefined)。
- [ ] **AC7**auto扇出受并发限:扇出数=10 但 MAX_CONCURRENT=5 → 排队不报错,最终全跑完。
- [ ] **AC8**human工作台内呈现:裂变入口在工作台/任务区**内**(非孤立新路由),点开有参考度+扇出数控件。
- [ ] **AC9**humandashboard 入口:⚠dashboard 有裂变统计卡片/入口(S10.5),点击进裂变。
- [ ] **AC10**human进度聚合:裂变后 FissionPanel 显 "x/N 完成" 实时更新。
- [ ] **AC11**human源追溯:子任务详情页有"来自裂变 #X"标识,可回查源爆款。
- [ ] **AC12**human参考度肉眼差异:同源裂高/中/低各1套高与原最像、低差异最大(北哥目视认可)。
## 待北哥定义(🔴阻断 S4/AC5/AC12
- **参考度档位(高/中/低)的具体含义** + **裂变维度定义**(沿哪些轴裂变:选题/结构/卖点/人群/场景?)。北哥未给前 S4 用占位规则(高=结构+卖点全保/中=保卖点换角度/低=只借选题)AC12 暂以"三档肉眼有梯度差异"验收。
- 扇出数上限(受 MAX_CONCURRENT=5 约束,是否允许排队超 5)。
- 裂变是否消耗与正常任务相同的额度/并发名额。

View File

@@ -0,0 +1,39 @@
# 核销表 · 第12环 归档
> 90分级验收孙总方法论·硬门禁。已吸收独立交叉验证修正。auto=机器判定human=目视。
## 模块目标
①history 按日期/品类筛选(现平铺) ②approved 下载交付包 zip 结构完整 ③多套打包(1-3套各独立笔记夹) ④客户输入物(产品/标杆)可导出(数据归属红线)。
## Ralph 修改步骤
| # | 改什么 | 落点 |
|---|--------|------|
| S1 | list_tasks 加 date_from/date_to/product_id query paramfromisoformat 转换invalid 返回 40001 | tasks.py:137-149 |
| S2 | _fmt_task 加 product_name(调用方传入)list_tasks 一次性 `Product.id.in_([...])` 建 id→name dict 避免N+1顶部补 `from app.models.product import Product`(当前无此import) | tasks.py:58-64 |
| S3 | history/page.tsx 加 dateFrom/dateTo state + 两个 `<input type=date>`(提 DateRangeFilter 子组件防超100行) | history/page.tsx:28-44 + JSX 50-94 |
| S4 | HistoryTable 表头/行加"产品"列(显 product_name ?? '-') | history/components.tsx:70-127 |
| S5 | TaskListItem 加 `product_name?:string` | dto.tasks.ts:8-16 |
| S6 | ⚠️多套打包:查所有 is_selected=True TextCandidate 按 angle_label 分组每组取第一notes 列表长度=选中套数(改 line 77-85 为 for loop)images_data 循环外查一次,每套传 `list(images_data)` 副本(退化:图共享复制进各套夹) | packaging_task.py:45-47,77-85 |
| S7 | 新建 GET /products/export + /benchmarks/export(format=json/csv)require_write_permissionbenchmarks/export 需 Product JOIN 填 product_name(复用 _fmt_benchmark 不够,只有 product_id) | products.py + benchmarks.py |
| S8 | 配置页产品 tab + 历史归档页各加"导出数据"按钮,通用 ExportButton(url,filename) 调 getBlob 下载 | history/components.tsx 或 config/ExportTab.tsx |
## 验收清单(做完一个勾一个)
- [ ] **A1**auto日期筛选传 date_from/date_to → items 全落区间;传 date_from=2099 → 空数组 total=0。⚠审计补:再验 `date_from=not-a-date` → code=40001(非500)。
- [ ] **A2**autoproduct_id 筛选:传 product_id=1 → 每条 product_id=1 且 product_name 非空。
- [ ] **A3**human前端产品列/history 表头有"产品"列,每行显产品名(非数字),与 GET /products/{id}.name 一致。
- [ ] **A4**human日期控件有开始/结束 date input填后表格刷新XHR URL 含 date_from/date_to结果≤全量。
- [ ] **A5**human下载交付包approved 任务点"下载交付包"≤60s 触发下载 delivery-{id}.zip(>1KB)`unzip -l` 含 note_01/文案.txt/发布清单/合规说明。
- [ ] **A6**autozip 结构完整:`unzip -l` grep 文案.txt/发布清单/合规说明/note_01//.jpg 全非空。⚠️审计补:若 .jpg 空先查 ImageCandidate.url 文件容器内可达(packaging_task.py:64-70 读失败静默跳过)。
- [ ] **A7**auto文案.txt 格式:`unzip -p note_01/文案.txt` 含"【标题】"、不以 `{` 开头(JSON 已解析)。
- [ ] **A8**human+auto多套打包审计改 human(需先 seed 3条 is_selected TextCandidate)→构造后 `unzip -l|grep 'note_0[1-3]/'|wc -l`≥3三套标题互不相同。
- [ ] **A9**auto产品 JSON 导出GET /products/export → 200,application/json,数组,每元素含 id/name/selling_points,且 selling_points 是数组(非JSON字符串)。
- [ ] **A10**auto标杆 CSV 导出GET /benchmarks/export?format=csv → 200,text/csv,首行表头含 product_id/highlights/created_at,行数≥已录标杆数。
- [ ] **A11**auto导出权限审计注——require_write_permission 当前只查 workspace_members 不分角色(workspace_guard.py:65-88);未登录调 → code=40101workspace 成员 → 200。
- [ ] **A12**human不显 token 余额(红线):⚠️审计改 human(curl 拿不到Next.js水合后DOM)——浏览器 Ctrl+F 搜"余额/用量/tokens/balance"无结果。
## 待北哥定义(不阻断代码)
- 多套打包图片套间对应ImageCandidate 无 set_index是否加列关联文案还是退化"图共享复制进每套夹"(本期默认退化)。
- 导出入口位置(产品管理 tab 按钮 / 历史归档页全局)。
- CSV 是否加 UTF-8 BOM(Windows Excel 不乱码)。

View File

@@ -0,0 +1,49 @@
# 核销表 · 第2环 竞品标杆分析标杆8特征
> 90分级验收孙总方法论·硬门禁。已吸收独立交叉验证修正。本环是本轮**补全的缺失引擎环**。
## 模块目标
①用户截图/手填竞品爆款 → 提取标杆8特征(features_json) ②标杆可在任务里被选中(benchmark_ids) ③选中的标杆特征**真注入文案生成 prompt**(不能只存不用) ④分析结果落库可复用。
## 🔴 迁移版本号统一(防三环撞车 008
- 008 = brand_keyword第5环
- **009 = features_json + analyze_status本环**
- 010 = fission_tasks 表第11环
- **011 = benchmark_ids(task) + source_fission_id本环S12 + 第11环合并**
## Ralph 修改步骤
| # | 改什么 | 落点 |
|---|--------|------|
| S1 | 迁移 009benchmark 表加 `features_json TEXT NULL` + `analyze_status VARCHAR(20) DEFAULT 'pending'` | alembic versions/009_*.py |
| S2 | ⚠️行号修正:benchmark ORM 在 created_at(line 73)后插 features_json/analyze_status(非68-79) | models/benchmark.py:73 |
| S3 | benchmark_analyzer.py 新建(≤120行):入参截图URL/手填文本,调 chat_complete 出8特征 dict走 MODEL_TEXT(claude-opus-4-8) | services/benchmark_analyzer.py(新) |
| S4 | 8特征 prompt 模板新建:输出严格 JSON(8个 key),含 few-shot温度0.3 | prompts/benchmark_features.py(新) |
| S5 | POST /benchmarks/{id}/analyze触发分析写 features_jsonanalyze_status=done/failed | benchmarks.py |
| S6 | analyze 异步:丢 Celery generation 队列(同步会超 60s 网关);analyze_status=running→done | tasks/benchmark_task.py(新) |
| S7 | BenchmarkSelector.tsx(底座 S5 已建)展示8特征 chips + analyze_status 角标 | BenchmarkSelector.tsx |
| S8 | dto.benchmark.ts 加 features_json?:Record<string,string> + analyze_status | dto.benchmark.ts |
| S9 | 提取失败兜底:JSON parse 失败 retry 1次仍失败→analyze_status=failed,前端显"重新分析" | benchmark_analyzer.py |
| S10 | 8特征注入文案 prompt:text_variants.py 组 prompt 处拼入选中标杆 features | text_variants.py(组prompt处) |
| **S11** | ⚠️构造校验:analyze 输出必须8个 key 齐(缺 key→failed),防模型偷工 | benchmark_analyzer.py |
| **S12a** | ⚠️拆分:迁移011 task 表加 `benchmark_ids TEXT NULL`(JSON list)task.py ORM 加字段task_service.py:60-73 构造任务时补传 benchmark_ids | 011_*.py + task.py + task_service.py:60-73 |
| **S12b** | ⚠️拆分:pipeline 读取 task.benchmark_ids → 查 features_json → 注入(S10 的数据来源接通) | pipeline_io.py + text_variants.py |
## 验收清单(做完一个勾一个)
- [ ] **A1**auto迁移009:`alembic upgrade head` 成功,`DESC benchmark` 含 features_json/analyze_status。
- [ ] **A2**autoanalyze 接口:POST /benchmarks/{id}/analyze → 202/200analyze_status 转 running。
- [ ] **A3**auto8特征产出:分析完 features_json 是 dict 且**恰好8个 key**(非空、非 null、key 名与北哥定义一致)。
- [ ] **A4**auto走最强档:抓 chat_complete 请求体 model==claude-opus-4-8(非 sonnet)。
- [ ] **A5**auto异步不超时:analyze 触发后接口 <2s 返回(非阻塞等模型)。
- [ ] **A6**auto失败兜底:喂坏输入(乱码截图)→analyze_status=failed(非500/非永久 running)。
- [ ] **A7**human前端8特征:选标杆 → 卡片显8个特征 chip + 状态角标(分析中/已完成/失败)。
- [ ] **A8**human重新分析:failed 标杆有"重新分析"按钮,点后重跑。
- [ ] **A9**auto注入文案:选中标杆生文案,抓文案 prompt 请求体**含该标杆 features 文本**(grep 特征关键词命中)。
- [ ] **A10**auto不选不注入:不选标杆生文案prompt **不含** benchmark features 段(反向断言,防硬编码常驻)。
- [ ] **A11**human复用:同标杆第二个任务直接读 features_json(不重新调模型analyze_status 已 done)。
- [ ] **A12**auto审计补·最高风险:benchmark_ids **真持久化**——建任务带 benchmark_ids=[1,2]→ `SELECT benchmark_ids FROM task WHERE id=?` 取回==[1,2]。(防链路断:S10/S9 仍可能因 benchmark_ids 没存而 A9/A11 假过)。
## 待北哥定义(🔴阻断 S4/A3标杆8维度必须先定义
- **标杆8特征的名称+定义**(如:钩子类型/痛点切入/卖点呈现/信任背书/场景/情绪/CTA/排版风格?)——北哥未给前 S4 prompt 用占位8维A3 key 名校验放宽到"恰好8个 key"不校验具体名。
- 截图提取:截图是先 OCR 还是直接喂多模态(gpt 多模态 vs claude vision)?本期默认手填文本优先,截图 OCR 留接口。

View File

@@ -0,0 +1,59 @@
# 核销表 · 第5环 写文案
> 90分级验收清单孙总方法论·硬门禁。已吸收独立交叉验证修正标注处
> 规则做完一个勾一个每勾必附证据SQL结果/日志行/截图。auto=机器判定human=倩倩姐/北哥目视。
## 模块目标
文案生成做到①只展示≥90分合格文案 ②合格不足时先展示后台补 ③品牌词每条植入 ④模型升 opus-4-8 ⑤503真退避重试。
## Ralph 修改步骤(先全列,按序执行)
| # | 改什么 | 落点 |
|---|--------|------|
| S1 | run_text_generation 存库前过滤:`if not (c.get('passed') and c.get('score',0)>=90 and c.get('banned_word_status')!='hard_block'): continue`;合格数<目标时返回 needs_replenish=True | pipeline_io.py:96-118 |
| S2 | Celery 主函数检查 needs_replenish合格<text_count 时 apply_async 补充子任务(同 task_id 补 deficit主任务不等待直接推 task_done SSE子任务跑完追加写库+推 text_candidate SSE | 先 grep `@app.task`/`celery.task` 确认入口文件 |
| S3 | build_product_dict 补 brand_keyword 透传(`product.brand_keyword or ''`),与 custom_prompt 同行 | pipeline_steps.py:58-68 |
| S4 | ORM Product 加 `brand_keyword`String(64) nullable+ alembic migration 008 | product.py:39 + alembic/versions/008_brand_keyword.py新建 |
| S5 | products.py ProductCreate DTO 补 brand_keyword_fmt_product 序列化补create/update 写库赋值 | products.py:24-97 |
| S6 | 前端 dto.ts Product/CreateProductRequest 补 brand_keywordProductForm 加品牌词输入框 | dto.ts:40-62 + ProductSubComponents.tsx:138-165 |
| S7 | MODEL_TEXT 默认值改 claude-opus-4-8**三处必须全改**gemini_factory.py:166 + config.py:27 + .env:20 | 见左 |
| S8 | _call_llm 捕获 httpx.HTTPStatusError503/429 做指数退避重试≤3次2^attempt 秒),其他异常仍 return '' 降级 | text_variants.py:22-39 |
| S9 | 前端 ProductForm 补 custom_prompt 文本域品牌词下方rows=3label='自定义指令(可选)' | ProductSubComponents.tsx:154 |
⚠️ **交叉验证补强(执行前必看)**
- **S7 三处缺一假通过**:若只改 gemini_factory 默认值、.env 没改log 里 model 仍是旧值且不报错。执行后 `docker exec clover_worker env | grep MODEL_TEXT` 确认环境变量已生效。
- **S8 双保险盲点**text_variants.py:136 `dedupe_copies(...)[:count]` 的截断在 S1 过滤之前,截断后列表仍可能含 hard_blockdedupe 只去重不过滤。S1 存库前过滤是兜底,但需确认 generate_text_variants 返回值本身的口径——单保险还是双保险,执行时定。
## 验收清单(做完一个勾一个)
> 🔄 2026-06-15重大变更评分从机械5维→AI评委真读文案7维(忠于富贵理论)合格线90→**80(临时线)**。
> 已用 task54 端到端真验(product_id=1,text_count=3,image_count=0),证据见下。
- [x] **AC-1**auto✅ 合格线过滤生效task54 入库5条 score 80~86 全≥80 且无 hard_block。阈值 constants.py QUALITY_PASS_SCORE=80。
- [x] **AC-2**human✅ 先展示+后台补task54 首轮2条<目标3→触发补充→达标即停(日志"库内合格=N/3 replenished")。
- [x] **AC-3**auto✅ 品牌词全链路:临时配 product_id=1 brand_keyword='龙石'跑 task54 → 5条 title+content 全含'龙石'。**已按倩倩姐2026-06-15要求清回NULL(品牌词客户填不预置)**。
- [x] **AC-3b**auto✅ 反向断言task54 `content NOT LIKE '%龙石%'` 条数=0(全植入)。
- [ ] **AC-4**human前端有品牌词框+自定义指令域:录入保存 → GET 产品响应 brand_keyword/custom_prompt 一致。(待前端浏览器验)
- [x] **AC-5**auto✅ 实际调 opus-4-8ai_call_logs task54 model='claude-opus-4-8' success=1worker env MODEL_TEXT=claude-opus-4-8。
- [x] **AC-6**auto✅ 503真退避task51~54 日志多次出现"LLM 返回 503第1/4次重试等待5s"后恢复。
- [x] **AC-7**human✅ 前端最后一公里(2026-06-15浏览器真验)admin登录 localhost:3000 → /tasks/54/text → 用户视角看到 5/5 条文案全展示 + 每条 7维评分条(情绪张力/痛点人群/产品聚焦/买点转化/开头钩子/标题点击/合规性+总分)真实渲染总分80~86全过线顶部飞轮偏好回填("已选41次信号")同时生效。ScoreDimBars 成功消费后端 dims 数组。
## 🔴 后续待补正式工作倩倩姐2026-06-15拍板·质量优先级
- **提升文案生成质量把分数自然顶上去,不靠继续降评分线**。80是临时观察值。
方向优化生成prompt/角度正交/卖点翻译成买点的深度。质量优化是独立工作项,非本环已完成范围。
## ✅ M1 质量优化2026-06-15 去套路化·已真跑验收)
> 针对"后续待补正式工作"做的第一轮质量优化:①去掉收尾套路句 ②卖点翻译加深。
> 改动落点:`_text_prompt.py`_PERSONA 去写死范例+收尾铁律 line16_STRUCTURE_RULES 收尾策略池A-F line74-81build_prompt 卖点翻译范例 line159兜底模板去套路 line203
> 真跑证据task65(3条)+task66(5条)=8条样本product_id=1 真瓶身image_count=0。
- [x] **Q1**auto+human✅ 收尾套路句清零8条收尾**0条**含"买不买跟我没关系/东西放这了"(目标≤1)。
- [x] **Q2**human✅ 收尾多样性达标8条覆盖 **A留白/B反问/C场景延续/D克制回购** 四种策略(目标≥4种),无单一策略霸屏。
- [x] **Q3**auto✅ 分数不降8条 score_json 总分 82~92 全≥80(80=合格线,未动)。
- [x] **Q4**auto✅ 无违禁8条 banned_word_status 全 pass无 hard_block。
- [x] **Q5**human✅ 卖点翻译到位:全为可感知使用感受("熬夜后脸没那么黄""推开不卡纹路""洗面奶就能洗掉不用卸"),无裸功效词堆列。
- ⚠️ 旁证:两次跑均碰 apiports 503 短时过载致单任务少出1条(目标6实得3/5)503退避重试生效但过载窗口内仍掉条——网络层问题非质量问题已记 eval_score 列设计留NULL(真分在score_json)。
## 待北哥/倩倩姐定义(不阻断本环代码)
- 合格不足的上限重试次数(现默认补到达标或 MAX_REPLENISH_ROUNDS=3 即止,实测生效)。

View File

@@ -0,0 +1,82 @@
# 核销表 · 第6环 配图
> 90分级验收清单孙总方法论·硬门禁。已吸收独立交叉验证修正标注处含1处严重落点错误已修
> 规则做完一个勾一个每勾必附证据。auto=机器判定human=目视。
>
> 🔴 **2026-06-15 倩倩姐拍板重大调整**
> 1. **本轮目标收缩=先打通单套配图**含去AI化+尺寸可选3套正交A/B/C扩展挪到下一轮。
> 2. **去AI化对齐大卫xhs实测版**`大卫/小红书系统图片定制/xhs-tool/backend/infrastructure/imagePostProcess.js` 只读素材源运营实测去AI化能力强
> 3. **尺寸按大卫=3:4默认1024×1536gpt原生免拉伸**,原 S4/A5 写的"强缩1080×1440"**作废**——大卫±2%容差内不resize零失真。
> 4. 三套叙事措辞由倩倩姐起草,不临时占位。
>
> 🔴 **2026-06-15 端到端验证发现task58 codeproxy主通道实测**
> - **根因修复**`.env` 图片主通道曾误配 `IMAGE_PROVIDER_PRIMARY=apiports`,但 apiports 无 gpt-image-2 的 edits 端点返回SPA首页HTML→`Expecting value`报错),违反红线「生图主=codeproxy」。已改回 codeproxyworker重建task58 六图全出provider=codeproxy/success=1。详见记忆 clover-apiports-no-image-edits-endpoint。
> - ⚠️ **产品名占位污染产出(待北哥真数据)**product_id=1 name="素颜霜(预置样本)""(预置样本)"被画进图02特写标题。同"龙石"类是测试数据污染非链路bug换真实产品名即正常。
> - ⚠️ **status enum 无 'failed'**:任务失败只能无限重试或硬改 rejected设计缺口待补。
## 🟢 本轮施工图(单套配图打通·先列后做)
| # | 改什么 | 落点 | 对应大卫 |
|---|--------|------|---------|
| P1 | image_postprocessor 重写:加 RATIO_MAP(1:1/3:4/4:3/9:16/16:9)、±2%容差跳过、SynthID破除(缩2px裁1px边+modulate亮度1.005/饱和0.998env SYNTHID_HARD_MODE开关)、quality 88→100/chroma4:4:4 | image_postprocessor.py | imagePostProcess.js逐项 |
| P2 | process_image 加 aspect_ratio='3:4' 参数pipeline_io 调用处传尺寸 | image_postprocessor.py + pipeline_io.py:204 | RATIO_MAP默认3:4 |
| P3 | 生图请求尺寸对齐 1024×1536(gpt原生3:4),确认 image_gen size 正确 | constants.py + image_gen.py | 1024×1536 |
| P4 | 配图段写 ai_call_logs(call_type='image',provider,success,latency,error_code) | pipeline_io.py:244前 | Clover自有 |
> 🔴 **2026-06-15 倩倩姐纠偏:标绿门槛=真实数据端到端跑通**
> task58 是**占位产品**("素颜霜(预置样本)")跑的,**不算端到端成功**。下方 B1-B8 的"✅"降级为"🟡链路自测通过(占位数据)"**必须用北哥真实数据(产品名=素颜霜/品牌词=倍分子)重跑通才能标真绿**。倩倩姐原话"标绿不能随便标,得端到端测试成功之后才能标"。
> - apiports **确实有生图接口**(后台image key已启用/有余额/历史54万tokens),只是接法与 `/images/edits` 不同在大卫xhs里是可用备用通道待coder查正确接法后修成真备用。本轮主线先codeproxy。
## 🟡 验收清单(本轮·单套)— 占位数据自测通过,待真实数据复验
> 下列✅=占位产品task58链路自测通过🔴 = 待倍分子素颜霜真实数据重跑确认。
- [x] **B1**auto单套6图入库✅task58 `image_candidates` COUNT=6(id171-176)role齐(hook/product_closeup/ingredient/texture/applied_proof/closer)url非空/app/uploads/3/58/ 6个jpg真落盘(1.1-1.35MB)。
- [x] **B2**auto尺寸3:4=1024×1536✅task58 PIL独立读6张全部(1024,1536),容差内未拉伸。
- [x] **B3**auto去元数据✅task58 6张 exif全NONE。(SYNTHID缩边验证归B8 coder交叉)
- [x] **B4**auto尺寸可选真生效✅单测 process_image('1:1')→(1024,1024)、('3:4')→(1024,1536)、传1080×1440→resize到(1024,1536)。
- [x] **B5**auto生图写日志✅task58 `ai_call_logs` call_type='image'/provider='codeproxy'/success=1/latency_ms=345907/error_code=NULL。
- [x] **B6**auto禁降级硬失败保持✅task57 need_product_image=True无参考图→拒绝降级(日志"拒绝降级纯文生图")image_candidates COUNT=0无"降级"成功字眼。
- [x] **B7**human浏览器真验✅倩倩姐+我目视task58封面(01_hook"早八来不及"大字清晰/三卖点勾选/产品与参考图一致/场景去AI化真实/瓶身无虚假品牌词合规)+02特写(产品居中/卖点+气泡框清晰)3:4比例画质佳。⚠仅"(预置样本)"占位字样待真数据。
- [x] **B8**auto交叉验证✅coder独立起脚本重核task58结论与team-lead一致B1(COUNT=6/role齐)、B2(6张全1024×1536/exif=None/icc=None/xmp=None)、B4=B5(provider=codeproxy/success/无Expecting value报错)真绿B3 N/A(SYNTHID_HARD_MODE未开)。无谎报无放水。
---
## 📦 下一轮3套正交扩展本轮不做归档备查
> 单套打通后再做。叙事措辞等倩倩姐起草。原 S1/S2/S3/S7/S8 + A1/A2/A3/A4/A7/A8 归此。
### Ralph 修改步骤(下一轮)
| # | 改什么 | 落点 |
|---|--------|------|
| S1 | generate_storyboard_images 循环3次strategy A/B/C每次传不同 strategy_hint 影响叙事维度;返回 list[dict]→list[list[dict]] | image_gen.py:121-173 |
| S2 | plan_image_set 接收 strategy 参数,按 strategy 切换叙事描述新增A痛点先行/B场景先行/C成分背书先行3条写进 base_prompt 叙事链路段 | storyboard.py:119-193 + constants.py:66-70 |
| S3 | run_image_generation 对 A/B/C 各调一次,存 ImageCandidate 时 strategy 分别写 A/B/C修掉:207硬编码'A'SSE strategy 随之正确 | pipeline_io.py:156-213 |
| S4 | ⚠️**强制 resize**(落点已修正,见下):`Image.open(...).convert('RGB')` 后**立即**插入 `img=img.resize((1080,1440),Image.LANCZOS)`并把第47-49行 `resize(original_size)` 改为 `resize((1080,1440))` | image_postprocessor.py:41 之后 |
| S5 | run_image_generation 仿 run_text_generation:77-93三套全完后写 AiCallLogcall_type='image'provider取实际路由success/latency覆盖整批单套失败不阻断success=False写error_code | pipeline_io.py:215 db.commit() 前 |
| S6 | ALLOW_TEXT_ONLY_IMAGE 默认 'true'→'false',与 pipeline_io:150 硬失败对齐 | image_gen.py:70 |
| S7 | 前端 generationStore 新增 imageSets:Record<'A'\|'B'\|'C',ImageCandidate[]>addImageCandidate 按 strategy 分流reset/hydrate 同步 | generationStore.ts:15-122 |
| S8 | 图片选择页加 A/B/C 切换 Tab默认套A每套内单张可选DTO strategy 字段已存在无需改类型 | 新建 ImageSetTabs.tsx 或 page 内联 |
⚠️ **交叉验证补强(执行前必看)**
- **🔴S4 严重修正**:原清单写"在 buf.save 之前插入 resize"是**错的**——那个位置已经过了基于 original_size 的缩放,拿到的还是 gpt-image-2 返回的 1024×1536。正确落点`Image.open().convert('RGB')` 之后立即锁死 1080×1440且第47-49行原 `resize(original_size)` 同步改成 `resize((1080,1440))`
- **S1+S3 必须同步**S1 改返回值 list→list[list]pipeline_io.py:165 的 `enumerate(image_results)` 解包会变。**不能只做 S1 不做 S3**,中间是崩溃态。
- **S6 两层说清**pipeline_io:150 是第一层(按产品 need_product_image 字段拦image_gen:70 是第二层(直调 generate_one_image 的兜底)。两层同时维护,别只改一处。
## 验收清单(做完一个勾一个)
- [ ] **A1**auto3套各6张`SELECT strategy,COUNT(*) FROM image_candidates WHERE task_id=<id> GROUP BY strategy` → 3行每行 count=6或=image_countstrategy=A/B/C。
- [ ] **A2**autoSSE strategy 三值DevTools Network 找 SSE 流grep image_candidatestrategy 出现 A/B/C 各>0次非全'A')。
- [ ] **A3**human前置S1+S2 已完成。三套 base_prompt 叙事段不同:在 plan_image_set 加 `logger.info("strategy=%s base_prompt前100字=%s", strategy, base_prompt[:100])`确认套A含'痛点先行'/套B含'场景先行'/套C含'成分背书先行'。
- [ ] **A4**〔拆两层〕⚠️品牌词进特写图:
-auto代码层storyboard.py 中 strategy=A 的第2/6张 item 包含 brand_keyword 与 brand_keyword_rule 字段DEBUG日志或单测断言。**这是 pass/fail 判据**。
-human效果层下载第2/6张目视有'龙石'best-effort模型概率性**不作代码验收判据**——gpt-image-2瓶身小字会糊已记录在案
- [ ] **A5**auto尺寸严格 1080×1440先确认实际写盘路径worker 日志,默认 UPLOAD_BASE_PATH='uploads/packages' 不是 /app/uploads`python3 -c "from PIL import Image;print(Image.open('<实际路径>/01_hook.jpg').size)"` 必须 (1080,1440)。
- [ ] **A6**auto生图写日志`SELECT provider,success,latency_ms FROM ai_call_logs WHERE task_id=<id> AND call_type='image'` → ≥1行provider非空、latency_ms>0、success IN(0,1)。
- [ ] **A6b**auto日志内容正确性S5核心差错逻辑三套全成功时 success=1至少一套失败时 success=0 且 error_code 非空。
- [ ] **A7**auto无参考图硬失败建 need_product_image=True 但产品无参考图的任务 → task status='failed'image_candidates 无该 task 记录worker 日志**不含**'降级为纯文生图'。
- [ ] **A8**human前端 A/B/C Tab图片选择页有 A/B/C 可点 Tab点击切换图片网格内容三套 URL 不同(非平铺混在一起)。
## 待北哥定义不阻断本环代码骨架prompt 占位先留)
- 三套叙事维度的具体文案措辞(先用 痛点/场景/成分背书 占位,北哥方案到位再填)。

View File

@@ -0,0 +1,35 @@
# 核销表 · 第8环 审核
> 90分级验收孙总方法论·硬门禁。已吸收独立交叉验证修正。auto=机器判定human=目视。
> ⚠️审计结论:原清单 S1-S6 全部"描述了但代码里没有"——即这是**待执行**清单,不是已完成。落点行号经核对基本准确。
## 模块目标
①Sidebar 死链清零 + 加审核台入口 ②组长待审队列(通过/打回带原因) ③打回回路闭环(operator 能感知重选)。
## Ralph 修改步骤
| # | 改什么 | 落点 |
|---|--------|------|
| S1 | 删4条死链(/tasks /images /tasks/build /tasks/list),加 `{label:'审核台',href:'/review',roles:['supervisor','admin'],icon:'✅'}`共5条全有页面 | Sidebar.tsx:19-28 NAV_ITEMS |
| S2 | _fmt_task return dict 末尾加 `reject_reason`/`review_status`(均可None);模型 task.py:50-55 已有字段直接引用 | tasks.py:58-64 |
| S3 | TaskListItem 加 `reject_reason?:string\|null` + `review_status?:'pending'\|'approved'\|'rejected'\|null` | dto.tasks.ts:8-16 |
| S4 | 状态 span 下加 `{task.reject_reason && <p className='text-xs text-status-error mt-0.5 line-clamp-1'>打回:{task.reject_reason}</p>}`(需先 S3) | RecentTasksBar.tsx:49-61 |
| S5 | h2 后插3个 Tab(待审/已通过/已打回)已通过→router.push('/history?status=approved')已打回→rejected顶部 import useRouter | review/page.tsx:54-57 |
| S5b | ⚠审计补history/page.tsx 改 `useSearchParams` 初始化 statusFilter否则跳来后筛选器停"全部"(A7假通过) | history/page.tsx:26 |
| S6 | useEffect setCurrentTask 后补 GET /tasks/{id} 取 reject_reason 存 stateProgressBar 下、FlywheelBanner 上插红色 alert 横幅(需先 S2/S3) | tasks/[id]/text/page.tsx:23-25 |
## 验收清单(做完一个勾一个)
- [ ] **A1**autoSidebar 无死链:`grep -n href Sidebar.tsx` 不含四条死链且含 '/review'。
- [ ] **A2**auto待审队列可用supervisor GET /api/v1/review/queue → code=0 且 data.items 是数组。
- [ ] **A3**auto通过写库正确`SELECT status,review_status,approved_at,reviewer_id FROM generation_tasks WHERE id=<id>` → 四项全满足(status=review_status='approved'、approved_at 与 reviewer_id 均非NULL)。⚠审计修正assert 要含 reviewer_id(r[3])。
- [ ] **A4**auto打回写库正确RejectModal 空提交报"原因必填"不发请求;填后 `SELECT status,review_status,reject_reason` → status='pending_selection'、review_status='rejected'、reject_reason 非空。
- [ ] **A5**autoGET /tasks 含字段:被打回任务 reject_reason 为字符串、review_status='rejected';未打回为 null接口不500。
- [ ] **A6**humanoperator 感知打回supervisor 打回填"标题太硬广"→切 operator 访问 /tasks/newRecentTasksBar 卡上见红字"打回:标题太硬广"→点卡进 text 页顶部有含该文字红色横幅。
- [ ] **A7**humanTab 跳转无404/review 三 Tab点已通过→/history?status=approved 页面有内容**且筛选器自动选中"已通过"**(非"全部"),点已打回同理。⚠️审计补:需验筛选器自动预选。
- [ ] **A8**auto角色守卫审计修正——分两查`curl -w '%{http_code}'` 验 HTTP 403 + 读 body 验 `code==40301`(原命令 -o /dev/null 读不到 body)。
## 待北哥定义(不阻断代码)
- 已通过/已打回 Tab 是跳 /history 还是 /review 内分 Tab 调独立接口。
- 打回原因卡片截断字数 + 展开交互(tooltip/点击)。
- RejectModal 是否预设快选分类(标题太广告体/图文不符/违规词)。

View File

@@ -0,0 +1,101 @@
# 程1复盘 + 后续执行设计(断点续)
> 2026-06-13。程1(wf_d840d358-d3e)跑1.9h后failed。本文件记根因+已落成果+程2/3设计,断点可续。
## 程1根因已诊断
workflow 的 stall 检测 = **180s 无工具调用完成就杀 agent**
Clover 端到端生成本身要 **312s**。任何把"跑完整生成验证"当单步阻塞的 agent → 必超180s被杀 → 6次重试全栽同一坑 → workflow failed。
这是**编排设计问题,不是代码问题**。
## 程1已落成果没白跑真进项目
1. ✅ 环境勘验完成:
- codeRoot=`Clover/backend`frontendRoot=`Clover/frontend`(不在docker compose,需npm单独跑)
- docker-compose.yml 在 `backend/` 子目录(不在项目根)compose命令要加 `-f` 或 cd backend
- 后端代码挂载热重载(api带--reload改.py自动生效)**worker无热重载改worker/service代码后须 `docker compose restart worker`**
- 迁移命令 `docker exec clover_api alembic upgrade head`api启动也自动跑一次
- 6容器全Up健康端到端跑法见环境勘验result(登录admin/Clover2026!→product_id=1→建任务→轮询)
-backend的.py改动不在大repo的git status里(被ignore?)无法git回滚追踪
2. ✅ 迁移008-011真跑成功落库(alembic 007→011)
- 008 products.brand_keyword VARCHAR(64)
- 009 benchmark_notes.features_json TEXT + analyze_status VARCHAR(20)
- 010 fission_tasks 表新建
- 011 generation_tasks.benchmark_ids TEXT + source_fission_id INT
- 新建 app/models/fission.py FissionTask ORMmodels/__init__.py 已导出
3. ◐ M1文案三处改动已写进代码(待端到端验证)
- S7模型三处全改对config.py:27 + gemini_factory.py:166 + .env:20 = claude-opus-4-8
- S8重试退避text_variants.py:43-49 503/429指数退避 2^attempt
- S1合格过滤+needs_replenishpipeline_io.py:98-138 passed且score>=QUALITY_PASS_SCORE且非hard_blocksaved<text_count触发补充
- 验证中task42(2026-06-13)端到端真跑确认
## 后续执行设计倩倩姐拍板拆细workflow+我跑验证)
铁律:**agent 只改代码不跑312s长验证**;端到端真跑验证由主线程(我)用 Monitor 后台盯不受stall限。
- workflow里的agent活拆到180s内能完成读清单+改文件+跑只读/快命令(grep/SELECT/import检查)
- 抓"模型是不是opus-4-8"用 grep 代码+抓单次请求体,不靠跑完整生成
- 端到端一条龙、312s生成 → 我在主线程 Monitor
- 每环仍独立交叉验证(另起agent重核代码层),但效果层(真出文案/图)我主线程验
## 程2待办(M3审核/M4归档/M5底座) — 多碰pipeline_io/task/tasks/config须串行
## 程3待办(M6标杆/M7裂变 用占位规则)
## M1验证中断点task42 状态待Monitor回报通过则M1勾✅进程2
## M1验证实况2026-06-13真跑抓到3个真bug绝不信自评的价值
- **bug1 模型没切**task42 worker日志跑的还是 claude-sonnet-4-5。根因=worker容器env_file固化4天前旧值restart无效必须 `docker compose up -d worker` 重建(已记忆 clover-worker-env-reload-trap)。修后 printenv MODEL_TEXT=claude-opus-4-8 ✅
- **bug2 返回值解包炸**程1把 run_text_generation 改成返回3元组(加needs_replenish),但 tasks.py:102 只解包2个 → `too many values to unpack (expected 2)`,整个pipeline崩+retry循环。这正是核销表"S1+S3必须同步"风险。已修 tasks.py:102 解包3元组。
- **bug3 后台补充task缺失**needs_replenish只算出来没人消费(先展示后台补铁律没落地)。已新建 app/workers/replenish_task.py 的 replenish_text_candidates(MAX_REPLENISH_ROUNDS=3),tasks.py:108 needs_replenish时.delay触发,celery_app include+tasks.py re-export注册。
- **确认链路**task44日志铁证 model=claude-opus-4-8 success=1 latency296s(opus确实慢~300s)。opus单次响应慢,注意网关60s上限风险。
- **task45**:发干净任务验证全部修复后的完整链路(opus+解包+补充),Monitor盯中。
- sonnet旧分数(task42)3条total 80/81/80全不过90,第4/5分项系统性低(9分/0-5分)——待opus这轮看能否过90,要倩倩姐判质量。
## 程2待办(M3审核/M4归档/M5底座) — 多碰pipeline_io/task/tasks/config须串行
## M1验证收尾2026-06-13下午60s网关根因彻底解决+又揪2个真bug
### ✅ 已铁证跑通task47完整闭环
- **60s网关503根因锁定**不是apiports过载/opus慢`max_tokens=8192写死`——opus会撑满输出空间导致单批>60s撞网关。实测单条max_tokens=1500~2500仅16~18s。
- **修复3处全验证生效**:①`_call_llm`的max_tokens参数化 ②`_generate_one_batch`按批量`min(8192,max(1800,n*1800))`缩放 ③`.env`的TEXT_BATCH_SIZE=1。
- **task47链路全绿**首轮3条串行112s全成功零503→评分→过滤(只1条≥90)→先展示入库→needs_replenish触发→后台补充任务received。"先展示后台补"两截都跑通。
- **opus文案质量样本(task47 id=227)**91分(标题23/情绪25/买点25/关键词13/合规5)真实素人口吻、痛点切入、emoji自然、合规满分。明显优于sonnet旧档(80分)。
### 🐞 又揪2个真bug绝不信自评的价值
- **bug4 补充任务计数维度错**replenish_task.py第76行`added_total += len(raw)`把"原始生成数"当"合格入库数"task47实测len(raw)=2但saved=0(都没过90)→误判"累计3/3"提前停库里实际仍缺2条。已修=改用DB真实count(`db.expire_all()`+`db.query(TextCandidate).count()`)做循环条件return真实`current-existing`
- **bug5 tasks.py日志措辞误导**`已合格=%d`实际填的是len(candidates_raw)原始生成数。已修措辞为"本轮生成"+注释说明以库内saved_count为准。
### ⚠️ apiports实时负载波动非代码问题需留意
- task48验证补充修复时撞apiports高负载同样batch1单条第1条35s成功第2条起涨到61s→5033次退避重试都撞高负载窗口。基线18s→35s→61s说明是中转站负载翻倍不是代码。
- **代码已是最优**(串行单条+动态max_tokens+退避)apiports抽风时单条也会被拖过60s重试救不回。这是产品级风险点要攒给倩倩姐判断容错策略。
### M1状态代码层✅全绿(3修复+2bug已修验);效果层◐ task47闭环已证补充DBcount修复待apiports恢复后真跑确认
## M1最后一跑(task49,2026-06-15):机制全绿但合格率暴露结构性问题
### ✅ 机制层全部验证通过(哪怕极端0合格case)
- task49跑出9条文案分数79/83/71/71/87/81/79...**无一自然≥90**。
- 先展示0条合格也置pending_selection不卡用户 ✅
- 后台补充3轮全跑用DB真实count判断(bug4修复生效,没再误报"够了") ✅
- 诚实上报:`replenished=0 rounds=3 final=0 target=3`,达上限停止不无限补 ✅
- 容错(倩倩姐拍板加大重试)max_attempts=5+退避5/10/20/30s 已生效 ✅
- bug6修复image_count=0早退守卫(纯文案任务不再空跑生图通道) ✅
### 🔴 暴露的结构性质量问题(需倩倩姐判断,非bug)
- **90分线对素颜霜合格率极低**(task47首轮3条过1条,task49首轮3条+补充6条共9条过0条≈合格率0-25%)。
- **根因=评分权重结构**:满分=标题25+情绪25+买点25+关键词20+合规5。实测每条卡在**关键词覆盖13/20**(必扣5-7分,note总是"建议补品类词/长尾词")。光这项扣7分→要过90必须其余四项几乎全满分,实际把及格线推到"四项满分"。
- task47那条91分=标题23+情绪25+买点25+关键词13+合规5,是"四项接近满"的运气case。
- **opus文案本身质量不差**(真实素人口吻/痛点切入/emoji自然/合规满分),是90线+关键词20分权重太严,不是文案烂。
### 待倩倩姐判断(攒批):①90线降不降/关键词权重调不调 ②还是先让北哥抽检原文再定线 ③合格率低时补充上限3轮够不够
## 根因实锤+错误回滚(task50,2026-06-15晚)
### 🎯 关键词维度卡死的真正底因(已实测坐实)
- 之前说"依赖products.keywords配置"还不够准。**实测products表根本没有keywords字段**(只有name/category/selling_points/style_tone/text_angles/custom_prompt/image_path/brand_keyword)build_product_dict()也没传keywords。
- 所以score_keyword的`matched=[k for k in keywords...]`里keywords恒为[]→matched恒空→matched≥1(+6)+matched≥2(+5)=11分**永远拿不到**关键词维度天花板被锁在9-13分(只靠tags≥3+5/有#+4/tags≥5+4凑)。
- 入库3条实测明细坐实id225=标19情23买25**关9**合5=81id226=18/23/25/**9**/5=80id227=23/25/25/**13**/5=**91✅**。关键词全卡9-13。
### ❌ "调权重"是错误方向,已回滚
- 试过keyword20→10、把10分补给title/emotion(30/30)。task50实测84/67/75**反而更低**。
- 失败原因title/emotion的加分项要文案命中特定硬词表(场景词/情绪词/品类词)才填得满封顶34/33。文案没变命中的词没变新增的权重空间填不满→总分不升反降。删了keyword能稳拿的分没换来title/emotion的新增分。
- **已回滚constants.py到原始权重25/25/25/20/5**worker重启确认生效。constants.py注释已记录真相+正确解方向。
### ✅ 正确解(等北哥标准到位,二选一或都做)
1. 给products表补keywords字段+前端录入(让matched能真匹配)——治标,让现有硬词表评分跑通。
2. 评分用LLM语义判分替代硬编码词表(score_keyword/title/emotion都改成让模型判)——治本,但要北哥的质量标准/prompt到位。
- 现阶段:维持原始权重占位,真过关靠北哥抽检,不靠机器调权重凑数(机器分高≠过关,CLAUDE.md铁律)。
### M1结论机制层✅全绿(已勾);合格率=占位规则的已知局限,不阻断进程2,等北哥质量标准到位再治本

View File

@@ -0,0 +1,49 @@
# 配图3套正交叙事草稿北哥过目版
> 2026-06-15 提炼。**不是凭空编**——直接扒北哥给的3个真实爆款"图片爆款原因"映射成3套正交叙事。
> 产品:倍分子素颜霜(品牌词=倍分子,客户输入)。
> 用途:填进 `constants.NARRATIVE_BY_COUNT` 的套1/套2/套3 + 每套侧重3套整组拉开差异、不重复。
> **请北哥确认措辞,确认后我让 coder 填进生图 prompt。**
## 三套对应的北哥真实爆款来源
| 套 | 正交轴 | 来源爆款 | 爆款原因原话 |
|---|--------|---------|------------|
| 套1 | **痛点先行** | 爆款2 (649b) | 「脸越黄亮越快」直击痛点·针对暗黄人群;产品特写+文字突出;感叹号+对比词制造紧迫感 |
| 套2 | **场景先行** | 爆款3 (680a) | "早八""伪素颜自由"场景钩子;简洁清晰产品突出;价格"二十几"性价比 |
| 套3 | **成分背书先行** | 爆款1 (63db) | 对比强烈真实感强情绪共鸣;适合加成分图解、使用前后时间线、用户评论增强信任 |
---
## 套1 · 痛点先行(暗黄/伪素颜焦虑切入)
**叙事链路6图**
痛点暴击封面 → 暗黄脸实拍对比 → 倍分子素颜霜单品特写 → 成分为什么能救暗黄 → 上脸提亮实证 → "别再顶着黄脸早八"促单。
**整组基调**:紧迫感、强对比、情绪共鸣。文字短促带感叹号,直戳"脸黄显疲惫""素颜不敢出门"。
---
## 套2 · 场景先行(早八/通勤伪素颜自由)
**叙事链路6图**
"早八来不及"场景封面 → 手忙脚乱通勤场景 → 倍分子素颜霜一抹搞定特写 → 养肤成分让你敢素颜 → 30秒上脸效果 → "伪素颜自由+平价"促单。
**整组基调**:轻松、生活化、代入感。突出"快""省时""伪素颜自由",点到性价比但不堆砌。
---
## 套3 · 成分背书先行(信任/真实感/前后对比)
**叙事链路6图**
成分权威封面 → 核心成分图解 → 倍分子素颜霜单品特写 → 使用前后时间线对比 → 真实上脸细节 → "成分党闭眼入"促单。
**整组基调**:专业、可信、真实测评感。强调成分逻辑、前后对比、像有用户实证背书。
---
## 待北哥确认点
1. 三套基调/链路方向对不对北哥的味?
2. 措辞要不要更口语/更狠?
3. 性价比"二十几"这种具体价格要不要进图(涉及真实定价,需北哥给准数)?