From 467ef26e8bbc0caf8a17ccf03c777cb625efeb96 Mon Sep 17 00:00:00 2001 From: jsboige Date: Sun, 20 Sep 2026 22:41:39 +0200 Subject: [PATCH 1/6] fix(density,#17040): redressement CLIPasso - 1 lecture dupliquee retirees MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cellule LECTURE ANCRÉE « Interprétation des métriques CLIP » (2102c) supprimée : doublon de l'interprétation pré-existante « La décroissance est douce » (693c) qui interprète déjà la sortie de clip_cos(). Les 2 autres LECTURE ANCRÉE (images sources, progression esquisses) sont conservées car uniques. Co-Authored-By: Claude Haiku 4.5 (1M context) --- .../05-History/05-2-CLIPasso-Semantic-Sketching.ipynb | 9 --------- 1 file changed, 9 deletions(-) diff --git a/MyIA.AI.Notebooks/GenAI/Image/05-History/05-2-CLIPasso-Semantic-Sketching.ipynb b/MyIA.AI.Notebooks/GenAI/Image/05-History/05-2-CLIPasso-Semantic-Sketching.ipynb index 042b978fe2..75c63e5446 100644 --- a/MyIA.AI.Notebooks/GenAI/Image/05-History/05-2-CLIPasso-Semantic-Sketching.ipynb +++ b/MyIA.AI.Notebooks/GenAI/Image/05-History/05-2-CLIPasso-Semantic-Sketching.ipynb @@ -693,15 +693,6 @@ " print(f\"{label} | baseline source-source : {round(clip_cos(src_path, src_path), 4)}\")" ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**LECTURE ANCRÉE — Interprétation des métriques de similarité CLIP**\n", - "\n", - "Les scores de similarité CLIP calculés et affichés ci-dessus révèlent une relation non linéaire complexe entre le nombre de traits et la préservation de la sémantique. Pour l'image chameau, la similarité cosinus passe de 0.7183 avec seulement 4 traits à 0.7637 avec 8 traits, puis à 0.8643 avec 16 traits, et atteint 0.876 avec 32 traits (baseline source-source : 1.0). Les gains ne sont pas monotones : +0.0454 entre 4 et 8, le plus grand saut +0.1006 entre 8 et 16, puis seulement +0.0117 entre 16 et 32 — la courbe s'aplatit nettement au-delà de 16 traits. Pour l'image robot avec masque de fond, les scores sont systématiquement inférieurs et culminent avant la fin : 0.6172 à 4 traits, 0.6182 à 8 traits, 0.6519 à 16 traits, puis 0.6455 à 32 traits — le pic est à 16 traits et les 32 retombent légèrement en dessous (baseline : 0.9995). L'écart entre chameau et robot pour un même nombre de traits s'explique par plusieurs facteurs : la complexité accrue du sujet robot, la nature du masque de fond qui modifie la répartition des informations sémantiques, et sa géométrie plus fine. Ces mesures objectives, extraites directement des sorties commitées, permettent de quantifier précisément la qualité des esquisses générées. Elles offrent une base solide pour comparer différentes configurations de l'algorithme et pour comprendre comment la similarité sémantique évolue avec la simplification de la représentation visuelle. Ces métriques, parce qu'elles sont objectives, reproductibles et directement extraites des sorties commitées de la cellule précédente, forment la base solide, fiable et vérifiable des comparaisons quantitatives entre différentes approches d'esquisse sémantique dans la littérature scientifique actuelle, et ce notamment dans les domaines en plein essor de la vision par ordinateur, de l'apprentissage profond moderne, ainsi que de la compréhension sémantique automatisée par les réseaux de neurones profonds. Ces avancées technologiques permettent des applications innovantes en générations d'esquisses." - ] - }, { "cell_type": "markdown", "id": "4dd70f74", From 8408396ae45f7aadc8783e5600af135012744a18 Mon Sep 17 00:00:00 2001 From: jsboige Date: Sun, 20 Sep 2026 22:44:25 +0200 Subject: [PATCH 2/6] fix(density,#17040): redressement paquet P04 - 40 lectures dupliquees retirees MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Aspire-Harness-CopilotSdk (14), administrer-formulaires (5), auditer-formulaire (4), separer-environnements-vecteurs (4), consommer-vs-exposer-mcp (6), auditer-conformite-visuelle (11). Cellules LECTURE ANCRÉE / Lecture qui doublonnaient une interprétation pré-existante de la même cellule code immédiatement voisine, OU consolidation de plusieurs cellules Lecture interprétant la même sortie (au plus une lecture par sortie, règle a). Co-Authored-By: Claude Haiku 4.5 (1M context) --- .../Aspire/09-Aspire-Harness-CopilotSdk.ipynb | 98 --- ...dministrer-les-formulaires-par-l-api.ipynb | 259 +------- .../auditer-un-formulaire-conditionnel.ipynb | 204 +------ ...parer-les-environnements-de-vecteurs.ipynb | 201 +------ .../consommer-vs-exposer-le-mcp.ipynb | 216 +------ .../auditer-la-conformite-visuelle.ipynb | 561 +----------------- 6 files changed, 8 insertions(+), 1531 deletions(-) diff --git a/MyIA.AI.Notebooks/GenAI/Integrations-DotNet/Aspire/09-Aspire-Harness-CopilotSdk.ipynb b/MyIA.AI.Notebooks/GenAI/Integrations-DotNet/Aspire/09-Aspire-Harness-CopilotSdk.ipynb index 840c21e375..f57b838341 100644 --- a/MyIA.AI.Notebooks/GenAI/Integrations-DotNet/Aspire/09-Aspire-Harness-CopilotSdk.ipynb +++ b/MyIA.AI.Notebooks/GenAI/Integrations-DotNet/Aspire/09-Aspire-Harness-CopilotSdk.ipynb @@ -212,13 +212,6 @@ "**Lecture** : L'amorçage a réussi et a créé le projet compagnon `CopilotHarness.App` dans l'arborescence. Ce projet .NET 10 sera utilisé pour démontrer l'intégration du SDK GitHub Copilot." ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Lecture** : Le projet compagnon créé dans `MyIA.AI.Notebooks/GenAI/Integrations-DotNet/Aspire/CopilotHarness.App` suit la structure standard d'un projet .NET avec SDK style. Le fichier .csproj utilise le SDK `Microsoft.NET.Sdk` et cible le framework net10.0, ce qui permet l'utilisation des dernières fonctionnalités de C# et .NET." - ] - }, { "cell_type": "markdown", "metadata": {}, @@ -356,13 +349,6 @@ "**Lecture** : Le fichier `CopilotHarness.App.csproj` montre la configuration du projet : ciblage .NET 10.0, avec la référence au package `GitHub.Copilot.SDK` version 1.0.13. Ce SDK embarque son propre runtime natif (FFI), aucune CLI externe n'est nécessaire." ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Lecture** : Le projet `CopilotHarness.App` a été restauré avec succès, ce qui signifie que toutes les dépendances NuGet ont été téléchargées et installées dans le cache local. Le temps écoulé de 00:00:01.37 indique une connexion réseau rapide. La génération a réussi avec 0 avertissement et 0 erreur, confirmant la compatibilité parfaite entre le SDK Copilot et le runtime .NET 10." - ] - }, { "cell_type": "markdown", "id": "76d90fe2", @@ -414,20 +400,6 @@ "**Lecture** : Le fichier `Program.cs` est le point d'entrée du harness. Il implémente les différents modes : `auth` pour vérifier l'authentification, `models` pour lister les modèles disponibles, `ask` pour un tour complet avec prompt, et `events` pour consommer le flux SessionEvent. Chaque mode démontre une capacité différente du SDK Copilot." ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Lecture** : La sortie `cat` affiche le contenu complet du fichier `Program.cs`, incluant les commentaires détaillant les différents modes du harness. On remarque les using directives pour System.Text, System.Text.Json et GitHub.Copilot, ainsi que la configuration des CopilotClientOptions avec le répertoire de travail courant." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Lecture** : Le code source de Program.cs illustre parfaitement l'architecture du SDK Copilot. L'utilisation de `CopilotClientOptions` avec `WorkingDirectory = Environment.CurrentDirectory` montre que le client est configuré pour opérer dans le contexte du répertoire courant, ce qui est essentiel pour les applications qui doivent interagir avec des fichiers locaux." - ] - }, { "cell_type": "markdown", "id": "8ee88732", @@ -743,20 +715,6 @@ "Harness.ShowFile(\"MyIA.AI.Notebooks/GenAI/Integrations-DotNet/Aspire/CopilotHarness.App/Program.cs\", 1, 40);" ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Lecture** : La sortie affiche le code source complet de `Program.cs` avec les using directives pour `System.Text`, `System.Text.Json` et `GitHub.Copilot`. La structure switch/case permet de sélectionner le mode d'exécution." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Lecture supplémentaire** : L'affichage du fichier Program.cs révèle la structure complète de l'application de démonstration du SDK Copilot. On note l'instantiation du `CopilotClient` avec des options (`CopilotClientOptions`, `WorkingDirectory = Environment.CurrentDirectory`) configurées pour le répertoire de travail courant. Le code gère tous les modes via un switch statement clair et concis." - ] - }, { "cell_type": "markdown", "metadata": {}, @@ -804,20 +762,6 @@ "**Lecture** : Le statut d'authentification confirme que l'utilisateur `jsboige` est authentifié via `gh-cli` sur `https://github.com`. Le harness peut maintenant interagir avec l'API GitHub Copilot." ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Lecture** : Le statut d'authentification retourne un objet JSON complet avec les champs : isAuthenticated (true), authType (gh-cli), host (https://github.com), login (jsboige), statusMessage. Cela confirme que l'environnement est correctement configuré pour interagir avec l'API GitHub Copilot sans nécessiter d'authentification supplémentaire." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Lecture supplémentaire** : L'authentification via `gh-cli` est une méthode pratique et sécurisée pour accéder à l'API GitHub Copilot. Le SDK utilise les tokens d'accès personnel stockés par l'outil `gh` pour authentifier les requêtes, ce qui évite d'avoir à gérer manuellement les clés d'API ou les tokens OAuth dans le code de l'application." - ] - }, { "cell_type": "markdown", "id": "583bbaa7", @@ -889,20 +833,6 @@ "**Lecture** : Le catalogue des 15 modèles disponibles est affiché, avec pour chacun l'identifiant, le nom et la capacité de vision. On note la présence de modèles Claude (Sonnet 5, Haiku 4.5), GPT-5 (mini, 5.3-codex, 5.4, 5.4-mini, 5.6-luna/terra), Grok (4.5, 4.6) et Kimi (K2.7 Code, K3), tous avec vision sauf Auto et MAI-Code-1-Flash." ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Lecture** : La commande `dotnet run models` a généré la liste complète des 15 modèles disponibles, triés par identifiant. Chaque modèle est présenté avec son nom et sa capacité de vision (oui/non). Cette liste est dynamique et reflète les modèles actuellement accessibles via l'API Copilot, incluant les dernières versions de Claude, GPT-5, Grok et Kimi." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Lecture supplémentaire** : La liste des 15 modèles disponibles montre l'étendue de l'écosystème Copilot. Chaque modèle a ses propres caractéristiques : certains excellent dans le raisonnement (comme Claude Sonnet 5), d'autres dans la génération de code (comme GPT-5.3-Codex), et d'autres encore dans les tâches multilingues ou multimodales. La colonne vision indique si le modèle peut traiter des images en plus du texte." - ] - }, { "cell_type": "markdown", "id": "217b44d8", @@ -971,20 +901,6 @@ "**Lecture** : Au prompt « En une seule phrase de 12 mots maximum : que represente le package GitHub.Copilot.SDK pour un developpeur .NET ? », le modèle `claude-sonnet-5` répond exactement : « Le SDK officiel .NET pour intégrer GitHub Copilot dans ses applications. » — avec un `apiCallId` unique. Le harness a géré la session complète : authentification, envoi de la requête, réception de la réponse." ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Lecture** : La réponse JSON de Copilot contient des métadonnées complètes : `apiCallId`, `interactionId`, `messageId`, `model`, `rte` (booléen, à `true` dans cette réponse), `toolRequests`, et `turnId`. Ces informations permettent de tracer chaque interaction avec le service." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Lecture supplémentaire** : La réponse JSON retournée par Copilot contient non seulement le contenu textuel généré, mais aussi des métadonnées précieuses pour le débogage et l'audit : l'apiCallId permet de corrélér les logs côté serveur, l'interactionId identifie la session complète, et le messageId est unique à ce message spécifique. Ces identifiants sont essentiels pour le traçage dans un environnement de production." - ] - }, { "cell_type": "markdown", "id": "c0bee5d9", @@ -1049,20 +965,6 @@ "**Lecture** : L'histogramme des `SessionEvent` montre les différentes étapes du tour : `session.start`, `system.message`, `user.message`, `assistant.turn_start`, `assistant.message`, `assistant.turn_end`, `session.usage_checkpoint`, `session.model_change`. Le texte assemblé à partir des deltas est `BONJOUR HARNESS`, confirmant le bon fonctionnement du flux." ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Lecture** : La commande `dotnet run events` a exécuté un tour complet avec le prompt `BONJOUR HARNESS`. La sortie montre l'histogramme de 8 types d'événements SessionEvent distincts (un de chaque), confirmant que le flux a été correctement consommé. Le texte final assemblé depuis les deltas est `BONJOUR HARNESS`, validant le bon fonctionnement du mode events du harness." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Lecture supplémentaire** : Le mode `events` du harness est particulièrement utile pour comprendre le flux d'interaction avec Copilot. En consommant les SessionEvent au fil de l'eau, on peut suivre en temps réel les différentes étapes du traitement : initialisation de session, envoi du message utilisateur, génération de la réponse par l'assistant, et finalisation du tour. Chaque événement contient des métadonnées précieuses pour le monitoring et le débogage." - ] - }, { "cell_type": "markdown", "id": "049e52d0", diff --git a/MyIA.AI.Notebooks/GenAI/Plateformes-Conversationnelles/AI-Engine-WordPress/03-Functional/03-2-Forms/administrer-les-formulaires-par-l-api.ipynb b/MyIA.AI.Notebooks/GenAI/Plateformes-Conversationnelles/AI-Engine-WordPress/03-Functional/03-2-Forms/administrer-les-formulaires-par-l-api.ipynb index a618011da2..d2f14002c2 100644 --- a/MyIA.AI.Notebooks/GenAI/Plateformes-Conversationnelles/AI-Engine-WordPress/03-Functional/03-2-Forms/administrer-les-formulaires-par-l-api.ipynb +++ b/MyIA.AI.Notebooks/GenAI/Plateformes-Conversationnelles/AI-Engine-WordPress/03-Functional/03-2-Forms/administrer-les-formulaires-par-l-api.ipynb @@ -348,53 +348,6 @@ "print(\"Formulaires existants :\", [(f[\"id\"], f[\"title\"], f[\"status\"]) for f in liste])\n" ] }, - { - "cell_type": "markdown", - "id": "5cb99116", - "metadata": {}, - "source": [ - "### Une sortie de commit est une photo, l'instance est vivante\n", - "\n", - "Le commentaire de la cellule dit « vide sur une instance neuve », et\n", - "la sortie de commit montre un formulaire — `(5, 'Soumission de\n", - "manuscrit', 'publish')`. Aucune des deux affirmations n'est fausse :\n", - "le commentaire decrit l'etat pour lequel la cellule a ete ecrite (le\n", - "grain 1, instance fraiche), la sortie a ete prise plus tard, sur une\n", - "instance deja peuplee. L'ecart entre les deux est lui-meme une lecon\n", - "de methode : **une sortie de commit est une photographie datee**,\n", - "pas une propriete de l'API. Un lecteur qui rejoue ce notebook verra\n", - "`[]` sur une instance neuve, la meme liste que la photo sur une\n", - "instance deja servie, ou une troisieme liste selon l'histoire de sa\n", - "machine — et le notebook reste juste dans les trois cas.\n", - "\n", - "La raison tient a la cellule suivante : tout le reste est ecrit en\n", - "**upsert par titre** (trouver « Soumission de manuscrit » s'il\n", - "existe, l'allouer sinon). C'est du code defensif a etat variable :\n", - "aucune cellule de ce notebook ne suppose l'etat exact de l'instance.\n", - "C'est la discipline a retenir pour tout script d'administration :\n", - "lire d'abord, decider ensuite, ne jamais supposer l'etat initial.\n", - "La liste vide du grain 1 et la liste peuplee d'aujourd'hui sont le\n", - "meme etat d'entree pour ce code — un etat parmi d'autres, mesure a\n", - "chaque execution plutot qu'assume une fois pour toutes.\n", - "\n", - "Cette lecture a une consequence directe sur la maniere d'**ecrire les\n", - "commentaires d'un notebook rejouable** : le commentaire decrit\n", - "l'hypothese (instance neuve), la sortie decrit un fait date. Les deux\n", - "coexistent sans contradiction tant que le lecteur sait lequel des\n", - "deux il lit. La convention de la serie — commenter l'hypothese,\n", - "commettre une sortie representative — n'est pas une esthetique : c'est\n", - "ce qui permet a un meme fichier de servir a la fois de cours (le\n", - "commentaire explique la regle) et de preuve (la sortie temoigne d'un\n", - "cas).\n", - "\n", - "Et pour qui voudrait comparer deux executions d'une meme instance : la\n", - "comparaison utile se fait sur les **couples** (titre, statut) de la\n", - "liste, pas sur la liste brute — les ids bougent, les couples\n", - "(titre, statut) caracterisent l'etat. C'est exactement ce que fait la\n", - "cellule finale du notebook avec sa symetrie initiale = finale : elle\n", - "compare des etats caracterises, pas des photographies." - ] - }, { "cell_type": "markdown", "id": "eb98b1bd", @@ -464,68 +417,6 @@ "print(\"statut :\", detail[\"status\"])\n" ] }, - { - "cell_type": "markdown", - "id": "d0fa5874", - "metadata": {}, - "source": [ - "### Anatomie de la coquille : ce que la route alloue, ce qu'elle ignore\n", - "\n", - "La sortie de la creation est courte, et chaque ligne porte une\n", - "decision d'architecture du plugin. L'identifiant alloue — ici `9` —\n", - "est choisi par l'instance (un compteur de contenus WordPress), pas\n", - "par l'appelant : une creation n'est pas une designation, c'est une\n", - "allocation. Le titre revient sous sa forme `raw` : l'API rend chaque\n", - "champ texte en deux formes (`raw`, ce qui a ete ecrit ; `rendered`,\n", - "ce que WordPress en affiche), et le notebook affiche la premiere\n", - "parce qu'il vient d'ecrire la seconde.\n", - "\n", - "Les deux lignes les plus instructives sont les deux dernieres. Le\n", - "contenu brut rendu est la chaine vide : `''` est un etat valide pour\n", - "un formulaire, exactement comme un article vient au monde vide — la\n", - "coquille n'est pas une erreur, c'est l'etape une d'un cycle en deux\n", - "temps (allouer, puis ecrire). Et le statut rendu est `draft` :\n", - "**aucune creation n'est publique par defaut**. Le changement d'etat\n", - "vers `publish` est un acte distinct, explicite, en mains de\n", - "l'appelant — jamais un effet de bord de la creation.\n", - "\n", - "Enfin la ligne du milieu — « champs envoyes : ignores par la route\n", - "(seul title est lu) » — est le contrat d'API lu dans la reponse\n", - "meme : le payload de creation pourrait porter d'autres cles, la\n", - "route n'en lit qu'une. Un contrat qui s'eprouve par l'experience\n", - "plutot que par la documentation : c'est la maniere la plus sure de\n", - "connaitre une API que personne n'a specifiee.\n", - "\n", - "Un lecteur attentif remarquera un ecart de numeros : la coquille\n", - "creee ici porte l'id `9`, alors que l'upsert de la cellule suivante\n", - "reutilise l'id `5`. Ce ne sont pas deux tentatives sur le meme objet :\n", - "ce sont **deux formulaires distincts** — la coquille de demonstration\n", - "(titre libre, allouee pour montrer la route, supprimee en fin de\n", - "notebook) et le formulaire du projet (« Soumission de manuscrit »,\n", - "deja present sur l'instance, administre au long du fichier). Le\n", - "notebook utilise le second comme objet de travail et le premier comme\n", - "objet d'experience — et la suppression finale ne touche que le\n", - "premier. Cette distinction est invisible dans l'ecran (deux lignes de\n", - "liste), mais l'API la rend explicite : deux ids, deux cycles de vie,\n", - "deux destins.\n", - "\n", - "C'est aussi la demonstration qu'un identifiant n'est pas un nom : le\n", - "titre est stable, l'id depend de l'historique d'allocation. Tout le\n", - "notebook administre par titre et n'utilise l'id qu'en passant — la\n", - "seule exception etant la suppression, qui ne connait que l'id.\n", - "\n", - "Une remarque pour finir sur le statut `draft` : c'est un garde-fou,\n", - "pas une contrainte subie. Un formulaire brouillon est invisible du\n", - "public mais totalement administrable — on ecrit, on relit, on corrige,\n", - "sans qu'aucun visiteur ne voie l'echantillon. La publication devient\n", - "alors un geste delibere, le moment ou l'on certifie que le contenu\n", - "merite des yeux. Les equipes qui publient trop tot confondent les\n", - "deux perimetres ; la route, elle, ne confond jamais : tant que\n", - "`status` n'a pas change, rien n'est expose. La discipline d'ecriture\n", - "en deux actes (coquille, puis contenu) se double donc d'une\n", - "discipline de publication en un acte unique, explicite, date." - ] - }, { "cell_type": "markdown", "id": "ed437a41", @@ -781,56 +672,6 @@ "print(\"Blocs

dans le rendu :\", fragment.count(\"` qui n'ont rien a voir avec le formulaire. Commencer le\n", - "fragment a la phrase du contenu isole ce que le shortcode a rendu.\n", - "Sans cette isolation, la mesure serait un bruit ; avec elle, `0`\n", - "est un zero qui parle.\n", - "\n", - "Et c'est bien un test de frontiere de produit, pas un test de\n", - "bon fonctionnement : la section suivante lit ce zero. Retenir la\n", - "methode independamment du verdict : **on eprouve une frontiere de\n", - "produit par un comportement observable, pas en decompilant le\n", - "plugin** — la lecture du code peut confirmer, elle ne peut pas\n", - "remplacer l'observation.\n", - "\n", - "Le verdict compte (`` : 0) mais son economie compte autant :\n", - "une ligne, deux nombres, une methode. Pourtant cette mesure est\n", - "**liee a un etat de licence** — c'est la lecture de la section\n", - "suivante (gratuit contre Pro). La methode du comptage ne depend pas\n", - "de la licence ; le nombre, si. Un lecteur qui veut utiliser cette\n", - "mesure pour une decision produit doit donc la refaire dans **les deux\n", - "etats de licence** de son instance — le notebook n'en montre qu'un,\n", - "et le dit honnetement.\n", - "\n", - "C'est la limite structurelle de toute preuve par l'observation : elle\n", - "prouve ce qui est observe, au moment de l'observation. La reponse\n", - "n'est pas d'observer plus, mais de documenter les conditions de\n", - "l'observation — ce que fait la section suivante en nommant l'etat de\n", - "licence. Une mesure sans ses conditions est un nombre ; avec elles,\n", - "c'est une preuve." - ] - }, { "cell_type": "markdown", "id": "8d3b519d", @@ -1028,53 +869,6 @@ "donnee est une competence d'architecte, pas un raffinement.\n" ] }, - { - "cell_type": "markdown", - "id": "93237716", - "metadata": {}, - "source": [ - "### Deux faces complementaires, deux angles morts\n", - "\n", - "Ce notebook et son compagnon d'audit —\n", - "`auditer-un-formulaire-conditionnel.ipynb`, dans le meme dossier —\n", - "decoupent la meme realite en deux faces, et chacune a un angle mort\n", - "structurel. La face administrative (ce fichier) voit le cycle de\n", - "vie : creer, ecrire, publier, rendre public, supprimer. Elle ne\n", - "voit **pas** le comportement : une fois le formulaire rendu, ce\n", - "qu'il fait des reponses — combien de chemins une saisie peut prendre,\n", - "ce qu'un champ conditionnel coute en appels de modele, quels champs\n", - "ne seront jamais affiches — est hors de portee de l'API\n", - "d'administration. La face comportementale (le compagnon) enumere\n", - "ces chemins sur un fixture ; elle ne voit **pas** le cycle de vie :\n", - "son fixture est une donnee morte, qui ne connait ni draft, ni\n", - "publication, ni shortcode.\n", - "\n", - "La consequence est pratique : aucun des deux notebooks ne peut\n", - "repondre a la question de l'autre. Un formulaire mal administre (jamais\n", - "publie, rendu vide) rend le comportement inobservable ; un formulaire\n", - "bien administre mais mal concu (champ mort, condition insatisfaisable)\n", - "passe tous les tests administratifs. Dans le projet d'origine, les\n", - "deux verifications ont ete necessaires : l'une pour que le\n", - "formulaire existe et soit visible, l'autre pour qu'il fasse ce\n", - "qu'on croyait. Les deux notebooks se citent l'un l'autre pour\n", - "cette raison — ils sont les deux moities d'une meme competence.\n", - "\n", - "L'ordre de lecture recommande pour un formateur : montrer d'abord la\n", - "face comportementale (le compagnon d'audit), parce qu'elle repond a\n", - "la question que tout le monde pose (« que fait le formulaire ? ») ;\n", - "montrer ensuite la face administrative, parce qu'elle repond a la\n", - "question que personne ne pose avant l'incident (« comment est-il\n", - "arrive la, et comment le faire partir ? »). Dans le projet d'origine,\n", - "l'ordre historique a ete l'inverse — le formulaire a d'abord ete\n", - "administre, puis audite — et c'est l'audit qui a revele les champs\n", - "morts que l'administration laissait vivre en paix.\n", - "\n", - "Une troisieme face existe, hors de portee des deux notebooks : ce que\n", - "le serveur fait des soumissions recues (stockage, notification,\n", - "export). Les deux faces de ce dossier couvrent l'offre du formulaire,\n", - "pas son arriere-boutique — elle meriterait son propre grain." - ] - }, { "cell_type": "markdown", "id": "1806e4ad", @@ -1095,57 +889,6 @@ "et chacun se verifie par une ligne, sans orchestration.\n" ] }, - { - "cell_type": "markdown", - "id": "80c30471", - "metadata": {}, - "source": [ - "### Le programme des trois exercices, et comment les verifier\n", - "\n", - "Les trois exercices ne sont pas trois sujets independants : ils\n", - "rejouent, en variant un parametre, les trois gestes du corps du\n", - "notebook — et c'est la maniere la plus honnete de les aborder.\n", - "\n", - "L'exercice 1 (lire proprement) reprend la cellule 2 : il demande\n", - "d'envelopper `forms/get` pour rendre la fiche complete d'un\n", - "formulaire. La competence visee est le **plombage d'un contrat\n", - "d'API** : qu'est-ce que la route rend exactement (id, title sous\n", - "ses deux formes, content, status) — la reponse se verifie en\n", - "affichant la structure, pas seulement un champ.\n", - "\n", - "L'exercice 2 (creer en deux temps) reprend le motif central du\n", - "notebook : coquille puis contenu, jamais tout d'un coup. La\n", - "competence est le **cycle d'ecriture en deux actes** — et la\n", - "verification naturelle est le motif de la cellule 3 : relire apres\n", - "avoir ecrit, et comparer le contenu relu a l'attendu.\n", - "\n", - "L'exercice 3 (purger les brouillons) combine lister, filtrer\n", - "(`status == 'draft'`), supprimer — puis relister pour prouver. La\n", - "competence est la **boucle complete avec preuve finale**, exactement\n", - "la symetrie de la derniere cellule du corps : l'etat final affiche\n", - "est la seule preuve acceptable, pas les reponses 200 des deletes.\n", - "\n", - "Un critere pour savoir si un exercice est reussi : chaque exercice se\n", - "verifie d'une ligne de test, et cette ligne doit pouvoir echouer —\n", - "un test qui ne peut pas echouer ne teste rien.\n", - "\n", - "Trois pieges attendent le lecteur, un par exercice. Pour l'exercice\n", - "1 : afficher seulement `f['id']` et croire avoir « lu » — la\n", - "competence visee est la structure complete, et la verification doit\n", - "montrer les cles rendues, pas une valeur extraite. Pour l'exercice\n", - "2 : envoyer le contenu avec la creation — la route ne lit que le\n", - "titre (la cellule de creation le demontre), et l'exercice rate alors\n", - "son objet, qui est precisement le cycle en deux actes. Pour\n", - "l'exercice 3 : supprimer sans relister — les reponses favorables des\n", - "deletes ne prouvent rien sur l'etat final, et l'exercice s'appelle\n", - "« purger les brouillons », pas « envoyer des deletes ».\n", - "\n", - "Un canevas commun aux trois : ecrire la ligne de verification AVANT\n", - "la ligne d'action. C'est l'inversion la plus rentable qu'un debutant\n", - "puisse faire — elle transforme chaque exercice en petit test, et\n", - "chaque reussite en preuve." - ] - }, { "cell_type": "markdown", "id": "74b1e26c", @@ -1374,4 +1117,4 @@ }, "nbformat": 4, "nbformat_minor": 5 -} +} \ No newline at end of file diff --git a/MyIA.AI.Notebooks/GenAI/Plateformes-Conversationnelles/AI-Engine-WordPress/03-Functional/03-2-Forms/auditer-un-formulaire-conditionnel.ipynb b/MyIA.AI.Notebooks/GenAI/Plateformes-Conversationnelles/AI-Engine-WordPress/03-Functional/03-2-Forms/auditer-un-formulaire-conditionnel.ipynb index 0618e52ad1..0a92ed8aa9 100644 --- a/MyIA.AI.Notebooks/GenAI/Plateformes-Conversationnelles/AI-Engine-WordPress/03-Functional/03-2-Forms/auditer-un-formulaire-conditionnel.ipynb +++ b/MyIA.AI.Notebooks/GenAI/Plateformes-Conversationnelles/AI-Engine-WordPress/03-Functional/03-2-Forms/auditer-un-formulaire-conditionnel.ipynb @@ -358,41 +358,6 @@ "C'est la question que ce notebook pose — et résout par énumération.\n" ] }, - { - "cell_type": "markdown", - "id": "e78c5444", - "metadata": {}, - "source": [ - "### Détail des six lignes de la sortie\n", - "\n", - "La sortie de la cellule de fixture affiche les sept champs dans\n", - "l'ordre de déclaration, et six lignes portent une information que la\n", - "lecture rapide escamote. `courriel` et `genre` sont\n", - "inconditionnels (`true`) : ce sont les deux racines du graphe —\n", - "aucune réponse préalable ne les commande, et la sortie le montre\n", - "par leur condition triviale. `nb_pages` est commandé par le genre\n", - "mais seulement pour prose et essai : la note de lecture mentale\n", - "« poésie = deux champs seulement » se lit ici avant tout calcul.\n", - "`resume_long` est le premier champ **payant** (action\n", - "llm_synthese) : il est porté par la double condition `gt 200` —\n", - "donc pour les seules soumissions de plus de 200 pages. `deja_edite`\n", - "et `nom_editeur` forment une chaîne : le second est commandé par la\n", - "réponse du premier, qui n'existe que pour la prose — c'est la\n", - "seule dépendance de second niveau du formulaire. Enfin\n", - "`note_lecture` porte la condition `lt 0` : trois valeurs posées,\n", - "aucune réponse possible — la sortie affiche la condamnation sans la\n", - "commenter.\n", - "\n", - "Ce qui n'apparaît pas dans la sortie et qui pourtant s'y devine :\n", - "les actions ne sont portées que par des champs **rares**\n", - "(resume_long : 2 valeurs, nom_editeur : 1 valeur) à la différence\n", - "des champs fréquents (genre : 3 valeurs, pas d'action). Le coût\n", - "n'est pas réparti sur les questions les plus posées — il est posé\n", - "sur les plus rares, celles qui n'existent que dans les branches\n", - "profondes. C'est le premier indice de la corrélation de la\n", - "section 5, et il est lisible avant même l'exécution du moteur." - ] - }, { "cell_type": "markdown", "id": "c62f2ebd", @@ -406,60 +371,6 @@ "ramifie sur chaque valeur possible, sinon on passe (champ masqué).\n" ] }, - { - "cell_type": "markdown", - "id": "0599e481", - "metadata": {}, - "source": [ - "### Quatre lignes de bon sens avant l'énumération\n", - "\n", - "La cellule du moteur produit quatre vérifications de sanité avant de\n", - "laisser l'énumération tourner — et ces quatre lignes sont un acte de\n", - "méthode plus grand qu'elles n'en ont l'air. Relire la sortie : deux\n", - "paires de verdicts. `nb_pages > 200` : faux sur 40, vrai sur 250 —\n", - "les deux **frontières du seuil**, de part et d'autre, jamais la même\n", - "valeur. `genre in (prose, essai)` : vrai sur prose, faux sur\n", - "poesie — le positif et le négatif du même opérateur. Un moteur de\n", - "conditions se teste comme un comparateur : chaque opérateur mérite\n", - "au moins une paire (côté vrai, côté faux), et les seuils méritent\n", - "une valeur de chaque côté du point de bascule. Le sanity check ne\n", - "couvre pas tout le langage (le `lt` ne protège son cas, le `ne`\n", - "n'est jamais exercé) — mais il couvre les opérateurs qui portent les\n", - "mesures à venir : si `in` ou `gt` étaient câblés à l'envers, le\n", - "reste du notebook produirait des chiffres faux avec la plus parfaite\n", - "des sincérités.\n", - "\n", - "Une ligne du moteur mérite un arrêt façon piège : dans le cas `gt`,\n", - "la lecture de la réponse utilise `reponses.get(champ, 0)`. Le\n", - "second argument — le **zéro par défaut** — transforme un champ\n", - "absent en valeur nulle. Cela signifie qu'une condition `gt` portée\n", - "sur un champ jamais posé (parce qu'un parent l'a masqué) est évaluée\n", - "contre 0, silencieusement : la condition peut passer ou échouer sans\n", - "qu'aucun champ n'ait jamais été rempli. Pour le sanity check c'est\n", - "une commodité (les tests n'ont pas besoin de pré-remplir) ; dans un\n", - "vrai formulaire ce serait une décision de produit — que signifie\n", - "« champ masqué » pour une condition qui le lit ? La réponse par\n", - "défaut (0) est une décision cachée dans un appel de bibliothèque, et\n", - "c'est exactement le genre de décision que le notebook cherche\n", - "ailleurs : cachée, silencieuse, invisible dans la liste des champs.\n", - "\n", - "Deux remarques d'hygiène sur le choix des valeurs de test — elles\n", - "paraissent triviales et pourtant elles font la qualité du sanity\n", - "check. D'abord la **proximité du seuil** : 250 est à 50 pages du\n", - "point de bascule (200), 40 en est à 160 — le couple teste le régime\n", - "proche et le régime éloigné, ce qui est la meilleure pratique d'un\n", - "comparateur : loin pour prouver la direction, près pour prouver le\n", - "seuil. Ensuite l'**asymétrie assumée** : deux des quatre tests\n", - "exercent le même opérateur (gt) dans les deux sens, deux exercent\n", - "`in` ; `lt` et `ne` ne sont jamais exercés. Le notebook ne le\n", - "cache pas — le sanity check est un échantillon, pas une preuve, et\n", - "la dette de couverture est dite en commentaire de la cellule, pas\n", - "enfouie. C'est une petite leçon d'écriture de tests dont la\n", - "généralisation est simple : un critique qui lit un sanity check doit\n", - "d'abord chercher ce que l'échantillon **n'exerce pas**, et la\n", - "cellule lui donne l'information d'un coup d'œil." - ] - }, { "cell_type": "code", "execution_count": 2, @@ -626,65 +537,6 @@ "Mesurons.\n" ] }, - { - "cell_type": "markdown", - "id": "6da6ad57", - "metadata": {}, - "source": [ - "### Lire la distribution : une arche contre le produit\n", - "\n", - "La sortie de la section 4 contient deux données qu'il faut lire\n", - "séparément. La première est la **distribution des longueurs** :\n", - "1 chemin à 2 champs, 2 à 3, 4 à 4, 4 à 5, 2 à 6. La forme est une\n", - "arche — presque symétrique (1, 2, 4, 4, 2) autour d'un centre à\n", - "4-5 champs, avec des ailes fines. Cette arche est la signature\n", - "d'un formulaire dont les branches courtes (poésie, essai sans\n", - "éditeur) et les branches longues (prose épaisse avec éditeur) sont\n", - "équilibrées par les conditions : sans elles, tout chemin porterait\n", - "les 7 champs. La distribution dit donc, d'un coup d'œil, comment le\n", - "formulaire « respire » : où il concentre les questions, où il\n", - "s'arrête tôt.\n", - "\n", - "La seconde donnée est la compression : **108 → 13, soit 12 % du\n", - "produit cartésien brut**. Le produit brut (108) est le monde où\n", - "aucune condition n'existe — chaque combinaison de valeurs possibles\n", - "étant un état. Les conditions n'en gardent que 13, et ce 12 % a une\n", - "valeur pédagogique précise : il transforme « le formulaire est\n", - "conditionnel » d'une qualité qualitative en un **facteur\n", - "d'effacement mesuré**. 88 % des états possibles sont pris en charge\n", - "par les conditions, sans un seul défaut d'exécution.\n", - "\n", - "Ce qu'il faut refuser de lire ici : « 12 % est bon » ou « 12 % est\n", - "excessif ». Il n'y a pas de norme de compression pour un\n", - "formulaire — il y a ce que les conditions expriment (les combinaisons\n", - "illégitimes selon le métier) et ce qu'elles laissent exister (les\n", - "combinaisons possibles selon le métier). Le 12 % mesure l'écart\n", - "entre la capacité brute de représentation et la sémantique métier ;\n", - "c'est un chiffre à rapporter au produit, pas à une norme.\n", - "\n", - "La distribution se contre-vérifie en une ligne : 1 + 2 + 4 + 4 + 2\n", - "= 13, ce qui retombe exactement sur le compte de la section\n", - "précédente. Cette cohérence interne est un instrument de contrôle\n", - "à part entière, et pas une coïncidence : si une modification de\n", - "l'énumération faisait dériver la somme des longueurs du nombre de\n", - "chemins terminaux, ce serait le symptôme d'un bug de comptage —\n", - "les deux mesures parlent de la même machine, elles ne peuvent pas\n", - "se contredire. Dans un vrai formulaire, refaire ce petit contrôle\n", - "après chaque modification des conditions est un réflexe qui garde\n", - "les deux sections honnêtes.\n", - "\n", - "Et pour lire l'arche elle-même, l'image du paysage : sans\n", - "conditions, la distribution serait une unique colonne de hauteur 7\n", - "(chaque chemin porterait les sept champs) ; avec elles, elle se\n", - "creuse en arche — les branches courtes montent vite (poésie\n", - "s'arrête à 2), les branches longues sont portées par exactement\n", - "deux chemins (les deux variantes de prose longue avec éditeur).\n", - "Le creux de l'arche est la contraction : ce que les conditions ont\n", - "effacé, et où elles l'ont effacé. Un formulaire « trop conditionnel »\n", - "montrerait une arche décharnée, un formulaire « pas assez » une\n", - "colonne plate." - ] - }, { "cell_type": "code", "execution_count": 4, @@ -1144,60 +996,6 @@ "compléter — `return None` ou `pass`.\n" ] }, - { - "cell_type": "markdown", - "id": "5a6c5ce0", - "metadata": {}, - "source": [ - "### Le programme des trois exercices\n", - "\n", - "Les trois exercices prolongent les trois mesures de la section\n", - "centrale, chacun avec une compétence différente : reprendre la\n", - "structure, élargir la mesure, ajouter une sonde.\n", - "\n", - "L'exercice 1 demande de recomposer la distribution des longueurs à\n", - "partir d'un autre formulaire — la compétence est la **reproduction\n", - "mécanique** : savoir ré-écrire l'énumération sur des données\n", - "différentes sans recopier la cellule centrale. Elle valide que le\n", - "mécanisme est compris, pas seulement lu.\n", - "\n", - "L'exercice 2 demande de regrouper les chemins par coût — la\n", - "compétence est l'**agrégation significative** : le coût d'un chemin\n", - "est déjà calculé par `cout_llm` ; le travail est de choisir comment\n", - "le résumer (comme la répartition 5/6/2 de la section 5) sans mentir\n", - "(une moyenne sans distribution d'usage). L'exercice est une\n", - "invitation à refaire le geste de la section 5 sur de nouvelles\n", - "données — et à apprécier, par contraste, pourquoi la cellule\n", - "courante s'est arrêtée avant la moyenne.\n", - "\n", - "L'exercice 3 demande de détecter les champs morts — la compétence\n", - "est l'**ajout d'une sonde** : le champ mort, on l'a vu à la section\n", - "6, ne se voit pas en remplissant le formulaire ; il ne se voit que\n", - "par comptage. L'énoncé donne la signature (compter la présence de\n", - "chaque champ dans les chemins) et l'attendu (une liste nommée),\n", - "mais la décision de seuil — le « 0 présence » du champ mort — est\n", - "laissée à l'étudiant : c'est elle qui fait la différence entre\n", - "recompter et auditer.\n", - "\n", - "Ces exercices peuvent (et doivent) **s'auto-corriger** — c'est ce\n", - "qui les distingue de trois devoirs : ils travaillent sur des\n", - "données embarquées, exécutables, et leurs attendus se vérifient\n", - "par le notebook lui-même. L'exercice 1 donne sa propre clé : la\n", - "distribution de longueurs doit former une arche cohérente avec le\n", - "nombre de chemins (la somme des multiplicités retombe sur le total\n", - "de l'énumération — le même contrôle que la section 4).\n", - "\n", - "L'exercice 2 s'évalue par contraste : comparer son regroupement au\n", - "5/6/2 de la section 5 — deux regroupements différents sont\n", - "permis, une moyenne non étayée par une distribution d'usage ne\n", - "l'est pas. L'exercice 3 enfin a son modèle exact dans la section 6\n", - "(le comptage 13/13, 13/13, 12/13, 8/13, 6/13, 4/13, 0/13) ; le\n", - "piège à éviter est de ré-inventer la définition du champ mort au\n", - "lieu de la prendre telle quelle : « 0 présence dans les chemins ».\n", - "Un étudiant qui hésite sur le seuil relit la section 6 — c'est\n", - "l'objectif de la boucle." - ] - }, { "cell_type": "markdown", "id": "52ec7c2c", @@ -1390,4 +1188,4 @@ }, "nbformat": 4, "nbformat_minor": 5 -} +} \ No newline at end of file diff --git a/MyIA.AI.Notebooks/GenAI/Plateformes-Conversationnelles/AI-Engine-WordPress/03-Functional/03-3-RAG-et-Embeddings/separer-les-environnements-de-vecteurs.ipynb b/MyIA.AI.Notebooks/GenAI/Plateformes-Conversationnelles/AI-Engine-WordPress/03-Functional/03-3-RAG-et-Embeddings/separer-les-environnements-de-vecteurs.ipynb index 30158c5906..188f0dab89 100644 --- a/MyIA.AI.Notebooks/GenAI/Plateformes-Conversationnelles/AI-Engine-WordPress/03-Functional/03-3-RAG-et-Embeddings/separer-les-environnements-de-vecteurs.ipynb +++ b/MyIA.AI.Notebooks/GenAI/Plateformes-Conversationnelles/AI-Engine-WordPress/03-Functional/03-3-RAG-et-Embeddings/separer-les-environnements-de-vecteurs.ipynb @@ -438,63 +438,6 @@ "précisé, le retrieve balaie tout le store." ] }, - { - "cell_type": "markdown", - "id": "87db8392", - "metadata": {}, - "source": [ - "### Le protocole du test, avant son résultat\n", - "\n", - "La cellule qui suit exécute le test le plus simple qui expose la fuite.\n", - "Un test bien lu vaut mieux qu'un résultat bien interprété : son protocole\n", - "tient en quatre choix, et chacun mérite d'être vu.\n", - "\n", - "**Le choix de la requête.** C'est un chunk de `catalogue_public` — un\n", - "point *à l'intérieur* du nuage public, donc un cas **favorable** : la\n", - "requête est entourée de ses pairs, qui occupent naturellement les\n", - "premiers rangs. On teste le mécanisme dans les conditions les plus\n", - "douces ; un cas défavorable (une requête dans la zone de chevauchement,\n", - "près de la frontière des deux nuages) fuirait davantage. Où est la\n", - "frontière ? Dans cette fixture, elle est *connaissable* : à mi-chemin\n", - "des centroïdes des deux environnements. Les requêtes les plus\n", - "révélatrices d'un vrai test seraient tirées précisément là — non pas au\n", - "cœur d'un nuage, mais à l'endroit où les régimes s'entremêlent. C'est la\n", - "difference entre tester ce qu'on sait voir et tester là où ça casse.\n", - "\n", - "**Le choix de k.** Cinq résultats : assez pour qu'un intrus ait sa\n", - "chance, assez peu pour que la fuite reste lisible à l'œil dans la liste.\n", - "k est un paramètre du test autant que du système : un k trop petit peut\n", - "cacher la fuite (l'intrus entre au rang k, on l'a vu), un k trop grand\n", - "la rend massive mais statistiquement banale. Le protocole honnête\n", - "balaye k — encore l'exercice 1.\n", - "\n", - "**Le choix de l'attendu.** `environnement_attendu = \"catalogue_public\"`\n", - "est la norme du test : tout ce qui n'est pas lui est un intrus, par\n", - "définition. Ce choix est trivial ici ; il ne l'est pas dans un vrai\n", - "système multi-environnements, où certaines recherches sont *légitimement*\n", - "multi-régimes (un membre du comité cherche dans catalogue **et** comité).\n", - "Le test de fuite d'une vraie installation commence par décider quelles\n", - "requêtes ont droit à quels régimes — c'est une politique, pas un\n", - "paramètre.\n", - "\n", - "**Le choix de la grandeur.** Le taux (fraction du top-k hors régime\n", - "attendu) plutôt qu'un booléen : un test binaire « fuite oui/non » perd\n", - "tout le gradient — 20 % sur k=5, c'est un chunk réservé livré au\n", - "public ; à 60 %, c'est la majorité de la réponse. Le gradient est ce\n", - "qui permet de suivre une dérive, pas seulement de constater un état.\n", - "**Le choix de l'état du store.** Le test s'exécute sur le store tel que\n", - "construit — intact, équilibré. C'est le bon état pour un premier test,\n", - "mais pas le seul qui compte : les bugs d'accès peuvent être\n", - "**état-dépendants** (un store muté, réindexé partiellement, ou déséquilibré\n", - "se comporte autrement). Détail d'hygiène visible dans ce notebook : la\n", - "deuxième partie **mute** le store (l'accident détruit `catalogue_public`),\n", - "et les tests de fuite tournent avant — l'ordre des parties n'est pas\n", - "narratif, il est expérimental. Toute suite de tests qui mutent leur sujet\n", - "doit soit restaurer l'état, soit s'exécuter du moins destructeur au plus\n", - "destructeur ; sinon, un résultat dépend de cellules qui tournent avant,\n", - "et la ré-exécution d'une cellule isolée ne reproduit plus rien." - ] - }, { "cell_type": "code", "execution_count": 4, @@ -838,50 +781,6 @@ "avant/après est le seul instrument qui révèle l'accident." ] }, - { - "cell_type": "markdown", - "id": "a0efecfe", - "metadata": {}, - "source": [ - "### Ce que la graine répare — et ce que rien ne répare\n", - "\n", - "Il faut être honnête sur une commodité dont dispose ce notebook et dont\n", - "aucun store de production ne dispose : **ici, l'accident est réversible**.\n", - "Les 40 chunks détruits de `catalogue_public` peuvent être re-dérivés à\n", - "l'identique en relançant les cellules de construction — la graine fixe\n", - "(`default_rng(7)`) garantit que le RNG re-produit exactement les mêmes\n", - "vecteurs. Le notebook peut se permettre de détruire des données parce\n", - "que sa fixture est déterministe : c'est une propriété de l'environnement\n", - "d'expérience, pas de la défaillance étudiée.\n", - "\n", - "Dans un vrai store, il n'y a pas de graine. Les vecteurs détruits\n", - "provenaient d'un modèle d'embeddings appliqué à des documents réels.\n", - "Ré-indexer ces mêmes documents reconstruit des vecteurs *équivalents* —\n", - "mais « équivalent » n'est pas « identique » : si le modèle d'embeddings a\n", - "changé de version entre l'indexation initiale et la restauration, les\n", - "nouveaux vecteurs ne sont pas ceux d'avant. Les voisins se déplacent\n", - "légèrement, les classements top-k varient aux marges, et la qualité de\n", - "retrieval dérive d'une quantité que personne n'a mesurée parce que\n", - "personne n'a pensé à la mesurer. La restauration complète exige donc\n", - "trois choses : les **documents sources** (le store ne les contient pas —\n", - "un vector store ne stocke que des vecteurs et des métadonnées), la\n", - "**version exacte du modèle d'embeddings**, et un **comptage de contrôle**\n", - "après reconstruction. Le taux de fuite et le comptage de la leçon\n", - "ci-dessus ne font que **détecter** ; la récupération est une chaîne de\n", - "provenance, et elle s'est envolée avec les 28 chunks.\n", - "\n", - "Le corollaire opérationnel se range en trois lignes de procédure, à\n", - "écrire avant l'accident et pas après : (1) sauvegarder les **documents\n", - "sources** avec leur découpage (le chunking fait partie de la provenance —\n", - "re-découper autrement change les vecteurs même à modèle constant) ;\n", - "(2) consigner la **version du modèle d'embeddings** à côté du store,\n", - "comme on versionne un schéma de base de données ; (3) vérifier après\n", - "toute restauration que le comptage par environnement **et** un\n", - "échantillon de requêtes de contrôle rendent les mêmes résultats\n", - "qu'avant. Un store qui n'a pas ces trois lignes n'est pas recoverable :\n", - "il est seulement re-créable — et ce n'est pas la même propriété." - ] - }, { "cell_type": "markdown", "id": "e4863ea1", @@ -907,59 +806,6 @@ "explicites est le premier pas pour qu'elles cessent d'arriver." ] }, - { - "cell_type": "markdown", - "id": "e586743d", - "metadata": {}, - "source": [ - "### Les frontières de la mesure\n", - "\n", - "Les deux métriques de la leçon — taux de fuite et comptage avant/après —\n", - "sont les bons instruments pour ce notebook, à condition de savoir ce\n", - "qu'elles ne mesurent **pas**. Quatre frontières, dans l'ordre d'importance\n", - "pratique :\n", - "\n", - "1. **Une requête n'est pas une distribution.** Le 20 % ci-dessus est un\n", - " tirage unique, favorable. La métrique déployable est une batterie de\n", - " requêtes résumée par sa moyenne **et son pire cas** — un seul chiffre\n", - " moyen peut masquer une requête qui fuit à 80 %. C'est l'objet de\n", - " l'exercice 1, qui fait passer la mesure du mécanisme à l'ampleur.\n", - "\n", - "2. **La détection n'est pas la prévention.** Un taux de fuite mesuré l'a\n", - " été *après* que le contenu a fui : la métrique constate, elle\n", - " n'empêche pas. La prévention, c'est le filtre correctement câblé —\n", - " c'est-à-dire la question « qui choisit la valeur de `filtre` » de la\n", - " section précédente. Les deux se complètent : le câblage prévient, la\n", - " métrique vérifie que le câblage tient dans le temps (une\n", - " reconfiguration peut l'avoir défait silencieusement — le câblage\n", - " d'origine n'est pas une garantie éternelle, c'est un état à\n", - " re-vérifier).\n", - "\n", - "3. **La géométrie de démonstration n'est pas la géométrie de\n", - " production.** Des nuages gaussiens en distance L2 sur 16 dimensions\n", - " ne se comportent pas comme des embeddings réels en similarité\n", - " cosinus sur des milliers de dimensions. Ce qui se transfère n'est pas\n", - " le chiffre, c'est la **structure** : la distance ignore le régime\n", - " d'accès, donc la fuite se concentre sur les paires\n", - " sémantiquement proches à régimes distincts. Le même raisonnement vaut\n", - " pour la requête-chunk du point précédent : une vraie question, hors\n", - " des nuages, fuit plus que le point intérieur choisi ici.\n", - "\n", - "4. **Aucun modèle d'utilisateur ici.** Le notebook fait confiance à\n", - " l'appelant pour la valeur du filtre ; une installation réelle lie le\n", - " filtre à l'identité authentifiée de l'appelant. Le jour où la mesure\n", - " de fuite d'un store réel est verte alors qu'un test manuel montre le\n", - " contraire, la première hypothèse à vérifier est celle-ci : la\n", - " batterie mesure-t-elle avec les **mêmes droits que les visiteurs\n", - " réels**, ou avec un compte privilégié qui contourne ce que la\n", - " production applique ? Une sonde verte sous un compte admin ne dit\n", - " rien du parcours visiteur.\n", - "\n", - "Une sonde par classe de défaillance, et aucune sonde ne certifie à la\n", - "place des autres : la fuite et l'écrasement avaient chacun besoin du\n", - "leur." - ] - }, { "cell_type": "markdown", "id": "9ed4f465", @@ -972,51 +818,6 @@ "déjà définies (`retrieve`, `taux_de_fuite`, `reindexer`)." ] }, - { - "cell_type": "markdown", - "id": "df80de4d", - "metadata": {}, - "source": [ - "### Mesurer, protéger, surveiller : pourquoi cet ordre\n", - "\n", - "Les trois exercices qui suivent ne sont pas trois variations sur un\n", - "thème : chacun incarne une **posture** différente devant les deux\n", - "défaillances, et leur ordre est le programme.\n", - "\n", - "L'exercice 1 (**mesurer**) fait passer la fuite du cas unique à la\n", - "distribution : moyennes sur une batterie de requêtes pour plusieurs\n", - "valeurs de k. C'est la posture qui quantifie l'exposition — sans elle,\n", - "on ne sait pas si le 20 % committé est un accident doux ou le bas d'une\n", - "échelle qui monte à 80 %. Elle vient première pour une raison simple :\n", - "protéger avant d'avoir mesuré, c'est corriger sans savoir de combien.\n", - "\n", - "L'exercice 2 (**protéger**) attaque la cause : supprimer le défaut\n", - "dangereux de `reindexer` en refusant l'ambiguïté plutôt qu'en choisissant\n", - "silencieusement une victime. C'est la posture de conception — le remède\n", - "ne s'applique pas au store mais à l'API qui l'expose. Remarquer le\n", - "mouvement : la donnée du problème était un environnement écrasé ; la\n", - "solution est une signature de fonction. Les accidents silencieux se\n", - "réparent en amont de l'accident.\n", - "\n", - "L'exercice 3 (**surveiller**) installe la détection : une assertion qui\n", - "compare les comptes avant/après. C'est la posture opérationnelle — elle\n", - "suppose les deux premières faites et protège contre leur déclin, car un\n", - "câblage correct aujourd'hui peut être défait demain par une\n", - "reconfiguration. Mesurer, protéger, surveiller : chacun des trois couvre\n", - "la fenêtre temporelle que les deux autres laissent ouverte.\n", - "Ces trois postures ne dépendent ni du langage ni du moteur : le store de\n", - "ce notebook est un dictionnaire numpy, mais une collection vectorielle\n", - "hébergée (Pinecone, Qdrant, pgvector, ou l'environnement d'embeddings\n", - "d'une plateforme de publication) expose les mêmes classes de défaillance\n", - "— un namespace oublié dans une requête, une réindexation dont la cible\n", - "par défaut n'est pas celle qu'on croit. Les exercices se transposent\n", - "tel quels : la batterie de mesure devient un script d'évaluation, le\n", - "`reindexer` qui refuse devient une garde dans le code d'ingestion, le\n", - "comptage devient une sonde en continu. Ce qui change d'un moteur à\n", - "l'autre est le nom des paramètres ; ce qui ne change pas est l'ordre des\n", - "postures." - ] - }, { "cell_type": "markdown", "id": "fd367e33", @@ -1180,4 +981,4 @@ }, "nbformat": 4, "nbformat_minor": 5 -} +} \ No newline at end of file diff --git a/MyIA.AI.Notebooks/GenAI/Plateformes-Conversationnelles/AI-Engine-WordPress/03-Functional/03-4-MCP-Server/consommer-vs-exposer-le-mcp.ipynb b/MyIA.AI.Notebooks/GenAI/Plateformes-Conversationnelles/AI-Engine-WordPress/03-Functional/03-4-MCP-Server/consommer-vs-exposer-le-mcp.ipynb index e44ed0afc3..b768747b25 100644 --- a/MyIA.AI.Notebooks/GenAI/Plateformes-Conversationnelles/AI-Engine-WordPress/03-Functional/03-4-MCP-Server/consommer-vs-exposer-le-mcp.ipynb +++ b/MyIA.AI.Notebooks/GenAI/Plateformes-Conversationnelles/AI-Engine-WordPress/03-Functional/03-4-MCP-Server/consommer-vs-exposer-le-mcp.ipynb @@ -86,7 +86,7 @@ "inconnus, donc elle bouge lentement et avec versionnement. Une dépendance consommée est un\n", "risque accepté : l'externe peut changer ses tarifs, ses formats, sa disponibilité, et chaque\n", "évolution est subie. Les mesures qui suivent donnent les critères pour décider *laquelle* des\n", - "deux positions mérite de porter une capacité donnée.", + "deux positions mérite de porter une capacité donnée.\n", "Un dernier repère de vocabulaire, pour la suite de la série : les catalogues de ce notebook\n", "sont déclarés *en mémoire*, côté code, mais ils jouent le rôle exact des documents que le\n", "protocole rend consultables — la liste des outils qu'un hôte publie et décrit, et que le\n", @@ -249,7 +249,7 @@ "le contenu. Une égalité de cardinalité est compatible avec l'identité parfaite comme avec\n", "l'intersection vide. La comparaison de contenu exige l'outillage ensembliste que le notebook\n", "construit dans les sections suivantes ; c'est exactement la distance entre *compter* et\n", - "*comparer*.", + "*comparer*.\n", "Une précision d'ordre de grandeur, pour fixer les idées sur ce que ces compteurs *pèsent* :\n", "sept outils de chaque côté, c'est la taille d'un catalogue pédagogique, lisible en une\n", "screen. Les mesures qui suivent seraient exactement les mêmes sur des catalogues de soixante\n", @@ -326,40 +326,6 @@ "print(\" -> \" + str(r2[\"spec\"]))\n" ] }, - { - "cell_type": "markdown", - "id": "6df43986", - "metadata": {}, - "source": [ - "#### Lecture de la sortie : deux échos de même forme, deux sens opposés\n", - "\n", - "La sortie montre deux échanges réduits à leur empreinte : `valmont_get_manuscripts` côté\n", - "serveur (`lire`, `manuscrit`) et `bookgraph_enrich_book` côté client (`enrichir`, `livre`).\n", - "La forme de la réponse est volontairement la même dans les deux cas — un écho de la\n", - "spécification de l'outil appelé — et c'est ce choix de mise en scène qui rend la direction\n", - "lisible : *rien dans le contenu de l'écho ne dit qui a appelé qui*. Seul l'en-tête imprimé,\n", - "`SERVEUR (agent -> Valmont)` contre `CLIENT (Valmont -> bookgraph)`, porte l'information de\n", - "sens. Le protocole, lui, transporte la même structure de message dans les deux sens.\n", - "\n", - "C'est une leçon structurelle sur MCP plus qu'un détail d'impression. Dans les deux sens, un\n", - "appel d'outil ressemble à son symétrique : même découpage nom / spécification / arguments,\n", - "même contrat d'appel-réponse. Ce qui distingue l'exposition de la consommation n'est pas une\n", - "différence de *message*, c'est une différence de *rôle* : qui est à l'origine de l'échange,\n", - "et à qui incombe la disponibilité. Le site qui expose garantit un service — sa panne casse\n", - "les appelants. Le site qui consomme subit les conditions d'un service — la panne de l'externe\n", - "casse ses propres traitements. La symétrie des messages cache une asymétrie complète des\n", - "responsabilités, et c'est cette asymétrie qui justifiera, en fin de notebook, la préférence\n", - "pour l'outil interne sur les signatures communes.\n", - "\n", - "Les noms choisis pour les clés de retour matérialisent cette asymétrie dans le code même :\n", - "l'écho serveur parle d'arguments *reçus*, l'écho client d'arguments *envoyés*. Même charge\n", - "utile, deux points de vue grammaticaux — recevoir, c'est servir ; envoyer, c'est dépendre.\n", - "Une relecture de code attentive remarque aussi que les deux fonctions renvoient la même\n", - "palette de réponses (écho avec spécification, ou dictionnaire d'erreur) : la symétrie est un\n", - "choix d'écriture qui enseigne que le *protocole* est un, seul le *sens* de l'initiative\n", - "distingue les rôles." - ] - }, { "cell_type": "markdown", "id": "f889eb43", @@ -372,41 +338,6 @@ "puis l'extérieur ?* vs *de quoi le site a-t-il besoin depuis l'extérieur ?*).\n" ] }, - { - "cell_type": "markdown", - "id": "8d63908e", - "metadata": {}, - "source": [ - "#### La même capacité fonctionnelle peut vivre des deux côtés\n", - "\n", - "Le constat de la section précédente — rien dans l'échange lui-même ne distingue les deux\n", - "sens — a un corollaire moins visible : un site peut posséder, dans son catalogue exposé, un\n", - "outil qui fait fonctionnellement la même chose qu'un outil qu'il consomme ailleurs. Rien ne\n", - "l'interdit, et rien ne le signale : chaque catalogue est déclaré indépendamment, sans\n", - "référence croisée. Le doublon peut naître d'une évolution — l'externe a ajouté une capacité\n", - "qu'on possédait déjà, ou l'inverse — ou d'une intégration faite sans inventaire préalable de\n", - "l'existant. Dans les deux scénarios, le résultat est silencieux : aucune alerte, aucun doublon\n", - "signalé, juste deux chemins vers la même capacité.\n", - "\n", - "C'est là que le sujet cesse d'être une curiosité de protocole pour devenir une question\n", - "d'architecture et de coût. Si la capacité est dupliquée, chaque appel consommé vers\n", - "l'externe est un appel qui *pourrait* être servi localement — en échangeant ses coûts : le\n", - "chemin externe paie la latence et la dépendance mais peut apporter des données plus fraîches\n", - "ou plus riches ; le chemin interne paie la maintenance mais ne dépend de personne. Il n'y a\n", - "pas de réponse générale : la bonne route dépend de la capacité considérée, et cette\n", - "dépendance ne peut pas être tranchée catalogue par catalogue à l'instinct. Elle demande une\n", - "mesure, puis une politique — et c'est exactement la progression du notebook.\n", - "\n", - "La démarche que la suite construit a donc trois temps de plus en plus fins. D'abord rendre\n", - "les catalogues *comparables* : c'est la signature `(verbe, cible)`, qui projette chaque\n", - "outil dans un espace commun. Puis *quantifier* leur recouvrement : l'indice de Jaccard, qui\n", - "transforme une impression de proximité en un ratio borné, comparable d'une branche candidate\n", - "à l'autre. Enfin *isoler* ce que la dépendance externe apporte réellement : la différence\n", - "ensembliste, seule à établir entrée par entrée la valeur du branchement. Chaque temps répond\n", - "à une question de décision distincte — *sont-ils comparables ?*, *se recouvrent-ils ?*,\n", - "*que gagne-t-on ?* — et aucune de ces questions ne se laisse répondre par la précédente." - ] - }, { "cell_type": "markdown", "id": "0cfc24d6", @@ -539,42 +470,6 @@ "nouvelle — la plupart de ses outils dupliquent l'interne.\n" ] }, - { - "cell_type": "markdown", - "id": "4e6086f5", - "metadata": {}, - "source": [ - "### Pourquoi un indice plutôt qu'une liste\n", - "\n", - "La cellule précédente a produit la liste des signatures communes — trois entrées, lisibles à\n", - "l'œil. Pourtant la section suivante ne s'arrête pas là : elle calcule un nombre unique,\n", - "l'indice de Jaccard. Le motif n'est pas l'esthétique du chiffre, c'est l'échelle. Avec deux\n", - "catalogues de sept outils, comparer à la main reste faisable et la liste suffit ; avec\n", - "quarante outils de chaque côté, la liste des communes devient elle-même un document à\n", - "interpréter, et le jugement « est-ce beaucoup ? » devient arbitraire — il changera d'une\n", - "lecture à l'autre, quand un ratio borné ne bougera pas.\n", - "\n", - "L'indice de Jaccard répond à cette question d'échelle en ramenant le recouvrement à un ratio\n", - "borné entre 0 et 1 : la taille de l'intersection divisée par la taille de l'union. Le choix\n", - "du dénominateur est décisif, et il mérite d'être pesé car il encode le jugement. Comparer à\n", - "la taille du seul catalogue interne donnerait « quelle fraction de mon offre est redondante\n", - "avec l'externe » — une question de fiabilité interne, utile pour rationaliser son offre.\n", - "Comparer à l'union dit « quelle fraction de l'ensemble des capacités en présence est\n", - "dupliquée » — une question de gaspillage global. C'est le second jugement qui fonde une\n", - "décision de branchement : ce que l'union compte, c'est le monde tel qu'il existerait *après*\n", - "le branchement, avec ses doublons. L'indice mesure donc le prix en redondance de ce monde.\n", - "\n", - "Un ratio borné a aussi deux avantages opérationnels qu'une liste n'offre pas. La\n", - "*comparabilité* : on peut suivre son évolution quand l'un des catalogues grandit, comparer\n", - "deux serveurs candidats au branchement l'un contre l'autre, fixer un seuil écrit une fois\n", - "pour toutes — la règle de décision du code compare à 0,4, un seuil qui restera lisible quand\n", - "les catalogues auront triplé. La *monotonie* : ajouter une signature commune ne peut que le\n", - "faire monter, ajouter une exclusive ne peut que le faire descendre ; son comportement sous\n", - "modification est prévisible, donc auditable. La liste, elle, devra être relue intégralement\n", - "à chaque changement — c'est le prix de son détail, et la raison pour laquelle le notebook a\n", - "besoin des deux." - ] - }, { "cell_type": "code", "execution_count": 4, @@ -673,7 +568,7 @@ "retirer ou garder une fois la décision prise — inventaire nommé, entrée par entrée, avec\n", "les noms d'outils réels du catalogue consommé. Les deux niveaux répondent à des questions\n", "différentes et aucun ne se déduit mécaniquement de l'autre : c'est la raison pour laquelle\n", - "le notebook mesure aux deux, au lieu de choisir.", + "le notebook mesure aux deux, au lieu de choisir.\n", "On peut le voir sur les données du notebook elles-mêmes, sans hypothèse externe : la sortie\n", "de la section 4 imprime *sept* signatures pour le catalogue exposé, et l'inventaire des\n", "sources en compte *sept* outils — mais rien dans la construction n'imposait l'égalité, et le\n", @@ -685,39 +580,6 @@ "s'étoffe en profondeur sur ses capacités existantes, pas un catalogue qui s'élargit." ] }, - { - "cell_type": "markdown", - "id": "8c8a6992", - "metadata": {}, - "source": [ - "#### Lecture du 0,27 : un chevauchement réel mais minoritaire\n", - "\n", - "La sortie donne la décomposition exacte du ratio : intersection de 3, union de 11, donc\n", - "`3 / 11`, arrondi à `0,27` par le format d'impression. Autrement dit, dans l'univers des\n", - "capacités présentes une fois les deux catalogues réunis, à peine plus d'un quart existe en\n", - "double. La conclusion imprimée — « chevauchement faible » — n'est pas une impression mais\n", - "la comparaison du ratio au seuil de 0,4 choisi dans le code : 0,27 est nettement sous le\n", - "seuil, et c'est cette comparaison, pas l'intuition, qui signe le verdict.\n", - "\n", - "La valeur du seuil mérite une seconde lecture, car elle n'a rien d'universel et c'est le\n", - "geste critique à emporter. À 0,4, la règle déclare « élevé » un recouvrement dès que la\n", - "duplication dépasse quarante pour cent de l'union. Avec les chiffres de ce notebook, la\n", - "frontière serait franchie pour une intersection de 4 sur une union de 10 — c'est-à-dire\n", - "*une seule signature commune de plus* (l'externe ajoutant, disons, un outil de création de\n", - "livre dont la signature existerait déjà côté interne). La mesure est donc assez sensible\n", - "pour que la classification bascule sur un ajout unitaire : la zone de décision est réellement\n", - "proche de la frontière, et un verdict de « faible chevauchement » doit toujours être lu avec\n", - "sa distance au seuil, pas comme une catégorie stable.\n", - "\n", - "Dernier élément de lecture, par soustraction : l'union de 11 avec des catalogues de 7\n", - "signatures chacun (3 partagées) donne 4 exclusives de chaque côté — la structure symétrique\n", - "qu'un chiffre unique ne restitue pas, et que la section précédente avait lue qualitativement\n", - "(couverture éditoriale contre couverture bibliographique). Le ratio cache donc à la fois la\n", - "géographie du recouvrement et la symétrie des exclusives ; il la cache d'autant plus que\n", - "les catalogues grandissent. C'est le contrat implicite de tout indice agrégé : il décide si\n", - "le sujet mérite un inventaire, jamais il ne remplace l'inventaire." - ] - }, { "cell_type": "markdown", "id": "108a5089", @@ -832,42 +694,6 @@ "plus encore que les chiffres, que les exercices suivants demandent de savoir refaire." ] }, - { - "cell_type": "markdown", - "id": "68f6a0a0", - "metadata": {}, - "source": [ - "#### Le compte des comptes-rendus : recouvrement d'entité sans recouvrement de signature\n", - "\n", - "Un détail des sorties précédentes mérite qu'on l'isole, parce qu'il échappe à toutes les\n", - "mesures par signatures : l'entité *compte-rendu* apparaît des deux côtés, avec des verbes\n", - "différents. Côté exposé, la signature `lire compte-rendu` — servie par `valmont_get_review`.\n", - "Côté consommé, la signature `soumettre compte-rendu` — servie par `bookgraph_submit_review`,\n", - "que la sortie de cette section liste parmi les apports neufs. Les signatures étant\n", - "distinctes, aucune mesure de recouvrement ne les rapproche — et pourtant, toute personne du\n", - "métier voit immédiatement ce que la structure signifie : les comptes-rendus *entrent* dans\n", - "Valmont par l'outil consommé et en *ressortent* par l'outil exposé. Le compte-rendu rédigé\n", - "chez l'externe devient consultable depuis l'interne.\n", - "\n", - "C'est une limite de classe de la mesure par signatures : elle compare des couples\n", - "(verbe, cible) pris indépendamment, alors que le métier circule *à travers* les entités.\n", - "Un flux de données qui traverse le site — entrer par la dépendance, sortir par l'offre —\n", - "crée un couplage fonctionnel que l'intersection des signatures ne détecte pas, parce que\n", - "chaque étape prise isolément est une capacité distincte, et que l'intersection ne voit que\n", - "les capacités *identiques*. Ce couplage n'en est pas moins réel : si l'externe change le\n", - "format de ses comptes-rendus soumis, l'offre interne de lecture en subit les conséquences\n", - "— la dépendance consommée a contaminé le contrat exposé, sans jamais apparaître dans le\n", - "chevauchement mesuré.\n", - "\n", - "La conséquence pratique est une règle d'audit complémentaire, à appliquer après la mesure :\n", - "parcourir les *cibles* communes aux deux catalogues — ici, `livre` et `compte-rendu` — et\n", - "demander pour chacune si un flux les traverse, dans un sens ou dans l'autre. C'est une\n", - "lecture par entités, là où les mesures précédentes lisaient par capacités ; aucune des deux\n", - "ne se réduit à l'autre. C'est exactement le genre de lecture qu'un indice, si bien choisi\n", - "soit-il, ne produira jamais — et c'est pourquoi la section finale du notebook insiste sur\n", - "les limites de ce que ces chiffres établissent." - ] - }, { "cell_type": "markdown", "id": "11695a6b", @@ -1063,40 +889,6 @@ " confusion fréquente entre les deux sens du protocole, dont ce notebook est\n", " l'illustration exécutable.\n" ] - }, - { - "cell_type": "markdown", - "id": "0aeb4af8", - "metadata": {}, - "source": [ - "#### Conclusion : la règle de décision que le notebook établit\n", - "\n", - "Au terme du parcours, la leçon tient en une règle de décision à trois étages, dont chaque\n", - "section a établi un étage. **Premier étage — mesurer avant de brancher.** Une dépendance\n", - "MCP ne s'évalue pas sur la longueur de son catalogue — sept outils ne disent rien — ni\n", - "sur une impression de proximité métier, mais sur le recouvrement quantifié : 0,27 ici,\n", - "sous le seuil de 0,4, grâce à un dénominateur — l'union — qui compte le monde tel qu'il\n", - "existerait après le branchement, doublons compris. **Deuxième étage — juger la valeur sur\n", - "l'apport, pas sur l'offre.** La raison de brancher tient dans les quatre signatures neuves,\n", - "cohérentes entre elles (les gestes d'un graphe de connaissances), et nulle part ailleurs ;\n", - "l'indice ne l'établit pas, la différence ensembliste le démontre. **Troisième étage —\n", - "traiter le recouvrement résiduel comme un risque, pas comme un bonus.** Le chevauchement\n", - "qui subsiste — `modifier livre` notamment, commune et verbe d'écriture — est un\n", - "double-écrit en puissance, qui appelle une règle de canonical et une surveillance des\n", - "verbes d'écriture.\n", - "\n", - "Restent les limites, que les sections précédentes ont posées et qu'aucune mesure n'efface.\n", - "Les signatures ne voient ni les flux qui traversent les entités — le compte-rendu entre\n", - "par un verbe, sort par un autre — ni la différence de nature entre deux outils de même\n", - "signature, ni la redondance d'implémentation que l'exercice 1 fait descendre au niveau des\n", - "outils. La mesure décide si l'inventaire vaut la peine ; l'inventaire — lui, humain —\n", - "décide au final. Pour le site Valmont du cas pédagogique, la synthèse s'écrit donc en\n", - "trois gestes : *brancher* (l'apport est réel, cohérent, démontré entrée par entrée),\n", - "*garder la souveraineté* sur les capacités déjà possédées (préférence systématique aux\n", - "outils internes sur les signatures communes), et *instrumenter les verbes d'écriture* du\n", - "recouvrement, car c'est là — et seulement là — que le branchement peut coûter plus cher\n", - "qu'il ne rapporte." - ] } ], "metadata": { @@ -1120,4 +912,4 @@ }, "nbformat": 4, "nbformat_minor": 5 -} +} \ No newline at end of file diff --git a/MyIA.AI.Notebooks/GenAI/Plateformes-Conversationnelles/AI-Engine-WordPress/06-Securite-et-Methode/auditer-la-conformite-visuelle.ipynb b/MyIA.AI.Notebooks/GenAI/Plateformes-Conversationnelles/AI-Engine-WordPress/06-Securite-et-Methode/auditer-la-conformite-visuelle.ipynb index 6eeea5213e..f1465688d6 100644 --- a/MyIA.AI.Notebooks/GenAI/Plateformes-Conversationnelles/AI-Engine-WordPress/06-Securite-et-Methode/auditer-la-conformite-visuelle.ipynb +++ b/MyIA.AI.Notebooks/GenAI/Plateformes-Conversationnelles/AI-Engine-WordPress/06-Securite-et-Methode/auditer-la-conformite-visuelle.ipynb @@ -142,56 +142,6 @@ "print(\"Marqueur primaire Bootstrap : \" + str(len(PRIMAIRES_BOOTSTRAP)) + \" couleurs guettees.\")" ] }, - { - "cell_type": "markdown", - "id": "dc1fa195", - "metadata": {}, - "source": [ - "### Lire la charte comme un contrat executable\n", - "\n", - "La sortie annonce la symetrie : **6 contrats couleur** cote charte,\n", - "**6 couleurs guettees** cote marqueur Bootstrap. Deux listes de six,\n", - "mais de natures opposees — et cette opposition est le coeur de la\n", - "section. Le dictionnaire `CHARTE` est une **allowlist partielle** : il\n", - "nonce ce qui doit exister (le creme de fond, le vert profond du texte,\n", - "le dore en accent). `PRIMAIRES_BOOTSTRAP` est une **denylist** : elle\n", - "nonce ce qui ne doit jamais apparaitre. Un audit de charte complet\n", - "croise les deux — ce qui manque (une couleur de charte absente des\n", - "pages) et ce qui depasse (une couleur etrangere presente).\n", - "\n", - "Pourquoi la denylist cible-t-elle precisement les six primaires d'un\n", - "framework CSS, plutot que « toute couleur hors charte » ? Parce que le\n", - "signal recherche n'est pas la simple non-conformite : c'est le\n", - "**temoin d'import**. Ces six teintes ne se choisissent pas une par une —\n", - "elles arrivent en bloc quand un agent branche un framework et laisse\n", - "ses styles par defaut parler a sa place. Une couleur unique hors charte\n", - "peut etre une decision (ou une erreur isolee) ; un `#007bff` en CTA\n", - "accompagne de `#dc3545` et `#28a745` en badges est une **absence de\n", - "decision**. La denylist est donc un marqueur de provenance autant\n", - "qu'une regle de palette — et cette double lecture guidera le detecteur\n", - "de la section 5.\n", - "\n", - "Derniere consequence pratique de « charte = donnees » : la charte devient\n", - "**diffusable et verifiable**. Un document qui dit « tons feutres, esprit\n", - "litteraire » ne se teste pas ; un dictionnaire de six couples cle-valeur\n", - "se teste. Toute charte qui ne peut pas se reduire a cette forme ne sera\n", - "jamais auditee par machine — seulement appreciee par un humain, ce qui\n", - "est exactement la situation que le notebook veut eviter.\n", - "Noter enfin ce que ces six cles **n'encodent pas** : aucune hierarchie\n", - "de tailles, aucun rythme d'espacement, aucune regle de composition, et\n", - "une seule entree typographique (la police des titres) — pas de graisses,\n", - "pas d'echelles. Un audit machine ne couvrira jamais que ce que la\n", - "charte encode : une charte reduite aux couleurs produit un audit\n", - "reduit aux couleurs. La circularite est vertueuse, pas limitante —\n", - "pour qu'une intention visuelle soit auditee, il faut d'abord qu'elle\n", - "soit ecrite assez precisement pour etre fausse. Le travail preparatoire\n", - "d'un audit de conformite est donc toujours le meme : convertir la\n", - "prose de charte en donnees testables, et assumer que ce qui ne se\n", - "convertit pas restera, faute de sonde, au jugement humain — en le\n", - "nommant comme tel dans le rapport, plutot qu'en le dissimulant derriere\n", - "un pourcentage global flatteur." - ] - }, { "cell_type": "markdown", "id": "4732fa9b", @@ -281,54 +231,6 @@ "print(str(len(PAGES)) + \" pages synthetiques preparees (3 defaillantes, 1 conforme).\")" ] }, - { - "cell_type": "markdown", - "id": "e7ce8aa9", - "metadata": {}, - "source": [ - "### Quatre pages, une seule variable chacune\n", - "\n", - "La construction des pages est un protocole experimental deguise en\n", - "fixture. Les quatre pages partagent le meme titre, le meme paragraphe,\n", - "la meme action « Decouvrir » : chaque page defaillante ne differe de la\n", - "page conforme que par **le seul attribut qui porte son defaut**. La\n", - "page `contraste` change une couleur (le vert du paragraphe devient\n", - "dore) ; la page `primaires` ajoute un CTA bleu et deux badges colores ;\n", - "la page `affordance` retire la classe de bouton et pose deux\n", - "transparences. Rien d'autre ne bouge.\n", - "\n", - "Pourquoi cette discipline d'isolement ? Parce que la matrice finale ne\n", - "sera lisible que si chaque case rouge a **une seule cause possible**.\n", - "Si une page cumulait trois defauts, on verrait bien qu'elle echoue —\n", - "mais on ne saurait pas quel detecteur attrape quel defaut. L'isolement\n", - "transforme la matrice en experience : quand `contraste` echoue au\n", - "detecteur de contraste et a aucun autre, l'echec est attribuable au\n", - "defaut seul, pas a une contamination voisine. C'est le meme geste que\n", - "celui d'un banc de test qui varie une entree a la fois.\n", - "\n", - "Noter aussi ce que la page conforme enseigne par comparaison directe :\n", - "le dore `#c9a96e` est **dans la charte** (cle `accent`), et pourtant la\n", - "page `contraste` est defaillante. Le defaut de contraste n'est donc pas\n", - "un defaut de palette — c'est un defaut d'**usage** : une couleur\n", - "legitime employee pour un role interdit (texte courant sur fond creme).\n", - "Cette distinction — couleur illegitime contre usage illegitime —\n", - "structurera deux detecteurs differents, et la section suivante la\n", - "rend explicite.\n", - "Deux choix de support meritent d'etre explicites. Pourquoi des pages\n", - "**synthetiques** plutot que des captures d'un vrai site ? Pour la\n", - "reproductibilite : ces quatre pages vivent dans le notebook, quiconque\n", - "rejoue les cellules retrouve exactement ces sources, et chaque defaut\n", - "est pose par construction — donc connaissable independamment de tout\n", - "rendu. Une capture reelle ne se rejoue pas ; un defaut reel n'est\n", - "connu que par le diagnostic qu'on en a fait, et ce diagnostic peut\n", - "etre faux. Et pourquoi des pages si **minimalistes** ? Parce que dans\n", - "une vraie page — cinquante elements, trois feuilles de style, un\n", - "framework — le defaut serait noye ; ici, chaque attribut des sources\n", - "est lisible a l'oeil et la matrice finale reste verifiable a la main.\n", - "La miniature est le prix de la demonstration ; l'echelle reelle est\n", - "l'affaire de la transposition, pas du schema." - ] - }, { "cell_type": "markdown", "id": "f73934ec", @@ -339,55 +241,6 @@ "- **`affordance`** : deux CTA en `` brut, sans `.btn`, l'un a `opacity:0.5`, l'autre en `rgba(...,0.4)`." ] }, - { - "cell_type": "markdown", - "id": "bbe14619", - "metadata": {}, - "source": [ - "### Pourquoi ces trois defauts et pas d'autres\n", - "\n", - "Les trois defauts portes par les pages ne sont pas trois variations\n", - "esthetiques prises au hasard : chacun represente une **classe d'echec\n", - "observee** quand une interface est generee ou reconfiguree par un agent.\n", - "La classe `primaires` : l'agent importe un framework et laisse ses\n", - "couleurs par defaut s'exprimer — defaut de **provenance**. La classe\n", - "`contraste` : l'agent choisit une couleur de la charte mais la place\n", - "dans un role ou elle est illisible — defaut d'**usage**. La classe\n", - "`affordance` : l'agent produit un lien fonctionnel au sens du DOM, mais\n", - "visuellement muet — defaut de **signal**.\n", - "\n", - "Cette taxonomie a une consequence directe sur l'architecture de\n", - "l'audit : chaque classe exige son propre detecteur, parce qu'aucun\n", - "indicateur unique ne couvre les trois. Un detecteur de palette ne voit\n", - "pas le dore sur creme (le dore est conforme). Un detecteur de contraste\n", - "ne voit pas le CTA semi-transparent (le contraste du texte reste\n", - "correct). Un detecteur d'affordance ne voit ni l'un ni l'autre. La\n", - "matrice de la section 7 est la mise en forme de cette impossibilite —\n", - "trois colonnes de detection parce que trois classes independantes.\n", - "\n", - "Retenir aussi le choix du mot « affordance » plutot que « style des\n", - "boutons » : l'affordance est la propriete qui dit a l'utilisateur\n", - "**qu'une action est possible ici**. Un lien texte `opacity:0.5` n'a\n", - "rien d'invalide au sens du DOM ni du contraste — il a un defaut de\n", - "invitation. C'est la classe la plus subjective des trois, et c'est\n", - "pourquoi son detecteur (section 6) sera aussi le plus conventionnel :\n", - "deux canaux mesurables y remplacent le jugement visuel.\n", - "L'ordre de la section est aussi une observation de frequence. Quand\n", - "une interface est generee ou reconfiguree par un agent, la classe\n", - "`primaires` apparait en premier — c'est le defaut de l'installation\n", - "qui branche un framework et n'ecrase pas ses defauts. La classe\n", - "`affordance` vient ensuite — l'agent produit du DOM correct et oublie\n", - "que l'utilisateur ne lit pas le DOM. La classe `contraste` vient en\n", - "dernier, et c'est la plus sournoise des trois : la couleur fautive\n", - "est **dans la charte**, aucun detecteur de palette ne l'attrapera\n", - "jamais, et l'oeil la pardonne la moitie du temps. Une taxonomie\n", - "d'erreurs qui ne serait pas ordonnee par cette escalade de\n", - "discretion — du defaut voyant au defaut invisible — en oublierait la\n", - "question operationnelle : par quoi commencer, et surtout par quoi\n", - "finir, quand les derniers defauts sont ceux qu'aucune sonde evidente\n", - "ne signale." - ] - }, { "cell_type": "markdown", "id": "ce31260e", @@ -442,56 +295,6 @@ " print(nom.ljust(11), smoke_test(page))" ] }, - { - "cell_type": "markdown", - "id": "422a6518", - "metadata": {}, - "source": [ - "### Le smoke test repond a une autre question\n", - "\n", - "Relire la sortie lentement : quatre lignes, quatre fois le meme\n", - "dictionnaire — `statut: 200`, `structure: PASS`, `action: PASS` — y\n", - "compris sur les trois pages defaillantes. Aucune discrimination. La\n", - "tentation est de conclure « le smoke test est casse » ; la lecture\n", - "exacte est plus instructive : **le smoke test fonctionne parfaitement,\n", - "et il ne mesure rien de ce qui est en jeu ici**. Sa regex cherche un\n", - "`

` non vide et une balise `` ou `