<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Graphes De Connaissances on Boris Dupoux</title><link>https://borisdupoux.com/fr/categories/graphes-de-connaissances/</link><description>Recent content in Graphes De Connaissances on Boris Dupoux</description><generator>Hugo -- gohugo.io</generator><language>fr</language><lastBuildDate>Thu, 01 Oct 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://borisdupoux.com/fr/categories/graphes-de-connaissances/index.xml" rel="self" type="application/rss+xml"/><item><title>Un agent IA entièrement local, avec graphe de sens et mesure multimodale des émotions</title><link>https://borisdupoux.com/fr/research/local-ai-agent/</link><pubDate>Thu, 01 Oct 2026 00:00:00 +0000</pubDate><guid>https://borisdupoux.com/fr/research/local-ai-agent/</guid><description>&lt;h2 id="contexte"&gt;&lt;a href="#contexte" class="header-anchor"&gt;&lt;/a&gt;Contexte
&lt;/h2&gt;&lt;p&gt;Les traces numériques personnelles (messageries, courriels, photos, écoutes musicales,
notes, agenda, exports de santé, dépôts de code) comptent parmi les données les plus
sensibles qu&amp;rsquo;une personne possède, mais aussi parmi les plus riches pour étudier le
comportement — et le ressenti — dans la durée. Les confier à un LLM dans le cloud n&amp;rsquo;est
pas acceptable : tout fonctionne donc sur un unique ordinateur de bureau Apple silicon
(M4, 32 Go de mémoire unifiée), et aucune donnée ne quitte la machine.&lt;/p&gt;
&lt;p&gt;L&amp;rsquo;objectif est un agent qui réponde à des questions sur sa propre vie tout en maintenant
une séparation stricte entre ce qui est &lt;em&gt;observé&lt;/em&gt;, ce qui est &lt;em&gt;calculé&lt;/em&gt;, ce qui est
&lt;em&gt;supposé par un modèle&lt;/em&gt; et ce qui est &lt;em&gt;accepté comme vrai par son propriétaire&lt;/em&gt;.&lt;/p&gt;
&lt;h2 id="ce-qui-est-original"&gt;&lt;a href="#ce-qui-est-original" class="header-anchor"&gt;&lt;/a&gt;Ce qui est original
&lt;/h2&gt;&lt;p&gt;Les agents locaux sur des fichiers personnels ne sont pas nouveaux. Deux aspects de ce
projet le sont.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. Un graphe de sens au-dessus d&amp;rsquo;une couche de mesure.&lt;/strong&gt; La connaissance est organisée
à deux niveaux. Un &lt;em&gt;observatoire&lt;/em&gt; stocke faits et signaux au format long (élément,
dimension, valeur, confiance, modèle, version). Au-dessus, un &lt;strong&gt;graphe de sens&lt;/strong&gt; stocke ce
que ces signaux &lt;em&gt;signifient&lt;/em&gt; : des &lt;strong&gt;relations&lt;/strong&gt; (réifiées, pour qu&amp;rsquo;une relation puisse
évoluer et se mesurer), des &lt;strong&gt;épisodes affectifs&lt;/strong&gt; (qui a ressenti quoi, quand, avec quelle
intensité, par quelle modalité), des &lt;strong&gt;thèmes&lt;/strong&gt;, des &lt;strong&gt;chapitres&lt;/strong&gt; de vie et des
&lt;strong&gt;vérités&lt;/strong&gt; — des énoncés assortis de preuves qui les étayent et de preuves qui les
contredisent, que seul le propriétaire peut valider. Chaque nœud et chaque arête porte sa
provenance jusqu&amp;rsquo;à l&amp;rsquo;élément source, ainsi qu&amp;rsquo;une origine classée par degré de confiance
(humain &amp;gt; déclaré &amp;gt; structurel &amp;gt; règle/calcul &amp;gt; éditeur &amp;gt; modèle &amp;gt; inféré).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. Des émotions mesurées à travers les modalités, selon des dimensions atypiques.&lt;/strong&gt; Le
même vocabulaire fixe de &lt;strong&gt;53 émotions&lt;/strong&gt; (fondé sur Plutchik, chacune dotée de coordonnées
de valence et d&amp;rsquo;éveil) s&amp;rsquo;applique aux &lt;strong&gt;messages&lt;/strong&gt; (LLM local), à la &lt;strong&gt;voix&lt;/strong&gt; (cinq couches
acoustiques et multimodales fusionnées avec la transcription, avec un signalement explicite
du &lt;em&gt;désaccord&lt;/em&gt; entre texte et voix) et aux &lt;strong&gt;photos&lt;/strong&gt; (mesures déterministes de couleur et
de lumière, plongements SigLIP, signaux de visage traités comme des indices faibles). Ces
mesures s&amp;rsquo;inscrivent dans un catalogue de &lt;strong&gt;929 dimensions réparties en 88 groupes&lt;/strong&gt;, qui
va bien au-delà des métadonnées habituelles. Quelques-unes de ses entrées les moins
courantes :&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;modalité&lt;/th&gt;
					&lt;th&gt;dimension&lt;/th&gt;
					&lt;th&gt;définition&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;photo&lt;/td&gt;
					&lt;td&gt;température de couleur&lt;/td&gt;
					&lt;td&gt;équilibre moyen rouge–bleu de l&amp;rsquo;image (chaud ou froid)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;photo&lt;/td&gt;
					&lt;td&gt;colorfulness&lt;/td&gt;
					&lt;td&gt;métrique de couleurs opposées de Hasler &amp;amp; Süsstrunk (2003)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;photo&lt;/td&gt;
					&lt;td&gt;heure dorée / heure bleue&lt;/td&gt;
					&lt;td&gt;élévation du soleil calculée hors ligne à partir de la date et de la position&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;photo&lt;/td&gt;
					&lt;td&gt;taille du visage&lt;/td&gt;
					&lt;td&gt;part de l&amp;rsquo;image occupée par un visage (indice de proximité)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;voix&lt;/td&gt;
					&lt;td&gt;jitter, shimmer, rapport harmoniques/bruit&lt;/td&gt;
					&lt;td&gt;prosodie openSMILE eGeMAPS&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;voix&lt;/td&gt;
					&lt;td&gt;rires, pleurs, soupirs&lt;/td&gt;
					&lt;td&gt;détection d&amp;rsquo;événements sonores (classes AudioSet)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;voix&lt;/td&gt;
					&lt;td&gt;désaccord texte/voix&lt;/td&gt;
					&lt;td&gt;valence de la voix et valence de la transcription écartées d&amp;rsquo;au moins 0,6&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;message&lt;/td&gt;
					&lt;td&gt;valence, éveil, ton&lt;/td&gt;
					&lt;td&gt;par participant, contraints à la grille fixe&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;message&lt;/td&gt;
					&lt;td&gt;ponctuation expressive, palette d&amp;rsquo;emojis&lt;/td&gt;
					&lt;td&gt;mesures déterministes du texte&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;relation&lt;/td&gt;
					&lt;td&gt;asymétrie de latence de réponse&lt;/td&gt;
					&lt;td&gt;logarithme du rapport des délais médians de réponse des deux parties&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;relation&lt;/td&gt;
					&lt;td&gt;initiatives&lt;/td&gt;
					&lt;td&gt;conversations ouvertes après 3 h de silence, de chaque côté&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;relation&lt;/td&gt;
					&lt;td&gt;tendance&lt;/td&gt;
					&lt;td&gt;pente de l&amp;rsquo;intensité de la relation sur 90 jours (refroidissement &amp;lt; 0)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;période&lt;/td&gt;
					&lt;td&gt;nostalgie musicale&lt;/td&gt;
					&lt;td&gt;âge moyen des titres écoutés&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;période&lt;/td&gt;
					&lt;td&gt;création / consommation&lt;/td&gt;
					&lt;td&gt;temps passé sur des outils de création ÷ temps de consommation&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="des-signaux-au-sens"&gt;&lt;a href="#des-signaux-au-sens" class="header-anchor"&gt;&lt;/a&gt;Des signaux au sens
