# run8 剩余差异根因分析 & v2 优化方案

生成时间：2026-05-07 18:45
数据：run8 vs Ground Truth，共 231 条差异（比 run7 减少 11 条），涉及 30 个字段

---

## 总体看哪里动了、哪里没动

**P0（靶点字段）回顾**
| 字段 | run7 | run8 | 预期目标 | 实际 |
|------|:----:|:----:|:--------:|:----:|
| `subject.people_count` | 53% | **100%** | 90% | ✅ 超额 |
| `theme.primary_theme` | 20% | **53%** | 50% | ✅ 达标 |
| `production.source_type` | 13% | 27% | 85% | ❌ 严重不达标 |

**P1（secondary 系列）回顾**
- `copy.hook_type`: 40% → **73%**（+33%）✅
- `visual.secondary_presentation_formats`: 20% → **40%**（+20%）✅
- `subject.role_type`: 40% → **53%**（+13%）✅
- `offer.secondary_angles`: 7% → **7%**（0）❌ 几乎未动
- `platform_style.secondary_format_patterns`: 20% → 27%（+7%）微动
- `visual.secondary_elements`: 33% → 47%（+14%）微动
- `visual.primary_element`: 40% → 40%（0）❌
- `visual.color_tone`: 20% → 27%（+7%）微动
- `structure.edit_pace`: 73% → 73%（0）已较好

---

## 5 大根因（run8 剩余差异归类）

### 根因 1：`source_type = composite` 定义仍不够可操作（11 条差异，占 5%）

**差异模式**：
- `composite → template`（5×）：模型把"有文字叠层的实拍视频"归类为 template
- `composite → original`（5×）：模型把"有 UI 截图的真人视频"归类为 original
- `composite → mashup`（1×）：误判

**根因**：模型把 "composite" 理解成「后期合成视觉效果（AE/motion graphics）」，而人工标准是「多层元素叠加」。prompt 写了 4 个触发条件，但没讲清楚**它和 template / original 的互斥关系**。

**修复**：
- 明确"模板套用"（template）和"多层叠加"（composite）的区分：**template 看的是结构，composite 看的是层数**
- 给出具体反例：一个带大字幕的真人口播视频 = composite，不是 original

---

### 根因 2：`offer.secondary_angles` 的 "application_process" 被误多选（14 条，全字段第一）

**差异模式**：run8 高频多选 `application_process`（添加 +5）、`fully_online`（+3），而漏选 `emergency_cashflow`（-3）、`no_papers`（-2）、`flexible_terms`（-2）

**根因**：prompt 里对 secondary 的要求是"列出所有有证据的候选"，但对 `application_process` 这个枚举的定义太宽（任何"申请方便"的措辞都会命中）。同时模型对 `emergency_cashflow`（急用钱）这种**语境暗示**型的卖点识别率低。

**修复**：
- 给 `application_process` 加更严的触发条件（必须出现具体步骤：上传证件、填表、拍照等）
- 补充 `emergency_cashflow` 的触发词 hint（"急用"、"emergency"、"生病"、"家里急事"等触发场景）

---

### 根因 3：`visual.primary_element` 真人出镜被低估（9 条）

**差异模式**：
- `app_screenshot → live_person`（3×）、`badge_label → live_person`（2×）
- 总的来说 run8 倾向选 `live_person`，而 ground truth（run4 填充）倾向选 UI/badge

**根因**：这是 ground truth 本身的问题。run4 当时的判断偏向"产品元素优先"，而 run8 按新规则"面积×时长最大者优先"更合理。15 条素材里很多是**真人口播为主体、UI/数字作为辅助画面**，run8 选 live_person 其实是正确的。

**判断**：**这 9 条大部分 run8 是对的，不需要改 prompt**。建议：
- 抽样让你确认几个（materials_003、004、023、026）
- 如确认 run8 更对，则在下一轮 ground truth 迭代里修正 run4 填充值

---

### 根因 4：`visual.color_tone` 单色调归类边界值（11 条）

**差异模式**：
- `vibrant → dark`（3×）、`bright → vibrant`（2×）、`vibrant → bright`（2×）

**根因**：这是枚举定义本身的模糊地带。vibrant（鲜艳）和 bright（明亮）在人类标注者之间也经常混用，属于**边界值抖动**。

**修复**：
- 加 few-shot 示例：给出 3-4 组典型画面 + 对应 color_tone 的明确判断
- 或放弃这个字段的精确优化，在 v7 字典里合并 vibrant/bright 为一档

---

