Challenge 01 - Vérification du PoC RAG Assortiment. Les six questions, en un clic, avec lecture guidée et mise en évidence des erreurs du LLM. Mêmes données et même LLM local gratuit que le Swagger de Philippe.
Vérification de l'atelier...
Progression
Questions 1 à 3 - guichets bleus (GET)
Lecture directe de la base de données. La réponse est la vérité brute : c'est toi qui comptes et compares.
Questions 4 à 6 - guichets verts (POST /llm)
Une IA traduit ta phrase en requête. Elle se trompe parfois : ton travail est d'expliquer pourquoi.
Q1
Combien de catégories différentes contient l'assortiment ?
Réussie
Méthode du jour J : demander la liste des catégories au guichet bleu, puis compter toi-même les lignes. Jamais via l'IA, qui prédit au lieu de compter.
Requête envoyée :GET/categories?lang=fr
Interrogation de la base...
Maintenant refais le geste dans le Swagger brut, comme le jour J : dans la version Philippe, ouvre la ligne GET /categories, puis Try it out, puis Execute, et compte les éléments de la réponse.
Q2
Quel est le produit le plus cher ?
Réussie
Méthode du jour J : récupérer tous les produits avec leur prix, puis chercher toi-même le prix le plus élevé. Remarque au passage que la réponse ne précise ni unité ni devise : c'est typiquement une limite à signaler dans un PoC (prototype de démonstration).
Requête envoyée :GET/products?lang=fr
Interrogation de la base...
Refais le geste dans le Swagger brut, comme le jour J : ligne GET /products, Try it out, Execute, puis balaie la colonne des prix à l'œil.
Q3
Quelle catégorie compte le plus de produits ?
Réussie
Méthode du jour J : la liste des catégories donne directement le compte de produits par catégorie (champ product_count). Un seul appel suffit, tu cherches le maximum. S'il y a égalité, l'une ou l'autre réponse est acceptée.
Requête envoyée :GET/categories?lang=fr
Interrogation de la base...
Refais le geste dans le Swagger brut, comme le jour J : même geste que Q1, mais cette fois tu lis le champ product_count de chaque catégorie.
Q4-5
Le piège des "berries" : une réponse fluide, assurée, et fausse
Réussie
Le mode d'échec le plus dangereux n'est pas l'erreur visible : c'est la réponse qui a l'air parfaitement juste et qui est fausse. Au jour J, l'IA a répondu, sans aucune erreur levée, que les "berries" étaient deux produits, "Mandarins" et "Oranges". Or ce sont des agrumes (catégorie Agrumes), pas des baies (catégorie Baies). Rien dans le système n'a signalé la faute. Tu envoies ici la même phrase et tu observes ce que l'IA met dans le blanc "nom de catégorie" : c'est là que tout se joue (Q4), et c'est ce qui manque au prompt (Q5).
Preuve du jour J. Réponse réelle de la v1 : "We have two products in the berries category: Mandarins and Oranges..." (SKU ZF-003 et ZF-001). Crédible, fluide, assurée - et factuellement fausse : ce sont des agrumes présentés comme des baies. C'est une erreur sémantique silencieuse, sans erreur levée.
Voir la preuve du jour J
Requête envoyée :POST/llm/v1
L'IA locale réfléchit, compte 10 à 60 secondes...
Réponse Q5 : ce qui manque au prompt, c'est un identifiant de catégorie sans ambiguïté et la langue. "berries" est un mot anglais dont la résolution par défaut est fragile. Correction : fournir la catégorie exacte (par id, ou nom localisé exact avec lang), ou forcer le système à résoudre l'entité contre le vrai catalogue AVANT de répondre - ne jamais laisser la couche générative inventer la correspondance. En live, l'IA locale est instable : relance plusieurs fois et compare. Tu observeras les trois cas - parfois un nom de catégorie inventé (422), parfois du JSON invalide (500), parfois un succès. La question est validée quand tu as observé au moins une défaillance.
Refais le geste dans le Swagger brut, comme le jour J : dans la version Philippe, ligne POST /llm/v1, Try it out, remplace le texte après "prompt": par ta phrase entre guillemets, Execute.
Q6
La table que l'IA invente : une hallucination de schéma
Réussie
Le guichet IA v2 écrit lui-même la requête SQL à partir du plan de la base. Au jour J, elle a inventé une table en généralisant un motif : categories a sa table categories_i18n, products a products_i18n, donc l'IA a supposé que suppliers avait suppliers_i18n. Cette table n'existe pas - les noms de fournisseurs ne sont pas traduits - et la base a refusé la requête. Envoie la phrase de la donnée et inspecte le SQL généré : cherche un nom de table absent des 6 vraies tables (languages, categories, categories_i18n, products, products_i18n, suppliers). Le cockpit surligne en rouge toute table inventée.
Preuve du jour J. Erreur réelle de la v2 : Table 'examdb.suppliers_i18n' doesn't exist (erreur 1146). Le SQL généré joignait une table suppliers_i18n hallucinée par imitation du motif _i18n des autres tables. Erreur d'exécution dure : au moins, elle est visible.
Voir la preuve du jour J
Requête envoyée :POST/llm/v2
L'IA locale écrit du SQL, compte 10 à 60 secondes...
La table inventée au jour J était suppliers_i18n, généralisée par imitation du motif _i18n. En live, l'IA locale est instable : relance plusieurs fois. Parfois elle invente une table (l'erreur attendue par Q6), parfois un SQL invalide (erreur de syntaxe ou 0 résultat), parfois elle réussit. La question est validée quand une table inventée OU un SQL invalide a été observé.
Refais le geste dans le Swagger brut, comme le jour J : dans la version Philippe, ligne POST /llm/v2, Try it out, remplace le prompt, Execute, puis lis le champ generated_sql à la loupe.
La leçon d'ensemble
Le coeur du Challenge
Le label "PoC RAG" masque que le mécanisme réel est du text-to-SQL / function-calling : le LLM ne voit jamais les données, il écrit seulement une requête contre un schéma. Cette couche est non déterministe et échoue de trois façons, par gravité croissante.
Mode d'échec
Exemple
Pourquoi c'est grave
1. Réponse fausse silencieuse
Q4 : des agrumes présentés comme des baies
A l'air juste, est faux. Le pire : rien ne le signale.
2. Erreur d'exécution dure
Q6 : table suppliers_i18n hallucinée, la base refuse
Faux aussi, mais au moins c'est visible.
3. Instabilité
Le même prompt donne des résultats différents
On ne peut pas s'y fier d'une exécution à l'autre.
Méthode de vérification : pour une question factuelle, lire la base directement en GET et compter soi-même. Traiter la couche LLM comme une suggestion à vérifier, jamais comme une vérité.