&lt;/h2&gt;&lt;pre class="mermaid" style="visibility:hidden"&gt;flowchart LR
 PH["Photo"] --&gt; PM["Mesures&lt;br/&gt;lumière · contraste · température de couleur&lt;br/&gt;colorfulness · palette · netteté"]
 PH --&gt; PS["Plongement SigLIP&lt;br/&gt;(similarité image ↔ texte)"]
 PH --&gt; PF["Signaux de visage de l'éditeur&lt;br/&gt;sourire · expression · regard · taille du visage"]
 VN["Note vocale"] --&gt; VT["Transcription Whisper"]
 VN --&gt; VL["Couches acoustiques&lt;br/&gt;valence/éveil/dominance · catégories&lt;br/&gt;événements sonores · prosodie · LLM audio"]
 VT --&gt; VX["Émotion du texte de la transcription"]
 VL --&gt; VF["Fusion pondérée&lt;br/&gt;confiance = accord&lt;br/&gt;signalement du désaccord texte/voix"]
 VX --&gt; VF
 MS["Messages&lt;br/&gt;(pseudonymisés : Moi, P1, P2)"] --&gt; ML["LLM local, grille fixe&lt;br/&gt;émotion · intensité · valence&lt;br/&gt;éveil · ton · sujets"]
 PM --&gt; OB[("Observatoire&lt;br/&gt;929 dimensions")]
 PS --&gt; OB
 PF --&gt; OB
 VF --&gt; OB
 ML --&gt; OB
 OB -- "émotion suffisamment sûre" --&gt; AFF["Épisode affectif (AFF)&lt;br/&gt;qui · émotion · quand · intensité · modalité"]
 PF -. "indice faible, confiance ≤ 0,4" .-&gt; AFF
 ML -- "sujets" --&gt; THM["Thèmes"]
 OB -- "agrégats" --&gt; AG["Indicateurs par jour / période&lt;br/&gt;valence · lumière · palette"]
 AFF --&gt; G["Graphe de sens&lt;br/&gt;relations · épisodes · thèmes · chapitres · vérités&lt;br/&gt;(tous proposés)"]
 THM --&gt; G
 AG --&gt; G
 G --&gt; HV(("Propriétaire&lt;br/&gt;valider · rejeter · corriger"))&lt;/pre&gt;&lt;p&gt;Chaque épisode affectif est un nœud relié à la personne qui l&amp;rsquo;a ressenti, à l&amp;rsquo;émotion du
