Black Friday · 30% off

Get 30% off
Bloga dön
Entegrasyonlar

How to Build a RAG Pipeline with YouTube Transcripts

A working RAG pipeline over YouTube video transcripts: collect transcripts across a video list, chunk them, embed and store the vectors, retrieve the relevant chunks, and generate a cited answer - full code for every step, plus how to keep the index fresh.

00:09:00 · SEP 27, 2026 · GÜNCELLENDI OCT 09, 2026

Hızlı yanıt

Her videonun transkriptini barındırılan bir API üzerinden alın, metni parçalara bölün, parçaları embedding'e dönüştürün ve vektörleri saklayın - sorgu anında ise soruyu embedding'e dönüştürün, en yakın parçaları alın ve bunları kaynak videoya atıf içeren, temellendirilmiş bağlam olarak bir LLM'e verin.
01

Transkriptleri toplayın

panelden bir anahtar alın (100 ücretsiz kredi, kart gerekmez) ve her videonun transkriptini id'sine göre alın. Krediler video dakikası başına değil, istek başına alınır, bu yüzden 3 saatlik bir ders 2 dakikalık bir klip ile aynı 1 krediye mal olur - bir kanalın tüm arşivini içeri aktarırken bu önemlidir:

async function fetchTranscript(videoId: string) {
  const res = await fetch(
    `https://getyoutubetranscript.com/api/v1/transcript?v=${videoId}`,
    { headers: { Authorization: `Bearer ${process.env.GETYOUTUBETRANSCRIPT_API_KEY}` } }
  );
  const json = await res.json();
  if (!json.success) throw new Error(json.message);
  return json.data as { video_id: string; title: string; transcript: string; word_count: number };
}

const videoIds = ['dQw4w9WgXcQ', 'jNQXAC9IVRw' /* ... */];
const videos = await Promise.all(videoIds.map(fetchTranscript));

video_id ve title, transkript metniyle birlikte döner - 5. adımın yanıtı geri atıfladığı şey tam olarak budur.

02

Transkriptleri parçalara bölün

Her transkripti embedding'e dönüştürmeden önce üst üste binen pencerelere bölün - tüm videoyu tek bir embedding'e dönüştürmek belirli bir yanıtı almak için çok kaba olur ve bunun için hiçbir kütüphaneye gerek yoktur:

function chunkText(text: string, size = 1200, overlap = 200) {
  const chunks: string[] = [];
  let start = 0;
  while (start < text.length) {
    const end = Math.min(start + size, text.length);
    chunks.push(text.slice(start, end));
    start += size - overlap;
  }
  return chunks;
}

const records = videos.flatMap((video) =>
  chunkText(video.transcript).map((text, chunkIndex) => ({
    videoId: video.video_id,
    title: video.title,
    chunkIndex,
    text,
  }))
);

Konuşma metinleri için 200 karakter örtüşmeli 1.200 karakterlik bir pencere makul bir varsayılandır - kısa, yoğun klipler için küçültün, daha fazla çevresel bağlamın yardımcı olduğu uzun ders tarzı içerikler için büyütün.

03

Embedding'e dönüştürün ve saklayın

Her parçayı embedding'e dönüştürün ve video id'sini ve başlığı vektörle birlikte saklayın, çünkü alınan bir parçayı daha sonra bir atıfa dönüştüren şey tam olarak budur:

import OpenAI from 'openai';
const openai = new OpenAI();

async function embed(text: string) {
  const res = await openai.embeddings.create({ model: 'text-embedding-3-small', input: text });
  return res.data[0].embedding;
}

const index = await Promise.all(
  records.map(async (r) => ({ ...r, embedding: await embed(r.text) }))
);

Bu, netlik için vektörleri bellekte tutar. Birkaç yüz parçadan sonra, diziyi pgvector, Pinecone veya başka bir vektör deposuyla değiştirin - aşağıdaki alma adımı yalnızca en yakın k vektörü döndüren bir fonksiyona ihtiyaç duyar, tam olarak bu şekle değil.

04

İlgili parçaları alın

