Retour au blog

Comment collecter des données YouTube pour les systèmes RAG : extraction des sous-titres et des métadonnées avec Python

Guide étape par étape pour collecter des données YouTube pour former des systèmes RAG : travail avec l'API, extraction des sous-titres et des métadonnées, configuration de proxies pour l'évolutivité.

📅6 mars 2026
```html

Les systèmes RAG (Retrieval-Augmented Generation) nécessitent des données de qualité pour l'apprentissage. YouTube est une immense source de contenu structuré : vidéos avec sous-titres, métadonnées, commentaires. Dans cet article, nous allons explorer comment collecter efficacement des données YouTube pour RAG, en évitant les blocages et en respectant les limites de l'API.

Qu'est-ce que RAG et pourquoi les données YouTube sont-elles nécessaires

RAG (Retrieval-Augmented Generation) est une approche pour construire des systèmes d'IA où le modèle linguistique est complété par une base de connaissances. Au lieu de se fier uniquement aux données sur lesquelles le modèle a été formé, RAG extrait des informations pertinentes d'une source externe et les utilise pour générer des réponses.

YouTube contient des millions d'heures de contenu avec des sous-titres dans différentes langues. Cela fait de la plateforme une source précieuse de données pour les systèmes RAG dans divers domaines :

  • Systèmes éducatifs — cours, tutoriels, leçons avec des horodatages
  • Documentation technique — guides vidéo sur la programmation, DevOps, configuration de logiciels
  • Bases de connaissances médicales — conférences de médecins, études de cas cliniques
  • Analyse commerciale — interviews avec des experts, études de cas, analyses de marché
  • Support produit — critiques de produits, FAQ au format vidéo

L'avantage des données YouTube réside dans leur structure : sous-titres avec horodatages, métadonnées (catégories, tags), contexte social (commentaires, likes). Tout cela aide le système RAG à comprendre non seulement le contenu, mais aussi le contexte de l'information.

Quelles données YouTube sont utiles pour les systèmes RAG

Pour un fonctionnement efficace du système RAG, il est nécessaire de collecter plusieurs types de données. Chaque type remplit ses propres fonctions dans le processus d'extraction et de génération d'informations.

Sous-titres (Transcripts)

La principale source de données textuelles. YouTube fournit deux types de sous-titres :

  • Automatiques — générés par des algorithmes de reconnaissance vocale de Google. Disponibles pour la plupart des vidéos en anglais et dans d'autres langues populaires. Précision de 85-95 % selon la qualité du son.
  • Manuels — téléchargés par les auteurs ou la communauté. Plus précis, contiennent souvent du formatage et un contexte supplémentaire.

Les sous-titres incluent des horodatages, ce qui permet de lier le texte à des moments spécifiques de la vidéo. Cela est critique pour créer des références précises aux sources dans les réponses RAG.

Métadonnées vidéo

Les métadonnées aident le système RAG à comprendre le contexte et la pertinence des informations :

Type de données Application dans RAG
Titre et description Recherche sémantique, définition du sujet
Tags et catégories Classification du contenu, filtrage
Date de publication Pertinence de l'information (important pour les sujets techniques)
Durée Évaluation de la profondeur du sujet
Statistiques (vues, likes) Évaluation de la qualité et de la popularité de la source
Informations sur la chaîne Détermination de l'autorité de la source

Commentaires

Les commentaires contiennent un contexte supplémentaire : questions des spectateurs, clarifications des auteurs, discussions. Pour les systèmes RAG, cela est précieux car :

  • Les commentaires contiennent souvent des FAQ sur le sujet de la vidéo
  • Les auteurs peuvent publier des corrections et des ajouts
  • Les discussions révèlent différents points de vue sur le problème

Travailler avec l'API YouTube Data v3 : configuration et limites

L'API YouTube Data v3 est le moyen officiel d'obtenir des données. Elle donne accès aux métadonnées, aux statistiques, aux commentaires. Les sous-titres sont obtenus via des méthodes distinctes.

Obtention de la clé API

Pour travailler avec l'API, vous avez besoin d'une clé depuis Google Cloud Console :

  1. Allez sur console.cloud.google.com
  2. Créez un nouveau projet ou sélectionnez un projet existant
  3. Activez l'API YouTube Data v3 dans la section "APIs & Services"
  4. Créez des identifiants (Credentials) → clé API
  5. Copiez la clé — elle sera nécessaire pour toutes les requêtes

Limites et quotas

L'API YouTube utilise un système de quotas. Chaque requête "coûte" un certain nombre d'unités :

Opération Coût en quotas
Recherche de vidéos (search.list) 100 unités
Obtention des données vidéo (videos.list) 1 unité
Obtention des commentaires (commentThreads.list) 1 unité

La limite quotidienne par défaut est de 10 000 unités. Cela représente environ 100 requêtes de recherche ou 10 000 requêtes de métadonnées. Pour augmenter le quota, il faut faire une demande à Google.

Exemple de base de travail avec l'API

import requests

API_KEY = 'votre_cle_api'
BASE_URL = 'https://www.googleapis.com/youtube/v3'

# Recherche de vidéos par requête
def search_videos(query, max_results=10):
    url = f'{BASE_URL}/search'
    params = {
        'part': 'snippet',
        'q': query,
        'type': 'video',
        'maxResults': max_results,
        'key': API_KEY
    }
    
    response = requests.get(url, params=params)
    return response.json()

# Obtention des métadonnées vidéo
def get_video_details(video_id):
    url = f'{BASE_URL}/videos'
    params = {
        'part': 'snippet,contentDetails,statistics',
        'id': video_id,
        'key': API_KEY
    }
    
    response = requests.get(url, params=params)
    return response.json()

# Exemple d'utilisation
results = search_videos('tutoriel apprentissage automatique', max_results=5)
for item in results.get('items', []):
    video_id = item['id']['videoId']
    title = item['snippet']['title']
    print(f'ID : {video_id}, Titre : {title}')
    
    # Obtention des informations détaillées
    details = get_video_details(video_id)
    stats = details['items'][0]['statistics']
    print(f"Vues : {stats.get('viewCount')}, Likes : {stats.get('likeCount')}")

Extraction de sous-titres vidéo : automatiques et manuels

L'API YouTube Data v3 ne fournit pas d'accès direct aux sous-titres. Pour les obtenir, des méthodes alternatives sont utilisées.

Utilisation de la bibliothèque youtube-transcript-api

Le moyen le plus simple est la bibliothèque youtube-transcript-api pour Python. Elle extrait les sous-titres directement, sans clé API :

from youtube_transcript_api import YouTubeTranscriptApi

# Obtention des sous-titres
video_id = 'dQw4w9WgXcQ'

try:
    # Tentative d'obtenir les sous-titres en russe, sinon en anglais
    transcript = YouTubeTranscriptApi.get_transcript(video_id, languages=['ru', 'en'])
    
    # Affichage des sous-titres avec horodatages
    for entry in transcript:
        start_time = entry['start']
        duration = entry['duration']
        text = entry['text']
        print(f"[{start_time:.2f}s] {text}")
        
except Exception as e:
    print(f"Erreur lors de l'obtention des sous-titres : {e}")

# Obtention de la liste des langues disponibles
transcript_list = YouTubeTranscriptApi.list_transcripts(video_id)
for transcript in transcript_list:
    print(f"Langue : {transcript.language}, Automatique : {transcript.is_generated}")

La bibliothèque détermine automatiquement les sous-titres disponibles et peut les traduire dans d'autres langues (si YouTube le permet).

Traitement des horodatages pour RAG

Pour les systèmes RAG, il est important de maintenir le lien entre le texte et les horodatages. Cela permet de créer des références précises aux sources :

def format_timestamp(seconds):
    """Conversion des secondes au format MM:SS"""
    minutes = int(seconds // 60)
    secs = int(seconds % 60)
    return f"{minutes:02d}:{secs:02d}"

def create_chunks_with_timestamps(transcript, chunk_size=500):
    """Découpage des sous-titres en morceaux tout en conservant les horodatages"""
    chunks = []
    current_chunk = ""
    chunk_start_time = 0
    
    for i, entry in enumerate(transcript):
        if len(current_chunk) == 0:
            chunk_start_time = entry['start']
        
        current_chunk += entry['text'] + " "
        
        # Si la taille souhaitée est atteinte ou fin des sous-titres
        if len(current_chunk) >= chunk_size or i == len(transcript) - 1:
            chunks.append({
                'text': current_chunk.strip(),
                'start_time': chunk_start_time,
                'timestamp': format_timestamp(chunk_start_time),
                'video_id': video_id
            })
            current_chunk = ""
    
    return chunks

# Utilisation
transcript = YouTubeTranscriptApi.get_transcript(video_id)
chunks = create_chunks_with_timestamps(transcript)

for chunk in chunks[:3]:  # Les 3 premiers morceaux
    print(f"[{chunk['timestamp']}] {chunk['text'][:100]}...")

Collecte de métadonnées : titres, descriptions, tags

Les métadonnées enrichissent le contexte pour le système RAG. Voici un exemple complet de collecte de toutes les données nécessaires :

import requests
from datetime import datetime

def collect_video_metadata(video_id, api_key):
    """Collecte des métadonnées complètes de la vidéo"""
    url = f'https://www.googleapis.com/youtube/v3/videos'
    params = {
        'part': 'snippet,contentDetails,statistics,topicDetails',
        'id': video_id,
        'key': api_key
    }
    
    response = requests.get(url, params=params)
    data = response.json()
    
    if 'items' not in data or len(data['items']) == 0:
        return None
    
    item = data['items'][0]
    snippet = item['snippet']
    stats = item.get('statistics', {})
    content = item.get('contentDetails', {})
    
    metadata = {
        'video_id': video_id,
        'title': snippet['title'],
        'description': snippet['description'],
        'channel_title': snippet['channelTitle'],
        'channel_id': snippet['channelId'],
        'published_at': snippet['publishedAt'],
        'tags': snippet.get('tags', []),
        'category_id': snippet.get('categoryId'),
        'duration': content.get('duration'),
        'view_count': int(stats.get('viewCount', 0)),
        'like_count': int(stats.get('likeCount', 0)),
        'comment_count': int(stats.get('commentCount', 0)),
        'topics': item.get('topicDetails', {}).get('topicCategories', [])
    }
    
    return metadata

# Exemple d'utilisation
metadata = collect_video_metadata('dQw4w9WgXcQ', API_KEY)
print(f"Titre : {metadata['title']}")
print(f"Chaîne : {metadata['channel_title']}")
print(f"Vues : {metadata['view_count']:,}")
print(f"Tags : {', '.join(metadata['tags'][:5])}")

Détermination de la pertinence du contenu

Pour les sujets techniques, la fraîcheur de l'information est importante. Ajoutons une fonction d'évaluation de la pertinence :

from datetime import datetime, timedelta

def calculate_content_freshness(published_date_str):
    """Évaluation de la pertinence du contenu"""
    published_date = datetime.fromisoformat(published_date_str.replace('Z', '+00:00'))
    age_days = (datetime.now(published_date.tzinfo) - published_date).days
    
    if age_days < 30:
        return 'très_frais'
    elif age_days < 180:
        return 'frais'
    elif age_days < 365:
        return 'modéré'
    else:
        return 'ancien'

def calculate_quality_score(metadata):
    """Calcul de l'évaluation de la qualité de la source"""
    score = 0
    
    # Popularité
    views = metadata['view_count']
    if views > 100000:
        score += 3
    elif views > 10000:
        score += 2
    elif views > 1000:
        score += 1
    
    # Engagement (likes par rapport aux vues)
    if views > 0:
        like_ratio = metadata['like_count'] / views
        if like_ratio > 0.05:
            score += 2
        elif like_ratio > 0.02:
            score += 1
    
    # Pertinence
    freshness = calculate_content_freshness(metadata['published_at'])
    if freshness == 'très_frais':
        score += 2
    elif freshness == 'frais':
        score += 1
    
    return score

# Utilisation
metadata = collect_video_metadata('dQw4w9WgXcQ', API_KEY)
quality = calculate_quality_score(metadata)
freshness = calculate_content_freshness(metadata['published_at'])
print(f"Évaluation de la qualité : {quality}/7")
print(f"Pertinence : {freshness}")

Extraction de commentaires pour l'analyse contextuelle

Les commentaires peuvent contenir des informations précieuses : corrections d'erreurs dans la vidéo, ressources supplémentaires, questions fréquentes. Pour les systèmes RAG, cela constitue un contexte supplémentaire.

def get_video_comments(video_id, api_key, max_results=100):
    """Obtention des commentaires de la vidéo"""
    url = 'https://www.googleapis.com/youtube/v3/commentThreads'
    comments = []
    next_page_token = None
    
    while len(comments) < max_results:
        params = {
            'part': 'snippet',
            'videoId': video_id,
            'maxResults': min(100, max_results - len(comments)),
            'order': 'relevance',  # Tri par pertinence
            'key': api_key
        }
        
        if next_page_token:
            params['pageToken'] = next_page_token
        
        response = requests.get(url, params=params)
        data = response.json()
        
        if 'items' not in data:
            break
        
        for item in data['items']:
            top_comment = item['snippet']['topLevelComment']['snippet']
            comments.append({
                'author': top_comment['authorDisplayName'],
                'text': top_comment['textDisplay'],
                'like_count': top_comment['likeCount'],
                'published_at': top_comment['publishedAt'],
                'reply_count': item['snippet']['totalReplyCount']
            })
        
        next_page_token = data.get('nextPageToken')
        if not next_page_token:
            break
    
    return comments

def filter_valuable_comments(comments, min_likes=5):
    """Filtrage des commentaires précieux"""
    valuable = []
    
    for comment in comments:
        # Critères de valeur :
        # 1. Beaucoup de likes (popularité)
        # 2. A des réponses (a suscité une discussion)
        # 3. Texte long (commentaire détaillé)
        
        if (comment['like_count'] >= min_likes or 
            comment['reply_count'] > 0 or 
            len(comment['text']) > 200):
            valuable.append(comment)
    
    return valuable

# Utilisation
comments = get_video_comments('dQw4w9WgXcQ', API_KEY, max_results=50)
valuable_comments = filter_valuable_comments(comments)

print(f"Total des commentaires : {len(comments)}")
print(f"Commentaires précieux : {len(valuable_comments)}")

for comment in valuable_comments[:3]:
    print(f"\n[{comment['like_count']} likes] {comment['author']}:")
    print(comment['text'][:200])

Utilisation de proxy pour l'évolutivité de la collecte de données

Lors de la collecte de données à grande échelle, deux problèmes se posent : les limites de l'API YouTube (10 000 quotas par jour) et les blocages lors de l'extraction des sous-titres. Les proxies aident à résoudre les deux problèmes.

Quand avoir besoin de proxies pour l'extraction YouTube

  • Dépassement des quotas API — en utilisant plusieurs clés API via différentes IP, il est possible d'augmenter la limite quotidienne
  • Extraction de sous-titres en contournant l'API — la bibliothèque youtube-transcript-api effectue des requêtes directes, qui peuvent être bloquées à haute fréquence
  • Collecte de données de différentes régions — certaines vidéos ne sont disponibles que dans certains pays
  • Collecte parallèle — répartition de la charge sur plusieurs IP pour accélérer le processus

Choix du type de proxy

Type de proxy Avantages Quand utiliser
Centre de données Haute vitesse, faible coût Travail avec l'API, petits volumes
Résidentiels Faible risque de blocages, IP réelles Extraction massive de sous-titres, contournement des restrictions
Mobiles Confiance maximale, rares blocages Collecte de données à partir d'applications mobiles, tâches critiques

Pour la plupart des tâches des systèmes RAG, les proxies résidentiels sont adaptés — ils offrent un équilibre entre coût et fiabilité lors de l'extraction massive.

Configuration des proxies dans le code

import requests
from youtube_transcript_api import YouTubeTranscriptApi
from youtube_transcript_api._api import TranscriptListFetcher

# Configuration du proxy
PROXY = {
    'http': 'http://username:password@proxy-server:port',
    'https': 'http://username:password@proxy-server:port'
}

# Pour travailler avec l'API via proxy
def get_video_details_with_proxy(video_id, api_key, proxy):
    url = f'https://www.googleapis.com/youtube/v3/videos'
    params = {
        'part': 'snippet,statistics',
        'id': video_id,
        'key': api_key
    }
    
    response = requests.get(url, params=params, proxies=proxy, timeout=10)
    return response.json()

# Pour l'extraction de sous-titres via proxy
class ProxiedTranscriptApi:
    def __init__(self, proxy):
        self.proxy = proxy
    
    def get_transcript(self, video_id, languages=['en']):
        # Créer une session personnalisée avec proxy
        session = requests.Session()
        session.proxies = self.proxy
        
        # Utiliser la session pour les requêtes
        fetcher = TranscriptListFetcher(session)
        transcript_list = fetcher.fetch(video_id)
        
        # Obtenir la langue souhaitée
        for lang in languages:
            try:
                transcript = transcript_list.find_transcript([lang])
                return transcript.fetch()
            except:
                continue
        
        raise Exception(f"Sous-titres non trouvés pour les langues : {languages}")

# Utilisation
api = ProxiedTranscriptApi(PROXY)
transcript = api.get_transcript('dQw4w9WgXcQ', languages=['ru', 'en'])
print(f"Obtenu {len(transcript)} segments de sous-titres")

Rotation des proxies pour l'évolutivité

Lors de la collecte de données à partir de milliers de vidéos, il est important de répartir la charge entre plusieurs proxies :

import random
import time

class ProxyRotator:
    def __init__(self, proxy_list):
        self.proxies = proxy_list
        self.current_index = 0
    
    def get_next_proxy(self):
        """Rotation séquentielle"""
        proxy = self.proxies[self.current_index]
        self.current_index = (self.current_index + 1) % len(self.proxies)
        return proxy
    
    def get_random_proxy(self):
        """Rotation aléatoire"""
        return random.choice(self.proxies)

# Liste de proxies
PROXY_LIST = [
    {'http': 'http://user:pass@proxy1:port', 'https': 'http://user:pass@proxy1:port'},
    {'http': 'http://user:pass@proxy2:port', 'https': 'http://user:pass@proxy2:port'},
    {'http': 'http://user:pass@proxy3:port', 'https': 'http://user:pass@proxy3:port'},
]

rotator = ProxyRotator(PROXY_LIST)

def collect_data_with_rotation(video_ids):
    results = []
    
    for video_id in video_ids:
        proxy = rotator.get_next_proxy()
        
        try:
            # Obtention des métadonnées
            metadata = get_video_details_with_proxy(video_id, API_KEY, proxy)
            
            # Obtention des sous-titres
            api = ProxiedTranscriptApi(proxy)
            transcript = api.get_transcript(video_id)
            
            results.append({
                'video_id': video_id,
                'metadata': metadata,
                'transcript': transcript
            })
            
            # Délai entre les requêtes
            time.sleep(1)
            
        except Exception as e:
            print(f"Erreur pour {video_id} : {e}")
            continue
    
    return results

# Utilisation
video_ids = ['video1', 'video2', 'video3', 'video4', 'video5']
data = collect_data_with_rotation(video_ids)
print(f"Données collectées pour {len(data)} vidéos")

Traitement et préparation des données pour RAG

Après la collecte des données, il est nécessaire de les traiter et de les structurer pour un fonctionnement efficace des systèmes RAG.

Création d'embeddings vectoriels

Les systèmes RAG utilisent la recherche vectorielle pour trouver des fragments pertinents. Il faut transformer le texte en embeddings :

from sentence_transformers import SentenceTransformer
import numpy as np

# Chargement du modèle pour créer des embeddings
model = SentenceTransformer('paraphrase-multilingual-MiniLM-L12-v2')

def create_embeddings_from_transcript(transcript_chunks):
    """Création d'embeddings pour les morceaux de sous-titres"""
    embeddings = []
    
    for chunk in transcript_chunks:
        # Combiner le texte avec les métadonnées pour un meilleur contexte
        text_with_context = f"{chunk['title']} | {chunk['text']}"
        
        # Création de l'embedding
        embedding = model.encode(text_with_context)
        
        embeddings.append({
            'video_id': chunk['video_id'],
            'timestamp': chunk['timestamp'],
            'text': chunk['text'],
            'embedding': embedding.tolist(),
            'metadata': {
                'title': chunk['title'],
                'channel': chunk['channel'],
                'views': chunk['views']
            }
        })
    
    return embeddings

# Préparation des données
def prepare_rag_data(video_data):
    """Préparation de toutes les données pour RAG"""
    all_chunks = []
    
    for video in video_data:
        metadata = video['metadata']
        transcript = video['transcript']
        
        # Découper les sous-titres en morceaux
        chunks = create_chunks_with_timestamps(transcript)
        
        # Ajouter les métadonnées à chaque morceau
        for chunk in chunks:
            chunk['title'] = metadata['title']
            chunk['channel'] = metadata['channel_title']
            chunk['views'] = metadata['view_count']
            all_chunks.append(chunk)
    
    # Création des embeddings
    embeddings = create_embeddings_from_transcript(all_chunks)
    
    return embeddings

# Utilisation
rag_data = prepare_rag_data(collected_videos)
print(f"{len(rag_data)} fragments préparés pour RAG")

Sauvegarde dans une base de données vectorielle

Pour une recherche efficace, les embeddings sont sauvegardés dans des bases de données spécialisées. Options populaires : Pinecone, Weaviate, Qdrant, ChromaDB.

import chromadb
from chromadb.config import Settings

# Initialisation de ChromaDB (base de données vectorielle locale)
client = chromadb.Client(Settings(
    chroma_db_impl="duckdb+parquet",
    persist_directory="./youtube_rag_db"
))

# Création d'une collection
collection = client.create_collection(
    name="youtube_transcripts",
    metadata={"description": "Transcriptions de vidéos YouTube pour RAG"}
)

def store_in_vector_db(embeddings_data, collection):
    """Sauvegarde des embeddings dans la base de données vectorielle"""
    
    ids = []
    embeddings = []
    documents = []
    metadatas = []
    
    for i, item in enumerate(embeddings_data):
        ids.append(f"{item['video_id']}_{i}")
        embeddings.append(item['embedding'])
        documents.append(item['text'])
        metadatas.append({
            'video_id': item['video_id'],
            'timestamp': item['timestamp'],
            'title': item['metadata']['title'],
            'channel': item['metadata']['channel'],
            'views': str(item['metadata']['views']),
            'youtube_url': f"https://youtube.com/watch?v={item['video_id']}&t={int(float(item['timestamp'].split(':')[0])*60 + float(item['timestamp'].split(':')[1]))}s"
        })
    
    # Ajout à la collection
    collection.add(
        ids=ids,
        embeddings=embeddings,
        documents=documents,
        metadatas=metadatas
    )
    
    print(f"{len(ids)} embeddings sauvegardés dans la base de données vectorielle")

# Utilisation
store_in_vector_db(rag_data, collection)

Recherche et génération de réponses

La dernière étape consiste à mettre en œuvre la recherche RAG et la génération de réponses :

def search_youtube_knowledge(query, collection, model, top_k=3):
    """Recherche de fragments pertinents à partir de YouTube"""
    
    # Création de l'embedding de la requête
    query_embedding = model.encode(query).tolist()
    
    # Recherche dans la base de données vectorielle
    results = collection.query(
        query_embeddings=[query_embedding],
        n_results=top_k
    )
    
    # Formatage des résultats
    sources = []
    for i in range(len(results['ids'][0])):
        sources.append({
            'text': results['documents'][0][i],
            'metadata': results['metadatas'][0][i],
            'distance': results['distances'][0][i] if 'distances' in results else None
        })
    
    return sources

def generate_rag_answer(query, sources, llm_api_key):
    """Génération de la réponse basée sur les sources trouvées"""
    
    # Formulation du contexte à partir des sources trouvées
    context = "\n\n".join([
        f"Source : {s['metadata']['title']} ({s['metadata']['timestamp']})\n{s['text']}"
        for s in sources
    ])
    
    # Prompt pour LLM
    prompt = f"""Sur la base des fragments suivants de vidéos YouTube, répondez à la question de l'utilisateur.
Assurez-vous d'indiquer les sources avec des horodatages.

Contexte :
{context}

Question : {query}

Réponse :"""
    
    # Ici, appel de votre LLM (OpenAI, Claude, modèle local)
    # Exemple avec OpenAI :
    # response = openai.ChatCompletion.create(
    #     model="gpt-4",
    #     messages=[{"role": "user", "content": prompt}]
    # )
    # answer = response.choices[0].message.content
    
    # Pour l'exemple, renvoyons le prompt
    return {
        'answer': 'Voici la réponse de LLM',
        'sources': sources
    }

# Utilisation
query = "Comment configurer un proxy en Python ?"
sources = search_youtube_knowledge(query, collection, model, top_k=3)

print("Sources trouvées :")
for source in sources:
    print(f"\n{source['metadata']['title']}")
    print(f"Heure : {source['metadata']['timestamp']}")
    print(f"Lien : {source['metadata']['youtube_url']}")
    print(f"Texte : {source['text'][:200]}...")

Optimisation de la qualité RAG

Quelques conseils pour améliorer la qualité du système RAG sur les données YouTube :

  • Filtrer le contenu de faible qualité — utilisez des métriques de vues, de likes, de date de publication
  • Conserver le contexte — ajoutez le titre de la vidéo et de la chaîne à chaque morceau de texte
  • Optimiser la taille des morceaux — pour le contenu technique, 300-500 mots est optimal
  • Utiliser les métadonnées pour le classement — un contenu plus frais et populaire peut avoir la priorité
  • Ajouter des commentaires — ils contiennent souvent des clarifications importantes et des FAQ
  • Vérifier la disponibilité des vidéos — certaines vidéos peuvent être supprimées ou devenir privées

Conseil : Pour la collecte de données à grande échelle sur YouTube, il est recommandé d'utiliser une combinaison de l'API officielle (pour les métadonnées) et de l'extraction via des proxies (pour les sous-titres). Cela permet de contourner les limites et d'obtenir un maximum d'informations.

Conclusion

La collecte de données YouTube pour les systèmes RAG est un processus en plusieurs étapes, incluant le travail avec l'API, l'extraction de sous-titres, le traitement des métadonnées et la création d'embeddings vectoriels. Points clés :

  • L'API YouTube Data v3 fournit des métadonnées, des statistiques et des commentaires avec une limite de 10 000 quotas par jour
  • Les sous-titres sont extraits via la bibliothèque youtube-transcript-api ou des requêtes directes
  • Les horodatages sont critiques pour créer des références précises aux sources
  • Les métadonnées (vues, likes, date) aident à évaluer la qualité et la pertinence du contenu
  • Les commentaires ajoutent du contexte et contiennent souvent des FAQ
  • Les proxies sont nécessaires pour l'évolutivité et le contournement des limites
  • Les embeddings vectoriels et les bases de données spécialisées assurent une recherche sémantique rapide

Avec un processus correctement configuré, il est possible de collecter des dizaines de milliers de fragments de contenu de qualité par jour, créant ainsi une puissante base de connaissances pour les systèmes RAG dans n'importe quel domaine.

Si vous prévoyez une collecte massive de données YouTube en contournant les limites et les blocages, nous vous recommandons d'utiliser des proxies résidentiels — ils assurent la stabilité lors de l'extraction de milliers de vidéos et minimisent le risque de blocages de la part de YouTube.

```