--- id: question-gen-v3-construction-paradigm title: question-gen v3 — 构造优先范式重构(全孪生 + 四家族真独立 + 坍缩度量) type: design created: 2026-07-15 status: draft supersedes: 2026-07-15-question-gen-v2-grounded-contrastive-design.md --- # question-gen v3:构造优先范式重构 ## 1. 目标与范围 **完全重构**出题管线,**只做 Action Recognition 分支**。范式从 v2 的"自由生成候选池→打分过滤"(被 [2026-07-15-question-gen-paradigm-shift-construction-over-filtering.md] 判为 AFLite 死路)转向**"从视频树的结构化事实受控构造对比对,grounding/难度/唯一性由构造保证;难度/歧义用两个正交且真独立的信号验证;验收用配对坍缩度量而非原始准确率"**。 **范围铁律**:v3 只产 AR 题(全部 pair 格式);11 个非 AR 题型仍走旧 `generate-v2`(single,byte-identical,零改动)。题库混格(AR pair + 非 AR single),评测/训练侧用 `QuestionUnit(single|pair)` 兼容。 **决策锁定**(本次 brainstorming):① 全设计一次到位(6 子模式 + 完整契约);② 全孪生格式(含 fine_grained 改造成对比对);③ 全栈验证每题跑,不为成本砍;④ 四家族真独立裁判。 ## 2. 范式与文献依据 依据 6 篇原文深读(`reference/papers-distractor-gen/`,证据页码见各深读报告): | 论文 | 移植的核心机制(本质,非表面) | |------|------------------------------| | Vinoground | 负项=正项**最小结构编辑**(bag-of-words 完全相同、只换单轴);grounding 靠真实时序事实;**双向 AND** 消语言先验;0 帧盲答对照 | | TempCompass | **冲突孪生对**(A 的干扰项=B 孪生体正解);**去捷径坍缩度量**(配对准确率掉回随机=有效性证明);多格式交叉一致性 | | VITATECS | **aspect 正交分解 + 单轴等信息量非蕴含最小编辑**;precision-over-recall;**警告:纯词汇/名词替换→74.5-90.3% 可解**(禁止) | | GroundAttack | 只换负项保 V/Q/A;grounding=独立度量真实视觉对齐;**软肋:wrongness 无独立验证**(必须外挂独立核验) | | AFLite | **过滤救不了质量**(单信号混淆难/歧义)→ 后置过滤只作兜底 | | AdVQA | **对抗前移生成端**(活求解器试答骗不过就重构)+ **独立于求解器的多裁判答案一致性**;自动对抗无核验→答案漂移 | **核心不变量**:① 干扰项=视频里真实存在、但绑到错误查询点的事实(grounded 且 wrong 由构造保证);② 答案核验器必须独立于被攻求解器;③ 度量用配对坍缩,非原始准确率。 ## 3. 架构与数据流 ```mermaid flowchart TD T[视频树: 有序L1/L2/L3 + 结构化列表 + subtitle + frame_path] --> FS[fact_sampler 采可翻转结构化事实] FS --> AX{子模式→孪生轴路由} AX --> TB[twin_builder 构造孪生对 P/Q
单轴最小编辑, bag-of-words 硬匹配, 禁蕴含] AX --> AB[attribute_binder 静态属性绑定
需薄抽取层: 树自由文本→对象,属性,位置] TB --> L1[层1 结构构造保证: 相反事实锚定树节点] AB --> L1 L1 --> L2[层2 坍缩度量: text-only盲答 + 单帧基线 掉回随机] L2 -->|未坍缩| RJ[拒/重构] L2 --> L3[层3 看帧核实: qwen+MiniMax 交叉查构造事实真伪] L3 -->|安慰剂: 错配帧分不坍塌| RJ L3 --> L4[层4 活求解器难度探针: deepseek AgentLoop 双向答对=太易] L4 -->|太易| RJ L4 --> L5[层5 独立多裁判歧义: kimi+qwen+MiniMax 三异家族判唯一性] L5 -->|歧义/双正解| RJ L5 --> L6[层6 多格式交叉: MC vs Y-N 求解器一致] L6 -->|不一致=格式捷径| RJ L6 --> ACC[on_accept 逐 unit 原子成对落盘] RJ --> QN[失败内容指纹入 quarantine 去重] --> BF[补构造迭代
收敛上界+产量降级路径] BF --> FS ``` ## 4. 六子模式构造算法 统一原理:**对锚定真实树事实的"正题"做单轴最小编辑得孪生"反题",干扰项=视频里真实存在但绑到错误查询点的事实**。 **选项基数(契约锁定,§7 阈值全对齐)**:每个孪生子题 = **4 选 MCQ**(1 正解 + 3 干扰项),孪生 P/Q **共享同一 bag-of-words 选项集**(同词不同绑定),答案跨孪生翻转。 所有孪生对硬约束: - **bag-of-words 硬匹配**(非"尽量")、单轴、等信息量、动词/事件结构编辑(**严禁名词/属性词汇替换**,VITATECS 实测改 1 名词即 82% 可解); - **禁蕴含**:正解与各干扰项互不蕴含,由 **kimi 真 LLM 裁判判定**(text-embedding 仅作 bag-of-words 词形辅助,**不得作蕴含唯一信号**——审核 C7:embedding 近似蕴含是假绿灯); - **平衡/因子布局根治逐维众数(C1 根治,非仅事后指标)**:4 个选项在每个语义维度上每个取值出现次数均衡(→逐维众数无定义),构造后跑 `majority_vote_baseline(options)==answer → fail` **纯算法硬校验**,作阶段 2 CI hard-fail; - **槽位强制反置**(防 C6 槽位偏置)+ **干扰项多样性**(3 个干扰项两两 embedding 距离须过下界门,防 GroundAttack distractor-similarity 扎堆一起被排除); - **题干模板对称(C8,防翻转轴泄露)**:before/after、first/last 题干本身会暴露翻转轴 → 题干须模板对称(不靠词面差异指示答案);**pair 关系可解率(P+Q 盲答+规则解法)作构造期 hard-fail**,不只事后验收指标。 | 子模式 | 孪生轴 | 锚定树的什么 | 正/反题构造 | 干扰项来源 | |--------|--------|-------------|------------|-----------| | **temporal** | 时序换序 | L1 下有序 L2 序列或 L2 下有序 L3(`time_range`/`timestamp`,`children` 顺序=时序) | 正"X 之后是什么"→答真实后继;反 before↔after 翻转→答真实前驱 | 同视频真实存在但时序位置错的事件 | | **cross_segment** | 主宾互换/first-last | `action_subjects`+`actions` 跨 L2 段 | 正"谁**先**做 X"、反"谁**后**做 X",选项同集 | 别的段真实做该动作的主体 | | **premature** | 早/晚段锚点 | 段位**随机**(early/mid/late/final 各占,不固定 final) | 正问最终态、反问指定中间态 | 过早锚定的早段真实读数 | | **evidence_gap** | 诚实↔虚构因果 | 事件链 + `state_changes`(注意常 null,不可依赖) | 正支证据在场答=事实;反支证据缺席答="不可确定" | 树中未展示的合理因果延续(虚构但貌真) | | **semantic_rigidity** | 同义↔字幕陷阱 | 树的 `subtitle` 字段 + 视觉 `event_description` | 正题字幕与视觉真相一致;反题字幕是陷阱(匹配干扰项) | 字幕字面项(与视觉真相冲突) | | **fine_grained** | 同动作不同方式 | `ongoing_actions`+`visual_attributes`+看帧(需薄抽取) | 同一动作两个真实时刻的不同执行方式做对比 | 另一时刻该动作的真实不同方式 | > **事实来源澄清(对齐 §9)**:上表"锚定树的什么"列对 temporal 是**树结构直取**;对其余 5 子模式**仅为索引/候选提示**——真正的 grounded 事实由 **§9 帧感知抽取层从真实帧感知 + 双 VLM 交叉核实**得出(树的 `state_changes` 常 null、`actions/action_subjects` 无绑定等有损,均由帧感知绕过)。 > **VITATECS 硬警告落地**:编辑必须落在**动词/事件结构**(时序/主宾/次数/方式),**严禁名词/属性词汇替换**(原文实测改 1 名词即 82% 可解)。每题构造后跑纯算法门校验单轴性 + bag-of-words 相等 + 逐维众数无定义。 > **非 temporal 子模式的范式合法性论证 + 必达归属**(回应 finding §5 与 VITATECS 静态退化警告;构造机制见 §9 帧核实抽取层): > - **cross_segment / premature / semantic_rigidity = 必达**(§15 阶段2)。合法性——编辑轴均落在**事件结构**(主体-动作绑定 / 段位状态 / 视觉真相 vs 字幕字面),**非静态名词替换**,不落入 VITATECS 退化区;grounding 由 §9 帧核实抽取保证。semantic_rigidity 作为必达静态类,编辑轴=视觉真相 vs 字幕字面。 > - **fine_grained = 实现+目标必达 + 运行时门兜底**:编辑轴是**动作执行方式(manner,属动词/事件结构轴:快↔慢、左手↔右手、单次↔重复)非静态名词**;grounding 由"两个真实时刻的方式对比"锚定。风险=未必总能找到两个真实对比时刻(产量)+ 方式差异是否够单轴等信息量。运行时合法性门不过则退 finding B 路线。 > - **evidence_gap = 实现+目标必达 + 运行时门兜底**:"不可确定"选项**必须在正/反题对称出现**(防审核 C3"恒定文本靶");编辑轴=证据在场↔缺席(事件结构);幻觉风险最高,运行时门不过退保守构造。 ## 5. 四家族模型分工 | 角色 | 模型 | .env 变量 | 家族 | |------|------|----------|------| | 活求解器难度探针(复用 `core/agent` AgentLoop) | deepseek-v4-pro | SEARCH_LLM | A | | 构造表面实现 + 看帧核实 | qwen3.6-plus | VL_LLM | B | | 独立看帧核实(异家族交叉) | MiniMax-M3 | M3_VL_LLM | C | | 独立歧义/唯一性 + **禁蕴含真裁判** | **kimi-for-coding** | **新增 JUDGE_PANEL_LLM** | D | | **仅 bag-of-words 词形辅助**(非蕴含判定) | text-embedding-v4 | TEXT_EMBEDDING | 纯算法 | > **禁蕴含/语义等价判定用 kimi 真 LLM 裁判**,text-embedding 只做"选项词袋是否相等"的词形辅助——**embedding 余弦不得作蕴含唯一信号**(审核 C7:测不出语义泛化蕴含,是假绿灯)。 > 图像嵌入 `qwen3-vl-embedding` 暂不可用(几何跨模态 grounding 推迟);全孪生构造范式不依赖它。`kimi-for-coding` 需新增 .env 配置并**先测网关 newapi 是否服务**(实现第一步验证)。所有调用经 `GovernedLLMClient`(`adapters/llm.py`)治理,禁裸调。 ## 6. 六层验证栈(每题全跑,机制种类各异,不共享失效模式) | 层 | 机制种类 | 判据 | 失败处置 | |----|---------|------|---------| | **1 结构构造保证** | 符号 | 孪生答案=锚定树节点的相反事实,构造时即成立 | 构造非法→重构 | | **2 坍缩度量** | **模型探针→统计判据**(非纯算法,见 §7 分类) | text-only 盲答(deepseek,**输入含 subtitle** 以捕字幕泄答案)+ 单帧基线(VLM)正确率**必须掉回随机**(4 选≈0.25;pair 双向≈0.0625);超容差=可纯文本/单帧/字幕解→拒 | 拒+指纹去重 | | **3 看帧核实 + 帧错配安慰剂** | 视觉感知 | qwen+MiniMax 交叉查"构造相反事实真成立、干扰项在查询点真不成立";**安慰剂:喂错配帧分数须坍塌**(不坍塌=没真看帧)→拒 | 拒+重构 | | **4 活求解器难度探针** | 行为/对抗 | deepseek AgentLoop 对 pair 双向作答;双向都对=太易→拒(对抗前移,AdVQA) | 拒+补构造 | | **5 独立多裁判歧义核验** | 语义 | **多裁判 = kimi(D 文本)+ qwen(B 看帧)+ MiniMax(C 看帧)三异家族**,均独立于求解器(deepseek A);判是否有干扰项也成立/双正解,AdVQA 式一致性(无共识/多数判双真→拒)。text-embedding **不算裁判** | 拒+指纹去重 | | **6 多格式交叉一致性** | 跨格式 | 同一构造事实生成 **MC + Y/N 两格式**,求解器跨格式作答须一致;不一致=格式捷径而非真理解→拒(TempCompass 多格式交叉) | 拒+重构 | > **ABSTAIN 处置明确 + 终态闭环(防旧非对称谬误 + Codex I5)**:任一 VLM 探针"无法给有效帧引用"→记 `ABSTAIN` 入**分层人工抽检队列**,既不自动放行(防"引不出=放过")也不自动过杀。**必须有终态**:人工结论回写 `unit_verdict`(accept/reject);**超 SLA 阈值未标注按 fail 处理**(防无限 pending 吞产量)。 > **难度/歧义两口径正交不复用**:难度=求解器答错(层4);歧义=独立裁判判唯一性(层5)。永不用同一次评分兼两职。 ## 7. 坍缩度量与反自证验收指标 **主验收=配对坍缩**(TempCompass 度量革命):有效性证明不是原始准确率高,而是去捷径后掉回随机的幅度。 > **指标三分类(I3,防 R4 自证误分类)**:**纯结构指标**(逐维众数命中率、答案槽位卡方、pair 关系规则解法、distractor 距离)——不依赖任何模型,是真正的算法地锚;**模型探针指标**(text-only 盲答、单帧基线、帧错配安慰剂、双正解率+κ、多格式一致率)——依赖模型输出的统计判据,**不得当"纯算法"背书**;**人工/抽检指标**(难/烂混淆矩阵)——分层小样本人工双标签。三类须分别标注,验收结论以纯结构 + 人工为硬地锚,模型探针为辅助信号。 | 指标 | 靶向 | 手段(外部/纯算法/独立) | |------|------|------------------------| | 逐维众数命中率 | ②结构捷径 | 纯算法机械投票,阈值≈随机 | | 答案槽位卡方 + pair 槽位反置率 | ②C6 | 纯统计 | | text-only 盲答 / 单帧基线 掉回随机幅度 | 语言先验/单帧 | **模型探针**(deepseek 盲答 + VLM 单帧,非纯算法地锚,见上分类)| | 帧错配安慰剂坍塌幅度 | ①虚假 grounding | 错配帧分数须显著坍塌 | | pair 关系可解率 | ②C2 | P+Q 盲答+时序排序规则,须≈1/16 | | **subtitle_answerability_rate** | ②字幕泄答案 | 仅喂 subtitle+选项盲答,须≈随机 | | **distractor_similarity(多样性)** | GroundAttack 扎堆 | 3 干扰项两两 embedding 距离须过下界 | | **多格式交叉一致率** | 格式捷径 | MC vs Y/N 求解器答案一致率(低=格式捷径) | | 双正解率 + 裁判 κ | ③歧义 | kimi vs qwen/MiniMax(异家族),基线 33%→阈值≤5% | | 难/烂混淆矩阵 | ④/R4 | 分层人工抽检小样本双标签(可选锚点) | | quarantine_rate / backfill_yield_by_round / judge_disagreement_by_subpattern | R5/系统 | 观测落 run_store | 阈值全部进科研 YAML + harness run 快照(可复现、可扫动);kimi/qwen endpoint 属工程 `.env`。 ## 8. QuestionUnit 契约(贯穿采样/分批/聚合,混格题库) `core/types.py` 新增 `QuestionUnit(single|pair)`:pair 载 `pair_id`/`twin_a`/`twin_b`/`flip_axis`/`unit_hash`/`collapse_metric`;`GeneratedQuestion` 加 `unit_id`/`pair_id`/`question_role`/`flip_axis`(默认值保非 AR single 不变)。 > **选项基数契约(锁定,与 §4/§7 对齐)**:每个 `GeneratedQuestion`(含 twin 的 P/Q 子题)**仍是 4 选 MCQ + 字母答案**,AgentLoop/harness 的 MCQ 作答契约**不变**;pair 语义只是"P、Q 共享 bag-of-words 选项集、答案翻转、双向 AND 聚合"。多格式的 Y/N 子题作为**验证探针**(层6)——**独立类型、独立存储表、硬校验其不进 benchmark/pools/predictions、不复用 `GeneratedQuestion`**(M1),仅在构造期核验一致性后即抛弃,不改 MCQ 契约。 **≥13 处改造入口**(复用审计 + 契约审核全表,v2 只覆盖 7 处,遗漏必崩): | 入口 | 文件 | 改造 | |------|------|------| | Global 三池切分 | `pools.py::build_pools`/`_sample_excluding` | 互斥单元 qid→pair_id,pair 同池 | | per-category 切分 | `pools.py::_split_one_category` | 输入改 unit,pair 不跨 train/val | | 分层采样 | `loader.py::stratified_sample` | 按 unit 计数,flatten 前 pair 不拆 | | batching 对错桶 | `batching.py::_select_mixed_by_task_type` | 按 **unit correctness(双向 AND)** 分桶 | | batching 整锁 | `batching.py::build_batches` | pair 像小类整组装箱,**同 batch 不拆**(否则坍缩算不出) | | 聚合 | `inference.py::run_inference` | pair 按 pair_id 收齐→pair-level record 双向 AND;unit 粒度 total/correct | | 序列化冻结/解冻 | `pools.py::_q_to_dict`/`_dict_to_q` + `save_pools.categories` | 显式写读 4 pair 字段 + 以 unit 记 train/val | | gate 阶梯 | `gate_ladder.py::build_cold_entries`/`ladder_for`/`update_probs` | entry 迁 unit_id + **schema_version + 迁移脚本**(存量 gate_pools.json 失效防硬崩) + 冷启动 2:1/gamma-EMA/Beta 先验按 unit 重定义 | | e-process | `core/evolution/validate.py::pair_block` | McNemar 臂配对按 unit(P AND Q 折叠后比对) | | correctness 消费(C3) | `runner.py`(rollout 回写 163-190 / accept 合并 1125-1142 / val 回写 1442-1454 / quadrant 分桶 / probation / momentum 1719-1760)+ `core/evolution/validate.py`(`pair_block` 12-37 / `compute_accuracy` 72-85) | 见下"correctness API 规格"——**逐一列出并改写这 8+ 调用点**,非仅"新增视图" | | **checkpoint/resume(C2,新增)** | `runner.py::epoch_batches`/`_batch_from_ids`(199-210/711-725) | 保存 **unit_id 序列**(非逐题 qid),恢复时展开完整 unit,防断点续跑后拆 pair | | **gate BaselineCache(C2,新增)** | `gate_ladder.py::BaselineCache`(277-335) | 键从 qid 改 unit_id,基线缓存按 unit 记忆,防 P/Q 分开缓存污染双向 AND | | 作弊门 | `adversarial_filter`→v3 难度探针 | pair 粒度判太易,禁半剔 | | 读回 benchmark | `loader.py::load_benchmark` | 补读 4 pair 字段(`.get` 兼容旧 JSON) | | 非 AR rng 隔离(I4) | `loader.py`(86-98/123-131/154-172 的 `rng.sample`)+ `pools.py`(604-612/811-815 的 split/shuffle) | **实现前先枚举所有 `rng.sample/shuffle` 调用点**;非 AR 抽样输入与 RNG 流固定,AR pair 折叠用**独立 seed namespace**,二者 draw 互不干扰 | **correctness API 规格(C3,三对象转换边界,非口号)**:显式定义三个对象及转换—— - **逐题 predictions**(`question_id → prediction`):唯一溯源真相,rollout 逐题写。 - **unit correctness**(`unit_id → bool`):AR pair = P.pred==P.ans **AND** Q.pred==Q.ans;非 AR = 单题。由 predictions 折叠得出,供进化/gate/quadrant/momentum/probation **统一消费**。 - **pair collapse metric**(`pair_id → 坍缩指标`):验收用,不进 correctness。 上表 8+ 调用点**逐一改写为消费 unit correctness**(含 `validate.py::compute_accuracy` 分母改 unit 数、`pair_block` McNemar 臂按 unit 折叠、quadrant 分桶按 unit_id);e-process 的 delta 信号在 unit 粒度计算,防 P/Q 单题计分污染进化。**先写此 API 规格 + 调用点替换清单,再动实现。** ## 9. 帧感知 grounded 事实抽取层(一等公民,支撑全部 6 子模式) **这是让 6 子模式全部进入必达、又不滑回 v2 生成-过滤陷阱的关键机制。核心原则:树只是有损索引,真正的 ground truth 是帧本身——抽取直接喂真实帧,不依赖树的有损自由文本。** 盘上每视频有真实关键帧(5 帧/L2 段,`store/videos//frames/`,L3 `frame_path` 定位);需更密帧时按 video id 重下原视频补采(有界局限,见 §16)。`grounded_fact_extractor`(新建一等公民组件): 1. **帧感知抽取(VLM 对真实帧做感知,非对文本做解读)**:把目标段/时刻的真实帧喂 VLM,直接感知结构化事实——cross_segment 感知 `(主体,动作,段)` 绑定;premature 感知"各段状态读数";semantic_rigidity 感知"视觉真相"再与 `subtitle` 比;fine_grained 感知"动作执行方式"(左右手/快慢/次数);evidence_gap 感知"哪些证据视觉在场"。树的 `event_description`/`entities` 仅作**索引与候选提示**,不作事实来源。 2. **双 VLM 交叉核实 + Fact schema(Codex C6)**:每条感知事实由 **qwen + MiniMax 两异家族 VLM 对同帧交叉核实**,落 **Fact schema**:`fact_id, subject, action, object, segment_id, frame_ids, polarity(真/假), verifier_refs, cross_agree, fact_type, difficulty_tier, negative_at_target`。**只有两 VLM 一致 + 多帧核实通过 + 绑定唯一的 fact 才进构造**;不一致/不唯一→丢弃。 ### 9.1 构造合法性硬约束(Codex 三审 C3/C5/C1/C4,缺一即滑回歧义/伪难题) - **判别性 + `negative_at_target` 排他(C5,最关键)**:干扰项**不是"任何真实事实绑错点"**——错绑定 ≠ 逻辑否定。必须:(a) 只选**判别性事实**(跨查询点/翻转轴会变的,非"表演者在台上"这类跨段持续/复现的事实);(b) 每个干扰项显式 `negative_at_target`——**帧核实它在目标查询点确为假**(闭世界证据或翻转轴互斥证明),不过则**判双正解 hard-fail**。重复场景视频(同一主体贯穿)大量事实非判别,须按此剔除(产量由 §10 降级兜底)。 - **按 fact_type 的最小采样密度(C3)**:凡涉及**顺序/变化/次数/速度**的 fact(cross_segment 先后、premature 状态变化、evidence_gap 在场缺席、fine_grained 方式)——5 帧/段不足以稳定感知 → **触发密帧重采(按 video id 重下补帧)或降级**;不止 fine_grained。§9 为每个 fact_type 定最小密度。 - **fact_type 难度分层(C1)**:粗粒度物体/姿态感知可靠,但**主体-动作绑定/快慢/计数/证据缺席是高阶判断**——这些 fact_type 打高 `difficulty_tier`,走**更严核实**(更多帧 + 人工小样本校准),禁止当普通感知放行。 - **唯一绑定粒度 + 不唯一拆分(C4,防产量崩)**:定义唯一性粒度(同 segment/同 frame/同 action class/同 option set);多主体多动作段不唯一时**给拆分策略**(拆到可唯一的粒度再构造),而非一律丢弃。 - **双 VLM 共享盲区校准(C2)**:两 VLM 一致**只降随机噪声、不排除同向幻觉**;加错配/遮挡/反提示一致性校准 + **人工小样本估 shared-error rate** 落验收面板;一致不当真值背书。 ### 9.2 实证验证状态(小样本 spike,见 [2026-07-15-v3-frame-perception-spike-validation.md]) 5 视频×3 段、94 次 VLM 调用 + Claude 亲自看帧核查,**机制已验证站得住**:可抽取率 100%、判别性 ~83%、negative_at_target 实证有效(正确抓双正解)、双 VLM 一致 87%、粗时序 5 帧可感知、抽样无双 VLM 一致幻觉。据实证细化 5 条(须折进实现): 1. **fact_sampler 加"动作性"前置筛**(样本含幻灯片/录屏非动作视频,抽取虽成功但对 AR 无意义)。 2. **fine_grained 密帧从"运行时兜底"升为"硬前置"**(实证:manner 5 帧确实不够,必须密帧重采或走 B 路线,不等运行时才发现)。 3. **manner 类 fact 不靠双 VLM 交叉核**(实证一致性低)→ 走更严核实(更多帧+人工小样本),对齐 §9.1 C1 难度分层。 4. **抽取主用详细但准确的 VLM(MiniMax 风格),保守 VLM(qwen)作交叉核**。 5. 多主体绑定未被 spike 压测(样本多单主体)→ 见 §16 开放风险。 **为何这不是 v2 陷阱、且比"从树文本抽取"更强**:v2 的失败是"VLM **判分**自由发明的干扰项"(判断题,不可靠);这里是"VLM **感知**真实帧里有什么"(感知/描述题,可靠得多)——干扰项始终是**从真实帧感知到的真实事实绑到错误查询点**,从不自由发明、从不循环打分。wrongness 由构造保证(真事实、错绑定),grounding 由**真实帧感知 + 双 VLM 交叉**保证(短于人工标注下最强)。 **做不了**:bbox/像素坐标/精确计数/说话人 ID——放弃,不硬凑。 **grounding 强度诚实分档**(不抹平):temporal = **结构保证**(树顺序,零模型依赖);其余 5 = **帧感知验证保证**(真实帧 + 双 VLM 交叉 + Fact schema,模型依赖但锚在真实视觉证据,非自由发明)。两档都是合法 grounded,来源不同,须在验收报告分别标注。 ## 10. 对抗前移、产量与续跑 - **难度探针前移**:构造后、落盘前即用 deepseek AgentLoop 试答(对抗前移),不是事后过滤。 - **失败题内容指纹去重**(R5 真正对症):对**题面语义内容**(非 question_id)算指纹,`拒/太易/歧义` 的内容指纹入 quarantine 黑名单;补构造命中黑名单即丢(堵"等价题换皮重试穿门")。 - **收敛上界**:`max_total_constructed`/`max_backfill_per_slot`/`min_pass_yield`;连续 N 轮低产即停并报告。 - **产量降级路径**(解产量危机,三选一写进配置):欠产(如 22/30)作为**带质量标签的正式交付物**;或 min_pass_yield 触发转分层人工抽检;明确**质量优先于数量**,`generate_ar30.sh` 的 TARGET 变软。 ## 11. 模块结构(Clean Architecture 四层) **在现有 `app/question_gen/` 内按领域模块替换/重组**(对齐 CLAUDE.md §4.2"直接改原文件、不留向后兼容"与 §5"禁版本化并行目录"——**不建 `app/question_gen_v3/` 并行目录**)。废弃模块(generator_v2/synthesizer/distractor_selector/gates/pipeline_v2)**原地删除或改写**,新增领域模块同目录落位:`fact_sampler`(采可翻转事实)、`constructor`(子模式→孪生轴路由)、`twin_builder`(孪生构造)、`grounded_fact_extractor`(§9 帧核实事实抽取,喂 cross_segment/premature/semantic_rigidity/fine_grained/evidence_gap)、`difficulty_prober`(活求解器,**不兼答案裁判**)、`ambiguity_verifier`(kimi 独立多裁判)、`collapse_metric`(结构/探针/人工三类验收,见 §7)、`pipeline`(主编排,替换 pipeline_v2);`run_store` 原地扩 pair 感知(不新建 run_store_v3)。 **复用地基**:`adapters/*` 全部(GovernedLLMClient/VLM/telemetry/熔断/缓存)、`core/protocols`(扩 `JudgePanelProvider`)、`core/types`(扩 QuestionUnit)、`app/harness/*`(pair 契约适配,见 §8)、`run_store.py`/`loader.py`(续跑/加载基建)。 **废弃**:`generator_v2`/`synthesizer`/`distractor_selector`/`gates`/`pipeline_v2` 主编排 + 对应 prompts/config。**拆解复用**:`adversarial_filter` 的孪生翻转构造 + 活求解器探针 + verdicts 续跑(去后置过滤外壳,提升为构造/核验主路径)。**借鉴语义**:`strategy_action_recognition` 的 6 skill 靶点 + flip_axis 标注。 ## 12. 非功能性需求(重写必须继承,防隐式丢失) | 维度 | 设计 | |------|------| | **持久化** | 逐 **unit** 原子成对落盘:pair 在内存 pending buffer 收齐 P+Q 后一次性进 accepted;全量 tmp + `os.replace`,**pair 同落或都不落**,崩溃不留半对 | | **幂等性** | 同 seed→同构造;孪生由 flip_axis 确定性构造;VLM 非确定为既有属性;`unit_hash` 检测续跑失效 | | **断点续跑** | progress(slot→status);pair 以"整对完成"为 accepted 单位;verdicts 表按 (question_id/hash/config 指纹) 三元组续跑;config 指纹失效作废脏续跑 | | **原子性** | 逐 unit 落盘;读回校验 pair 成对完整、剔孤儿;补构造续跑三件套(seq_offset/used_node_ids/embed_pool) | | **治理/遥测** | 所有 LLM/VLM 经 GovernedLLMClient 五层栈;session_id 透传每次调用必录 telemetry | | **并发/降级** | asyncio.Semaphore 限流;JSON 解析失败区分"契约违反 raise"vs"可降级 warning",不静默 | ### 12.1 日志与可观测方案(须走 structured-logging skill) v3 产生大量运行时数据。设计阶段先给出**表结构骨架**(对齐 CLAUDE.md §3 Phase 1.4"设计阶段强制项",细节仍由 `structured-logging` skill 在 writing-plans 前定稿 + Wiki schema 注册): | 表 | 关键列 | |----|--------| | `unit_verdict` | unit_id, pair_id, sub_pattern, stage(层1-6), verdict(pass/fail), reason, metric_value, model, session_id | | `collapse_metrics` | pair_id, text_only_acc, single_frame_acc, placebo_drop, majority_vote_hit, slot_chi2, distractor_min_dist, multiformat_consistency | | `quarantine` | content_fingerprint, sub_pattern, quarantine_reason, round_no, ts | | `resume_state` | slot_id/unit_id, status, config_fingerprint(断点恢复+失效检测), seq_offset | | telemetry | 每次 LLM/VLM 调用(GovernedLLMClient 自动录,session_id 透传) | 基线指标(各门通过率、backfill_yield_by_round、judge_disagreement_by_subpattern)定义与阈值进科研 YAML + run 快照。 ## 13. 错误处理 孪生构造失败(找不到真实相反事实)→该 slot 重构或走产量降级;VLM/裁判异常→slot 级隔离宽异常重出不崩整批;kimi/NLI 裁判不可用→明确报错不静默跳过(防漏歧义);安慰剂/坍缩门模型不可用→报错。 ## 14. 测试策略 - 单元:6 子模式孪生构造分流;bag-of-words 硬匹配校验;禁蕴含 NLI;逐维众数纯算法门;坍缩度量;pair 原子写/半写检测;双向 AND。 - 集成:AR 端到端(mock 四家族)→ pair 成对落盘、**六层验证全部生效(含层6 MC vs Y/N 多格式交叉的 mock 与失败路径)**、坍缩验收。 - 回归(pair 不拆):`stratified_sample`/`build_batches`/`run_inference`/`pools.build_pools` 四处 pair 同进同出、同批、配对聚合、孤儿剔除;gate_ladder 迁移续跑不崩。 - 回归(非 AR byte-identical):11 非 AR generate-v2 字节级不变,含 rng 隔离验证。 - Agent 类测试产出 MD(CLAUDE.md §4.6)。 ## 15. 分期实现(一个设计,writing-plans 分阶段) 1. **契约地基**:QuestionUnit + ≥13 入口最小 pair 支持 + gate_ladder schema_version 迁移 + 非 AR rng 隔离 + pair 原子落盘。 2. **帧感知事实抽取层(§9)+ 构造器 + fact_sampler**。**v3 必达 = 全部 6 子模式**(用户决策:接受帧感知抽取风险): - **temporal** grounding=树结构保证(零模型);**其余 5**(cross_segment/premature/semantic_rigidity/fine_grained/evidence_gap)grounding=**§9 帧感知验证保证**(喂真实帧 + 双 VLM 交叉核 + Fact schema,见 §9); - 六者共用 bag-of-words/禁蕴含/单轴/逐维众数平衡纯算法门 + 六层验证 + §9 题干模板对称 hard-fail(C8)。**帧感知抽取层是本阶段核心交付。** - **运行时合法性门兜底**:fine_grained(需两个真实对比时刻,可能超 5 帧/段密度→重下密帧)、evidence_gap(幻觉风险最高)各挂运行时门(帧核实+坍缩+小样本人工抽检),门不过该 pair 走 fallback(fine_grained 退 finding B 路线、evidence_gap 退保守构造)——**兜底是质量安全网,不是把子模式踢出必达**。 3. **六层验证栈**:坍缩度量(含 subtitle 输入)+ 看帧核实 + 帧错配安慰剂 + 难度探针(deepseek AgentLoop)+ kimi 独立歧义多裁判 + **多格式交叉一致(MC+Y/N)**。 4. **对抗前移 + 产量**:失败指纹去重 + quarantine + 收敛上界 + 产量降级路径 + 补构造迭代。 5. **验收面板 + 混格全链路**:反自证指标面板 + AR pair/非 AR single 端到端评分正确性验收。 > 质量闸门前移:§7 纯算法指标(逐维众数/坍缩/槽位卡方)在阶段 2 即作 CI hard-fail;难度探针在阶段 3 出早期难度信号——不等阶段 5 才验质量(对治上一版盲飞根因)。 ## 16. 风险与回退 | 风险 | 回退 | |------|------| | kimi 网关不可用 | 实现第一步验证;退回 qwen+MiniMax 异家族双看帧裁判并标注局限 | | **帧感知抽取风险(按 fact_type 的 failure taxonomy,C6)** | 逐类列失败路径 + 失败率进验收面板:稀疏帧漏检(顺序/变化/次数/速度类)→密帧重采/降级;双 VLM 共享盲区→错配/遮挡校准+人工 shared-error 抽样;**负事实不可证/双正解**→`negative_at_target` hard-fail(§9.1);事实过宽跨段复用→判别性筛;ABSTAIN 吞吐→SLA 终态(§6)| | **重复场景视频(同主体贯穿)大量事实非判别** | §9.1 判别性筛 + `negative_at_target` 剔双正解;产量由 §10 降级兜底(宁少勿歧义)。**spike 实证:连 GsYi 重复场景判别性仍 ~83%,双正解剔除率 ~17% 可控** | | **多主体繁忙场景的唯一绑定(Codex C4,spike 未压测)** | 样本多单主体,唯一绑定风险未验证 → writing-plans/实现早期补一次多主体段实测;不唯一时按 §9.1 拆分粒度处理 | | **fine_grained 产量/合法性**("两时刻不同方式"未必总能找到、未必构成合法单轴编辑) | 运行时合法性门(帧核实+坍缩+人工抽检);不过退 finding B 路线(生成候选+独立 wrongness 帧核验);产量降级兜底 | | **evidence_gap 虚构因果幻觉**(幻觉风险最高) | 运行时合法性门 + 保守构造 fallback;"不可确定"选项正/反题对称(防 C3 文本靶)| | **semantic_rigidity(必达静态类)** | 编辑轴=视觉真相 vs 字幕字面(非名词替换,避 VITATECS 静态退化);视觉真相由帧核实确证 | | fine_grained/静态类产量低(找不到真实对比时刻) | 产量降级路径;必要时该子模式先缓 | | 属性抽取层不准 | 抽取后 VLM 看帧复核;不准即弃该题 | | gate_ladder 迁移破坏冷启动算法保真 | schema_version + 迁移脚本 + 2:1/gamma-EMA/Beta 按 unit 重定义并写入保真清单 | | 混格题库拖累训练 | 阶段 5 先验评分正确性;必要时 AR pair 与非 AR 分池 | ## 17. 核心算法保真 v3 触及算法保真清单(`ARCHITECTURE.md §6`)第 5 项(信息阶梯冷启动 2:1/gamma-EMA/反泄漏)——因 gate_ladder 迁 unit_id,须逐条比对按 unit 重定义、不简化,并在 commit 标注。其余 11 项不涉及。 > **gate-unit 迁移 ADR(C4,阶段 1 强制交付,不得占位进实现)**:以下每项须有**可测试**的明确定义——① unit 的冷启动"对/错"如何从 P/Q 得出(建议 unit 错=P 或 Q 任一错);② 2:1 错优先交错在 unit 上如何保持;③ unit `p_hat` 初值(Beta 先验参数);④ gamma-EMA 观测来源(predictions 折叠成 unit 观测再更新,防 `update_probs` 按 qid 匹配失效致 EMA 停摆);⑤ probe_quota 按 unit 还是按题抽;⑥ 存量 `gate_pools.json`(无 schema_version、qid 键)的处理:加 `schema_version` + 拒绝或一次性迁移脚本;⑦ 反泄漏(run_id 含 `_gate_` 过滤)不受影响的确认。 ## 相关 - 范式依据:[2026-07-15-question-gen-paradigm-shift-construction-over-filtering.md] - 前序审核:[2026-07-15-question-gen-v2-adversarial-audit.md] - 被取代:[2026-07-15-question-gen-v2-grounded-contrastive-design.md] - 论文:`reference/papers-distractor-gen/`(6 篇深读)