### 根因 5：`structure.secondary_story_formats` / `platform_style.secondary_format_patterns` 漏标 "none"（各 13/8 条）

**差异模式**：
- structure: `none → data_comparison`(+3)、`none → demo_walkthrough`(+2)，ground truth 是 `none`，run8 给了具体值
- platform_style: `none → talking_head_pitch`(+2)

**根因**：secondary 的"逐值检查"规则发力太猛了，在**候选证据很弱时也塞进 secondary**，导致多选。ground truth 里标 `["none"]` 意味着"除 primary 外没有次要候选"，run8 反而加了弱证据候选。

**修复**：
- 给 secondary 加「证据强度门槛」：只有在画面出现超过 3 秒、或 OCR/audio 明确提及时，才列入 secondary；偶现一两帧的候选不要写

---

## v2 优化方案（P0 精准修）

### 改动 1：重写 composite 定义（最高优先级）

```
[A-v2] production.source_type = composite 当满足以下任一：
  (a) 实拍/真人/照片画面 + 任何覆盖文字或数字叠层（文字占屏面积 > 10% 或停留 > 2 秒）
  (b) 实拍/真人画面 + 嵌入的 UI 截图或 app 界面作为画中画
  (c) 产品 UI 画面 + 独立的装饰图形、徽章、金额弹窗
  (d) 两段以上不同来源的素材拼接（真人 + 卡通、实拍 + 动画）

template 只选当：整条创意是同一模板填充（logo/商品图替换式），缺少定制化内容
original 只选当：单镜头实拍/照片，没有任何文字叠层、UI 画中画或图形叠层
```

### 改动 2：给 secondary 加"证据强度门槛"

```
[C-v2] secondary_* 补充规则：
secondary 的候选证据必须满足以下至少一项：
- 画面元素出现 ≥ 3 秒（或占总时长 20%+）
- OCR 识别到相关关键词
- 音频转写中有明确表达
- 多帧反复出现

若候选证据只出现在单帧（少于 1 秒）或只是暗示性元素，不列入 secondary。
当除 primary 外没有满足证据强度的候选时，secondary 填 ["none"]。
```

### 改动 3：offer.secondary_angles 枚举触发词校准

```
[F-new] offer.secondary_angles 关键枚举的严格触发条件：
- application_process: 必须提到具体申请步骤（上传、填表、拍照、验证、认证），不能只靠"申请方便"就选
- emergency_cashflow: 涉及紧急用钱场景（生病、家庭急事、房租、学费、意外、"不用等"、"马上到账"、"今天就要"）
- no_papers: 明确提到"无需材料/证件/抵押/担保"
- flexible_terms: 明确提到分期数、还款期可选、可延期
- high_amount: 显示具体大额数字（≥ $3000 或本币等值）
- instant_approval: 明确提到秒批/秒审/秒过
```

### 改动 4：color_tone 加 few-shot 示例

```
[G-new] visual.color_tone few-shot 示例：
- 红黄橙为主 + 饱和度高 = vibrant_colorful
- 白色/浅色背景 + 柔和色块 = bright_clean
- 深蓝/深紫/黑背景 + 冷色霓虹 = dark_neon
- 黑白灰为主 = monochrome
- 温暖棕/米/金色调 = warm_earthy
```

### 不改的（留给人工或字典 v7）

- `visual.primary_element` run8 vs run4 的 9 条差异：需要你人工判断哪边对
- `visual.color_tone` 的 vibrant/bright 边界：建议 v7 字典合并
- `subject.role_type` 的 unknown vs agent_staff：属于画面没明示身份的判断边界

---

## 执行计划

**Step 1（这轮）**：把 4 段改动注入 LABEL_SYSTEM prompt，跑 run9
**Step 2**：用同一份 ground truth 校验 run9，对比 run7/run8/run9 三版变化
**Step 3**：抽样 4 条素材人工复核 `visual.primary_element` 的判断，如果 run8/run9 更合理，则修正 ground truth 再重跑一次评估

**预计 run9 目标**：
- 总体 73.2% → **78%+**
- 人工字段 44.1% → **55%+**
- 如果 source_type 修好了，P0 三个字段全部达标

---

## 备份状态

- run7 snapshot tag: `ad-labeler-run7-snapshot-20260507-1800`
- llm_adapter/provider_bridge/label_creative_e2e 备份：`ad-creative-system/backup/run7-snapshot-20260507-1800/`
- 回滚命令：`git checkout ad-labeler-run7-snapshot-20260507-1800 -- ad-creative-system/scripts/llm_adapter.py`
