9.6 KiB
id, title, type, created, status
| id | title | type | created | status |
|---|---|---|---|---|
| grounded-question-gen-phaseA | 出题质量提升 Phase A — Grounded 单题质量(候选池 + VLM 视觉打分 selector + 单维反事实) | design | 2026-07-14 | draft |
Phase A:Grounded 单题质量
1. 目标与范围
把"干扰项 grounded 约束"从 prompt 文案(求 VLM 主观写得像)下沉到机制层:VLM 生成候选池 → VLM 视觉打分 → 按视觉可信度区间选出真实 near-miss 干扰项,从机制上消灭 Easy-Options Bias(负空间干扰项 → 排除法秒杀)。Phase A 完全不依赖 inference agent,纯出题质量 + 观测。
问题来源:[2026-07-14-ar30-too-easy-analysis.md](负空间干扰项 96.7% 正确率、SubPattern 归属跑偏)、[2026-07-14-hard-distractor-literature.md](GroundAttack/TempCompass/VITATECS 范式)。
路径归属(严格区分,避免改错路径)
| 改动 | 代码位置 | 生效范围 |
|---|---|---|
| L0 tree 错配 bug 修复 | pipeline_v2.py |
公共(纯 bug,全题型正向) |
| 候选池 + VLM 视觉打分 selector | 新建 distractor_selector.py |
公共层,strategy 声明开关,默认只 AR 启用 |
| 单维反事实约束 | strategy_action_recognition.py |
仅 AR |
| multi_true 门松绑 | gate_multi_true.md |
公共,12 类统一(grounded 干扰项过门的前提) |
| sub_pattern 持久化 + selector 观测 | tools/generate_questions.py、run_store.py |
公共(纯数据) |
非 AR 的 11 个 BaseTaskTypeStrategy:uses_grounded_selector=False,走原路径(VLM 直接出 3 个干扰项),行为不变。
2. 架构与数据流
flowchart TD
A[sample_material_v2] --> B[VLM 生成正解 + N 个候选干扰项]
B --> C{strategy.uses_grounded_selector?}
C -->|False 11类| D[取前 3 个候选 = 原行为]
C -->|True AR| E[VLM 视觉打分: 每候选 + 正解 打 0-1]
E --> F[区间选择: 选 3 个落在 正解分-δ 区间的]
F -->|凑不齐 3 个| G[退回重出 prev_reason 引导]
F -->|成功| H[组题 candidate]
D --> H
H --> I[四门 gate 用 current_tree 修复]
I -->|通过| J[on_accept 落盘 含 sub_pattern]
3. 组件设计
3.1 L0:tree 错配 bug 修复
pipeline_v2.py _process_one_slot:run_gates(tree=tree, ...) → run_gates(tree=current_tree, ...)。retry 换视频后门控用当前树验证,消除"无 source material"假拒绝。1 行改动。
3.2 策略开关与候选池生成(distractor_selector.py)
策略开关(路径隔离的核心):TaskTypeStrategy protocol 新增 uses_grounded_selector property;BaseTaskTypeStrategy 默认返回 False(11 类走原路径),ActionRecognitionStrategy 覆盖为 True。generator_v2._build_v2_prompt 的公共输出 schema 不变;候选池 + selector 逻辑放新模块 distractor_selector.py,仅当 strategy.uses_grounded_selector=True 时 _process_one_slot 调用它,其余题型仍走 generate_one_v2 直接出 4 选项。
出题拆为两步(仅 uses_grounded_selector=True):
- 正解生成(现有 generate_one_v2):VLM 生成 question + 正解 + difficulty。
- 候选池生成(新 distractor_selector):给定 question + 正解 + 素材,VLM 一次生成
N个候选干扰项(默认 N=24),每个都要求 grounded near-miss(真实发生、只在一维不同)。
3.3 VLM 视觉打分 Selector(核心,消灭 EOB)
输入: N 个候选干扰项 + 正解 + 采样帧
VLM(看真帧 + question + 每个选项) → 每个选项打"视觉可信度" score ∈ [0,1]
正解得分 s_correct(应偏高)
选 3 个 distractor,使 score ∈ [s_correct - δ_high, s_correct - δ_low]:
- 上界 s_correct - δ_low: 不能太接近正解(否则真歧义/也对)
- 下界 s_correct - δ_high: 不能太低(否则负空间,排除法可解)
凑不齐 3 个 → 退回重出(reject_reason="grounded 干扰项不足")
δ_low、δ_high 为配置参数(默认 δ_low=0.05、δ_high=0.35)。核心洞察:干扰项与正解视觉可信度接近 → 排除法("搜不到就排除")失效。
退化处理(避免 AR 系统性欠产):候选池凑不齐 3 个落区间时按序退火:
- 扩大候选池再生成一轮(N → 2N);
- 仍不足则逐步放宽 δ_high(+0.1,最多 2 次),保证下界不越过 δ_low;
- 仍不足才走正常重出(reject_reason="grounded 干扰项不足",retry_limit 兜底)。 每次 hard-fail(走到步骤 3)记录到 run_store 的 selector 观测,供调参。
3.4 单维反事实约束(仅 AR,strategy_action_recognition.py)
6 个 SubPattern 的 instruction + distractor_rules 改为内嵌"只改一维"模板 + few-shot 正例,硬约束"干扰项必须是视频中真实发生的动作/实体,仅在时点/主体/方式/对象单一维度上与正解不同,严禁缺席事件":
| SubPattern | 反事实维度 | few-shot 要求 |
|---|---|---|
| temporal_reasoning_failure | 事件顺序(同组真实事件错序) | 正解正确排序,干扰项是真实事件的错误排列 |
| fine_grained_visual_action | 执行方式(同动词的另一种真实做法) | 4 选项为同一动词的真实执行方式变体 |
| cross_segment_entity_tracking | 主体(另一实体的真实动作) | 干扰项=另一实体在该段真实做的事 |
| semantic_rigidity | 表述(同义 vs 字面陷阱) | 正解同义改写,1 干扰项复用素材原文但语义错 |
| premature_evidence_anchoring | 时点(前段真实诱饵) | 前段必须有与某干扰项字面吻合的真实局部匹配 |
| evidence_gap_confabulation | 因果完整性(诚实 vs 编造) | 正解仅陈述可观测,干扰项编造未展示因果 |
3.5 multi_true 门松绑(gate_multi_true.md,公共)
rubric 从"≥2 选项 plausibly correct → fail"改为"仅当 ≥2 选项完全满足题干限定(同主体/时点/方式/对象下都为真)→ fail"。放行"错误选项有局部真实证据、但在题干限定下为假"的近似干扰项。12 题型统一(用户确认全局松绑)。
3.6 sub_pattern 持久化 + selector 观测(公共,纯数据)
accepted_questions.json每题增sub_pattern字段:改tools/generate_questions.py的_on_accept(当前未写该字段),从 pipeline 逐题传下的 sub_pattern 写入 JSON。这是 Phase B 配对翻转门的硬前提(Phase B 按 sub_pattern 查 supports_flip),务必落实。- selector 打分观测:
question_gen_items表新增列selector_scores TEXT(JSON:正解分、选中 3 干扰项分、候选池大小、退火轮次、是否 hard-fail),幂等 ALTER TABLE 迁移(与 sub_pattern 列同法)。供 EOB 观测与调参。
4. Prior-Version Audit(现有 v2 管线行为清单)
| 现有行为 | Phase A 处置 |
|---|---|
| 每 slot 独立重出循环(retry_limit,prev_reason 传回) | 保留 — selector 凑不齐干扰项走同一重出机制 |
| on_accept 逐题追加 JSON(崩溃最多丢一题) | 保留 — 仅新增 sub_pattern 字段 |
| progress 断点续跑(slot_id → status) | 保留 — 不动 |
| 四门 gate 并发 + verbatim 短路 | 保留 — 仅改 multi_true rubric(prompt)+ 修 tree 传参 |
| embedding 去重 | 保留 |
| heavy_check 抽检 | 保留 |
| 11 个 BaseTaskTypeStrategy 出题 | 保留 — uses_grounded_selector=False 走原路径 |
未发现隐式删除。唯一行为变更:AR 出题多一个 selector 步骤;multi_true rubric 放宽(有意,全局)。
5. 非功能性需求
| 维度 | 设计 |
|---|---|
| 持久化 | 不变 — on_accept 逐题追加,崩溃最多丢一题。selector 打分随题落 run_store |
| 幂等性 | 不变 — 同 seed → 同 slot;候选池生成与 selector 打分由 rng/VLM 决定,同输入同输出(VLM 非确定性已有,不新增) |
| 断点续跑 | 不变 — progress 机制在 pipeline 层;selector 无状态,重出即重跑 |
| 原子性 | 不变 — 逐题落库;JSON 用 tmp + os.replace 原子写(现有) |
6. 行为保真检查清单
| # | 行为 | 状态 |
|---|---|---|
| 1 | 12 题型 slot 分配 | 保留 |
| 2 | 重出循环 + 换视频 | 保留 |
| 3 | 四门 gate | 保留(multi_true rubric 有意松绑 + tree 传参修复) |
| 4 | 去重/heavy_check/on_accept/断点续跑 | 保留 |
| 5 | 11 个 BaseTaskTypeStrategy 行为 | 保留(selector 默认关闭) |
| 6 | AR 出题 | 有意变更 — 候选池 + selector + 单维反事实 |
7. 配置参数(YAML)
| 参数 | 默认 | 说明 |
|---|---|---|
candidate_pool_size |
24 | VLM 生成的候选干扰项数 N |
selector_delta_low |
0.05 | 干扰项视觉分与正解的最小差 |
selector_delta_high |
0.35 | 干扰项视觉分与正解的最大差 |
8. 测试策略
- 单元:selector 区间选择(构造候选打分,验证选出落区间的 3 个 / 凑不齐时退回);uses_grounded_selector 分流(AR 走 selector、其余走原路径)。
- 集成:AR 出题端到端(mock VLM 返回候选池 + 打分)→ 验证干扰项来自候选池且落区间;sub_pattern 写入 JSON。
- 回归:11 个非 AR 题型出题行为不变(现有测试全绿)。
9. 与 Phase B 的衔接
Phase A 产出 grounded 单题;Phase B([2026-07-14-adversarial-question-gen-phaseB-design.md])在其上加"完整 agent 对抗过滤门 + 配对翻转门"揪残余 shortcut。Phase A 的 selector 观测数据为 Phase B 的难度报告提供基线。