

# YouTubeの文字起こしを出典のタイムスタンプ付きでRAG用に整える

時刻付きのキューを残し、各主張をその条件とまとめ、答えがわかっている質問でチャンクを検証します。キューとは、時刻が付いた字幕の1行です。チャンクとは、検索結果として返せるように保存した文章のまとまりです。条件とは、主張が成り立つ範囲を限定するものです。各具体例や対比も、その主張と一緒に残します。RAGは検索拡張生成の略です。検索では、モデルが回答する前に、保存済みのテキストを見つけます。セマンティックとは、意味に基づくということです。すべての動画に最適な固定の秒数はありません。すべての動画に最適な固定の単語数もありません。検証によって、まとめ方を選びます。まずは1本の動画から始めます。元の行を保存し、作業用コピーを編集します。再生して、発話が1回だったと確認できた場合にだけ、重複を削除します。元のキュー番号はすべて残します。答えがわかっている質問に加え、その動画では答えられない質問も1つ使います。埋め込みとは、似た内容のテキストを扱うための数値のリストです。データベースは必須ではありません。この方法には明確な限界があります。以下のスコアは、説明用に作った手作業の比較です。実測した検索テストではありません。一般的な改善を示すものでもありません。字幕を1回取得しただけでは、字幕の言葉が発話と一致するとは証明できません。その字幕が後でも利用できることも証明できません。字幕に必要な事実がなければ、出典からは回答できないと伝えます。

