Chatbot E-commerce IA : Booster les conversions avec le RAG

Déployez un chatbot IA sur votre boutique en ligne pour augmenter vos ventes, réduire l'abandon de panier et améliorer l'expérience client.

Auteur
Équipe Ailog
Date de publication
Temps de lecture
22 min de lecture
Niveau
intermediate

Chatbot E-commerce IA : Booster les conversions avec le RAG

Les chatbots IA révolutionnent l'e-commerce. Un assistant capable de comprendre vos produits, de guider les clients et de répondre instantanément aux questions peut transformer votre taux de conversion. Ce guide vous montre comment déployer un chatbot RAG performant sur votre boutique en ligne.

Pourquoi un chatbot RAG pour l'e-commerce ?

Les limites des chatbots traditionnels

Les chatbots à base de règles (if/then) ou les FAQ statiques montrent vite leurs limites : • Rigidité : Ne comprennent que les formulations prévues • Maintenance lourde : Chaque nouvelle question nécessite une règle • Expérience frustrante : "Je n'ai pas compris votre question" répété en boucle • Pas de contexte produit : Incapables de recommander le bon produit

L'avantage RAG

Un chatbot RAG connecté à votre catalogue produit :

| Aspect | Chatbot traditionnel | Chatbot RAG | |--------|---------------------|-------------| | Compréhension langage naturel | Limitée (mots-clés) | Excellente (sémantique) | | Connaissance produits | Statique, manuelle | Dynamique, synchronisée | | Personnalisation | Basique | Contextuelle | | Scalabilité | Difficile (règles) | Simple (documents) | | Maintenance | Lourde | Automatisée |

Impact business prouvé

Les boutiques utilisant des chatbots IA rapportent : • +15-30% de taux de conversion sur les visiteurs engagés • -40% de tickets support pour questions pré-vente • +25% de panier moyen grâce aux recommandations • 24/7 de disponibilité sans coût supplémentaire

Architecture d'un chatbot e-commerce RAG

`` ┌─────────────────────────────────────────────────────────────┐ │ SOURCES DE DONNÉES │ ├─────────────┬─────────────┬─────────────┬──────────────────┤ │ Catalogue │ FAQ │ Politique │ Historique │ │ Produits │ Support │ Retour │ Client │ └──────┬──────┴──────┬──────┴──────┬──────┴────────┬─────────┘ │ │ │ │ └─────────────┴──────┬──────┴───────────────┘ ▼ ┌─────────────────┐ │ Indexation │ │ (Embeddings) │ └────────┬────────┘ ▼ ┌─────────────────┐ │ Base Vecto. │ │ (Qdrant) │ └────────┬────────┘ │ ┌───────────────────────────┴───────────────────────────────┐ │ RUNTIME │ ├─────────────────────────────────────────────────────────────┤ │ ┌─────────┐ ┌───────────┐ ┌──────────┐ ┌────────┐ │ │ │ Widget │───▶│ Retriever │───▶│ LLM │──▶│Response│ │ │ │ Chat │ │ │ │(Génération)│ │ │ │ │ └─────────┘ └───────────┘ └──────────┘ └────────┘ │ └─────────────────────────────────────────────────────────────┘ `

Synchroniser le catalogue produit

Connecteur Shopify

`python import shopify from datetime import datetime

class ShopifyConnector: def __init__(self, shop_url: str, access_token: str): shopify.ShopifyResource.set_site(shop_url) shopify.ShopifyResource.set_headers({ 'X-Shopify-Access-Token': access_token })

def get_all_products(self) -> list[dict]: """ Récupère tous les produits avec leurs variantes """ products = [] page = shopify.Product.find(limit=250)

while page: for product in page: products.append(self._format_product(product))

Pagination if len(page) < 250: break page = shopify.Product.find(limit=250, since_id=page[-1].id)

return products

def _format_product(self, product) -> dict: """ Formate un produit pour l'indexation RAG """ Construire une description riche pour le RAG description_parts = [ f"Produit : {product.title}", f"Description : {self._clean_html(product.body_html)}", f"Catégorie : {product.product_type}", f"Marque : {product.vendor}", f"Tags : {', '.join(product.tags.split(', '))}", ]

Ajouter les variantes for variant in product.variants: variant_info = f"Variante : {variant.title}" if variant.price: variant_info += f" - Prix : {variant.price}€" if variant.inventory_quantity: variant_info += f" - Stock : {variant.inventory_quantity}" description_parts.append(variant_info)

return { "id": f"product_{product.id}", "title": product.title, "content": "\n".join(description_parts), "metadata": { "type": "product", "product_id": product.id, "price_min": min(v.price for v in product.variants), "price_max": max(v.price for v in product.variants), "category": product.product_type, "in_stock": any(v.inventory_quantity > 0 for v in product.variants), "url": f"/products/{product.handle}", "image": product.images[0].src if product.images else None, "updated_at": product.updated_at } }

def _clean_html(self, html: str) -> str: from bs4 import BeautifulSoup return BeautifulSoup(html or "", "html.parser").get_text() `

Connecteur WooCommerce

`python from woocommerce import API

class WooCommerceConnector: def __init__(self, url: str, consumer_key: str, consumer_secret: str): self.wcapi = API( url=url, consumer_key=consumer_key, consumer_secret=consumer_secret, version="wc/v3" )

def get_all_products(self) -> list[dict]: """ Récupère tous les produits WooCommerce """ products = [] page = 1

while True: response = self.wcapi.get("products", params={ "per_page": 100, "page": page, "status": "publish" })

batch = response.json() if not batch: break

for product in batch: products.append(self._format_product(product))

