yangagent/hologram-presenter-video-skill

hologram-presenter-video

将用户内容制作成单人知识讲解视频。适用于知识科普、教程、课程、信息摘要或产品机制说明,并要求讲解角色开口说话、与悬浮全息信息互动的场景。

Ver código-fonte
Documento original do Skill

Renderizado do repositório de origem, preservando títulos, exemplos, código, tabelas, links e imagens.

全息讲解视频

在复用一套角色与场景档案的前提下,通过多个确认 Gate 建立可追溯的视频生产流程。讲解角色在每个生成片段中说出已经确认的口播文稿;不同片段通过硬切改变视角和构图,最后合并为一个 MP4 视频。

不可违反的规则

  • 只维护一套当前 Profile,不得实现 Profile 选择器。
  • 将角色图与场景图视为彼此独立的风格参考。遇到卡通角色与写实场景或其他混合组合时,不得强行统一成同一种艺术风格。
  • 以用户确认的口播文稿作为知识内容的唯一事实来源,不得静默增加外部事实。
  • Gate3 未确认前,不得调用任何视频生成 API。
  • 不得添加背景音乐或转场。
  • 指令、脚本、配置和持久化运行产物中的路径必须使用相对路径。用户可以提供绝对的源图片路径,但复制图片后不得持久化保存该绝对路径。
  • 每个 Gate 都必须等待用户明确确认,不得把沉默视为同意。

相对路径基准

  • Skill 资源相对于本 Skill 所在目录解析。
  • profile/profile.json 内的路径相对于 profile/ 解析。
  • 运行产物创建在用户当前工作目录下。
  • 单次运行清单内的路径相对于该次运行目录解析。
  • 不得假设本 Skill 安装在任何固定位置。

执行顺序与阶段边界

Profile 构建和单次视频任务是两个严格串行、不能并行推进的阶段。每次调用本 Skill 时必须先检查 Profile,再从当前适用的阶段开始;需要构建 Profile 时,只有 Gate0 确认并成功写入完整 Profile 后,才可以在同一次调用中继续进入单次视频任务阶段:

  1. 如果 profile/profile.json 不完整、引用图片缺失,或用户明确要求重新设计 Profile,进入 Profile 构建阶段
  2. Profile 构建阶段只处理角色图、场景图、图片分析、长期风格偏好和 Gate0。Gate0 确认并且完整 Profile 已成功写入前,不得询问本期内容、目标时长、单次受众、单次讲解深度或其他本期视频要求;不得创建 hologram-video-runs/ 运行目录、run.json、口播稿或分镜,也不得提前执行 Gate1 及之后的步骤。
  3. 用户如果已经主动提供了本期内容或目标时长,可以在对话中保留这些信息,但 Profile 构建阶段不得处理、补问或据此创建运行产物。Profile 成功启用后再复用已经提供的信息,不要重复询问。
  4. 只有检查确认 Profile 在本次调用开始时已经完整可用,或刚刚通过 Gate0 成功建立,才能进入 单次视频任务阶段;此时才获取尚未提供的本期内容和目标时长。

不得为了减少对话轮次而并行或混合两个阶段的提问。

Gate0:建立可复用 Profile

每次收到请求时,首先检查 profile/profile.json 是否包含下述全部必要字段,以及其中引用的两张图片是否存在。

如果 Profile 完整,直接复用并省略图片收集。如果任意必要文件缺失,必须要求用户同时提供一张本地角色图和一张本地场景图。用户没有提供两张图片时,说明这一前置要求并终止后续视频生产流程。

如果用户明确要求重新设计、更换或重置 Profile,也必须重新提供两张图片并完整重建 Profile,不支持只替换其中一张。新 Profile 经确认并准备启用前,将旧的当前 Profile 保存为唯一的 profile.backup/;如果已有旧备份,则替换它。

凡进入 Profile 构建阶段,均完整读取并遵循 references/profile-interview.md。该参考文件负责图片分析、五个描述字段的起草、场景调度筛选、长期偏好访谈和 Gate0 语义复核;本入口文件只负责阶段编排与持久化。等待参考文件规定的 Gate0 明确确认后,把两张图片复制到 profile/assets/,保留有意义的文件扩展名,并写入下述最小化 Profile。持久化路径只记录复制后的相对路径。

