

# 为 RAG 准备带来源时间戳的 YouTube 转录文本

保留带时间的字幕条目，将每项论断与其适用条件放在一起，并用已知答案的问题测试文本块。字幕条目就是一行带时间的字幕。文本块是存储起来、可由检索返回的一个文段。适用条件限定了论断在什么情况下成立。将每个例子和每项对比与对应的论断放在一起。RAG 指检索增强生成。检索是在模型回答之前查找已保存的文本。语义指的是文本的含义。没有一种固定秒数适合所有视频。没有一种固定词数适合所有视频。应通过测试选择分块方式。从一个视频开始。保留原始记录，在工作副本上编辑。只有在回放确认实际只说了一遍时，才删除重复条目。保留所有原始字幕条目编号。使用已知答案的问题，再加上一个视频无法回答的问题。嵌入向量是用于查找相似文本的数字列表。数据库是可选的。这种方法有一个明确的局限。下文的评分是虚构的人工比较，不是实测的检索结果，也不能表明存在普遍提升。提取一次字幕不能证明字幕文字与语音一致，也不能证明以后这些字幕仍然可用。如果字幕中没有所需事实，就说明该来源无法回答。

模型是编写回复的程序。生成就是编写回复这一步。检索先找到文本。模型应根据找到的文本来编写回复。最初的 [RAG 论文](https://arxiv.org/abs/2005.11401)为检索与生成相结合提供了依据。它没有为视频选定文本块大小，也没有为下文的虚构计数提供依据。

有些开发者会问：对于内容重复、话题跳跃的字幕，按时间分块和按语义分块哪种更好？没有一种方式对所有视频都最好。请测试你自己的视频。

## 获取一份带时间戳的转录文本

JSON 是一种文本数据格式，用文本表示结构化数据。字幕条目索引是读者为 segments 数组中某个原始位置指定的标签。字幕条目索引不是 Actor 承诺提供的输出字段。教学表格中的位置编号从 1 开始。第一个位置是 1。不要修改原始记录。在工作副本中保存这些标签及其来源追溯信息。

Actor 是为你在线运行的数据采集程序。Task 是为 Actor 保存的一组输入设置。如果你已有字幕，不使用 Actor 也可以采用此方法。如果你还需要字幕，请参阅 [YouTube 字幕提取](https://chronometrica.com/zh-Hans/articles/youtube-%E6%96%87%E5%AD%97%E7%A8%BF%E6%8F%90%E5%8F%96%E4%B8%8E%E7%BC%BA%E5%A4%B1%E5%AD%97%E5%B9%95%E6%A3%80%E6%9F%A5/)。本页不再重复介绍提取过程。

2026年10月13日核查的公开采集程序是 Actor 构建版本 0.1.43。成功读取字幕时，该版本会提供带时间戳的片段。片段就是 json 中的一个字幕条目。后续构建版本可能有所不同。核查日期是观察日期，不是视频发布日期。Actor 页面为 [YouTube Transcript Scraper](https://apify.com/chronometrica/youtube-transcript-scraper)。已保存的 Task 为 [YouTube Transcripts for RAG Pipelines](https://apify.com/chronometrica/youtube-transcript-scraper/examples/youtube-transcripts-for-rag)。

这里需要明确范围。数据粒度指一行代表什么。Actor 输出的数据粒度是：数据集中的每行代表一个成功处理且不重复的视频。数据集行就是一条已保存的记录。读者创建的文本块表中，每行代表一个文本块。文本块不是数据集行。所有文本块列都由读者创建。Actor 接收直接指向视频的 URL，或你已知的视频 ID。它不会替你查找视频。Task 返回 json、text 和 llm。请使用 json 制作引用。引用包含支持某项论断的视频及其时间范围。llm 结果是 llmText。llmText 是可直接用于提示词的文本。提示词是你发送给模型的消息。llmText 不能替代片段时间。

Actor 不会创建文本块，不会生成嵌入向量，也不会构建索引。索引是为搜索而存储的数据结构。Actor 不会检索文段，不会回答问题，也不会为答案评分。你需要手动清洗、分块和测试。

在未经修改的原始记录中保留以下来源字段。

| 字段 | 需保留的内容 |
| --- | --- |
| videoId | 视频 ID |
| videoUrl | 直接指向视频的 URL |
| transcriptLanguageCode | 字幕语言代码 |
| isAutoGenerated | 字幕轨道是否标记为自动生成 |
| segments | 字幕条目列表 |
| scrapedAt | 该记录的采集时间 |
| status | 本次运行返回的状态 |

字幕轨道是字幕的一个语言版本。在每个片段中保留以下字段。

| 字段 | 需保留的内容 |
| --- | --- |
| startSeconds | 字幕条目的开始时间，单位为秒 |
| endSeconds | 字幕条目的结束时间，单位为秒 |
| durationSeconds | 字幕条目的持续时长，单位为秒 |
| text | 字幕条目的文字 |

如果 preferredLanguages 为空，运行时会选择一个可用的字幕轨道。请检查 transcriptLanguageCode。空列表不代表你已选择语言。添加第二个视频之前，先确定一条语言规则。将 isAutoGenerated 与记录一起保留。自动生成表示该轨道被标记为由机器生成。机器字幕可能重复显示同一句话。仅凭这一标记不能证明字幕文字有误。

输入处理失败的详细信息位于 OUTPUT。请设置 includeFailedInputDetails，让这些信息保持可见。输入处理失败不等于得到一份含有 0 个字幕条目的转录文本。不要用 0 表示未知时间。真实字幕条目可以从 0 秒开始。未知值与零值不同。scrapedAt 是你采集该记录的时间，不是视频的发布时间。

核查一次字幕不能证明字幕文字与语音一致，也不能证明以后这些字幕仍然可用。已核查的 Task 只是一个起点，其中包含示例视频。请将它们替换为你选择的一个公开视频。Task 不会清洗、分块或测试。

## 依次完成 7 项操作

请按顺序操作。如果先分块后清洗，重复内容可能看起来像两个事实。如果先评分后写问题，你可能过早偏向某种分块方式。先写问题，再用相同的问题测试两种分块方式。

1. 原样保存采集程序返回的原始记录。不要编辑该记录，也不要修改原始来源。创建一个工作副本，用于清洗和分块。在工作副本上保存由读者指定的原始数组位置标签。保留视频 ID、视频 URL、语言代码和 scrapedAt。保留 status 和 isAutoGenerated。
2. 相邻字幕条目的时间重叠时，将它们放在一起阅读。相同文字可能来自滚动字幕。滚动字幕会在下一个条目中再次显示同一句口述内容。只有在字幕条目和回放都表明实际只说了一遍时，才删除多余条目。在真实视频中，使用 [YouTube 按字幕行定位播放](https://support.google.com/youtube/answer/15930243?hl=en)功能回放该时刻。仅凭文字相同不足以证明这一点。保留实际再次说出、用于强调的内容。保留重复说出的指令。不要删除视频中所有相同的句子。为这项修改记录对应的原始字幕条目编号。
3. 将论断与其适用条件放在一起。将例子与它所说明的论断放在一起。将对比与它所限定的论断放在一起。将问题与答案放在一起。优先保留一个完整的短文段。不要按随意选定的秒数切分，也不要按随意选定的词数切分。特别长的文段可以在话题确实改变的位置切分。之后要检查，确保没有遗漏必要的限制条件。
4. 每个文本块建立一行。列名为 chunk_id、source_video_id、source_url、language、start_seconds、end_seconds、original_cue_indices、text 和 cleaned_text_version。start_seconds 是文本块内最早的字幕条目开始时间。end_seconds 是文本块内最晚的字幕条目结束时间。将这一对时间称为文段时间范围。文段时间范围可能包含静音或间隔。存在间隔意味着并非每一秒都有人说话。如果为了保留上下文而让文本块重叠，请记录重叠部分。重复证据只计 1 次。
5. 在进行任何搜索之前，先写 3 至 5 个问题。为每个问题写出有来源依据的答案。标记答案所需的每个要点。要点就是答案中一个必需的组成部分。仅有相同关键词还不够。加入一个字幕中没有证据可支持的问题。
6. 用相同的问题测试两种分块方式。在查看结果之前，写明要选取的文本块数量。两种分块方式都使用相同数量。本教学示例使用 1 个文本块。记录你选取的文本块 ID。记录该文本块是否包含完整答案及其适用条件。记录引用是否指向正确文段。人工阅读即可完成这项检查。如果你只是阅读，就不要声称运行了嵌入向量搜索。
7. 保留仍能包含所需上下文的最简单分块方式。它也必须保留明确的时间。缺少必要要点时，文本块更短并不代表更好。不要根据极小的样本集报告普遍提升。如果来源没有证据，就说明它无法回答。不要用看似合理的说法填补空白。

## 将这些操作用于虚构字幕条目

本节字幕条目是虚构的教学文本。VID-DEMO-01 不是真实的 YouTube ID。不要搜索它。原始示例语句使用英语，因此语言单元格填写 en。真实记录必须从来源复制 transcriptLanguageCode。本例没有真实 URL，也没有发布日期。

| 字幕条目 | start_seconds | end_seconds | text |
| --- | --- | --- | --- |
| 1 | 0 | 6 | 按来源 ID 存储文档。 |
| 2 | 5 | 9 | 按来源 ID 存储文档。 |
| 3 | 9 | 15 | 来源发生变化时，保留一个版本。 |
| 4 | 15 | 22 | 新版本不等于新来源。 |
| 5 | 22 | 29 | 只有来源 ID 和版本都相同时，才删除完全重复的导入记录。 |
| 6 | 29 | 36 | 保留不同版本，因为文本可能发生变化。 |

字幕条目 1 的时间为 0 至 6 秒。这里的 0 是真实的开始时间，不是用于代替未知值。字幕条目 2 的时间为 5 至 9 秒。两个时间范围有重叠，文字也相同。但文字相同仍不能证明实际只说了一遍。在这个虚构示例中，回放核查确实证明了这一点。字幕条目 2 重复显示了条目 1 中的同一句口述内容。请从工作文本中删除条目 2。为这项修改保留字幕条目编号 1 和 2。在未经修改的原始来源记录中保留全部 6 个字幕条目。

字幕条目 6 与条目 2 对应的不是同一次口述。条目 6 给出了保留不同版本的原因，因此要保留。不要删除视频中所有重复出现的观点。

下文两种分块方式都使用这个工作副本。它们共用同一份清洗结果。比较的是分块边界，不是两套清洗规则。cleaned_text_version 是你自行指定的标签，不是 Actor 字段。本例使用的标签是 clean-1。只要文本块覆盖了条目 2 原来的时间范围，字幕条目编号列表中就保留 2，但不再重复写入它的句子。

按时间分块时，在较短的字幕条目边界处切分。

T1 包含字幕条目编号 1、2 和 3，时间为 0 至 15 秒。清洗后的文本为：“按来源 ID 存储文档。来源发生变化时，保留一个版本。”

T2 是字幕条目 4，时间为 15 至 22 秒。文本为：“新版本不等于新来源。”

T3 是字幕条目 5，时间为 22 至 29 秒。文本为：“只有来源 ID 和版本都相同时，才删除完全重复的导入记录。”

T4 是字幕条目 6，时间为 29 至 36 秒。文本为：“保留不同版本，因为文本可能发生变化。”

按语义分块时，将每项论断与其限制条件放在一起。M1 说明什么用于标识文档，以及变化意味着什么。M2 说明何时可以删除重复导入的记录。这里确实发生了话题变化。

M1 包含字幕条目编号 1、2、3 和 4，时间为 0 至 22 秒。条目 2 仅用于来源追溯。保留的句子为：“按来源 ID 存储文档。来源发生变化时，保留一个版本。新版本不等于新来源。”

M2 包含字幕条目编号 5 和 6，时间为 22 至 36 秒。保留的句子为：“只有来源 ID 和版本都相同时，才删除完全重复的导入记录。保留不同版本，因为文本可能发生变化。”

0 至 22 秒是一个文段时间范围，取最早的开始时间和最晚的结束时间。这不代表每一秒都有人说话。M1 在 22 秒结束。M2 在 22 秒开始。它们共用一个边界，但没有共用句子。如果以后有意让文本块重叠，请记录重叠部分。重复证据只计 1 次。

这 2 行按语义分块的记录构成了通过下文虚构测试的文本块表。

| chunk_id | source_video_id | source_url | language | start_seconds | end_seconds | original_cue_indices | text | cleaned_text_version |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| M1 | VID-DEMO-01 | 无，虚构示例 | en | 0 | 22 | 1, 2, 3, 4 | 按来源 ID 存储文档。来源发生变化时，保留一个版本。新版本不等于新来源。 | clean-1 |
| M2 | VID-DEMO-01 | 无，虚构示例 | en | 22 | 36 | 5, 6 | 只有来源 ID 和版本都相同时，才删除完全重复的导入记录。保留不同版本，因为文本可能发生变化。 | clean-1 |

按时间分块的记录是比较用的数据集，不是最终选用的表。

| chunk_id | source_video_id | source_url | language | start_seconds | end_seconds | original_cue_indices | text | cleaned_text_version |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| T1 | VID-DEMO-01 | 无，虚构示例 | en | 0 | 15 | 1, 2, 3 | 按来源 ID 存储文档。来源发生变化时，保留一个版本。 | clean-1 |
| T2 | VID-DEMO-01 | 无，虚构示例 | en | 15 | 22 | 4 | 新版本不等于新来源。 | clean-1 |
| T3 | VID-DEMO-01 | 无，虚构示例 | en | 22 | 29 | 5 | 只有来源 ID 和版本都相同时，才删除完全重复的导入记录。 | clean-1 |
| T4 | VID-DEMO-01 | 无，虚构示例 | en | 29 | 36 | 6 | 保留不同版本，因为文本可能发生变化。 | clean-1 |

评判任何一种分块方式之前，问题就已固定。选取的文本块数量也已固定，为 1 个文本块。选择由人工完成。没有运行嵌入向量搜索，也没有运行数据库。

问题 1：什么用于标识文档？文档发生变化时该怎么办？答案需要 3 个要点。文档与来源 ID 关联。发生变化时，要保留一个版本。新版本不等于新来源。

问题 2：何时可以删除重复导入的记录？为什么要保留其他版本？答案需要 2 个要点。只有来源 ID 和版本都相同时，才删除。保留其他版本，因为文本可能发生变化。

问题 3：存储费用是多少美元？没有任何字幕条目说明以美元计的费用。该来源无法回答。

在这个虚构的人工比较中，问题 1 在按时间分块的一侧选取 T1，在按语义分块的一侧选取 M1。T1 包含来源 ID 和保留版本这两个要点。T1 在 15 秒结束，因此缺少字幕条目 4。没有条目 4，新版本可能被误解为新文档。这项对比就是适用条件。M1 保留了全部 3 个要点。单独使用条目 4 也不合格，因为它缺少来源 ID 和保留版本这两个要点。没有任何单个按时间划分的文本块包含全部 3 个要点。合并 T1 和 T2 可以将这些要点重新放在一起，但那采用的是 2 个文本块的规则。本测试不采用 2 个文本块的规则。

在这个虚构的人工比较中，问题 2 在按时间分块的一侧选取 T3，在按语义分块的一侧选取 M2。T3 包含删除规则，但缺少原因。原因是文本可能发生变化。没有这个原因，删除规则看起来会比本课所讲的适用范围更广。T4 包含原因，但缺少匹配规则。没有任何单个按时间划分的文本块包含这 2 个要点。M2 两者都包含。

任何文本块中都没有支持问题 3 的要点。即使文本块提到存储，也仍未给出价格。两种分块方式都必须标记为无依据。回复应说明该来源无法回答。

| 问题 | 能否回答 | 所需要点 | 选取的时间文本块 | 时间文本块是否完整 | 选取的语义文本块 | 语义文本块是否完整 | 引用时间范围（秒） |
| --- | --- | --- | --- | --- | --- | --- | --- |
| Q1 | 是 | 来源 ID；来源发生变化时保留一个版本；新版本不等于新来源 | T1 | 否 | M1 | 是 | 0-22 |
| Q2 | 是 | 来源 ID 和版本都相同；文本可能发生变化 | T3 | 否 | M2 | 是 | 22-36 |
| Q3 | 否 | 任何字幕条目都未说明以美元计的费用 | 无 | 无依据 | 无 | 无依据 | 无 |

这些引用时间范围内包含以下各段具体时间。

| 问题 | 时间范围（秒） | 字幕条目 | 作用 |
| --- | --- | --- | --- |
| Q1 | 0-6 | 1 | 来源 ID，已保留在文本中 |
| Q1 | 5-9 | 2 | 同一句口述内容，已删除文字，保留字幕条目编号 |
| Q1 | 9-15 | 3 | 来源发生变化时，保留一个版本 |
| Q1 | 15-22 | 4 | 新版本不等于新来源 |
| Q2 | 22-29 | 5 | 只有来源 ID 和版本都相同时，才删除重复记录 |
| Q2 | 29-36 | 6 | 保留其他版本，因为文本可能发生变化 |

这里的评分是通过检查的数量。完整支持率只计算可回答的问题。

完整支持率 = 所选文本块包含全部所需要点的可回答问题数 / 可回答问题数

按时间分块 = 0/2

按语义分块 = 2/2

弃答指不作回答。弃答计数只计算那个没有字幕证据的问题。

弃答率 = 正确拒绝回答的次数 / 无依据的问题数 = 1/1

不要把 1/1 加到 2 上。对无依据问题的检查单独计算。

这些分数只属于这个虚构的人工比较。它们不是嵌入向量基准测试结果。基准测试应提供实测分数。它们也不是实测的质量提升。质量提升应是在真实搜索中证实的改善。不要据此推断其他视频也会提升。对另一个视频，较短的时间文本块可能已经包含全部要点。此时，能通过检查且更简单的分块方式可能就是按时间分块。

虚构回复的引用应落在保留的时间范围内。之后由复核人员检查回放。VID-DEMO-01 没有真实页面，因此回放步骤也是虚构的。对于真实视频，请使用 [YouTube 按字幕行定位播放](https://support.google.com/youtube/answer/15930243?hl=en)功能。

问题 1 的虚构回复：“来源 ID 用于标识文档。来源发生变化时，保留一个版本。新版本不等于新来源。”引用：VID-DEMO-01，0-22 秒，字幕条目编号 1、2、3 和 4。实际口述的要点位于条目 1、3 和 4。条目 2 仅用于记录删除操作。

问题 2 的虚构回复：“只有来源 ID 和版本都相同时，才删除完全重复的导入记录。保留不同版本，因为文本可能发生变化。”引用：VID-DEMO-01，22-36 秒，字幕条目编号 5 和 6。

问题 3 的虚构回复：“该来源无法回答。没有任何字幕条目说明以美元计的存储费用。”没有可引用的时间范围。

在只选取 1 个文本块的规则下，按语义分块能够保留所需上下文。每个答案都包含在 1 个文本块中，时间也保持明确。按时间分块时，每块更短，但会遗漏一个要点。对于这个虚构案例，请保留 M1 和 M2。不要把这个选择当作适用于所有视频的规则。[添加更多视频之前](/zh-Hans/articles/%E4%BB%8E%E6%90%9C%E7%B4%A2%E7%BB%93%E6%9E%9C%E6%9E%84%E5%BB%BA%E5%AD%97%E5%B9%95%E8%AF%AD%E6%96%99%E5%BA%93/)，请对你自己的文件执行同样的 7 项操作。

## 下一步操作

选择一个你已知的视频。使用 [YouTube Transcript Scraper](https://apify.com/chronometrica/youtube-transcript-scraper) 和 Task [YouTube Transcripts for RAG Pipelines](https://apify.com/chronometrica/youtube-transcript-scraper/examples/youtube-transcripts-for-rag)。保留带时间戳的 JSON。制作两组文本块。添加更多视频之前，先用已知答案的问题测试。

## 来源和延伸阅读

- [最初的 RAG 论文](https://arxiv.org/abs/2005.11401)
- [YouTube 按字幕行定位播放](https://support.google.com/youtube/answer/15930243?hl=en)
- [YouTube 字幕提取](https://chronometrica.com/zh-Hans/articles/youtube-%E6%96%87%E5%AD%97%E7%A8%BF%E6%8F%90%E5%8F%96%E4%B8%8E%E7%BC%BA%E5%A4%B1%E5%AD%97%E5%B9%95%E6%A3%80%E6%9F%A5/)
- [YouTube Transcript Scraper](https://apify.com/chronometrica/youtube-transcript-scraper)
- [YouTube Transcripts for RAG Pipelines](https://apify.com/chronometrica/youtube-transcript-scraper/examples/youtube-transcripts-for-rag)