page += 1

return products

def _format_product(self, product: dict) -> dict: """ Formate un produit WooCommerce pour le RAG """ description_parts = [ f"Produit : {product['name']}", f"Description : {self._clean_html(product.get('description', ''))}", f"Description courte : {self._clean_html(product.get('short_description', ''))}", ]

Catégories categories = [cat['name'] for cat in product.get('categories', [])] if categories: description_parts.append(f"Catégories : {', '.join(categories)}")

Attributs for attr in product.get('attributes', []): description_parts.append(f"{attr['name']} : {', '.join(attr['options'])}")

Prix if product.get('sale_price'): description_parts.append(f"Prix : {product['sale_price']}€ (au lieu de {product['regular_price']}€)") else: description_parts.append(f"Prix : {product.get('price', 'N/A')}€")

return { "id": f"product_{product['id']}", "title": product['name'], "content": "\n".join(description_parts), "metadata": { "type": "product", "product_id": product['id'], "price": float(product.get('price', 0)), "categories": categories, "in_stock": product.get('stock_status') == 'instock', "url": product.get('permalink', ''), "image": product['images'][0]['src'] if product.get('images') else None } }

def _clean_html(self, html: str) -> str: from bs4 import BeautifulSoup return BeautifulSoup(html or "", "html.parser").get_text() `

Synchronisation automatique

`python import asyncio from datetime import datetime, timedelta

class ProductSyncService: def __init__(self, connector, indexer, sync_interval_hours: int = 6): self.connector = connector self.indexer = indexer self.sync_interval = timedelta(hours=sync_interval_hours) self.last_sync = None

async def start_sync_loop(self): """ Lance la synchronisation périodique """ while True: try: await self.sync() except Exception as e: print(f"Erreur sync : {e}")

await asyncio.sleep(self.sync_interval.total_seconds())

async def sync(self): """ Synchronise les produits avec la base vectorielle """ print(f"[{datetime.now()}] Début synchronisation produits...")

Récupérer tous les produits products = self.connector.get_all_products()

Indexer await self.indexer.index_documents( documents=products, collection="products" )

self.last_sync = datetime.now() print(f"[{datetime.now()}] {len(products)} produits synchronisés")

async def sync_single_product(self, product_id: str): """ Synchronise un seul produit (webhook) """ product = self.connector.get_product(product_id) if product: await self.indexer.update_document( document=product, collection="products" ) `

Prompts e-commerce optimisés

Prompt assistant de vente

`python SALES_ASSISTANT_PROMPT = """Tu es l'assistant de vente IA de {boutique_name}, une boutique spécialisée dans {categorie}.

OBJECTIF PRINCIPAL : Aider les visiteurs à trouver le produit parfait et les accompagner jusqu'à l'achat.

RÈGLES STRICTES : Base tes recommandations UNIQUEMENT sur les produits du catalogue fourni Ne jamais inventer de produits, prix ou caractéristiques Si un produit n'est pas en stock, le mentionner et proposer des alternatives Toujours inclure le lien vers la fiche produit

COMPORTEMENT : • Pose des questions pour comprendre le besoin • Propose 2-3 produits maximum par réponse • Mets en avant les promotions actuelles • Rassure sur la politique de retour si hésitation détectée

FORMAT RECOMMANDATION : Pour chaque produit recommandé, utilise ce format : [Nom du produit] Prix : XX€ [Description courte de 1-2 phrases expliquant pourquoi ce produit correspond] 👉 Voir le produit

PRODUITS DISPONIBLES : {context}

CONVERSATION : {history}

QUESTION CLIENT : {question} """ `

Prompt support après-vente

`python SUPPORT_PROMPT = """Tu es l'assistant support de {boutique_name}.

OBJECTIF : Aider les clients avec leurs commandes, retours et questions après-achat.

RÈGLES : Réponds uniquement à partir des politiques et FAQ fournies Pour toute question sur une commande spécifique, demande le numéro de commande Si le problème nécessite une intervention humaine, oriente vers le formulaire de contact Reste empathique face aux frustrations

INFORMATIONS DISPONIBLES : {context}

QUESTION : {question} """ `

Détection d'intention et routage

`python from enum import Enum

class CustomerIntent(Enum): PRODUCT_SEARCH = "recherche_produit" PRODUCT_COMPARISON = "comparaison" PRICE_QUESTION = "question_prix" STOCK_CHECK = "verification_stock" ORDER_STATUS = "suivi_commande" RETURN_REQUEST = "demande_retour" GENERAL_SUPPORT = "support_general" CHITCHAT = "conversation"

class IntentDetector: def __init__(self, llm): self.llm = llm

async def detect(self, message: str, history: list = None) -> CustomerIntent: """ Détecte l'intention du client """ prompt = f""" Analyse ce message client et détermine son intention principale.

Message : {message}

Intentions possibles : • recherche_produit : Le client cherche un produit • comparaison : Le client compare des produits • question_prix : Question sur un prix ou promotion • verification_stock : Vérifie la disponibilité • suivi_commande : Demande le statut d'une commande • demande_retour : Veut retourner un produit • support_general : Question support autre • conversation : Simple conversation/salutation

Réponds uniquement avec l'intention (un seul mot). """

response = await self.llm.generate(prompt, temperature=0) intent_str = response.strip().lower()

try: return CustomerIntent(intent_str) except ValueError: return CustomerIntent.GENERAL_SUPPORT

class EcommerceRAGRouter: def __init__(self, intent_detector, retrievers: dict, generators: dict): self.intent_detector = intent_detector self.retrievers = retrievers self.generators = generators

