视频课怎么被AI搜索引用:VideoObject 结构化的 45 天对照

2026-10-10 01:16:00 1 次浏览
GEOAI搜索VideoObjectJSON-LDSchema.org.NET 8

一、起点:视频全都在,引用是零

10 月 8 日早上,运营同事在群里甩来一张截图:用户在 DeepSeek 里问「XX 数据分析课哪家的系统」,AI 回答里列了两家竞品的课程,还整段引用了他们的课程介绍。而这次,我们服务的那家在线职业教育平台第一次出现在回答里——45 天前,同样的提问,回答里连平台的名字都搜不到。

回溯到 8 月下旬,情况完全相反。平台有 400 多节视频课,列表页和课程详情页做了三年,传统搜索引擎收录一直正常。但我们按 20 组课程相关提问、DeepSeek/豆包/文心三家引擎做引用监测,60 组问答里课程页被引用 0 次,竞品被引用 11 次。抓取日志同样难看:AI 爬虫每周只碰详情页 3 次左右,还基本停留在列表页第一屏。

内容质量没毛病,视频讲得清楚,简介也写了八百字。问题出在内容形态:视频本体对生成式引擎是个黑盒,简介太短,撑不起生成式引擎优化(Generative Engine Optimization, GEO)需要的「可引用单元」。AI 搜索组织回答时要把网页拆成小段落摘引,一页只有一段简介的页面,很难被切出合适的引用块。我们要做的,是把每一节课变成引擎能读懂、能切碎、能溯源的结构。

视频课结构化改造示意

改造前后的整体对照

先给结论性的全景,后面逐项展开。口径统一为:20 组固定提问、每周统计一次,D0 指结构化数据全量上线的当天。

对照项 改造前(D0) 改造后(D45)
AI 搜索周引用次数(20 组提问) 0 17
课程详情页 AI 爬虫周抓取频次 约 3 次 约 60 次
被 AI 引擎缓存快照的课程页 0 312
每节课可引用的文本单元 0(纯视频+短简介) 平均 46 段
传统搜索引擎收录 正常 正常,无波动

二、补了什么:VideoObject 的最小可用集

结构化选型没有悬念。课程页本来就是 ASP.NET Core(.NET 8)的 Razor 页面,直接在详情页输出 JSON-LD,按 Schema.org 的 VideoObject 补字段。我们的最小可用集是七个:name、description、transcript、uploadDate、duration、thumbnailUrl、contentUrl。前两个页面里本来就有,真正新增的工作量集中在 transcript——其余字段告诉引擎「这是什么」,transcript 告诉引擎「里面讲了什么」,整个改造的分水岭就在这一行。

// 环境:.NET 8 / ASP.NET Core Razor Pages,序列化用内置 System.Text.Json,无第三方包
@page "{courseId:int}"
@using System.Text.Json
@using System.Text.Encodings.Web
@{
    // 课程实体由 PageModel 注入,这里只负责组装 JSON-LD
    var course = Model.Course;
    // 用字典拼对象比写 DTO 省事,字段名与 Schema.org 逐字对齐
    var videoLd = new Dictionary<string, object>
    {
        // @context 必须挂在第一层,嵌进内层整段会被静默丢弃
        ["@context"] = "https://schema.org",
        ["@type"] = "VideoObject",
        // name 与页面 title 保持一致,实体对不上会拉低引用置信度
        ["name"] = course.Title,
        // description 取课程简介,控制在两百字内
        ["description"] = course.Summary,
        // transcript 由 SRT 字幕转纯文本按句拼接,是本次改造的核心字段
        ["transcript"] = course.TranscriptText,
        // uploadDate 必须是 ISO 8601 日期,带时区更稳
        ["uploadDate"] = course.PublishedAt.ToString("yyyy-MM-ddTHH:mm:sszzz"),
        // duration 必须写 PT45M30S 这种 ISO 8601 时长,写 45:30 会被丢弃
        ["duration"] = course.IsoDuration,
        // thumbnailUrl 用带域名的完整地址,相对路径部分引擎不抓
        ["thumbnailUrl"] = "https://cdn.example.com/" + course.CoverPath,
        // contentUrl 指向视频文件本体,供引擎确认资源可达
        ["contentUrl"] = course.VideoUrl
    };
    // 序列化时关掉中文转义,输出保持可读
    var ldJson = JsonSerializer.Serialize(videoLd,
        new JsonSerializerOptions { Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping });
}
<script type="application/ld+json">@Html.Raw(ldJson)</script>