Sorgu anında, soruyu aynı modelle embedding'e dönüştürün ve saklanan parçaları kosinüs benzerliğine göre sıralayın:

function cosineSimilarity(a: number[], b: number[]) {
  let dot = 0, normA = 0, normB = 0;
  for (let i = 0; i < a.length; i++) {
    dot += a[i] * b[i];
    normA += a[i] ** 2;
    normB += b[i] ** 2;
  }
  return dot / (Math.sqrt(normA) * Math.sqrt(normB));
}

async function retrieve(query: string, k = 5) {
  const queryEmbedding = await embed(query);
  return index
    .map((r) => ({ ...r, score: cosineSimilarity(r.embedding, queryEmbedding) }))
    .sort((a, b) => b.score - a.score)
    .slice(0, k);
}

k=5 iyi bir başlangıç noktasıdır - çok az parça modelin tam olarak yanıt vermesi için yeterli bağlama sahip olmamasına, çok fazlası ise alakasız parçaların yanıtı sulandırmaya başlamasına yol açar.

05

Temellendirilmiş bir yanıt üretin

Alınan parçaları modele numaralandırılmış bağlam olarak verin ve yalnızca oradakinden yanıt vermesini ve kaynaklarına atıfta bulunmasını söyleyin - yanıtı modelin kendi genel bilgisi yerine gerçek bir videoya kadar izlenebilir kılan şey budur:

async function answer(query: string) {
  const matches = await retrieve(query);
  const context = matches
    .map((m, i) => `[${i + 1}] From "${m.title}":\n${m.text}`)
    .join('\n\n');

  const completion = await openai.chat.completions.create({
    model: 'gpt-4.1-mini',
    messages: [
      {
        role: 'system',
        content:
          "Answer only using the numbered transcript excerpts below. Cite sources as [1], [2], etc. " +
          "If the excerpts don't contain the answer, say so.",
      },
      { role: 'user', content: `${context}\n\nQuestion: ${query}` },
    ],
  });

  return completion.choices[0].message.content;
}

Bir zaman damgası uydurmak yerine video başlığına göre atıf yapmak, transkript API'sinin gerçekte döndürdüğü şeyle örtüşür - modelin kendisine hiç verilmemiş bir zaman damgası uydurmasına izin vermeyin.

Dizini güncel tutun

Yayın yapmaya devam eden bir kanal için, /channel/latest uç noktasıyla (kontrol başına 1 kredi) yeni yüklemeleri belirli aralıklarla kontrol edin, zaten dizine eklediğiniz video id'lerini atlayın ve yalnızca yenilerini alın, parçalayın ve embedding'e dönüştürün. Böylece içe aktarma maliyeti her çalıştırmada tam bir yeniden indeksleme yerine yeni içerikle orantılı kalır.

Transkriptler RAG için neden iyi çalışır

Video, üzerinde arama yapılacak bir yapı kurmak için en zahmetli formatlardan biridir - bir videoda grep yapamazsınız. Bir transkript, kendi konuşmadan-metne işinizi çalıştırmanıza gerek kalmadan onu mevcut embedding ve alma yığınınızın zaten nasıl işleyeceğini bildiği metne geri dönüştürür. Ve istek başına ücretlendirilen bir transkript API'si video uzunluğuna göre ölçmediği için, uzun biçimli içeriklerden (podcast'ler, dersler, çok saatlik yayınlar) oluşan bir arşivi içeri aktarmak, kısa klipleri içeri aktarmaktan sistematik olarak daha pahalıya gelmez - ki bir RAG pipeline'ının genellikle aramak üzere kurulduğu arşiv tam olarak budur.

Tam endpoint referansı, kimlik doğrulama ve hız limitleri API belgelerinde yer alır. Bunu baştan sona denemek için panelden 100 ücretsiz kredi içeren bir anahtar alın.

RAG pipeline SSS

Q01

Bunu takip etmek için gerçek bir vektör veritabanına ihtiyacım var mı?