async def route(self, message: str, history: list = None) -> dict: """ Route la requête vers le bon retriever et générateur """ intent = await self.intent_detector.detect(message, history)

Mapping intention -> configuration config = { CustomerIntent.PRODUCT_SEARCH: { "retriever": "products", "generator": "sales", "filters": {"in_stock": True} }, CustomerIntent.PRODUCT_COMPARISON: { "retriever": "products", "generator": "sales", "top_k": 10 }, CustomerIntent.PRICE_QUESTION: { "retriever": "products", "generator": "sales" }, CustomerIntent.STOCK_CHECK: { "retriever": "products", "generator": "sales" }, CustomerIntent.ORDER_STATUS: { "retriever": "support", "generator": "support", "require_order_number": True }, CustomerIntent.RETURN_REQUEST: { "retriever": "policies", "generator": "support" }, CustomerIntent.GENERAL_SUPPORT: { "retriever": "support", "generator": "support" }, CustomerIntent.CHITCHAT: { "retriever": None, "generator": "chitchat" } }

return { "intent": intent, "config": config.get(intent, config[CustomerIntent.GENERAL_SUPPORT]) } `

Recommandations produits intelligentes

Recommandation par similarité

`python class ProductRecommender: def __init__(self, retriever): self.retriever = retriever

async def similar_products( self, product_id: str, exclude_ids: list[str] = None, limit: int = 4 ) -> list[dict]: """ Trouve des produits similaires """ Récupérer le produit source source_product = await self.retriever.get_by_id(product_id) if not source_product: return []

Rechercher par similarité results = await self.retriever.search( query=source_product["content"], top_k=limit + len(exclude_ids or []) + 1, filters={"type": "product", "in_stock": True} )

Filtrer exclude = set(exclude_ids or []) | {product_id} recommendations = [ r for r in results if r["metadata"]["product_id"] not in exclude ][:limit]

return recommendations

async def complementary_products( self, cart_items: list[str], limit: int = 3 ) -> list[dict]: """ Suggère des produits complémentaires (cross-sell) """ Construire une requête basée sur le panier cart_products = [] for product_id in cart_items: product = await self.retriever.get_by_id(product_id) if product: cart_products.append(product["title"])

if not cart_products: return []

Recherche de compléments query = f"Produits qui vont bien avec : {', '.join(cart_products)}"

results = await self.retriever.search( query=query, top_k=limit + len(cart_items), filters={"type": "product", "in_stock": True} )

Exclure les produits déjà dans le panier return [r for r in results if r["metadata"]["product_id"] not in cart_items][:limit] `

Recommandation contextuelle avec LLM

`python async def generate_recommendation( self, customer_query: str, customer_context: dict, retrieved_products: list[dict] ) -> str: """ Génère une recommandation personnalisée """ prompt = f""" Tu dois recommander des produits à un client.

CONTEXTE CLIENT : • Requête : {customer_query} • Budget indiqué : {customer_context.get('budget', 'Non précisé')} • Historique achats : {customer_context.get('purchase_history', 'Nouveau client')}

PRODUITS DISPONIBLES : {self._format_products(retrieved_products)}

CONSIGNES : Choisis 2-3 produits maximum Explique pourquoi chaque produit correspond Adapte ton discours au budget si indiqué Propose une alternative moins chère si budget limité

RECOMMANDATION : """

return await self.llm.generate(prompt, temperature=0.3) `

Gestion du panier et upsell

Détection d'abandon de panier

`python class CartAbandonmentDetector: def __init__(self, session_timeout_minutes: int = 30): self.timeout = timedelta(minutes=session_timeout_minutes) self.active_carts = {}

def track_activity(self, session_id: str, cart_items: list): """ Suit l'activité du panier """ self.active_carts[session_id] = { "items": cart_items, "last_activity": datetime.now(), "notified": False }

def get_abandoned_carts(self) -> list[dict]: """ Identifie les paniers abandonnés """ abandoned = [] now = datetime.now()

for session_id, cart in self.active_carts.items(): if (now - cart["last_activity"] > self.timeout and not cart["notified"] and len(cart["items"]) > 0): abandoned.append({ "session_id": session_id, "items": cart["items"], "abandoned_at": cart["last_activity"] })

return abandoned

class CartRecoveryBot: def __init__(self, recommender, llm): self.recommender = recommender self.llm = llm

async def generate_recovery_message( self, cart_items: list[dict], customer_name: str = None ) -> str: """ Génère un message de récupération de panier """ items_text = "\n".join([ f"- {item['title']} ({item['price']}€)" for item in cart_items ])

prompt = f""" Un client a abandonné son panier. Génère un message amical pour l'encourager à finaliser.

Articles dans le panier : {items_text}

Le message doit : • Être chaleureux mais pas insistant • Rappeler les articles • Mentionner qu'on peut aider si question • Proposer de l'aide pour choisir

{"Commence par 'Bonjour " + customer_name + "'" if customer_name else ""} """

return await self.llm.generate(prompt, temperature=0.7) `

Widget de chat optimisé

Configuration du widget

`javascript // Configuration widget e-commerce const chatConfig = { // Apparence theme: { primaryColor: '#2563eb', position: 'bottom-right', bubbleText: 'Besoin d\'aide ?' },

// Comportement proactif proactive: { enabled: true, triggers: [ { event: 'time_on_page', value: 60, // secondes message: 'Vous cherchez quelque chose en particulier ? Je peux vous aider !' }, { event: 'page_type', value: 'product', delay: 30, message: 'Des questions sur ce produit ? Je suis là pour vous aider.' }, { event: 'cart_value', value: 100, message: 'Saviez-vous que la livraison est gratuite dès 150€ ?' } ] },

