LlamaIndex YouTube-transkripsjoner: Spør et sett med videoer

En LlamaIndex YouTube transkripsjon rørledning er tre trinn: hent transkripsjoner som Document-objekter, bygg en VectorStoreIndex, still spørsmål på tvers av alle videoene på en gang. Her er hele tingen i ett skript, pluss det ene fragmenterings-problemet som ødelegger de fleste første forsøk.
Hent transkripsjoner som dokumenter
Jeg kjører youtube2text.org, en REST API som returnerer YouTube-transkripsjoner som JSON — ingen skraping fra din egen IP, noe som betyr når dette kjøres noe annet sted enn bærbare datamaskinen (se hvorfor lokale skrapere blir blokkert hvis du er nysgjerrig). En GET per video:
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"]},
))
For en nøkkel, logg inn med Google på youtube2text.org/app/keys, eller trekk den delte demo-nøkkelen fra GET https://youtube2text.org/api/demo-key (5 videoer/måned per IP — OK for dette tre-video-eksemplet, ikke for en kanal).
Fragmenterings-gotchaen: auto-undertekster har ingen punktum
LlamaIndex sin standard node-parser er SentenceSplitter, som finner fragment-grenser ved setnings-ender. Manuelt opplastet undertekster har disse. Auto-generert undertekster har ofte ikke — du får førti minutter med små bokstaver tekst uten perioder, SentenceSplitter finner ingenting å dele på, og du ender opp med oppblåste, ubekvem fragmenter.
Token-basert splitting omgår problemet helt:
from llama_index.core.node_parser import TokenTextSplitter
splitter = TokenTextSplitter(chunk_size=512, chunk_overlap=64)
512 tokens med 64 overlapping har vært sweet spot i min testing: stor nok at et fragment bærer en komplett tanke, lite nok at hentning blir presis.
Bygg indeksen og spør den
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"]})')
Fordi hvert Document bærer videoId og title i metadata, vet hvert hentet fragment hvilken video det kom fra — source_nodes gir deg funksjons-lenker tilbake til kilder. Dette bruker uansett embedding-modell og LLM du har konfigurert i Settings; standard OpenAI-oppsett fungerer ut av boksen hvis OPENAI_API_KEY er satt.
Begrensningen du bør vite om
APIen returnerer transkripsjoner som vanlig tekst uten tidsstempel, så sitater din oppløser seg til en video, ikke et øyeblikk inni den. "Dette kravet kom fra Q3-resultats-oversikts-videoen" er oppnåelig; "på 14:32" er ikke. For mest Q&A-brukstilfeller er video-nivå attribusjon nok, og ærlig talt, fragment-tekst pluss en video-lenke får en menneske til det riktige stedet på under ett minutt.
Også merk de to feilkodene verdt å håndtere i hent-løkken: TRANSCRIPT_UNAVAILABLE (404, video har ingen undertekster — hopp den) og RATE_LIMIT_EXCEEDED (429, kommer med retryAfterSeconds i feil-kropp).
Skalering forbi en håndful videoer
Tre videoer er en demo. For en hel kanal ønsker du RSS-feeden for video-oppdagelse, kvote-bevisst henting og en vedvarende vektor-butikk — jeg dekker den rørledningen i RAG over en YouTube-kanal. LangChain-bruker i stedet? Samme loader-mønster, annet rammeverk.
Gratis nivå dekker 5 videoer per måned; pro-plan gjør 500 for $9.99, som komfortabelt indekserer de fleste kanalene. Nøkkler på youtube2text.org/app/keys.