

# 為 RAG 準備保留來源時間標記的 YouTube 逐字稿

保留附有時間的字幕行，將每項主張與其成立條件放在一起，再用已知答案的問題測試文字片段。字幕行是附有時間的一行字幕。文字片段是已儲存、可由搜尋傳回的一段文字。條件是主張成立時的限制。每個例子及每項對比，都要與相關主張放在一起。RAG 指檢索增強生成。檢索會在模型回答前，找出已儲存的文字。語意是指以意思為依據。沒有一個固定秒數最適合所有影片。也沒有一個固定字數最適合所有影片。應由測試決定分組方式。先從 1 段影片開始。保留原始資料列，並在工作副本上編輯。只有在播放影片後，確認實際只說過 1 次，才移除重複內容。保留每個原始字幕行編號。使用已知答案的問題，再加 1 條影片無法回答的問題。嵌入向量是一組數值，用來尋找相似的文字。資料庫並非必需。這個方法有明確限制。下文的分數是虛構的人工比較。這不是實際量測的搜尋測試，亦不能顯示普遍的改善。擷取 1 次字幕，不能證明文字與說話內容一致，也不能證明這些字幕日後仍會存在。如果字幕沒有相關事實，便應說明來源無法回答。

模型是撰寫回覆的程式。生成就是這個撰寫步驟。檢索會先找出文字。模型應根據找出的文字撰寫回覆。原始的 [RAG 論文](https://arxiv.org/abs/2005.11401)支持結合檢索與生成的方法。它沒有為影片選定文字片段大小，也沒有為下文的虛構計數提供依據。

有些開發者會問，遇到重複或跳接的字幕時，按時間分組還是按語意分組較好。沒有一種分組方式最適合所有影片。請測試你自己的影片。

## 取得 1 份附有時間標記的逐字稿

JSON 是一種文字資料格式，以文字表示結構化資料。字幕行索引是讀者自行指定的標籤，用來標示 segments 陣列中的 1 個原始位置。Actor 並未承諾輸出字幕行索引欄位。教學表格的位置從 1 開始計算。第 1 個位置是 1。原始資料列須保持不變。將這些標籤及其來源追溯資料儲存在工作副本中。

Actor 是在線上為你執行的資料收集程式。Task 是為 Actor 儲存的一組輸入設定。如果你已有字幕，無須使用 Actor 也可依照這個方法操作。如果你仍需要字幕，請依照 [YouTube 字幕擷取](https://chronometrica.com/zh-Hant/articles/%E5%8F%96%E5%BE%97-youtube-%E9%80%90%E5%AD%97%E7%A8%BF-%E6%AA%A2%E6%9F%A5%E7%BC%BA%E5%B0%91%E5%AD%97%E5%B9%95/)的步驟操作。本頁不會重複該項工作。

2026年10月13日核查的公開收集程式是 Actor 組建版本 0.1.43。成功讀取字幕時，該版本會提供附有時間標記的字幕區段。每個字幕區段是 json 中的 1 行字幕。後續版本可能有所不同。核查日期是觀察日期，並非影片發佈日期。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 輸出的資料粒度，是每個資料集資料列代表 1 段成功處理且不重複的影片。資料集資料列是 1 筆已儲存的記錄。讀者自行建立的文字片段表，其資料粒度是每列代表 1 個文字片段。文字片段並非資料集資料列。所有文字片段欄位都由讀者自行建立。Actor 接收影片的直接網址，或你已知的影片 ID。它不會替你尋找影片。Task 會傳回 json、text 及 llm。引用來源時應使用 json。來源引用是指支持某項主張的影片及時間範圍。llm 的結果是 llmText。llmText 是可直接放入提示的文字。提示是你傳給模型的訊息。llmText 不能取代字幕區段的時間。

Actor 不會建立文字片段，也不會建立嵌入向量或索引。索引是為搜尋而儲存的資料結構。Actor 不會檢索文字片段、回答問題或為答案評分。你須手動清理、分組及測試。

在未經修改的資料列中保留以下來源欄位。

| 欄位 | 須保留的內容 |
| --- | --- |
| videoId | 影片 ID |
| videoUrl | 影片的直接網址 |
| transcriptLanguageCode | 字幕語言代碼 |
| isAutoGenerated | 字幕軌是否標示為自動產生 |
| segments | 字幕行清單 |
| scrapedAt | 收集此資料列的時間 |
| status | 執行時傳回的狀態 |

字幕軌是字幕的 1 個語言版本。每個字幕區段都要保留以下欄位。

| 欄位 | 須保留的內容 |
| --- | --- |
| startSeconds | 字幕行的開始時間，以秒為單位 |
| endSeconds | 字幕行的結束時間，以秒為單位 |
| durationSeconds | 字幕行的持續時間，以秒為單位 |
| text | 字幕行的文字 |

如果 preferredLanguages 為空，執行時會選取 1 條可用的字幕軌。請檢查 transcriptLanguageCode。空白清單不代表你已選定語言。加入第 2 段影片前，先訂下 1 套語言規則。在資料列中保留 isAutoGenerated。自動產生是指字幕軌標示為由機器製作。機器字幕可能會重複句子。單憑這個標記，不能證明文字有誤。

失敗輸入的詳細資料位於 OUTPUT。請設定 includeFailedInputDetails，讓這些資料保持可見。失敗輸入不等於字幕行數為 0 的逐字稿。未知時間不可填作 0。真實字幕行可以從 0 秒開始。未知與零並不相同。scrapedAt 是收集該資料列的時間，並非影片發佈時間。

核查 1 次字幕，不能證明文字與說話內容一致，也不能證明這些字幕日後仍會存在。已核查的 Task 只是一個起點。它包含示範影片。請將其換成你選定的 1 段公開影片。Task 不會清理、分組或測試。

## 依次完成 7 個步驟

請依次完成各步驟。如果先分組、後清理，重複內容可能會看似 2 項事實。如果在寫問題前便評分，你可能會過早偏向某種分組方式。先寫問題，再用相同的問題測試 2 種分組方式。

1. 將收集程式傳回的原始資料列原樣儲存。不要編輯該資料列，也不要修改原始來源。建立工作副本，用於清理及分組。將讀者自行指定的原始陣列位置標籤儲存在工作副本中。保留影片 ID、影片網址、語言代碼及 scrapedAt。保留 status 及 isAutoGenerated。
2. 如果相鄰字幕行的時間重疊，請一併閱讀。相同文字可能來自滾動字幕。滾動字幕會在下一行再次顯示同一句說話。只有在字幕行及影片播放都顯示實際只說過 1 次時，才移除多出的字幕行。在真實影片上，使用 [YouTube 按字幕行跳轉](https://support.google.com/youtube/answer/15930243?hl=en)功能播放該時刻。單憑文字相同並不足以證明。為強調而再次說出的內容須保留。重複說出的指示也須保留。不要刪除影片中所有相同句子。記下這次修改所涉及的原始字幕行編號。
3. 將主張與其成立條件放在一起。將例子與它所說明的主張放在一起。將對比與它所限制的主張放在一起。將問題與答案放在一起。優先保留完整而簡短的文字片段。不要任意按某個秒數或字數切分。很長的文字片段可以在主題確實改變之處分開。然後檢查有沒有遺漏必要的限制條件。
4. 每個文字片段建立 1 個資料列。欄位為 chunk_id、source_video_id、source_url、language、start_seconds、end_seconds、original_cue_indices、text 及 cleaned_text_version。start_seconds 是片段內最早的字幕行開始時間。end_seconds 是片段內最遲的字幕行結束時間。這 2 個時間合稱片段時間範圍。片段時間範圍可能涵蓋靜默或空檔。有空檔不代表每 1 秒都有說話。如果為提供上下文而讓文字片段重疊，請記錄重疊部分。重複證據只計算 1 次。
5. 進行任何搜尋前，先寫 3 至 5 條問題。為每條問題寫出有來源支持的答案。標示答案所需的每個分句。分句是答案中 1 個不可缺少的部分。只有共同關鍵字並不足夠。加入 1 條字幕沒有提供證據的問題。
6. 對 2 種分組方式使用相同問題。查看結果前，先寫下要選取多少個文字片段。2 種分組方式須使用相同數目。本教學例子使用 1 個文字片段。記錄所選片段的 ID。記錄該片段是否包含完整答案及其條件。記錄來源引用是否指向正確的文字片段。人工閱讀便可完成這項核查。如果只作閱讀，不可聲稱曾執行嵌入向量搜尋。
7. 採用仍能保留必要上下文的最簡單分組方式。它也必須保留清楚的時間。若遺漏必要分句，較短的文字片段並不較好。不要根據極少量資料宣稱有普遍改善。如果來源沒有證據，便應說明它無法回答。不要用看似合理的說法填補空白。

## 將步驟應用於虛構字幕行

本節的字幕行是虛構教學文字。VID-DEMO-01 並非真實 YouTube ID。不要搜尋它。這些字幕原文是英文，因此語言儲存格填作 en。真實資料列必須從來源複製 transcriptLanguageCode。這裏沒有真實網址，也沒有發佈日期。

| 字幕行 | 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。在這次修改的記錄中保留字幕行編號 1 及 2。未經修改的來源資料列仍須保留全部 6 行字幕。

字幕行 6 與字幕行 2 並非同一次說話。字幕行 6 說明保留不同版本的原因。因此須保留。不要清除影片中所有重複出現的觀點。

下文 2 種分組方式都使用該工作副本。它們共用同一份清理結果。比較的是分段位置，而非 2 套清理規則。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 秒是片段時間範圍。它採用最早的開始時間及最遲的結束時間，並不代表每 1 秒都有說話。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 及保留版本的分句。沒有任何 1 個按時間分組的文字片段包含全部 3 個分句。合併 T1 及 T2 可以將這些分句重新放在一起，但這等於採用 2 個文字片段的規則。本測試不採用 2 個文字片段的規則。

在這個虛構例子中，問題 2 的人工選擇是：按時間分組選 T3，按語意分組選 M2。T3 包含移除規則，但缺少原因。原因是文字可能改變。沒有這個原因，移除規則看來會比本課所教的適用範圍更廣。T4 包含原因，但缺少資料相符的規則。沒有任何 1 個按時間分組的文字片段同時包含這 2 個分句。M2 則包含兩者。

沒有任何文字片段包含支持問題 3 的分句。即使片段提及儲存，也沒有列出價格。2 種分組方式都必須標示為沒有證據支持。回覆應說明來源無法回答。

| 問題 | 能否回答 | 必要分句 | 所選的按時間分組片段 | 按時間分組片段是否完整 | 所選的按語意分組片段 | 按語意分組片段是否完整 | 引用時間範圍（秒） |
| --- | --- | --- | --- | --- | --- | --- | --- |
| 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 個文字片段內，時間也保持清楚。按時間分組的每個片段較短，但會遺漏 1 個分句。在這個虛構案例中，應保留 M1 及 M2。不要將這個選擇視為適用於所有影片的規則。[加入更多影片前](/zh-Hant/articles/%E5%BE%9E%E6%90%9C%E5%B0%8B%E7%B5%90%E6%9E%9C%E5%BB%BA%E7%AB%8B-youtube-%E9%80%90%E5%AD%97%E7%A8%BF%E8%AA%9E%E6%96%99%E5%BA%AB/)，先對你自己的檔案執行相同的 7 個步驟。

## 下一步

選用你已知的 1 段影片。使用 [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。建立 2 組文字片段。加入更多影片前，先用已知答案的問題測試。

## 來源與延伸閱讀

- [原始 RAG 論文](https://arxiv.org/abs/2005.11401)
- [YouTube 按字幕行跳轉](https://support.google.com/youtube/answer/15930243?hl=en)
- [YouTube 字幕擷取](https://chronometrica.com/zh-Hant/articles/%E5%8F%96%E5%BE%97-youtube-%E9%80%90%E5%AD%97%E7%A8%BF-%E6%AA%A2%E6%9F%A5%E7%BC%BA%E5%B0%91%E5%AD%97%E5%B9%95/)
- [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)