写入以下最小化的 profile/profile.json

json
{
  "updated_at": "YYYY-MM-DDTHH:mm:ss",
  "character_image": "assets/character.png",
  "scene_image": "assets/scene.png",
  "character_description": "一段自然语言描述",
  "scene_description": "一段自然语言描述",
  "visual_defaults": "一段自然语言描述",
  "presentation_defaults": "一段自然语言描述",
  "staging_defaults": "一段自然语言描述"
}

示例中的 .png 只表示字段格式;实际文件名保留复制后图片的真实扩展名,且两个路径必须与 profile/assets/ 中的文件一致。

开始一次视频任务

进入本阶段前必须再次确认完整 Profile 已存在且其中引用的图片可读取;否则返回 Gate0,不得询问单次任务信息。确认后才获得用户内容和目标时长。内容可以是高度凝练的笔记、完整脚本、粘贴的上下文或可读取的本地文件。从本次请求中提取受众、讲解深度、措辞保留程度和特殊表达要求;用户未说明时使用 presentation_defaults 合理推断。只有尚未解决的歧义会显著改变文稿时才向用户提问。

使用精确到秒的本地时间,在当前工作目录下创建:

text
hologram-video-runs/YYYYMMDDHHMMSS/
├── run.json
├── script.md
├── storyboard.json
├── prompts/
├── ref2v-tasks.json
├── clips/
└── final.mp4

如果同一时间戳目录已经存在,追加一个简短数字后缀,不得覆盖已有目录。

保持 run.json 最小化:

json
{
  "created_at": "YYYY-MM-DDTHH:mm:ss",
  "status": "awaiting_gate1",
  "target_duration": 30,
  "script_path": "script.md",
  "storyboard_path": "storyboard.json",
  "final_path": "final.mp4"
}

status 只允许使用 awaiting_gate1awaiting_gate2awaiting_gate3generatingfailedcomplete。每次直接覆盖当前状态,不保存状态历史。

Gate1:确认口播文稿

从用户提供的信息中提炼并改写出约为目标时长的口播文稿。严格受输入来源约束:可以重组、澄清、简化和使用类比,但除非用户明确要求研究,否则不得联网补充或虚构新事实。遇到实质性矛盾或关键缺失时,应当指出问题,不得猜测。

生成文稿前,先按目标秒数计算整篇口播预算:

  • 理想写作区间为每秒 4.6–5.0 个口播单元。
  • 允许进入 Gate1 的区间为每秒 4.2–5.2 个口播单元。
  • 每秒大于 5.2 时必须精简;每秒大于 5.8 属于严重超量,必须重新改写。
  • 每秒少于 4.2 时应补充有效讲解内容;如果用户明确想保留慢节奏、长停顿或大量无台词表演,先说明影响并获得确认。

口播单元的计算规则与 Gate2 完全相同。按预算起草后,先把候选口播正文写入 script.md;文件中不得加入标题、字数、时长说明或其他非台词内容。然后在本次运行目录执行:

bash
python3 <skill-dir>/scripts/check_dialogue_density.py \
  --script script.md \
  --target-duration <target-seconds>

检查未通过时,不得展示 Gate1;根据结果扩写或精简候选文稿并重新运行。不得为了满足预算引入来源中不存在的事实。唯一例外是检查结果为 TOO_SHORT,且用户已经在 Gate1 之前明确确认采用慢节奏、长停顿或较多无台词表演;除此之外,只有检查通过后才能进入 Gate1。

Gate1 只展示目标时长和完整文稿。用户要求修改时,先把修改后的完整正文覆盖写入 script.md 并重新运行整篇检查;检查通过且用户明确确认后,才把运行状态更新为 awaiting_gate2。因此进入 Gate2 的 script.md 始终是完全一致的最终确认稿。

Gate2:确认 H3 分镜

