ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

构建AI工程师演讲索引:1124场视频到秒级定位的实战

构建AI工程师演讲索引:1124场视频到秒级定位的实战 把 1124 场 AI Engineer 演讲整理成一个可搜索、带时间戳的索引这事儿一开始听起来像是个“用脚本跑一遍就行”的小工具但真正动手做的时候光是数据清洗就折腾掉我两个周末。我最初的需求很朴素每次听技术演讲听到一半想回头找某个具体的观点或代码片段就得在 YouTube 时间轴上反复拖动运气好能一次命中运气不好基本等于把视频重看了一遍。我需要的不是一份“有哪些视频”的目录而是一个能让我直接跳到“讲某话题的第几秒”的检索系统。所以这个项目的目标很明确把散落在各个平台、各个会议里的 AI Engineer 演讲全部收进来做完数据清洗和去重之后给每一场演讲生成带时间戳的段落索引让用户输入关键词就能定位到具体的那一场演讲甚至是那一段话。最终做出来的索引覆盖了 1124 场演讲包含标题、演讲人、会议/频道来源、时长、上传时间、以及按字幕对齐生成的分钟级时间戳。适合谁用如果你是 AI 工程师、技术内容策展人、想系统学习某一方向但不知道从哪看起的学习者这个索引能帮你把几百小时视频变成一本可以翻目录的书。1. 项目动机为什么我觉得“能搜到视频”远远不够1.1 AI 工程内容供给爆炸但检索能力还停留在“浏览”AI Engineer 这个方向这两年的内容增速非常夸张。各大会议开始增设 AI Engineer 专题一些以 AI 为主题的独立会议也冒了出来更别提那些每周更新的技术频道。我在收集过程中统计过光是我接触到的来源里2023 年之后的演讲数量占了总量的七成以上而且这个比例还在涨。问题在于内容的增量并没有带来检索的便利。今天你想找一个“RAG 评估指标怎么设计”的演讲最常规的做法是在 YouTube 上搜关键词然后从搜索结果里一个个点进去看简介再手动拖视频进度条找相关内容。运气好的话演讲者会在简介里贴时间轴运气不好你只能在评论区找其他观众的“好人一生平安”。这种体验本质上是在做手工索引人力成本极高而且换一个关键词就要重新来一遍。1.2 视频本身是“不可搜索”的需要中间层视频这个载体天然有信息盲区。搜索引擎能索引标题、描述、标签但索引不了画面里的每一句话。语音识别技术早就能把语音转成文字可转出来的文字如果没有跟时间轴做对齐你也只能看到整段文本却不知道这句话出现在视频的第几分钟。我做这个索引的核心思路就是在“视频内容”和“用户检索词”之间加一层结构化的中间数据字幕文本 时间戳 元信息。有了这一层搜索就能从“搜视频标题”升级成“搜演讲内容”能力完全不一样了。1.3 市面上的现成工具为什么不满足需求说实话做之前我也尝试过用一些现成的工具组合。比如直接用 YouTube 搜索或者用某些会议官网自带的议程检索。但它们各有各的问题。YouTube 搜索本质是标题和描述的全文匹配精度非常差而且没有跨会议的聚合能力。会议官网的议程页倒是结构化但只能覆盖自家内容我想跨会议对比同一主题的不同观点时就完全没辙了。还有一些第三方课程平台做了人工精选但覆盖量太小并且更新慢。这些都促使我下定决心自己搭一套能持续更新的索引系统。2. 数据收集1124 场演讲是怎么筛出来的2.1 演讲来源与采集策略我一开始定了一条原则只收“演讲”不收“教程视频”和“播客节目”。这两者区别是什么演讲一般有明确的主题边界、通常在某个会议或技术社区活动中发布、时长大多在 20 到 60 分钟教程视频则往往是系列化、分 P 的比如“XX 框架入门到精通 01”播客又是完全不同的内容形式没有画面的时序结构。这条原则帮我过滤掉了很多噪音。来源大致可以分为以下几类来源类型示例在最终索引中的占比大型行业会议各类 AI/ML 技术大会约 40%语言/框架社区会议PyCon、JSConf 等约 20%技术公司官方频道大厂研究院、工程博客配套视频约 25%独立技术社区线上 meetup、社区月度分享约 15%采集端主要是写了一个 Python 爬虫通过 YouTube Data API 按频道和播放列表拉取视频列表再按关键词过滤比如标题或描述里包含 AI Engineer、LLM、AI Agent、RAG 等词。这里要注意API 只返回视频的标题、描述、时长这些基础信息字幕文件要走另一个接口而且有些字幕是自动生成的有些是人工精校的质量差距很大。2.2 去重与清洗3000 多场到 1124 场的过滤过程原始抓取量大概是 3000 多场最终只留下 1124 场。很多人会问为什么砍掉这么多因为数据脏的程度超出我的预期。第一层去重是视频级别的重复同一个演讲被多个频道搬运、剪辑成不同版本这在 AI 内容领域特别常见。比如一个 40 分钟的完整演讲有人截了其中 5 分钟单独上传标题还写得特别吸引人如果不做重复检测你的索引里就会出现两个“不同”的条目但实际内容是同一场。第二层过滤是标题规范性。有些视频标题写得很随意比如“chat with 李雷 about AI”。这种标题在自动抓取时很难判断它是不是一次合格的演讲我最后采用了一个综合评分规则标题里有明确主题词加分有演讲人姓名加分描述里有议程信息加分时长在 25 到 70 分钟区间加分低于 5 分钟直接排除。这套规则虽然没法做到百分百精确但在数据量级下已经足够实用。2.3 元信息的统一与规范化清洗完之后还需要把每一场演讲的元信息结构化。这里容易踩的坑是同一个人名有多种写法比如“Zhang Wei”和“Wei Zhang”在原始数据里可能是两个人其实是同一个人。我做了一个简单的归一化处理把拼音名统一成“姓在前”的形式西文名统一按“名姓”来存储另外保留一个别名表用来关联花名和常用缩略称呼。规范化的好处体现在后续搜索上用户搜“大模型对齐”的时候系统能同时匹配到中英文表述和不同的演讲人拼音写法查全率明显提高。3. 搜索与时间戳把视频变成可检索的语料库3.1 时间戳从哪里来字幕对齐的三条路径这是整个项目里技术含量最高的部分。要做“带时间戳的搜索”核心是拿到每一场演讲的逐句字幕时间轴。我的方案分三条路径按优先级依次尝试第一优先是 YouTube 自带字幕。平台提供的字幕文件里其实包含每个句子出现的时间点以秒为单位直接把.vtt文件解析出来就能拿到结构化数据。问题在于并不是每场演讲都有字幕很多搬运视频连自动字幕都没开。第二优先是视频描述或评论区里的章节标记。不少演讲者会在简介里写“00:00 Intro, 05:30 Main Talk, 30:00 QA”这种数据虽然粒度粗但胜在干净。我写了解析器去识别这类时间轴格式提取出来之后存成一个粗粒度索引。第三是兜底方案用 Whisper 做本地语音转写。这个方案最费时间尤其是时长接近一个小时的演讲转写一次可能需要几分钟到十几分钟取决于 GPU 资源。但它是唯一能保证所有演讲都能被“内容化”的方案。我会先判断前两条路径是否命中只有全部失败才走 Whisper。字幕拿到之后我会按每分钟做一个内容分片每个分片对应一个时间戳。搜索的粒度就是“某一分钟到下一分钟之间的内容”用户点击搜索结果时直接跳转到该时间点的视频位置。3.2 搜索索引的字段设计与排序规则搜索不是简单地存进去就能查。我用数据库建了一个索引表每个演讲的字段包含演讲标题、演讲人、会议/频道、内容分片文本、时间戳范围、上传日期、视频时长。搜索时这些字段的权重是不一样的。字段权重说明标题高精准命中最重要演讲人高用户找特定讲者时优先匹配分片文本中命中说明是正文级别的相关性会议/频道名低仅作为降级匹配排序逻辑是先算关键词在标题和演讲人上的命中分数再算分片文本上的命中分数。两者都命中的内容排最前只有标题命中的其次只有内容命中的再次。另外上传日期越新在同等分数下排名越靠前这符合 AI 领域内容迭代快的特点老演讲的观点可能已经过时了。3.3 一个最简单的搜索流程示例我用一个实际的搜索场景演示这个过程假设你想找“AI Agent 的 planning 模块怎么设计”。输入关键词 agent planning。搜索层把这两个词拆成独立 token在数据库里做全文检索。先看标题字段找到标题含 agent 和 planning 的演讲。没有完全命中的情况下再查内容分片文本。返回结果时每条结果带上“命中位置所在的时间戳”比如第 12 分钟。点击后前端把视频播放器跳转到第 12 分钟并开始播放。整个过程在用户侧看是一步操作但背后的时间戳对齐、权重排序和分片命中逻辑决定了返回结果是不是真的有用。4. 技术选型与实现整套索引系统我用了什么4.1 数据管道采集、清洗、索引、服务整个系统分成四个环节。采集端用 Python YouTube Data API 每天跑一次增量任务把新增视频拉进原始库。清洗端负责去重、标题规范化、人名归一等脏活我用的是 Pandas 做批处理跑完输出一份干净的 JSON。索引端把 JSON 写入数据库同时对字幕文件分片并生成全文索引。服务端用一个轻量 API 提供搜索接口前端页面把 API 包装成一个看起来像搜索引擎的界面。这一套架构没有用什么花哨的技术核心原则是每个环节都能独立重跑。比如脏数据清洗脚本我改了一版之后能直接对全量数据重放不用人工介入。这一点在项目后期帮了大忙因为每次调整清洗规则我都需要知道历史数据有哪些会被“新规则”重新归类。4.2 存储选型SQLite 起步Postgres 收尾最开始我图省事用了 SQLite数据量到几千条记录的时候完全没问题。但等索引表加上全文索引数据增长到几十万行级别时SQLite 的并发写入和查询性能开始吃紧。最后我把核心数据迁移到了 PostgreSQL用了它自带的全文检索能力。其实有两种方案方案优势不足PostgreSQL 全文检索数据不用同步到第三方SQL 一个查询搞定中文分词需要额外插件Meilisearch / Typesense开箱即用的搜索体验支持模糊匹配多一套服务部署和维护成本高考虑到这个项目的核心是英文技术演讲Postgres 内置的tsvector和tsquery已经够用而且少维护一个搜索引擎组件所以最终选了 Postgres。如果你的索引数据里中文内容占比很高建议直接上 Meilisearch中文分词体验会好很多。4.3 时间戳对齐的代码实现思路时间戳对齐的核心逻辑其实不复杂从字幕文件里拿到每个句子的开始时间和结束时间然后按“分钟”聚合。每一分钟的文本内容就是该分钟的字幕片段整个演讲的分片文本构成了一个时间轴。import webvtt def parse_vtt_to_segments(vtt_path): segments [] for caption in webvtt.read(vtt_path): start_sec caption.start_in_seconds end_sec caption.end_in_seconds text .join(caption.text.split()) segments.append({ start: start_sec, end: end_sec, text: text }) return segments拿到 segments 之后再按整分钟聚合文本。比如一个 40 分钟的演讲最终生成 40 个分片每个分片包含该分钟内讲到的内容片段。这样查询就可以通过“时间戳索引表”直接定位到具体分钟不需要实时扫描整个演讲稿。4.4 前端展示搜索框之外还做了什么前端部分我坚持了极简原则一个搜索框、一个结果列表、一个展开详情区域。结果列表里每一条显示演讲标题、演讲人、会议名称、日期以及命中内容所在的时间段。点击之后右侧会拉起来一个内嵌播放器直接定位到对应时间戳。额外加的细节是“关键词高亮”。搜索词在结果描述里会用黄色底色标出来这样用户能快速判断这条结果是否真的命中了需求。高亮逻辑放在后端因为前端做会泄露所有内容分片的数据不必要的传输会拖慢加载速度。5. 踩坑记录与排查实录我做索引时遇到的 7 个典型问题5.1 大量视频没有字幕怎么兜底我最初以为 YouTube 字幕覆盖率至少有八成结果实际跑下来只有六成左右。很多会议的官方录像是真的没有字幕只有自动生成的英文 CC但自动字幕质量参差不齐断句错乱严重很多专有名词完全识别错误。最终的选择是自动字幕照单全收但对专有名词做了一次全局纠错比如把常见的模型名、框架名的识别错误批量替换掉。这个纠错词表是人工整理的大概花了一个下午但效果立竿见影搜索命中率提升了不少。5.2 时间戳偏移视频片头导致所有索引错位这是一个很隐蔽的坑。不少会议视频都有 1 到 2 分钟的片头动画和主持人开场这段时间里演讲者并没有开讲。字幕文件的时间轴是以整个视频为单位计算的所以第 2 分钟的字幕可能是片头音乐而不是演讲内容。我最初的索引直接拿字幕时间戳建结果用户点击第 15 分钟看到的往往还是主持人铺垫真正的内容从第 16 分半才开始。解决方法是检测字幕文本里的“关键词起点”。如果字幕前几行没有出现演讲者名字或者会议名首字母这类标记就往后找第一个包含技术关键词的句子把它所在的时间点设为“实际内容起点”后续所有时间戳按这个起点做偏移。这个方案不完美但在大部分场景下能把偏差缩小到 30 秒之内。5.3 重复视频的“标题变体”骗过了去重原始数据里的重复除了完全一样的 URL还有不少是标题里加了一堆前后缀的变体。比如“Keynote: Building AI Agent”和“Building AI Agent | Keynote 2024”。字符串比对基本无效只能用语义相似度。我对标题做了向量化处理用嵌入模型算标题相似度超过阈值就标记为重复候选再人工确认。这个方法把重复检测的召回率拉高了很多也顺便帮我识别出了一批“同一演讲、不同语言字幕”的版本。5.4 全文检索的中文分词问题虽然是英文语料为主但 AI Engineer 圈子里很多内容会夹杂中文、日文、韩文的专有词。Postgres 默认的英文分词器遇到中文内容会把一整个句子当成一个 token导致搜索几乎失效。我的临时方案是只对中文字段做特殊处理在写入索引前按字符 n-gram 拆开比如拆成 2-gram 的 token 子串。这样至少保证中文关键词也能被部分匹配到。如果后续要做全面中文支持我还是建议上一个专用的搜索引擎。5.5 搜索“太精确”导致结果太少早期的搜索结果我按单词精确匹配输入“agent planning”就只能返回同时包含两个词的结果。真实用户的搜索词经常是“AI agent 怎么设计规划”这里的“规划”和“planning”是不同语言、不同词形精确匹配完全没办法。后来我引入了一个简单的词形还原和同义词扩展层比如“planning”匹配“plan”、“planner”、“规划”、“计划”等变体。不需要多复杂一个同义词表就能提升不少体验。5.6 增量更新的幂等性爬虫每天跑增量任务最怕的是同一条数据被重复写入。我的解决方式是给每个视频规定一个唯一业务 ID以它作为主键。每次写入前检查是否存在存在则更新元信息不存在则新增。这个逻辑很基础但我一开始偷懒没做导致数据库里出现了几千条重复记录清洗脚本又得重跑一遍白白浪费了一个下午。5.7 无法按“话题脉络”浏览的缺口搜索做得再好也只能解决“我知道要查什么”的需求。还有一类用户他们不知道要查什么只是想按时间顺序看看这个月 AI Engineer 圈子里大家讲了什么。目前索引虽然可以按上传日期倒序排列但缺少“话题聚类”能力同一主题的多场演讲没有关联起来。这个我打算后面用主题建模做轻量聚类把“Agent”、“RAG”、“Inference Optimization”这样的主题标签加到每条记录上让用户能按脉络浏览。6. 实操心得如果你的索引要覆盖 5000 场我建议这样设计中间有一段时间我尝试过把收集范围扩大到所有 ML 相关演讲结果数据量很快冲到 5000 多场。这时候我发现几个设计上的瓶颈值得提前规划一是字幕分片表的存储占用增长很快建议提前做分区表按月或者按会议 ID 分区二是全文索引的构建时间会随着数据量非线性增长最好用增量索引而不是全量重建三是去重逻辑必须考虑“批量搬运”这种内容农场行为我在后期用聚类方式把同一来源的批量上传视频做分组再按组内相似度去重效率高了很多。另一个心得很重要元数据质量直接决定索引价值。一个字段缺失的演讲即使内容再好也会在搜索里沉底。我建议在做数据清洗时把“元数据完整度”作为核心指标来监控。如果某个来源的演讲有超过 20% 缺少文字表述、缺失演讲人信息就应该考虑把该来源降权甚至剔除。最后说一点工具层面的经验。整个项目我大部分时间花在数据清洗和字幕处理上真正写搜索逻辑的时间反而不多。前端用的是一个很轻量的静态页面后端是 FastAPI 暴露的搜索接口部署在一台低配云主机上跑得很稳。整套系统加起来不到 3000 行代码但数据管道里的每一环节都经历过手工检查和规则调优。这也是我最想强调的这类索引项目的难度不在技术有多深而在于你愿不愿意花时间把脏数据一点点擦干净。
返回列表