Files
Video-Tree-TRM5/research-wiki/ARCHITECTURE.md
T
2026-07-06 11:23:25 -04:00

17 KiB
Raw Blame History

Video-Tree-TRM5 架构设计

版本 v1 · 状态 提案 · 读者 工程团队

本文分两部分。Part 1「架构」与具体技术栈无关,只描述边界、依赖方向、接缝与核心算法——它是长期承诺,预期能跨越多次技术选型而不变。Part 2「韧性与运维」描述 LLM 调用治理与可观测规范——它随实现演进,但当前约束所有实现必须满足。


§1 核心定位

项目目标:在层次化视频树上构建可自我进化的搜索 Agent + 可训练的递归检索器,实现长视频理解。目标会议 EMNLP 2026。

系统类比——自进化循环对标 PyTorch 训练:

PyTorch 本项目 代码位置
DataLoader 出题 question_gen app/question_gen/generator.py
model.forward() 推理 inference app/harness/inference.py + core/agent/loop.py
loss.backward() 诊断 diagnose core/evolution/diagnose.py
optimizer.step() 进化 evolve core/evolution/evolve.py
nn.Parameter Skills + Prompts(版本化) store/skills/, store/prompts/
training loop 外层循环 runner app/harness/runner.py
checkpoint Store 版本快照 app/harness/workspace.py

只有 inference 是 agent-controlledLLM 自主调工具),其余三步是 code-controlled workflow。

三大模块

模块 目录 一句话定义
建树 app/tree/ 离线预处理——VLM 生成三层 TreeIndex(L1段落→L2片段→L3帧),支持字幕注入和后增强
训练 app/harness/ + core/ 自进化循环(推理→诊断→进化)+ RecursiveRetriever 参数训练
新题构建 app/question_gen/ 生成 Video-MME 风格训练题,原始 benchmark 作 held-out 泛化评测

