Files
beige/plans/R-裂变重写核销表.md
yangqianqian 4bed7425a8 A8多套打包+M4归档+R5多图:存量功能备份
A8 多套交付包(packaging_task.py):
- 修复交付包只打第1条混乱note的bug,按ImageCandidate.strategy分A/B/C组
- 每组生独立note_0N夹(6图+文案.txt),同seq留最新去重,老数据兼容
- task74端到端验:3套各6图,独立agent7项交叉验证全过

M4 归档(tasks.py/exports.py/前端):
- list_tasks加date_from/date_to/product_id筛选+product_name批量填(防N+1)
- 新增exports.py:产品JSON导出+标杆CSV导出(UTF-8 BOM)
- 前端HistoryFilters日期/产品筛选+产品列+打回原因红banner
- response.py加raise_param_error;独立agent验A1/A2/A9通过

R5 产品多图(product_images.py/020迁移/前端):
- product_images表+5端点(上传/列/改场景/设主图/删图)
- 生图按ROLE_SCENE_PREFERENCE选对应场景图,回落primary
- 前端ProductImageManager多图画廊

R6 账号config拆页(settings/):
- 配置页按角色拆/settings(运营+组长+admin)+/config(仅admin)
- Key只显末4位不显余额(守红线)

核销表对齐真实代码状态:D1改稿框/M7裂变/E12评图分纠偏为已完成(曾漏回写)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 17:32:49 +08:00