vocabulaire fixe et — lorsqu&amp;rsquo;il existe — à la conversation ou au moment où il s&amp;rsquo;est produit.
Des règles d&amp;rsquo;inférence font ensuite remonter l&amp;rsquo;affect (par exemple l&amp;rsquo;affect d&amp;rsquo;un chapitre ou
d&amp;rsquo;une routine), et les corrélations fortes entre agrégats peuvent devenir des vérités
&lt;em&gt;proposées&lt;/em&gt;, avec leurs mesures pour preuves.&lt;/p&gt;
&lt;h2 id="la-mesure-des-émotions-en-détail"&gt;&lt;a href="#la-mesure-des-%c3%a9motions-en-d%c3%a9tail" class="header-anchor"&gt;&lt;/a&gt;La mesure des émotions en détail
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Vocabulaire.&lt;/strong&gt; La grille est fixe et versionnée : les 8 émotions primaires de Plutchik
à 3 intensités, ses 8 dyades primaires, plus des émotions sociales et réflexives utiles à
une vie (gratitude, tendresse, fierté, honte, solitude, nostalgie, émerveillement,
apaisement, épuisement…), soit &lt;strong&gt;53 au total&lt;/strong&gt;. Chacune porte des coordonnées de départ
dans le modèle circomplexe de Russell — valence dans [−1, 1], éveil dans [0, 1] — destinées
à être étalonnées ensuite sur les validations du propriétaire. Les oppositions de Plutchik
sont encodées, et les étiquettes d&amp;rsquo;humeur de l&amp;rsquo;application Santé sont rattachées à la grille.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Messages.&lt;/strong&gt; Un LLM local (Qwen3-30B-A3B) lit chaque conversation, les participants y
étant remplacés par « Moi », « P1 », « P2 », les messages présentés comme des données
auxquelles il ne doit pas obéir, et les médias réduits à des repères tels que
« [vocal 23 s] ». La sortie est contrainte par un schéma JSON : pour chaque participant,
l&amp;rsquo;émotion dominante prise dans la grille (ou aucune), l&amp;rsquo;intensité, la valence, l&amp;rsquo;éveil, un
ton choisi dans une liste fermée de 19, et une confiance ; plus 1 à 3 sujets qui deviennent
des thèmes. Les longues conversations sont réduites à leur début et à leur fin ; les
courtes sont regroupées par dix dans un même appel. Un épisode affectif n&amp;rsquo;est proposé que
si la confiance atteint au moins 0,3.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Voix.&lt;/strong&gt; Chaque enregistrement est converti en mono 16 kHz puis passe par :&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Whisper large-v3-turbo (MLX) pour la transcription ;&lt;/li&gt;
&lt;li&gt;un modèle wav2vec2 dimensionnel donnant valence, éveil et dominance sur des fenêtres
de 15 s, pondérées par leur durée, ainsi que la variabilité de l&amp;rsquo;éveil ;&lt;/li&gt;
&lt;li&gt;emotion2vec+ large pour l&amp;rsquo;émotion catégorielle, rattachée à la grille (retenue à
partir de 0,4) ;&lt;/li&gt;
&lt;li&gt;un classifieur AST AudioSet pour les rires, pleurs, soupirs, cris, chuchotements,
la musique et l&amp;rsquo;ambiance ;&lt;/li&gt;
&lt;li&gt;la prosodie openSMILE eGeMAPS : hauteur (en demi-tons) et sa variabilité, intensité
sonore, jitter, shimmer, rapport harmoniques/bruit, segments voisés par seconde, durée
moyenne des pauses ;&lt;/li&gt;
&lt;li&gt;Qwen2.5-Omni-7B (llama.cpp, Metal), qui écoute l&amp;rsquo;audio et renvoie une émotion de la
grille, une valence et de brefs indices acoustiques ;&lt;/li&gt;
&lt;li&gt;le modèle d&amp;rsquo;émotion du texte décrit ci-dessus, appliqué à la transcription.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Les avis catégoriels (catégories vocales, LLM audio, transcription) sont combinés par un
vote pondéré (poids 1,0, 1,0 et 0,8) ; la valence est une moyenne pondérée du modèle
dimensionnel, du LLM audio et de la transcription. &lt;strong&gt;La confiance correspond à l&amp;rsquo;accord
entre les couches&lt;/strong&gt; : une source d&amp;rsquo;accord donne 0,45, deux donnent 0,65, trois donnent
0,85, moins 0,1 par source en désaccord. Lorsque la voix et les mots divergent d&amp;rsquo;au moins
0,6 en valence (un « ça va » dit tristement), un &lt;strong&gt;désaccord texte/voix&lt;/strong&gt; est signalé au
lieu d&amp;rsquo;être noyé dans une moyenne. Les scores de rires et de pleurs sont conservés à côté.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Photos.&lt;/strong&gt; Sur des miniatures de 256 px, sans aucun modèle : luminosité, contraste,
saturation, température de couleur, colorfulness, netteté (variance du laplacien) et
palette de 5 couleurs avec teinte dominante nommée. Les plongements SigLIP so400m rendent
la photothèque interrogeable en texte. Les attributs de visage calculés par l&amp;rsquo;éditeur
(sourire, type de sourire, expression, regard, état des yeux, taille du visage) sont lus
comme des signaux, mais le schéma pose qu&amp;rsquo;&lt;em&gt;un sourire photographié n&amp;rsquo;est pas une joie
ressentie&lt;/em&gt; : la modalité visage est un indice faible, dont la confiance est plafonnée à
0,4. L&amp;rsquo;humeur musicale est traitée de la même façon : l&amp;rsquo;humeur d&amp;rsquo;un morceau n&amp;rsquo;est jamais, à
elle seule, une preuve de l&amp;rsquo;humeur de l&amp;rsquo;auditeur. À l&amp;rsquo;échelle d&amp;rsquo;une période, la valence est
fusionnée selon une priorité fixe : déclarée &amp;gt; voix &amp;gt; texte &amp;gt; visage.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Validation humaine.&lt;/strong&gt; Chaque épisode, thème, chapitre ou vérité est émis avec le statut
&lt;code&gt;proposed&lt;/code&gt;. La PWA présente une file de validation — les épisodes affectifs classés par
confiance, accompagnés de leur preuve (la conversation ou l&amp;rsquo;enregistrement d&amp;rsquo;origine) — et
le propriétaire valide, rejette ou corrige. Seul cet événement de décision humaine fait
passer une proposition à &lt;code&gt;validated&lt;/code&gt;, équivalence vérifiée automatiquement. L&amp;rsquo;étape
suivante prévue est un petit classifieur personnel sur les caractéristiques emotion2vec,
entraîné sur ces validations.&lt;/p&gt;
&lt;h2 id="architecture"&gt;&lt;a href="#architecture" class="header-anchor"&gt;&lt;/a&gt;Architecture
&lt;/h2&gt;&lt;pre class="mermaid" style="visibility:hidden"&gt;flowchart TB
 S["Sources (instantanés en lecture seule)&lt;br/&gt;messageries · courriels · photos · musique · notes · agenda · exports"]
 C["Connecteurs&lt;br/&gt;processus d'ingestion dédié, seul détenteur de l'accès disque"]
 V["Coffre (propriétaire seul, 0700)&lt;br/&gt;stockage brut adressé par contenu"]
 O["Observatoire&lt;br/&gt;faits + signaux (SQLite)"]
 K["Graphe de sens&lt;br/&gt;journal JSONL en ajout seul → repli SQLite + FTS"]
 N["Chaînes nocturnes / horaires&lt;br/&gt;vignettes · mesures · SigLIP · émotions&lt;br/&gt;(verrou GPU, un modèle à la fois)"]
 M["Serveur MCP (stdio, sans port)&lt;br/&gt;20 outils en lecture seule / proposition seule"]
 H["Hermes Agent&lt;br/&gt;LLM local via Ollama"]
 P["PWA (HTTPS + TOTP)&lt;br/&gt;discussion · file de validation"]
 U(("Propriétaire"))
 S --&gt; C --&gt; V --&gt; O --&gt; K
 N --&gt; O
 O --&gt; M
 K --&gt; M
 M --&gt; H --&gt; P
 P -- "valider / rejeter / corriger" --&gt; K
 U -- "VPN NetBird" --&gt; P&lt;/pre&gt;&lt;p&gt;Les données brutes sont capturées sous forme d&amp;rsquo;instantanés (SQLite ouvert en
&lt;code&gt;mode=ro&amp;amp;immutable=1&lt;/code&gt;) et ne sont jamais modifiées ; tout ce qui en dérive réside dans un
coffre distinct, accessible au seul propriétaire, et le dépôt de code ne contient aucune
donnée. Le graphe de sens repose sur le module de base de connaissances de la bibliothèque
d&amp;rsquo;atomes : un journal d&amp;rsquo;événements JSONL en ajout seul, validé par schéma et replié dans
un index SQLite jetable.&lt;/p&gt;
&lt;p&gt;Le schéma est lui-même une donnée, vérifiée mécaniquement : &lt;strong&gt;27 types de nœuds et
50 prédicats&lt;/strong&gt;, &lt;strong&gt;9 origines de provenance&lt;/strong&gt;, &lt;strong&gt;31 types de localisateurs&lt;/strong&gt; qui rattachent
chaque assertion à son élément source, le vocabulaire de 53 émotions, &lt;strong&gt;17 règles
d&amp;rsquo;inférence&lt;/strong&gt; et &lt;strong&gt;42 sources&lt;/strong&gt; derrière les 929 dimensions (610 natives, 126 calculées par
les éditeurs, 86 agrégats, 74 mesures déterministes, 29 interprétations de modèles).&lt;/p&gt;
&lt;h2 id="modèle-de-sécurité"&gt;&lt;a href="#mod%c3%a8le-de-s%c3%a9curit%c3%a9" class="header-anchor"&gt;&lt;/a&gt;Modèle de sécurité
&lt;/h2&gt;&lt;p&gt;Le contenu des sources est supposé hostile (injection de prompt dans un message ou un
courriel), et le modèle peut halluciner ou détourner les outils. Les défenses sont
structurelles :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Aucune capacité ambiante.&lt;/strong&gt; Le framework d&amp;rsquo;agent (Hermes Agent) a 20 ensembles
d&amp;rsquo;outils intégrés désactivés (terminal, fichiers, exécution de code, web, navigateur,
délégation, mémoire, voix dans le cloud…) ; aucun fournisseur cloud, aucune vérification
de mise à jour ni connexion externe ; le seul point d&amp;rsquo;accès au modèle est un serveur
Ollama en boucle locale.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Une interface unique et étroite.&lt;/strong&gt; Les données ne sont accessibles que par un serveur
MCP local via stdio, avec schémas fermés, arguments validés, troncature explicite et
journal d&amp;rsquo;accès sans contenu. Les outils peuvent &lt;em&gt;proposer&lt;/em&gt;, jamais &lt;em&gt;décider&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Séparation des privilèges et pseudonymisation.&lt;/strong&gt; Seule l&amp;rsquo;ingestion dispose de l&amp;rsquo;accès
complet au disque ; l&amp;rsquo;analyse n&amp;rsquo;a pas de réseau. Les tiers sont des codes opaques, et un
nom réel dans un identifiant est rejeté par le schéma.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Niveaux de sensibilité&lt;/strong&gt; (0–3) par élément, avec un plafond plus bas pour les sessions
à distance ; accès à distance uniquement par VPN NetBird, TOTP et cookies de session
stricts.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Exclusions éthiques&lt;/strong&gt; : l&amp;rsquo;origine ethnique, la couleur de peau et le genre inférés par
les éditeurs ne sont jamais lus.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="modèles"&gt;&lt;a href="#mod%c3%a8les" class="header-anchor"&gt;&lt;/a&gt;Modèles
&lt;/h2&gt;&lt;p&gt;Toute l&amp;rsquo;inférence est locale ; un seul grand modèle est chargé à la fois, sous un verrou
GPU partagé.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;tâche&lt;/th&gt;
					&lt;th&gt;modèle&lt;/th&gt;
					&lt;th&gt;environnement d&amp;rsquo;exécution&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;agent (usage d&amp;rsquo;outils, contexte ≥ 64k)&lt;/td&gt;
					&lt;td&gt;gpt-oss:20b, qwen3:8b en repli&lt;/td&gt;
					&lt;td&gt;Ollama&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;émotions du texte, émotions des transcriptions vocales&lt;/td&gt;
					&lt;td&gt;Qwen3-30B-A3B-Instruct-2507 (Q4)&lt;/td&gt;
					&lt;td&gt;Ollama&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;plongements texte / image&lt;/td&gt;
					&lt;td&gt;bge-m3 · SigLIP so400m&lt;/td&gt;
					&lt;td&gt;Ollama · PyTorch MPS&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;lecture d&amp;rsquo;images&lt;/td&gt;
					&lt;td&gt;qwen3-vl:8b&lt;/td&gt;
					&lt;td&gt;Ollama&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;transcription de la parole&lt;/td&gt;
					&lt;td&gt;Whisper large-v3-turbo&lt;/td&gt;
					&lt;td&gt;MLX&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;émotion vocale (5 couches)&lt;/td&gt;
					&lt;td&gt;wav2vec2 dimensionnel · emotion2vec+ · AST · openSMILE eGeMAPS · Qwen2.5-Omni-7B&lt;/td&gt;
					&lt;td&gt;PyTorch MPS · CPU · llama.cpp (Metal)&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Chaque modèle est soumis à un test de validation rapide sur des données synthétiques
