▶VIDEO.md

VIDEO.md 为什么是这个样子

规范 讲一个包里有什么。这一页讲为什么:它解决什么问题,想法从哪来,每个决定背后的理由。

一句话

每个技能有一个 SKILL.md,每条视频也有一个 VIDEO.md。它从一张几百 token 的卡片开始,逐层展开,直到单个镜头。每一层都写明自己有多大,并把看到的和推断的分开。

卡片是这条视频的身份证:它是什么、怎么做的、有多确定。整个包是它的档案:概览、时间线、单个镜头。需要哪一页就翻哪一页,不用把整个档案读完。

要解决的问题

拆解一条视频会产出很多东西:逐镜的测量值、每一镜制作方式的概率、证据、字幕时间、音效位置、复刻提示词、帧图、分轨音频。三类读者想从中拿到的东西不一样:

读者 想要 难处
人 结论、好在哪、复刻步骤 细节零散、太技术
模型和 agent 能回答用户问题的那些事实 上下文成本、在细节里迷路、把推断当事实
程序 稳定的字段和取值 格式悄悄变化、要解析文字

人有报告,程序有原始数据,模型没有专门给它的东西。

把原始数据交给模型行不通。一条三分钟的口播视频,JSON 约 19 万 token;一条 75 镜的影视解说约 24 万。每个问题都读一遍,又慢又贵。而且测量值、推断和结论并排放着,「工具认为这一镜有 41% 可能是录屏」就变成了「这是录屏」。

把给人看的报告交给模型也不行。报告是按从头读到尾写的,有折叠、有叙述,没有稳定的结构,没法只读其中一部分。

VIDEO.md 就是给这个缺位的读者准备的格式。

想法从哪来

VIDEO.md 里没有新东西。它把几种已经好用的做法组合在一起。

Agent Skills:渐进式展开

一个技能就是一个文件夹。SKILL.md 前置信息里的 name 和 description 常驻 agent 的上下文,只有几十个 token。只有技能用得上时,agent 才读正文;正文指向 references/ 下的文件,需要时才打开。

VIDEO.md 用的是同样的结构,只是把一项能力换成了一条视频:

Agent Skill VIDEO.md
SKILL.md 前置信息:name、description VIDEO.md 前置信息:卡片(name、description、制作方式占比、置信度)
SKILL.md 正文:指令 VIDEO.md 正文:结论、待复核的问题、地图
references/*.md,按需打开 video/*.md,每个一个主题,按需打开
脚本和资源文件 原始数据、帧图、分轨音频

它多走了一步:每个文件都写明自己有多少 token,地图里也有。技能告诉 agent 有什么;VIDEO.md 还告诉它打开要花多少,模型读之前就能权衡。

小型 DSL:一行一个镜头

时间线是整个包的主干。它不是 JSON 数组,也不是 Markdown 表格,而是一种很小的行格式:

#07 16.2-18.5 | seen man talking, chat screenshots pop up | camera static | made~ screen capture 41% | flag low confidence

思路和 SRT 字幕、EDL 剪辑表、日志行一样:一行一条记录,先写编号和时间,再写 key value 对。这样做的原因:

DSL 只用在这一处。卡片和镜头数据是 YAML 前置信息,用 JSON Schema 校验;说明文字是普通 Markdown。紧凑的语法放在最需要密度的地方,其他地方都用大家已经会读的格式。

另外

VIDEO.md 里的地图和时间线用同一种行格式(path | tokens | about),所以一个包只有一套小语法,不是两套。

设计决定

必需的核心很小

一张卡片只需要六个字段:版本、名字、描述、来源、镜头数、语言。一个镜头只需要编号和时间。其他都是可选的,包括判断每一镜是怎么做的。

技能也是这样:只有 name 和 description 是必需的。一个只总结内容的工具,或者一位描述自己视频的创作者,不用编造手里没有的数据,也能写出合格的包。会判断制作方式的工具再加上 made_mix 和 inferred,懂这些字段的读取方就会用上。

身份

卡片叫身份证,就得有身份:source.sha256 是整个文件的哈希;视频来自链接时,还有 source.url。两个工具为同一条视频写的两个包,可以据此对上、比较、合并。

四层,每层大一个量级

层 大小 够回答什么
L0 卡片 100–300 token 讲什么,要不要打开
L1 概览和地图 1–2k 结论、复刻概要、哪里不确定、下一步读哪个文件
L2 主题 几百到几千 某一方面的完整信息:时间线、声音、包装、复刻
L3 镜头 500–1000 某一镜:看到的、推断的和依据、提示词、帧图
L4 原始 10 万以上 程序

多数问题(「这条怎么做的」「要准备什么素材」「哪几镜要复核」)在 L1 就能回答。按镜头的问题加上时间线,总共约 4k token。只有核实某一镜才需要 L3。

分层跟着人提问的顺序:先问整条视频,再问某一方面,最后问某一镜。

读之前就知道代价

每个文件的前置信息里都有 tokens,地图里也有一列。这改变了模型读文件的方式:不是「打开看看」,而是「这个问题值得花 14k token 读复刻方案吗,还是时间线里的 remake 字段就够了?」

看到的和推断的分开

这是最重要的一条规则。拆解里有两种性质很不一样的内容:

两者混在一起,模型会把推断当事实转述,用户也分不清哪句该信。所以 VIDEO.md 在三处把它们分开:时间线里用 ~ 键;镜头文件里看到的和推断的各占一节;所有推断的字段都放在 inferred 下,附概率、次选和 decided_by(tools、model、agent、human)。两者对不上时,以帧图为准。

时间线是主干

视频是线性的,几乎所有问题最后都落到「第几秒、哪一镜」。时间线是唯一值得整个读完的 L2 文件;主题文件和镜头文件都按镜头编号挂在它上面。它的 flag 字段标出需要复核的镜头,模型扫一遍就知道该打开哪些帧图。

形式固定,内容开放

程序依赖的部分是固定的:前置信息字段、时间线语法、取值表里的 id。能扩展的部分是开放的:新的时间线键、新的主题文件、新的叠加层 id,以及取值表以外的 x- id。读的一方忽略不认识的内容。只做增加时版本号不变,改变含义才升版本。

这样生成方能力变强时(比如多了一个运镜维度),现有的读取方照常工作。

随视频一起扩展

六秒的广告和两小时的电影用的是同一个格式。广告只用卡片、时间线和两个镜头文件。电影多一份场景列表,模型先读几千 token 再决定看哪里,时间线也按场景拆开。一小时的长镜头按内容拆成多行,共用一个 take;反应视频在 layers 下描述画面的每一部分;先环绕再甩镜的镜头按顺序列出两个运镜动作。这些都是可选的,视频需要时才加,简单的视频依然简单。

文字给模型,id 给程序

时间线的值是用包的语言写的文字:「screen capture 41%」或「屏幕录制 41%」,因为读它的是模型。screen_capture 这类稳定的 id 放在镜头文件的前置信息和 made_mix 里,程序只读这些。每一层只做一件事,谁都不用从另一层里解析出来。

它带来什么

agent

程序

人

生态

它不是什么

其他做法

做法 问题
把原始 JSON 交给模型 太大;测量、推断和结论混在一起
把报告交给模型 没有稳定结构,没法只读一部分
每次让模型看一遍视频 慢、贵、不可复现,也看不到帧率、噪声和元数据
一个大 Markdown 文件 要么太长读不完,要么太短没用;没法按需展开
只提供 JSON API 适合程序,对模型浪费,人读不了

VIDEO.md 不是从中挑一个,而是把它们分层:上层给模型,中层给模型和程序,底层给程序。