Files
Video-Tree-TRM5/research-wiki/designs/2026-07-09-main-inference-entry-design.md
T
2026-07-09 08:41:22 -04:00

9.2 KiB
Raw Blame History

id, title, type, status, created
id title type status created
main-inference-entry main.py 推理入口 + 初始 Prompt 集设计 design approved 2026-07-09

main.py 推理入口 + 初始 Prompt 集设计

1. 目标

完成第一版 900 道题推理基线,具体交付:

交付物 说明
main.py CLI Composition Root,本次仅实现 infer 模式
app/harness/deps_router.py 按 video_id 懒加载 InferenceDeps 的路由器
app/ports.py 扩展 新增 ToolDispatchFactory / PromptBuilderFactory Protocol
app/harness/runner.py 小改 __init__ 注入 factory,替换 noop 占位
store/skills/v1/ 14 个 skill(从 TRM4 v1 精简 + 注入 TRM5 card 字段)
store/prompts/v1/ 目录重组(从 store/prompts/ 扁平结构迁入)
配置变更 concurrency=24, max_steps=40, breaker_threshold=48

2. 架构

2.1 依赖流(Clean Architecture Composition Root

main.py (Composition Root — 最外层)
  │
  ├─ 构建 adapters ──────────────────────────────┐
  │   CircuitBreaker                             │
  │   RedisResponseCache (可选,降级为 None)       │ adapters/
  │   SQLiteTelemetryRecorder                    │
  │   GovernedLLMClient (search)                 │
  │   GovernedLLMClient (evolve, 本次传同一实例)   │
  │   GovernedVLMClient                          │
  │   LocalEmbeddingProvider                     │
  │   MonkeyOCRClient (可选)                      │
  │                                              │
  ├─ 构建 InferenceDepsRouter ───────────────────┤
  │   接收: store_dir, embed, llm, vlm, ocr      │ app/harness/deps_router.py
  │   复用: factory.build_inference_deps()        │
  │                                              │
  ├─ 构建 Runner ────────────────────────────────┤
  │   注入: config, llm, evolve_llm, vlm,        │ app/harness/runner.py
  │         telemetry,                           │
  │         tool_dispatch_factory,               │
  │         prompt_builder_factory               │
  │                                              │
  └─ asyncio.run(runner.infer()) ────────────────┘

依赖只向内:main.pyadapters/ + app/core/

2.2 InferenceDepsRouter

位置app/harness/deps_router.py

职责:将 Runner 的全局统一 dispatch/prompt_builder 接口路由到 per-video 的 InferenceDeps

prompt_builder(qa)          ← 先调用,注册 qid→vid 映射
    ↓
AgentLoop.run()
    ↓
dispatch(tool, args, ctx)   ← 后调用,通过 ctx["session_id"] 查映射

核心伪代码:

class InferenceDepsRouter:
    _deps_cache: dict[tuple, InferenceDeps]   # (vid, skills_dir, prompts_dir) → deps
    _qid_to_vid: dict[str, str]               # question_id → video_id

    def create_dispatch(self, *, skills_dir=None):
        async def _dispatch(tool_name, args, *, context):
            vid = self._qid_to_vid[context["session_id"]]
            deps = self._ensure_deps(vid, skills_dir, ...)
            return await deps.tool_dispatch_fn(tool_name, args, context=context)
        return _dispatch

    def create_prompt_builder(self, *, skills_dir=None, prompts_dir=None):
        def _builder(qa):
            self._qid_to_vid[qa.question_id] = qa.video_id  # 注册映射
            deps = self._ensure_deps(qa.video_id, skills_dir, prompts_dir)
            return deps.prompt_builder(qa)
        return _builder

    def _ensure_deps(self, video_id, skills_dir, prompts_dir):
        key = (video_id, str(skills_dir or ""), str(prompts_dir or ""))
        if key not in self._deps_cache:
            self._deps_cache[key] = build_inference_deps(...)
        return self._deps_cache[key]

时序保证run_inference() 中每道题先调 prompt_builder(qa) 构建 prompt,再启动 AgentLoop(调 dispatch)。映射注册总先于使用。

2.3 Runner 改动

__init__ 新增 2 个可选参数(向后兼容):

def __init__(self, config, *, llm, evolve_llm, vlm, telemetry,
             tool_dispatch_factory=None,
             prompt_builder_factory=None):

_make_tool_dispatch_fn / _make_prompt_builder 优先用注入值,缺省保留 noop fallback。

2.4 Protocol 定义

app/ports.py 新增:

class ToolDispatchFactory(Protocol):
    def __call__(self, *, skills_dir: Path | None = None) -> Callable[..., Any]: ...

class PromptBuilderFactory(Protocol):
    def __call__(self, *, skills_dir: Path | None = None,
                 prompts_dir: Path | None = None
    ) -> Callable[[GeneratedQuestion], tuple[str, str]]: ...

2.5 main.py 结构

使用 argparse(复用 RunConfig + load_config() 的 YAML/CLI 三层合并逻辑)。

def _build_parser():       # CLI 参数定义,与 TRM4 main.py 保持一致
def _build_adapters():     # 从 .env 构建全套 adapters,返回 NamedTuple
def _log_result():         # 输出推理结果摘要
def main():                # Composition Rootload_config → adapters → router → runner

本次只实现 mode == "infer" 分支,其余模式 raise SystemExit("尚未实现")

3. 初始 Prompt 集

3.1 设计原则

进化能学到的 → v1 留框架、去细节(给进化留空间)
进化学不到的 → v1 用人类版(否则永远缺失)

依据 TRM4 进化历史(v1→v40):skills 进化 39 轮(主力),system prompt 仅 1 轮,tool prompts 未变。

3.2 三类 Prompt 处理

类别 是否进化 v1 来源 处理
system.md 微量 TRM5 现有版本 保留(已含 card 字段说明,是基础设施)
skills/v1/ (14个) 主力 TRM4 v1 精简 + TRM5 注入 见 §3.3
extract/verify (8个) 不变 TRM5 现有版本 保留(已适配 card 结构)

3.3 Skills v1 内容策略

每个 skill 文件的改造规则:

内容层次 进化能学到? v1 处理
YAML frontmattertask_type 保留原版
Step 标题 + 一句话基本意图 保留原版
reflect/plan/action JSON schema 保留原版
TRM5 card 字段索引 新增(注入各层字段名及适用场景)
数据驱动统计 移除
步骤间精确转换条件 移除
详细操作性规则 移除
大多数自检信号 移除(保留最基本 1 条)
特定失败模式陷阱 移除(保留 1-2 条通用警告)

card 字段索引表(注入每个 skill):

层级 字段 适用场景
L1 scene_summary 整体概况
L1 key_entities 查找人物/物体
L1 main_actions 主要动作
L1 temporal_flow 时间线概览
L1 topic_keywords 主题定位
L2 event_description 事件因果
L2 entities / actions 实体和动作细节
L2 state_changes 状态转变
L2 spatial_relations 空间关系变化
L3 frame_summary 精确视觉证据
L3 visible_entities 具体物体确认
L3 ongoing_actions 正在发生的动作
L3 spatial_layout 精确空间位置
L3 visual_attributes 光照、色调、机位
全层 visible_text 画面文字(OCR
全层 subtitle 字幕转写

3.4 store/ 目录重组

store/
  prompts/
    v1/                          ← 新建(从 store/prompts/*.md 移入)
      system.md
      observe_frame_extract.md
      observe_frame_verify.md
      search_similar_extract.md
      search_similar_verify.md
      view_node_extract.md
      view_node_verify.md
      view_node_children_extract.md
      view_node_children_verify.md
  skills/
    v1/                          ← 新建(14 个文件)
      default-strategy.md
      action-reasoning.md
      action-recognition.md
      attribute-perception.md
      counting-problem.md
      information-synopsis.md
      object-reasoning.md
      object-recognition.md
      ocr-problems.md
      spatial-perception.md
      spatial-reasoning.md
      temporal-perception.md
      temporal-reasoning.md

4. 配置变更

参数 原值 新值 位置
concurrency 12 24 config/default.yaml
max_steps 15 40 config/default.yaml
breaker_threshold 5 48 .env

熔断器行为:所有 24 并发 agent 共享同一 CircuitBreaker 实例,record_success() 归零计数。48 = 连续 2 波全失败才触发开路,间歇抖动不会误触。

5. 拒绝的方案

方案 拒绝原因
Runner 子类覆盖 _make_* Template Method 反模式,违反依赖反转
绕过 Runner 直接调 run_inference 不复用 workspace 管理、日志、报告逻辑
照搬 TRM4 v1 skills 进化空间不足,且缺少 TRM5 card 字段知识
极简骨架 skills 基线质量过低,可能不收敛
typer CLI 需重写 RunConfig 的 YAML/CLI 合并逻辑,ROI 不值