GuideIntermédiaire

Prompt Engineering RAG : Optimiser les prompts système pour de meilleures réponses

12 mars 2026
18 min de lecture
Équipe Ailog

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 :

  1. Guider l'utilisation du contexte : Indiquer au LLM comment exploiter les documents récupérés
  2. Définir le comportement : Ton, style, niveau de détail des réponses
  3. Prévenir les hallucinations : Forcer le modèle à s'appuyer sur les sources
  4. 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 :

ComposantRôleExemple
PersonaDéfinit l'identité de l'assistant"Tu es un expert support client"
InstructionsRègles de comportement"Réponds en 3 phrases max"
ContraintesLimitations explicites"N'invente jamais d'informations"
FormatStructure de la réponse"Utilise des bullet points"
ContexteDocuments récupérés"{context}"
RequêteQuestion utilisateur"{query}"

Template de base recommandé

DEVELOPERpython
RAG_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.

DEVELOPERpython
def 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 :

DEVELOPERpython
few_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 :

DEVELOPERpython
cot_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 :

DEVELOPERpython
edge_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é :

DEVELOPERpython
def 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 :

DEVELOPERpython
def 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

DEVELOPERpython
SUPPORT_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

DEVELOPERpython
ECOMMERCE_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

DEVELOPERpython
KNOWLEDGE_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étriqueDescriptionCible
Faithfulness% de réponses basées sur le contexte> 95%
RelevancePertinence par rapport à la question> 90%
CompletenessCouverture de l'information disponible> 85%
Hallucination rate% d'informations inventées< 5%
Format complianceRespect du format demandé> 95%

A/B Testing de prompts

DEVELOPERpython
import 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

DEVELOPERpython
def 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 :

  1. Structure claire : Persona, instructions, contraintes, format
  2. Gestion des cas limites : Prévoir l'absence d'information
  3. Exemples guidés : Montrer le comportement attendu
  4. Mesure continue : A/B testing et analyse des échecs
  5. Itération : Améliorer progressivement basé sur les données

Ressources complémentaires


Prêt à optimiser vos prompts RAG ? Essayez Ailog gratuitement et bénéficiez de templates pré-optimisés pour votre cas d'usage.

FAQ

Un prompt système efficace fait généralement entre 300 et 800 tokens. Trop court, il manque de précision sur les comportements attendus. Trop long, les instructions se diluent et le LLM peut en ignorer certaines. Structurez par priorité : règles critiques en premier, préférences ensuite.
Ajoutez des contraintes explicites comme "Réponds UNIQUEMENT avec les informations présentes dans les documents" et "Si l'information n'est pas disponible, dis-le clairement". Demandez des citations pour chaque affirmation factuelle. Incluez des exemples de comportement attendu quand l'information est absente.
Non, adaptez le prompt au contexte. Un prompt pour le support client privilégie l'empathie et les étapes actionnables. Un prompt pour la documentation technique favorise la précision et les références. Créez des variantes par cas d'usage et testez-les avec des métriques appropriées.
Incluez une instruction explicite dans le prompt : "Si les documents se contredisent, mentionne les deux versions avec leurs sources et indique la plus récente ou recommande une vérification". Le LLM doit signaler le conflit plutôt que choisir arbitrairement.
Oui, les LLM ont tendance à mieux utiliser les informations en début et fin de contexte (effet "sandwich"). Placez les documents les plus pertinents en première position. Pour les longs contextes, utilisez la stratégie "relevance_sandwich" qui met les documents importants au début et à la fin.

Tags

RAGprompt engineeringLLMsystem promptsgenerationoptimisation

Articles connexes

Ailog Assistant

Ici pour vous aider

Salut ! Pose-moi des questions sur Ailog et comment intégrer votre RAG dans vos projets !