先按照完整的语义边界,把 Gate1 已确认的 script.md 切分为逐段台词:

  • 每段时长必须是 8–15 秒的整数,优先选择 10–12 秒。
  • 尽可能让一句话完整保留在同一个片段中。
  • 如果一句话明显过长,应在 Gate1 阶段缩短,而不是跨片段拆分。
  • 每段对应一个独立生成的视频,内部只有一个连续的 [Shot 1],不得再次切镜。
  • 在相邻片段之间改变视角、构图、景别和角色站位;片段之间直接硬切。

先创建 storyboard.json,使用顶层数组。每个元素只包含以下四个字段:

json
{
  "id": "001",
  "duration": 10,
  "dialogue": "本分镜中角色说出的完整台词。",
  "prompt_path": "prompts/001.txt"
}

dialogue 必须来自 Gate1 已确认文稿,并且是该分镜唯一的台词来源。所有分镜的 dialogue 按编号连接后,必须与 script.md 的内容和顺序一致;只允许按分镜边界拆分,不得在这一阶段改写、增删或润色。storyboard.json 不保存口播单元数、密度、建议时长或检查状态等派生字段。

所有分镜的 duration 之和必须尽量等于 run.json 中的 target_duration,允许最多 10% 的计划误差。如果受 8–15 秒整数片段限制而无法满足,应在 Gate2 前向用户说明并确认新的目标时长,不得静默改变最终计划。

台词密度检查

直接对 storyboard.json 中每个分镜的 dialogue 计算口播单元:

  • 每个中文字符记 1 个单元。
  • 每个连续英文单词、英文缩写或数字组记 1 个单元。
  • 标点和空格不计入单元。
  • 台词密度等于口播单元总数除以该分镜的设定秒数。

使用以下阈值:

  • 推荐区间:每秒 4.2–5.2 个单元。
  • 警戒区间:大于 5.2 且不超过 5.8。只有句式简单、视觉状态变化较少时才可保留。
  • 硬上限:每秒 5.8 个单元。超过时不得继续生成提示词,必须延长时长、缩短台词或拆分分镜。优先延长或拆分;如果缩短台词会改变 Gate1 确认稿,必须先把修改交给用户确认。
  • 枚举较多、专业词较多或全息状态变化较多时,目标密度应不高于每秒 5.0 个单元。

规划时可用 向上取整(口播单元 ÷ 5.0) 得到建议时长,再限制在 8–15 秒内;结果超过 15 秒时必须缩短或拆分。

在本次运行目录执行:

bash
python3 <skill-dir>/scripts/check_dialogue_density.py \
  --storyboard storyboard.json \
  --target-duration <target-seconds>

<skill-dir> 只表示运行时解析得到的 Skill 目录,不得把安装位置的绝对路径写进持久化文件。检查出现 FAIL 时必须修正 storyboard.json 并重新运行;出现 WARNING 时必须结合句式和视觉动作负载复核,不能直接忽略。只有检查通过,或警戒项完成复核后,才能生成 H3 提示词。

全片场景调度与多样性

通过台词密度检查后,读取 staging_defaults,把全部分镜作为一个整体规划,而不是逐段孤立选择构图。

  • 普通站立讲解始终是有效的基础方式,不要求每段都使用场景锚点。
  • 根据各段知识语义,选择适合的高价值调度能力及其场景锚点;不得为了变化而使用参考图中不存在或空间关系不可信的物件,也不得总是优先选择最容易联想到知识展示的信息设备。
  • 将 Profile 中共享核心物件、空间位置或全息承载区域的一组行为视为同一个锚点簇。更换同一锚点簇内的行为不等于更换了核心场景锚点,但独特的姿态、朝向、讲解状态或动作阶段变化仍属于有意义的行为多样性,不得在合并或规划时丢失。
  • 判断两个调度是否重复时比较完整可观察配置,包括身体支撑、姿态性质、角色与锚点的朝向关系、活动状态、互动对象和全息承载机制;不得只比较动作动词。
  • 状态变化不是每个分镜或锚点的必备项。只有参考图明确支持、变化确实由锚点造成、能够在安全构图内完成,并且相对于其他分镜带来新增价值时才采用;否则使用稳定姿态、操作状态或手势互动即可。
  • 确实采用状态变化时,在提示词中明确可观察的起始状态、由锚点支持的连接动作和结束状态;“改变朝向”“状态切换”等抽象标签本身不是分镜设计。优先描述角色相对于锚点的关系如何变化,不得把“固定正面”等通用机位结果持久化为调度能力。
  • 在全片中尽可能提高场景锚点、角色行为、人物位置、朝向、全息方位和安全机位的多样性。
  • 存在合适替代方案时,避免相邻分镜同时重复核心场景锚点和角色行为。必须复用时,从人物位置、朝向、动作阶段、全息方位或安全机位等其他维度制造明显差异。
  • 场景调度应当通过角色动作、信息来源或承载空间,与全息知识互动形成可信关系;不得用无关的场景动作取代本 Skill 的核心特点。
  • 知识表达、人物清晰度和生成稳定性始终高于形式上的不同。片段确实不适合场景锚点或全息因果互动时,不得强行加入。