uniquement (une phrase française fictive synthétisée par une TTS locale, puis passée dans
toute la chaîne audio).&lt;/p&gt;
&lt;h2 id="évaluation--résultats"&gt;&lt;a href="#%c3%a9valuation--r%c3%a9sultats" class="header-anchor"&gt;&lt;/a&gt;Évaluation &amp;amp; résultats
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Qualité des réponses de l&amp;rsquo;agent.&lt;/strong&gt; Un banc d&amp;rsquo;essai de 16 questions (dont 2 questions
pièges), avec une vérité terrain calculée en appelant directement les outils, évalue le
choix des outils, la &lt;em&gt;fidélité numérique&lt;/em&gt; (chaque nombre de la réponse doit figurer dans
les sorties d&amp;rsquo;outils de ce tour), l&amp;rsquo;exactitude, la gestion des pièges et le signalement
des périodes partielles : &lt;strong&gt;73 % → 100 %&lt;/strong&gt; après des corrections des descriptions
d&amp;rsquo;outils, de la validation des arguments et de la configuration.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Correction des erreurs côté serveur.&lt;/strong&gt; Avec une interface réduite à 8 outils, les
questions simples sont passées de 76 % à 90 % et les questions croisant plusieurs sources
de 73 % à 90 % ; 20 questions délibérément inhabituelles ont obtenu 89 % et mis au jour
des échecs silencieux renvoyant zéro, corrigés depuis.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Contexte et latence.&lt;/strong&gt; Descriptions d&amp;rsquo;outils réduites de 23,5 k à 9,5 k caractères ;
une requête d&amp;rsquo;agrégation lourde passée de 172 s à 0,1 s ; toutes les requêtes lourdes du
banc d&amp;rsquo;essai en ≤ 0,3 s.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Banc d&amp;rsquo;essai d&amp;rsquo;exploration croisée.&lt;/strong&gt; 60 scénarios écrits uniquement avec des valeurs
fictives, chacun doté d&amp;rsquo;un oracle ; les oracles passent 61/61, sans aucune fuite aux
plafonds de sensibilité à distance 1 et 2.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Vérification.&lt;/strong&gt; 56 contrôles de schéma nommés au vert ; 631 colonnes natives/éditeurs
confirmées par rapport aux structures réelles des bases ; 1 235 tests unitaires Python,
15 fichiers de tests JavaScript et 110 tests de qualité sur données réelles qui ne
rapportent que des comptages.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="limites--suite"&gt;&lt;a href="#limites--suite" class="header-anchor"&gt;&lt;/a&gt;Limites &amp;amp; suite
&lt;/h2&gt;&lt;p&gt;Les jeux d&amp;rsquo;évaluation sont restreints et rédigés par le concepteur du système ; ils mesurent
la fidélité et les régressions plutôt que la capacité générale. Les sorties émotionnelles
sont des hypothèses : les coordonnées de valence et d&amp;rsquo;éveil du vocabulaire sont des valeurs
de départ, et le calibrage personnel de l&amp;rsquo;émotion vocale à partir d&amp;rsquo;exemples validés reste
à réaliser, de même que le modèle d&amp;rsquo;agent cible, plus grand. Les réponses de l&amp;rsquo;agent
prennent plusieurs dizaines de secondes avec un modèle de 20B.&lt;/p&gt;
&lt;h2 id="stack-technique"&gt;&lt;a href="#stack-technique" class="header-anchor"&gt;&lt;/a&gt;Stack technique
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;Python&lt;/code&gt; · &lt;code&gt;SQLite / FTS5&lt;/code&gt; · &lt;code&gt;Ollama&lt;/code&gt; · &lt;code&gt;llama.cpp (Metal)&lt;/code&gt; · &lt;code&gt;MLX&lt;/code&gt; · &lt;code&gt;PyTorch MPS&lt;/code&gt; · &lt;code&gt;Hermes Agent&lt;/code&gt; · &lt;code&gt;MCP&lt;/code&gt; · &lt;code&gt;SigLIP&lt;/code&gt; · &lt;code&gt;Whisper&lt;/code&gt; · &lt;code&gt;emotion2vec&lt;/code&gt; · &lt;code&gt;openSMILE&lt;/code&gt; · &lt;code&gt;NetBird&lt;/code&gt; · &lt;code&gt;PWA&lt;/code&gt; · &lt;code&gt;launchd&lt;/code&gt;&lt;/p&gt;</description></item><item><title>Graphes de connaissances de mission : des preuves de conseil à une ontologie interrogée via MCP</title><link>https://borisdupoux.com/fr/research/mission-knowledge-graph/</link><pubDate>Tue, 01 Sep 2026 00:00:00 +0000</pubDate><guid>https://borisdupoux.com/fr/research/mission-knowledge-graph/</guid><description>&lt;h2 id="contexte"&gt;&lt;a href="#contexte" class="header-anchor"&gt;&lt;/a&gt;Contexte
&lt;/h2&gt;&lt;p&gt;Le conseil en observation des processus produit des logigrammes, des notes d&amp;rsquo;entretien, des
enregistrements d&amp;rsquo;écran et des recommandations. Une fois la mission livrée, ce matériau est
de fait inerte : la mission suivante repart d&amp;rsquo;une page blanche, même lorsque la réponse avait
déjà été trouvée ailleurs. La question de recherche est de savoir comment transformer les
livrables, de &lt;strong&gt;documents en données typées, sourcées et interrogeables&lt;/strong&gt;, afin qu&amp;rsquo;un
assistant puisse répondre à « où avons-nous déjà vu cela, et qu&amp;rsquo;en avions-nous conclu ? » en
citant des preuves vérifiables.&lt;/p&gt;
&lt;p&gt;Deux exigences structurent le travail : la &lt;strong&gt;traçabilité&lt;/strong&gt; (chaque assertion renvoie à sa
preuve) et une stricte &lt;strong&gt;séparation entre preuve et connaissance&lt;/strong&gt; (ce qui a été observé
n&amp;rsquo;est pas ce qui a été généralisé). La génération augmentée par la recherche (RAG) est
rapide à mettre en place, mais cite des passages, pas des assertions vérifiables ; une
ontologie formelle est traçable, mais coûteuse. Ce projet explore une voie pragmatique entre
les deux.&lt;/p&gt;
&lt;h2 id="approche"&gt;&lt;a href="#approche" class="header-anchor"&gt;&lt;/a&gt;Approche
&lt;/h2&gt;&lt;pre class="mermaid" style="visibility:hidden"&gt;flowchart TB
 A["`Sources brutes de mission
immuables, hachées`"] --&gt; B["`Journal d'événements en ajout seul
source de vérité`"]
 B --&gt; C["`Base SQLite reconstructible
jetable`"]
 C --&gt; D[Extraction déterministe]
 C --&gt; E["`Extraction par LLM
simple force de proposition`"]
 D --&gt; F["`Nœuds et arêtes proposés
avec provenance`"]
 E --&gt; F
 F --&gt; G{"`Revue humaine
hors MCP`"}
 G --&gt;|validé| H[Graphe de connaissances]
 H --&gt; I[MCP : preuves]
 H --&gt; J[MCP : connaissances]
 H --&gt; K[MCP : ontologie]
 I --&gt; L[Assistant IA]
 J --&gt; L
 K --&gt; L&lt;/pre&gt;&lt;p&gt;Le choix de conception central consiste à scinder l&amp;rsquo;interface en &lt;strong&gt;trois serveurs MCP selon
le statut épistémique&lt;/strong&gt; : &lt;em&gt;preuves&lt;/em&gt; (observations attestées et sourcées), &lt;em&gt;connaissances&lt;/em&gt;
(généralisations) et &lt;em&gt;ontologie&lt;/em&gt; (le méta-modèle lui-même). Cette séparation empêche un
assistant de présenter une généralisation comme une observation.&lt;/p&gt;
&lt;pre class="mermaid" style="visibility:hidden"&gt;flowchart TB
 subgraph SCHEMA["SCHÉMA · nommage"]
 ON["`serveur ontologie
Comment le nomme-t-on ?`"]
 end
 subgraph PROVEN["PROUVÉ · observé"]
 EV["`serveur preuves
Qu'a-t-on capté, et où ?`"]
 end
 subgraph GENERAL["GÉNÉRALISÉ · conclu"]
 KN["`serveur connaissances
Qu'en conclut-on ?
propose, ne valide jamais`"]
 end
 ON -. "type" .-&gt; EV
 EV == "fonde chaque conclusion" ==&gt; KN
 EV --&gt; AI["`Assistant IA
réponses étiquetées par statut`"]
 KN --&gt; AI
 ON --&gt; AI&lt;/pre&gt;&lt;p&gt;Le graphe est unique ; seules les façades sont séparées. La frontière qui compte passe entre
preuves et connaissances : le serveur &lt;em&gt;preuves&lt;/em&gt; ne renvoie que ce qui a été observé, et où ;
le serveur &lt;em&gt;connaissances&lt;/em&gt; renvoie des conclusions qui doivent remonter jusqu&amp;rsquo;à ces preuves,
et aucun outil MCP ne peut marquer quoi que ce soit comme validé.&lt;/p&gt;
&lt;h2 id="méthodes"&gt;&lt;a href="#m%c3%a9thodes" class="header-anchor"&gt;&lt;/a&gt;Méthodes
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Méta-modèle.&lt;/strong&gt; Un noyau fixe, complété de profils de mission et d&amp;rsquo;une ontologie
versionnée (v0). Chaque nœud porte une origine (structurelle, déterministe, extraite par
LLM) et un statut (proposé → validé).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Invariants (I1–I6).&lt;/strong&gt; La provenance est obligatoire sur chaque nœud et chaque arête
dérivés ; une recommandation doit pouvoir être rattachée, de proche en proche, à un constat
sourcé ; les citations extraites par LLM doivent être des sous-chaînes littérales de leur
fragment ; le statut « validé » exige une décision humaine enregistrée. Les sources brutes
sont immuables ; la base de données est jetable et reconstruite à partir du journal.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Questions de compétence avant l&amp;rsquo;implémentation.&lt;/strong&gt; Un jeu v0 de 33 questions, typées
comme factuelles, agrégées, de traçabilité, de contradiction, temporelles, inter-missions
et &lt;strong&gt;négatives&lt;/strong&gt; (requêtes que le système doit refuser, par exemple une fuite entre
clients), dans un format exécutable avec réponses attendues et références.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Protocole d&amp;rsquo;évaluation.&lt;/strong&gt; Au moins 30 tâches en langage naturel, notées automatiquement
ou par un juge. Les seuils de passage ont été fixés en amont : exactitude ≥ 0,8, citations
valides ≥ 0,98, ancrage ≥ 0,95, fuite = 0, médiane ≤ 6 appels d&amp;rsquo;outils par tâche ; chaque
question soluble en ≤ 3 appels ; précision de l&amp;rsquo;extraction déterministe ≥ 0,95 par type ;
κ inter-annotateurs ≥ 0,7.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Phases P0–P6 avec jalons humains.&lt;/strong&gt; L&amp;rsquo;implémentation est déléguée à une session d&amp;rsquo;agent
qui doit s&amp;rsquo;arrêter à chaque jalon et consigner les décisions en suspens.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cartographie d&amp;rsquo;un logiciel en boîte noire.&lt;/strong&gt; La même méthode a été appliquée à un
logiciel commercial de gestion d&amp;rsquo;entreprise, sans lecture de son code source. La cible est
un triplet de vérités — utilisateur, logiciel et base de données — reliées par des arêtes
prouvées. Onze heuristiques (H1–H11) couvrent l&amp;rsquo;appariement de valeurs, la perturbation
inverse et directe, les champs calculés, la visibilité conditionnelle, les différences
entre scénarios, la fouille d&amp;rsquo;invariants, le fuzzing des saisies, les a priori sémantiques
(jamais considérés comme preuve), le passage de la documentation au test et du symptôme à
la règle. Entrées : l&amp;rsquo;arborescence des menus via AT-SPI, un relevé des écrans, le
profilage des colonnes et une typologie d&amp;rsquo;événements issue du journal d&amp;rsquo;audit de
l&amp;rsquo;application. Une hypothèse n&amp;rsquo;est acceptée qu&amp;rsquo;avec une contre-preuve indépendante ; les
cartographies produites par l&amp;rsquo;éditeur sont tenues en quarantaine et servent d&amp;rsquo;oracle de
notation.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Un extrait illustratif du graphe typé (libellés fictifs) : la préconisation n&amp;rsquo;est recevable
que parce que la chaîne qui descend jusqu&amp;rsquo;à un fragment littéral d&amp;rsquo;une source est complète.&lt;/p&gt;
&lt;pre class="mermaid" style="visibility:hidden"&gt;flowchart TB
 R["`Préconisation
point de saisie unique`"] -- répond à --&gt; C["`Constat
double saisie à la réception`"]
 O["`Observation
« le stock est ressaisi à la main »`"] -- atteste --&gt; C
 O -- extrait de --&gt; F["`Fragment
notes d'entretien, lignes 40–52`"]
 F -- cite --&gt; P["`Pièce source
hachée, immuable`"]
 C -- porte sur --&gt; A["`Activité
réception des marchandises`"]
 A -- utilise --&gt; S["`Écran
formulaire de réception`"]
 S -- module de --&gt; Y["`Système
logiciel de gestion`"]&lt;/pre&gt;&lt;h2 id="état-davancement--résultats"&gt;&lt;a href="#%c3%a9tat-davancement--r%c3%a9sultats" class="header-anchor"&gt;&lt;/a&gt;État d&amp;rsquo;avancement &amp;amp; résultats
&lt;/h2&gt;&lt;p&gt;Il s&amp;rsquo;agit &lt;strong&gt;principalement d&amp;rsquo;une conception partiellement implémentée&lt;/strong&gt;, et non d&amp;rsquo;un
système en service.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Pilote (corpus d&amp;rsquo;observation, passe déterministe).&lt;/strong&gt; 6 195 fichiers (6,92 Go) acquis de
manière idempotente ; 13 272 nœuds et 6 022 arêtes extraits en 2,1 s pour un coût LLM nul ;
les six invariants au vert sur 57 969 vérifications.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mesure sur jeu de référence.&lt;/strong&gt; 145 unités d&amp;rsquo;annotation et 100 paires de résolution
d&amp;rsquo;entités. L&amp;rsquo;annotation humaine était partielle et le second annotateur était un LLM.
Accord humain × LLM : κ = 0,72 (logiciel), 0,41 (écran), 0,31 (catégorie), 0,52 (limites
de segments). Précision de l&amp;rsquo;extracteur par rapport à la référence humaine : 0,74, 0,43,
0,04, 0,63. &lt;strong&gt;Jalon G2 (≥ 0,95) non franchi&lt;/strong&gt; ; le résultat sur la catégorie traduit un
désaccord de définition, et non une erreur de calcul.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cartographie du logiciel.&lt;/strong&gt; Schéma de 427 tables sans aucune clé étrangère, aucun
déclencheur ni aucune vue déclarés (toute la logique est applicative) ; 1 048 entrées de
menu (899 feuilles) cartographiées ; 154 des 899 écrans relevés (17 %) ; 2 845 hypothèses
de règles ramenées à 1 519 par un filtre LLM local, avec 1 erreur de décision sur un
échantillon de 50 éléments revu par l&amp;rsquo;agent superviseur. Un prototype MCP en lecture seule
existe ; &lt;strong&gt;aucune règle n&amp;rsquo;a encore été prouvée&lt;/strong&gt; dans le logiciel. Les travaux ont été
suspendus après une surcharge de la VM hôte.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Mesure sur jeu de référence face aux seuils fixés à l&amp;rsquo;avance : les barres sont les valeurs
mesurées par champ, la ligne orange est le seuil. Une seule barre le franchit.&lt;/p&gt;
&lt;pre class="mermaid" style="visibility:hidden"&gt;---
config:
 xyChart:
 width: 540
 height: 320
 themeVariables:
 xyChart:
 backgroundColor: "transparent"
 plotColorPalette: "#3F86B8, #C46A2B"
---
xychart-beta
 title "Accord humain × LLM, κ (seuil 0,7)"
 x-axis ["logiciel", "écran", "catégorie", "segments"]
 y-axis "κ" 0 --&gt; 1
 bar [0.72, 0.41, 0.31, 0.52]
 line [0.7, 0.7, 0.7, 0.7]&lt;/pre&gt;&lt;pre class="mermaid" style="visibility:hidden"&gt;---
config:
 xyChart:
 width: 540
 height: 320
 themeVariables:
 xyChart:
 backgroundColor: "transparent"
 plotColorPalette: "#3F86B8, #C46A2B"
---
xychart-beta
 title "Précision vs référence humaine (seuil 0,95)"
 x-axis ["logiciel", "écran", "catégorie", "segments"]
 y-axis "Précision" 0 --&gt; 1
 bar [0.74, 0.43, 0.04, 0.63]
 line [0.95, 0.95, 0.95, 0.95]&lt;/pre&gt;&lt;p&gt;La cartographie du logiciel, en entonnoir : l&amp;rsquo;arborescence des menus est entièrement
cartographiée, mais la couverture des écrans et la preuve restent loin derrière, et la
chaîne d&amp;rsquo;hypothèses n&amp;rsquo;a encore produit aucune règle prouvée.&lt;/p&gt;
&lt;pre class="mermaid" style="visibility:hidden"&gt;---
config:
 xyChart:
 width: 540
 height: 360
 themeVariables:
 xyChart:
 backgroundColor: "transparent"
 plotColorPalette: "#3F86B8"
---
xychart-beta
 title "Cartographie en boîte noire : de l'inventaire à la preuve"
 x-axis ["Entrées menu", "Feuilles", "Écrans", "Hypothèses", "Filtrées", "Prouvées"]
 y-axis "Nombre" 0 --&gt; 3000
 bar [1048, 899, 154, 2845, 1519, 0]&lt;/pre&gt;&lt;p&gt;Les serveurs MCP et l&amp;rsquo;évaluation de bout en bout (P4–P5) ne sont &lt;strong&gt;pas implémentés&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id="limites--suite"&gt;&lt;a href="#limites--suite" class="header-anchor"&gt;&lt;/a&gt;Limites &amp;amp; suite
&lt;/h2&gt;&lt;p&gt;Les résultats du pilote sont inférieurs aux seuils et reposent sur une annotation humaine
partielle. Prochaines étapes : redéfinir l&amp;rsquo;étiquette de catégorie, constituer une référence
entièrement humaine, mesurer à nouveau G1/G2, puis construire les trois serveurs et mener
l&amp;rsquo;évaluation préenregistrée. Pour la cartographie du logiciel, les heuristiques de
perturbation en écriture attendent une autorisation écrite et une VM dédiée.&lt;/p&gt;
&lt;h2 id="stack-technique"&gt;&lt;a href="#stack-technique" class="header-anchor"&gt;&lt;/a&gt;Stack technique
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;Python 3.11&lt;/code&gt; · &lt;code&gt;JSONL event log&lt;/code&gt; · &lt;code&gt;SQLite&lt;/code&gt; · &lt;code&gt;YAML ontology&lt;/code&gt; · &lt;code&gt;MCP&lt;/code&gt; · &lt;code&gt;AT-SPI&lt;/code&gt; · &lt;code&gt;Ollama&lt;/code&gt; · &lt;code&gt;pytest&lt;/code&gt;&lt;/p&gt;</description></item></channel></rss>