89 lines
8.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 裂变重写核销表(对齐上线版 split.js一次出N套完整包
> 倩倩姐 2026-06 拍板:①架构=一次LLM出N套完整笔记包 ②N套存FissionNote表+独立展示页 ③参考度保留三档枚举,内部映射数值(low=35/mid=60/high=82)。
> 断点可续;做完一项物理勾一项;报✅必附真实证据。
## 🔴 规则清单(开工前每人逐条确认,违反即返工)
| # | 红线/约束 | 后果 |
|---|---|---|
| R1 | QUALITY_PASS_SCORE=80 任何地方不得改 | 返工 |
| R2 | 生图引擎零改动:不碰 image_gen.py/storyboard.py/pipeline_io.run_image_generation | 返工 |
| R3 | 模型最强档:文字 claude-opus-4-8回落 gpt-5.5(codeproxy),绝不降 sonnet | 返工 |
| R4 | 新建文件目标≤100行上限200行单次编辑≤100行超先建框架再Edit | — |
| R5 | 裂变三档真实措辞待北哥定义,本次用占位但接口按"内部数值"做对 | — |
| R6 | 差异化质量验收北哥过目N套真差异搁置不在本次范围 | — |
| R7 | LLM 走 chat_complete(OpenAI兼容 messages[system,user]),不是上线版/v1/messages原生端点 | 风险1 |
| R8 | FISSION_SYSTEM 作 messages[0].role=system 传不是顶级system字段 | 风险1 |
| R9 | llm_score_copy 是 asyncCelery同步环境用 asyncio.run 不能直接await | 风险 |
| R10 | 参考度入参保留 low/mid/high内部 _LEVEL_TO_INT 映射DB列不动不加迁移 | 已拍板 |
## 数据结构(已拍板)
- **新建 FissionNote 表**018迁移每套笔记一行存 文案JSON+score+passed+imagePlan+images+status。
- reference_level DB列保持 String(low/mid/high)**不改**。
- FissionTask 状态机pending→generating_text→text_done→generating_images→done/failed
- FissionNote 状态pending→scored→image_done→failed
## 文件改动清单与核销
### 后端
| # | 文件 | 改什么 | 编辑轮次 | 状态 |
|---|------|--------|---------|------|
| B1 | models/fission.py | 追加 FissionNote class(~50行) | 1次 | ✅ 已加(103行,含idx) |
| B2 | alembic/versions/018_fission_notes_table.py | 新建迁移 create_table+index(~40行) | 新建 | ✅ 已建(rev018←017) |
| B3 | ai_engine/fission_prompt.py | 全量重写:_LEVEL_TO_INT+reference_strategy_from_level+FISSION_SYSTEM+build_fission_prompt+sanitize_image_plan_text+normalize_tags+notes_array_from_parsed | 4次 | ✅ 183行;品类兜底超200行拆至 fission_fallback.py(145行) |
| B4 | services/fission_service.py | 重写:create_fission改丢Celery+编排(一次LLM出N套→评分→排序→落FissionNote→喂生图) | 4次 | ✅ 超200行拆3文件:service入口76行/fission_pipeline.py编排179行/fission_images.py生图81行 |
| B5 | workers/tasks.py | 追加 run_fission_pipeline Celery task(~35行);删旧裂变扇出注入(build_fission_context已删) | 1次 | ✅ 已注册(celery inspect registered见run_fission_pipeline);实测task5 worker日志"run_fission_pipeline start: fission_id=5 src=76"真触发 |
| B6 | api/v1/fission.py | 进度改读FissionNote聚合+新增 GET /fission/{id}/notes | 2次 | ✅ 117行,py_compile过,清掉GenerationTask import,进度按FissionNote.status聚合,notes端点剥_score/_passed内部字段+workspace隔离 |
### 前端
| # | 文件 | 改什么 | 状态 |
|---|------|--------|------|
| F1 | components/fission/FissionProgress.tsx | 进度数据源改读FissionNote结构 | ✅ status对齐generating/completed/failed,去掉子任务入口,完成跳/fission/{id}/notes展示页 |
| F2 | app/fission/[id]/notes 展示页(或组件) | 新建N套笔记展示页(标题/正文/标签/封面/imagePlan/图) | ✅ page.tsx(116行框架+类型)+FissionNoteCard.tsx(分数徽章/文案/标签/图网格/imagePlan),tsc全过 |
| F3 | FissionLauncher.tsx | 三档保留,零改动(确认即可) | ✅ low/mid/high三档+POST契约(reference_level/fanout_count/回调fission_id)与新后端一致,零改动 |
## 生图触发方案(已定)
方案一裂变Celery任务内对每套FissionNote串行调 generate_storyboard_images(现有接口零改动),结果存 FissionNote.images_json。评分用 asyncio 并发限2(参考image并发模式)。
## 验证方案
- TDD: tests/test_fission_engine.py — reference_strategy_from_level/sanitize/normalize_tags/build_fallback_notes/infer_category/评分每套独立@80 | ✅ 19 passed(197行)
- 集成: mock LLM固定JSON → parse N套→各评分→合格套排序→不合格降草稿不丢弃 | ✅ test_fission_engine(parse 4例:全套/imagePlan校正/markdown包裹/兜底不崩) + test_fission_pipeline.py(_score_notes 5例:合格线/违禁词硬拦/异常记0/多套) 全过
- 端到端: POST /fission→状态done; 一次LLM拿N套完整字段; imagePlan数=image_count; score<80标needs_optimization非丢弃; 兜底不报500; 生图走现有接口 | ✅ **真实容器实测task5(fanout=2,mid,src=76)2026-06-18跑通**: POST返回fission_id=5→worker一次apiports/chat拿2套完整(title/content/tags/imagePlan)→seq0=85分passed/seq1=79分needs_optimization=1非丢弃(R1守住)→生图走codeproxy/v1/images/edits(R2现有接口零改动)→落FissionNote→task=completed→GET/fission/5/notes返2套完整数据内部字段(_score/_passed)零泄漏;图1024×1536(对齐大卫去AI化未强缩);apiports503→回落codeproxy gpt-5.5(R3铁律真生效,日志"强档兜底非降级");seq1 hook图codeproxy重试3次失败被捕获记error不阻塞不崩任务(健壮性正确)
- 交叉审: 另起独立agent重核, 不信第一遍 | ⏳ 进行中
- 全量回归: tests/ 104 passed(顺手补 test_integration_seams mock product 缺 brand_keyword/target_audience 字段,非裂变引入的预存在失败)
## 风险点
1. FISSION_SYSTEM端点格式(chat_complete非/v1/messages) — 最易踩
2. max_tokens按note_count缩放,实测超时加FISSION_MAX_TOKENS env
3. FissionNote前端展示(已定独立展示页F2)
4. build_fallback_notes品类映射表完整移植(~80行,单独一次编辑)
5. 评分并发vs串行(asyncio.gather限2)
6. FissionProgress进度数据源同步改(F1)
## 搁置/待北哥(攒批)
- 裂变三档/参考度真实业务措辞
- N套真差异化质量验收(北哥过目)
## 补图机制中转站波动兜底2026-06-18 追加并实测✅)
> 实测发现 codeproxy 偶发不稳单套中某张图重试3次仍失败会记 error。倩倩姐拍板"不稳定的需要加再次重试的机制"。原则:只重生失败分镜,成功的图与 token 不浪费;生图引擎零改动(R2)。
| # | 文件 | 改什么 | 状态 |
|---|------|--------|------|
| RT1 | alembic 019 + models/fission.py | fission_tasks 加 source_task_id(新架构不扇出GenerationTask,补图需复刻首轮上下文:产品/operator key/张数,故落库回查;原 source_fission_id 反查链在新架构下断裂) | ✅ 迁移019 head,列已加 |
| RT2 | services/fission_service.py | create_fission 写入 source_task_id | ✅ |
| RT3 | services/fission_image_retry.py | 只补标 error 的 role(引擎 target_role 单张重生,R2零改动),merge 回 images_json,全恢复则 status=image_done | ✅ 105行 |
| RT4 | workers/tasks.py | retry_fission_images Celery task,key归属源任务operator(基石B不传明文key),幂等锁防重复补图 | ✅ 已注册(celery inspect registered) |
| RT5 | api/v1/fission.py | POST /fission/{id}/notes/{seq}/retry-images,无失败分镜守卫 queued=false | ✅ |
| RT6 | 前端 FissionNoteCard + notes/page.tsx | 失败提示改"重试补图"按钮+loading,父页轮询6次×8s刷新 | ✅ tsc过 |
- 端到端实测✅: task5 seq1(hook图首轮codeproxy重试3次失败,note_id=2)触发补图→**只补hook**(1024×1536去AI化新落盘)、**applied_proof原图不动**(时间戳未变)、recovered=1 still_failed=0、status=image_done; apiports503回落codeproxy gpt-5.5强档兜底(R3); seq0无失败图守卫返回queued=false不浪费token
- git: 285791c "裂变补图:中转站波动导致单张失败时只重生失败分镜"(8文件)
## git 提交记录2026-06-18
- 7f419f4 存量后端(生图素人感约束+评图分+幂等防重跑+审核回路)
- d85dcd4 第11环裂变重写(一次LLM出N套完整笔记包)
- 25f86b2 存量前端(生图分组/灯箱/重生控件等)
- 285791c 裂变补图机制