这一规划只用于指导后续英文 H3 提示词。不得向 storyboard.json 增加调度字段,也不得创建调度清单、评分、配额或结构化重复检查脚本。全部提示词完成后,必须把它们作为一组复核整体多样性与跨片段声音一致性,再提交 Gate2。

构图安全区

视频模型会在主体或信息元素占画面比例过小时丢失身份、面部、肢体和文字细节,因此所有分镜必须从第一帧到最后一帧持续满足以下构图约束:

  • 角色默认采用肩部以上的特写(close-up)构图;需要为较大幅度的手部动作或互动对象保留更多画面空间的分镜,可以放宽到近景(medium close-up),但不得再远。不得把中景(腰部以上)、中远景、远景、全身构图或完整环境总览作为角色讲解镜头。
  • 开场构图必须已经位于安全景别内,不能依赖后半段推镜才让角色变清晰。
  • 角色的脸部必须持续处于清晰、显著的画面区域;用于互动的手部在互动发生时必须清晰可见,可以抬入画面或位于画面下缘,其余时刻允许画面只保留脸部与肩部。
  • 用画面占比复核景别,而不只依赖景别名称:视频模型实际出图通常小于提示词声明的占比,因此提示词中按脸部约占画面高度 40% 来写,从第一帧到最后一帧都不得声明更低。
  • 在提示词中用否定表述锁定景别下限:腰部及以下不得进入画面,场景中的家具、陈列与环境总览不得成为画面主体,最多出现在画面下缘。
  • 完整 Profile 仍用于保持角色身份,但 detailed_description 只能强调当前安全构图中实际可见的特征,不得为了展示完整造型而扩大景别。
  • 允许小幅推近、横移、摇摄、俯仰或环绕;任何时刻都不得拉远出近景范围,即不得退到中景或更远。分镜变化主要来自机位角度、角色左右位置、视线方向、全息元素方位和互动动作,而不是扩大景别。
  • 当前承载知识的主要全息信息单元应位于角色手部附近的前景或中景,建议至少占画面宽度约 25%,不得缩成远处背景装饰。
  • 如果 Profile 中某个承载位置无法与角色动作同时纳入安全构图,保留可信的场景锚点和动作关系,把全息信息调整到该锚点附近稳定可见的区域;不得为服从低位或不可见的承载位置而扩大景别。
  • 同一时刻优先突出 1–2 个主要信息单元。多步骤内容采用依次出现、当前项放大、已讲项弱化的方式;不得为了同时容纳全部信息而缩小角色或主要全息元素。
  • 如果角色与全部必要信息无法同时在安全构图内保持清晰,应拆分分镜,不得退回宽景解决空间不足。

在 H3 的英文 detailed_description 中明确写出:角色全程保持 close-up(肩部以上)构图,或在本分镜允许时放宽到 medium close-up,脸部大而清晰、约占画面高度五分之二,开场第一帧即满足该占比;并说明相机全程不会拉远到中景或更宽的画面,腰部及以下与环境总览不进入画面主体。任何房间布局、完整外观或信息总览要求都不得覆盖这项约束。

