id, title, type, created, status
| id |
title |
type |
created |
status |
| task-type-strategy |
出题管线 TaskTypeStrategy 拆分设计(Clean Architecture) |
design |
2026-07-14 |
approved |
出题管线 TaskTypeStrategy 拆分设计
1. 目标
借鉴 Clean Architecture 思想,将出题管线从 5 个粗粒度 Family 替换为 12 个题型级别的 TaskTypeStrategy,实现题型独立的出题策略。第一个特化实现为 ActionRecognitionStrategy(含 6 个失败子模式靶向出题)。
设计驱动
| 问题 |
数据来源 |
| v2-360 全部 30 道 AR 题 100% 单帧可答 |
research-wiki/findings/2026-07-14-question-quality-gap-analysis.md |
| 12/12 题型存在 CRITICAL 或 HIGH 差距 |
同上 |
| 同一 task_type 跨 family 随机选择导致行为不确定 |
app/question_gen/families.py — AR 同时在 RETRIEVAL 和 VISUAL |
| 5 个 prompt 模板零题型分支 |
store/prompts/question_gen/*.md |
2. 架构
2.1 替换关系
2.2 类层次
2.3 接口定义
strategy_name / skill_target / leak_probe_template 替代了 pipeline 中对 slot.family.name / slot.family.skill_target / slot.family.leak_profile.probe_template 的访问,确保 gate 和 store 合约不破坏。
3. SubPattern 数据结构
4. ActionRecognitionStrategy 的 6 个 SubPattern
来源:22 道错题双分类器仲裁分析。
| SubPattern |
权重 |
采样 |
错题# |
失败机制 |
| premature_evidence_anchoring |
0.20 |
L1 |
#3,4,12,17 |
找到一个证据就停搜,未验证全部选项 |
| temporal_reasoning_failure |
0.20 |
L1 |
#8,9,15,16 |
事件排序错误 / 无法定位第 N 次事件 |
| semantic_rigidity |
0.15 |
L2 |
#1,2,22 |
要求字面匹配,拒绝同义词释义 |
| fine_grained_visual_action |
0.15 |
L2 |
#6,13,14,18 |
识别"做了什么"但分不清"怎么做的" |
| cross_segment_entity_tracking |
0.15 |
L1 |
#7,19,20 |
单段正确但无法跨段合并 |
| evidence_gap_confabulation |
0.15 |
L2 |
#5,10,11,21 |
缺证据时编造因果链 |
ActionRecognitionStrategy 的 gate/store 合约值
| 字段 |
值 |
说明 |
| strategy_name |
"ACTION_RECOGNITION" |
store 的 family 字段 |
| skill_target |
"M1_AR" |
继承自 RETRIEVAL 的 M1 + AR 后缀区分 |
| leak_probe_template |
"gate_leak_retrieval.md" |
复用 RETRIEVAL 的泄漏检测模板 |
| sampling_level(默认) |
2 |
L2 事件级(从 L3 提升,有意变更) |
| sampling_constraint(默认) |
min_subtitles=3, min_l3_nodes=5, require_frames=True, cross_l2_span=True |
加强约束(有意变更) |
SubPattern 可通过 sampling_level_override / constraint_override 进一步覆盖默认值。
4.1 能力保持机制
capability_maintenance 不是生成子模式,而是采样来源:从 Video-MME AR 的 41 道正确题中采样,直接进训练集。通过 batch_correct_ratio 控制混合比例。
5. pipeline 集成
5.1 调用链变更
5.2 接口影响面
| 文件 |
变更 |
影响范围 |
sampler_v2.py |
sample_material_v2 签名:family_spec → level: int + constraint: SamplingConstraint |
函数签名 + 内部 constraint = family_spec.sampling 行 |
pipeline_v2.py |
_process_one_slot:slot.family → strategy;SlotAssignment.family 字段移除 |
_assign_slots / _process_one_slot / _process_wrapper |
generator_v2.py |
generate_one_v2 签名:新增 prompt_ctx: dict 参数,替代内部读 family_spec.prompt_template |
_build_v2_prompt / generate_one_v2 |
gates.py |
run_gates 签名:family_spec → leak_template: str |
_run_leak_test 参数变更 |
run_store.py |
record_item 新增 `sub_pattern: str |
None` 参数 |
5.3 不变的部分
后处理(postprocess)、四门 gate 内部逻辑、去重(embedding)、重量抽检(heavy_check)、on_accept 回调、progress 断点续跑 — 全部不动。
6. Strategy 注册
6.1 BaseTaskTypeStrategy family 消歧绑定表
消除多 family 随机性。每个 task_type 确定性绑定一个 family。
| task_type |
旧合法 families |
新绑定 |
被移除行为 |
理由 |
| Action Recognition |
RETRIEVAL, VISUAL |
特化策略 |
不走 family |
完全自包含 |
| Object Recognition |
RETRIEVAL |
RETRIEVAL |
无 |
唯一 |
| Object Reasoning |
RETRIEVAL, REASONING |
REASONING |
RETRIEVAL 的 L3 单帧 + 禁推理 prompt |
需要推理;RETRIEVAL 产出识别题是已知 bug |
| Action Reasoning |
REASONING |
REASONING |
无 |
唯一 |
| Attribute Perception |
RETRIEVAL, VISUAL |
VISUAL |
RETRIEVAL 的 require_frames=False |
属性感知需要帧 |
| OCR Problems |
RETRIEVAL, VISUAL |
VISUAL |
RETRIEVAL 的 require_frames=False |
OCR 需要帧 |
| Counting Problem |
ENUMERATION, VISUAL |
ENUMERATION |
VISUAL 的 L3 单帧采样 |
计数需要跨帧 |
| Information Synopsis |
REASONING, ENUMERATION |
REASONING |
ENUMERATION 的 cross_l2_span=False |
综述需要跨段 |
| Temporal Reasoning |
ENUMERATION |
ENUMERATION |
无 |
唯一 |
| Temporal Perception |
ENUMERATION |
ENUMERATION |
无 |
唯一 |
| Spatial Reasoning |
SPATIAL |
SPATIAL |
无 |
唯一 |
| Spatial Perception |
SPATIAL |
SPATIAL |
无 |
唯一 |
6.2 多归属题型约束变化明细
确定性绑定会改变多归属题型的采样约束,这是有意的行为变更(旧行为是随机混合,本身就是不可控的)。
| task_type |
旧约束(随机选择) |
新约束(确定绑定) |
变化 |
| Object Reasoning |
RETRIEVAL(L3,no-frame,no-cross) 或 REASONING(L2,no-frame,cross) |
REASONING 固定 |
不再退化为 L3 识别题 |
| Attribute Perception |
RETRIEVAL(no-frame) 或 VISUAL(frame) |
VISUAL 固定 |
始终要求帧 |
| OCR Problems |
RETRIEVAL(no-frame) 或 VISUAL(frame) |
VISUAL 固定 |
始终要求帧 |
| Counting Problem |
ENUMERATION(no-frame) 或 VISUAL(frame) |
ENUMERATION 固定 |
不再混入 VISUAL 的 L3 采样 |
| Information Synopsis |
REASONING(cross) 或 ENUMERATION(no-cross) |
REASONING 固定 |
始终跨段 |
7. 文件结构
| 操作 |
文件 |
职责 |
| 新建 |
app/question_gen/strategy.py |
Protocol + SubPattern + BaseTaskTypeStrategy + 注册表 |
| 新建 |
app/question_gen/strategy_action_recognition.py |
ActionRecognitionStrategy 实现 + 6 个 SubPattern 定义 |
| 修改 |
app/question_gen/pipeline_v2.py |
_process_one_slot / _assign_slots 改为通过 strategy |
| 修改 |
app/question_gen/sampler_v2.py |
签名 family_spec → level + constraint |
| 修改 |
app/question_gen/generator_v2.py |
签名 family_spec → prompt_ctx |
| 修改 |
app/question_gen/gates.py |
run_gates 签名 family_spec → leak_template |
| 修改 |
app/question_gen/run_store.py |
record_item 新增 sub_pattern 参数 + DDL 加列 |
| 不动 |
app/question_gen/families.py |
保留,BaseTaskTypeStrategy 内部使用 |
| 不动 |
app/question_gen/postprocess.py |
后处理不变 |
8. 非功能性需求
| 维度 |
设计 |
| 持久化 |
不变 — on_accept 逐题回调。SubPattern 名写入 store 的 sub_pattern 列以便追溯 |
| 幂等性 |
不变 — 同 seed → 同 slot 分配。strategy 查找确定性,sub_pattern 选择由 rng 控制 |
| 断点续跑 |
不变 — progress 机制在 pipeline 层,strategy 无状态 |
| 原子性 |
不变 — 逐题落库 |
| store 迁移 |
question_gen_items 表新增 sub_pattern TEXT 列,默认 NULL(BaseTaskTypeStrategy 写 NULL) |
9. 行为保真检查清单
| # |
行为 |
状态 |
说明 |
| 1 |
12 种 task_type 列表 |
保留 |
pipeline 不变 |
| 2 |
slot round-robin 视频 |
保留 |
pipeline 不变 |
| 3 |
family 加权随机选择 |
有意变更 |
消除不确定性 → 确定性绑定。详见 §6.2 |
| 4 |
_TASK_TYPE_TO_LEVEL 映射 |
有意变更 |
BaseTaskTypeStrategy 从绑定 family 读取原值(唯一归属题型数值不变);AR 特化策略从 L3→L2(有意提升);多归属题型因消歧而变化(详见 §6.2) |
| 5 |
SamplingConstraint 约束 |
有意变更 |
同 #4 逻辑:唯一归属不变,多归属因消歧变化,AR 有意加强 |
| 6 |
重出循环 + 换视频 |
保留 |
|
| 7 |
后处理洗牌 + verbatim |
保留 |
|
| 8 |
四门 gate |
保留 |
leak_test 通过 strategy.leak_probe_template 获取模板 |
| 9 |
embedding 去重 |
保留 |
|
| 10 |
重量抽检 |
保留 |
|
| 11 |
on_accept 回调 |
保留 |
|
| 12 |
progress 断点续跑 |
保留 |
|
| 13 |
reject_reason 传入重出 |
保留 |
|
| 14 |
QuestionGenStore 记录 |
保留 |
family → strategy_name;新增 sub_pattern 列 |
10. 渐进替换路径