// Quick replies contextuels quickReplies: { homepage: [ 'Quelles sont vos meilleures ventes ?', 'Y a-t-il des promotions ?', 'Comment fonctionne la livraison ?' ], product: [ 'Ce produit est-il disponible ?', 'Quels sont les délais de livraison ?', 'Puis-je retourner ce produit ?' ], cart: [ 'Comment utiliser un code promo ?', 'Quels sont les frais de livraison ?', 'Puis-je modifier ma commande ?' ] } }; `

Tracking des conversions

`python class ChatAnalytics: def __init__(self, analytics_client): self.client = analytics_client

def track_conversation( self, session_id: str, messages: list, outcome: str, metadata: dict = None ): """ Track une conversation pour analyse """ self.client.track({ "event": "chat_conversation", "session_id": session_id, "message_count": len(messages), "outcome": outcome, "purchase", "support_ticket", "abandoned" "duration_seconds": self._calculate_duration(messages), "products_discussed": metadata.get("products", []), "intent_detected": metadata.get("intent"), "timestamp": datetime.now().isoformat() })

def track_chat_to_purchase( self, session_id: str, order_value: float, products: list ): """ Track une conversion chat -> achat """ self.client.track({ "event": "chat_conversion", "session_id": session_id, "order_value": order_value, "products": products, "attribution": "chat_assisted" })

def get_chat_roi_metrics(self, period_days: int = 30) -> dict: """ Calcule le ROI du chat """ data = self.client.query(f""" SELECT COUNT(DISTINCT session_id) as conversations, COUNT(DISTINCT CASE WHEN outcome = 'purchase' THEN session_id END) as conversions, SUM(CASE WHEN outcome = 'purchase' THEN order_value ELSE 0 END) as revenue, AVG(message_count) as avg_messages FROM chat_events WHERE timestamp > NOW() - INTERVAL '{period_days} days' """)

return { "total_conversations": data["conversations"], "conversions": data["conversions"], "conversion_rate": data["conversions"] / data["conversations"] * 100, "revenue_attributed": data["revenue"], "avg_messages_per_conversation": data["avg_messages"] } `

Bonnes pratiques e-commerce Réponses riches avec produits

Toujours formater les recommandations produits de manière visuelle :

`python def format_product_card(product: dict) -> str: """ Formate un produit en carte visuelle (Markdown) """ price_text = f"{product['price']}€" if product.get('original_price'): price_text = f"~~{product['original_price']}€~~ {product['price']}€"

stock_badge = "En stock" if product['in_stock'] else "Rupture de stock"

return f""" {product['title']} {price_text} | {stock_badge}

{product['short_description']}

Voir le produit """ ` Gestion des ruptures de stock

`python async def handle_out_of_stock(self, product: dict, query: str) -> str: """ Gère intelligemment les ruptures de stock """ Trouver des alternatives alternatives = await self.recommender.similar_products( product_id=product["id"], filters={"in_stock": True}, limit=3 )

if alternatives: alt_text = "\n".join([format_product_card(p) for p in alternatives]) return f""" Malheureusement, {product['title']} n'est plus disponible actuellement.

Voici des alternatives similaires que vous pourriez aimer :

{alt_text}

Souhaitez-vous être notifié quand le produit sera de retour en stock ? """ else: return f""" Malheureusement, {product['title']} n'est plus disponible actuellement et nous n'avons pas d'alternative similaire.

Souhaitez-vous être notifié quand le produit sera de retour en stock ? """ ` Escalade vers le support humain

