最近几个月,我一直在折腾 AI 视频剪辑的自动化流程。从最早直接用对话窗口丢提示词,到后来尝试各种 Agent 串联,最终让我真正觉得“能稳定复现、能交到项目里用”的,反而是很多人忽略的 Skill 机制。这篇文章不是来介绍某个新产品的,而是想把我已经反复跑通的 3 个自动化剪辑 Skill 拆开讲清楚:它们解决什么问题、目录结构长什么样、每一步怎么执行、以及实际运行时最容易卡在哪儿。
先给一个明确判断:AI 自动化剪辑的关键,不在于大模型多聪明,而在于你有没有把剪辑经验固化成一套可复用的 Skill。如果你还在靠每次写一大段提示词让 AI“自由发挥”,那结果不稳定是必然的。Skill 的本质,是把剪辑师的工作流程、判断标准、输出格式全部封装成结构化指令,让 AI 每次都在同一套规则下干活。
这篇文章适合这几类读者:
- 已经在用 AI 辅助剪辑,但觉得结果不稳定、每次都要反复调提示词的人。
- 想把素材筛选、脚本分镜、时间线生成这些重复劳动交给自动化,但不知道从哪下手的人。
- 刚接触 Skill 概念,想知道它和普通提示词到底有什么区别的人。
我会从基础概念讲起,然后逐个拆解我跑通的 3 个 Skill,最后给出完整目录结构和代码示例。你可以直接把我的目录结构拿走改,不用从零开始。先说明一点,下面所有配置都基于 Skill 机制的通用水位,具体工具版本以你手头的实际环境为准,但核心思路是通用的。
1. 先搞清楚:Skill 和普通提示词到底差在哪
很多人以为 Skill 就是“把提示词写长一点”,这是一个很大的误解。普通提示词是一次性的对话上下文,你给 AI 一段文字,它基于这段文字生成回复,聊完就结束了。Skill 则是一套可复用的执行规范,它不只是告诉 AI“做什么”,还规定了“按什么流程做”“每个步骤输出什么格式”“遇到异常怎么处理”。
打个比方:你让一个实习生帮你剪辑,普通提示词相当于口头交代一句“把这些素材剪成一条片子”,实习生可能理解成各种样子。Skill 则相当于你给他一份《剪辑操作手册》,里面写了素材筛选标准、脚本拆解规则、时间线结构要求、导出参数,甚至包括常见的错误处理方式。实习生只要按手册执行,结果就稳定得多。
在当前的 AI 工具生态里,Skill 一般以目录的形式存在,核心入口是一个SKILL.md文件。这个文件用结构化 Markdown 描述技能的目标、适用场景、执行步骤、输入输出格式。工具加载 Skill 后,会把里面的指令作为系统级的上下文注入,让模型在固定规则下完成工作。有的实现还支持配套脚本,比如用 Python 读取视频元数据、调用 FFmpeg 完成转码,这些脚本可以放在 Skill 目录下的scripts/文件夹中。
更关键的一点是,Skill 可以被多个 Agent 或工作流重复加载。你今天让 AI 做一条带货视频,明天做一条科普视频,只要剪辑的底层流程一致,就复用同一套 Skill。改动一次规则,所有后续任务都生效。这种“一次封装、处处复用”的特性,才是 Skill 真正降低剪辑成本的原因。
2. 我跑通的 3 个 Skill 分别是什么
我做的这 3 个 Skill,是一条完整的自动化剪辑流水线,覆盖了从拿到原始素材到生成粗剪时间线的核心环节。
第一个是素材筛选 Skill,我把它命名为ShotFilter。它的工作是面对几十上百条原始视频片段,自动判断哪些片段是有效素材,哪些是废镜头。所谓有效,不只是“画面不黑、声音不杂”,还包括构图有没有明显问题、镜头有没有大幅抖动、主体是否完整入画。这个 Skill 会调用视频分析脚本,从时长、分辨率、帧率、音轨信息入手,再结合模型对抽帧画面的视觉判断,给出“可用/疑似可用/不可用”的标签,并附上理由。
第二个是脚本拆解 Skill,命名为ScriptToStoryboard。输入是一段视频文案脚本,输出是一个结构化的分镜表。它会把文案按语义拆成多个镜头,每个镜头分配景别、时长、画面描述、字幕文案和备注。这个 Skill 解决的核心痛点是:剪辑师拿到文案后,往往要花大量时间把文字转成镜头语言,而这个转换过程恰恰是最能体现经验的地方。我把判断标准写进 Skill 规则里,比如一段话超过多少字就该拆成两个镜头、什么位置的停顿适合切特写、什么语境下适合用空镜过渡。
第三个是时间线生成 Skill,命名为TimelineBuilder。它接收分镜表作为输入,生成一个可以直接导入剪辑软件的 XML 或 EDL 文件,同时生成对应的剪辑指令清单。这个 Skill 不需要 AI 自己去渲染视频,而是把分镜表中的每个镜头和素材筛选结果做匹配,在时间线上排好顺序、设定好每段片段的入点出点,并标注需要添加转场或特效的位置。粗剪的效率提升主要靠这一步。
这三个 Skill 的依赖关系是这样的:原素材先经过 ShotFilter 筛选,得到可用素材清单;文案脚本经过 ScriptToStoryboard 拆解,得到分镜表;最后 TimelineBuilder 把素材清单和分镜表做匹配,产出可直接用的时间线文件。我实际跑通后的感受是,最难的并不是让 AI 生成某个具体片段,而是让这三个环节之间的数据格式能对齐。所以我在每个 Skill 里都严格定义了输出格式,这一步非常重要。
3. Skill 目录结构与输入输出约定
在动手写规则之前,先把目录规范定下来。下面是我常用的 Skill 组织方式:
skills/ ├── shot-filter/ │ ├── SKILL.md │ ├── scripts/ │ │ ├── probe_video.py │ │ └── check_frame.py │ └── assets/ │ └── criteria.md ├── script-to-storyboard/ │ ├── SKILL.md │ └── assets/ │ └── shot_types.md └── timeline-builder/ ├── SKILL.md └── scripts/ └── build_edl.py每个 Skill 目录下的SKILL.md是入口文件,里面用name、description、when_to_use、instructions等字段来描述这个技能。scripts/目录存放可执行的辅助脚本,比如用 FFprobe 探测视频基本信息、用 Python 处理 EDL 文本。assets/目录存放被引用的规则文档,比如判断素材好坏的详细标准、景别定义表。
关于输入输出,我会为每个 Skill 定义一个明确的契约,也就是输入是什么格式、输出是什么格式。以 ShotFilter 为例:
- 输入:一个目录路径,里面是要分析的视频文件,也可以是一个 CSV 清单,包含文件名和路径。
- 输出:一个 JSON 文件,每条素材包含
file_name、duration、resolution、has_audio_track、verdict、reason字段。
把输入输出格式定死的好处是,后续可以在多个 Skill 之间传递数据,组合成更长的自动化流水线。AI 在处理时不需要猜测该输出什么,直接按模板填充即可。这在工程上非常关键,因为自动化的价值不是某个环节单点变快,而是整个链路能稳定打通。
4. 环境准备:我用了哪些工具和依赖
先把环境说清楚。我的运行环境是 macOS,终端使用 zsh,Python 版本为系统自带的 Python 3,额外安装了以下 Python 包:
openai:用于调用大模型接口做画面分析和文本分析。ffmpeg-python:封装 FFmpeg 命令,用于视频抽帧和元数据读取。pydantic:做输出数据的结构校验,避免模型返回的 JSON 字段缺失。
如果你需要调用视觉模型来分析视频帧,还需要准备一个可用的模型 API Key。注意不要把 Key 写死在 Skill 脚本里,建议通过环境变量传入,比如export LLM_API_KEY="xxxx"。这里也提醒一下,你的 Key 要妥善保管,不要提交到公开仓库。
FFmpeg 本身也需要安装。如果你用的是 macOS 且装了 Homebrew,可以直接执行:
brew install ffmpeg测试 FFmpeg 是否安装成功:
ffmpeg -version如果输出中包含版本信息,说明安装正常。另外,视频分析脚本会调用 FFprobe 获取视频流信息。FFmpeg 安装后 FFprobe 一般会同时可用,可以通过下面命令确认:
ffprobe -version关于 AI 工具的选择,我使用的是支持 Skill 机制的 CLI 编程工具(比如 Claude Code、Codex CLI 这类工具都开始支持类似机制)。不同工具对 Skill 的加载方式略有差异,有的通过@技能名的语法引用,有的通过自动扫描目录加载。具体以你使用的工具文档为准。下面我示例中会采用通用的 Markdown 指令格式,任何支持结构化技能注入的工具都可以参考。
5. 第一个 Skill 的完整实现:素材筛选
5.1 构建 SKILL.md 规则文件
我创建skills/shot-filter/SKILL.md,内容如下:
--- name: shot-filter description: 批量分析视频素材,判断画面是否可用,输出带 verdict 标签的 JSON 清单。 when_to_use: 当用户提供一批原始视频素材,需要筛选出有效片段时使用。 --- # Shot Filter 你的任务是对输入目录中的视频素材逐条分析,输出标准 JSON。 ## 分析步骤 1. 遍历输入目录下的所有视频文件(支持 mp4、mov、mkv)。 2. 使用 scripts/probe_video.py 获取每个视频的时长、分辨率、帧率、音轨信息。 3. 对每个视频,在时间轴中段抽取 3 帧画面,调用视觉模型判断画面质量。 4. 结合元数据和画面判断,给出 verdict。 ## 判断标准 - verdict 为 "usable" 的要求:时长不少于 3 秒;画面无明显抖动;主体完整入画。 - verdict 为 "needs_review" 的要求:画面基本清晰,但存在轻微晃动、光线不均或遮挡。 - 不属于以上情况的,标记为 "rejected",并写明原因。 ## 输出格式 只输出 JSON 数组,不要输出额外说明。示例: [ { "file_name": "take_01.mp4", "duration": 12.3, "resolution": "1920x1080", "has_audio_track": true, "verdict": "usable", "reason": "构图完整,画面稳定,音轨正常" } ]这里我将 AI 的判断标准显式写入进 SKILL.md,这样模型不会再凭自己的感觉随意评价。特别要注意最后一句“只输出 JSON 数组”,避免模型在输出里夹杂解释性文字,导致下游脚本解析失败。
5.2 编写视频探测脚本
接下来创建skills/shot-filter/scripts/probe_video.py,用 FFprobe 获取视频的基础信息:
#!/usr/bin/env python3 import json import sys import subprocess def probe_video(file_path: str) -> dict: cmd = [ "ffprobe", "-v", "quiet", "-print_format", "json", "-show_format", "-show_streams", file_path ] result = subprocess.run(cmd, capture_output=True, text=True) if result.returncode != 0: return {"error": result.stderr.strip()} data = json.loads(result.stdout) video_stream = None audio_stream = None for stream in data.get("streams", []): if stream.get("codec_type") == "video" and video_stream is None: video_stream = stream elif stream.get("codec_type") == "audio" and audio_stream is None: audio_stream = stream duration = float(data.get("format", {}).get("duration", 0)) return { "file_name": file_path.split("/")[-1], "duration": round(duration, 2), "resolution": f"{video_stream.get('width', 0)}x{video_stream.get('height', 0)}", "has_audio_track": audio_stream is not None } if __name__ == "__main__": for path in sys.argv[1:]: print(json.dumps(probe_video(path), ensure_ascii=False))这个脚本本身不复杂,但它把“获取视频元信息”这一步从模型能力中抽离出来,变成确定性执行,避免模型对时长和分辨率产生幻觉。在实际项目中,我更推荐这种混合方式:能用脚本确定性算出来的,就不要让模型用视觉去猜。
5.3 调用方式与运行验证
当 Skill 被加载后,你可以在支持的 CLI 工具中这样调用:
@shot-filter /path/to/raw_materials工具会分析/path/to/raw_materials目录下的视频文件,并返回 JSON 格式的筛选清单。如果希望在单条命令中看到结果,可以直接让工具读取脚本输出并生成最终 JSON。
我实际运行时的预期输出大致如下:
[ { "file_name": "take_01.mp4", "duration": 12.3, "resolution": "1920x1080", "has_audio_track": true, "verdict": "usable", "reason": "构图完整,画面稳定,音轨正常" }, { "file_name": "take_02.mp4", "duration": 2.1, "resolution": "1280x720", "has_audio_track": false, "verdict": "rejected", "reason": "时长不足3秒且缺少音轨" } ]判断这个 Skill 是否真正生效,不是看它有没有输出 JSON,而是看两个点:第一,对于明显不合格的素材(比如时长过短、没有音轨),它是否稳定给出rejected;第二,对于画面质量相近的素材,它给出的 verdict 是否一致。如果你发现同一个素材不同次调用结果不同,说明判断标准没有写清楚,需要回到SKILL.md里补充更细的规则。
6. 第二个 Skill 的完整实现:脚本拆分为分镜
6.1 分镜表的结构设计
分镜表是连接“文案”和“成片”的中间产物。在自动化剪辑里,分镜表必须能够被下游程序直接解析,所以不能用自由文本,而要用结构化格式。我定义的分镜表是一个 JSON 数组,每个元素代表一个镜头:
[ { "shot_id": 1, "narration": "大家好,今天我们来聊聊如何提高视频剪辑效率。", "visual": "主播正面中景,背景为工作台", "shot_type": "medium", "duration": 5.0, "subtitle": "今天我们来聊聊如何提高视频剪辑效率", "notes": "开场镜头,背景干净,光线充足" } ]字段说明:
shot_id:镜头序号,从 1 开始递增。narration:这个镜头对应的解说词原文。visual:画面内容描述,方便素材匹配。shot_type:景别,如close-up、medium、wide、cutaway。duration:预计时长,单位为秒。subtitle:用于渲染字幕的文本,一般比解说词更精简。notes:剪辑备注,比如是否需要转场、是否需要背景音乐切入点。
为什么要用 JSON 而不是直接输出表格?因为后续 TimelineBuilder 需要读取分镜表来生成时间线,JSON 可以直接被 Python 解析,而表格还需要额外转换。一句话,自动化流水线里,数据格式统一比人类阅读友好更重要。
6.2 SKILL.md 中的拆解规则
下面是skills/script-to-storyboard/SKILL.md的关键内容:
--- name: script-to-storyboard description: 将视频文案脚本转换为结构化的分镜表 JSON。 when_to_use: 用户提供文案脚本,需要生成剪辑分镜时使用。 --- # Script to Storyboard 将输入文案按语义拆分为多个镜头,并输出分镜表 JSON。 ## 拆解规则 1. 每段语义完整的话对应一个镜头,通常一段话的字数不超过 80 字,超过则拆分为多个镜头。 2. 文案中的“首先/然后/最后”等逻辑词,通常是切换镜头的信号。 3. 如果文案描述了具体动作(比如“点击按钮”“打开软件”),优先使用特写或近景。 4. 如果文案是背景介绍或总结,可以使用中景或全景。 5. 每个镜头时长建议在 3 至 8 秒之间,根据解说词长度估算,语速按每分钟 220 字计算。 ## 输出格式 只输出 JSON 数组,每个元素包含 shot_id、narration、visual、shot_type、duration、subtitle、notes 字段。这里我把“语速按每分钟 220 字计算”作为一个可复用的经验值写进规则。虽然不同主播语速不同,但剪辑时有一个基准值就能自动估算时长,后续再人工微调,比从零开始快很多。你也可以根据自己的内容类型调整,比如知识口播类可以稍快,教程操作类往往需要留出操作演示的时间。
6.3 运行示例
输入文案示例:
大家好,欢迎来到本期教程。今天我们要讲的是如何使用 AI 工具优化剪辑流程。首先,我们需要准备一批素材。其次,用脚本对素材进行批量分析。最后,把生成的结果导入剪辑软件。预期输出(节选):
[ { "shot_id": 1, "narration": "大家好,欢迎来到本期教程。", "visual": "主播正面中景,背景为工作台", "shot_type": "medium", "duration": 3.0, "subtitle": "欢迎来到本期教程", "notes": "开场镜头" }, { "shot_id": 2, "narration": "今天我们要讲的是如何使用 AI 工具优化剪辑流程。", "visual": "主播近景,语气强调 AI 工具", "shot_type": "close-up", "duration": 4.0, "subtitle": "使用 AI 工具优化剪辑流程", "notes": "可以配一个 AI 工具界面截图" } ]这里有个值得注意的点:模型的输出并不总是完全符合预期,有时会遇到shot_type取值不在预设列表内、duration明显不合理之类的情况。为了不让脏数据进入下游,我会在接收分镜表后加一个简单校验,比如用 Python 检查字段是否齐全、时长是否为数字。只要校验不通过,就重新调用 Skill 生成一次,直到通过为止。这个做法在工程上叫做“防御式处理”,在 AI 流程里尤其重要,因为你永远要假设模型的输出可能不符合规范。
7. 第三个 Skill 的完整实现:从分镜表到时间线文件
7.1 EDL 格式简介
时间线生成 Skill 的最终产物是一个 EDL(Edit Decision List,剪辑决策列表)文件。EDL 是一种纯文本格式,剪辑软件可以导入并重建时间线。一个最简单的 EDL 片段长这样:
TITLE: AUTO_CUT_PROJECT FCM: NON-DROP FRAME 001 AX 00:00:01:00 00:00:05:00 00:00:00:00 00:00:04:00逐行解释一下:
TITLE:项目名称。FCM:时间码制式,NON-DROP FRAME表示无丢帧时间码。001:剪辑序号。AX:源素材卷号,这里用AX表示来自自动匹配的素材。00:00:01:00 00:00:05:00:源素材的入点和出点。00:00:00:00 00:00:04:00:时间线上的入点和出点。
EDL 的历史非常悠久,几乎所有专业剪辑软件都支持导入,是一种很稳妥的交换格式。如果你用的剪辑软件对 EDL 支持不太好,也可以让 Skill 输出 CSV 或 JSON 格式的剪辑指令清单,人工在软件里快速照着排。这里我以 EDL 为例,因为它的自动化程度最高。
7.2 TimelineBuilder 的 SKILL.md
skills/timeline-builder/SKILL.md核心内容:
--- name: timeline-builder description: 根据分镜表和素材清单生成 EDL 时间线文件。 when_to_use: 已有素材筛选结果和分镜表,需要生成时间线时使用。 --- # Timeline Builder 你的任务是将分镜表和可用的素材片段进行匹配,生成 EDL 文件。 ## 执行步骤 1. 读取素材筛选结果 JSON,只使用 verdict 为 "usable" 或 "needs_review" 的素材。 2. 读取分镜表 JSON。 3. 根据 visual 描述和素材文件名中的关键词(如 take_01、scene_02)进行匹配。 4. 按 shot_id 顺序排列,设置入点出点。 5. 输出 EDL 文本,直接写入到输出文件。 ## 匹配规则 - 如果分镜表的 visual 包含“特写”或“近景”,优先匹配画面里有主体面部或手部特写的素材。 - 如果分镜表指定为“空镜”或“cutaway”,优先匹配风景、城市空镜头素材。 - 如果无法找到完全匹配的素材,用 resources 中 notes 为“可替代”的片段填充,并在输出的 EDL 文件名上添加 "_with_placeholder" 后缀。7.3 生成 EDL 的 Python 脚本
下面是一个简化版的 EDL 生成脚本:
#!/usr/bin/env python3 import json import sys def time_to_edl(seconds: float) -> str: hours = int(seconds // 3600) minutes = int((seconds % 3600) // 60) secs = int(seconds % 60) frames = int((seconds - int(seconds)) * 25) return f"{hours:02d}:{minutes:02d}:{secs:02d}:{frames:02d}" def build_edl(shots, output_path): lines = ["TITLE: AUTO_CUT_PROJECT", "FCM: NON-DROP FRAME", ""] total_time = 0.0 for idx, shot in enumerate(shots, start=1): src_in = shot.get("source_in", 0) src_out = src_in + shot["duration"] tl_in = total_time tl_out = total_time + shot["duration"] lines.append( f"{idx:03d} AX {time_to_edl(src_in)} {time_to_edl(src_out)} " f"{time_to_edl(tl_in)} {time_to_edl(tl_out)}" ) lines.append(f"M2 VIDEO {shot.get('shot_type', 'cut')}") lines.append("") total_time = tl_out with open(output_path, "w", encoding="utf-8") as f: f.write("\n".join(lines)) return output_path if __name__ == "__main__": shots_path = sys.argv[1] output_path = sys.argv[2] with open(shots_path, "r", encoding="utf-8") as f: shots = json.load(f) result = build_edl(shots, output_path) print(f"EDL written to {result}")将分镜表保存为storyboard.json后,运行:
python3 scripts/build_edl.py storyboard.json output.edl如果一切正常,你会得到output.edl,可以用支持 EDL 导入的剪辑软件打开。如果你手头没有这类软件,也可以用文本编辑器打开,检查时间码是否连续。这个 Skill 跑通后,从“分镜表”到“粗剪时间线”的转换就不再需要手动操作了。
8. 把 3 个 Skill 串成一条自动化流水线
前面 3 个 Skill 是独立的,但它们真正的威力在于串联。在实际项目中,我通常用下面这样的 Shell 脚本把它们串起来:
#!/bin/bash set -e RAW_DIR="/path/to/raw_materials" SCRIPT_TEXT="/path/to/script.txt" WORK_DIR="/tmp/auto_cut" mkdir -p "$WORK_DIR" # Step 1: 素材筛选 @shot-filter "$RAW_DIR" > "$WORK_DIR/shot_filter.json" # Step 2: 脚本拆解为分镜 cat "$SCRIPT_TEXT" | @script-to-storyboard > "$WORK_DIR/storyboard.json" # Step 3: 生成时间线 @timeline-builder "$WORK_DIR/storyboard.json" "$WORK_DIR/shot_filter.json" --output "$WORK_DIR/project.edl" echo "所有步骤已完成,时间线文件在: $WORK_DIR/project.edl"这段脚本的作用是把三个 Skill 按顺序串起来。这里我用@技能名的语法来表示调用对应 Skill;如果你使用的工具不是这种语法,只要按文档改成对应的加载方式即可。关键点在于每个步骤的输出都保存在WORK_DIR下,后续步骤通过文件路径读取,这样即使中间某一步失败,你也可以从断点继续,不需要从头再跑。对于较长的视频项目,这个能力很实用。
把这个脚本保存为auto_cut_pipeline.sh,然后执行:
chmod +x auto_cut_pipeline.sh ./auto_cut_pipeline.sh当最后出现EDL written to /tmp/auto_cut/project.edl时,说明流水线已经完整跑通。
9. 常见问题与排查方法
我在实际跑这几个 Skill 时,遇到过不少问题,下面列出的几个最有代表性:
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
| 素材筛选时视频全部被标记为 rejected | 视频路径错误或文件损坏,FFprobe 返回异常 | 手动执行ffprobe -v quiet -print_format json -show_format -show_streams 文件路径,查看返回内容 | 修正路径或替换正常视频文件 |
| 模型输出的 JSON 格式不合法 | 输出包含多余说明文字,或 JSON 字段缺失 | 将模型回复保存在文件中,用python3 -m json.tool校验 | 在 SKILL.md 中强调“只输出 JSON”,并增加输出样例 |
| 分镜表时长和实际文案长度不匹配 | 语速假设与实际情况差异较大 | 使用已知文稿和成片时长反推实际语速 | 调整 SKILL.md 中的语速参数,或者增加事后时长校准 |
| 生成的 EDL 在剪辑软件中打不开 | 时间码帧率与项目设置不一致 | 查看剪辑软件的时间和项目设置 | 在 build_edl.py 中根据项目帧率调整 frames 计算逻辑 |
| 同一个素材两次筛选结果不同 | 判断标准不够具体,模型自由度太大 | 对比两次输出,找出不稳定字段 | 在 SKILL.md 中细化判断标准,增加更多示例 |
这里最值得强调的一点是:模型的输出要当作“不稳定数据”来处理。每两个 Skill 之间的数据交换,都应该有校验环节。你可以用 pydantic 定义输出模型,也可以简单写一个validate.py脚本检查关键字段。不要假设模型每次都输出正确,这是所有 AI 自动化流程里最重要的工程思维。
10. 最佳实践与工程建议
在这个项目里,我总结了几条可以复用的经验,供大家参考。
第一,Skill 的粒度不要太大。我见过有人试图写一个“超级 Skill”来完成所有剪辑工作,结果规则太多,模型执行时经常前后矛盾。更好的做法是像我这 3 个 Skill 一样,每个只负责一个单一职责:筛选、拆解、生成时间线。单个 Skill 的规则控制在 10 条以内,效果最稳定。
第二,把确定性计算和模型判断分开。能用脚本计算出来的信息,比如视频时长、分辨率、帧率,不要依赖模型通过视觉去估算。模型的不确定性应该只用在真正的判断环节上,比如“画面构图是否完整”“这段文案适合什么景别”。这种混合架构既提高了准确性,也降低了 token 消耗和延迟。
第三,输出格式必须严格定义。每个 Skill 的输出都要有清晰的 schema,最好是 JSON,并且字段名、类型、取值范围都写清楚。你可以在 SKILL.md 里直接给一个完整的输出样例,模型通常会照着样例复刻格式,比单纯文字描述更可靠。
第四,给每个 Skill 都写 assets 文档。assets/shot_types.md、assets/criteria.md这些文档可以承载更详细的背景知识,避免 SKILL.md 过长。模型在需要时可以从目录中读取这些附件,不需要时不会浪费上下文窗口。对长文本场景尤其有用。
第五,版本管理一定要做。Skill 的规则可能经常调整,建议把整个skills/目录放进 Git 仓库。每次改动都提交一次,整理后可以比较不同版本对最终剪辑结果的影响。我踩过的一个坑是,改了一次判断标准后,素材筛选结果变化很大,但没有版本记录,根本不知道改了什么导致差异。
11. 这 3 个 Skill 目前的天花板和优化方向
说说我对这套方案局限性的判断。当前最大的瓶颈不是模型能力,而是素材匹配的准确度。TimelineBuilder 在匹配“分镜描述”和“实际素材”时,依赖的是文件名关键词和 visual 描述的文本相似度,但在真实项目中,拍摄素材的文件名往往没有任何语义信息,比如00123.MP4。这种情况下,匹配准确率会明显下降。要解决这个问题,需要在 ShotFilter 阶段让视觉模型给每个素材打上内容标签,比如“人物中景-看镜头”“手部特写-操作键盘”“空镜-街道夜景”,然后在匹配阶段用标签去检索。这也是我下一步打算优化的方向。
另一个优化方向是增加音频分析。目前的 3 个 Skill 只看画面和文案,没有分析原素材中的音频质量。比如某个片段画面很好,但背景噪音很大,或者说话声音爆音了,这需要音频分析脚本介入。可以在 ShotFilter 里增加一个analyze_audio.py,使用 FFmpeg 提取音频响度数据,或者直接调用音频模型做声音质量评分。这样筛选结果会更有参考价值。
12. 收起说明
我写这篇文章不是为了告诉你“AI 已经完全取代剪辑师”,而是想提供一个可落地的思路:把剪辑经验拆成有边界的、可复用的 Skill,让 AI 在固定规则里帮你完成重复度较高的工作。素材初筛、文案分镜、时间线生成这三个环节,恰恰是剪辑流程中最适合自动化的部分,也是我目前跑通后收益最大的三个环节。
如果你想动手试,我建议不要贪多,先只做一个最痛点的 Skill。比如你发现自己每天都在重复做“把一堆素材挑出可用的”,那就先抄 ShotFilter 这个目录,把判断标准改成你自己的习惯,跑通一天后自然就能感受到 Skill 的价值。之后再扩展到分镜和时间线。
每个 Skill 目录下的代码和规则,建议都保存到自己的代码仓库里。自动化剪辑这条路,后面拼的不是谁的提示词写得更华丽,而是谁把自己的工作方法沉淀得更系统。