做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成本。等你把中间表示做好之后,后面换成更强的视觉模型、加上说话人识别、接上向量检索,都是水到渠成的事。

Logo

邀请您加入社区

更多推荐