Prompt Engineering RAG : Optimiser les prompts système pour de meilleures réponses
Guide complet du prompt engineering pour systèmes RAG : techniques avancées, templates optimisés et bonnes pratiques pour maximiser la qualité des réponses.
TL;DR
Le prompt engineering RAG est l'art d'optimiser les instructions données au LLM pour maximiser la qualité des réponses générées à partir du contexte récupéré. Un bon prompt système peut améliorer la pertinence de 40%, réduire les hallucinations de 60% et garantir des réponses cohérentes avec votre marque. Ce guide vous montre les techniques avancées, les templates éprouvés et les erreurs à éviter.
Introduction au Prompt Engineering RAG
Dans un système RAG, le prompt engineering joue un rôle crucial mais souvent sous-estimé. Contrairement au prompt engineering classique pour LLM, le contexte RAG ajoute une complexité supplémentaire : le modèle doit non seulement comprendre la requête utilisateur, mais aussi exploiter efficacement les documents récupérés.
Pourquoi le prompt engineering est critique en RAG
Le prompt système dans un pipeline RAG a plusieurs responsabilités :
- Guider l'utilisation du contexte : Indiquer au LLM comment exploiter les documents récupérés
- Définir le comportement : Ton, style, niveau de détail des réponses
- Prévenir les hallucinations : Forcer le modèle à s'appuyer sur les sources
- Gérer l'incertitude : Que faire quand l'information n'est pas dans le contexte
DEVELOPERpython# Exemple de prompt RAG basique vs optimisé # ❌ Prompt basique (problématique) basic_prompt = """ Tu es un assistant. Voici des documents : {context} Question : {query} """ # ✅ Prompt optimisé optimized_prompt = """ Tu es un assistant expert pour {company_name}. Tu aides les utilisateurs en t'appuyant UNIQUEMENT sur les documents fournis. ## Instructions 1. Réponds uniquement avec les informations présentes dans les documents 2. Si l'information n'est pas disponible, dis-le clairement 3. Cite tes sources avec [Source: nom_du_document] 4. Utilise un ton professionnel mais accessible ## Documents disponibles {context} ## Question de l'utilisateur {query} ## Ta réponse (basée uniquement sur les documents ci-dessus) """
Architecture d'un prompt RAG efficace
Les 6 composants essentiels
Un prompt RAG bien structuré contient ces éléments :
| Composant | Rôle | Exemple |
|---|---|---|
| Persona | Définit l'identité de l'assistant | "Tu es un expert support client" |
| Instructions | Règles de comportement | "Réponds en 3 phrases max" |
| Contraintes | Limitations explicites | "N'invente jamais d'informations" |
| Format | Structure de la réponse | "Utilise des bullet points" |
| Contexte | Documents récupérés | "{context}" |
| Requête | Question utilisateur | "{query}" |
Template de base recommandé
DEVELOPERpythonRAG_PROMPT_TEMPLATE = """ # Rôle Tu es {persona} pour {company}. {personality_traits} # Objectif {primary_goal} # Instructions {numbered_instructions} # Contraintes importantes - {constraint_1} - {constraint_2} - {constraint_3} # Format de réponse {response_format} --- # Documents de référence Les informations suivantes proviennent de notre base de connaissances : {context} --- # Question {query} # Réponse """
Techniques avancées de prompt engineering RAG
1. Instruction Hierarchy (Hiérarchie d'instructions)
Organisez vos instructions par ordre de priorité. Les LLM ont tendance à mieux respecter les instructions en début de prompt.
DEVELOPERpythondef build_hierarchical_prompt(context, query, config): """Construit un prompt avec hiérarchie d'instructions.""" return f""" # RÈGLES CRITIQUES (TOUJOURS RESPECTER) 1. Ne JAMAIS inventer d'informations non présentes dans les documents 2. Si tu ne sais pas, réponds "Je n'ai pas cette information" 3. Toujours citer tes sources # RÈGLES IMPORTANTES 1. Réponds en français uniquement 2. Utilise un ton {config.tone} 3. Limite ta réponse à {config.max_words} mots # PRÉFÉRENCES 1. Privilégie les exemples concrets 2. Structure avec des bullet points si pertinent 3. Propose des ressources complémentaires si disponibles # DOCUMENTS {context} # QUESTION {query} """
2. Few-Shot Examples (Exemples guidés)
Incluez des exemples de bonnes réponses pour guider le comportement du LLM :
DEVELOPERpythonfew_shot_prompt = """ Tu es un assistant support produit. Voici comment répondre : ## Exemple 1 Question : "Comment réinitialiser mon mot de passe ?" Documents : [Contient la procédure de réinitialisation] Réponse : "Pour réinitialiser votre mot de passe : 1. Cliquez sur 'Mot de passe oublié' sur la page de connexion 2. Entrez votre email 3. Suivez le lien reçu par email [Source: Guide utilisateur, section Authentification]" ## Exemple 2 Question : "Quel est le prix du forfait Enterprise ?" Documents : [Ne contient pas les tarifs] Réponse : "Je n'ai pas accès aux informations tarifaires dans ma base de connaissances. Je vous invite à contacter notre équipe commerciale à [email protected] pour obtenir un devis personnalisé." ## Exemple 3 Question : "Votre produit est-il compatible avec Linux ?" Documents : [Mentionne Windows et Mac uniquement] Réponse : "D'après notre documentation, le produit est compatible avec Windows et macOS. La compatibilité Linux n'est pas mentionnée. Je vous recommande de contacter le support technique pour vérifier. [Source: Guide d'installation]" --- Maintenant, réponds à cette question avec les documents fournis : Documents : {context} Question : {query} """
3. Chain-of-Thought RAG
Demandez au LLM de raisonner étape par étape avant de répondre :
DEVELOPERpythoncot_rag_prompt = """ Tu es un assistant qui analyse les documents avant de répondre. ## Documents {context} ## Question {query} ## Processus de réponse Avant de répondre, suis ces étapes : 1. **Analyse des documents** : Identifie les passages pertinents 2. **Vérification de couverture** : L'information demandée est-elle présente ? 3. **Synthèse** : Combine les informations pertinentes 4. **Formulation** : Rédige une réponse claire et sourcée ## Ton analyse (raisonnement interne) <thinking> [Analyse les documents ici] </thinking> ## Ta réponse finale """
4. Gestion des cas limites
Préparez votre prompt pour les situations difficiles :
DEVELOPERpythonedge_case_prompt = """ # Gestion des cas particuliers ## Si l'information n'est pas dans les documents : Réponds : "Je n'ai pas trouvé cette information dans notre documentation. Voici ce que je peux vous dire : [information connexe si disponible]. Pour plus de détails, contactez [canal approprié]." ## Si la question est ambiguë : Réponds : "Votre question peut être interprétée de plusieurs façons. Pourriez-vous préciser si vous parlez de [option A] ou [option B] ?" ## Si les documents se contredisent : Réponds : "J'ai trouvé des informations qui semblent différer. Selon [source 1], [info 1]. Cependant, [source 2] indique [info 2]. Je recommande de vérifier avec [autorité]." ## Si la question est hors sujet : Réponds : "Cette question sort du cadre de mon expertise sur [domaine]. Je suis spécialisé dans [votre domaine]. Puis-je vous aider sur un autre sujet ?" """
Optimisation du contexte injecté
Structurer le contexte pour le LLM
La façon dont vous présentez les documents récupérés impacte fortement la qualité :
DEVELOPERpythondef format_context(retrieved_docs, max_tokens=3000): """Formate les documents pour injection optimale.""" formatted_chunks = [] current_tokens = 0 for i, doc in enumerate(retrieved_docs): # Métadonnées utiles source = doc.metadata.get('source', 'Document inconnu') date = doc.metadata.get('date', '') relevance = doc.metadata.get('score', 0) # Format structuré chunk_text = f""" ### Document {i+1}: {source} - Pertinence: {relevance:.2f} - Date: {date} {doc.page_content} --- """ # Contrôle des tokens chunk_tokens = len(chunk_text.split()) * 1.3 # Approximation if current_tokens + chunk_tokens > max_tokens: break formatted_chunks.append(chunk_text) current_tokens += chunk_tokens return "\n".join(formatted_chunks)
Ordre des documents
L'ordre des documents dans le contexte influence leur utilisation :
DEVELOPERpythondef order_documents_strategically(docs, strategy="relevance_first"): """ Stratégies d'ordonnancement : - relevance_first: Plus pertinents en premier - relevance_sandwich: Pertinents au début et à la fin - recency_first: Plus récents en premier """ if strategy == "relevance_first": return sorted(docs, key=lambda x: x.score, reverse=True) elif strategy == "relevance_sandwich": # Les LLM ont tendance à mieux utiliser le début et la fin sorted_docs = sorted(docs, key=lambda x: x.score, reverse=True) if len(sorted_docs) <= 2: return sorted_docs middle = sorted_docs[1:-1] return [sorted_docs[0]] + middle[::-1] + [sorted_docs[-1]] elif strategy == "recency_first": return sorted(docs, key=lambda x: x.metadata.get('date', ''), reverse=True) return docs
Templates par cas d'usage
Support client
DEVELOPERpythonSUPPORT_PROMPT = """ Tu es un agent de support client pour {company}. Tu aides les clients avec leurs questions sur nos produits et services. ## Ton style - Amical et professionnel - Empathique face aux frustrations - Concis mais complet ## Priorités 1. Résoudre le problème du client 2. Fournir des étapes claires et actionnables 3. Proposer des alternatives si la solution principale ne fonctionne pas ## Ce que tu NE DOIS PAS faire - Inventer des fonctionnalités qui n'existent pas - Promettre des délais ou des résultats - Donner des informations sur les prix sans source ## Base de connaissances {context} ## Question du client {query} ## Ta réponse (commence par saluer le client) """
Assistant e-commerce
DEVELOPERpythonECOMMERCE_PROMPT = """ Tu es un conseiller shopping pour {store_name}. Tu aides les clients à trouver les produits parfaits pour leurs besoins. ## Ton objectif Guider le client vers le produit idéal en comprenant ses besoins. ## Style de conversation - Enthousiaste mais pas pushy - Expert produit sans être technique - Orienté solution ## Informations produits disponibles {context} ## Quand recommander un produit - Explique POURQUOI ce produit correspond au besoin - Mentionne 2-3 caractéristiques clés - Indique le prix si disponible - Suggère des alternatives si pertinent ## Question du client {query} ## Ta recommandation """
Base de connaissances interne
DEVELOPERpythonKNOWLEDGE_BASE_PROMPT = """ Tu es l'assistant IA interne de {company}. Tu aides les employés à trouver des informations dans notre documentation. ## Ton rôle - Répondre aux questions sur les processus internes - Orienter vers les bons documents - Clarifier les politiques de l'entreprise ## Règles strictes - Réponds UNIQUEMENT avec les informations documentées - Pour les questions RH sensibles, oriente vers le service RH - Ne partage pas d'informations confidentielles hors contexte ## Documentation disponible {context} ## Question de l'employé {query} ## Ta réponse (cite toujours le document source) """
Mesurer et améliorer vos prompts
Métriques clés
| Métrique | Description | Cible |
|---|---|---|
| Faithfulness | % de réponses basées sur le contexte | > 95% |
| Relevance | Pertinence par rapport à la question | > 90% |
| Completeness | Couverture de l'information disponible | > 85% |
| Hallucination rate | % d'informations inventées | < 5% |
| Format compliance | Respect du format demandé | > 95% |
A/B Testing de prompts
DEVELOPERpythonimport random from dataclasses import dataclass @dataclass class PromptVariant: name: str template: str metrics: dict = None class PromptABTester: def __init__(self, variants: list[PromptVariant]): self.variants = variants self.results = {v.name: [] for v in variants} def get_prompt(self, context, query): """Sélectionne aléatoirement une variante.""" variant = random.choice(self.variants) prompt = variant.template.format(context=context, query=query) return prompt, variant.name def record_feedback(self, variant_name, score): """Enregistre le feedback utilisateur.""" self.results[variant_name].append(score) def get_winner(self): """Retourne la variante avec le meilleur score moyen.""" averages = { name: sum(scores) / len(scores) if scores else 0 for name, scores in self.results.items() } return max(averages, key=averages.get) # Utilisation tester = PromptABTester([ PromptVariant("concise", CONCISE_PROMPT), PromptVariant("detailed", DETAILED_PROMPT), PromptVariant("structured", STRUCTURED_PROMPT), ]) # Dans votre pipeline prompt, variant = tester.get_prompt(context, query) response = llm.generate(prompt) # ... collecter feedback ... tester.record_feedback(variant, user_rating)
Itération continue
DEVELOPERpythondef analyze_failed_responses(responses, threshold=0.7): """Identifie les patterns dans les réponses de mauvaise qualité.""" failed = [r for r in responses if r.quality_score < threshold] patterns = { "hallucination": 0, "incomplete": 0, "off_topic": 0, "wrong_format": 0, "too_long": 0, "too_short": 0, } for response in failed: # Analyse automatique ou manuelle if response.has_unsourced_claims: patterns["hallucination"] += 1 if response.missing_key_info: patterns["incomplete"] += 1 # ... autres analyses # Identifie le problème principal main_issue = max(patterns, key=patterns.get) # Suggère des améliorations au prompt suggestions = { "hallucination": "Renforcer les contraintes de sourcing", "incomplete": "Demander explicitement la couverture complète", "off_topic": "Ajouter des exemples de réponses hors sujet", "wrong_format": "Clarifier le format avec des exemples", "too_long": "Ajouter une limite de mots explicite", "too_short": "Demander des détails et exemples", } return main_issue, suggestions[main_issue]
Erreurs courantes à éviter
1. Prompts trop vagues
DEVELOPERpython# ❌ Mauvais : trop vague bad_prompt = "Réponds à la question avec les documents." # ✅ Bon : instructions précises good_prompt = """ Réponds à la question en suivant ces règles : 1. Utilise UNIQUEMENT les informations des documents fournis 2. Structure ta réponse avec des bullet points 3. Cite le document source entre crochets [Source: ...] 4. Si l'information n'est pas disponible, dis "Information non trouvée" 5. Limite ta réponse à 200 mots maximum """
2. Ignorer les cas d'échec
DEVELOPERpython# ❌ Mauvais : pas de gestion des cas limites bad_prompt = "Réponds à partir des documents : {context}" # ✅ Bon : gestion explicite good_prompt = """ Réponds à la question avec les documents. SI l'information n'est pas dans les documents : - Ne devine PAS la réponse - Dis : "Cette information n'est pas dans ma base de connaissances" - Suggère une source alternative si possible SI la question est ambiguë : - Demande une clarification - Propose les interprétations possibles """
3. Contexte mal structuré
DEVELOPERpython# ❌ Mauvais : contexte brut bad_context = doc1.text + doc2.text + doc3.text # ✅ Bon : contexte structuré good_context = f""" Document 1 - {doc1.title} (pertinence: {doc1.score:.0%}) {doc1.text} --- Document 2 - {doc2.title} (pertinence: {doc2.score:.0%}) {doc2.text} --- Document 3 - {doc3.title} (pertinence: {doc3.score:.0%}) {doc3.text} """
Intégration avec Ailog
Ailog simplifie le prompt engineering RAG en proposant :
- Templates pré-optimisés par cas d'usage
- Variables dynamiques pour personnaliser sans coder
- A/B testing intégré pour optimiser vos prompts
- Analytics pour identifier les points d'amélioration
DEVELOPERpython# Exemple avec l'API Ailog from ailog import AilogClient client = AilogClient(api_key="your-key") # Utiliser un template optimisé response = client.chat( channel_id="support-widget", message="Comment réinitialiser mon mot de passe ?", prompt_template="customer_support_v2", prompt_variables={ "company": "Acme Corp", "tone": "friendly", "max_words": 150 } )
Conclusion
Le prompt engineering RAG est un levier puissant pour améliorer la qualité de vos chatbots. Les clés du succès :
- Structure claire : Persona, instructions, contraintes, format
- Gestion des cas limites : Prévoir l'absence d'information
- Exemples guidés : Montrer le comportement attendu
- Mesure continue : A/B testing et analyse des échecs
- Itération : Améliorer progressivement basé sur les données
Ressources complémentaires
- Introduction au RAG - Comprendre les fondamentaux
- Génération LLM pour RAG - Guide parent sur la génération
- Chain-of-Thought RAG - Raisonnement étape par étape
- Streaming RAG - Réponses en temps réel
Prêt à optimiser vos prompts RAG ? Essayez Ailog gratuitement et bénéficiez de templates pré-optimisés pour votre cas d'usage.
FAQ
Tags
Articles connexes
Génération RAG : Choisir et optimiser son LLM
Guide complet pour sélectionner et configurer votre LLM dans un système RAG : prompting, température, tokens et optimisation des réponses.
Agents RAG : Orchestrer des systemes multi-agents
Architecturez des systemes RAG multi-agents : orchestration, specialisation, collaboration et gestion des echecs pour des assistants complexes.
RAG Conversationnel : Memoire et contexte multi-sessions
Implementez un RAG avec memoire conversationnelle : gestion du contexte, historique multi-sessions et personnalisation des reponses.