台词动词与全息互动

口播台词中的动词是全息互动最容易出彩的来源。写每段提示词前,检查该段 dialogue 中是否存在适合转译为全息互动的动词;存在时,把它设计为该段的亮点节拍。

适用判定。动词必须在语义上能以全息信息为作用对象,并能转译为可见的手部或身体动作,例如“拿出来、写进去、压缩、展开、拆开、堆叠、对比、翻转”。抽象静态动词(认为、意味着、代表)、纯言语动词(说、告诉、说明)和弱指向动词(看、指)不适用;弱指向属于通用手势,不构成亮点。动词作用于场景中实体锚点(而非全息信息)时,按场景调度处理,不适用本节。

设计方法。动词互动必须与台词中该动词说出的时刻同步:在 detailed_description 中写清当 <Subject 1> (S1) 说到该词时动作发生,并按起始状态 → 手部动作 → 全息结束状态的顺序描述;角色在动作过程中保持自然讲述。互动是段内的一个节拍,不拖满全段,其余时间保持稳定讲解。每段至多一个主动词互动;多个候选时选与知识关系最强、动作最可见的一个。动词互动是角色与全息信息因果互动的优先实现方式;没有合适动词时退回既有规则,不得强制。

约束

  • 动作必须能在构图安全区内可信完成,互动手部位于画面可见区域;需要大幅度手臂动作或低位空间才能完成的动词,放弃互动改用稳定手势。
  • 互动复用该段当前的主要全息信息单元,不为动作新增信息单元。
  • 不得为制造互动改写、增删已确认台词。
  • 全片复核多样性时,相邻分镜不得重复同一种动词互动类型;台词动词相近时,改变手部动作、全息响应方式或互动方位。

Few-shot 示例(只说明判定与写法,不构成固定映射;同一动词在不同分镜中应根据当前全息内容重新设计动作)。

正面:

  • 台词“我们把这个概念拿出来看看” → as <Subject 1> (S1) says "拿出来", she reaches into the floating holographic cluster near her hand and pulls one glowing panel forward into the foreground, where it settles enlarged beside her face.
  • 台词“把结果写进去” → as <Subject 1> (S1) says "写进去", she traces a short stroke toward the holographic panel, and a new line of text inscribes itself onto the panel under her fingertip.
  • 台词“这些信息被压缩成一个指标” → as <Subject 1> (S1) says "压缩", she brings both hands inward, and the scattered holographic blocks shrink and merge into a single compact readout between her palms.

反面(忽略,不设计互动):

  • “我们看一下这个数据” —— 弱指向动词,用常规视线与手势即可。
  • “这意味着更高的效率” —— 抽象静态动词,没有可转译的物理动作。
  • “我告诉你一个规律” —— 纯言语动词,动作与全息信息无关。

通过台词密度检查后,必须明确告诉用户正在使用 h3-prompt-writing Skill。加载该 Skill 及其完整参考模式 Ref2VA 指南,遵循其当前字段名、章节顺序、标签、时间规则和细节要求。不得凭记忆复制或近似复现外部规则,也不得用脚本拼接、替换或注入 H3 提示词。

