docs(wiki): add three-round analysis findings and Spec-1/2/3 designs
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
# Spec-1:Agent 执行环境修复(解析容错 + 步级重试 + 摘要附实体)
|
||||
|
||||
- **日期**: 2026-07-11
|
||||
- **状态**: 已批准(用户确认,步级重试退避改为 20s/40s)
|
||||
- **依据**: `research-wiki/findings/2026-07-11-benchmark-failure-taxonomy.md` §四(T8,5 题)与 §二 M1(view_node 摘要吞 entities)
|
||||
- **系列**: Spec-1/2/3 三件套之一,见 [2026-07-11-batch-tree-build-design.md]、[2026-07-11-question-gen-v2-design.md]
|
||||
|
||||
## 1. 问题
|
||||
|
||||
| # | 缺陷 | 证据 | 影响 |
|
||||
|---|------|------|------|
|
||||
| A1 | `_parse_response`(`core/agent/loop.py:265-300`)只接受 `action.args` 嵌套结构;deepseek 稳定输出变体(args 平铺 + ```json 围栏)解析三连拒 → 0 步阵亡 | 637-3、615-3 | 整题报废,且 json_repair 修不了结构错位 |
|
||||
| A2 | LLM 调用异常(`loop.py:118-129`)直接整题终止,无步级重试 | 796-3(SSL BAD_RECORD_MAC 废掉 13 步上下文) | 一次网络抖动损失全部已积累推理 |
|
||||
| B | `summarize_node`(`app/search/summarizer.py`)两轮按题摘要后 entities/visible_text 不保证幸存 | 786-2、872-3、750-1(Agent 站在证据节点上漏读实体) | M1 负证据幻觉的恶化因素 |
|
||||
|
||||
## 2. 设计
|
||||
|
||||
### A1 解析容错(结构归一化层)
|
||||
|
||||
在现有 `repair_json → json.loads → 校验` 之后、返回 None 之前,增加确定性归一化:
|
||||
|
||||
1. **围栏剥除**:repair_json 前先剥 ```json / ``` 围栏(正则,幂等)。
|
||||
2. **args 收拢**:若 `action` 为 dict 且含 `tool` 但缺 `args`,把 action 下除 `tool` 外的所有平铺键收拢为 `args` 嵌套。
|
||||
3. 归一化成功 → 照常执行;失败 → 走现有 retry 追问路径(行为不变)。
|
||||
|
||||
纯函数实现,用 637-3/615-3 的真实坏输出作单测样本。
|
||||
|
||||
### A2 步级重试
|
||||
|
||||
`_call_llm` 异常处理改为步级重试循环:
|
||||
|
||||
| 参数 | 值 | 说明 |
|
||||
|------|-----|------|
|
||||
| 重试次数 | 2 | 第 3 次失败才整题终止(stop_reason=error 不变) |
|
||||
| 退避 | 20s / 40s | 用户指定 |
|
||||
| 异常范围 | 全部 Exception | 这一层防的是穿透 GovernedLLMClient 内部重试栈的异常(SSL 等),统一兜底不分型 |
|
||||
| 上下文 | 原样保留 | messages 不回滚,重试即重发 |
|
||||
| 遥测 | 中间失败记入 error 字段 | 保持调用链可追溯 |
|
||||
|
||||
### B 摘要附带实体原文
|
||||
|
||||
`summarize_node` 输出末尾由**确定性代码**(非 LLM)追加节点 card 的字段原文:
|
||||
|
||||
```
|
||||
[实体] <entities + visible_entities 原文>
|
||||
[画面文字] <visible_text 原文>
|
||||
```
|
||||
|
||||
- 摘要后追加 → LLM 无法吞掉;字段为空则不加对应区块
|
||||
- 对 anchor / 非 anchor 两种模式一致生效
|
||||
|
||||
## 3. 不做什么(YAGNI)
|
||||
|
||||
- 不改 GovernedLLMClient 的内部重试栈(已有四层治理)
|
||||
- 不改判分协议、不动 prompt 版本化内容
|
||||
- 不做异常分型重试策略(统一兜底已覆盖已知案例)
|
||||
|
||||
## 4. 验证
|
||||
|
||||
1. 单测:坏输出样本(围栏/平铺/两者叠加)归一化正确;空 content、缺 tool 仍拒
|
||||
2. 单测:步级重试计数与退避(mock LLM 抛错)
|
||||
3. 单测:summarize_node 追加区块(有/无实体字段两种节点)
|
||||
4. 集成:抽 10 道 T2/T8 错题重跑(637-3、615-3、786-2、872-3、750-1 必含),对比修复前后
|
||||
5. `make test` 全绿 + 覆盖率不降
|
||||
|
||||
## 5. 被否方案
|
||||
|
||||
- **prompt 层要求 LLM 修正输出格式**:治标,deepseek 变体是稳定行为,代码归一化是确定性修复
|
||||
- **重试时区分异常类型**(仅网络类重试):已知案例全是穿透型异常,分型收益低且易漏
|
||||
@@ -0,0 +1,83 @@
|
||||
# Spec-2:建树批量并行入口
|
||||
|
||||
- **日期**: 2026-07-11
|
||||
- **状态**: 已批准(用户确认两层参数推荐方案)
|
||||
- **系列**: Spec-1/2/3 三件套之一,见 [2026-07-11-agent-runtime-fixes-design.md]、[2026-07-11-question-gen-v2-design.md]
|
||||
|
||||
## 1. 问题
|
||||
|
||||
TRM5 只有单视频建树(`app/tree/video_builder.py`,内部 Semaphore(16) 限 VLM/LLM 调用)与修复/迁移工具,**没有多视频批量构建入口**——批量建树只能视频间串行,非 API 阶段(ffmpeg 帧提取、图像编码、IO)与 API 阶段无法跨视频重叠,太慢。
|
||||
|
||||
## 2. 并发语义调研结论(项目惯例)
|
||||
|
||||
| 位置 | 并行单元 | 惯例 |
|
||||
|------|---------|------|
|
||||
| `app/harness/inference.py` | 题目 | 一个 `asyncio.Semaphore` + `gather`,任务级 |
|
||||
| `tools/repair_trees.py` | 视频 | 视频级 Semaphore + gather + progress.json + 熔断阈值随并发缩放 |
|
||||
| `app/tree/video_builder.py` | API 调用 | Semaphore 作为参数在协程链中显式传递 |
|
||||
|
||||
建树是唯一任务内部本身有大并发的场景 → **视频级与 API 级信号量必须分开**,否则 16×16=256 API 并发打爆端点与熔断器。
|
||||
|
||||
## 3. 设计
|
||||
|
||||
### 入口形态(遵循项目结构规范)
|
||||
|
||||
- `tools/build_trees.py`:独立工具(不被其他模块 import),复刻 `repair_trees.py` 的编排模式
|
||||
- `scripts/build_trees.sh`:自包含实验记录,写死参数、零参数复现(GPU 卡号除外)
|
||||
|
||||
### 两层并发参数
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
subgraph tools/build_trees.py
|
||||
V[视频级 Semaphore<br/>video_concurrency=16] --> B1[VideoTreeBuilder 视频A]
|
||||
V --> B2[VideoTreeBuilder 视频B]
|
||||
V --> B3[...]
|
||||
end
|
||||
B1 --> API[全局共享 Semaphore<br/>api_concurrency=16]
|
||||
B2 --> API
|
||||
B3 --> API
|
||||
API --> E[VLM/LLM 端点]
|
||||
```
|
||||
|
||||
| 参数 | 默认 | 语义 |
|
||||
|------|------|------|
|
||||
| `--video-concurrency` | 16 | 同时在建的视频数;吞吐提升来自非 API 阶段跨视频重叠 |
|
||||
| `--api-concurrency` | 16 | 全局在途 VLM/LLM 调用上限,跨所有视频共享**一个** Semaphore 实例——端点压力与今天单视频建树完全一致 |
|
||||
|
||||
熔断阈值按 repair_trees 惯例缩放:`max(cfg_threshold, api_concurrency * 2)`。
|
||||
|
||||
### builder 改动(唯一的存量修改)
|
||||
|
||||
`VideoTreeBuilder` 的内部 Semaphore 改为**可注入参数**(构造器可选传入外部 Semaphore;不传则自建,单视频调用行为零变化)。builder 内部协程链本就显式传递 Semaphore,改动面极小。
|
||||
|
||||
### 断点续跑
|
||||
|
||||
- 视频级:`progress.json`(复用 repair_trees 的 `save_progress` 模式);tree.json 存在且完整性校验通过的视频自动跳过
|
||||
- 视频内:现有段级恢复(核心算法 #3)不动
|
||||
|
||||
### 输入输出
|
||||
|
||||
- 输入:`--videos-dir`(视频文件 + 可选同名 SRT)
|
||||
- 输出:`store/videos/<video_id>/tree.json`;帧持久化沿用现有 cache 机制
|
||||
|
||||
## 4. 风险与观测
|
||||
|
||||
- 16 路并行 ffmpeg/cv2 解码可能压满 CPU/磁盘 → 实现时输出速率日志(视频/分钟,复刻 repair_trees),观测后再调 video_concurrency
|
||||
- 日志遵循"禁止缓存、立即输出"(CLAUDE.md §2.1)
|
||||
|
||||
## 5. 不做什么(YAGNI)
|
||||
|
||||
- 不做分布式/多机;不做动态并发自适应
|
||||
- 不改单视频建树算法(核心算法 #1/#2/#3 保真,仅信号量注入)
|
||||
|
||||
## 6. 验证
|
||||
|
||||
1. 单测:Semaphore 注入后单视频行为不变(默认自建路径)
|
||||
2. 集成:3-4 个短视频小批量构建,验证跨视频并行、progress 跳过、全局 API 信号量生效(遥测里在途调用数 ≤ api_concurrency)
|
||||
3. 中断-恢复测试:构建中 Ctrl+C 后重跑,已完成视频跳过、未完成视频从段级断点续跑
|
||||
|
||||
## 7. 被否方案
|
||||
|
||||
- **单一视频级 Semaphore(repair_trees 原样照搬)**:建树内部并发大,总 API 并发 = 视频数 × 内部并发,不可控
|
||||
- **仅共享全局 API Semaphore、视频数不限**:任意多视频同时提帧会压垮磁盘 IO/CPU
|
||||
@@ -0,0 +1,112 @@
|
||||
# Spec-3:出题管线 v2(失败机理靶向 + 逐题质量门)
|
||||
|
||||
- **日期**: 2026-07-11
|
||||
- **状态**: 已批准(用户确认:双标签体系、轻量档全量 + 重量档 15% 抽检)
|
||||
- **依据**: 三轮分析——`findings/2026-07-11-question-gen-calibration-analysis.md`(生成题缺陷与根因)、`findings/2026-07-11-benchmark-failure-taxonomy.md`(242 错题机理分类与 11 种题型规格)
|
||||
- **系列**: Spec-1/2/3 三件套之一;Spec-1 修好的推理环境是本 spec 重量抽检的前置
|
||||
|
||||
## 1. 目标重定义
|
||||
|
||||
出题目标从"难度与 benchmark 一致"改为:**覆盖已证实的失败机理(M1-M5)+ 逐题质量门**。
|
||||
|
||||
| 决策 | 内容 |
|
||||
|------|------|
|
||||
| calibrate 降级 | 仅作观测性报表,不再是验收门 |
|
||||
| 评分协议不变 | 标准四选一按字母判分;harness/推理侧零改动。题型规格中"附证据节点 id"等要求降级为**构造时验证材料**,存题目元数据供 diagnose 分析 |
|
||||
| 双标签体系 | 主标签 `task_type`(Video-MME 12 类,进化循环 mini-batch/gate/skills/diagnose 零改动)+ 附加字段 `skill_target`(M1-M5/题族,仅用于出题配比、质检、覆盖率统计) |
|
||||
| 质检两档 | 轻量四门全量逐题;重量档(盲 Agent 全树试答)15% 抽检 + 难度标签 |
|
||||
|
||||
## 2. 流水线架构
|
||||
|
||||
重构 `app/question_gen/synthesizer.py` + `tools/generate_questions.py` generate 子命令:
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
S[采样器<br/>按题族选素材] --> G[生成器<br/>题族 prompt 模板<br/>双标签输出]
|
||||
G --> P[确定性后处理<br/>shuffle+答案重映射<br/>指代黑名单<br/>verbatim 检测]
|
||||
P --> Q{轻量四门 全量}
|
||||
Q -->|拒| R[带拒因重出<br/>同 slot 最多 3 次]
|
||||
R --> G
|
||||
Q -->|过| H[重量抽检 15%<br/>盲 Agent 试答→difficulty_steps]
|
||||
H --> W[入库 generated-v2]
|
||||
```
|
||||
|
||||
### 2.1 五题族(11 种题型的落地归并)
|
||||
|
||||
每族一个采样器 + 一个 prompt 模板,题型(shape)作为模板参数:
|
||||
|
||||
| 题族 | 覆盖题型 | 采样约束 | 治什么 | 默认配比 |
|
||||
|------|---------|---------|--------|---------|
|
||||
| 检索族 | 证据埋深/反"不存在"、ASR 实体对齐、属性辨析 | 证据取自 entities/visible_entities/visible_text/长字幕单句;配镜像题(真不存在) | M1 负证据幻觉(最大杠杆) | 30% |
|
||||
| 推理族 | 转述还原、NOTA 校准对 | 从字幕单句做一步语义变换(蕴含/虚拟语气/序数映射);NOTA 成对生成(半正解半陷阱) | M2 字面匹配 | 25% |
|
||||
| 枚举族 | 多实例锚定、序数枚举、覆盖率权重 | **source_nodes ≥ 3 跨 L1**;同类事件 ≥2 次;首个表面匹配必须是错的 | M3 锚定/盘点 | 20% |
|
||||
| 视觉族 | 状态演化多帧、实例消歧数字 | 证据仅在帧内、不在任何 card 文本;多时刻真实读数做干扰项 | M4 视觉验证 | 15% |
|
||||
| 空间族 | 参照系空间 | spatial_layout 字段 + 时间锚;摄像机/被摄者双参照系 | T5 空间 | 10% |
|
||||
|
||||
### 2.2 确定性后处理(零 LLM 成本,通用硬约束)
|
||||
|
||||
1. **选项 shuffle** + 答案字母重映射(修复 v1 答案 57% 在 A 的偏斜)
|
||||
2. **指代黑名单**(正则):禁 this segment / this frame / this clip / the current frame / the scene / frame summary 等;题干必须含 L1 time_range 时间锚("between 10:52 and 21:44"式)或全局限定语("in the entire video")
|
||||
3. **verbatim 检测**:题干+正确项 vs 源节点文本的 n-gram 重合门(检索族豁免正确项检测——其证据本来就在文本,见 2.3)
|
||||
4. **出题禁区**:不出 T1 类素材题(瞬时动作/记分牌时序/无对白因果);不复刻 T7 噪声模式(选项重复、口径含糊的计数边界)
|
||||
|
||||
### 2.3 轻量四门(全量逐题,约 4 次单轮 LLM 调用/题)
|
||||
|
||||
| 门 | 判定 | 杀什么 |
|
||||
|----|------|--------|
|
||||
| 键验证 | 拿出题依据(source_nodes 原文)判标注答案是否成立 | 标注幻觉(v1 CP 组 2 例无出处) |
|
||||
| 盲答测试 | 不给任何视频信息裸答,答对即拒 | 常识可解题、干扰项秒排题 |
|
||||
| 多真测试 | 拿全树素材判是否 >1 选项可为真 | 歧义多解题(v1 SR 组 5/8) |
|
||||
| 泄漏测试 | **按题族条件化**(见下) | 一跳检索捷径 |
|
||||
|
||||
**泄漏门的题族捷径画像**("信息不对称化"的落地):
|
||||
|
||||
| 题族 | 捷径画像(该捷径必须失败才放行) |
|
||||
|------|--------------------------------|
|
||||
| 检索族 | top-5 语义搜索片段裸答必须失败(全树 card 文本裸答**允许**成功——考的是检索深度) |
|
||||
| 视觉族 | 全树 card 文本裸答必须失败(逼 observe_frame) |
|
||||
| 推理/枚举/空间族 | 锚点节点文本裸答必须失败(需变换/跨节点) |
|
||||
|
||||
### 2.4 重出循环与重量抽检
|
||||
|
||||
- 拒题 → 拒因回填到生成 prompt → 同 slot 重出,最多 3 次;3 次仍拒则该 slot 换素材重采样
|
||||
- 通过四门的题按 15% 抽样跑盲 Agent 全树试答(复用 Spec-1 修复后的推理管线):验证真实可答性,产出 `difficulty_steps` 难度标签
|
||||
|
||||
## 3. 数据与版本
|
||||
|
||||
| 项 | 决策 |
|
||||
|----|------|
|
||||
| 旧 240 题 | 原地保留 `store/questions/generated/`(infer_gen240 run 引用它,保可复现) |
|
||||
| 新题集 | `store/questions/generated-v2/`,workspace 以 `--questions generated-v2` 指向 |
|
||||
| 题目元数据新增 | `skill_target`、`source_nodes`(已有)、`gate_report`(四门判定)、`difficulty_steps`(抽检题) |
|
||||
| 规模 | 默认 240 题;**task_type 均匀(20/类)为硬约束**(进化循环分层需要),**族配比为软目标(±5%)**——采样器按"族 × task_type 兼容矩阵"(如枚举族→Counting/Temporal 类)分配每题的双标签;YAML 可扫 |
|
||||
|
||||
## 4. 配置归属(D7 规则)
|
||||
|
||||
- **科研配置**(per-experiment YAML):族配比、门阈值(n-gram 窗口、多真判定温度)、抽检率、重出上限、规模
|
||||
- **工程配置**(`.env`):LLM/VLM 端点、超时、熔断——沿用现有
|
||||
|
||||
## 5. 运行时数据
|
||||
|
||||
每题的门判定记录(哪门拒、拒因文本、重出轮次、最终状态)落 SQLite。表结构在设计批准后走 `structured-logging` skill 单独设计(本 spec 只约定:记录必须逐题可追溯、可聚合出各门拦截率报表)。
|
||||
|
||||
## 6. 不做什么(YAGNI)
|
||||
|
||||
- 不改判分协议、不改 harness/推理侧、不改 mini-batch/gate/diagnose 的 task_type 分组
|
||||
- 不做对抗式加难迭代(留到自进化循环跑通后,须固定出题对手版本)
|
||||
- 不做 T1 树增强(用户已确认本次不做)
|
||||
- 不引入树外信息源(原始视频重新抽帧出题)——视觉族用现有帧缓存即可
|
||||
|
||||
## 7. 验证
|
||||
|
||||
1. Smoke:12 个视频 × 每族 2-3 题,验证四门拦截率、重出收敛(≤3 轮)、双标签与元数据完整性
|
||||
2. 全量:生成 240 题 → `bash scripts/infer_generated.sh`(指向 generated-v2)→ calibrate 报表观测
|
||||
3. 回归断言:新题集答案位置分布均匀(卡方检验);指代黑名单零命中;泄漏门画像全部通过
|
||||
4. 单测:后处理层纯函数(shuffle 重映射、黑名单、n-gram 门)
|
||||
|
||||
## 8. 被否方案
|
||||
|
||||
- **纯 prompt 补丁**:第二轮设计层分析证明 7 类缺陷中 5 类会换形复发(信息闭环是结构问题)
|
||||
- **失败机理作为主标签**:进化循环全链改造,收益不明确;先以元数据形式观察其价值
|
||||
- **重量档全量**:240 题 ≈ 一次完整推理实验(4-5 小时),轻量四门已拦截三轮发现的全部缺陷类型
|
||||
- **难度一致性作为验收门**:三轮分析证明分数一致性是坏代理指标(假难/假易双向失真)
|
||||
@@ -0,0 +1,14 @@
|
||||
---
|
||||
type: design
|
||||
node_id: design:agent-runtime-fixes
|
||||
title: "Spec-1 Agent 执行环境修复(解析容错+步级重试+摘要附实体)"
|
||||
date: 2026-07-11
|
||||
---
|
||||
|
||||
# Spec-1 Agent 执行环境修复(解析容错+步级重试+摘要附实体)
|
||||
|
||||
**完整设计**: [2026-07-11-agent-runtime-fixes-design.md](2026-07-11-agent-runtime-fixes-design.md)
|
||||
|
||||
- **选定方案**: 解析层结构归一化(围栏剥除+args 收拢)+ 步级重试(2 次,20s/40s 退避,全异常兜底)+ summarize_node 确定性追加实体原文区块
|
||||
- **依据**: benchmark 错题 T8 5 例(0 步阵亡/网络抖动废题)+ M1 恶化因素(摘要吞实体)
|
||||
- **被否方案**: prompt 层修格式(治标);异常分型重试(收益低易漏)
|
||||
@@ -0,0 +1,13 @@
|
||||
---
|
||||
type: design
|
||||
node_id: design:batch-tree-build
|
||||
title: "Spec-2 建树批量并行入口"
|
||||
date: 2026-07-11
|
||||
---
|
||||
|
||||
# Spec-2 建树批量并行入口
|
||||
|
||||
**完整设计**: [2026-07-11-batch-tree-build-design.md](2026-07-11-batch-tree-build-design.md)
|
||||
|
||||
- **选定方案**: tools/build_trees.py + scripts/build_trees.sh;两层并发参数(video_concurrency=16 视频级 + api_concurrency=16 全局共享 Semaphore 注入 builder);repair_trees 惯例的 progress.json 断点续跑与熔断阈值缩放
|
||||
- **被否方案**: 单一视频级信号量(API 并发不可控 16×16);仅全局 API 信号量(磁盘 IO 无界)
|
||||
@@ -0,0 +1,14 @@
|
||||
---
|
||||
type: design
|
||||
node_id: design:question-gen-v2
|
||||
title: "Spec-3 出题管线 v2(失败机理靶向+逐题质量门)"
|
||||
date: 2026-07-11
|
||||
---
|
||||
|
||||
# Spec-3 出题管线 v2(失败机理靶向+逐题质量门)
|
||||
|
||||
**完整设计**: [2026-07-11-question-gen-v2-design.md](2026-07-11-question-gen-v2-design.md)
|
||||
|
||||
- **选定方案**: 失败机理靶向(5 题族/11 题型,族配比软目标)+ 确定性后处理 + 轻量四门全量(键验证/盲答/多真/按族泄漏画像)+ 重量档 15% 抽检;双标签(task_type 主键 + skill_target 元数据);新题集 generated-v2
|
||||
- **依据**: 三轮分析(生成题缺陷两轮 + benchmark 242 错题机理分类)
|
||||
- **被否方案**: 纯 prompt 补丁(5/7 缺陷类换形复发);机理作主标签(进化循环全链改造);重量档全量(成本≈一次完整推理实验);难度一致性验收(坏代理指标)
|
||||
Reference in New Issue
Block a user