A8: 文案按A/B/C三套正交叙事生成,避免套路化重复

- constants: 新增 TEXT_NARRATIVE_BY_STRATEGY(A痛点/B场景/C成分),与图片侧同轴
- build_prompt: 加 strategy_narrative 参数并注入 prompt
- text_variants: 全链路透传(含优化轮)
- run_text_generation: 改循环三套,text_count均摊(divmod余前补),跨套去重,打_strategy标记
- TextCandidate: 加 strategy String(4) 字段 + 迁移021(已upgrade head)
- packaging: 打包按strategy精准配对文图(texts_by_strategy映射+三层兜底)
- SSE text_candidate 事件携带 strategy

独立agent交叉验证7改造点全过,边界(text_count<3/无别名/不截断)无must-fix

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
yangqianqian
2026-06-22 10:00:47 +08:00
parent 4bed7425a8
commit ff21116ff8
8 changed files with 123 additions and 26 deletions

View File

@@ -80,12 +80,27 @@ def build_delivery_package(self, package_id: int) -> dict:
if prev is None or ic.id > prev.id:
slot[ic.seq] = ic # 同 seq 留最新
# 文案按 strategy 建映射供图片组按套精准配对A8文图同套对齐不靠脆弱 idx
# 同套多条选中取第 1 条;老数据 strategy=None 的归入 fallback 列表。
texts_by_strategy: dict = {}
texts_no_strategy: list = []
for tc in selected_texts:
if tc.strategy:
texts_by_strategy.setdefault(tc.strategy, tc)
else:
texts_no_strategy.append(tc)
_text_fallback = iter(texts_no_strategy or selected_texts)
notes = []
for idx, (_strategy, slot) in enumerate(groups.items()):
images_data = [_read_image(slot[k]) for k in sorted(slot)]
# 文案配对:选中文案数≥套数则一套一条;否则各套共用第 1 条
# (图均以第 1 条文案为语境生成,共用合理;多选则尊重运营按套选的文案)
tc = selected_texts[idx] if idx < len(selected_texts) else selected_texts[0]
# 配对优先级:①同 strategy 文案精准对齐 ②无同套则按顺序取无套文案
# ③再兜底用第 idx 条/第 1 条,确保每组图都有文案不漏。
tc = texts_by_strategy.get(_strategy)
if tc is None:
tc = next(_text_fallback, None)
if tc is None:
tc = selected_texts[idx] if idx < len(selected_texts) else selected_texts[0]
text_data = json.loads(tc.content or "{}")
notes.append({
"title": text_data.get("title", ""),