对于每个片段:

  • 使用复制后的角色图作为参考图 1,场景图作为参考图 2。
  • 把来自 <Picture 1> 的讲解角色定义为 <Subject 1>,把来自 <Picture 2> 的环境定义为 <Subject 2>
  • 在提示词中充分复现角色、场景、视觉和讲解风格描述,确保每个片段都能独立获得参考约束,不得依赖其他片段的提示词上下文。对于 staging_defaults,只写入本段实际选择的场景调度方式,不得在每个提示词中枚举所有未使用的可能性。
  • 角色开口时始终标记为 <Subject 1> (S1)
  • storyboard.json 中本段的 dialogue 作为唯一台词来源,由 h3-prompt-writing 按其当前规范写入对应的 <d>[Language] ...</d>。不得改写词句;只允许该 Skill 明确要求的语言标签和标点规范化。
  • H3 的六个提示词章节全部使用英文;台词、专有名词和画面可见文字保留原语言。
  • 使用 Profile 中的讲解偏好描述声音表现、表情和动作;所有片段的声音描述逐字一致,演绎修饰仅限外放型情绪,禁止耳语、悄话等改变发声方式的描述。
  • 内容适合时,优先设计角色与全息信息之间清晰可见的因果互动;片段没有适合承载的内容时,不得强行加入互动。
  • 如果图表、模型、对比、过程或高亮概念能够传递知识,就不要只生成装饰性全息效果。
  • 文字仅当本身就是知识负载(关键数字、公式或核心术语)时才允许出现在全息信息中,装饰性标签、标题和列表文字一律用图形代替;出现的文字字形高度不得低于画面高度的三分之一,每个分镜至多一个文字元素,中文、英文与数字统一适用该阈值。
  • 提示词中不得出现 emoji 字符,所需图形一律用文字描述;也无需在提示词中写入“不使用 emoji”之类的否定声明。
  • 包含角色台词、合适的环境底噪和克制的全息交互音效。
  • 明确禁止背景音乐,并写入 non_diegetic_music: N/A

把完整英文提示词依次保存为 prompts/001.txtprompts/002.txt 等文件,并保持每个 prompt_path 与实际文件一致。台词密度只根据 storyboard.json 中的结构化 dialogue 校验;提示词中的台词一致性由 Agent 对照 storyboard.json 进行语义复核,不得反向解析或用脚本改写提示词。

Gate2 只展示每段的编号、时长和英文提示词路径。不得创建中文提示词或中文审阅译文。等待用户确认后,把状态更新为 awaiting_gate3

查找生成能力并执行 Gate3

Gate2 确认后,检查当前可用 Skills,查找能够根据多张本地参考图和提示词生成视频的能力。不得硬编码任何生成视频 Skill 的名称。

  • 如果没有找到,说明流程必须依赖一个多参考图生成视频 Skill,并终止后续流程。
  • 如果只找到一个,选择该 Skill。
  • 如果找到多个,列出它们的名称和实质差异,让用户选择。
  • 加载用户选定的 Skill,遵循其输入、批处理、重试和输出规则。不得自行重新实现它的上传、轮询、重试或下载逻辑。

按照选定 Skill 的要求生成 ref2v-tasks.json。文件内使用相对于本次运行目录的路径,并从该运行目录调用生成流程。所有任务使用相同的参考图顺序:角色图在前,场景图在后。将返回的成功片段保存或规范化为 clips/<id>.mp4,确保最终顺序确定。

Gate3 展示分镜数量、各段计划时长之和、两张参考图路径、片段目录和最终视频路径。必须等待用户明确确认,才能进行任何外部生成调用。

生成、失败恢复与拼接

Gate3 确认后,把状态更新为 generating,并通过选定的生成 Skill 提交任务。

部分任务失败时保留已经成功的片段,绝不拼接不完整的视频。允许选定的生成 Skill 执行其文档规定的内部重试;内部重试全部耗尽后,将状态更新为 failed,报告失败分镜编号和错误,并等待用户确认后才能再次发起可能产生费用的生成调用。修复得到确认后,只修改失败的提示词或任务,除非用户明确要求扩大修改范围。

storyboard.json 中的所有编号都有可读取的规范化片段时,执行:

bash
python3 <skill-dir>/scripts/concat_videos.py \
  --storyboard storyboard.json \
  --clips-dir clips \
  --output final.mp4

上面的 <skill-dir> 表示运行时解析得到的本 Skill 目录;不得把该占位符或安装位置的绝对路径写入持久化产物。

拼接脚本执行硬切;必要时把不兼容的片段统一为 H.264/AAC,并验证结果可读取。脚本不得添加转场或音乐,也不检查最终时长。保留所有原始片段。成功后把状态更新为 complete,并告知用户最终本地路径。

用户要求的修改

严格按照用户要求执行修改。不得自行设计自动失效、回退或版本规则,也不得推翻用户指定的修改范围。如果修改需要重新调用外部生成能力,先展示更新后的生成范围,并在调用前获得用户确认。