モデルとは、返信文を書くプログラムです。生成とは、その文章を書く処理です。検索では、先にテキストを見つけます。モデルは、見つかったテキストに基づいて書くことを想定しています。[RAGの原論文](https://arxiv.org/abs/2005.11401)は、検索と生成を組み合わせる方法を裏付けています。動画用のチャンクサイズを定めたものではありません。以下の架空の集計結果を裏付けるものでもありません。

繰り返しや内容の飛びがある字幕には、時間でまとめる方法と意味でまとめる方法のどちらがよいのか、と考える開発者もいます。どちらの方法も、すべての動画に最適とは限りません。自分の動画で検証してください。

## タイムスタンプ付きの文字起こしを1件取得する

JSONは、テキスト形式のデータフォーマットです。構造化されたデータをテキストとして記述します。キューインデックスとは、segments配列内の元の位置を示すために、読者が付けるラベルです。キューインデックスがActorの出力フィールドとして提供される保証はありません。説明用の表では、位置を1から数えます。最初の位置は1です。元の行は変更せずに残します。これらのラベルと元データとの対応関係は、作業用コピーに保存します。

Actorとは、利用者のためにオンラインで動作するデータ収集プログラムです。Taskとは、Actorの入力設定を保存したものです。すでに字幕があれば、Actorを使わずにこの方法を実行できます。字幕がまだ必要な場合は、[YouTube字幕の抽出](https://chronometrica.com/ja/articles/youtube-%E6%96%87%E5%AD%97%E8%B5%B7%E3%81%93%E3%81%97%E3%81%AE%E5%8F%96%E5%BE%97-%E5%AD%97%E5%B9%95%E3%81%AE%E7%A2%BA%E8%AA%8D/)の手順に従ってください。このページでは、その作業を繰り返し説明しません。

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)です。

ここで、役割の範囲を明確にします。粒度とは、1行が何を表すかということです。Actorの出力では、データセットの各行が、取得に成功した重複のない1本の動画を表します。データセットの1行とは、保存された1件のレコードです。読者が作るチャンク表では、1行が1つのチャンクを表します。チャンクは、データセットの行ではありません。チャンクの列は、すべて読者が作成します。Actorには、動画の直接URLか、すでにわかっている動画IDを入力します。Actorが動画を探すわけではありません。Taskはjson、text、llmを返します。出典を示すにはjsonを使います。出典の参照情報とは、主張の根拠となる動画とその時間範囲です。llmの結果はllmTextです。llmTextは、プロンプトに使える状態のテキストです。プロンプトとは、モデルに送るメッセージです。llmTextは、セグメントの時刻の代わりにはなりません。

Actorはチャンクを作りません。埋め込みも作りません。インデックスも構築しません。インデックスとは、検索のために保存するデータ構造です。Actorは文章の検索・取得を行いません。質問への回答もしません。回答の採点もしません。データの整備、グループ分け、検証は手作業で行います。

変更せずに保存する元の行には、次の出典フィールドを残します。

| フィールド | 保存する内容 |
| --- | --- |
| videoId | 動画ID |
| videoUrl | 動画の直接URL |
| transcriptLanguageCode | 字幕の言語コード |
| isAutoGenerated | 字幕トラックに自動生成の印が付いているかどうか |
| segments | キューのリスト |
| scrapedAt | この行を収集した日時 |
| status | 実行結果として返された状態 |

トラックとは、1つの言語版の字幕です。各セグメントには、次のフィールドを残します。

| フィールド | 保存する内容 |
| --- | --- |
| startSeconds | キューの開始時刻。単位は秒 |
| endSeconds | キューの終了時刻。単位は秒 |
| durationSeconds | キューの長さ。単位は秒 |
| text | キューの文言 |

preferredLanguagesが空の場合、実行時に利用可能な字幕トラックが選ばれます。transcriptLanguageCodeを確認してください。リストが空でも、自分で言語を選んだことにはなりません。2本目の動画を追加する前に、言語の選択ルールを1つ決めます。isAutoGeneratedも行と一緒に残します。自動生成とは、そのトラックに機械生成の印が付いているという意味です。機械生成の字幕では、同じ行が繰り返されることがあります。ただし、その印だけでは、字幕の言葉が間違っているとは証明できません。

処理に失敗した入力の詳細はOUTPUTにあります。includeFailedInputDetailsを設定し、その詳細を確認できるようにします。入力の処理に失敗した状態は、キューが0件の文字起こしではありません。時刻が不明な場合に0を記入しないでください。実際のキューが0秒から始まることはあります。不明と0は同じではありません。scrapedAtは、その行を収集した日時です。動画の公開日時ではありません。

字幕を1回確認しただけでは、字幕の言葉が発話と一致するとは証明できません。その字幕が後でも利用できることも証明できません。確認済みのTaskは、あくまで出発点です。サンプル動画が含まれています。それらを、自分で選んだ1本の公開動画に置き換えてください。Taskはデータの整備、グループ分け、検証を行いません。

## 7つの手順に従う

手順は順番どおりに実行します。データを整備する前にグループ分けすると、重複した内容を2つの事実と見なすおそれがあります。質問を書く前に採点すると、早い段階で一方のまとめ方を有利に評価してしまう可能性があります。先に質問を書きます。その後、同じ質問を両方のまとめ方に使います。

1. 収集ツールから届いた行を、そのまま保存します。その行は編集しません。元の出典データを変更しないでください。データの整備とグループ分けには、作業用コピーを作ります。読者が付けた、元の配列位置を示すラベルを作業用コピーに保存します。動画ID、動画URL、言語コード、scrapedAtを残します。statusとisAutoGeneratedも残します。
2. 隣り合うキューの時刻が重なっている場合は、それらを続けて読みます。同じ言葉が、繰り返し表示される字幕である可能性があります。この形式の字幕では、1回の発話が次のキューにも再び書かれます。キューと動画の再生によって、発話が1回だったと確認できる場合にだけ、余分なキューを削除します。[YouTubeで字幕の行から該当箇所へ移動する機能](https://support.google.com/youtube/answer/15930243?hl=en)を使い、実際の動画でその箇所を再生します。言葉が同じというだけでは証拠になりません。強調のために実際に繰り返された発話は残します。繰り返された指示も残します。動画内の同じ文をすべて削除してはいけません。変更の記録に、元のキュー番号を書きます。
3. 主張とその条件を一緒にまとめます。具体例は、それが説明する主張とまとめます。対比は、それによって範囲が限定される主張とまとめます。質問と回答も一緒に残します。短くても内容が完結する1つの文章のまとまりを優先します。任意の秒数で区切らないでください。任意の単語数でも区切らないでください。非常に長い文章は、実際に話題が変わる箇所で分割してもかまいません。その場合は、必要な限定条件が切り離されていないか確認します。
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は、チャンク内で最も遅いキューの終了時刻です。この組を、文章の時間範囲と呼びます。文章の時間範囲には、無音や空白の時間が含まれる場合があります。時間の空白があるからといって、範囲内のすべての秒で発話があったことにはなりません。文脈を保つためにチャンクを重ねる場合は、その重複を記録します。重複した根拠は1回だけ数えます。
5. 検索する前に、3〜5個の質問を書きます。各質問について、出典に裏付けられた回答を書きます。回答に必要な要素をすべて明示します。ここでいう要素とは、回答に必要な1つの部分です。共通のキーワードがあるだけでは不十分です。字幕に根拠がない質問も1つ含めます。
6. 両方のまとめ方に、同じ質問を使います。内容を見る前に、選択するチャンク数を書きます。両方のまとめ方で、同じ数を使います。この説明例では、1つのチャンクを使います。選択したチャンクIDを記録します。そのチャンクに回答の全内容と条件が含まれているかを記録します。出典の参照情報が、正しい文章を指しているかも記録します。これは、人が読んで行えます。読んだだけの場合に、埋め込み検索を実行したと主張してはいけません。
7. 必要な文脈を保てる、最も単純なまとめ方を残します。時刻も明確に保つ必要があります。必要な要素が欠けるなら、短いチャンクのほうがよいとはいえません。ごく小さなデータ群から、一般的な改善を報告しないでください。出典に根拠がなければ、回答できないと伝えます。もっともらしい説明で不足を埋めてはいけません。

## 架空のキューに手順を適用する

この節のキューは、説明用に作った架空のテキストです。VID-DEMO-01は実在するYouTube IDではありません。検索しないでください。元の文は英語なので、languageのセルは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と同じ1回の発話を繰り返しています。作業用テキストからキュー2を削除します。その変更の記録には、キュー番号1と2を残します。変更しない元の行には、6つのキューをすべて残します。

キュー6は、キュー2と同じ発話ではありません。キュー6は、異なるバージョンを残す理由を示しています。そのため、残します。動画内で繰り返される考えをすべて削除してはいけません。

以下の両方のまとめ方で、この作業用コピーを使います。データの整備結果は共通です。比較するのは区切る位置であり、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秒は、文章の時間範囲です。最も早い開始時刻と、最も遅い終了時刻を使っています。すべての秒が発話で埋まっているという意味ではありません。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には理由がありますが、一致を求めるルールがありません。時間でまとめたチャンクには、両方の要素を単独で含むものがありません。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を残します。この選択を、すべての動画に当てはまるルールと見なさないでください。[動画を追加する前に](/ja/articles/youtube-%E6%A4%9C%E7%B4%A2%E7%B5%90%E6%9E%9C%E3%81%8B%E3%82%89%E4%BD%9C%E3%82%8B%E5%AD%97%E5%B9%95%E3%82%B3%E3%83%BC%E3%83%91%E3%82%B9/)、自分のファイルで同じ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/ja/articles/youtube-%E6%96%87%E5%AD%97%E8%B5%B7%E3%81%93%E3%81%97%E3%81%AE%E5%8F%96%E5%BE%97-%E5%AD%97%E5%B9%95%E3%81%AE%E7%A2%BA%E8%AA%8D/)
- [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)