`python def should_escalate(self, conversation: list, last_response: dict) -> bool: """ Détermine si une escalade vers un humain est nécessaire """ escalation_triggers = [ Sentiment négatif répété len([m for m in conversation[-3:] if m.get("sentiment") == "negative"]) >= 2,

Demande explicite any(kw in conversation[-1]["text"].lower() for kw in [ "parler à quelqu'un", "humain", "conseiller", "téléphone" ]),

Confiance faible du modèle last_response.get("confidence", 1) < 0.5,

Conversation trop longue sans résolution len(conversation) > 10 and not last_response.get("resolved") ]

return any(escalation_triggers) ``

Mesurer le succès

KPIs à suivre

| Métrique | Cible | Comment mesurer | |----------|-------|-----------------| | Taux d'engagement | > 15% visiteurs | Visiteurs ayant ouvert le chat | | Taux de résolution | > 80% | Conversations sans escalade | | Conversion assistée | > 5% | Achats après interaction chat | | CSAT chat | > 4/5 | Évaluation fin de conversation | | Temps de réponse | < 3s | Latence première réponse | | Coût par conversation | < 0.10€ | Coût LLM / nombre conversations |

Pour aller plus loin • Fondamentaux du Retrieval - Optimiser la recherche produit • Support Client IA - Réduire les tickets support • Introduction au RAG - Comprendre les bases

---

Lancez votre chatbot e-commerce avec Ailog

Déployer un chatbot RAG performant sur votre boutique peut prendre des mois de développement. Avec Ailog, lancez-vous en quelques heures : • Connecteurs natifs : Shopify, WooCommerce, PrestaShop, Magento • Synchronisation automatique du catalogue produit • Widget personnalisable qui s'intègre à votre charte graphique • Analytics conversationnels pour mesurer le ROI • Hébergement France conforme RGPD

Testez Ailog gratuitement et boostez vos conversions dès aujourd'hui.

Tags

  • RAG
  • e-commerce
  • chatbot
  • conversion
  • Shopify
  • WooCommerce
GuideIntermédiaire

Chatbot E-commerce IA : Booster les conversions avec le RAG

19 janvier 2026
22 min de lecture
Équipe Ailog

Déployez un chatbot IA sur votre boutique en ligne pour augmenter vos ventes, réduire l'abandon de panier et améliorer l'expérience client.

Chatbot E-commerce IA : Booster les conversions avec le RAG

Les chatbots IA révolutionnent l'e-commerce. Un assistant capable de comprendre vos produits, de guider les clients et de répondre instantanément aux questions peut transformer votre taux de conversion. Ce guide vous montre comment déployer un chatbot RAG performant sur votre boutique en ligne.

Pourquoi un chatbot RAG pour l'e-commerce ?

Les limites des chatbots traditionnels

Les chatbots à base de règles (if/then) ou les FAQ statiques montrent vite leurs limites :

  • Rigidité : Ne comprennent que les formulations prévues
  • Maintenance lourde : Chaque nouvelle question nécessite une règle
  • Expérience frustrante : "Je n'ai pas compris votre question" répété en boucle
  • Pas de contexte produit : Incapables de recommander le bon produit

L'avantage RAG

Un chatbot RAG connecté à votre catalogue produit :

AspectChatbot traditionnelChatbot RAG
Compréhension langage naturelLimitée (mots-clés)Excellente (sémantique)
Connaissance produitsStatique, manuelleDynamique, synchronisée
PersonnalisationBasiqueContextuelle
ScalabilitéDifficile (règles)Simple (documents)
MaintenanceLourdeAutomatisée

Impact business prouvé

Les boutiques utilisant des chatbots IA rapportent :

  • +15-30% de taux de conversion sur les visiteurs engagés
  • -40% de tickets support pour questions pré-vente
  • +25% de panier moyen grâce aux recommandations
  • 24/7 de disponibilité sans coût supplémentaire

Architecture d'un chatbot e-commerce RAG

┌─────────────────────────────────────────────────────────────┐
│                    SOURCES DE DONNÉES                        │
├─────────────┬─────────────┬─────────────┬──────────────────┤
│  Catalogue  │    FAQ      │  Politique  │   Historique     │
│  Produits   │  Support    │   Retour    │    Client        │
└──────┬──────┴──────┬──────┴──────┬──────┴────────┬─────────┘
       │             │             │               │
       └─────────────┴──────┬──────┴───────────────┘
                            ▼
                   ┌─────────────────┐
                   │   Indexation    │
                   │  (Embeddings)   │
                   └────────┬────────┘
                            ▼
                   ┌─────────────────┐
                   │  Base Vecto.    │
                   │   (Qdrant)      │
                   └────────┬────────┘
                            │
┌───────────────────────────┴───────────────────────────────┐
│                        RUNTIME                              │
├─────────────────────────────────────────────────────────────┤
│  ┌─────────┐    ┌───────────┐    ┌──────────┐   ┌────────┐ │
│  │ Widget  │───▶│ Retriever │───▶│   LLM    │──▶│Response│ │
│  │  Chat   │    │           │    │(Génération)│   │        │ │
│  └─────────┘    └───────────┘    └──────────┘   └────────┘ │
└─────────────────────────────────────────────────────────────┘

Synchroniser le catalogue produit

Connecteur Shopify

DEVELOPERpython
import shopify from datetime import datetime class ShopifyConnector: def __init__(self, shop_url: str, access_token: str): shopify.ShopifyResource.set_site(shop_url) shopify.ShopifyResource.set_headers({ 'X-Shopify-Access-Token': access_token }) def get_all_products(self) -> list[dict]: """ Récupère tous les produits avec leurs variantes """ products = [] page = shopify.Product.find(limit=250) while page: for product in page: products.append(self._format_product(product)) # Pagination if len(page) < 250: break page = shopify.Product.find(limit=250, since_id=page[-1].id) return products def _format_product(self, product) -> dict: """ Formate un produit pour l'indexation RAG """ # Construire une description riche pour le RAG description_parts = [ f"Produit : {product.title}", f"Description : {self._clean_html(product.body_html)}", f"Catégorie : {product.product_type}", f"Marque : {product.vendor}", f"Tags : {', '.join(product.tags.split(', '))}", ] # Ajouter les variantes for variant in product.variants: variant_info = f"Variante : {variant.title}" if variant.price: variant_info += f" - Prix : {variant.price}€" if variant.inventory_quantity: variant_info += f" - Stock : {variant.inventory_quantity}" description_parts.append(variant_info) return { "id": f"product_{product.id}", "title": product.title, "content": "\n".join(description_parts), "metadata": { "type": "product", "product_id": product.id, "price_min": min(v.price for v in product.variants), "price_max": max(v.price for v in product.variants), "category": product.product_type, "in_stock": any(v.inventory_quantity > 0 for v in product.variants), "url": f"/products/{product.handle}", "image": product.images[0].src if product.images else None, "updated_at": product.updated_at } } def _clean_html(self, html: str) -> str: from bs4 import BeautifulSoup return BeautifulSoup(html or "", "html.parser").get_text()

Connecteur WooCommerce

DEVELOPERpython
from woocommerce import API class WooCommerceConnector: def __init__(self, url: str, consumer_key: str, consumer_secret: str): self.wcapi = API( url=url, consumer_key=consumer_key, consumer_secret=consumer_secret, version="wc/v3" ) def get_all_products(self) -> list[dict]: """ Récupère tous les produits WooCommerce """ products = [] page = 1 while True: response = self.wcapi.get("products", params={ "per_page": 100, "page": page, "status": "publish" }) batch = response.json() if not batch: break for product in batch: products.append(self._format_product(product)) page += 1 return products def _format_product(self, product: dict) -> dict: """ Formate un produit WooCommerce pour le RAG """ description_parts = [ f"Produit : {product['name']}", f"Description : {self._clean_html(product.get('description', ''))}", f"Description courte : {self._clean_html(product.get('short_description', ''))}", ] # Catégories categories = [cat['name'] for cat in product.get('categories', [])] if categories: description_parts.append(f"Catégories : {', '.join(categories)}") # Attributs for attr in product.get('attributes', []): description_parts.append(f"{attr['name']} : {', '.join(attr['options'])}") # Prix if product.get('sale_price'): description_parts.append(f"Prix : {product['sale_price']}€ (au lieu de {product['regular_price']}€)") else: description_parts.append(f"Prix : {product.get('price', 'N/A')}€") return { "id": f"product_{product['id']}", "title": product['name'], "content": "\n".join(description_parts), "metadata": { "type": "product", "product_id": product['id'], "price": float(product.get('price', 0)), "categories": categories, "in_stock": product.get('stock_status') == 'instock', "url": product.get('permalink', ''), "image": product['images'][0]['src'] if product.get('images') else None } } def _clean_html(self, html: str) -> str: from bs4 import BeautifulSoup return BeautifulSoup(html or "", "html.parser").get_text()

Synchronisation automatique

DEVELOPERpython
import asyncio from datetime import datetime, timedelta class ProductSyncService: def __init__(self, connector, indexer, sync_interval_hours: int = 6): self.connector = connector self.indexer = indexer self.sync_interval = timedelta(hours=sync_interval_hours) self.last_sync = None async def start_sync_loop(self): """ Lance la synchronisation périodique """ while True: try: await self.sync() except Exception as e: print(f"Erreur sync : {e}") await asyncio.sleep(self.sync_interval.total_seconds()) async def sync(self): """ Synchronise les produits avec la base vectorielle """ print(f"[{datetime.now()}] Début synchronisation produits...") # Récupérer tous les produits products = self.connector.get_all_products() # Indexer await self.indexer.index_documents( documents=products, collection="products" ) self.last_sync = datetime.now() print(f"[{datetime.now()}] {len(products)} produits synchronisés") async def sync_single_product(self, product_id: str): """ Synchronise un seul produit (webhook) """ product = self.connector.get_product(product_id) if product: await self.indexer.update_document( document=product, collection="products" )

Prompts e-commerce optimisés

Prompt assistant de vente

DEVELOPERpython
SALES_ASSISTANT_PROMPT = """Tu es l'assistant de vente IA de {boutique_name}, une boutique spécialisée dans {categorie}. OBJECTIF PRINCIPAL : Aider les visiteurs à trouver le produit parfait et les accompagner jusqu'à l'achat. RÈGLES STRICTES : 1. Base tes recommandations UNIQUEMENT sur les produits du catalogue fourni 2. Ne jamais inventer de produits, prix ou caractéristiques 3. Si un produit n'est pas en stock, le mentionner et proposer des alternatives 4. Toujours inclure le lien vers la fiche produit COMPORTEMENT : - Pose des questions pour comprendre le besoin - Propose 2-3 produits maximum par réponse - Mets en avant les promotions actuelles - Rassure sur la politique de retour si hésitation détectée FORMAT RECOMMANDATION : Pour chaque produit recommandé, utilise ce format : **[Nom du produit]** Prix : XX€ [Description courte de 1-2 phrases expliquant pourquoi ce produit correspond] 👉 [Voir le produit](URL) PRODUITS DISPONIBLES : {context} CONVERSATION : {history} QUESTION CLIENT : {question} """

Prompt support après-vente

DEVELOPERpython
SUPPORT_PROMPT = """Tu es l'assistant support de {boutique_name}. OBJECTIF : Aider les clients avec leurs commandes, retours et questions après-achat. RÈGLES : 1. Réponds uniquement à partir des politiques et FAQ fournies 2. Pour toute question sur une commande spécifique, demande le numéro de commande 3. Si le problème nécessite une intervention humaine, oriente vers le formulaire de contact 4. Reste empathique face aux frustrations INFORMATIONS DISPONIBLES : {context} QUESTION : {question} """

Détection d'intention et routage

DEVELOPERpython
from enum import Enum class CustomerIntent(Enum): PRODUCT_SEARCH = "recherche_produit" PRODUCT_COMPARISON = "comparaison" PRICE_QUESTION = "question_prix" STOCK_CHECK = "verification_stock" ORDER_STATUS = "suivi_commande" RETURN_REQUEST = "demande_retour" GENERAL_SUPPORT = "support_general" CHITCHAT = "conversation" class IntentDetector: def __init__(self, llm): self.llm = llm async def detect(self, message: str, history: list = None) -> CustomerIntent: """ Détecte l'intention du client """ prompt = f""" Analyse ce message client et détermine son intention principale. Message : {message} Intentions possibles : - recherche_produit : Le client cherche un produit - comparaison : Le client compare des produits - question_prix : Question sur un prix ou promotion - verification_stock : Vérifie la disponibilité - suivi_commande : Demande le statut d'une commande - demande_retour : Veut retourner un produit - support_general : Question support autre - conversation : Simple conversation/salutation Réponds uniquement avec l'intention (un seul mot). """ response = await self.llm.generate(prompt, temperature=0) intent_str = response.strip().lower() try: return CustomerIntent(intent_str) except ValueError: return CustomerIntent.GENERAL_SUPPORT class EcommerceRAGRouter: def __init__(self, intent_detector, retrievers: dict, generators: dict): self.intent_detector = intent_detector self.retrievers = retrievers self.generators = generators async def route(self, message: str, history: list = None) -> dict: """ Route la requête vers le bon retriever et générateur """ intent = await self.intent_detector.detect(message, history) # Mapping intention -> configuration config = { CustomerIntent.PRODUCT_SEARCH: { "retriever": "products", "generator": "sales", "filters": {"in_stock": True} }, CustomerIntent.PRODUCT_COMPARISON: { "retriever": "products", "generator": "sales", "top_k": 10 }, CustomerIntent.PRICE_QUESTION: { "retriever": "products", "generator": "sales" }, CustomerIntent.STOCK_CHECK: { "retriever": "products", "generator": "sales" }, CustomerIntent.ORDER_STATUS: { "retriever": "support", "generator": "support", "require_order_number": True }, CustomerIntent.RETURN_REQUEST: { "retriever": "policies", "generator": "support" }, CustomerIntent.GENERAL_SUPPORT: { "retriever": "support", "generator": "support" }, CustomerIntent.CHITCHAT: { "retriever": None, "generator": "chitchat" } } return { "intent": intent, "config": config.get(intent, config[CustomerIntent.GENERAL_SUPPORT]) }

Recommandations produits intelligentes

Recommandation par similarité

DEVELOPERpython
class ProductRecommender: def __init__(self, retriever): self.retriever = retriever async def similar_products( self, product_id: str, exclude_ids: list[str] = None, limit: int = 4 ) -> list[dict]: """ Trouve des produits similaires """ # Récupérer le produit source source_product = await self.retriever.get_by_id(product_id) if not source_product: return [] # Rechercher par similarité results = await self.retriever.search( query=source_product["content"], top_k=limit + len(exclude_ids or []) + 1, filters={"type": "product", "in_stock": True} ) # Filtrer exclude = set(exclude_ids or []) | {product_id} recommendations = [ r for r in results if r["metadata"]["product_id"] not in exclude ][:limit] return recommendations async def complementary_products( self, cart_items: list[str], limit: int = 3 ) -> list[dict]: """ Suggère des produits complémentaires (cross-sell) """ # Construire une requête basée sur le panier cart_products = [] for product_id in cart_items: product = await self.retriever.get_by_id(product_id) if product: cart_products.append(product["title"]) if not cart_products: return [] # Recherche de compléments query = f"Produits qui vont bien avec : {', '.join(cart_products)}" results = await self.retriever.search( query=query, top_k=limit + len(cart_items), filters={"type": "product", "in_stock": True} ) # Exclure les produits déjà dans le panier return [r for r in results if r["metadata"]["product_id"] not in cart_items][:limit]

Recommandation contextuelle avec LLM

DEVELOPERpython
async def generate_recommendation( self, customer_query: str, customer_context: dict, retrieved_products: list[dict] ) -> str: """ Génère une recommandation personnalisée """ prompt = f""" Tu dois recommander des produits à un client. CONTEXTE CLIENT : - Requête : {customer_query} - Budget indiqué : {customer_context.get('budget', 'Non précisé')} - Historique achats : {customer_context.get('purchase_history', 'Nouveau client')} PRODUITS DISPONIBLES : {self._format_products(retrieved_products)} CONSIGNES : 1. Choisis 2-3 produits maximum 2. Explique pourquoi chaque produit correspond 3. Adapte ton discours au budget si indiqué 4. Propose une alternative moins chère si budget limité RECOMMANDATION : """ return await self.llm.generate(prompt, temperature=0.3)

Gestion du panier et upsell

Détection d'abandon de panier

DEVELOPERpython
class CartAbandonmentDetector: def __init__(self, session_timeout_minutes: int = 30): self.timeout = timedelta(minutes=session_timeout_minutes) self.active_carts = {} def track_activity(self, session_id: str, cart_items: list): """ Suit l'activité du panier """ self.active_carts[session_id] = { "items": cart_items, "last_activity": datetime.now(), "notified": False } def get_abandoned_carts(self) -> list[dict]: """ Identifie les paniers abandonnés """ abandoned = [] now = datetime.now() for session_id, cart in self.active_carts.items(): if (now - cart["last_activity"] > self.timeout and not cart["notified"] and len(cart["items"]) > 0): abandoned.append({ "session_id": session_id, "items": cart["items"], "abandoned_at": cart["last_activity"] }) return abandoned class CartRecoveryBot: def __init__(self, recommender, llm): self.recommender = recommender self.llm = llm async def generate_recovery_message( self, cart_items: list[dict], customer_name: str = None ) -> str: """ Génère un message de récupération de panier """ items_text = "\n".join([ f"- {item['title']} ({item['price']}€)" for item in cart_items ]) prompt = f""" Un client a abandonné son panier. Génère un message amical pour l'encourager à finaliser. Articles dans le panier : {items_text} Le message doit : - Être chaleureux mais pas insistant - Rappeler les articles - Mentionner qu'on peut aider si question - Proposer de l'aide pour choisir {"Commence par 'Bonjour " + customer_name + "'" if customer_name else ""} """ return await self.llm.generate(prompt, temperature=0.7)

Widget de chat optimisé

Configuration du widget

DEVELOPERjavascript
// Configuration widget e-commerce const chatConfig = { // Apparence theme: { primaryColor: '#2563eb', position: 'bottom-right', bubbleText: 'Besoin d\'aide ?' }, // Comportement proactif proactive: { enabled: true, triggers: [ { event: 'time_on_page', value: 60, // secondes message: 'Vous cherchez quelque chose en particulier ? Je peux vous aider !' }, { event: 'page_type', value: 'product', delay: 30, message: 'Des questions sur ce produit ? Je suis là pour vous aider.' }, { event: 'cart_value', value: 100, message: 'Saviez-vous que la livraison est gratuite dès 150€ ?' } ] }, // Quick replies contextuels quickReplies: { homepage: [ 'Quelles sont vos meilleures ventes ?', 'Y a-t-il des promotions ?', 'Comment fonctionne la livraison ?' ], product: [ 'Ce produit est-il disponible ?', 'Quels sont les délais de livraison ?', 'Puis-je retourner ce produit ?' ], cart: [ 'Comment utiliser un code promo ?', 'Quels sont les frais de livraison ?', 'Puis-je modifier ma commande ?' ] } };

Tracking des conversions

DEVELOPERpython
class ChatAnalytics: def __init__(self, analytics_client): self.client = analytics_client def track_conversation( self, session_id: str, messages: list, outcome: str, metadata: dict = None ): """ Track une conversation pour analyse """ self.client.track({ "event": "chat_conversation", "session_id": session_id, "message_count": len(messages), "outcome": outcome, # "purchase", "support_ticket", "abandoned" "duration_seconds": self._calculate_duration(messages), "products_discussed": metadata.get("products", []), "intent_detected": metadata.get("intent"), "timestamp": datetime.now().isoformat() }) def track_chat_to_purchase( self, session_id: str, order_value: float, products: list ): """ Track une conversion chat -> achat """ self.client.track({ "event": "chat_conversion", "session_id": session_id, "order_value": order_value, "products": products, "attribution": "chat_assisted" }) def get_chat_roi_metrics(self, period_days: int = 30) -> dict: """ Calcule le ROI du chat """ data = self.client.query(f""" SELECT COUNT(DISTINCT session_id) as conversations, COUNT(DISTINCT CASE WHEN outcome = 'purchase' THEN session_id END) as conversions, SUM(CASE WHEN outcome = 'purchase' THEN order_value ELSE 0 END) as revenue, AVG(message_count) as avg_messages FROM chat_events WHERE timestamp > NOW() - INTERVAL '{period_days} days' """) return { "total_conversations": data["conversations"], "conversions": data["conversions"], "conversion_rate": data["conversions"] / data["conversations"] * 100, "revenue_attributed": data["revenue"], "avg_messages_per_conversation": data["avg_messages"] }

Bonnes pratiques e-commerce

1. Réponses riches avec produits

Toujours formater les recommandations produits de manière visuelle :

DEVELOPERpython
def format_product_card(product: dict) -> str: """ Formate un produit en carte visuelle (Markdown) """ price_text = f"{product['price']}€" if product.get('original_price'): price_text = f"~~{product['original_price']}€~~ **{product['price']}€**" stock_badge = "En stock" if product['in_stock'] else "Rupture de stock" return f""" **{product['title']}** {price_text} | {stock_badge} {product['short_description']} [Voir le produit]({product['url']}) """

2. Gestion des ruptures de stock

DEVELOPERpython
async def handle_out_of_stock(self, product: dict, query: str) -> str: """ Gère intelligemment les ruptures de stock """ # Trouver des alternatives alternatives = await self.recommender.similar_products( product_id=product["id"], filters={"in_stock": True}, limit=3 ) if alternatives: alt_text = "\n".join([format_product_card(p) for p in alternatives]) return f""" Malheureusement, **{product['title']}** n'est plus disponible actuellement. Voici des alternatives similaires que vous pourriez aimer : {alt_text} Souhaitez-vous être notifié quand le produit sera de retour en stock ? """ else: return f""" Malheureusement, **{product['title']}** n'est plus disponible actuellement et nous n'avons pas d'alternative similaire. Souhaitez-vous être notifié quand le produit sera de retour en stock ? """

3. Escalade vers le support humain

DEVELOPERpython
def should_escalate(self, conversation: list, last_response: dict) -> bool: """ Détermine si une escalade vers un humain est nécessaire """ escalation_triggers = [ # Sentiment négatif répété len([m for m in conversation[-3:] if m.get("sentiment") == "negative"]) >= 2, # Demande explicite any(kw in conversation[-1]["text"].lower() for kw in [ "parler à quelqu'un", "humain", "conseiller", "téléphone" ]), # Confiance faible du modèle last_response.get("confidence", 1) < 0.5, # Conversation trop longue sans résolution len(conversation) > 10 and not last_response.get("resolved") ] return any(escalation_triggers)

Mesurer le succès

KPIs à suivre

MétriqueCibleComment mesurer
Taux d'engagement> 15% visiteursVisiteurs ayant ouvert le chat
Taux de résolution> 80%Conversations sans escalade
Conversion assistée> 5%Achats après interaction chat
CSAT chat> 4/5Évaluation fin de conversation
Temps de réponse< 3sLatence première réponse
Coût par conversation< 0.10€Coût LLM / nombre conversations

Pour aller plus loin


Lancez votre chatbot e-commerce avec Ailog

Déployer un chatbot RAG performant sur votre boutique peut prendre des mois de développement. Avec Ailog, lancez-vous en quelques heures :

  • Connecteurs natifs : Shopify, WooCommerce, PrestaShop, Magento
  • Synchronisation automatique du catalogue produit
  • Widget personnalisable qui s'intègre à votre charte graphique
  • Analytics conversationnels pour mesurer le ROI
  • Hébergement France conforme RGPD

Testez Ailog gratuitement et boostez vos conversions dès aujourd'hui.

Tags

RAGe-commercechatbotconversionShopifyWooCommerce

Articles connexes

Ailog Assistant

Ici pour vous aider

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