镜头理解(shot-understanding v2)
1. 定位与边界
- 在什么之后:
probe阶段(ffprobe/场景检测/ASR/节拍)已经产出确定性切点与词级时间戳。 - 在什么之前:
highlight(高光与关键帧)、edit-script(剪辑脚本)依赖本技能的字段。 - 只做什么:把每个镜头变成结构化文本字段(画面/人物/动作/实体/台词/文字/景别/运镜/光线/情绪/可用性)。
- 不做什么:不做切点检测(信号层的活)、不做选镜与排序(剪辑指导的活)、不做审美评分(评审链的活)。
- 纪律:本阶段逐镜调用模型,禁止"一次调用理解全片"。旧链路一次吐全片 JSON 的失败模式:长视频中后段字段坍缩、时间码漂移、镜头切分与画面不符。
2. 输入 / 输出契约
| 输入 | 来源 | 用途 |
|---|---|---|
probe.shotBoundaries[] | signal-analyst | 镜头区间(帧级 in/out)——唯一权威切点 |
probe.speech.words[] | ASR | 台词与切点复核(句末停顿优先) |
probe.technical.perShot[] | ffmpeg 指标 | 质量字段(清晰度/曝光/稳定性/噪声) |
| 关键帧图(每镜 3–6 帧) | 抽帧器 | 多模态模型的视觉输入 |
输出:shot_record[],逐字段遵循 schemas/footage-analysis.schema.json。
每个镜头必须包含:shotId、index、帧级 inTimecode/outTimecode、durationSeconds、sceneType、content(视觉描述/台词/画面文字/实体/动作)、tech(景别/运镜/光线/稳定性)、evidence[](≥1 帧)、confidence。
3. 执行 SOP
- 切点对齐:以信号层切点为骨架;若模型认为切点有问题,只能"建议"(写进
editing.cutInReason/cutOutReason备注),不得自行改时间码。 - 抽帧:镜头内均匀抽 3 帧 + 运动峰值帧 + 首末帧(长镜头每 2 秒加抽 1 帧)。
- 逐镜调用(并发 ≤4,单镜超时 90s,失败重试 1 次后进入
skippedShots,不静默跳过):- 输入:镜头首末时间码、抽帧图、该镜内的 ASR 词序列、该镜技术指标。
- 输出:严格 JSON(下方提示词给模板)。
- 一致性复核:台词与 ASR 逐字比对(允许标点差异,不允许内容篡改);技术指标以信号层为准(模型只能补充语义)。
- 落库:写
understand.事件 +shot_record产物(带模型名与 promptVersion)。
4. 提示词正文(可直接投喂,v2)
使用方式:
{{ }}为注入位;要求模型只输出 JSON。逐镜调用,不要传入整片。
主通道说明(多模态模型自采集):画面文字(OCR)与人声转写(ASR)由多模态模型在理解阶段直接产出—— 模型同时拿到「关键帧图」与「音频(若模型支持音频模态)」,自己读字、自己听写,不调用外部 OCR/ASR 工具。 工具通道(本机 Vision / 本机 ASR 引擎)只作为无模型能力时的兜底,且必须在回执里标
channel=fallback, 不允许把兜底结果冒充模型结论。两条通道的产出都写进同一组契约字段(content.onScreenText/content.speechText/probe.speech),差别只在coverage.asr.channel/coverage.ocr.channel的如实标注。
4.1 模型侧必做(画面文字 + 人声 + 环境音)
对每个镜头,模型必须完成这三件事,缺一即视为该镜未完成:
- 画面文字全量转写:逐帧读可见文字——招牌、门头、包装、横幅、路牌、屏幕 UI、字幕、水印;
同一文字重复出现只记一次,但要给证据帧;看不清的字用
[模糊]标注,不许脑补成通顺词组。 写进content.onScreenText(多条用/分隔)并在evidence[]里点名哪一帧看到。 - 人声转写:按句写
content.speechText(保留口语、不润色、不补句),并在probe.speech.sentences[]给句级时间戳; 模型具备音频模态时由模型直接听写(channel=model);只有兜底通道时同样如实标注。听不清写[听不清],不猜。 - 环境音描述:把该镜环境声写进
audio.ambience(风噪+树叶 / 厨房锅铲 / 市集人声 / 车流 / 鞭炮 / 安静), 并标注对剪辑的用途(可留白 / 可铺底 / 需降噪 / 与 BGM 冲突)。
这三件事是剪辑与后期的事实来源:画面文字决定地点/店铺/商品,人声决定文案与字幕,环境音决定声音设计与留白。
你是"镜头理解师"。任务:把一个镜头(已由确定性工具切好)转写为结构化字段。
【素材上下文】
- 视频领域:{{ content_domain }}(知识/旅行/评测/剧情/教学/生活记录/其他)
- 素材来源类型(整片级):{{ source_kind }}(实拍 / AI 生成 / 录屏 / 资料)
- 创作者画像:{{ creator_profile }}
- 用户需求:{{ user_requirement }}
【本镜头输入】
- 镜头号:{{ shot_index }}
- 时间码(帧级,权威,不得修改):{{ in_timecode }} - {{ out_timecode }}(时长 {{ duration_seconds }}s,帧率 {{ fps }})
- 抽帧图:{{ frames }}(按时间顺序;含首帧、末帧、运动峰值帧)
- 镜头内语音转写(词级,权威):{{ asr_words }}
- 技术指标(权威):清晰度 {{ sharpness }} / 曝光 {{ exposure }} / 稳定性 {{ stability }} / 噪声 {{ noise }}
【硬性纪律】
1. 只描述抽帧图与语音转写能证明的内容;看不见的一律写 null 或空数组,严禁虚构人物、地点、品牌、数据。
2. 不做内心活动推断:不写"他在想/她感到"这类无法证实的内容,只写可见的表情、姿态、动作与环境。
3. 台词文本与 ASR 逐字一致(可去标点),不得润色、不得补句。
4. 每条语义结论配 evidence(帧序号或秒点 + 为什么),confidence 为 0–1 的实数。
5. 输出必须是合法 JSON,不追加解释、不使用 Markdown 代码块之外的内容。
【场景分类(sceneType 单选,影响后期策略)】
- live_stream:直播切片(直播间 UI/互动/压缩画质/需降噪)
- on_location:实景拍摄(手持或稳定器/自然光或现场光/环境音)
- studio_talking:棚拍口播或访谈(背景干净/收音清晰/专业布光)
- b_roll_insert:空镜与辅助镜头(环境展示/细节特写/无人声)
- archive_footage:资料素材(非本次拍摄/历史影像/网络素材)
- screen_recording:屏幕录制(软件操作/PPT/游戏画面)
【剪辑友好度判断(写进 editing)】
- cutInReason / cutOutReason:本镜适合从哪里进、从哪里出(动作落点 / 语音气口 / 视觉硬切 / 情绪峰值 / 信息节点)
- transitionSuggestion:与相邻镜头可能的转场(硬切/叠化/匹配剪辑/甩镜/跳切)
- usage:主叙事线 / 情绪点 / 反应镜头 / 转场桥 / 背景填充 / 信息强调 / 封面候选
【画面文字 / 人声 / 环境音(模型直接产出,不得跳过)】
- 画面文字:逐帧读全部可见文字(招牌/门头/包装/横幅/路牌/屏幕/字幕/水印),重复只记一次,看不清标 [模糊];
写进 content.onScreenText,并在 evidence 里点名"在哪一帧看到"。
- 人声:按句转写 content.speechText(保留口语、不润色、不补句),听不清标 [听不清];
若你(模型)能直接处理音频,就以你的听写为准;只有兜底通道时同样如实标注。
- 环境音:写 audio.ambience(风噪/厨房/市集/车流/音乐/安静…)+ 对剪辑的用途(留白/铺底/降噪/与 BGM 冲突)。
【输出 JSON 模板】
{
"shotId": "{{ shot_id }}",
"index": {{ shot_index }},
"inTimecode": "{{ in_timecode }}",
"outTimecode": "{{ out_timecode }}",
"durationSeconds": {{ duration_seconds }},
"sceneType": "on_location",
"content": {
"visualDesc": "画面内容(人物/动作/关键物体/环境/视觉焦点)",
"speechText": "对应台词(无则 null)",
"onScreenText": "画面中出现的文字(招牌/包装/字幕,无则 null)",
"keyEntities": ["人物/产品/概念/地点/数据点"],
"actions": [{ "who": "谁", "what": "做了什么", "start": 0.0, "end": 0.0 }],
"setting": "环境(室内/室外/天气/时段)"
},
"tech": {
"shotSize": "extreme_wide|wide|medium|close_up|extreme_close_up|unknown",
"cameraMove": "static|pan|tilt|push_in|pull_out|tracking|handheld|aerial|unknown",
"lighting": "自然光/室内光/专业布光/逆光/低光",
"stability": "stable|slight_shake|heavy_motion|unknown",
"composition": { "subjectPosition": "", "headroom": "", "leadRoom": "" }
},
"audio": { "speechClarity": 0.0, "ambience": "", "music": true, "clipping": false },
"emotion": { "dominant": "", "intensity": 0.0, "valence": 0.0 },
"quality": { "score": 0.0, "usable": true },
"editing": { "cutInReason": "", "cutOutReason": "", "transitionSuggestion": "", "usage": [] },
"evidence": [{ "t": 0.0, "frame": 0, "why": "结论依据" }],
"confidence": 0.0
}
5. 自检清单(输出前逐条核对)
- 时间码与输入完全一致(没有 ±0.5s 的"四舍五入"漂移)
-
evidence至少 1 条,且每条能解释一个具体结论 - 台词与 ASR 逐字一致;无台词镜头
speechText为 null - 没有出现抽帧里看不到的人、物、地点
- 情绪字段只有可见依据(表情/姿态/环境),无内心描写
-
confidence < 0.6的结论已在editing或备注中标记为待复核 - JSON 合法(无注释、无尾逗号、无 Markdown 包裹)
决策原则(含阈值与失败关闭)
- 时间码以信号层为权威:模型只允许"建议切点",不得改写输入时间码;与信号层偏差 >1 帧即按信号层回退重对齐。
- 无证据不落库:每条语义结论必须带
evidence[](≥1 帧);confidence < 0.6的结论不得进入下游选镜池,只能进"待复核"。 - 台词以 ASR 为准:台词文本与词级转写逐字一致率 <98% 即退回重写,不得润色或补句。
- 失败关闭(fail-closed):看不到的字段写
null/空数组,不用"推测值"填充;宁可少一个字段,不可多一个幻觉。 - 单镜隔离:单镜失败重试 ≤2 次后进
skippedShots,不因一个镜头重跑整片(成本与可复现性)。
打法库(场景 → 动作序列 → 判据)
- 主线·逐镜标准解析:抽帧(首/末/运动峰值 + 均匀 3 帧)→ 单镜调用 → 一致性复核 → 落库(判据:字段完整率 ≥95%,证据覆盖率 100%)。
- 分支·长镜头(>8s):每 2s 加抽 1 帧,必要时拆"语义子段"(同一 shotId 内分段描述)(判据:动作/信息节点不漏标)。
- 分支·多人对话:按说话人归属标注
actions[].who,与 ASR 说话人切换对齐(判据:说话人归属正确率 ≥90%)。 - 分支·低置信度复核:对
confidence < 0.6的镜头二次抽帧重跑(判据:两次结果置信度差 ≤0.2,否则挂人审)。
SOP(每步带触发/回执/失败路径)
- 触发(probe 完成)→ 逐镜并发解析(并发 ≤4)→ 回执:
shot_record批次 + 模型名 + promptVersion;失败:单镜超时/解析异常重试 1 次,仍失败则记入skippedShots并写明原因,不静默跳过。 - 触发(批次解析完成)→ 一致性复核(ASR 逐字、技术指标以信号层为准)→ 回执:复核清单(冲突项与处理);失败:冲突项回退该镜并保留旧版本(只增不改)。
- 触发(复核通过)→ 落库并写
understand.五元事件 → 回执:事件编号 + 产物 sha256;失败:写库失败即整批挂起并告警,不得"部分落库当作完成"。
关键指标(含基准与护栏)
| 指标 | 口径 | 基准/阈值 | 类型 | 来源 |
|---|---|---|---|---|
| 字段完整率 | 通过必填校验的镜头 / 总镜头 | ≥95% | 质量 | 契约校验器 |
| 证据覆盖率 | 带 evidence[] 的结论 / 全部结论 | 100% | 护栏 | 落库前置校验 |
| 台词一致率 | 与 ASR 逐字一致的镜头 / 有台词镜头 | ≥98% | 质量 | 一致性复核 |
| 幻觉率 | 人工抽查判定为"素材中不存在"的结论 / 抽查结论 | 0(发现即回退) | 护栏 | 10% 人工抽检 |
| 单镜重跑率 | 触发重试的镜头 / 总镜头 | ≤5% | 成本 | 批次回执 |
失败模式(症状 → 检测器 → 处置)
| 症状 | 检测器 | 处置 |
|---|---|---|
| 中后段镜头描述变空/复制 | 是否退化成整片一次调用 | 改回逐镜调用;分批并发,单镜独立重试 |
| 时间码与画面对不上 | 是否用了模型自报时间 | 时间码一律取信号层输入,模型输出忽略时间码修改 |
| 台词牛头不对马嘴 | 抽帧与语音错配 | 用 ASR 词级区间反查镜头归属,重新对齐后再跑 |
| 出现素材里没有的品牌/地名 | 模型幻觉 | 删除该结论;强化"看不见就写 null",提高抽帧密度 |
| 同一镜头两次结果差异大 | 温度或抽帧不同 | 固定温度与抽帧策略;置信度差 >0.3 挂起复核 |
6. 与旧链路的差异(升级记录)
| 维度 | 旧版(2026-02 备份) | v2 |
|---|---|---|
| 调用粒度 | 一次调用理解全片 | 逐镜调用(长视频不再坍缩) |
| 时间码 | mm:ss 秒级 | 帧级 HH:MM:SS.mmm + 帧号 |
| 切点来源 | 模型"看图猜" | 信号层权威切点(内容感知检测 + 语音气口) |
| 证据 | 无 | 每条结论带证据帧与置信度 |
| 台词 | 模型转写(易错) | ASR 词级时间戳为准,模型只做语义补充 |
| 质量 | 4–5 分主观打分 | 信号层量化指标 + 语义可用性判断分离 |
| 输出对象 | 单份 file_id 大 JSON | shot_record[](可增量、可单镜重跑、可版本化) |