transcript 的来源是课程字幕。平台每节课都配了 SRT 字幕,我们写了个转换脚本按句切分再拼成纯文本,保留课程里的关键术语,没有做二次润色,也没往里塞营销话术。引用单元越接近讲义原文,AI 转述时越不容易跑偏。切分粒度上做过一轮小实验:按整节拼接的一大段 transcript,45 天里几乎没被引用过;按 80 到 150 字切成独立小段后,被整段摘引的记录才慢慢出现。这和引擎的段落级引用机制是吻合的——你交给它的粒度,就是它引用时的粒度。400 节课的字幕转换一个晚上跑完,真正花时间的是校验——这正好引出后面那个最贵的坑。

数据统计怎么做的

判断改造有没有效果不能靠体感。AI 爬虫日志按周聚合,引用监测按固定提问集每周跑一轮,两边用 Python 脚本对齐出周报表。

# 环境:Python 3.11,仅用标准库 csv 与 collections,无第三方依赖
import csv
from collections import defaultdict

# 读取引用监测表:每周、每引擎、每道提问记录课程页被引用次数
with open("citations_weekly.csv", encoding="utf-8") as f:
    citations = list(csv.DictReader(f))

# 读取爬虫日志汇总表:字段为周次与详情页抓取次数
with open("crawler_weekly.csv", encoding="utf-8") as f:
    crawl = {r["week"]: int(r["detail_hits"]) for r in csv.DictReader(f)}

# 按周聚合引用次数,同时把提问按意图分成问答型与比较型
weekly = defaultdict(int)
by_intent = defaultdict(int)
for row in citations:
    # 引用为 0 的行也要参与聚合,否则周均值会虚高
    weekly[row["week"]] += int(row["hits"])
    # intent 字段区分 qa(这课讲什么)与 compare(哪家好)两类
    by_intent[(row["week"], row["intent"])] += int(row["hits"])

# 输出周对照表,引用与抓取并排,方便看先行滞后关系
print("week\tcitations\tcrawl_hits")
for week in sorted(weekly):
    # 抓取频次是先行指标,通常领先引用两周左右
    print(f"{week}\t{weekly[week]}\t{crawl.get(week, 0)}")

# 汇总两类提问的引用分布,验证问答型更易被引用的假设
qa = sum(v for (w, i), v in by_intent.items() if i == "qa")
compare = sum(v for (w, i), v in by_intent.items() if i == "compare")
# 占比按整型百分比输出,报告里直接能贴
print(f"qa={qa} compare={compare} qa_pct={qa * 100 // max(qa + compare, 1)}%")

三、原理与机制剖析:为什么 transcript 是分水岭

这一节是 45 天里我们想得最多的部分,拆成三个机制讲透。

机制一:AI 引擎引用的是文本单元,不是视频

生成式引擎的检索链路里,能被大模型消费的是文本块。视频文件对它是不可读的二进制;就算引擎愿意做语音转写,那个成本也远高于直接读页面里现成的 transcript。所以引擎的引用单元(Citation Unit)基本按文本段落切:一节课有了 transcript,等于把 40 分钟口播变成一段段可检索、可摘引的文字。我们的经验值是每段 80 到 150 字、术语密集的段落单独成段时,被整段引用的概率明显更高。反过来说,没有 transcript 的视频页,在引擎眼里和一张大图片没有本质区别。

机制二:JSON-LD 解析器会静默丢字段

改造第一版上线后数据几乎没动,排查三天才发现原因:duration 写成了「45:30」,正确写法是 ISO 8601 的「PT45M30S」。解析器对这类字段不报错、不告警,直接丢掉——接口照常返回 200,日志里毫无痕迹。同样的坑还有 thumbnailUrl 指向 404 的封面图、uploadDate 带了非法时区写法。结构化数据的问题有个共同特征:坏了不响。这也是我们后来把结构化校验塞进发布流水线的原因,schema.org 官方校验器和 Rich Results Test 双跑一遍才允许上线,宁可在发布时多等一分钟。

机制三:页面层与视频层的双重索引

