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

8.1 KiB
Raw Blame History

裂变重写核销表(对齐上线版 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 裂变补图机制