让Agent看懂视频:基于Skill机制的claude-video视频理解方案
做Agent开发的朋友应该都有过这种经历:文本、图片、文档这些输入,现在的模型处理得都不错,但只要对方扔过来一个视频,Agent立马就蒙了。倒不是模型没这个能力,而是大多数Agent的工作流里压根没有“视频”这一个输入形态——你的Agent可能在读取PDF、解析网页、生成报告方面已经很熟练了,但面对.mp4文件时只能干瞪眼。我最近做一个内容分析类的Agent项目时被这个问题卡了很久,最后基于Agent的Skill机制做了一个叫claude-video的技能包,把“看视频”这件事拆成一条可复用的流水线:自动抽帧、语音转录、时间轴对齐,最终生成结构化的“视频脚本文本”交给Agent去推理。这篇文章就把它背后的设计思路、具体安装方式、实测效果和一些调优经验一次性讲清楚。正在做Agent开发、或者想给现有Agent加上视频理解能力的同学,可以直接照着做。
1. 先想明白:Agent的“视觉能力”不是让模型直接看视频
1.1 为什么不能直接把视频文件喂给模型
最直觉的方案是把视频文件直接作为一个输入丢给多模态模型。我最早也是这么试的,然后被现实教育了一顿。第一,当前的LLM上下文窗口虽然有扩展,但视频本质上是“24帧每秒的图像流+音频流”,直接传给模型意味着要把成千上万帧的画面都编码进去,token量轻松冲上几万甚至几十万,很多模型根本撑不住。第二,视频是多模态模型不太擅长的长序列任务——它可以准确描述单张图片,但面对几十秒甚至几分钟的视频,很难保持对“哪个画面在先、哪个事件在后”的空间一致性,经常出现逻辑混乱。第三,就算模型硬撑着处理了,响应时间也慢得离谱,而且按token计费的成本会让人肉疼。所以“视频直接进模型”在工程上是不现实的,至少不适合作为通用Agent能力。
那换个思路呢?视频信息可以拆成三个维度:画面内容、语音内容、时间关系。如果把这三个维度都提取出来,转换成语义密度高、带时间戳的文本,不就能复用文本型Agent最擅长的推理能力了吗?这就是claude-video这个Skill的出发点。
1.2 claude-video的核心思路:把视频翻译成Agent能读的“脚本文本”
说得直白一点,claude-video做的事就和“有人帮你看完视频后给你写了一份带时间轴的图文纪要”一样。Agent拿到的不是视频本身,而是这份纪要。纪要里包含三个部分:某个时间段画面里出现了什么、语音里说了什么、这两者发生在第几秒到第几秒。有了这份结构化的“脚本文本”,Agent就可以像分析一份文档一样去分析视频内容——总结要点、提取关键信息、回答关于视频细节的问题,甚至做跨时段的事件关联。
从项目结构上讲,claude-video不是一个视觉大模型,也不是一个视频处理框架,它就是一套针对Agent的Skill封装。Skill这个概念简单理解就是“给Agent额外配置的一组技能组合”,可以包含脚本、提示词模板、配置文件。调用时,Skill负责完成预处理,把视频变成结构化文本,再把结构化的中间结果交给Agent的推理层。这种分层的好处是解耦:视频处理管道的稳定性由脚本保证,而分析和推理的灵活性交给LLM,两边各自迭代,互不拖累。
2. claude-video的流水线拆解:抽帧、转录、对齐三步走
2.1 抽帧:不是抽得越多越好
抽帧是整个流水线的第一步,也是最容易用力过猛的一步。很多人一听“看视频”就想着每秒抽30帧,结果一个两分钟的视频抽出3600张图,光看图就看得眼花缭乱,丢给模型更是直接让上下文爆炸。实际使用下来,按场景选择抽帧频率才是最稳妥的。
我的默认配置是每秒1帧,对于大多数口播、访谈、产品介绍类视频已经足够。命令长这样:
ffmpeg -i input.mp4 -vf "fps=1,scale=1280:-2" -q:v 2 frames/frame_%04d.jpg
这里几个参数值得说明一下:
fps=1
表示每秒抽1帧;
scale=1280:-2
是把画面宽度缩放到1280像素,高度按比例自动计算,
-2
是为了保证高度是偶数,避免某些编码器报错;
-q:v 2
是JPEG输出质量,2在ffmpeg的尺度里属于高质量,既能保持画面细节又不会让文件大得离谱。
如果画面里文字占比较高(比如录屏、PPT讲解、代码演示),建议把宽度再调大一点到1920,这样OCR或者视觉模型在识别屏幕文字时才不会因为字太小而看错。反之,如果只是纯人物采访,1280足够了,再大纯属浪费。
2.2 视觉与听觉分路提取,两条腿走路
视频的视觉信息和听觉信息如果不分开处理,很容易互相干扰。我最初试过让一个多模态模型同时看帧画面和听转录文本,结果它在画面和语音之间反复横跳,要么过度关注画面忽略语音,要么被语音带偏。后来改成两条独立路径,效果稳定多了。
视觉路径负责逐帧生成画面描述。这里可以用带视觉能力的模型,比如Claude的多模态接口,逐帧调用,也可以用本地的视觉语言模型。逐帧调用要控制并发,避免被限流;本地模型则要处理好显存占用。我的做法是写一个批量脚本,把抽出来的帧按时间顺序排列,每张帧生成一句结构化的描述,尽量客观描述画面主体、文字信息和关键动作,不做过多的主观推测。
听觉路径用Whisper这类ASR工具做带时间戳的转录。先要从视频中提取出音频轨道:
ffmpeg -i input.mp4 -vn -acodec pcm_s16le -ar 16000 audio.wav
然后调用Whisper转录。
-ar 16000
把采样率统一到16kHz,这是Whisper最擅长处理的输入格式。转录结果里每一段都有start、end和text字段:
{
"segments": [
{"start": 0.0, "end": 5.2, "text": "大家好,欢迎收看本期产品评测"},
{"start": 5.2, "end": 12.8, "text": "今天我们拿到了最新的旗舰手机"}
]
}
2.3 时间轴合成:把画面和语音按时间码铆在一起
有了画面描述和语音转录,接下来最关键的一步是让两者按时间对齐。同步逻辑其实不复杂:每一帧图片在抽帧时都会记录下对应的时间点,而语音转录的每个段落也有起止时间,把前者归入后者所在的时间区间即可。我把合并后的结果设计成一个JSON数组,每个元素代表一个“时间段+画面+语音”三元组。
{
"duration": 320.5,
"timeline": [
{
"start": 0.0,
"end": 5.2,
"visual": "主持人站在演播台前,背后屏幕显示产品LOGO",
"audio": "大家好,欢迎收看本期产品评测"
},
{
"start": 5.2,
"end": 12.8,
"visual": "主持人手持手机,镜头特写背部摄像头模组",
"audio": "今天我们拿到了最新的旗舰手机"
}
]
}
生成这种结构之后,Agent的推理层拿到的是完整的“视频脚本文本”。它知道第几秒画面发生了什么、人物说了什么,后续无论你是让它做摘要、找关键信息点、还是回答指定的问题,它都有据可依。对齐这一步是整个Skill里最不起眼但最重要的部分——时间信息一旦错位,后面所有分析都会跟着出错。
3. 动手集成:从零把一个视频Skill挂载进你的Agent
3.1 Skill的目录结构与入口文件
如果你熟悉当前主流的Agent Skill生态,会发现它的基本单位是一个目录:里面有一个描述文件、若干脚本和提示词模板。claude-video我也按这个习惯组织:
claude-video/
├── SKILL.md
├── config.yaml
├── requirements.txt
├── scripts/
│ ├── extract_frames.py
│ ├── transcribe_audio.py
│ └── build_timeline.py
└── prompts/
└── video_analysis.md
SKILL.md是整个Skill的入口描述文件,Agent框架读取它来识别这个Skill能做什么、怎么调用。里面通常包含名称、描述、版本号和可执行入口等信息。config.yaml放可调参数,比如抽帧的fps、图片缩放宽度、是否启用场景检测等。scripts目录放三个核心脚本,prompts目录放给LLM的分析提示词模板。
3.2 依赖安装与最小配置
建议用虚拟环境隔离依赖。requirements.txt的内容很直观:
openai-whisper
opencv-python-headless
PyYAML
requests
装好依赖后,打开config.yaml,最需要关心的是这几个参数:
frame_rate: 1
frame_width: 1280
scene_detect: false
scene_threshold: 0.3
whisper_model: small
language: zh
-
frame_rate:每秒抽帧数,静态内容可以降到0.2,动态内容可以调到2 -
scene_detect:是否启用场景检测,true时自动忽略内容几乎不变的连续帧 -
whisper_model:Whisper模型尺寸,可选tiny/base/small/medium/large-v3,中文场景建议至少small起步 -
language:语音转录的目标语言,设置为zh可以避免模型在中文和英文之间摇摆
3.3 一次完整的调用过程
假设你的Agent框架已经支持Skill调用,那么调用claude-video的流程大致是这样的:先调用流水线脚本生成结构化视频纪要,再把这个纪要作为上下文的一部分交给Agent进行分析推理。核心代码可以理解为:
import yaml
from scripts.extract_frames import extract_frames
from scripts.transcribe_audio import transcribe_audio
from scripts.build_timeline import build_timeline
def analyze_video(video_path: str, config_path: str) -> str:
cfg = yaml.safe_load(open(config_path))
frames = extract_frames(video_path, cfg)
transcript = transcribe_audio(video_path, cfg["whisper_model"], cfg["language"])
timeline = build_timeline(frames, transcript, cfg)
return timeline
调用完成后,你会得到一个JSON字符串。把它插进Agent的提示词里,再发起类似“请根据上述视频信息,总结视频的核心观点”的请求,Agent就能给出基于完整视频内容的理解。
3.4 输出结构说明与后续用法
用一次典型的输出举例:一段2分钟的产品宣传片,最终输出的JSON大概包含20个左右的时间段节点,每个节点有画面描述和语音段落。你既可以让Agent通读全文做摘要,也可以指定“只看第30秒到第50秒之间发生了什么”做局部检索,还可以问“画面里一共出现了几种颜色”这类需要视觉细节的问题——只要帧率够密,细节基本都在。
4. 实测效果:好用的场景和翻车的场景都有
4.1 效果不错的三个场景
先说实测下来表现最好的三类。
第一类是产品宣传片和口播短视频。这类视频画面信息密度适中、语音清晰、时长一般控制在2到5分钟,claude-video抽取出来的结构化文本几乎能覆盖所有重要信息点。让它总结“产品有哪些核心卖点”,它能把口播里提到的每个卖点都列出来,还能补充画面上出现的参数表格。
第二类是录屏型教程。视频内容以屏幕文字和操作动作为主,只要抽帧率够密(我实测建议0.5fps以上),画面里的命令行、界面按钮文字都能被视觉模型识别出来,语音部分又能补充操作意图,两者一结合,生成的教程要点非常完整。
第三类是会议录像。这类视频通常有稳定的人像画面和连续语音,不太依赖动作细节,1fps的抽帧密度就足够了。Agent可以根据语音转录整理会议结论,再根据画面信息区分“谁在说话”(如果模型具备说话人识别能力的话),必要时还能定位到某个观点出现在视频的第几分钟。
4.2 表现一般甚至翻车的两种情况
第一类是动作快、节奏强的视频,比如运动比赛、舞蹈录像、游戏高光集锦。画面信息高度动态,固定帧率的抽帧方式经常把关键动作拦腰截断,要么错过爆发瞬间,要么在同一时间段内出现多个互不相关的画面描述,时间轴变得杂乱。这类内容需要引入运动检测和关键帧提取,复杂度会上一个台阶。
第二类是长视频,时长超过一个小时的讲座、直播录屏。完整的逐帧处理和逐段转录会产生大量中间数据,直接推送给Agent会出现两个后果:token量过大导致超上下文限制,或者模型被无关信息淹没,抓不住重点。处理长视频建议用下一章要讲的分段摘要法,而不是一股脑全量灌进去。
4.3 性能和成本参考
这里给一组我实测中的参考数据,方便你做资源规划。机器环境是CPU为主加少量GPU,Whisper用small模型,未启用场景检测:
| 视频类型 | 时长 | 抽帧数 | 转录耗时 | 结构化文本Token量 | 效果评分 |
|---|---|---|---|---|---|
| 产品宣传片 | 2分钟 | 120帧 | 约1分钟 | 约5k | 优秀 |
| 技术录屏 | 15分钟 | 450帧 | 约8分钟 | 约9k | 良好 |
| 电影解说 | 20分钟 | 200帧 | 约10分钟 | 约7k | 中等 |
| 1小时讲座 | 60分钟 | 3600帧 | 约40分钟 | 约25k | 容易超限 |
从表格能看出两个规律:第一,越长、越动态的视频,抽帧数和转录耗时都会线性上升;第二,结构化文本的token量必须提前控制,否则再好的分析能力也发挥不出来。
5. 调优手记:四个让视频理解从“能用”变“好用”的细节
5.1 抽帧策略从固定帧率改成场景检测
固定帧率的问题在于它不知道怎么偷懒。一个访谈节目里主持人连续10秒没动画面,这10秒里的每一帧几乎一模一样,抽出来10张图只会浪费token。我在config.yaml里加入场景检测开关后,ffmpeg的命令就会改用select过滤器:
ffmpeg -i input.mp4 -vf "select='gt(scene,0.3)',scale=1280:-2" -vsync vfr frames/scene_%04d.jpg
gt(scene,0.3)
的含义是:只有当前帧和前一帧的画面差异超过0.3时才保留。阈值越低,抽取的帧越多;0.3在大多数情况下是个不错的平衡点。这样处理之后,静态段落只保留1到2帧,动态段落则保留足够多帧,抽帧数量能降一半以上,信息密度反而更高。
补充一个细节:
select
过滤器在部分ffmpeg版本里对逗号比较敏感,建议整个filter表达式用单引号包起来,否则解析会出错。
5.2 视觉描述与语音转录的优先级取舍
不同的视频,画面和语音的权重完全不一样。录屏教程里画面是核心,语音只是辅助解释,描述prompt应该要求视觉模型详细提取屏幕上的文字和界面状态;而纯口播的新闻播报里,画面几乎一成不变,语音才是信息全集,此时可以把抽帧密度降到极低,甚至直接跳过纯静态段落,只依赖转录文本。
我在claude-video里给视觉描述设了两档prompt模板。普通档:用一句话客观描述画面主体、动作与场景;详细档:逐条列出画面中的文字、UI元素、人物位置和动作变化。config.yaml里的
visual_detail
参数控制选哪一档,录屏教程类选择详细档,人文访谈类选普通档即可。
5.3 长视频的分段摘要法
处理1小时以上的长视频时,我的建议是不要让Agent一次性读完全部结构化文本,而是先分段、再摘要、最后融合。思路很简单:把视频切成5到8分钟的片段,对每个片段分别抽帧、转录、生成局部时间轴,然后让LLM把每个片段分别压缩成一段200字以内的摘要;等所有片段摘要齐了,再把这些摘要拼接成一份“视频总览”,交给Agent做最终分析。
这样做的好处是上下文压力从“1小时视频全量文本”变成“若干段短摘要”;代价是细节会损失,回答具体到秒级的问题会变得困难。所以分段粒度要按需取舍:如果主要目标是全局总结与观点提取,8分钟一段没问题;如果还需要回答细节问题,建议控制在3分钟以内。
5.4 提示词里加上时间和空间约束
很多人最后一步容易犯一个错误:把结构化视频文本丢给Agent后就问一个笼统的问题。如果你问“这个视频讲了什么”,Agent给出的是全局泛泛的总结,很多细节会溜走。更好的做法是在分析提示词里加上明确的时间和空间约束。比如:“请只关注第2分钟到第5分钟之间出现的所有产品参数,并按时间顺序列出来”,或者“视频第10秒时画面背景里出现的那句话是什么”。这样Agent在检索结构化文本时会更有目标,输出也更精准。
6. 踩坑记录:安装和调用时最容易出问题的三个地方
6.1 ffmpeg版本带来的命令兼容性差异
我换过几台机器,遇到过最典型的坑是两个。第一个是scale过滤器里高度参数写成
-1
在某些老版本ffmpeg里会报“even height required”之类的错误,改成
-2
才稳定。第二个是select过滤器对逗号的处理方式在不同版本里不一致,带场景检测的抽帧命令在部分版本直接解析失败,必须用
select='gt(scene,0.3)'
加单引号包住整个表达式。解决这些问题的手段很朴素:先拿一个短视频试跑,确认命令无误后再处理大批量文件,不要一上来就全量跑。
6.2 Whisper模型尺寸的选择困境
Whisper模型的尺寸直接决定转录质量和速度。base模型速度很快,但中文口音重一点、专业术语多一点就很容易识别错字,比如把“Transformer”听成完全无关的词都是常有的事;small模型在速度和准确率之间最平衡,中文日常场景够用;medium和large-v3在专业领域效果好,但CPU上推理慢得让人怀疑人生,没有GPU的话不建议直接用large。
我自己的建议是:先跑一遍small看效果,如果错误率高到影响下游分析,再升级到medium,并且只对长视频里语音质量较差的片段做局部重转录,而不是全量重跑。语音转录是整个流水线里最耗时的一环,学会局部重处理能省很多时间。
6.3 上下文爆炸与成本失控
最后再提醒一个最容易被忽略的问题:视觉描述产生的token量往往比你想象的夸张。每张帧生成的描述句如果平均50个token,1fps抽帧下10分钟视频就是3万token,加上转录文本轻松突破上下文限制。更麻烦的是,如果你用的是按量计费的API,每次调用视频分析都会烧掉一大笔token额度。
控制手段有三层:第一层是抽帧端控制,开启场景检测、降低固定帧率、限制图片宽度;第二层是描述端控制,把视觉描述模板改成短句风格,每帧最多一句话;第三层是流程端控制,长视频走分段摘要,绝不把全量结构化文本一次性灌给模型。三层同时做,才能把token消耗控制在可接受的范围。
我个人的体会是,让Agent看懂视频这件事,真正的工程难点从来不在于模型够不够聪明,而在于你怎么把视频这个“连续、多维、语义稀疏”的信号,转成Agent天生擅长的“离散、线性、语义密集”的文本。claude-video这套Skill只是做了一个很朴素的转换,却能实打实地把视频分析任务的可行性提升一大截。如果你也在做类似的事情,建议先跑通最小闭环——一个视频、一条流水线、一次结构化输出,再逐步去优化抽帧策略和token成本。等你把中间表示做好之后,后面换成更强的视觉模型、加上说话人识别、接上向量检索,都是水到渠成的事。
更多推荐
所有评论(0)