Transcriptions YouTube LlamaIndex : Interroger un ensemble de vidéos

Un pipeline de transcription YouTube LlamaIndex est trois étapes : récupérer les transcriptions en tant qu'objets Document, construire un VectorStoreIndex, poser des questions à travers toutes les vidéos à la fois. Voici le tout dans un script, plus l'une des astuce de chunking qui ruine la plupart des premières tentatives.
Récupérer les transcriptions en tant que documents
Je gère youtube2text.org, une API REST qui retourne les transcriptions YouTube en JSON — pas de grattage de votre propre IP, ce qui compte à partir du moment où cela fonctionne n'importe où d'autre que votre portable (voir pourquoi les gratteurs locaux se font bloquer si vous êtes curieux). Un GET par vidéo :
import requests
from llama_index.core import Document, VectorStoreIndex
API_KEY = "yt_your_key_here"
VIDEOS = [
"https://www.youtube.com/watch?v=VIDEO_ID_1",
"https://www.youtube.com/watch?v=VIDEO_ID_2",
"https://www.youtube.com/watch?v=VIDEO_ID_3",
]
def fetch_transcript(url: str) -> dict:
resp = requests.get(
"https://youtube2text.org/api/transcribe",
params={"url": url},
headers={"x-api-key": API_KEY},
timeout=90,
)
resp.raise_for_status()
return resp.json()["result"]
docs = []
for url in VIDEOS:
r = fetch_transcript(url)
docs.append(Document(
text=r["content"],
metadata={"videoId": r["videoId"], "title": r["title"]},
))
Pour une clé, connectez-vous avec Google sur youtube2text.org/app/keys, ou tirez la clé démo partagée de GET https://youtube2text.org/api/demo-key (5 vidéos/mois par IP — bien pour cet exemple de trois vidéos, pas pour un canal).
L'astuce du chunking : les sous-titres auto-générés n'ont pas de ponctuation
Le parseur de nœud par défaut de LlamaIndex est SentenceSplitter, qui trouve les limites de chunk aux fins de phrase. Les sous-titres téléchargés manuellement en ont. Les sous-titres générés automatiquement n'en ont souvent pas — vous obtenez quarante minutes de texte en minuscules sans points, SentenceSplitter ne trouve rien à diviser, et vous vous retrouvez avec des chunks gonflés et maladroits.
Le splitting basé sur les jetons contourne complètement le problème :
from llama_index.core.node_parser import TokenTextSplitter
splitter = TokenTextSplitter(chunk_size=512, chunk_overlap=64)
512 jetons avec 64 chevauchements a été le sweet spot dans mon test : assez grand pour qu'un chunk porte une pensée complète, assez petit pour que la récupération reste précise.
Construire l'index et l'interroger
index = VectorStoreIndex.from_documents(docs, transformations=[splitter])
query_engine = index.as_query_engine(similarity_top_k=4)
response = query_engine.query("What did they say about pricing changes?")
print(response)
for node in response.source_nodes:
meta = node.metadata
print(f'- {meta["title"]} (https://www.youtube.com/watch?v={meta["videoId"]})')
Parce que chaque Document porte videoId et title en métadonnées, chaque chunk récupéré sait de quelle vidéo il provient — source_nodes vous donne des liens de travail vers les sources. Cela utilise n'importe quel modèle d'intégration et LLM que vous avez configuré dans Settings ; la configuration OpenAI par défaut fonctionne immédiatement si OPENAI_API_KEY est défini.
La limitation que vous devriez connaître
L'API retourne les transcriptions en tant que texte simple sans horodatages, donc vos citations se résolvent en une vidéo, pas à un moment à l'intérieur. "Cette affirmation provient de la vidéo de répartition Q3" est réalisable ; "à 14:32" ne l'est pas. Pour la plupart des cas d'utilisation Q&A, l'attribution au niveau vidéo est suffisante, et honnêtement, le texte du chunk plus un lien vidéo met un humain au bon endroit en moins d'une minute.
Notez aussi les deux codes d'erreur qui valent la peine d'être traités dans la boucle de récupération : TRANSCRIPT_UNAVAILABLE (404, la vidéo n'a pas de sous-titres — ignorez-la) et RATE_LIMIT_EXCEEDED (429, vient avec retryAfterSeconds dans le corps de l'erreur).
Passer au-delà de quelques vidéos
Trois vidéos c'est une démo. Pour un canal entier, vous voulez le flux RSS pour la découverte de vidéos, la récupération consciente des quotas, et un magasin de vecteurs persistant — je couvre ce pipeline dans RAG sur un canal YouTube. Utilisateur de LangChain à la place ? Le même motif de chargeur, cadre différent.
La limite gratuite couvre 5 vidéos par mois ; le plan pro en fait 500 pour $9.99, ce qui indexe confortablement la plupart des canaux. Clés sur youtube2text.org/app/keys.