RAG en production à grande échelle : leçons tirées du traitement de plus de 10 000 annonces par jour
J'ai conçu un pipeline RAG pour un site d'offres d'emploi. Il fonctionnait en environnement de staging, mais a peiné sous une charge réelle. Traiter des milliers d'annonces quotidiennement nécessite plus qu'un bon vector store. Il faut comprendre où le système flanche.
Voici mes leçons sur le chunking, les embeddings, les coûts et l'observabilité.
1. Ne devinez pas votre stratégie de chunking
La plupart des tutoriels traitent le chunking comme un simple paramètre. En production, votre stratégie dicte la précision et le coût.
J'ai testé trois méthodes pour les offres d'emploi :
- Chunks de taille fixe : Ils ont échoué. Ils divisaient des sections comme « exigences » et « avantages » à des points aléatoires. Cela crée une récupération (retrieval) bruitée.
- Chunking sémantique : C'était mieux, mais incohérent. Certains chunks étaient trop longs et d'autres trop courts.
- Découpage récursif de caractères avec chevauchement (overlap) : C'est ce qui a le mieux fonctionné. J'ai effectué le découpage sur les sauts de ligne et les phrases. J'ai utilisé une taille de 400 tokens avec un chevauchement de 50 tokens. Cela garantit que les phrases s'étendant sur deux chunks restent connectées.
Conseil de pro : Normalisez vos données avant le chunking. Différentes sources comme Greenhouse ou Lever renvoient des formats différents. Nettoyez d'abord le texte pour que votre chunker voie une structure cohérente.
2. Embeddings : Coût vs Précision
J'ai testé Llama 3.1 via Ollama par rapport à OpenAI text-embedding-3-small. Le modèle local était gratuit mais peinait avec les termes spécifiques au domaine comme « equity compensation ». Il produisait des résultats bruités. OpenAI coûtait plus cher mais fournissait des correspondances précises. J'ai choisi OpenAI car une mauvaise récupération coûte plus cher en appels LLM par la suite.
Pour gagner du temps, je regroupe mes requêtes par lots (batching). J'envoie jusqu'à 100 chunks en un seul appel. Cela réduit la latence et maintient la rapidité du pipeline.
3. Le compromis du Vector Store
J'ai utilisé Pinecone pour le prototypage car il est rapide à mettre en place. Cependant, à grande échelle, les coûts sont devenus trop élevés.
Je suis passé à pgvector à l'intérieur de PostgreSQL.
- Cela a demandé plus de travail de configuration.
- Cela a permis de réaliser des économies massives.
- Cela a assuré une cohérence transactionnelle. Puisque les embeddings résident dans la même base de données que les données d'emploi, vous disposez d'une source unique de vérité. Vous n'avez pas besoin de synchroniser deux systèmes différents.
4. Contrôler les coûts des LLM
Noter chaque annonce avec GPT-4o est coûteux. J'ai utilisé trois tactiques pour réduire les coûts :
- OpenAI Batch API : Je traite les tâches de notation pendant la nuit. Cela permet d'obtenir une réduction importante.
- Mise en cache (Caching) : Je mets en cache les résultats pour les profils de candidats récurrents.
- Hiérarchisation des modèles (Model tiering) : J'utilise GPT-4o-mini pour les rôles courants comme « Sales Representative ». Je n'utilise GPT-4o que pour les rôles de niche où la précision est vitale.
5. Construisez l'observabilité en priorité
Mon pipeline a un jour échoué silencieusement. Des données malformées ont provoqué des chunks vides, que le système a ignorés sans erreur.
J'ai corrigé cela en ajoutant un logging structuré avec un ID de corrélation. Cela m'a permis de tracer une annonce de l'ingestion à la notation. J'ai enfin pu voir quelles sources de données causaient les échecs.
La plus grande leçon : la plupart des problèmes proviennent de données désordonnées, pas de l'IA. Réparez d'abord votre tuyauterie de données.
Communauté d'apprentissage optionnelle : https://t.me/GyaanSetuAi