§2 分层架构(Clean Architecture

2.1 四层依赖规则

flowchart TB
    subgraph 外部实现层
        AD_LLM["adapters/llm.py\nGovernedLLMClient"]
        AD_VLM["adapters/vlm.py"]
        AD_EMB["adapters/embedding.py"]
        AD_CACHE["adapters/redis_cache.py"]
        AD_TEL["adapters/telemetry.py"]
        AD_OCR["adapters/ocr.py"]
        AD_ASR["adapters/asr.py"]
    end

    subgraph 应用层
        TREE["app/tree/\n建树模块"]
        HARNESS["app/harness/\n训练循环"]
        QGEN["app/question_gen/\n新题构建"]
        SEARCH["app/search/\nAgent 装配"]
        RET["app/retriever/\n可训练检索器"]
        PORTS["app/ports.py"]
    end

    subgraph 可提取内核
        AGENT["core/agent/\nAgentLoop 引擎"]
        EVO["core/evolution/\n诊断+进化引擎"]
        CPROTO["core/*/protocols.py"]
    end

    AD_LLM & AD_VLM & AD_EMB & AD_CACHE & AD_TEL -->|实现| CPROTO & PORTS
    HARNESS --> AGENT & EVO
    SEARCH --> AGENT
    TREE & RET & QGEN --> PORTS
    AGENT & EVO -->|定义| CPROTO

依赖只能向内,源码 import 方向严格单向。内层不认识外层:core/ 不知道自己被哪个 app/ 模块组合,app/ 不知道 Protocol 背后是哪个 adapter。判据:任意一个 core/ 模块,搬到没有 adapters 的环境里,用假实现替换 Protocol 即可原样运行

2.2 模块交互全景

flowchart TD
    CLI["main.py CLI"] --> RUNNER["app/harness/runner.py\n训练循环编排"]
    CLI --> BUILD["app/tree/video_builder.py\n建树"]
    CLI --> QGEN["app/question_gen/generator.py\n新题构建"]
    CLI --> TRAIN_RET["app/retriever/train.py\n检索器训练"]

    RUNNER --> INF["app/harness/inference.py\n推理 step"]
    RUNNER --> DIAG["core/evolution/diagnose.py\n诊断"]
    RUNNER --> EVOL["core/evolution/evolve.py\n进化"]
    RUNNER --> BATCH["app/harness/batching.py\nmini-batch"]
    RUNNER --> GATE["core/evolution/gate.py\nCE-Gate"]
    RUNNER --> WS["app/harness/workspace.py\nStore + Workspace"]

    INF --> LOOP["core/agent/loop.py\nAgentLoop"]
    LOOP --> SEARCH["app/search/\nprompt + skills"]
    LOOP --> LLM["adapters/llm.py\nGovernedLLMClient"]

    BUILD --> VLM["adapters/vlm.py"]
    BUILD --> EMB["adapters/embedding.py"]

2.3 目录结构

project_root/
├── core/                    # 可提取内核(不依赖 app/、adapters/
│   ├── agent/               # 【可提取包】AgentLoop 引擎
│   │   ├── loop.py          # Thinking+JSON 推理循环,pluggy hook
│   │   ├── types.py         # Step, LoopResult
│   │   └── protocols.py     # LLMProvider, ToolDispatcher Protocol
│   ├── evolution/           # 【可提取包】诊断+进化引擎
│   │   ├── diagnose.py      # 两阶段诊断管线
│   │   ├── evolve.py        # patch/rewrite 进化
│   │   ├── gate.py          # CE-Gate e-process
│   │   ├── validate.py      # 块顺序验证
│   │   ├── types.py         # DiagnosisResult, EvolutionRecord, ...
│   │   └── protocols.py     # SkillStore, RunLog, TelemetryRecorder Protocol
│   └── types.py             # 跨模块共享类型
│
├── app/                     # 应用层(组合 core + adapters,领域特化)
│   ├── tree/                # 模块1:建树
│   │   ├── index.py         # TreeIndex 数据结构(L1/L2/L3Node
│   │   ├── video_builder.py # VideoTreeBuilderasyncio 并发)
│   │   ├── text_builder.py  # TextTreeBuilder
│   │   ├── embeddings.py    # EmbeddingModellocal/remote 双后端)
│   │   ├── enhance/         # 树增强管线(verify/supplement/clean
│   │   └── subtitle.py      # SRT 解析 + 字幕注入
│   ├── harness/             # 模块2:训练 harness
│   │   ├── runner.py        # 训练循环编排(对标 Trainer)
│   │   ├── inference.py     # 推理 step
│   │   ├── batching.py      # mini-batch 构建
│   │   ├── question_gen.py  # 数据加载、三池切分
│   │   ├── gate_ladder.py   # 信息阶梯
│   │   ├── momentum.py      # 慢速动量
│   │   ├── config.py        # RunConfig
│   │   ├── log.py           # HarnessLog (SQLite)
│   │   └── workspace.py     # Store + Workspace 版本管理
│   ├── question_gen/        # 模块3:新题构建
│   │   ├── generator.py     # 题目生成
│   │   ├── calibrator.py    # 基线校准
│   │   └── dedup.py         # 去重
│   ├── search/              # 搜索 Agent 装配
│   │   ├── prompt.py        # PromptManager
│   │   └── skills.py        # SkillRegistry
│   ├── retriever/           # 可训练检索器
│   │   ├── recursive.py     # RecursiveRetriever (CrossAttention+ACT)
│   │   ├── losses.py        # NavigationLoss + ACTLoss
│   │   └── train.py         # 两阶段训练入口
│   └── ports.py             # 应用层特有端口
│
├── adapters/                # 外部实现层
│   ├── llm.py               # GovernedLLMClient(遥测+熔断+Redis缓存)
│   ├── vlm.py               # VLM 客户端
│   ├── embedding.py         # Embedding 服务实现
│   ├── redis_cache.py       # Redis 响应缓存
│   ├── ocr.py               # MonkeyOCR 客户端
│   ├── asr.py               # ASR (Whisper) 客户端
│   └── telemetry.py         # SQLite 遥测记录实现
│
├── config/                  # 声明性配置(YAML,禁止 .py
├── store/                   # 版本化资源(skills/prompts/questions/videos
├── workspaces/              # 实验工作区
├── prompts/                 # 诊断 prompt(不参与进化,是评估标尺)
├── tests/                   # 测试
├── data/                    # 数据(不提交 Git)
├── logs/                    # 日志(不提交 Git
├── results/                 # 实验结果
├── main.py                  # CLI 入口
└── research-wiki/           # 单一事实源

2.4 依赖方向硬性规则

可依赖 禁止依赖
core/ 标准库、typing、pluggy app/adapters/、任何框架
app/ core/、标准库 adapters/(只通过 Protocol
adapters/ core/app/ports.py、第三方库 app/ 内部模块

2.5 可提取内核

core/agent/core/evolution/ 是两个独立可提取包,只依赖 Protocol 接口。将它们连同 core/types.py 复制到另一个项目,提供 Protocol 实现即可运行——这是验证依赖方向是否守住的判据。


§3 接缝清单(Protocol 端口)

只在真正易变、需替换或需造测试替身处引入接口,其余写直白的领域函数。

3.1 核心端口(core/ 内,可提取)

Protocol 所在文件 关键方法 职责
LLMProvider core/agent/protocols.py chat(), chat_async() LLM 文本调用
VLMProvider core/agent/protocols.py chat_with_images(), chat_with_images_async() VLM 图文调用
ToolDispatcher core/agent/protocols.py dispatch(tool_name, args, context) Agent 工具调度
SkillStore core/evolution/protocols.py read_skill(), write_skill(), list_versions() 版本化技能存储
PromptStore core/evolution/protocols.py read_prompt(), write_prompt() 版本化提示词存储
RunLog core/evolution/protocols.py insert(), query() 实验日志
TelemetryRecorder core/evolution/protocols.py record_llm_call() Agent 遥测

3.2 应用层端口(app/ports.py

Protocol 关键方法 职责 当前实现
EmbeddingProvider embed(texts) 文本嵌入 adapters/embedding.py
TreeCache get(), set() 树索引缓存 adapters/redis_cache.py
ASRProvider transcribe(audio_path) 语音识别 adapters/asr.py
OCRProvider recognize(image_path) OCR adapters/ocr.py

判据:这块代码会不会被换实现、或需要在测试里替换成假的?不会,就别抽象。

3.3 当前实现映射

Protocol adapter 实现 说明
LLMProvider adapters/llm.py GovernedLLMClient OpenAI 兼容 API,内置治理栈(§5)
VLMProvider adapters/vlm.py Qwen VL 等 OpenAI 兼容 VLM API
ToolDispatcher app/search/skills.py SkillRegistry 按名称分发到已注册工具函数
SkillStore / PromptStore app/harness/workspace.py 文件系统版本化存储(store/skills/v{N}/
RunLog app/harness/log.py HarnessLog SQLite 持久化
TelemetryRecorder adapters/telemetry.py SQLite telemetry.db
EmbeddingProvider adapters/embedding.py localsentence-transformers/ remote 双后端
TreeCache adapters/redis_cache.py Redis 键值缓存
ASRProvider adapters/asr.py Groq Whisper API
OCRProvider adapters/ocr.py MonkeyOCR 自建端点

§4 Agent 遥测规范

每次 LLM/VLM 调用必须经过 TelemetryRecorder 记录以下字段:

字段 类型 说明
call_id str UUID,本次调用唯一标识
parent_call_id str? 父调用(agent step → LLM call 链路)
session_id str epoch/step/question 关联 ID
model_name str 使用的模型名
provider str API 端点标识
messages str (JSON) 原始输入
response str 原始输出
prompt_tokens int 输入 token 数
completion_tokens int 输出 token 数
latency_ms int 延迟毫秒
cache_hit bool 是否命中 Redis 缓存
error str? 异常信息(正常为 null

存储SQLite telemetry.dbllm_calls 表。adapters/telemetry.py 实现 TelemetryRecorder Protocoladapters/llm.pyGovernedLLMClient 在每次调用后自动写入。


§5 LLM 调用韧性

所有 LLM/VLM 调用必须经过 GovernedLLMClientadapters/llm.py)治理,禁止裸调 OpenAI SDK。治理栈包含五层:

机制 说明
1 硬超时 asyncio.wait_for(call, timeout=config.llm_timeout)
2 指数退避重试 max_retriesbase_delaymax_delay(可配置)
3 熔断器 连续 N 失败 → 短路 M 秒 → 探针恢复
4 Redis 响应缓存 content-addressedhash(model + messages) → response
5 ARQ 任务队列 长时间推理任务异步执行

熔断参数(LLM_CIRCUIT_BREAKER_THRESHOLDLLM_CIRCUIT_BREAKER_COOLDOWN)和超时(LLM_TIMEOUT)通过 .env 工程配置管理。

治理流程伪代码

call(messages) →
  if breaker.is_open: raise CircuitOpen
  key = hash(model, messages)
  if redis.exists(key): return cached     # 层4: 缓存
  try:
    resp = await wait_for(api(messages),   # 层1: 硬超时
                          timeout)
    breaker.record_success()
    redis.set(key, resp)
    telemetry.record(...)                  # 遥测
    return resp
  except Transient:
    retry with backoff                     # 层2: 退避重试
  except:
    breaker.record_failure()               # 层3: 熔断
    raise

§6 核心算法保真清单

迁移时逐一比对参考代码,不可简化。建树 4 项 + 训练 9 项 = 13 项:

# 算法 参考文件 核心逻辑
1 L2 轴心建树策略 reference/video_tree_trm/video_tree_builder.py L2 先行→L3 向下→L1 向上,asyncio 链式并发
2 VLM 批量帧描述 + JSON fallback reference/video_tree_trm/video_tree_builder.py _L3_BATCH_SIZE=5 批量调用,解析失败逐帧 fallback
3 断点续跑机制 reference/video_tree_trm/video_tree_builder.py progress.json + L1 中间 JSON,按段恢复
4 RecursiveRetriever reference/docs/architecture.md §5 Cross-Attention 选择器 + ACT halt + z 状态累积
5 CE-Gate e-process TRM4 core/harness/eprocess.py 截断 Beta 混合、四出口门控
6 信息阶梯 TRM4 core/harness/gate_ladder.py 冷启动 2:1、gamma-EMA、反泄漏
7 块顺序验证 TRM4 core/harness/validate.py 基线缓存、INFRA 护栏、配对翻转
8 诊断瀑布 TRM4 core/harness/diagnose.py 错误归因级联、缺陷 vs 失误、D1-D5
9 进化 patch 引擎 TRM4 core/harness/evolve.py + patch.py 保护跨度、rank-and-clip、附录/动量
10 Mini-batch 构建 TRM4 core/harness/batching.py FFD + round-robin + 正确率混合
11 Agent Loop TRM4 core/loop.py Thinking+JSON、json_repair、pluggy hook
12 树环境语义搜索 TRM4 core/tree/environment.py 分块 embedding、祖先去重、锚定验证
13 训练循环编排 TRM4 core/harness/runner.py 三级嵌套、慢更新10步、断点续训

TRM4/home/iomgaa/Projects/Video-Tree-TRM4/reference/home/iomgaa/Projects/Video-Tree-TRM5/reference/


§7 配置管理(双模式)

系统配置分两套,按用途隔离:

模式 载体 适用
工程配置 pydantic-settings + .env 系统运行所需、少变或敏感(API 密钥、Redis URL、LLM 超时等)
科研实验配置 per-experiment YAML + harness run 快照 会在实验中反复扫动/对比的参数(gate 阈值、batch 大小、评估口径等)

D7 归属判定规则(防串台,强制遵守):某参数是否会在科研实验中被反复扫动/对比?

  • → 科研配置(per-experiment YAML + harness run 快照,保证可复现)。
  • (系统运行所需、少变、或敏感)→ 工程配置(pydantic-settings + .env)。

CLI args 仅用于单次临时覆盖,不作为任何配置的常驻来源。两类载体之外,严禁在代码中散落硬编码默认值;缺失关键配置应直接报错而非兜底。

参数归属示例

参数 归属 理由
SEARCH_LLM_API_KEY 工程 .env 敏感,不变
LLM_TIMEOUT 工程 .env 系统运行所需,少变
gate_e_confirm 科研 YAML CE-Gate 阈值,实验中反复调优
batch_size 科研 YAML mini-batch 大小,实验中反复扫动
embed.model_name 科研 YAML 嵌入模型选型,实验中对比
REDIS_URL 工程 .env 基础设施地址,少变

附:横切原则

  • 溯源:每条推理链(Agent 看了哪些节点、如何汇总出答案)都带来源。遥测(§4)记录全部 LLM 调用,Store 版本化记录 skill/prompt 变更历史。
  • 可复现:每次 harness run 冻结当前 config/ YAML + Store 版本快照(app/harness/workspace.py),结果可重算。
  • 安全/合规API 密钥走 .env,不提交 Git;Redis 缓存中不存敏感信息的明文。