补齐 VideoObject 之后,引擎实际建了两层索引:页面层靠正文与简介,视频层靠 transcript 和结构化字段。两层互相印证——简介说这节课讲数据清洗,transcript 里反复出现「缺失值」「异常点」,实体一致性上去了,引用置信度才过得了线。只有简介没有 transcript 的页面,第二层索引是空的,回答「这门课具体讲了什么」时就轮不到它。整个链路如下图:

flowchart LR
    A[课程详情页 Razor] --> B[JSON-LD VideoObject]
    A --> C[页面正文与简介]
    B --> D[transcript 段落切分]
    C --> E[正文段落切分]
    D --> F[AI 引擎两层索引]
    E --> F
    F --> G[生成回答时整段引用课程页]

四、45 天数据对照

时间线从 8 月 26 日全量上线开始计,中间没有做其他大改版,传统 SEO 动作保持原样,可以近似认为变化来自结构化数据本身。

timeline
    title 视频课结构化改造 45 天对照
    D0 : 全量上线 JSON-LD : 引用 0 次
    D7 : 抓取频次升到 9 次/周 : 引用仍为 0
    D21 : 首次出现整段引用 : 快照 58 页
    D35 : 引用 11 次/周 : 快照 201 页
    D45 : 引用 17 次/周 : 快照 312 页
时间点 周引用次数 详情页周抓取 有快照课程页 备注
D0 0 3 0 400 页全量推 JSON-LD
D7 0 9 0 抓取先动,引用未动
D21 4 27 58 首条引用来自问答型提问
D35 11 44 201 三家引擎都有引用记录
D45 17 60 312 趋势趋稳,周波动变小

两条规律值得单独加粗。抓取频次是先行指标,领先引用变化大约两周——D7 抓取涨了三倍而引用为零,差一点据此误判改造无效。问答型提问的引用率远高于比较型:D21 之后的引用里,「某课程讲了什么」类提问占七成以上,「哪家好」类比较型提问引用稀少,后者更像多信源汇总场景,单个课程页能贡献的位置本来就少。

五、踩过的四个坑

一是 duration 格式。45:30、2700 秒、45 分 30 秒三种写法全被静默丢过,最后统一在 PageModel 里做转换,只输出 PT45M30S 格式。二是 thumbnailUrl 挂了 404。封面图迁移到 CDN 后旧路径没配跳转,引擎抓不到图就降低了对整个对象的可信度,修复后一周引用才开始出现。三是 transcript 放外链还是内嵌。我们试过用 js 注入 transcript,抓取记录显示部分引擎根本不执行脚本,最终改成随 HTML 直接输出。四是列表页与详情页的关系:JSON-LD 只放详情页,列表页保持轻量,别在一个页面堆几十个 VideoObject 对象,解析器对超长结构化数据的容忍度并不高。

六、两个误区与一个预判

误区一:加了结构化数据就会被引用。前两周引用为零是正常的,抓取频次先动,快照先建,引用后到,这个顺序没有跳过。误区二:transcript 越长越好。把竞品课程、广告词都拼进去只会稀释段落质量,我们砍掉了一版里的推广段落之后,单段被引用率反而上升。

预判部分:视频内容的 GEO 会从「给引擎读」走向「被引擎引用」。多模态模型迟早能直接理解音视频,但在那之前,transcript 加 VideoObject 仍是性价比最高的动作——它不挑框架,一个 Razor 分部页面加一个 Python 统计脚本,两百行以内的代码,45 天里没有再动过。如果你的课程站也在做类似改造,欢迎评论区聊聊引用监测的口径怎么定。

参考与延伸

  • Schema.org VideoObject 类型定义:https://schema.org/VideoObject
  • Google 搜索中心·视频结构化数据官方文档:https://developers.google.com/search/docs/appearance/structured-data/video
  • llms.txt 规范:面向 AI 引擎说明站点内容的提案:https://llmstxt.org/

课程视频结构化、VideoObject、JSON-LD、GEO、AI 搜索引用、transcript、教育行业AI流量

🤖
本内容由 AI 辅助生成,经人工校对审核;部分素材、资料来源于公开网络,仅作个人观点分享与交流使用,无任何商业侵权意图。若内容、图片、文字涉及您的合法著作权、版权权益,请联系本人,核实后将第一时间删除、修改相关内容。