Hayır - bu kılavuzdaki bellek içi dizi birkaç yüz parçaya kadar sorunsuz çalışır ve pipeline'ı baştan sona doğrulamanın en hızlı yoludur. Bundan fazlasını dizine eklemeniz gerektiğinde veya dizinin yeniden başlatmalar arasında kalıcı olması gerektiğinde pgvector'a veya yönetilen bir vektör deposuna geçin.

Q02

Hangi embedding modelini kullanmalıyım?

text-embedding-3-small makul bir varsayılandır - ucuzdur ve çoğu transkript alma işi için yeterince iyidir. Yalnızca makul şekilde düzeltebileceği bir alma kalitesi sorunu görüyorsanız text-embedding-3-large'a geçin; çağrı başına daha pahalıdır.

Q03

Bir videonun hiç transkripti yoksa ne olur?

Transkript endpoint'i boş bir dize yerine net bir hata kodu döndürür (TRANSCRIPT_DISABLED veya TRANSCRIPT_NOT_FOUND) - o videoyu gerçek içerikmiş gibi boş bir dizeyi embedding'e dönüştürmek yerine success: false olup olmadığını kontrol edip atlayın.

Q04

Diyelim ki 200 videoyu dizine eklemenin maliyeti nedir?

2 dakikalık klipler mi yoksa 2 saatlik videolar mı olduğuna bakılmaksızın transkript alma işlemleri için 200 kredi - 100 ücretsiz kayıt kredisi tek başına 200 videoluk bir arşivin kabaca yarısını karşılar. Embedding maliyeti ayrıdır ve embedding sağlayıcınız tarafından faturalandırılır.

Q05

Sadece video başlığı yerine kesin bir zaman damgasına atıfta bulunabilir miyim?

Bu endpoint ile değil - genel transkript API'si zaman damgalı segmentler değil, düz metin döndürür, bu yüzden buradaki örnekler video başlığı ve id'sine göre atıf yapar. Zaman damgası düzeyinde atıf kullanım durumunuz için önemliyse, video düzeyindeki atfın olabildiğince kesin kalması için parçaları küçük tutun.

İlgili

Featured on aitoolfame.comFeatured on Aura++Featured on DeepLaunch.ioFeatured on Dofollow.ToolsFeatured on EasyDoFollowFeatured on EarlyHuntFeatured on Findly.toolsFeatured on FoundrListGood AI ToolsFeatured on IndieHuntFeatured on LaunchBuffFeatured on launched.toolsFeatured on Launch Llama ToolsFeatured on LemonLaunchLiftOff launch badgeMy Launch StashGetYouTubeTranscript on Nick LaunchesOpenHunts Club MemberFeatured on saasfame.comShinyLaunchFeatured on ShowMeBestAIFeatured on toolfame.comListed on Turbo0Featured on Twelve ToolsHuzzler Embed BadgeFeatured on CodeHypeGetYouTubeTranscript on Better LaunchDokeyAIFeatured on WayfindioFeatured on LaunchZoneFeatured on NoonlaunchFeatured on WhatsthebigdataSurfaced on CodeTrendyFeatured on ScrollLaunchFeatured on ufind.bestFeatured on ShipBoostProduct WingWe Like ToolsAppa ListAcid ToolsPower Up ToolsToshi ListAIGC 160Appsy ToolsHunt for ToolsBeam ToolsTool Find DirTool SignalSaaS Tools DirSoftware BoltProduct List DirStack DirectorySaaS FieldSaaS WheelSaaS RootsStartup BenchmarksUnite ListTrustinerBest Tool VaultSolver ToolsAsh ListSmart Kit HubAI X CollectionAI Tech ViralMillion Dot HomepageThat App ShowLaunch ScrollMy Start ToolsLatest AI UpdatesSuper AI BoomTools Under RadarThe Key ToolsTool JourneyTools List HQThe App ToolsThe Mega ToolsSource DirTool CosmosTop Trend ToolsTiny Tool HubTool PrismStartup AIdeasFeatured on WonderLaunchFeatured on ShipycornFeatured on ToolsClawListed on ProofStoriesFeatured on ToolListedLaunched on Launch StreakIndieMarkdowns