<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>tazmen3 &#8211; tazmenworld</title>
	<atom:link href="https://tazmenworld.com/author/tazmen3/feed/" rel="self" type="application/rss+xml" />
	<link>https://tazmenworld.com</link>
	<description>Mon site WordPress</description>
	<lastBuildDate>Tue, 09 Jun 2026 06:49:40 +0000</lastBuildDate>
	<language>fr-FR</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0</generator>
	<item>
		<title>J&#8217;ai quitté OpenRouter pour OpenCode Go : ce que ça change vraiment sur la facture</title>
		<link>https://tazmenworld.com/2026/06/09/jai-quitte-openrouter-pour-opencode-go-ce-que-ca-change-vraiment-sur-la-facture/</link>
					<comments>https://tazmenworld.com/2026/06/09/jai-quitte-openrouter-pour-opencode-go-ce-que-ca-change-vraiment-sur-la-facture/#respond</comments>
		
		<dc:creator><![CDATA[tazmen3]]></dc:creator>
		<pubDate>Tue, 09 Jun 2026 06:49:40 +0000</pubDate>
				<category><![CDATA[Non classé]]></category>
		<guid isPermaLink="false">https://tazmenworld.com/?p=312</guid>

					<description><![CDATA[Je fais tourner un agent autonome (Hermes Agent de Nous Research) sur un mini PC dédié à la maison. Jusqu&#8217;à cette semaine, toutes ses requêtes LLM passaient par OpenRouter, avec DeepSeek V4 Flash comme modèle par défaut. OpenRouter, c&#8217;est pratique : une seule clé, des dizaines de modèles, paiement à l&#8217;usage. Mais le paiement à [&#8230;]]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-full"><img width="1024" height="572"  alt="" class="wp-image-316"/ loading="eager" fetchpriority="high" decoding="async" src="https://tazmenworld.com/wp-content/uploads/2026/06/opencode_cleanup.jpeg" srcset="https://tazmenworld.com/wp-content/uploads/2026/06/opencode_cleanup.jpeg 1024w, https://tazmenworld.com/wp-content/uploads/2026/06/opencode_cleanup-300x168.jpeg 300w, https://tazmenworld.com/wp-content/uploads/2026/06/opencode_cleanup-768x429.jpeg 768w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">Je fais tourner un agent autonome (<a href="https://github.com/NousResearch/hermes-agent">Hermes Agent</a> de Nous Research) sur un mini PC dédié à la maison. Jusqu&rsquo;à cette semaine, toutes ses requêtes LLM passaient par OpenRouter, avec DeepSeek V4 Flash comme modèle par défaut.</p>



<p class="wp-block-paragraph">OpenRouter, c&rsquo;est pratique : une seule clé, des dizaines de modèles, paiement à l&rsquo;usage. Mais le paiement à l&rsquo;usage a un défaut quand on laisse tourner un agent : on ne sait jamais à l&rsquo;avance ce qu&rsquo;on va payer.</p>



<p class="wp-block-paragraph">J&rsquo;ai regardé mes chiffres. Ils m&rsquo;ont décidé.</p>



<h2 class="wp-block-heading">Les chiffres qui font mal</h2>



<p class="wp-block-paragraph">Sur <strong>2 jours</strong> d&rsquo;utilisation, voici ce que mon dashboard OpenRouter affichait :</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>Modèle</th><th>Coût</th><th>Requêtes</th><th>Tokens</th></tr></thead><tbody><tr><td>DeepSeek V4 Flash</td><td>2,31 $</td><td>861</td><td>36 M</td></tr><tr><td>DeepSeek V4 Pro</td><td>1,40 $</td><td>13</td><td>~1,8 M</td></tr><tr><td><strong>Total</strong></td><td><strong>3,71 $</strong></td><td><strong>874</strong></td><td><strong>37,8 M</strong></td></tr></tbody></table></figure>



<p class="wp-block-paragraph">Deux choses sautent aux yeux.</p>



<figure class="wp-block-image size-large"><img width="1024" height="331"  alt="" class="wp-image-315"/ loading="lazy" decoding="async" src="https://tazmenworld.com/wp-content/uploads/2026/06/image-4-1024x331.png" srcset="https://tazmenworld.com/wp-content/uploads/2026/06/image-4-1024x331.png 1024w, https://tazmenworld.com/wp-content/uploads/2026/06/image-4-300x97.png 300w, https://tazmenworld.com/wp-content/uploads/2026/06/image-4-768x248.png 768w, https://tazmenworld.com/wp-content/uploads/2026/06/image-4-1536x497.png 1536w, https://tazmenworld.com/wp-content/uploads/2026/06/image-4.png 1973w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">D&rsquo;abord, 3,71 $ en deux jours. Si je projette ça sur un mois, je tourne autour de <strong>55 $</strong>. C&rsquo;est beaucoup pour un agent perso.</p>



<p class="wp-block-paragraph">Ensuite, le détail qui m&rsquo;a le plus surpris : DeepSeek V4 Pro. <strong>13 requêtes seulement, mais 1,40 $</strong>  soit près de 40 % de ma facture pour 1,5 % de mes appels. Ces quelques requêtes lourdes que l&rsquo;agent décide de router vers un gros modèle, on ne les voit pas venir. Et c&rsquo;est exactement là que le paiement à l&rsquo;usage devient imprévisible.</p>



<h2 class="wp-block-heading">OpenCode Go : le coût fixe</h2>



<p class="wp-block-paragraph"><a href="https://opencode.ai/go">OpenCode Go</a>, c&rsquo;est un abonnement à <strong>10 $/mois</strong> (5 $ le premier mois) qui donne accès à une douzaine de modèles open source curatés : DeepSeek V4 Flash et Pro, Qwen3, Kimi K2, GLM-5, MiniMax, MiMo.</p>



<p class="wp-block-paragraph">Le point clé pour moi : l&rsquo;endpoint est <strong>compatible OpenAI</strong>. Pas besoin d&rsquo;utiliser l&rsquo;outil OpenCode lui-même. On branche la clé sur n&rsquo;importe quel agent qui parle à une API LLM/Hermes dans mon cas.</p>



<h2 class="wp-block-heading">La migration, étape par étape</h2>



<p class="wp-block-paragraph">Bonne surprise : Hermes supporte OpenCode Go nativement. La section est déjà prévue dans le fichier de config. La bascule m&rsquo;a pris cinq minutes.</p>



<h3 class="wp-block-heading">1. Récupérer la clé OpenCode Go</h3>



<p class="wp-block-paragraph">Après abonnement sur <a href="https://opencode.ai/go">opencode.ai/go</a>, la clé API se récupère depuis le dashboard. Elle commence par <code>sk-</code>.</p>



<h3 class="wp-block-heading">2. Ajouter la clé dans le <code>.env</code></h3>



<p class="wp-block-paragraph">Le fichier d&rsquo;environnement de Hermes se trouve dans <code>~/.hermes/.env</code>. On y décommente la ligne dédiée à OpenCode Go et on colle la clé :</p>



<p class="wp-block-paragraph">bash</p>



<pre class="wp-block-code"><code>OPENCODE_GO_API_KEY=sk-votre-cle-ici</code></pre>



<p class="wp-block-paragraph">À noter : on peut laisser l&rsquo;ancienne clé OpenRouter en place. Hermes utilise le provider défini dans la config, pas celui dont la clé est présente. Pratique pour revenir en arrière sans rien réécrire.</p>



<h3 class="wp-block-heading">3. Pointer Hermes sur OpenCode Go</h3>



<p class="wp-block-paragraph">Trois commandes suffisent. On change le provider, l&rsquo;URL de base, et le modèle par défaut :</p>



<p class="wp-block-paragraph">bash</p>



<pre class="wp-block-code"><code>hermes config set model.provider opencode-go
hermes config set model.base_url https://opencode.ai/zen/go/v1
hermes config set model.default opencode-go/deepseek-v4-flash</code></pre>



<p class="wp-block-paragraph">Je garde le même modèle (DeepSeek V4 Flash), je change juste le tuyau qui y mène.</p>



<h3 class="wp-block-heading">4. Vérifier depuis Telegram</h3>



<p class="wp-block-paragraph">Mon Hermes est piloté en partie via Telegram. La commande <code>/model</code> affiche la configuration courante et permet de changer de provider à la volée. C&rsquo;est le moyen le plus rapide de confirmer que la bascule a pris.</p>



<figure class="wp-block-image size-full"><img width="424" height="341"  alt="" class="wp-image-313"/ loading="lazy" decoding="async" src="https://tazmenworld.com/wp-content/uploads/2026/06/image-2.png" srcset="https://tazmenworld.com/wp-content/uploads/2026/06/image-2.png 424w, https://tazmenworld.com/wp-content/uploads/2026/06/image-2-300x241.png 300w" sizes="auto, (max-width: 424px) 100vw, 424px" /></figure>



<p class="wp-block-paragraph">Et le résultat une fois le modèle sélectionné :</p>



<figure class="wp-block-image size-full"><img width="496" height="199"  alt="" class="wp-image-314"/ loading="lazy" decoding="async" src="https://tazmenworld.com/wp-content/uploads/2026/06/image-3.png" srcset="https://tazmenworld.com/wp-content/uploads/2026/06/image-3.png 496w, https://tazmenworld.com/wp-content/uploads/2026/06/image-3-300x120.png 300w" sizes="auto, (max-width: 496px) 100vw, 496px" /></figure>



<p class="wp-block-paragraph">C&rsquo;est fait. L&rsquo;agent tourne désormais entièrement sur OpenCode Go.</p>



<h2 class="wp-block-heading">Le calcul, sans enjoliver</h2>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th></th><th>Sur 2 jours</th><th>Projeté sur ~30 jours</th></tr></thead><tbody><tr><td>OpenRouter (réel)</td><td>3,71 $</td><td>~55 $</td></tr><tr><td>OpenCode Go (fixe)</td><td>—</td><td>10 $</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">Sur le papier, c&rsquo;est <strong>80 % d&rsquo;économie</strong>. Mais je veux être honnête sur deux nuances, parce que c&rsquo;est facile de vendre du rêve avec ce genre de tableau.</p>



<p class="wp-block-paragraph"><strong>Nuance 1 : mes deux jours étaient atypiques.</strong> J&rsquo;étais en plein build de mon serveur d&rsquo;automation, avec des sessions très denses. Mon usage courant est plus léger. Donc les 55 $ projetés sont un plafond, pas une moyenne.</p>



<p class="wp-block-paragraph"><strong>Nuance 2 : OpenCode Go n&rsquo;est pas illimité.</strong> Les limites sont exprimées en valeur dollar, pas en nombre de requêtes, et elles se rechargent toutes les 5 heures. Les modèles plus légers durent plus longtemps que les gros. Si vous balancez du DeepSeek V4 Pro en continu, vous taperez le plafond. Pour un usage agent normal sur un modèle Flash, ça passe largement.</p>



<p class="wp-block-paragraph">Autrement dit : l&rsquo;économie est réelle, mais elle suppose un usage qui rentre dans les limites du forfait. Ce n&rsquo;est pas une licence pour consommer sans compter.</p>



<h2 class="wp-block-heading">Ce que je retiens</h2>



<p class="wp-block-paragraph">Le vrai gain, ce n&rsquo;est pas seulement le prix. C&rsquo;est la <strong>prévisibilité</strong>. Je sais que je paie 10 $ ce mois-ci, point. Plus de facture qui dérape à cause de quelques requêtes routées vers un modèle premium sans que je l&rsquo;aie demandé.</p>



<p class="wp-block-paragraph">Pour un agent qui tourne 24/7 sur du matériel perso, c&rsquo;est exactement ce que je cherchais : un coût plat, une seule clé, et assez de modèles pour ne jamais être bloqué.</p>



<h2 class="wp-block-heading">Je n&rsquo;abandonne pas OpenRouter pour autant</h2>



<p class="wp-block-paragraph">Important : OpenCode Go remplace OpenRouter pour le <strong>cerveau texte</strong> de mon agent, pas pour tout le reste. Je garde OpenRouter en parallèle, et il garde tout son sens pour des usages plus spécialisés : le TTS, la génération d&rsquo;image et la génération de vidéo. C&rsquo;est devenu un vrai hub multimodal, là où le paiement à l&rsquo;usage reste le bon modèle, on ne génère pas une vidéo toutes les cinq minutes.</p>



<p class="wp-block-paragraph">En vidéo justement, je travaille beaucoup en local sur ma machine principale (ComfyUI, GPU dédié). LTX et Wan sont d&rsquo;excellents modèles open source, largement suffisants pour la plupart de mes besoins, et gratuits une fois le matériel amorti.</p>



<p class="wp-block-paragraph">Mais soyons honnêtes : quand je veux le résultat au-dessus du lot, un Seedance 2.0 reste exceptionnel. C&rsquo;est là que le cloud garde l&rsquo;avantage  pour ces générations ponctuelles où la qualité prime sur le coût. D&rsquo;où l&rsquo;intérêt de garder une porte ouverte sur OpenRouter, qui donne accès à ce genre de modèle sous la même clé.</p>



<p class="wp-block-paragraph">La bonne architecture, pour moi, n&rsquo;est donc pas « tout cloud » ni « tout local ». C&rsquo;est : <strong>OpenCode Go pour le LLM de l&rsquo;agent</strong> (coût fixe, prévisible), <strong>le local pour le gros du multimodal</strong> (LTX, Wan), et <strong>OpenRouter en appoint</strong> pour le TTS et les générations haut de gamme comme Seedance 2.0.</p>



<h2 class="wp-block-heading">En résumé</h2>



<p class="wp-block-paragraph">Si votre conso OpenRouter en LLM dépasse régulièrement 10 $/mois, basculer le cerveau de votre agent vers OpenCode Go est vite rentable. En dessous, restez sur le paiement à l&rsquo;usage vous paierez moins. Et dans les deux cas, gardez OpenRouter sous la main pour ce qu&rsquo;il fait désormais très bien : le multimodal à la demande.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://tazmenworld.com/2026/06/09/jai-quitte-openrouter-pour-opencode-go-ce-que-ca-change-vraiment-sur-la-facture/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Pourquoi acheter un Mac mini ? Alors qu&#8217;un mini PC à 130€ fait tourner Hermes Agent 24h/24 aussi bien</title>
		<link>https://tazmenworld.com/2026/06/05/pourquoi-acheter-un-mac-mini-alors-quun-mini-pc-a-130e-fait-tourner-hermes-agent-24h-24-aussi-bien/</link>
					<comments>https://tazmenworld.com/2026/06/05/pourquoi-acheter-un-mac-mini-alors-quun-mini-pc-a-130e-fait-tourner-hermes-agent-24h-24-aussi-bien/#respond</comments>
		
		<dc:creator><![CDATA[tazmen3]]></dc:creator>
		<pubDate>Fri, 05 Jun 2026 13:54:20 +0000</pubDate>
				<category><![CDATA[Non classé]]></category>
		<guid isPermaLink="false">https://tazmenworld.com/?p=296</guid>

					<description><![CDATA[Depuis quelques mois, je vois passer beaucoup de publications et de vidéos YouTube qui expliquent qu&#8217;il faut un Mac mini ou un VPS pour faire tourner un agent autonome comme OpenClow ou Hermes Agent. 700€ la machine, ou un abonnement mensuel qui part indéfiniment. Et en y réfléchissant bien, à ce qu&#8217;on leur demande concrètement [&#8230;]]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-large"><img width="1024" height="569"  alt="" class="wp-image-307"/ loading="lazy" decoding="async" src="https://tazmenworld.com/wp-content/uploads/2026/06/mac-vs-n150v2-1024x569.jpg" srcset="https://tazmenworld.com/wp-content/uploads/2026/06/mac-vs-n150v2-1024x569.jpg 1024w, https://tazmenworld.com/wp-content/uploads/2026/06/mac-vs-n150v2-300x167.jpg 300w, https://tazmenworld.com/wp-content/uploads/2026/06/mac-vs-n150v2-768x427.jpg 768w, https://tazmenworld.com/wp-content/uploads/2026/06/mac-vs-n150v2-1536x854.jpg 1536w, https://tazmenworld.com/wp-content/uploads/2026/06/mac-vs-n150v2.jpg 1682w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">Depuis quelques mois, je vois passer beaucoup de publications et de vidéos YouTube qui expliquent qu&rsquo;il faut un Mac mini ou un VPS pour faire tourner un agent autonome comme OpenClow ou Hermes Agent. 700€ la machine, ou un abonnement mensuel qui part indéfiniment. Et en y réfléchissant bien, à ce qu&rsquo;on leur demande concrètement : tourner 24h/24, attendre des messages Telegram, exécuter des workflows la nuit pendant qu&rsquo;on dort. Pas de l&rsquo;inférence lourde, pas de rendu 3D. Juste orchestrer et déléguer.</p>



<p class="wp-block-paragraph">Je vais te montrer une autre voie : un mini PC à 130€, moins gourmand, moins cher, qui fait exactement le même boulot.</p>



<p class="wp-block-paragraph">Cette machine tourne sans écran ni clavier depuis plusieurs semaines chez moi. Elle reçoit mes ordres par Telegram, exécute des tâches en arrière-plan, et s&rsquo;appuie sur ma machine principale ou OpenRouter quand elle a besoin de compute. C&rsquo;est le <strong>control plan permanent</strong> du setup, pas la brute de calcul.</p>



<p class="wp-block-paragraph">Voilà comment j&rsquo;ai fait, brique par brique, avec les détails d&rsquo;installation que j&rsquo;aurais aimé trouver en un seul endroit.</p>



<figure class="wp-block-image size-full"><img width="1020" height="768"  alt="" class="wp-image-297"/ loading="lazy" decoding="async" src="https://tazmenworld.com/wp-content/uploads/2026/06/PXL_20260604_155539924.jpg" srcset="https://tazmenworld.com/wp-content/uploads/2026/06/PXL_20260604_155539924.jpg 1020w, https://tazmenworld.com/wp-content/uploads/2026/06/PXL_20260604_155539924-300x226.jpg 300w, https://tazmenworld.com/wp-content/uploads/2026/06/PXL_20260604_155539924-768x578.jpg 768w" sizes="auto, (max-width: 1020px) 100vw, 1020px" /></figure>



<h2 class="wp-block-heading">1. Le matos et pourquoi pas autre chose</h2>



<h3 class="wp-block-heading">Le mini PC : MLLSE G2 Pro</h3>



<p class="wp-block-paragraph">Intel N150, 12 Go de LPDDR5, 512 Go de SSD, WiFi 5, Bluetooth 5.0. Windows 11 Pro pré-installé, que j&rsquo;ai remplacé par du Linux en dix minutes.</p>



<p class="wp-block-paragraph">Le N150 est un quad-core basse consommation. Il ne va pas faire tourner un Llama 70B en local. Ce n&rsquo;est pas son rôle. Son rôle, c&rsquo;est d&rsquo;être <strong>sobre et toujours allumé</strong>. Sous charge normale de serveur, il tire <strong>9W</strong>. C&rsquo;est ridicule. Une ampoule LED de bureau en consomme davantage. Ramené à l&rsquo;année entière, ça représente environ <strong>8€ d&rsquo;électricité</strong> pour un serveur qui tourne 24h/24, à comparer aux 180€ d&rsquo;un VPS entrée de gamme sur la même période, rien qu&rsquo;en abonnement. Le chassis est conçu pour un usage permanent : pas de batterie qui gonfle, pas de ventilo qui s&rsquo;encrasse.</p>



<h3 class="wp-block-heading">Pourquoi pas un VPS cloud ?</h3>



<p class="wp-block-paragraph">5€/mois, ça paraît rien. Sur trois ans, tu as payé 180€ pour une machine qui n&rsquo;est pas chez toi, qui ne voit pas ton réseau local, et qui te facture chaque byte de trafic sortant. Mon agent IA a besoin de parler à Ollama sur ma machine principale, à ComfyUI, à SearXNG. Avec un VPS, tout ça passerait soit par internet (latence plus coût), soit par un tunnel VPN. Avec un mini PC sur le LAN, c&rsquo;est une simple requête HTTP sur le réseau interne. Pas de souci.</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th></th><th>Mini PC local</th><th>VPS cloud</th></tr></thead><tbody><tr><td>Coût d&rsquo;entrée</td><td>130€ une fois</td><td>0€</td></tr><tr><td>Abonnement mensuel</td><td>0€</td><td>5 à 15€/mois</td></tr><tr><td>Coût total sur 3 ans</td><td>~154€ (matériel + élec)</td><td>180 à 540€</td></tr><tr><td>Accès réseau local</td><td>✅ Natif, zéro config</td><td>❌ Tunnel VPN requis</td></tr><tr><td>Latence vers Ollama, ComfyUI</td><td>&lt; 1ms (LAN)</td><td>20 à 100ms+</td></tr><tr><td>Données chez soi</td><td>✅</td><td>❌ Chez le prestataire</td></tr><tr><td>Coupure si impayé</td><td>Non</td><td>Oui</td></tr><tr><td>Upgrade RAM / SSD</td><td>✅ Possible</td><td>Dépend de l&rsquo;offre</td></tr><tr><td>Accès admin complet</td><td>✅ Root physique</td><td>✅ Root SSH</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">Le mini PC coûte plus cher le premier jour. Il est moins cher dès le quatorzième mois, et il reste sur ton réseau.</p>



<h3 class="wp-block-heading">Pourquoi pas un vieux laptop ?</h3>



<p class="wp-block-paragraph">Un laptop qui tourne 24h/24, c&rsquo;est une batterie qui gonfle dans les douze mois, un ventilo qui accumule de la poussière, et une consommation 3 à 5× supérieure au mini PC. La machine n&rsquo;est pas faite pour ça. Le mini PC, si.</p>



<h3 class="wp-block-heading">Pourquoi pas le Mac mini M4 à 700€ ?</h3>



<p class="wp-block-paragraph">Parce que le gros calcul, je l&rsquo;ai déjà : Ryzen 9 + RTX 5070 Ti sur ma machine principale. Ce que je cherche ici, c&rsquo;est un <strong>orchestrateur sobre et permanent</strong> qui sait déléguer. La même logique headless que partout ailleurs : mettre le bon outil au bon endroit, ne pas gâcher la ressource. Le Mac mini ferait la même chose six fois plus cher.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">2. La stack : ce qu&rsquo;on installe et pourquoi chaque brique</h2>



<p class="wp-block-paragraph">Avant le détail de l&rsquo;installation, une vue d&rsquo;ensemble de l&rsquo;architecture cible.</p>



<p class="wp-block-paragraph">[SCHÉMA : tazmenworld ↔ autoserver ↔ Telegram ↔ internet]</p>



<figure class="wp-block-image size-large"><img width="1024" height="936"  alt="" class="wp-image-310"/ loading="lazy" decoding="async" src="https://tazmenworld.com/wp-content/uploads/2026/06/image-1-1024x936.png" srcset="https://tazmenworld.com/wp-content/uploads/2026/06/image-1-1024x936.png 1024w, https://tazmenworld.com/wp-content/uploads/2026/06/image-1-300x274.png 300w, https://tazmenworld.com/wp-content/uploads/2026/06/image-1-768x702.png 768w, https://tazmenworld.com/wp-content/uploads/2026/06/image-1.png 1205w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">Le control plan (<code>autoserver</code>) décide et orchestre. Le compute (<code>tazmenworld</code>) calcule. La seule sortie cloud : les appels LLM vers OpenRouter. C&rsquo;est du <strong>pay-per-use</strong>, pas un abonnement fixe. À l&rsquo;usage courant, quelques dizaines de requêtes par jour sur DeepSeek V4, ça se chiffre en centimes. Tout le reste reste sur le réseau local.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">3. Ubuntu Server 26.04 LTS : le socle headless</h2>



<p class="wp-block-paragraph">Pas d&rsquo;interface graphique. C&rsquo;est un serveur, il vit en console. On choisit <strong>Ubuntu Server 26.04 LTS « Resolute Raccoon »</strong>, supporté jusqu&rsquo;en 2031 (2036 avec Ubuntu Pro, gratuit jusqu&rsquo;à 5 machines personnelles).</p>



<h3 class="wp-block-heading">Créer la clé USB depuis tazmenworld</h3>



<p class="wp-block-paragraph">bash</p>



<pre class="wp-block-code"><code>cd ~/Downloads
wget https://releases.ubuntu.com/26.04/ubuntu-26.04-live-server-amd64.iso

# Identifier la clé USB
lsblk

# Écrire l'image (remplace /dev/sdX, ATTENTION : tout sera effacé)
sudo dd if=ubuntu-26.04-live-server-amd64.iso of=/dev/sdX bs=4M status=progress conv=fsync
sync</code></pre>



<h3 class="wp-block-heading">Options d&rsquo;installation qui comptent</h3>



<p class="wp-block-paragraph">On démarre sur la clé (touche <strong>F7</strong> ou <strong>Del</strong> au boot pour le menu), puis dans l&rsquo;installeur Subiquity :</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>Étape</th><th>Choix</th></tr></thead><tbody><tr><td>Type d&rsquo;installation</td><td><strong>Ubuntu Server (minimized)</strong>, moins de paquets, moins de RAM grignotée</td></tr><tr><td>Réseau</td><td>DHCP pour l&rsquo;instant, on passe en IP statique après</td></tr><tr><td>Stockage</td><td><strong>Use entire disk</strong>, pas de LVM pour simplifier</td></tr><tr><td>Nom du serveur</td><td><code>autoserver</code></td></tr><tr><td><strong>OpenSSH</strong></td><td>✅ <strong>À cocher absolument</strong>, sinon tu ne peux plus te connecter à distance</td></tr><tr><td>Snaps additionnels</td><td>Rien, on installe tout manuellement</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">Une fois installé, on retire la clé USB, on redémarre. La machine boote en console texte. C&rsquo;est normal, c&rsquo;est voulu.</p>



<h3 class="wp-block-heading">Mise à jour complète et outils de base</h3>



<p class="wp-block-paragraph">bash</p>



<pre class="wp-block-code"><code>sudo apt update &amp;&amp; sudo apt upgrade -y
sudo apt autoremove -y

sudo apt install -y \
  curl wget git nano htop net-tools \
  ca-certificates gnupg lsb-release \
  ufw fail2ban unattended-upgrades \
  tree jq ncdu

sudo reboot</code></pre>



<h3 class="wp-block-heading">IP statique via Netplan</h3>



<p class="wp-block-paragraph">Un serveur ne peut pas changer d&rsquo;IP à chaque redémarrage. On configure une IP fixe via Netplan, mais avant d&rsquo;écrire quoi que ce soit, on vérifie <strong>la vraie adresse de la passerelle</strong>. Sur ton réseau, elle n&rsquo;est pas forcément <code>192.168.1.1</code>. La vérifier d&rsquo;abord sur <code>tazmenworld</code> :</p>



<p class="wp-block-paragraph">bash</p>



<pre class="wp-block-code"><code>ip route | grep default
# Exemple : default via 192.168.1.254 dev enp14s0
#                       ↑ c'est cette IP qu'on met dans netplan</code></pre>



<p class="wp-block-paragraph">Puis on identifie l&rsquo;interface réseau sur <code>autoserver</code> :</p>



<p class="wp-block-paragraph">bash</p>



<pre class="wp-block-code"><code>ip link show
# Exemple : enp2s0 (Ethernet), préférer l'Ethernet au WiFi pour un serveur</code></pre>



<p class="wp-block-paragraph">On édite la config :</p>



<p class="wp-block-paragraph">bash</p>



<pre class="wp-block-code"><code>sudo nano /etc/netplan/00-installer-config.yaml</code></pre>



<p class="wp-block-paragraph">yaml</p>



<pre class="wp-block-code"><code>network:
  version: 2
  renderer: networkd
  ethernets:
    enp2s0:                        # adapter à ton interface
      addresses:
        - 192.168.1.20/24
      routes:
        - to: default
          via: 192.168.1.254       # ta vraie passerelle, pas une supposée
      nameservers:
        addresses: &#91;1.1.1.1, 8.8.8.8]
      dhcp4: <strong>false</strong></code></pre>



<p class="wp-block-paragraph">On applique et on vérifie :</p>



<p class="wp-block-paragraph">bash</p>



<pre class="wp-block-code"><code>sudo netplan apply
ip addr show enp2s0        # l'IP 192.168.1.20 doit apparaître
ping -c 3 1.1.1.1          # si ça ne répond pas → passerelle incorrecte
ping -c 3 tazmenworld      # joignabilité réseau local</code></pre>



<h3 class="wp-block-heading">Synchronisation horaire</h3>



<p class="wp-block-paragraph">bash</p>



<pre class="wp-block-code"><code>sudo timedatectl set-timezone Europe/Paris
timedatectl status
# "System clock synchronized: yes" doit apparaître</code></pre>



<h3 class="wp-block-heading">Sécurisation SSH</h3>



<p class="wp-block-paragraph">On génère une paire de clés ed25519 sur <code>tazmenworld</code> :</p>



<p class="wp-block-paragraph">bash</p>



<pre class="wp-block-code"><code>ssh-keygen -t ed25519 -C "tazmenworld→autoserver" -f ~/.ssh/autoserver_key</code></pre>



<p class="wp-block-paragraph">On copie la clé publique sur <code>autoserver</code> (avec le mot de passe temporaire) :</p>



<p class="wp-block-paragraph">bash</p>



<pre class="wp-block-code"><code>ssh-copy-id -i ~/.ssh/autoserver_key.pub &lt;votre_user&gt;@192.168.1.20</code></pre>



<p class="wp-block-paragraph">On teste la connexion par clé :</p>



<p class="wp-block-paragraph">bash</p>



<pre class="wp-block-code"><code>ssh -i ~/.ssh/autoserver_key &lt;votre_user&gt;@192.168.1.20</code></pre>



<p class="wp-block-paragraph">Puis on durcit la config SSH sur <code>autoserver</code> :</p>



<p class="wp-block-paragraph">bash</p>



<pre class="wp-block-code"><code>sudo nano /etc/ssh/sshd_config</code></pre>



<pre class="wp-block-code"><code>Port 2222
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
MaxAuthTries 3
LoginGraceTime 30
AllowUsers &lt;votre_user&gt;
X11Forwarding no</code></pre>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>Spécificité Ubuntu 26.04, deux points à ne pas rater :</strong></p>



<p class="wp-block-paragraph"><strong>1. X11Forwarding en double.</strong> Le fichier par défaut contient souvent <code>X11Forwarding yes</code> plus haut. Commente cette ligne, sinon ta ligne <code>no</code> en bas sera ignorée.</p>



<p class="wp-block-paragraph"><strong>2. Socket activation.</strong> Ubuntu 26.04 gère le port SSH via <code>ssh.socket</code>. Un simple <code>restart ssh</code> ne suffit pas :</p>



<p class="wp-block-paragraph">bash</p>



<pre class="wp-block-code"><code>sudo systemctl daemon-reload
sudo systemctl restart ssh.socket</code></pre>
</blockquote>



<p class="wp-block-paragraph"><strong>⚠️ Teste depuis un deuxième terminal avant de fermer ta session actuelle :</strong></p>



<p class="wp-block-paragraph">bash</p>



<pre class="wp-block-code"><code># Depuis tazmenworld, nouveau terminal
ssh -i ~/.ssh/autoserver_key -p 2222 &lt;votre_user&gt;@192.168.1.20</code></pre>



<p class="wp-block-paragraph">Si ça passe, on peut fermer l&rsquo;ancienne session. On configure ensuite un profil SSH sur <code>tazmenworld</code> pour ne plus jamais taper l&rsquo;IP :</p>



<p class="wp-block-paragraph">bash</p>



<pre class="wp-block-code"><code>nano ~/.ssh/config</code></pre>



<pre class="wp-block-code"><code>Host autoserver
    HostName 192.168.1.20
    Port 2222
    User &lt;votre_user&gt;
    IdentityFile ~/.ssh/autoserver_key
    ServerAliveInterval 60</code></pre>



<p class="wp-block-paragraph">Désormais : <code>ssh autoserver</code>. C&rsquo;est tout.</p>



<h3 class="wp-block-heading">Pare-feu UFW et Fail2ban</h3>



<p class="wp-block-paragraph">bash</p>



<pre class="wp-block-code"><code># Règles UFW
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 2222/tcp comment "SSH"
sudo ufw allow 5678/tcp comment "n8n"
sudo ufw allow from 192.168.1.0/24 comment "Réseau local"
sudo ufw enable
sudo ufw status verbose</code></pre>



<p class="wp-block-paragraph">bash</p>



<pre class="wp-block-code"><code># Fail2ban, bannissement auto des tentatives de brute-force
sudo nano /etc/fail2ban/jail.local</code></pre>



<p class="wp-block-paragraph">ini</p>



<pre class="wp-block-code"><code>&#91;DEFAULT]
bantime  = 3600
findtime = 600
maxretry = 3

&#91;sshd]
enabled  = true
port     = 2222
logpath  = /var/log/auth.log</code></pre>



<p class="wp-block-paragraph">bash</p>



<pre class="wp-block-code"><code>sudo systemctl enable --now fail2ban
sudo fail2ban-client status sshd</code></pre>



<h3 class="wp-block-heading">Mises à jour automatiques de sécurité</h3>



<p class="wp-block-paragraph">bash</p>



<pre class="wp-block-code"><code>sudo dpkg-reconfigure --priority=low unattended-upgrades
# → Yes</code></pre>



<p class="wp-block-paragraph">Le serveur se patche tout seul sur les failles de sécurité. On n&rsquo;a plus à y penser.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">4. Docker : l&rsquo;isolement propre</h2>



<p class="wp-block-paragraph">Pour n8n, on containerise. Docker isole le service, simplifie les mises à jour, et évite de polluer le système hôte.</p>



<p class="wp-block-paragraph"><strong>Note Ubuntu 26.04 :</strong> Resolute Raccoon a supprimé le support de cgroup v1. Docker le gère nativement depuis la v20.10, mais il faut impérativement passer par le <strong>dépôt officiel Docker</strong>, pas le paquet <code>docker.io</code> des dépôts Ubuntu qui est souvent en retard.</p>



<h3 class="wp-block-heading">Installation Docker CE (méthode officielle)</h3>



<p class="wp-block-paragraph">bash</p>



<pre class="wp-block-code"><code># Supprimer d'éventuelles vieilles versions
sudo apt remove -y docker docker-engine docker.io containerd runc <strong>2</strong>&gt;/dev/null

# Clés GPG et dépôt officiel Docker
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
  | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

echo \
  "deb &#91;arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
  https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release &amp;&amp; echo "$VERSION_CODENAME") stable" \
  | sudo tee /etc/apt/sources.list.d/docker.list &gt; /dev/null

sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io \
                    docker-buildx-plugin docker-compose-plugin</code></pre>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>Si <code>apt update</code> échoue</strong> avec une erreur sur le codename <code>resolute</code> : le dépôt Docker n&rsquo;a peut-être pas encore indexé 26.04. Solution : forcer le codename <code>noble</code> (24.04), les paquets sont compatibles.</p>



<p class="wp-block-paragraph">bash</p>



<pre class="wp-block-code"><code>echo \
  "deb &#91;arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
  https://download.docker.com/linux/ubuntu noble stable" \
  | sudo tee /etc/apt/sources.list.d/docker.list &gt; /dev/null
sudo apt update</code></pre>
</blockquote>



<h3 class="wp-block-heading">Ajouter l&rsquo;utilisateur au groupe docker</h3>



<p class="wp-block-paragraph">bash</p>



<pre class="wp-block-code"><code>sudo usermod -aG docker &lt;votre_user&gt;</code></pre>



<p class="wp-block-paragraph"><strong>Piège sur install minimized :</strong> <code>newgrp</code> n&rsquo;est pas disponible. Le groupe ne s&rsquo;active pas dans la session en cours. Tu dois te déconnecter et te reconnecter, sans message d&rsquo;erreur explicite, juste un <code>permission denied</code> silencieux sur <code>docker run</code> si tu oublies ce détail.</p>



<p class="wp-block-paragraph">bash</p>



<pre class="wp-block-code"><code>exit
# puis : ssh autoserver

# Tester depuis la nouvelle session
docker run --rm hello-world
docker compose version</code></pre>



<h3 class="wp-block-heading">Configurer le daemon Docker</h3>



<p class="wp-block-paragraph">bash</p>



<pre class="wp-block-code"><code>sudo nano /etc/docker/daemon.json</code></pre>



<p class="wp-block-paragraph">json</p>



<pre class="wp-block-code"><code>{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  },
  "default-address-pools": &#91;
    {"base": "172.20.0.0/16", "size": 24}
  ]
}</code></pre>



<p class="wp-block-paragraph">bash</p>



<pre class="wp-block-code"><code>sudo systemctl restart docker
docker info | grep -i "log driver"
# Attendu : Logging Driver: json-file</code></pre>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">5. Structure des répertoires</h2>



<p class="wp-block-paragraph">bash</p>



<pre class="wp-block-code"><code>sudo mkdir -p /opt/autoserver/{n8n,hermes,shared,backups}
sudo chown -R &lt;votre_user&gt;:&lt;votre_user&gt; /opt/autoserver</code></pre>



<pre class="wp-block-code"><code>/opt/autoserver/
├── n8n/
│   ├── docker-compose.yml
│   ├── .env
│   └── data/            ← volume persistant n8n
├── hermes/
│   └── data/
├── shared/              ← fichiers échangés entre services
└── backups/             ← sauvegardes automatiques</code></pre>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">6. n8n : le moteur de workflows</h2>



<p class="wp-block-paragraph">n8n, c&rsquo;est le chef d&rsquo;orchestre des automatisations que tu as câblées. Il sait : « à 7h chaque matin, lance cette recherche ; si tel webhook arrive, déclenche ce traitement ». Interface visuelle, scriptable, il se connecte à des centaines de services.</p>



<h3 class="wp-block-heading">Fichier d&rsquo;environnement</h3>



<p class="wp-block-paragraph">bash</p>



<pre class="wp-block-code"><code>nano /opt/autoserver/n8n/.env</code></pre>



<p class="wp-block-paragraph">env</p>



<pre class="wp-block-code"><code># Réseau
N8N_HOST=0.0.0.0
N8N_PORT=5678
N8N_PROTOCOL=http
WEBHOOK_URL=http://192.168.1.20:5678/

# Sécurité
N8N_ENCRYPTION_KEY=&lt;générer_avec_openssl_rand_-hex_16&gt;
GENERIC_TIMEZONE=Europe/Paris
NODE_ENV=production

# Indispensable en HTTP local, voir section "pièges"
N8N_SECURE_COOKIE=false

# Désactiver la télémétrie (évite des erreurs réseau parasites dans les logs)
N8N_DIAGNOSTICS_ENABLED=false
N8N_VERSION_NOTIFICATIONS_ENABLED=false

# Connexion Ollama sur tazmenworld
OLLAMA_BASE_URL=http://192.168.1.100:11434</code></pre>



<p class="wp-block-paragraph">Pour générer une clé d&rsquo;encryption solide :</p>



<p class="wp-block-paragraph">bash</p>



<pre class="wp-block-code"><code>openssl rand -hex 16</code></pre>



<h3 class="wp-block-heading">Docker Compose n8n</h3>



<p class="wp-block-paragraph">bash</p>



<pre class="wp-block-code"><code>nano /opt/autoserver/n8n/docker-compose.yml</code></pre>



<p class="wp-block-paragraph">yaml</p>



<pre class="wp-block-code"><code>services:
  n8n:
    image: n8nio/n8n:latest
    container_name: n8n
    restart: unless-stopped
    ports:
      - "5678:5678"
    env_file:
      - .env
    volumes:
      - ./data:/home/node/.n8n
      - /opt/autoserver/shared:/shared
    networks:
      - autoserver_net
    extra_hosts:
      - "tazmenworld:192.168.1.100"

networks:
  autoserver_net:
    name: autoserver_net
    driver: bridge</code></pre>



<p class="wp-block-paragraph">Le <code>extra_hosts</code> permet d&rsquo;appeler <code>http://tazmenworld:11434</code> depuis les workflows n8n au lieu d&rsquo;une IP brute : plus lisible, et ça survit à un changement d&rsquo;IP sans tout recâbler.</p>



<h3 class="wp-block-heading">Fix permissions du volume (indispensable)</h3>



<p class="wp-block-paragraph">n8n tourne dans son container sous l&rsquo;utilisateur <code>node</code> (UID 1000). Si le dossier <code>data</code> appartient à root, il ne peut pas écrire et <strong>crashe en boucle</strong> dès le démarrage sans message clair.</p>



<p class="wp-block-paragraph">bash</p>



<pre class="wp-block-code"><code>sudo chown -R 1000:1000 /opt/autoserver/n8n/data</code></pre>



<h3 class="wp-block-heading">Autoriser Docker à sortir sur internet (UFW)</h3>



<p class="wp-block-paragraph">Par défaut, UFW bloque le forwarding des containers. n8n démarre correctement, mais tout appel HTTP externe échoue en silence : les workflows ne peuvent pas joindre d&rsquo;API extérieure.</p>



<p class="wp-block-paragraph">bash</p>



<pre class="wp-block-code"><code>sudo nano /etc/default/ufw
# Changer cette ligne :
# DEFAULT_FORWARD_POLICY="DROP"  →  DEFAULT_FORWARD_POLICY="ACCEPT"

sudo ufw reload</code></pre>



<h3 class="wp-block-heading">Lancer n8n</h3>



<p class="wp-block-paragraph">bash</p>



<pre class="wp-block-code"><code>cd /opt/autoserver/n8n
docker compose up -d
docker compose logs -f     # Ctrl+C pour quitter</code></pre>



<p class="wp-block-paragraph">Quand tu vois <code>n8n ready on ::, port 5678</code>, l&rsquo;interface est accessible depuis <code>tazmenworld</code> via <code>http://192.168.1.20:5678</code>.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">7. Hermes Agent : l&rsquo;IA qui décide seule</h2>



<p class="wp-block-paragraph">C&rsquo;est la brique qui fait passer le setup d&rsquo;un serveur d&rsquo;automatisation classique à un <strong>agent IA autonome</strong>. Hermes Agent est un projet open-source de Nous Research (licence MIT) : mémoire persistante entre les sessions, génération de ses propres skills, terminal sandboxé sous Docker, et gateway Telegram intégré. Là où n8n exécute des rails que tu as tracés, Hermes reçoit un objectif et se débrouille.</p>



<h3 class="wp-block-heading">Installation</h3>



<p class="wp-block-paragraph">bash</p>



<pre class="wp-block-code"><code>curl -fsSL https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.sh | bash</code></pre>



<p class="wp-block-paragraph">Le script gère tout : Python 3.11, Node.js 22, ripgrep, ffmpeg. Il lance ensuite automatiquement le wizard de configuration.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>Prérequis :</strong> internet doit être accessible depuis <code>autoserver</code>. Si <code>curl -I https://github.com</code> répond <code>No route to host</code>, tu as un problème de passerelle dans Netplan. Voir la section sur l&rsquo;IP statique.</p>
</blockquote>



<h3 class="wp-block-heading">Configuration via le wizard</h3>



<figure class="wp-block-image size-large"><img width="1024" height="712"  alt="" class="wp-image-303"/ loading="lazy" decoding="async" src="https://tazmenworld.com/wp-content/uploads/2026/06/Capture-decran-du-2026-06-04-22-09-37-1024x712.png" srcset="https://tazmenworld.com/wp-content/uploads/2026/06/Capture-decran-du-2026-06-04-22-09-37-1024x712.png 1024w, https://tazmenworld.com/wp-content/uploads/2026/06/Capture-decran-du-2026-06-04-22-09-37-300x208.png 300w, https://tazmenworld.com/wp-content/uploads/2026/06/Capture-decran-du-2026-06-04-22-09-37-768x534.png 768w, https://tazmenworld.com/wp-content/uploads/2026/06/Capture-decran-du-2026-06-04-22-09-37.png 1498w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">Les choix qui importent :</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>Étape</th><th>Choix</th></tr></thead><tbody><tr><td>Backend LLM</td><td><strong>OpenRouter</strong>, pour requêter DeepSeek V4</td></tr><tr><td>Clé API OpenRouter</td><td><code>sk-or-v1-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx</code></td></tr><tr><td>Modèle</td><td><code>deepseek/deepseek-v4</code></td></tr><tr><td>Outils</td><td>Tout cocher ✅ (web search, génération d&rsquo;image, browser, terminal)</td></tr><tr><td>Terminal backend</td><td><strong>Docker</strong>, sandbox isolé, propre</td></tr><tr><td>Messaging</td><td><strong>Set up messaging now</strong> → Telegram</td></tr><tr><td>Type de service</td><td><strong>System service</strong>, démarre au boot sans session ouverte</td></tr></tbody></table></figure>



<figure class="wp-block-image size-large"><img width="1024" height="764"  alt="" class="wp-image-301"/ loading="lazy" decoding="async" src="https://tazmenworld.com/wp-content/uploads/2026/06/Capture-decran-du-2026-06-04-22-21-58-1024x764.png" srcset="https://tazmenworld.com/wp-content/uploads/2026/06/Capture-decran-du-2026-06-04-22-21-58-1024x764.png 1024w, https://tazmenworld.com/wp-content/uploads/2026/06/Capture-decran-du-2026-06-04-22-21-58-300x224.png 300w, https://tazmenworld.com/wp-content/uploads/2026/06/Capture-decran-du-2026-06-04-22-21-58-768x573.png 768w, https://tazmenworld.com/wp-content/uploads/2026/06/Capture-decran-du-2026-06-04-22-21-58.png 1505w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<figure class="wp-block-image size-large"><img width="1024" height="601"  alt="" class="wp-image-302"/ loading="lazy" decoding="async" src="https://tazmenworld.com/wp-content/uploads/2026/06/Capture-decran-du-2026-06-04-22-26-22-1024x601.png" srcset="https://tazmenworld.com/wp-content/uploads/2026/06/Capture-decran-du-2026-06-04-22-26-22-1024x601.png 1024w, https://tazmenworld.com/wp-content/uploads/2026/06/Capture-decran-du-2026-06-04-22-26-22-300x176.png 300w, https://tazmenworld.com/wp-content/uploads/2026/06/Capture-decran-du-2026-06-04-22-26-22-768x451.png 768w, https://tazmenworld.com/wp-content/uploads/2026/06/Capture-decran-du-2026-06-04-22-26-22.png 1505w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<h3 class="wp-block-heading">Configurer le bot Telegram</h3>



<ol class="wp-block-list">
<li>Ouvre Telegram, cherche <code>@BotFather</code> → <code>/newbot</code></li>



<li>Donne un nom et un identifiant à ton bot</li>



<li>Récupère le token : <code>123456789:AAH-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx</code></li>



<li>Cherche <code>@userinfobot</code> → note ton User ID numérique</li>



<li>Renseigne le token et l&rsquo;User ID dans le wizard</li>



<li>Réponds <strong>Y</strong> pour le Home Channel (DM direct avec le bot)</li>



<li>Réponds <strong>Y</strong> pour installer comme service en arrière-plan</li>
</ol>



<h3 class="wp-block-heading">Activer le linger : le détail qui rend le setup vraiment autonome</h3>



<p class="wp-block-paragraph">Le gateway Telegram tourne en <strong>user service</strong> systemd. Sans cette configuration, il ne démarre pas au boot si aucune session utilisateur n&rsquo;est ouverte. Résultat : après une coupure de courant à 3h du matin, ton agent reste silencieux jusqu&rsquo;à ce que quelqu&rsquo;un se connecte en SSH.</p>



<p class="wp-block-paragraph">bash</p>



<pre class="wp-block-code"><code>sudo loginctl enable-linger &lt;votre_user&gt;

# Vérifier
loginctl show-user &lt;votre_user&gt; | grep Linger
# Attendu : Linger=yes</code></pre>



<p class="wp-block-paragraph">Une fois activé, le serveur peut redémarrer seul : le gateway Telegram revient en ligne sans intervention de ta part.</p>



<h3 class="wp-block-heading">Vérification et commandes utiles</h3>



<p class="wp-block-paragraph">bash</p>



<pre class="wp-block-code"><code># Statut du gateway
systemctl --user status hermes-gateway

# Test CLI interactif
source ~/.bashrc
hermes
&gt; Bonjour, que peux-tu faire sur ce serveur ?

# Changer de modèle à chaud, sans redémarrage
hermes setup model

# Mettre à jour
hermes update

# Diagnostic complet
hermes doctor</code></pre>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">8. Intégration avec la stack de tazmenworld</h2>



<p class="wp-block-paragraph">Depuis n8n ou Hermes sur <code>autoserver</code>, tous les services de <code>tazmenworld</code> sont accessibles directement par IP locale :</p>



<pre class="wp-block-code"><code>Ollama        → http://192.168.1.100:11434
Open WebUI    → http://192.168.1.100:3000
ComfyUI       → http://192.168.1.100:8188
SearXNG       → http://192.168.1.100:8080
n8n principal → http://192.168.1.100:5678</code></pre>



<p class="wp-block-paragraph">Pour centraliser ça proprement :</p>



<p class="wp-block-paragraph">bash</p>



<pre class="wp-block-code"><code>nano /opt/autoserver/.env.global</code></pre>



<p class="wp-block-paragraph">env</p>



<pre class="wp-block-code"><code>TAZMENWORLD_IP=192.168.1.100
AUTOSERVER_IP=192.168.1.20

OLLAMA_URL=http://192.168.1.100:11434
OPENWEBUI_URL=http://192.168.1.100:3000
COMFYUI_URL=http://192.168.1.100:8188
SEARXNG_URL=http://192.168.1.100:8080
N8N_TAZMEN_URL=http://192.168.1.100:5678

OPENROUTER_BASE_URL=https://openrouter.ai/api/v1
OPENROUTER_API_KEY=sk-or-v1-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx</code></pre>



<p class="wp-block-paragraph">Et les deux instances n8n peuvent se parler : depuis <code>autoserver</code>, un nœud <strong>HTTP Request</strong> vers <code>http://192.168.1.100:5678/webhook/&lt;ton-webhook-id&gt;</code> déclenche un workflow sur <code>tazmenworld</code>. Les deux instances bossent ensemble.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">9. Hermes en action : la démo Telegram</h2>



<p class="wp-block-paragraph">Là où n8n exécute des rails que tu as tracés, Hermes reçoit un <strong>objectif en langage naturel</strong> et se débrouille pour l&rsquo;atteindre. Sa mémoire persistante lui permet de se souvenir des échanges précédents et d&rsquo;ajuster son comportement au fil du temps.</p>



<p class="wp-block-paragraph">Exemple concret, hier soir depuis le téléphone :</p>



<pre class="wp-block-code"><code>Moi :    Fais une veille sur les modèles open-weight sortis cette semaine.
         Résume les 5 plus intéressants en 3 lignes chacun et dépose
         le résumé dans /shared/veille.md

Hermes : Je lance les recherches. Je te préviens quand c'est déposé.

&#91;quelques minutes plus tard]

Hermes : ✅ Résumé déposé dans /shared/veille.md, 5 modèles couverts.</code></pre>



<figure class="wp-block-video"><video height="468" style="aspect-ratio: 748 / 468;" width="748" controls src="https://tazmenworld.com/wp-content/uploads/2026/06/hermes_agent.mp4" class="lws-optimize-lazyload"></video></figure>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">Le fichier était là le matin. Je n&rsquo;avais pas rouvert l&rsquo;app entre les deux messages.</p>



<p class="wp-block-paragraph">Ce qui rend ça possible, c&rsquo;est le linger activé plus haut. L&rsquo;agent tourne en fond, il n&rsquo;a pas besoin que tu sois connecté en SSH, il n&rsquo;attend pas que l&rsquo;écran soit allumé. Il fait son boulot, prévient, et attend le prochain ordre.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">10. Les trois pièges que j&rsquo;ai rencontrés</h2>



<h3 class="wp-block-heading">Piège 1 : La passerelle réseau qu&rsquo;on suppose à tort</h3>



<p class="wp-block-paragraph">En configurant l&rsquo;IP statique, j&rsquo;ai mis <code>192.168.1.1</code> comme passerelle sans vérifier. Résultat : ping local OK, accès internet mort. Impossible d&rsquo;installer Hermes : <code>curl -I https://github.com</code> répondait <code>No route to host</code>.</p>



<p class="wp-block-paragraph">La règle : <strong>ne jamais supposer</strong> l&rsquo;IP de la passerelle. La vérifier en amont avec <code>ip route | grep default</code> sur une machine qui marche, reporter la vraie valeur dans Netplan. Vingt secondes de vérification qui évitent une heure de debug.</p>



<h3 class="wp-block-heading">Piège 2 : Les permissions Docker sur trois fronts</h3>



<p class="wp-block-paragraph">Trois problèmes distincts, tous liés aux permissions, tous bloquants à leur façon.</p>



<p class="wp-block-paragraph"><strong>Le groupe docker ne s&rsquo;active pas immédiatement.</strong> Après <code>usermod -aG docker</code>, sur une install minimized <code>newgrp</code> n&rsquo;est pas disponible. Le groupe ne prend effet qu&rsquo;après déconnexion/reconnexion, sans message d&rsquo;erreur explicite, juste un <code>permission denied</code> sur <code>docker run</code>.</p>



<p class="wp-block-paragraph"><strong>n8n crashe en boucle au démarrage.</strong> Le container tourne sous l&rsquo;UID 1000 (<code>node</code>). Si le dossier <code>data</code> appartient à root, n8n ne peut pas écrire et redémarre toutes les trente secondes. Fix : <code>sudo chown -R 1000:1000 /opt/autoserver/n8n/data</code>. C&rsquo;est la première chose à faire avant de lancer le container.</p>



<p class="wp-block-paragraph"><strong>n8n ne sort pas sur internet.</strong> UFW bloque par défaut le forwarding des containers. Les workflows se déclenchent, mais tout appel HTTP externe échoue en silence. Fix : passer <code>DEFAULT_FORWARD_POLICY</code> de <code>"DROP"</code> à <code>"ACCEPT"</code> dans <code>/etc/default/ufw</code>, puis <code>sudo ufw reload</code>.</p>



<h3 class="wp-block-heading">Piège 3 : Le cookie n8n qui bloque la connexion</h3>



<p class="wp-block-paragraph">Tu ouvres l&rsquo;interface, tu entres tes identifiants, ça ne passe pas. Aucun message d&rsquo;erreur clair. n8n exige par défaut un cookie sécurisé qui ne fonctionne qu&rsquo;en HTTPS. En HTTP sur le réseau local, c&rsquo;est l&rsquo;impasse.</p>



<p class="wp-block-paragraph">Une ligne dans le <code>.env</code> règle l&rsquo;affaire :</p>



<p class="wp-block-paragraph">env</p>



<pre class="wp-block-code"><code>N8N_SECURE_COOKIE=false</code></pre>



<p class="wp-block-paragraph">Redémarre le container, l&rsquo;interface s&rsquo;ouvre. À ne configurer qu&rsquo;en local sur un réseau de confiance. Dès qu&rsquo;on expose vers l&rsquo;extérieur, on passe par un reverse proxy HTTPS.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">11. Ce qu&rsquo;on peut faire avec</h2>



<p class="wp-block-paragraph">Le setup une fois en place, voilà ce qui tourne concrètement.</p>



<p class="wp-block-paragraph"><strong>Veille techno automatique.</strong> Chaque matin à 7h, n8n déclenche une recherche via SearXNG sur <code>tazmenworld</code>, envoie les résultats à l&rsquo;agent, et m&rsquo;expédie un digest propre sur Telegram. J&rsquo;ouvre le téléphone au réveil avec un résumé au lieu de vingt onglets à scroller.</p>



<p class="wp-block-paragraph"><strong>Tâches longues en arrière-plan.</strong> Je donne un objectif à Hermes le soir (un comparatif de solutions, une analyse de logs, une rédaction), il découpe, cherche, rédige, et dépose le fichier dans <code>/shared/</code>. Au matin, c&rsquo;est prêt. Le « pendant que tu dors » du titre, c&rsquo;est littéralement ça.</p>



<p class="wp-block-paragraph"><strong>Délégation au GPU.</strong> L&rsquo;agent reçoit une demande de génération d&rsquo;image, mais le N150 n&rsquo;a pas de GPU sérieux. Pas de souci : il envoie le job à ComfyUI sur <code>tazmenworld</code> via <code>http://192.168.1.100:8188</code>, récupère le résultat, me le renvoie. Le control plan décide, le compute exécute.</p>



<p class="wp-block-paragraph"><strong>Webhooks inter-machines.</strong> Un workflow sur <code>autoserver</code> peut déclencher un workflow sur le n8n de <code>tazmenworld</code> via un nœud HTTP Request vers <code>http://192.168.1.100:5678/webhook/&lt;id&gt;</code>. Les deux instances se parlent sans passer par internet.</p>



<p class="wp-block-paragraph"><strong>Sauvegarde automatique à 3h du matin.</strong> Un cron sauvegarde les volumes Docker et garde les 7 dernières copies. Un alias <code>as-status</code> donne en deux secondes l&rsquo;état des containers, la RAM, le disque, et la connectivité vers <code>tazmenworld</code>. Le serveur se surveille tout seul.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">Conclusion</h2>



<p class="wp-block-paragraph">Il y a six mois, monter ce genre de setup demandait une connaissance pointue de Docker, des agents IA, et du self-hosting Linux. Aujourd&rsquo;hui, l&rsquo;installation tient en une soirée, et le résultat c&rsquo;est un control plan IA permanent sur ton réseau local, piloté depuis ton téléphone, qui bosse sans te demander la permission.</p>



<p class="wp-block-paragraph">Le Mac mini n&rsquo;est pas mauvais. Il est juste disproportionné pour ce rôle. Et le vrai problème d&rsquo;un VPS, ce n&rsquo;est pas le prix : c&rsquo;est qu&rsquo;il ne voit pas ton réseau local. Un agent IA qui ne peut pas parler à tes services, c&rsquo;est un outil à moitié aveugle.</p>



<p class="wp-block-paragraph">Le mini PC à 130€ règle les deux problèmes : il est sur ton LAN, il est sobre, il ne s&rsquo;arrête pas. Le calcul lourd, il a juste à savoir l&rsquo;adresse de ta vraie machine pour le déléguer. C&rsquo;est la même logique qu&rsquo;on applique partout ici : ne pas gâcher la ressource, mettre le bon outil au bon endroit.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p class="wp-block-paragraph"><em>Matériel : MLLSE G2 Pro (Intel N150, 12 Go LPDDR5, 512 Go SSD). Stack : Ubuntu Server 26.04 LTS, Docker, n8n, Hermes Agent (Nous Research, licence MIT), DeepSeek V4 via OpenRouter. Les tokens, clés API et mots de passe dans les exemples sont des espaces réservés, génère les tiens avec les commandes indiquées.</em></p>
]]></content:encoded>
					
					<wfw:commentRss>https://tazmenworld.com/2026/06/05/pourquoi-acheter-un-mac-mini-alors-quun-mini-pc-a-130e-fait-tourner-hermes-agent-24h-24-aussi-bien/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		<enclosure url="https://tazmenworld.com/wp-content/uploads/2026/06/hermes_agent.mp4" length="2948597" type="video/mp4" />

			</item>
		<item>
		<title>RAG vs Gros Contexte : pourquoi tout balancer dans le prompt dégrade tes réponses</title>
		<link>https://tazmenworld.com/2026/06/03/rag-vs-gros-contexte-pourquoi-tout-balancer-dans-le-prompt-degrade-tes-reponses/</link>
					<comments>https://tazmenworld.com/2026/06/03/rag-vs-gros-contexte-pourquoi-tout-balancer-dans-le-prompt-degrade-tes-reponses/#respond</comments>
		
		<dc:creator><![CDATA[tazmen3]]></dc:creator>
		<pubDate>Wed, 03 Jun 2026 12:19:27 +0000</pubDate>
				<category><![CDATA[Non classé]]></category>
		<guid isPermaLink="false">https://tazmenworld.com/?p=292</guid>

					<description><![CDATA[Depuis quelque temps, je vois passer pas mal d&#8217;articles sur l&#8217;IA locale ou dans du cloud, et souvent la même idée revient : jouer sur le contexte. Charger une grosse fenêtre de contexte pour « fixer l&#8217;état » du modèle, cadrer son comportement et orienter le type de réponse qu&#8217;il va te sortir. L&#8217;intention est [&#8230;]]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-large"><img width="1024" height="573"  alt="" class="wp-image-293"/ loading="lazy" decoding="async" src="https://tazmenworld.com/wp-content/uploads/2026/06/rag-context-1024x573.jpeg" srcset="https://tazmenworld.com/wp-content/uploads/2026/06/rag-context-1024x573.jpeg 1024w, https://tazmenworld.com/wp-content/uploads/2026/06/rag-context-300x168.jpeg 300w, https://tazmenworld.com/wp-content/uploads/2026/06/rag-context-768x430.jpeg 768w, https://tazmenworld.com/wp-content/uploads/2026/06/rag-context-1536x859.jpeg 1536w, https://tazmenworld.com/wp-content/uploads/2026/06/rag-context.jpeg 1677w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">Depuis quelque temps, je vois passer pas mal d&rsquo;articles sur l&rsquo;IA locale ou dans du cloud, et souvent la même idée revient : jouer sur le contexte. Charger une grosse fenêtre de contexte pour « fixer l&rsquo;état » du modèle, cadrer son comportement et orienter le type de réponse qu&rsquo;il va te sortir. L&rsquo;intention est bonne donner au modèle un maximum de matière pour qu&rsquo;il réponde juste.</p>



<p class="wp-block-paragraph">Le problème, c&rsquo;est que ça part souvent dans le mur. Plus le contexte augmente, plus on tombe dans ce qu&rsquo;on appelle le <em>Lost in the Middle</em> : le modèle finit par perdre l&rsquo;info au milieu de tout ce qu&rsquo;on lui a donné. C&rsquo;est ce que je veux t&rsquo;expliquer ici, simplement  et voir pourquoi, dans la plupart des cas, un <strong>RAG</strong> (Retrieval-Augmented Generation) fait le boulot bien mieux qu&rsquo;un gros contexte.</p>



<h2 class="wp-block-heading">1. Le réflexe « balance tout, il triera »</h2>



<p class="wp-block-paragraph">Coller 800 pages dans la fenêtre et poser sa question, c&rsquo;est tentant parce que c&rsquo;est rapide à mettre en place. Pas de base vectorielle, pas de chunking, pas d&#8217;embeddings à calculer.</p>



<p class="wp-block-paragraph">Le souci, c&rsquo;est qu&rsquo;on mélange deux choses : <strong>la capacité</strong> (combien de tokens le modèle accepte en entrée) et <strong>l&rsquo;attention utile</strong> (ce qu&rsquo;il sait réellement exploiter là-dedans). Avoir 16 Go de VRAM ne veut pas dire qu&rsquo;on les utilise bien souviens-toi de la « taxe d&rsquo;affichage » Windows. Pour le contexte, c&rsquo;est le même principe.</p>



<h2 class="wp-block-heading">2. « Lost in the Middle » : l&rsquo;info au milieu passe à la trappe</h2>



<p class="wp-block-paragraph">Le papier de référence sur le sujet, c&rsquo;est <em>Lost in the Middle: How Language Models Use Long Contexts</em> (Liu et al., arXiv:2307.03172). Son constat : quand l&rsquo;information pertinente est placée <strong>au milieu</strong> d&rsquo;un long contexte, le modèle la retrouve mal.</p>



<p class="wp-block-paragraph">La performance suit une <strong>courbe en U</strong>. Le modèle exploite bien ce qui est en <strong>début</strong> et en <strong>fin</strong> de contexte, et décroche au centre. Autrement dit, ta réponse peut être présente noir sur blanc dans les tokens que tu as fournis, et passer à côté juste parce qu&rsquo;elle est tombée au mauvais endroit. Pour quelqu&rsquo;un qui automatise des workflows, c&rsquo;est un vrai problème : l&rsquo;info est là, mais le résultat est faux.</p>



<figure class="wp-block-image size-full"><img width="997" height="497"  alt="" class="wp-image-294"/ loading="lazy" decoding="async" src="https://tazmenworld.com/wp-content/uploads/2026/06/image.png" srcset="https://tazmenworld.com/wp-content/uploads/2026/06/image.png 997w, https://tazmenworld.com/wp-content/uploads/2026/06/image-300x150.png 300w, https://tazmenworld.com/wp-content/uploads/2026/06/image-768x383.png 768w" sizes="auto, (max-width: 997px) 100vw, 997px" /></figure>



<h2 class="wp-block-heading">3. Le « context rot » : plus c&rsquo;est gros, plus ça hallucine</h2>



<p class="wp-block-paragraph">« Lost in the middle » est la partie la plus connue. Il existe un phénomène plus large, baptisé <strong>context rot</strong> : la qualité des réponses baisse à mesure que le contexte s&rsquo;allonge, et ça commence <strong>avant</strong> que la fenêtre soit pleine.</p>



<p class="wp-block-paragraph">Une étude de Chroma a testé 18 modèles récents. Tous se dégradent quand l&rsquo;entrée s&rsquo;allonge ; un modèle à 200K tokens peut déjà perdre en qualité dès 50K. Ce n&rsquo;est donc pas la capacité qui compte, mais le <strong>rapport signal/bruit</strong>.</p>



<p class="wp-block-paragraph">Deux mécanismes l&rsquo;expliquent :</p>



<ol class="wp-block-list">
<li><strong>La dilution de l&rsquo;attention.</strong> L&rsquo;attention « soft » d&rsquo;un Transformer a une capacité fixe. Plus tu ajoutes de tokens, plus elle s&rsquo;étale sur du bruit, et moins chaque token utile en reçoit. C&rsquo;est architectural aucun prompt ne le contourne.</li>



<li><strong>Les hallucinations.</strong> Noyé dans la masse, le modèle comble les trous en inventant, avec le même aplomb que d&rsquo;habitude.</li>
</ol>



<p class="wp-block-paragraph">L&rsquo;analogie infra, c&rsquo;est le <strong>spillover VRAM</strong> dont je parlais dans la série VRAM Tuning : tant que tout tient, ça file à ~1000 Go/s ; dès que ça déborde, on tombe à ~60 Go/s. Le gros contexte fait pareil avec l&rsquo;attention du modèle, sauf que tu paies en plus ces tokens à chaque requête.</p>



<h2 class="wp-block-heading">4. Ce que change le RAG</h2>



<p class="wp-block-paragraph">Le RAG inverse la logique. Au lieu de tout donner d&rsquo;un coup, on récupère en amont les passages pertinents pour la question posée, et on ne sert que ça.</p>



<p class="wp-block-paragraph">Le déroulé est simple :</p>



<ol class="wp-block-list">
<li>La question arrive.</li>



<li>Un système de récupération (base vectorielle, recherche sémantique) sort les quelques morceaux utiles de ta base de connaissances.</li>



<li>On injecte <strong>seulement</strong> ces morceaux, propres et bien placés.</li>



<li>Le modèle répond sur une base nette.</li>
</ol>



<p class="wp-block-paragraph">Les trois problèmes tombent en même temps : pas de milieu géant où se perdre, une attention concentrée sur l&rsquo;utile, et un signal/bruit qui limite les hallucinations.</p>



<p class="wp-block-paragraph">C&rsquo;est la même logique que le <strong>headless</strong> : on garde le moteur de calcul utile, on enlève le reste. On ne charge que ce qui sert.</p>



<h2 class="wp-block-heading">5. Quand le gros contexte reste pertinent</h2>



<p class="wp-block-paragraph">Le RAG n&rsquo;est pas la réponse à tout. Le gros contexte garde du sens dans des cas précis :</p>



<ul class="wp-block-list">
<li><strong>Un document unique et court</strong> à analyser en entier (un contrat de 10 pages, un fichier de code) : monter un RAG là-dessus, c&rsquo;est disproportionné.</li>



<li><strong>Un raisonnement transversal</strong> qui doit croiser des infos dispersées dans tout le document (« résume l&rsquo;évolution du ton sur l&rsquo;ensemble du rapport ») : un RAG qui ne récupère que des bouts isolés peut manquer la vue d&rsquo;ensemble.</li>



<li><strong>Le prototypage</strong> : pour un test rapide, coller dans le contexte va plus vite. À condition de savoir que ça ne tiendra pas à l&rsquo;échelle.</li>
</ul>



<p class="wp-block-paragraph">La vraie réponse dépend de la charge. Mais en production, sur du volume, le RAG l&#8217;emporte.</p>



<h2 class="wp-block-heading">Tableau comparatif : RAG vs Gros Contexte</h2>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>Critère</th><th>Gros Contexte</th><th>RAG</th></tr></thead><tbody><tr><td>Info au milieu</td><td>Souvent ratée (courbe en U)</td><td>Toujours en tête de contexte</td></tr><tr><td>Attention du modèle</td><td>Diluée sur le bruit</td><td>Concentrée sur l&rsquo;utile</td></tr><tr><td>Risque d&rsquo;hallucination</td><td>Augmente avec la taille</td><td>Réduit (bon signal/bruit)</td></tr><tr><td>Coût en tokens</td><td>Élevé (et facturé)</td><td>Minimal, ciblé</td></tr><tr><td>Mise en place</td><td>Triviale (copier-coller)</td><td>Pipeline à construire</td></tr><tr><td>Passage à l&rsquo;échelle</td><td>Se dégrade vite</td><td>Tient la route</td></tr><tr><td>Cas idéal</td><td>Doc unique et court, proto</td><td>Base de connaissances, prod</td></tr></tbody></table></figure>



<h2 class="wp-block-heading">Conclusion</h2>



<p class="wp-block-paragraph">Le gros contexte, c&rsquo;est la solution rapide, et elle a un coût : ton info se perd au milieu, l&rsquo;attention se dilue, et tu paies plus pour des réponses moins fiables. « Lost in the middle » l&rsquo;a montré dès 2023, le context rot l&rsquo;a confirmé depuis.</p>



<p class="wp-block-paragraph">Le RAG demande un peu de travail en amont base vectorielle, chunking, embeddings. Mais c&rsquo;est la même logique que le reste du blog : ne pas gâcher la ressource, ne garder que l&rsquo;utile. La capacité brute, c&rsquo;est une chose ; savoir quoi mettre dedans, c&rsquo;en est une autre.</p>



<p class="wp-block-paragraph">On se retrouve pour la suite, où on montera un petit RAG local de bout en bout, avec une base vectorielle qui tourne sur ta machine et pas dans le cloud de quelqu&rsquo;un d&rsquo;autre. On va chunker, embedder et récupérer comme il faut.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p class="wp-block-paragraph"><em>Source principale : Liu et al., « Lost in the Middle: How Language Models Use Long Contexts », arXiv:2307.03172. Compléments sur le context rot et la dilution de l&rsquo;attention : recherches Chroma (2025) et travaux associés sur la dégradation en long contexte.</em></p>



<p class="wp-block-paragraph">Source: <a href="https://arxiv.org/abs/2307.03172v3">https://arxiv.org/abs/2307.03172v3</a></p>
]]></content:encoded>
					
					<wfw:commentRss>https://tazmenworld.com/2026/06/03/rag-vs-gros-contexte-pourquoi-tout-balancer-dans-le-prompt-degrade-tes-reponses/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Comment remplacer Perplexity par Mistral en local</title>
		<link>https://tazmenworld.com/2026/04/30/comment-remplacer-perplexity-par-mistral-en-local/</link>
					<comments>https://tazmenworld.com/2026/04/30/comment-remplacer-perplexity-par-mistral-en-local/#respond</comments>
		
		<dc:creator><![CDATA[tazmen3]]></dc:creator>
		<pubDate>Wed, 29 Apr 2026 22:06:46 +0000</pubDate>
				<category><![CDATA[Intelligence Artificielle (IA)]]></category>
		<category><![CDATA[Non classé]]></category>
		<guid isPermaLink="false">https://tazmenworld.com/?p=240</guid>

					<description><![CDATA[Je l&#8217;avoue : Perplexity est devenu, en l&#8217;espace de quelques mois, mon réflexe quotidien. C&#8217;est l&#8217;outil qui m&#8217;a fait oublier la liste interminable de liens bleus de Google pour me proposer des réponses synthétisées, sourcées et presque toujours pertinentes. Pourtant, plus je l&#8217;utilisais, plus une certaine gêne s&#8217;installait. À chaque requête, j&#8217;envoie un fragment de [&#8230;]]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-large"><img width="1024" height="572"  alt="" class="wp-image-260"/ loading="lazy" decoding="async" src="https://tazmenworld.com/wp-content/uploads/2026/04/Image_8411l08411l08411-1024x572.png" srcset="https://tazmenworld.com/wp-content/uploads/2026/04/Image_8411l08411l08411-1024x572.png 1024w, https://tazmenworld.com/wp-content/uploads/2026/04/Image_8411l08411l08411-300x167.png 300w, https://tazmenworld.com/wp-content/uploads/2026/04/Image_8411l08411l08411-768x429.png 768w, https://tazmenworld.com/wp-content/uploads/2026/04/Image_8411l08411l08411-1536x857.png 1536w, https://tazmenworld.com/wp-content/uploads/2026/04/Image_8411l08411l08411-2048x1143.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">Je l&rsquo;avoue : Perplexity est devenu, en l&rsquo;espace de quelques mois, mon réflexe quotidien. C&rsquo;est l&rsquo;outil qui m&rsquo;a fait oublier la liste interminable de liens bleus de Google pour me proposer des réponses synthétisées, sourcées et presque toujours pertinentes. Pourtant, plus je l&rsquo;utilisais, plus une certaine gêne s&rsquo;installait. À chaque requête, j&rsquo;envoie un fragment de mes réflexions, de mes projets et de ma vie privée sur des serveurs dont je ne contrôle ni l&rsquo;accès, ni la politique de conservation.</p>



<p class="wp-block-paragraph">Aujourd&rsquo;hui, je refuse de « louer » mon intelligence et ma vie privée à une boîte noire. J&rsquo;ai décidé de reprendre les commandes en construisant ma propre alternative souveraine. L&rsquo;objectif est simple : obtenir la même puissance de recherche et de synthèse, mais de manière totalement privée, sans abonnement, et en exploitant la puissance de calcul qui dort dans mon propre bureau.</p>



<h2 class="wp-block-heading">La quête de la souveraineté numérique</h2>



<p class="wp-block-paragraph">Pourquoi s&#8217;embêter à configurer sa propre machine quand un service à 20 dollars par mois fait le travail ? La réponse tient en un mot : la maîtrise. En installant ma propre « Tazmen Station », je ne dépends plus d&rsquo;une connexion internet pour réfléchir ou d&rsquo;une mise à jour logicielle qui pourrait brider les capacités de mon modèle favori.</p>



<p class="wp-block-paragraph">Ma configuration repose sur un matériel que j&rsquo;ai choisi pour ses capacités de calcul : un processeur <strong>AMD Ryzen 9 9900X</strong> épaulé par une carte <strong>NVIDIA GeForce RTX 5070 Ti</strong>. C&rsquo;est cette dernière qui est le véritable moteur de mon installation. Avec ses <strong>13 Go de mémoire vidéo (VRAM)</strong> mobilisés, elle me permet de faire tourner des modèles sophistiqués comme <strong>Mistral-Nemo 12B</strong> avec une fluidité déconcertante.</p>



<figure class="wp-block-image size-large"><img width="1024" height="599"  alt="" class="wp-image-244"/ loading="lazy" decoding="async" src="https://tazmenworld.com/wp-content/uploads/2026/04/image-21-1024x599.png" srcset="https://tazmenworld.com/wp-content/uploads/2026/04/image-21-1024x599.png 1024w, https://tazmenworld.com/wp-content/uploads/2026/04/image-21-300x176.png 300w, https://tazmenworld.com/wp-content/uploads/2026/04/image-21-768x449.png 768w, https://tazmenworld.com/wp-content/uploads/2026/04/image-21.png 1109w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">Le projet que je vais vous détailler n&rsquo;est pas une simple curiosité technique. C&rsquo;est un système de production robuste. Pour y parvenir, j&rsquo;ai assemblé une pile logicielle cohérente à l&rsquo;aide de conteneurs Docker :</p>



<ul class="wp-block-list">
<li><strong>SearXNG</strong> : Mon détective privé qui interroge le web à ma place, anonymement.</li>



<li><strong>Ollama</strong> : Le moteur qui héberge mes modèles de langage.</li>



<li><strong>Open WebUI</strong> : L&rsquo;interface élégante qui lie le tout et me permet de dialoguer avec mes données.</li>
</ul>



<p class="wp-block-paragraph">[CODE : arborescence_projet.txt]</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>~/tazmen-ai-station/
├── docker-compose.yml     # L'orchestrateur de mes services
├── open-webui/            # Mes données d'interface et historiques
├── mcpo/                  # Le bridge pour les outils avancés
└── searxng/               # Ma configuration de recherche privée
    └── settings.yml       # Le réglage fin de mes moteurs de recherche</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #A3BE8C">~/tazmen-ai-station/</span></span>
<span class="line"><span style="color: #A3BE8C">├── docker-compose.yml</span><span style="color: #D8DEE9FF">     </span><span style="color: #616E88"># L&#39;orchestrateur de mes services</span></span>
<span class="line"><span style="color: #A3BE8C">├── open-webui/</span><span style="color: #D8DEE9FF">            </span><span style="color: #616E88"># Mes données d&#39;interface et historiques</span></span>
<span class="line"><span style="color: #A3BE8C">├── mcpo/</span><span style="color: #D8DEE9FF">                  </span><span style="color: #616E88"># Le bridge pour les outils avancés</span></span>
<span class="line"><span style="color: #A3BE8C">└── searxng/</span><span style="color: #D8DEE9FF">               </span><span style="color: #616E88"># Ma configuration de recherche privée</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #A3BE8C">└── settings.yml</span><span style="color: #D8DEE9FF">       </span><span style="color: #616E88"># Le réglage fin de mes moteurs de recherche</span></span></code></pre></div>



<p class="wp-block-paragraph">En tant qu&rsquo;utilisateur passionné par la sécurité et l&rsquo;IA, je ne cherche pas seulement à obtenir une réponse, mais à comprendre comment elle est générée. Dans ce guide, je vais vous montrer comment j&rsquo;ai transformé une simple machine Ubuntu en un pôle d&rsquo;intelligence capable de tenir tête aux solutions propriétaires les plus en vue. Nous n&rsquo;allons pas seulement installer des logiciels ; nous allons bâtir un écosystème où chaque octet de donnée reste sous notre contrôle exclusif.</p>



<p class="wp-block-paragraph">Préparez votre terminal. Nous allons voir comment transformer radicalement votre manière de chercher l&rsquo;information, sans jamais compromettre votre confidentialité.</p>



<h2 class="wp-block-heading">II. SearXNG : Le cerveau qui murmure à l’oreille du Web</h2>



<p class="wp-block-paragraph">Pour que mon installation puisse réellement rivaliser avec Perplexity, il me fallait un moyen d&rsquo;interroger le web sans que les moteurs de recherche ne sachent qui je suis ni ce que je cherche. C&rsquo;est ici qu&rsquo;intervient <strong>SearXNG</strong>.</p>



<p class="wp-block-paragraph" id="p-rc_3a7d666432e8f79f-23">Je décris souvent SearXNG comme un moteur de recherche métacognitif. Contrairement à Google ou Bing, il ne possède pas son propre index de pages web. C’est un agrégateur : quand je lui pose une question, il va interroger simultanément des dizaines d’autres moteurs (Google, DuckDuckGo, Bing, Qwant) à ma place<sup></sup>. Il récupère les résultats, les nettoie, supprime les doublons et me les présente de manière structurée.</p>



<h3 class="wp-block-heading">L&rsquo;anonymat par procuration</h3>



<p class="wp-block-paragraph" id="p-rc_3a7d666432e8f79f-24">Le génie de SearXNG réside dans sa capacité à faire écran entre moi et les géants du web. Puisque c&rsquo;est mon serveur local qui envoie les requêtes, les moteurs de recherche voient l&rsquo;adresse IP de mon instance et non la mienne. En configurant correctement le fichier <code>settings.yml</code>, je m&rsquo;assure qu&rsquo;aucune donnée de profilage n&rsquo;est transmise<sup></sup>. C&rsquo;est la base indispensable pour garantir que mes recherches sur la <strong>sécurité</strong> ou l&rsquo;<strong>IA</strong> ne finissent pas dans une base de données publicitaire.</p>



<figure class="wp-block-image size-large"><img width="1024" height="425"  alt="" class="wp-image-246"/ loading="lazy" decoding="async" src="https://tazmenworld.com/wp-content/uploads/2026/04/image-23-1024x425.png" srcset="https://tazmenworld.com/wp-content/uploads/2026/04/image-23-1024x425.png 1024w, https://tazmenworld.com/wp-content/uploads/2026/04/image-23-300x125.png 300w, https://tazmenworld.com/wp-content/uploads/2026/04/image-23-768x319.png 768w, https://tazmenworld.com/wp-content/uploads/2026/04/image-23-1536x638.png 1536w, https://tazmenworld.com/wp-content/uploads/2026/04/image-23-2048x850.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<h3 class="wp-block-heading">Pourquoi c’est la pièce maîtresse du puzzle ?</h3>



<p class="wp-block-paragraph">Un modèle comme Mistral, aussi brillant soit-il, possède une limite de connaissances fixée au moment de son entraînement. Pour lui donner une « mémoire vive » du web actuel, j&rsquo;utilise le <strong>RAG (Retrieval-Augmented Generation)</strong>.</p>



<p class="wp-block-paragraph" id="p-rc_3a7d666432e8f79f-25">SearXNG est le fournisseur officiel de ce contexte. Dans ma configuration, Open WebUI envoie la requête utilisateur à SearXNG, récupère les 5 meilleurs extraits (snippets) et les injecte directement dans le prompt de Mistral<sup></sup>. C&rsquo;est ce mécanisme qui permet d&rsquo;obtenir des réponses sur le programme TV de demain ou sur une faille de sécurité découverte il y a trois heures.</p>



<p class="wp-block-paragraph">[CODE : Extrait de configuration des moteurs dans settings.yml]</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>engines:
  - name: google
    engine: google
    shortcut: go
  - name: bing
    engine: bing
    shortcut: bi
  - name: brave
    engine: brave
    shortcut: br
    categories: &#91;general, web&#93;</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #8FBCBB">engines</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #ECEFF4">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">name</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">google</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">engine</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">google</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">shortcut</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">go</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #ECEFF4">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">name</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">bing</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">engine</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">bing</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">shortcut</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">bi</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #ECEFF4">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">name</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">brave</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">engine</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">brave</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">shortcut</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">br</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">categories</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&#91;</span><span style="color: #A3BE8C">general</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">web</span><span style="color: #ECEFF4">&#93;</span></span></code></pre></div>



<p class="wp-block-paragraph" id="p-rc_3a7d666432e8f79f-26">Dans mon fichier <code>settings.yml</code>, j&rsquo;ai pris soin d&rsquo;activer des moteurs comme <strong>Bing</strong> et <strong>Brave</strong> pour ne pas dépendre uniquement de Google, qui a parfois tendance à bloquer les requêtes automatisées. Cette diversité est ce qui rend le système robuste : si un moteur fait défaut, les autres prennent le relais pour fournir l&rsquo;information à Mistral. </p>



<figure class="wp-block-image size-large"><img width="1024" height="303"  alt="" class="wp-image-245"/ loading="lazy" decoding="async" src="https://tazmenworld.com/wp-content/uploads/2026/04/image-22-1024x303.png" srcset="https://tazmenworld.com/wp-content/uploads/2026/04/image-22-1024x303.png 1024w, https://tazmenworld.com/wp-content/uploads/2026/04/image-22-300x89.png 300w, https://tazmenworld.com/wp-content/uploads/2026/04/image-22-768x227.png 768w, https://tazmenworld.com/wp-content/uploads/2026/04/image-22-1536x454.png 1536w, https://tazmenworld.com/wp-content/uploads/2026/04/image-22.png 1597w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">Sans cette brique, mon IA locale serait une encyclopédie figée dans le passé. Avec SearXNG, elle devient un analyste capable de lire le web en temps réel tout en respectant ma vie privée.</p>



<h2 class="wp-block-heading">II. L&rsquo;Infrastructure : Poser les fondations avec Docker</h2>



<p class="wp-block-paragraph" id="p-rc_ead4c7521dab0df2-36">Pour bâtir ma propre station d&rsquo;IA, j&rsquo;ai choisi la voie de la propreté et de la modularité : <strong>Docker Compose</strong>. L&rsquo;idée n&rsquo;est pas de transformer mon installation Ubuntu en un tas de dépendances Python incohérentes, mais de compartimenter chaque outil dans son propre conteneur. Cela me permet de tout démarrer ou d&rsquo;éteindre l&rsquo;ensemble de ma machine de recherche en une seule commande<sup></sup>.</p>



<h3 class="wp-block-heading">Architecture du flux de données</h3>



<p class="wp-block-paragraph">Avant de regarder le code, il est crucial de comprendre comment mes outils discutent entre eux. Voici le chemin parcouru par une simple question comme « Quel est le dernier driver NVIDIA pour Linux ? » :</p>



<figure class="wp-block-image size-full"><img width="859" height="643"  alt="" class="wp-image-247"/ loading="lazy" decoding="async" src="https://tazmenworld.com/wp-content/uploads/2026/04/image-24.png" srcset="https://tazmenworld.com/wp-content/uploads/2026/04/image-24.png 859w, https://tazmenworld.com/wp-content/uploads/2026/04/image-24-300x225.png 300w, https://tazmenworld.com/wp-content/uploads/2026/04/image-24-768x575.png 768w" sizes="auto, (max-width: 859px) 100vw, 859px" /></figure>



<h3 class="wp-block-heading">Le fichier de configuration : Analyse du docker-compose.yml</h3>



<p class="wp-block-paragraph" id="p-rc_ead4c7521dab0df2-37">Voici le cœur de ma <strong>Tazmen Station</strong>. J&rsquo;y ai regroupé tous les services nécessaires, de l&rsquo;interface au moteur de recherche, en passant par le pont MCP pour les outils étendus<sup></sup>.</p>



<p class="wp-block-paragraph">[CODE : docker-compose.yml]</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>name: tazmen-ai-station

services:
  # Moteur d'IA : Ollama gère le chargement et l'exécution de Mistral
  ollama:
    image: ollama/ollama
    container_name: ollama
    volumes:
      - /media/DATA/LLM/models:/root/.ollama # Stockage externe pour mes modèles
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              device_ids: &#91;'0'&#93; # Cible ma RTX 5070 Ti
              capabilities: &#91;gpu&#93;
    restart: unless-stopped

  # Recherche Web : L'agrégateur privé
  searxng:
    container_name: searxng
    image: searxng/searxng:latest
    ports:
      - "8080:8080"
    volumes:
      - ./searxng:/etc/searxng
    restart: unless-stopped

  # Interface : Le portail qui orchestre le RAG
  open-webui:
    image: ghcr.io/open-webui/open-webui:main
    container_name: open-webui
    depends_on:
      - ollama
      - searxng
    ports:
      - "3000:8080"
    environment:
      - OLLAMA_BASE_URL=http://ollama:11434
      - ENABLE_RAG_WEB_SEARCH=True
      - RAG_WEB_SEARCH_ENGINE=searxng
      - SEARXNG_QUERY_URL=http://searxng:8080/search?q=&lt;query>
      - RAG_WEB_SEARCH_RESULT_COUNT=5 # Nombre de sources lues par l'IA
    restart: unless-stopped</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #8FBCBB">name</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">tazmen-ai-station</span></span>
<span class="line"></span>
<span class="line"><span style="color: #8FBCBB">services</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #ECEFF4">  </span><span style="color: #616E88"># Moteur d&#39;IA : Ollama gère le chargement et l&#39;exécution de Mistral</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #8FBCBB">ollama</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">image</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">ollama/ollama</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">container_name</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">ollama</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">volumes</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #ECEFF4">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">/media/DATA/LLM/models:/root/.ollama</span><span style="color: #D8DEE9FF"> </span><span style="color: #616E88"># Stockage externe pour mes modèles</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">deploy</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #8FBCBB">resources</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #8FBCBB">reservations</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">          </span><span style="color: #8FBCBB">devices</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #ECEFF4">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">driver</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">nvidia</span></span>
<span class="line"><span style="color: #D8DEE9FF">              </span><span style="color: #8FBCBB">device_ids</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&#91;</span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">0</span><span style="color: #ECEFF4">&#39;</span><span style="color: #ECEFF4">&#93;</span><span style="color: #D8DEE9FF"> </span><span style="color: #616E88"># Cible ma RTX 5070 Ti</span></span>
<span class="line"><span style="color: #D8DEE9FF">              </span><span style="color: #8FBCBB">capabilities</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&#91;</span><span style="color: #A3BE8C">gpu</span><span style="color: #ECEFF4">&#93;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">restart</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">unless-stopped</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">  </span><span style="color: #616E88"># Recherche Web : L&#39;agrégateur privé</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #8FBCBB">searxng</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">container_name</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">searxng</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">image</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">searxng/searxng:latest</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">ports</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #ECEFF4">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">8080:8080</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">volumes</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #ECEFF4">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">./searxng:/etc/searxng</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">restart</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">unless-stopped</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">  </span><span style="color: #616E88"># Interface : Le portail qui orchestre le RAG</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #8FBCBB">open-webui</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">image</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">ghcr.io/open-webui/open-webui:main</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">container_name</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">open-webui</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">depends_on</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #ECEFF4">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">ollama</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #ECEFF4">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">searxng</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">ports</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #ECEFF4">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">3000:8080</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">environment</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #ECEFF4">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">OLLAMA_BASE_URL=http://ollama:11434</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #ECEFF4">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">ENABLE_RAG_WEB_SEARCH=True</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #ECEFF4">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">RAG_WEB_SEARCH_ENGINE=searxng</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #ECEFF4">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">SEARXNG_QUERY_URL=http://searxng:8080/search?q=&lt;query&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #ECEFF4">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">RAG_WEB_SEARCH_RESULT_COUNT=5</span><span style="color: #D8DEE9FF"> </span><span style="color: #616E88"># Nombre de sources lues par l&#39;IA</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">restart</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">unless-stopped</span></span></code></pre></div>



<h3 class="wp-block-heading">Le point critique : L&rsquo;accès au GPU</h3>



<p class="wp-block-paragraph" id="p-rc_ead4c7521dab0df2-38">Pour que ce système soit réactif, il n&rsquo;y a pas de secret : il faut que Docker puisse voir la carte graphique. Dans mon cas, c&rsquo;est une <strong>RTX 5070 Ti</strong>. Dans le service <code>ollama</code>, la section <code>deploy.resources.reservations</code> est indispensable. Sans elle, c&rsquo;est mon <strong>Ryzen 9 9900X</strong> qui prendrait tout le travail sur ses épaules, et la génération de texte deviendrait péniblement lente.</p>



<p class="wp-block-paragraph" id="p-rc_ead4c7521dab0df2-39">J&rsquo;ai également déporté le stockage des modèles sur un disque dur dédié via le volume <code>/media/DATA/LLM/models</code>. C&rsquo;est une astuce de vieux routier de l&rsquo;IA : les modèles comme Mistral pèsent plusieurs gigaoctets et je préfère ne pas encombrer ma partition système Ubuntu.</p>



<figure class="wp-block-image size-large"><img width="1024" height="341"  alt="" class="wp-image-248"/ loading="lazy" decoding="async" src="https://tazmenworld.com/wp-content/uploads/2026/04/image-25-1024x341.png" srcset="https://tazmenworld.com/wp-content/uploads/2026/04/image-25-1024x341.png 1024w, https://tazmenworld.com/wp-content/uploads/2026/04/image-25-300x100.png 300w, https://tazmenworld.com/wp-content/uploads/2026/04/image-25-768x256.png 768w, https://tazmenworld.com/wp-content/uploads/2026/04/image-25-1536x512.png 1536w, https://tazmenworld.com/wp-content/uploads/2026/04/image-25-2048x682.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph" id="p-rc_ead4c7521dab0df2-40">Une fois ce fichier prêt, un simple <code>sudo docker compose up -d</code> met en route toute la mécanique. L&rsquo;interface devient accessible sur le port 3000 de ma machine, prête à recevoir mes premières questions. </p>



<h2 class="wp-block-heading">IV. Configurer SearXNG : Le réglage de précision</h2>



<p class="wp-block-paragraph">Avoir un conteneur qui tourne, c&rsquo;est bien. Avoir un moteur qui répond exactement à ce que Mistral attend, c&rsquo;est mieux. Pour transformer SearXNG en une source de données fiable, je dois descendre dans les soutes et éditer le fichier <code>settings.yml</code>. C&rsquo;est ici que je définis quels moteurs interroger et comment formater les réponses pour qu&rsquo;elles soient digestes pour mon IA.</p>



<h3 class="wp-block-heading">La clé de voûte : La sécurité et l&rsquo;accès</h3>



<p class="wp-block-paragraph" id="p-rc_109101a035ca8487-70">La première chose que j&rsquo;ai configurée, c&rsquo;est la <code>secret_key</code><sup></sup>. C&rsquo;est elle qui sécurise les communications de mon instance. Pour cet article, je l&rsquo;ai remplacée par une valeur générique, mais dans mon installation réelle, j&rsquo;utilise une chaîne de caractères complexe générée aléatoirement.</p>



<p class="wp-block-paragraph" id="p-rc_109101a035ca8487-71">Un point technique m&rsquo;a demandé un peu de recherche : la méthode de communication. Par défaut, SearXNG utilise souvent <code>POST</code>, mais pour assurer une compatibilité totale avec le module de recherche d&rsquo;Open WebUI, j&rsquo;ai forcé le passage en <code>GET</code><sup></sup>. C&rsquo;est un détail qui peut éviter bien des maux de tête lors des premiers tests de connexion.</p>



<p class="wp-block-paragraph">[CODE : Configuration serveur dans settings.yml]</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>server:
  port: 8080
  bind_address: "0.0.0.0"
  secret_key: "VOTRE_CLE_ALÉATOIRE_ICI" # À anonymiser impérativement
  method: "GET" # Indispensable pour Open WebUI</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #8FBCBB">server</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #8FBCBB">port</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">8080</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #8FBCBB">bind_address</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">0.0.0.0</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #8FBCBB">secret_key</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">VOTRE_CLE_ALÉATOIRE_ICI</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF"> </span><span style="color: #616E88"># À anonymiser impérativement</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #8FBCBB">method</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">GET</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF"> </span><span style="color: #616E88"># Indispensable pour Open WebUI</span></span></code></pre></div>



<h3 class="wp-block-heading">Sortie JSON : Le langage de l&rsquo;IA</h3>



<p class="wp-block-paragraph" id="p-rc_109101a035ca8487-72">Pour que Mistral puisse « lire » les résultats de recherche, SearXNG ne doit pas seulement lui envoyer une page HTML pleine de bannières et de menus. J&rsquo;ai donc activé le format <code>json</code> dans la section <code>formats</code><sup></sup>. Cela permet à Open WebUI de recevoir une structure de données propre, contenant uniquement le titre, l&rsquo;URL et l&rsquo;extrait du site.</p>



<h3 class="wp-block-heading">Le choix des moteurs : Sortir de la bulle Google</h3>



<p class="wp-block-paragraph" id="p-rc_109101a035ca8487-73">C&rsquo;est sans doute la partie la plus gratifiante du réglage. Google est puissant, mais il déteste qu&rsquo;on l&rsquo;interroge via un script et il finit souvent par bloquer les requêtes avec des Captchas<sup></sup>. Pour rendre ma station robuste, j&rsquo;ai diversifié mes sources.</p>



<p class="wp-block-paragraph" id="p-rc_109101a035ca8487-74">J&rsquo;ai activé <strong>Bing</strong>, <strong>Qwant</strong> et <strong>Brave</strong>. En multipliant les moteurs, je m&rsquo;assure que si l&rsquo;un d&rsquo;eux boude ma requête, les autres fourniront quand même du grain à moudre à mon modèle. J&rsquo;ai également gardé <strong>DuckDuckGo</strong> actif pour sa pertinence globale. </p>



<figure class="wp-block-image size-large"><img width="1024" height="657"  alt="" class="wp-image-250"/ loading="lazy" decoding="async" src="https://tazmenworld.com/wp-content/uploads/2026/04/image-27-1024x657.png" srcset="https://tazmenworld.com/wp-content/uploads/2026/04/image-27-1024x657.png 1024w, https://tazmenworld.com/wp-content/uploads/2026/04/image-27-300x192.png 300w, https://tazmenworld.com/wp-content/uploads/2026/04/image-27-768x493.png 768w, https://tazmenworld.com/wp-content/uploads/2026/04/image-27-1536x985.png 1536w, https://tazmenworld.com/wp-content/uploads/2026/04/image-27.png 1643w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">[CODE : Activation des moteurs dans settings.yml]</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>engines:
  - name: google
    engine: google
    shortcut: go
    disabled: false # On le garde, mais on ne compte pas que sur lui
  - name: bing
    engine: bing
    shortcut: bi
    disabled: false
  - name: brave
    engine: brave
    shortcut: br
    disabled: false
  - name: qwant
    engine: qwant
    shortcut: qw
    disabled: false</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #8FBCBB">engines</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #ECEFF4">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">name</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">google</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">engine</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">google</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">shortcut</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">go</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">disabled</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">false</span><span style="color: #D8DEE9FF"> </span><span style="color: #616E88"># On le garde, mais on ne compte pas que sur lui</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #ECEFF4">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">name</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">bing</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">engine</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">bing</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">shortcut</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">bi</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">disabled</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">false</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #ECEFF4">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">name</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">brave</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">engine</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">brave</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">shortcut</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">br</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">disabled</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">false</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #ECEFF4">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">name</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">qwant</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">engine</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">qwant</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">shortcut</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">qw</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">disabled</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">false</span></span></code></pre></div>



<h3 class="wp-block-heading">Le filtrage et l&rsquo;autocomplétion</h3>



<p class="wp-block-paragraph" id="p-rc_109101a035ca8487-75">Pour affiner l&rsquo;expérience, j&rsquo;ai réglé le <code>safe_search</code> sur <code>0</code> (pour avoir les résultats bruts) et activé l&rsquo;autocomplétion via Google pour m&rsquo;aider à formuler mes recherches plus rapidement. J&rsquo;ai aussi veillé à ce que le temps de bannissement en cas d&rsquo;échec (<code>ban_time_on_fail</code>) soit assez court pour que le système se rétablisse vite si un moteur me bloque temporairement. </p>



<p class="wp-block-paragraph">Avec ces réglages, mon instance SearXNG n&rsquo;est plus un simple site web de recherche ; elle devient une API privée et ultra-rapide qui alimente mon cerveau numérique en temps réel. Nous avons maintenant un moteur de recherche qui parle le même langage que notre IA.</p>



<h2 class="wp-block-heading">V. Le Mariage : Lier Open WebUI, Ollama et Mistral</h2>



<p class="wp-block-paragraph">C’est ici que la magie opère. Jusqu’à présent, nous avons des moteurs puissants qui tournent chacun dans leur coin. Pour créer mon propre « Perplexity », je dois faire d&rsquo;<strong>Open WebUI</strong> le chef d&rsquo;orchestre de ma station. C&rsquo;est lui qui va recevoir mes questions, décider s&rsquo;il doit aller sur le web, et demander à Mistral de rédiger la synthèse finale.</p>



<h3 class="wp-block-heading">L’interface comme centre de commande</h3>



<p class="wp-block-paragraph" id="p-rc_8c4d4be7351ee485-82">Dans mon installation, Open WebUI n&rsquo;est pas qu&rsquo;une simple peau esthétique posée sur un modèle. C&rsquo;est le point de ralliement. Pour que la liaison soit parfaite, j&rsquo;ai configuré les variables d&rsquo;environnement directement dans le <code>docker-compose.yml</code><sup></sup>.</p>



<p class="wp-block-paragraph" id="p-rc_8c4d4be7351ee485-83">Le réglage le plus sensible concerne le <strong>RAG (Retrieval-Augmented Generation)</strong>. J&rsquo;ai activé la recherche web en pointant vers l&rsquo;URL interne de mon conteneur SearXNG<sup></sup>. Comme ils partagent le même réseau Docker, ils communiquent à une vitesse fulgurante.</p>



<p class="wp-block-paragraph">[CODE : Configuration RAG dans docker-compose.yml]</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly># Variables cruciales pour le mariage technique
- ENABLE_RAG_WEB_SEARCH=True
- RAG_WEB_SEARCH_ENGINE=searxng
- SEARXNG_QUERY_URL=http://searxng:8080/search?q=&lt;query>
- RAG_WEB_SEARCH_RESULT_COUNT=5 # Ma recommandation pour ne rien rater
- RAG_WEB_SEARCH_CONCURRENT_REQUESTS=10</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #616E88"># Variables cruciales pour le mariage technique</span></span>
<span class="line"><span style="color: #ECEFF4">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">ENABLE_RAG_WEB_SEARCH=True</span></span>
<span class="line"><span style="color: #ECEFF4">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">RAG_WEB_SEARCH_ENGINE=searxng</span></span>
<span class="line"><span style="color: #ECEFF4">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">SEARXNG_QUERY_URL=http://searxng:8080/search?q=&lt;query&gt;</span></span>
<span class="line"><span style="color: #ECEFF4">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">RAG_WEB_SEARCH_RESULT_COUNT=5</span><span style="color: #D8DEE9FF"> </span><span style="color: #616E88"># Ma recommandation pour ne rien rater</span></span>
<span class="line"><span style="color: #ECEFF4">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">RAG_WEB_SEARCH_CONCURRENT_REQUESTS=10</span></span></code></pre></div>



<h3 class="wp-block-heading">Le choix du modèle : Mistral-Nemo 12B</h3>



<p class="wp-block-paragraph" id="p-rc_8c4d4be7351ee485-84">Pourquoi avoir choisi <strong>Mistral-Nemo 12B</strong> plutôt qu&rsquo;un modèle plus imposant ? Pour une question d&rsquo;équilibre technique. Sur ma carte <strong>RTX 5070 Ti</strong>, ce modèle occupe environ <strong>13 Go de VRAM</strong> lorsqu&rsquo;il est chargé en précision 8-bit (q8_0)<sup></sup>.</p>



<p class="wp-block-paragraph" id="p-rc_8c4d4be7351ee485-85">C&rsquo;est le « sweet spot » : le modèle est assez intelligent pour comprendre des contextes de recherche complexes, tout en laissant assez de place en mémoire vidéo pour que la génération soit quasi instantanée. Si je prenais un modèle plus gros, je risquerais de saturer ma carte et de voir mes performances s&rsquo;effondrer, forçant le système à s&rsquo;appuyer sur le processeur<sup></sup>.</p>



<figure class="wp-block-image size-large"><img width="1024" height="328"  alt="" class="wp-image-253"/ loading="lazy" decoding="async" src="https://tazmenworld.com/wp-content/uploads/2026/04/image-30-1024x328.png" srcset="https://tazmenworld.com/wp-content/uploads/2026/04/image-30-1024x328.png 1024w, https://tazmenworld.com/wp-content/uploads/2026/04/image-30-300x96.png 300w, https://tazmenworld.com/wp-content/uploads/2026/04/image-30-768x246.png 768w, https://tazmenworld.com/wp-content/uploads/2026/04/image-30.png 1353w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<figure class="wp-block-image size-large"><img width="1024" height="495"  alt="" class="wp-image-252"/ loading="lazy" decoding="async" src="https://tazmenworld.com/wp-content/uploads/2026/04/image-29-1024x495.png" srcset="https://tazmenworld.com/wp-content/uploads/2026/04/image-29-1024x495.png 1024w, https://tazmenworld.com/wp-content/uploads/2026/04/image-29-300x145.png 300w, https://tazmenworld.com/wp-content/uploads/2026/04/image-29-768x371.png 768w, https://tazmenworld.com/wp-content/uploads/2026/04/image-29.png 1370w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<h3 class="wp-block-heading">La liaison SearXNG : Le test de vérité</h3>



<p class="wp-block-paragraph">Une fois les services lancés, je me rends dans les paramètres d&rsquo;Open WebUI pour tester la connexion. Il y a un petit indicateur visuel qui confirme que le « Web Search » est actif.</p>



<p class="wp-block-paragraph" id="p-rc_8c4d4be7351ee485-86">Ma petite astuce perso : j&rsquo;ai augmenté le nombre de résultats à <strong>5</strong><sup></sup>. Par défaut, beaucoup d&rsquo;outils s&rsquo;arrêtent à 3. Mais pour des sujets pointus comme la <strong>sécurité informatique</strong>, avoir deux sources supplémentaires permet souvent de dénicher le détail technique qui fait la différence entre une réponse vague et une solution précise.</p>



<figure class="wp-block-video"><video height="810" style="aspect-ratio: 1440 / 810;" width="1440" controls src="https://tazmenworld.com/wp-content/uploads/2026/04/search.mp4" class="lws-optimize-lazyload"></video></figure>



<h3 class="wp-block-heading">Le System Prompt : Donner une personnalité à l&rsquo;IA</h3>



<p class="wp-block-paragraph">Pour que Mistral se comporte comme un analyste et non comme un simple perroquet, j&rsquo;ai affiné son <strong>System Prompt</strong> dans l&rsquo;interface. Je lui demande explicitement de :</p>



<ol start="1" class="wp-block-list">
<li>Analyser systématiquement les sources fournies par SearXNG.</li>



<li>Citer chaque source avec un lien cliquable.</li>



<li>Préciser si les informations trouvées semblent contradictoires ou incomplètes.</li>
</ol>



<p class="wp-block-paragraph">C&rsquo;est cette couche finale qui transforme une suite de conteneurs Docker en un véritable assistant de recherche. Je ne lui demande pas simplement de « savoir », je lui demande de « chercher » avec la rigueur d&rsquo;un documentaliste.</p>



<h2 class="wp-block-heading">VI. Optimisations avancées : Devenir un Power User</h2>



<p class="wp-block-paragraph">Une fois que la liaison entre mon interface et mes moteurs est établie, je ne m&rsquo;arrête pas là. Pour que l&rsquo;expérience dépasse réellement celle d&rsquo;un outil grand public, je dois affiner la qualité des données que Mistral ingère. C&rsquo;est la différence entre une réponse « correcte » et une analyse de niveau expert.</p>



<h3 class="wp-block-heading">Filtrage des sources : Nettoyer le bruit</h3>



<p class="wp-block-paragraph" id="p-rc_928509796eabf825-92">Le web est rempli de sites de basse qualité, de fermes à contenus ou de pages saturées de publicités qui polluent le contexte envoyé à mon IA. Dans mon fichier <code>settings.yml</code>, j&rsquo;ai la possibilité d&rsquo;affiner ce que SearXNG considère comme pertinent<sup></sup>.</p>



<p class="wp-block-paragraph" id="p-rc_928509796eabf825-93">Je privilégie une approche chirurgicale : j&rsquo;augmente le poids (weight) des sources que je juge fiables, comme les dépôts de documentation technique ou les sites académiques, tout en réduisant la visibilité des sites trop généralistes<sup></sup>. C&rsquo;est ce qui permet à mon assistant de ne pas se perdre dans des tutoriels obsolètes quand je lui demande une information sur une bibliothèque Python précise.</p>



<figure class="wp-block-image size-large"><img width="1024" height="709"  alt="" class="wp-image-255"/ loading="lazy" decoding="async" src="https://tazmenworld.com/wp-content/uploads/2026/04/image-31-1024x709.png" srcset="https://tazmenworld.com/wp-content/uploads/2026/04/image-31-1024x709.png 1024w, https://tazmenworld.com/wp-content/uploads/2026/04/image-31-300x208.png 300w, https://tazmenworld.com/wp-content/uploads/2026/04/image-31-768x532.png 768w, https://tazmenworld.com/wp-content/uploads/2026/04/image-31.png 1504w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<h3 class="wp-block-heading">Prompt Engineering : Créer l&rsquo;Assistant Chercheur</h3>



<p class="wp-block-paragraph">Le secret d&rsquo;une bonne synthèse réside dans le <strong>System Prompt</strong>. Dans Open WebUI, je ne laisse pas le champ vide. J&rsquo;ai conçu un modèle de prompt qui force Mistral à adopter une démarche scientifique. Je lui demande de comparer les sources entre elles : « Si deux sites se contredisent sur une version logicielle, mentionne-le explicitement et cherche une troisième source pour arbitrer. »</p>



<p class="wp-block-paragraph" id="p-rc_928509796eabf825-94">Cette instruction change tout. L&rsquo;IA ne se contente plus de résumer ; elle vérifie la cohérence des informations qu&rsquo;elle extrait du web via SearXNG<sup></sup>.</p>



<p class="wp-block-paragraph">[CODE : chercheur_expert_prompt.txt]</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>Tu es un analyste technique de haut niveau. 
Ta mission est de synthétiser les résultats de recherche fournis. 
1. Ignore les publicités et les contenus promotionnels.
2. Priorise les documentations officielles et les forums spécialisés.
3. Cite systématiquement tes sources entre crochets &#91;Source X&#93;.
4. Si les informations sont datées de plus de deux ans, précise-le comme un risque potentiel.</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #A3BE8C">Tu es un analyste technique de haut niveau.</span><span style="color: #D8DEE9FF"> </span></span>
<span class="line"><span style="color: #A3BE8C">Ta mission est de synthétiser les résultats de recherche fournis.</span><span style="color: #D8DEE9FF"> </span></span>
<span class="line"><span style="color: #A3BE8C">1. Ignore les publicités et les contenus promotionnels.</span></span>
<span class="line"><span style="color: #A3BE8C">2. Priorise les documentations officielles et les forums spécialisés.</span></span>
<span class="line"><span style="color: #A3BE8C">3. Cite systématiquement tes sources entre crochets &#91;Source X&#93;.</span></span>
<span class="line"><span style="color: #A3BE8C">4. Si les informations sont datées de plus de deux ans, précise-le comme un risque potentiel.</span></span></code></pre></div>



<h3 class="wp-block-heading">Gestion de la performance et de la VRAM</h3>



<p class="wp-block-paragraph" id="p-rc_928509796eabf825-95">Travailler en local signifie gérer ses ressources. Avec ma <strong>RTX 5070 Ti</strong>, je surveille constamment l&rsquo;occupation de la mémoire vidéo via l&rsquo;outil <code>nvtop</code><sup></sup>. Pour éviter que le système ne ralentisse lors de recherches complexes qui génèrent beaucoup de texte, j&rsquo;ai ajusté la taille du contexte (Context Window) à environ 8 000 tokens.</p>



<p class="wp-block-paragraph" id="p-rc_928509796eabf825-96">C&rsquo;est largement suffisant pour contenir les 5 extraits de recherche de SearXNG et ma propre conversation, tout en gardant une vitesse de génération fulgurante sur mes 13 Go de VRAM disponibles. Si je montais trop haut, la carte pourrait saturer, entrainant une chute drastique des performances au profit du processeur.</p>



<figure class="wp-block-image size-large"><img width="1024" height="752"  alt="" class="wp-image-256"/ loading="lazy" decoding="async" src="https://tazmenworld.com/wp-content/uploads/2026/04/image-32-1024x752.png" srcset="https://tazmenworld.com/wp-content/uploads/2026/04/image-32-1024x752.png 1024w, https://tazmenworld.com/wp-content/uploads/2026/04/image-32-300x220.png 300w, https://tazmenworld.com/wp-content/uploads/2026/04/image-32-768x564.png 768w, https://tazmenworld.com/wp-content/uploads/2026/04/image-32-1536x1128.png 1536w, https://tazmenworld.com/wp-content/uploads/2026/04/image-32.png 1764w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<h3 class="wp-block-heading">Le réglage fin des concurrent requests</h3>



<p class="wp-block-paragraph" id="p-rc_928509796eabf825-97">Dans mon <code>docker-compose.yml</code>, j&rsquo;ai fixé <code>RAG_WEB_SEARCH_CONCURRENT_REQUESTS</code> à <strong>10</strong>. Pourquoi ? Parce que SearXNG est capable d&rsquo;interroger plusieurs moteurs en même temps. En autorisant 10 requêtes simultanées, je m&rsquo;assure que la phase de recherche ne prend que quelques millisecondes. Mon IA reçoit ses données presque instantanément, ce qui rend l&rsquo;interaction aussi fluide, voire plus, qu&rsquo;avec un service en ligne. </p>



<p class="wp-block-paragraph">Toutes ces petites touches font que ma machine ne se contente pas d&rsquo;imiter un service existant ; elle s&rsquo;adapte précisément à mes besoins et à mon matériel.</p>



<h2 class="wp-block-heading">VII. Démonstration de cas d&rsquo;usage réels</h2>



<p class="wp-block-paragraph">Installer toute cette artillerie est une chose, mais la vraie question demeure : est-ce que ça tient la route face à Perplexity au quotidien ? Pour le savoir, j&rsquo;ai soumis ma station à plusieurs tests intensifs. Voici comment se comporte ce duo Mistral-SearXNG sur des terrains où l&rsquo;on attend normalement des services payants au tournant.</p>



<h3 class="wp-block-heading">Cas d&rsquo;usage n°1 : La veille en cybersécurité</h3>



<p class="wp-block-paragraph">En tant que passionné de <strong>sécurité</strong>, je cherche souvent des détails sur des failles fraîchement découvertes. J&rsquo;ai posé la question suivante : <em>« Quelles sont les dernières vulnérabilités signalées sur Ollama ou les frameworks d&rsquo;IA locale cette semaine ? »</em></p>



<p class="wp-block-paragraph" id="p-rc_2951e23daf06491c-110">Grâce à SearXNG, mon système n&rsquo;est pas allé interroger une base de données statique. Il a fouillé GitHub, des blogs spécialisés et des sites de CVE. Mistral-Nemo a ensuite synthétisé les résultats en isolant les vecteurs d&rsquo;attaque potentiels. </p>



<p class="wp-block-paragraph" id="p-rc_2951e23daf06491c-111"><strong>Le verdict :</strong> La réponse est arrivée en moins de 10 secondes. Là où Perplexity m&rsquo;aurait parfois noyé sous des sources généralistes, ma configuration locale a privilégié les dépôts techniques parce que j&rsquo;ai configuré mes moteurs pour cela<sup></sup>.</p>



<figure class="wp-block-image size-large"><img width="1024" height="427"  alt="" class="wp-image-257"/ loading="lazy" decoding="async" src="https://tazmenworld.com/wp-content/uploads/2026/04/image-33-1024x427.png" srcset="https://tazmenworld.com/wp-content/uploads/2026/04/image-33-1024x427.png 1024w, https://tazmenworld.com/wp-content/uploads/2026/04/image-33-300x125.png 300w, https://tazmenworld.com/wp-content/uploads/2026/04/image-33-768x320.png 768w, https://tazmenworld.com/wp-content/uploads/2026/04/image-33-1536x641.png 1536w, https://tazmenworld.com/wp-content/uploads/2026/04/image-33.png 1685w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<h3 class="wp-block-heading">Cas d&rsquo;usage n°2 : La vie pratique (Le test du programme TV)</h3>



<p class="wp-block-paragraph">C&rsquo;est le test ultime pour vérifier la fraîcheur des données : <em>« Il y a quoi demain soir sur TF1 ? »</em> Pour une IA classique, c&rsquo;est une question piège. Pour mon installation, c&rsquo;est une routine de recherche web.</p>



<p class="wp-block-paragraph" id="p-rc_2951e23daf06491c-112">Open WebUI a lancé SearXNG, qui a récupéré les grilles horaires de plusieurs sites de programmes TV<sup></sup>. Mistral a lu ces extraits et m&rsquo;a présenté une réponse claire, avec les horaires précis.</p>



<figure class="wp-block-image size-large"><img width="1024" height="532"  alt="" class="wp-image-258"/ loading="lazy" decoding="async" src="https://tazmenworld.com/wp-content/uploads/2026/04/image-34-1024x532.png" srcset="https://tazmenworld.com/wp-content/uploads/2026/04/image-34-1024x532.png 1024w, https://tazmenworld.com/wp-content/uploads/2026/04/image-34-300x156.png 300w, https://tazmenworld.com/wp-content/uploads/2026/04/image-34-768x399.png 768w, https://tazmenworld.com/wp-content/uploads/2026/04/image-34-1536x798.png 1536w, https://tazmenworld.com/wp-content/uploads/2026/04/image-34.png 1748w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph"><strong>Le verdict :</strong> La précision est identique à celle d&rsquo;un moteur commercial. La seule différence ? Personne d&rsquo;autre que moi ne sait que j&rsquo;ai prévu de regarder un documentaire ou un film demain soir. Ma vie privée est préservée pour une information pourtant banale.</p>



<h3 class="wp-block-heading">Cas d&rsquo;usage n°3 : Développement et Hardware</h3>



<p class="wp-block-paragraph">J&rsquo;ai testé une requête technique sur mon propre matériel : <em>« Quelles sont les optimisations recommandées pour faire tourner Mistral-Nemo sur une RTX 5070 Ti sous Ubuntu ? »</em></p>



<p class="wp-block-paragraph" id="p-rc_2951e23daf06491c-113">Le système a croisé des benchmarks récents et des discussions sur des forums spécialisés. Il m&rsquo;a suggéré d&rsquo;utiliser des versions quantifiées (q8_0) pour occuper environ 13 Go de VRAM et conserver une réactivité maximale. C&rsquo;est exactement ce que j&rsquo;ai constaté en surveillant mon outil <code>nvtop</code>. </p>



<figure class="wp-block-image size-large"><img width="1024" height="589"  alt="" class="wp-image-259"/ loading="lazy" decoding="async" src="https://tazmenworld.com/wp-content/uploads/2026/04/image-35-1024x589.png" srcset="https://tazmenworld.com/wp-content/uploads/2026/04/image-35-1024x589.png 1024w, https://tazmenworld.com/wp-content/uploads/2026/04/image-35-300x173.png 300w, https://tazmenworld.com/wp-content/uploads/2026/04/image-35-768x442.png 768w, https://tazmenworld.com/wp-content/uploads/2026/04/image-35.png 1120w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<h3 class="wp-block-heading">Bilan de performance</h3>



<p class="wp-block-paragraph">Après plusieurs jours d&rsquo;utilisation intensive, voici mon constat :</p>



<ul class="wp-block-list">
<li><strong>Rapidité :</strong> Sur ma machine (Ryzen 9 9900X et RTX 5070 Ti), la génération est quasi instantanée après la phase de recherche web qui prend environ 2 secondes. </li>



<li><strong>Pertinence :</strong> En passant à 5 sources de recherche au lieu de 3, j&rsquo;ai éliminé la majorité des réponses incomplètes que j&rsquo;avais au début de mes tests.</li>



<li><strong>Confidentialité :</strong> C&rsquo;est le point de rupture total avec les solutions cloud. Je peux poser des questions sur des codes sources privés ou des documents sensibles sans aucune crainte.</li>
</ul>



<p class="wp-block-paragraph">[CODE : exemple_reponse_sourcee.json]</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>{
  "question": "Dernière version stable de SearXNG ?",
  "reponse": "La version actuelle est disponible sur GitHub...",
  "sources": &#91;
    {"titre": "SearXNG Releases", "url": "https://github.com/searxng/searxng/releases"},
    {"titre": "Documentation officielle", "url": "https://docs.searxng.org/"}
  &#93;
}</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">question</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Dernière version stable de SearXNG ?</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">reponse</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">La version actuelle est disponible sur GitHub...</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">sources</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&#91;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">{</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">titre</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">SearXNG Releases</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">url</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">https://github.com/searxng/searxng/releases</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">},</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">{</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">titre</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Documentation officielle</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">url</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">https://docs.searxng.org/</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #ECEFF4">&#93;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span></code></pre></div>



<p class="wp-block-paragraph">En résumé, remplacer Perplexity n&rsquo;est pas seulement une déclaration d&rsquo;indépendance ; c&rsquo;est un gain réel en précision et en tranquillité d&rsquo;esprit pour quiconque prend ses données au sérieux.</p>



<h2 class="wp-block-heading">VIII. Conclusion : Le bilan de la liberté</h2>



<p class="wp-block-paragraph">Après avoir parcouru ce long chemin de configuration, de réglages de fichiers YAML et de tests de requêtes, je me pose souvent la question : est-ce que le jeu en vaut la chandelle ? La réponse, pour moi, est un grand « oui ».</p>



<p class="wp-block-paragraph">Remplacer Perplexity par une solution locale n&rsquo;est pas seulement un défi technique gratifiant. C&rsquo;est un acte de reprise de contrôle. En voyant ma <strong>RTX 5070 Ti</strong> grimper à 79% de charge pour synthétiser en quelques secondes une réponse complexe, je ressens une satisfaction que seul le « fait maison » peut procurer.</p>



<h3 class="wp-block-heading">Performance vs Praticité : L&rsquo;heure du bilan</h3>



<p class="wp-block-paragraph">Si l&rsquo;on regarde froidement les chiffres, voici ce que je retiens de ma <strong>Tazmen Station</strong> face aux solutions propriétaires :</p>



<ul class="wp-block-list">
<li><strong>Vie privée :</strong> C&rsquo;est la victoire par K.O. Aucune de mes données ne quitte mon réseau local. SearXNG agit comme un bouclier impénétrable entre mes intentions de recherche et les régies publicitaires.</li>



<li><strong>Vitesse :</strong> Grâce au couple <strong>Ryzen 9 9900X</strong> et GPU NVIDIA, la latence est extrêmement faible. Une fois la phase de recherche web terminée, Mistral-Nemo génère du texte à une vitesse qui n&rsquo;a rien à envier aux versions payantes de GPT ou Claude. </li>



<li><strong>Coût :</strong> Certes, l&rsquo;investissement matériel est là. Mais à 20 € par mois d&rsquo;abonnement économisés, ma station est rentabilisée sur la durée, sans compter qu&rsquo;elle me sert aussi pour d&rsquo;autres tâches lourdes.</li>



<li><strong>Précision :</strong> En forçant le système à lire 5 sources via SearXNG au lieu des 3 habituelles, j&rsquo;ai obtenu une profondeur d&rsquo;analyse qui m&rsquo;a bluffé, notamment sur les sujets de <strong>sécurité</strong>.</li>
</ul>



<figure class="wp-block-table"><table class="has-fixed-layout"><tbody><tr><td><strong>Caractéristique</strong></td><td><strong>Perplexity (Cloud)</strong></td><td><strong>Mistral Local + SearXNG</strong></td></tr><tr><td><strong>Vie privée &amp; Sécurité</strong></td><td>Données traitées sur serveurs tiers (Cloud).</td><td>Souveraineté totale : aucune donnée ne quitte ton réseau local.</td></tr><tr><td><strong>Coût mensuel</strong></td><td>Environ 20 $ / mois pour la version Pro.</td><td>0 € (une fois le matériel acquis).</td></tr><tr><td><strong>Moteur de recherche</strong></td><td>Algorithme propriétaire (boîte noire).</td><td><strong>SearXNG</strong> : Agrégateur anonyme et transparent (Bing, Google, Brave, etc.).</td></tr><tr><td><strong>Contrôle du RAG</strong></td><td>Limité aux réglages de l&rsquo;interface.</td><td>Maîtrise totale du nombre de sources (ex: 5 sources) et du filtrage.</td></tr><tr><td><strong>Matériel requis</strong></td><td>Une simple connexion internet.</td><td>GPU dédié (<strong>RTX 5070 Ti</strong>) et CPU performant (<strong>Ryzen 9 9900X</strong>).</td></tr><tr><td><strong>Dépendance</strong></td><td>Dépend de la connexion et de la stabilité du service tiers.</td><td>Autonomie complète : fonctionne même hors-ligne (hors recherche web).</td></tr><tr><td><strong>Modèles de langage</strong></td><td>Modèles imposés (GPT-4, Claude, etc.).</td><td>Liberté de choix et de mise à jour (ex: <strong>Mistral-Nemo 12B</strong>).</td></tr><tr><td><strong>Performance (Inférence)</strong></td><td>Variable selon la charge des serveurs distants.</td><td>Quasi instantanée sur GPU local (13 Go de VRAM mobilisés).</td></tr></tbody></table></figure>



<h3 class="wp-block-heading">Et quoi après ?</h3>



<p class="wp-block-paragraph" id="p-rc_ba25ed05b53015be-130">Ce guide n&rsquo;est que le début. Avec cette infrastructure Docker solide, je peux maintenant explorer de nouveaux horizons<sup></sup>. L&rsquo;étape suivante pour moi sera d&rsquo;intégrer des agents autonomes capables d&rsquo;exécuter des tâches encore plus complexes à partir de mes recherches web.</p>



<p class="wp-block-paragraph">Bâtir sa propre IA, c&rsquo;est accepter de passer un peu de temps dans son terminal pour gagner une liberté qui n&rsquo;a pas de prix. J&rsquo;espère que ce guide vous aura donné les clés pour, vous aussi, transformer votre machine Ubuntu en une forteresse d&rsquo;intelligence privée.</p>



<p class="wp-block-paragraph">[CODE : commande_finale_restart.sh]</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly># Pour relancer l'ensemble après une mise à jour des modèles
sudo docker compose down &amp;&amp; sudo docker compose up -d --remove-orphans</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #616E88"># Pour relancer l&#39;ensemble après une mise à jour des modèles</span></span>
<span class="line"><span style="color: #A3BE8C">sudo docker compose down &amp;&amp; sudo docker compose up -d --remove-orphans</span></span></code></pre></div>



<p class="wp-block-paragraph">Merci de m&rsquo;avoir suivi dans cette exploration technique. Si vous avez des questions sur la configuration de votre GPU ou sur les subtilités de SearXNG, n&rsquo;hésitez pas à partager vos retours. La route vers l&rsquo;IA locale est vaste, et nous ne faisons que commencer à en dessiner les contours. </p>



<p class="wp-block-paragraph">A bientôt Louis 🐇 🤜 🤛 🐰</p>



<p class="wp-block-paragraph"></p>
]]></content:encoded>
					
					<wfw:commentRss>https://tazmenworld.com/2026/04/30/comment-remplacer-perplexity-par-mistral-en-local/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		<enclosure url="https://tazmenworld.com/wp-content/uploads/2026/04/search.mp4" length="2251368" type="video/mp4" />

			</item>
		<item>
		<title>La Chine est en train de dépasser les Américains sur l&#8217;IA, et &#8230;.. c&#8217;est une étude américaine qui le dit</title>
		<link>https://tazmenworld.com/2026/04/23/la-chine-est-en-train-de-depasser-les-americains-sur-lia-et-cest-une-etude-americaine-qui-le-dit/</link>
					<comments>https://tazmenworld.com/2026/04/23/la-chine-est-en-train-de-depasser-les-americains-sur-lia-et-cest-une-etude-americaine-qui-le-dit/#respond</comments>
		
		<dc:creator><![CDATA[tazmen3]]></dc:creator>
		<pubDate>Thu, 23 Apr 2026 15:05:21 +0000</pubDate>
				<category><![CDATA[Intelligence Artificielle (IA)]]></category>
		<guid isPermaLink="false">https://tazmenworld.com/?p=232</guid>

					<description><![CDATA[Si tu suis mes articles sur l&#8217;optimisation hardware et le scripting headless, tu sais que je ne suis pas du genre à m&#8217;emballer pour les communiqués de presse lisses ou les promesses marketing. Mais aujourd&#8217;hui, on va lever le nez du terminal pour regarder un dossier qui va sérieusement bousculer nos habitudes. Le baromètre mondial [&#8230;]]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-large"><img width="1024" height="559"  alt="" class="wp-image-238"/ loading="lazy" decoding="async" src="https://tazmenworld.com/wp-content/uploads/2026/04/Image_x9nge8x9nge8x9ng-1024x559.png" srcset="https://tazmenworld.com/wp-content/uploads/2026/04/Image_x9nge8x9nge8x9ng-1024x559.png 1024w, https://tazmenworld.com/wp-content/uploads/2026/04/Image_x9nge8x9nge8x9ng-300x164.png 300w, https://tazmenworld.com/wp-content/uploads/2026/04/Image_x9nge8x9nge8x9ng-768x419.png 768w, https://tazmenworld.com/wp-content/uploads/2026/04/Image_x9nge8x9nge8x9ng-1536x838.png 1536w, https://tazmenworld.com/wp-content/uploads/2026/04/Image_x9nge8x9nge8x9ng-2048x1117.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">Si tu suis mes articles sur l&rsquo;optimisation hardware et le scripting headless, tu sais que je ne suis pas du genre à m&#8217;emballer pour les communiqués de presse lisses ou les promesses marketing. Mais aujourd&rsquo;hui, on va lever le nez du terminal pour regarder un dossier qui va sérieusement bousculer nos habitudes.</p>



<p class="wp-block-paragraph">Le baromètre mondial de l&rsquo;IA (le fameux AI Index Report 2026 de Stanford) vient de sortir, et c’est une sacrée douche froide pour ceux qui pensaient que l’hégémonie de la Silicon Valley était gravée dans le marbre. On ne parle pas de spéculation ou de propagande, mais de faits documentés par l&rsquo;élite universitaire américaine : la Chine n&rsquo;est plus dans le rétroviseur, elle est en train de déboîter sur la file de gauche.</p>



<p class="wp-block-paragraph">Dans cet article, on va plonger dans le dur. On va voir comment les ingénieurs chinois ont réussi à transformer les sanctions sur les puces en un moteur pour leur propre souveraineté technique. On va parler de modèles massifs entraînés sans une seule puce Nvidia, de la fin de la dépendance à TSMC et de ce que cela signifie concrètement pour nos futures infras. Pas de langue de bois, juste de la technique, des chiffres et de la géopolitique appliquée. Attache ta ceinture, on va parler puissance brute et silicium.</p>



<h2 class="wp-block-heading">L&rsquo;évaporation de l&rsquo;écart technique : les chiffres qui fâchent</h2>



<p class="wp-block-paragraph">Pendant que les médias occidentaux se focalisaient sur les chatbots capables de générer des poèmes, les labos chinois ont bossé sur la performance brute. Le rapport de Stanford met en lumière une donnée qui devrait donner des sueurs froides à la tech américaine : l&rsquo;écart de performance entre les meilleurs modèles américains et les fleurons chinois comme DeepSeek ou Qwen est désormais inférieur à 3 %.</p>



<p class="wp-block-paragraph">En mars 2026, sur les benchmarks les plus exigeants ceux qui testent le codage informatique complexe, les mathématiques de niveau compétition et les raisonnements scientifiques de niveau doctorat la supériorité américaine est devenue un concept purement théorique. Pour nous, qui utilisons ces outils pour automatiser des workflows ou scripter des tâches complexes, la différence est devenue imperceptible en production.</p>



<figure class="wp-block-image size-full"><img width="906" height="632"  alt="" class="wp-image-233"/ loading="lazy" decoding="async" src="https://tazmenworld.com/wp-content/uploads/2026/04/image-17.png" srcset="https://tazmenworld.com/wp-content/uploads/2026/04/image-17.png 906w, https://tazmenworld.com/wp-content/uploads/2026/04/image-17-300x209.png 300w, https://tazmenworld.com/wp-content/uploads/2026/04/image-17-768x536.png 768w" sizes="auto, (max-width: 906px) 100vw, 906px" /><figcaption class="wp-element-caption">Benchmarks de performance technique de l&rsquo;IA sélectifs par rapport aux performances humaines. source: ai_index_report_2026</figcaption></figure>



<h2 class="wp-block-heading">Le cas DeepSeek V4 : 1000 milliards de paramètres sans Nvidia</h2>



<p class="wp-block-paragraph">C&rsquo;est ici qu&rsquo;on entre dans le vif du sujet hardware. Les USA ont misé gros sur l&#8217;embargo des puces H100 et H200 de Nvidia pour freiner la Chine. Ils ont pensé qu&rsquo;en coupant l&rsquo;accès au silicium de pointe produit par TSMC, ils bloqueraient net la capacité de calcul chinoise.</p>



<p class="wp-block-paragraph">C&rsquo;est exactement l&rsquo;inverse qui s&rsquo;est produit. Le rapport mentionne l&rsquo;émergence de DeepSeek V4, un modèle massif de 1 000 milliards de paramètres. La véritable claque technique réside dans le fait que ce modèle a été entraîné à 100 % sur des clusters de puces Huawei Ascend.</p>



<p class="wp-block-paragraph">Habituellement, l&rsquo;entraînement de modèles de cette taille nécessite une interconnexion ultra-rapide entre les puces, un domaine où Nvidia régnait sans partage avec son protocole NVLink. Huawei a réussi à développer sa propre stack complète pour contourner ce goulot d&rsquo;étranglement :</p>



<ol start="1" class="wp-block-list">
<li>Les puces Ascend qui, bien que moins performantes par unité que les dernières Blackwell de Nvidia, sont optimisées pour travailler en clusters géants de manière très cohérente.</li>



<li>Un framework propriétaire, MindSpore, qui remplace PyTorch et qui est taillé sur mesure pour exploiter le silicium domestique.</li>



<li>Une indépendance totale vis-à-vis de TSMC pour la production, la Chine ayant réussi à optimiser ses procédés de lithographie pour sortir des volumes suffisants de puces de calcul performantes.</li>
</ol>



<p class="wp-block-paragraph">On est passé d&rsquo;une dépendance critique à une autonomie forcée. La Chine a appris à faire de l&rsquo;IA avec son propre hardware, là où le reste du monde est encore suspendu aux carnets de commandes de Nvidia.</p>



<h2 class="wp-block-heading">L&rsquo;architecture MoE et l&rsquo;optimisation au couteau</h2>



<p class="wp-block-paragraph">Si tu as lu mes posts sur le VRAM tuning, tu sais que la mémoire est le nerf de la guerre. Les ingénieurs chinois n&rsquo;ont pas cherché à copier bêtement l&rsquo;approche de puissance brute adoptée par OpenAI. Ils ont poussé l&rsquo;architecture Mixture of Experts (MoE) dans ses derniers retranchements.</p>



<p class="wp-block-paragraph">L&rsquo;idée est simple : au lieu d&rsquo;activer les 1000 milliards de paramètres à chaque requête, le modèle ne sollicite que les experts concernés par le sujet. Cela permet de réduire la consommation électrique et, surtout, de faire tourner des modèles très puissants sur des configurations hardware qui auraient été jugées insuffisantes il y a deux ans. En clair, ils font plus avec moins de VRAM, ce qui est un avantage stratégique énorme quand on a un accès limité au hardware de pointe.</p>



<figure class="wp-block-image size-full"><img width="537" height="948"  alt="" class="wp-image-235"/ loading="lazy" decoding="async" src="https://tazmenworld.com/wp-content/uploads/2026/04/architecture-Dense.jpg" srcset="https://tazmenworld.com/wp-content/uploads/2026/04/architecture-Dense.jpg 537w, https://tazmenworld.com/wp-content/uploads/2026/04/architecture-Dense-170x300.jpg 170w" sizes="auto, (max-width: 537px) 100vw, 537px" /><figcaption class="wp-element-caption">Architecture <em>Dense</em>, chaque neurone est connecté à tous les neurones de la couche suivante (comme un réseau classique)</figcaption></figure>



<figure class="wp-block-image size-full is-resized"><img width="682" height="700"  alt="" class="wp-image-236" style="width:682px;height:auto"/ loading="lazy" decoding="async" src="https://tazmenworld.com/wp-content/uploads/2026/04/architecture-Mixture-of-Experts-MoE.jpg" srcset="https://tazmenworld.com/wp-content/uploads/2026/04/architecture-Mixture-of-Experts-MoE.jpg 682w, https://tazmenworld.com/wp-content/uploads/2026/04/architecture-Mixture-of-Experts-MoE-292x300.jpg 292w" sizes="auto, (max-width: 682px) 100vw, 682px" /><figcaption class="wp-element-caption"><em>Mixture of Experts (MoE)</em> utilise plusieurs sous-réseaux spécialisés (<em>experts</em>), activés dynamiquement par un <em>gating network</em> pour traiter l’entrée, combinant ensuite leurs résultats pondérés, ce qui permet une modélisation plus flexible et efficace pour des tâches complexes</figcaption></figure>



<h2 class="wp-block-heading">La fuite des cerveaux à l&rsquo;envers : l&rsquo;impact politique</h2>



<p class="wp-block-paragraph">Le rapport de Stanford souligne un point critique sur le capital humain, et c’est peut-être là que le bât blesse le plus pour Washington. Historiquement, les USA étaient un aspirateur à talents sans équivalent. Un étudiant chinois brillant finissait ses études à Stanford et restait bosser dans la Silicon Valley pour créer de la valeur aux États-Unis.</p>



<p class="wp-block-paragraph">Ce cycle vertueux pour l’économie américaine est en train de se briser. Le rapport note une chute brutale de 89 % des arrivées de chercheurs étrangers en IA aux USA depuis 2017. Cette date n&rsquo;est pas un hasard : elle marque le début du durcissement drastique de la politique migratoire sous l&rsquo;administration Trump.</p>



<p class="wp-block-paragraph">L&rsquo;image projetée à l&rsquo;international, marquée par une administration perçue comme hostile aux étrangers et les actions d&rsquo;une agence comme l&rsquo;ICE (Immigration and Customs Enforcement) aux méthodes de plus en plus paramilitaires, a créé un climat de méfiance profonde. Pour un chercheur de haut niveau, le rêve américain a été remplacé par l&rsquo;incertitude des visas et un sentiment d&rsquo;insécurité.</p>



<p class="wp-block-paragraph">Aujourd&rsquo;hui, la majorité des cerveaux formés en Chine, ou même ceux formés aux États-Unis, choisissent de retourner au pays pour monter des structures ou rejoindre des géants comme Baidu, Tencent ou Huawei. Ce n&rsquo;est plus seulement une guerre de puces, c&rsquo;est une guerre de neurones, et les USA sont en train de perdre leur force d&rsquo;attraction principale. La Chine produit désormais plus de papiers de recherche de haut niveau que n&rsquo;importe quelle autre nation, et la force de leur système est que ces recherches sont immédiatement injectées dans leur tissu industriel.</p>



<figure class="wp-block-image size-full"><img width="932" height="1001"  alt="" class="wp-image-237"/ loading="lazy" decoding="async" src="https://tazmenworld.com/wp-content/uploads/2026/04/image-18.png" srcset="https://tazmenworld.com/wp-content/uploads/2026/04/image-18.png 932w, https://tazmenworld.com/wp-content/uploads/2026/04/image-18-279x300.png 279w, https://tazmenworld.com/wp-content/uploads/2026/04/image-18-768x825.png 768w" sizes="auto, (max-width: 932px) 100vw, 932px" /><figcaption class="wp-element-caption">Tableau issu du chapitre Economy du rapport montrant la répartition géographique des publications de recherche en IA. source: ai_index_report_2026</figcaption></figure>



<h2 class="wp-block-heading">La frontière en dents de scie et le pragmatisme industriel</h2>



<p class="wp-block-paragraph">Un concept fondamental du rapport est la Sawtooth Frontier. Cela décrit le fait que l&rsquo;IA ne progresse pas de manière uniforme. Un modèle peut être un génie en programmation mais être incapable de comprendre un concept social simple.</p>



<p class="wp-block-paragraph">Alors que les Américains cherchent à créer une Intelligence Artificielle Générale capable de tout faire, les Chinois se concentrent sur une IA de production. Leurs investissements massifs sont fléchés vers des domaines concrets :</p>



<ol start="1" class="wp-block-list">
<li>L&rsquo;optimisation des réseaux électriques et des flux logistiques.</li>



<li>La conception assistée de nouveaux matériaux et semi-conducteurs.</li>



<li>L&rsquo;automatisation de la cybersécurité.</li>
</ol>



<p class="wp-block-paragraph">C&rsquo;est une approche purement utilitaire. Ils ne cherchent pas à ce que l&rsquo;IA soit humaine, ils cherchent à ce qu&rsquo;elle soit efficace. C&rsquo;est du headless appliqué à l&rsquo;échelle d&rsquo;un pays : on enlève l&rsquo;interface polie pour ne garder que le moteur de calcul.</p>



<h2 class="wp-block-heading">Le coût caché : l&rsquo;alerte environnementale</h2>



<p class="wp-block-paragraph">Même si la Chine gagne la course, le rapport de Stanford tire une sonnette d&rsquo;alarme sur le coût énergétique et environnemental. On parle souvent de la consommation des datacenters, mais les chiffres ici sont vertigineux. L&rsquo;entraînement d&rsquo;un modèle comme DeepSeek V4 consomme plus d&rsquo;eau pour le refroidissement que ce que consomme une ville moyenne en un an.</p>



<p class="wp-block-paragraph">La Chine, avec ses besoins énergétiques monstrueux, semble prête à payer ce prix pour la domination technologique. C&rsquo;est un facteur que les régulations européennes ou américaines pourraient limiter chez nous, créant un nouveau déséquilibre compétitif majeur.</p>



<h2 class="wp-block-heading">Conclusion : On fait quoi maintenant ?</h2>



<p class="wp-block-paragraph">On ne va pas se mentir : le centre de gravité a basculé. Ce rapport de Stanford n&rsquo;est pas une simple étude de plus, c&rsquo;est l&rsquo;aveu de la fin d&rsquo;un monopole. Pour nous, les techniciens, cela signifie que notre boîte à outils va changer.</p>



<p class="wp-block-paragraph">Il va falloir apprendre à bosser avec ces modèles venus d&rsquo;ailleurs, comprendre leurs frameworks et arrêter de penser que si ce n&rsquo;est pas développé en Californie, c&rsquo;est forcément moins bon. La réalité du terrain, celle des benchmarks et des clusters de serveurs, raconte une tout autre histoire.</p>



<p class="wp-block-paragraph">On est à l&rsquo;aube d&rsquo;une ère où la puissance de calcul ne dépendra plus d&rsquo;une seule marque de cartes graphiques ou d&rsquo;une seule fonderie à Taïwan. C&rsquo;est le retour de la diversité technique, et pour ceux qui aiment l&rsquo;optimisation et la performance, c&rsquo;est un nouveau terrain de jeu passionnant.</p>



<p class="wp-block-paragraph">On se retrouve pour le prochain article où on verra comment installer et quantifier localement ces nouveaux modèles pour voir ce qu&rsquo;ils ont vraiment dans le ventre.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">Analyse comparative (Données Stanford AI Index 2026)</h3>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><td><strong>Critère</strong></td><td><strong>Bloc Américain</strong></td><td><strong>Bloc Chinois</strong></td></tr></thead><tbody><tr><td>Hardware dominant</td><td>Nvidia (Série H/Blackwell)</td><td>Huawei (Série Ascend)</td></tr><tr><td>Dépendance TSMC</td><td>Totale (N3/N2)</td><td>En forte diminution</td></tr><tr><td>Stratégie de modèle</td><td>AGI / Conversationnel</td><td>Industriel / Efficience MoE</td></tr><tr><td>Flux de talents</td><td>En baisse (Immigration -89%)</td><td>En hausse (Rétention interne)</td></tr><tr><td>Contexte politique</td><td>Instabilité des visas / ICE</td><td>Souveraineté et rapatriement</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">Source: https://hai.stanford.edu/ai-index</p>
]]></content:encoded>
					
					<wfw:commentRss>https://tazmenworld.com/2026/04/23/la-chine-est-en-train-de-depasser-les-americains-sur-lia-et-cest-une-etude-americaine-qui-le-dit/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Diagrammes auto-générés : Comment piloter Excalidraw en local avec une IA sans aucun effort</title>
		<link>https://tazmenworld.com/2026/04/22/diagrammes-auto-generes-comment-piloter-excalidraw-en-local-avec-une-ia-sans-aucun-effort/</link>
					<comments>https://tazmenworld.com/2026/04/22/diagrammes-auto-generes-comment-piloter-excalidraw-en-local-avec-une-ia-sans-aucun-effort/#respond</comments>
		
		<dc:creator><![CDATA[tazmen3]]></dc:creator>
		<pubDate>Wed, 22 Apr 2026 07:12:49 +0000</pubDate>
				<category><![CDATA[Intelligence Artificielle (IA)]]></category>
		<guid isPermaLink="false">https://tazmenworld.com/?p=224</guid>

					<description><![CDATA[Aujourd&#8217;hui, on va parler d&#8217;un sujet qui me tient à cœur : comment faire bosser une IA à sa place quand on a une tablette graphique, des idées, mais une flemme monumentale de tracer des flèches droites. On va transformer une simple interface de dessin en un outil agentique piloté par Ollama. Accrochez-vous, ça va [&#8230;]]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-large"><img width="1024" height="572"  alt="" class="wp-image-229"/ loading="lazy" decoding="async" src="https://tazmenworld.com/wp-content/uploads/2026/04/47yhmv47yhmv47yh_cleanup-1024x572.png" srcset="https://tazmenworld.com/wp-content/uploads/2026/04/47yhmv47yhmv47yh_cleanup-1024x572.png 1024w, https://tazmenworld.com/wp-content/uploads/2026/04/47yhmv47yhmv47yh_cleanup-300x167.png 300w, https://tazmenworld.com/wp-content/uploads/2026/04/47yhmv47yhmv47yh_cleanup-768x429.png 768w, https://tazmenworld.com/wp-content/uploads/2026/04/47yhmv47yhmv47yh_cleanup.png 1376w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">Aujourd&rsquo;hui, on va parler d&rsquo;un sujet qui me tient à cœur : comment faire bosser une IA à sa place quand on a une tablette graphique, des idées, mais une flemme monumentale de tracer des flèches droites. On va transformer une simple interface de dessin en un outil agentique piloté par Ollama. Accrochez-vous, ça va être dense.</p>



<h2 class="wp-block-heading">L&rsquo;Intro : La Tablette, la Formation et la Grosse Flemme</h2>



<p class="wp-block-paragraph">Quand je donne des formations, j’adore utiliser Excalidraw. C&rsquo;est souple, c&rsquo;est propre, et avec ma tablette, j&rsquo;ai l&rsquo;impression d&rsquo;être sur un vrai tableau blanc. C&rsquo;est parfait pour gribouiller des concepts en direct. Mais on va être honnête deux minutes : parfois, je suis en manque total d’inspiration pour mes schémas.</p>



<p class="wp-block-paragraph">Dessiner une architecture microservices avec 15 nœuds, trois bases de données et un bus de messages alors que j&rsquo;ai déjà parlé pendant trois heures ? J&rsquo;ai juste une grosse flemme. L’idée, c&rsquo;était simple : je veux une IA, en local (parce que ma VRAM, je l&rsquo;ai payée, alors je l&rsquo;utilise), qui puisse « tenir le pinceau » pendant que j&rsquo;explique le concept aux élèves. On ne parle pas juste de générer une image statique, mais d&rsquo;avoir un vrai <strong>Agent</strong> qui manipule le canvas en temps réel sous mes yeux.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">Étape 1 : Monter le Tableau Blanc (Installation d&rsquo;Excalidraw)</h2>



<p class="wp-block-paragraph" id="p-rc_bd3390bc77cb145e-172">Avant de parler IA, il nous faut le support. La façon la plus simple et la plus propre de faire tourner Excalidraw chez soi sans dépendre du cloud, c&rsquo;est Docker<sup></sup>.</p>



<p class="wp-block-paragraph" id="p-rc_bd3390bc77cb145e-173">Tu peux le lancer en une seule ligne de commande pour tester<sup></sup>: <code>docker run --rm -dit --name excalidraw -p 8000:80 excalidraw/excalidraw:latest</code><sup></sup>.</p>



<p class="wp-block-paragraph">Mais comme on est sur une <strong>AI Station</strong> sérieuse, on va l&rsquo;intégrer proprement dans notre <code>docker-compose.yml</code>. Cela nous permet de gérer les ports et les redémarrages automatiques.</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly># --- TABLEAU BLANC EXCALIDRAW ---
  excalidraw:
    image: excalidraw/excalidraw:latest
    container_name: excalidraw
    ports:
      - "8000:80" # Accessible sur http://localhost:8000
    restart: unless-stopped</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #616E88"># --- TABLEAU BLANC EXCALIDRAW ---</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">excalidraw:</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">image:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">excalidraw/excalidraw:latest</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">container_name:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">excalidraw</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">ports:</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">8000:80</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF"> </span><span style="color: #616E88"># Accessible sur http://localhost:8000</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">restart:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">unless-stopped</span></span></code></pre></div>



<p class="wp-block-paragraph"><br>Une fois que c&rsquo;est lancé, tu as ton Excalidraw perso sur le port 8000. C’est rapide, c’est léger, et ça ne demande aucune configuration complexe pour commencer à dessiner avec sa tablette ou sur son ordinateur et c&rsquo;est gratuit :D.<br></p>



<figure class="wp-block-image size-large"><img width="1024" height="746"  alt="" class="wp-image-225"/ loading="lazy" decoding="async" src="https://tazmenworld.com/wp-content/uploads/2026/04/image-16-1024x746.png" srcset="https://tazmenworld.com/wp-content/uploads/2026/04/image-16-1024x746.png 1024w, https://tazmenworld.com/wp-content/uploads/2026/04/image-16-300x219.png 300w, https://tazmenworld.com/wp-content/uploads/2026/04/image-16-768x560.png 768w, https://tazmenworld.com/wp-content/uploads/2026/04/image-16.png 1253w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading">Étape 2 : L&rsquo;Intelligence de Dessin (Serveur MCP)</h2>



<p class="wp-block-paragraph" id="p-rc_bd3390bc77cb145e-176">Maintenant, on veut que l&rsquo;IA puisse interagir avec ce canvas. Pour ça, on utilise le protocole <strong>MCP</strong> (Model Context Protocol). J’ai choisi le projet <code>mcp-excalidraw-local</code> qui propose environ 32 outils pour manipuler le tableau blanc (créer des formes, du texte, des flèches, etc.).</p>



<p class="wp-block-paragraph" id="p-rc_bd3390bc77cb145e-177">Pour l&rsquo;intégrer à l&rsquo;infra, on ajoute un service dédié qui va compiler les sources GitHub.</p>



<h3 class="wp-block-heading">Le Dockerfile du serveur MCP</h3>



<p class="wp-block-paragraph">On crée un fichier <code>Dockerfile.mcp-excalidraw</code> :</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>FROM node:20-slim
RUN apt-get update &amp;&amp; apt-get install -y git python3 make g++ &amp;&amp; rm -rf /var/lib/apt/lists/*
RUN npm install -g pnpm
WORKDIR /app
RUN git clone https://github.com/sanjibdevnathlabs/mcp-excalidraw-local.git .
RUN pnpm install &amp;&amp; pnpm build
# Le serveur attend des commandes stdio par défaut
CMD &#91;"node", "dist/index.js"&#93;</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">FROM</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">node:20-slim</span></span>
<span class="line"><span style="color: #88C0D0">RUN</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">apt-get</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">update</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&amp;&amp;</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">apt-get</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">install</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">-y</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">git</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">python3</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">make</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">g++</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&amp;&amp;</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">rm</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">-rf</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">/var/lib/apt/lists/</span><span style="color: #81A1C1">*</span></span>
<span class="line"><span style="color: #88C0D0">RUN</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">npm</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">install</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">-g</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">pnpm</span></span>
<span class="line"><span style="color: #88C0D0">WORKDIR</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">/app</span></span>
<span class="line"><span style="color: #88C0D0">RUN</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">git</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">clone</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">https://github.com/sanjibdevnathlabs/mcp-excalidraw-local.git</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">.</span></span>
<span class="line"><span style="color: #88C0D0">RUN</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">pnpm</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">install</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&amp;&amp;</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">pnpm</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">build</span></span>
<span class="line"><span style="color: #616E88"># Le serveur attend des commandes stdio par défaut</span></span>
<span class="line"><span style="color: #88C0D0">CMD</span><span style="color: #D8DEE9FF"> &#91;</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">node</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">, </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">dist/index.js</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">&#93;</span></span></code></pre></div>



<h3 class="wp-block-heading">Le Bridge pour Open-WebUI</h3>



<p class="wp-block-paragraph" id="p-rc_bd3390bc77cb145e-178">Le souci, c&rsquo;est que mon interface préférée, <strong>Open-WebUI</strong>, ne parle pas nativement le « stdio » (le langage des terminaux) pour le MCP. Elle préfère le HTTP. On va donc utiliser un bridge appelé <strong>mcpo</strong> qui va faire la traduction.</p>



<p class="wp-block-paragraph" id="p-rc_bd3390bc77cb145e-179">On ajoute ces deux services à notre <code>docker-compose.yml</code><sup></sup><sup></sup><sup></sup><sup></sup>:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>mcp-excalidraw:
    build:
      context: .
      dockerfile: Dockerfile.mcp-excalidraw
    container_name: mcp-excalidraw
    ports:
      - "3001:3000"
    environment:
      - CANVAS_PORT=3000
      - EXCALIDRAW_DB_PATH=/app/data/excalidraw.db
    volumes:
      - /chemin/vers/votre/data:/app/data
    restart: unless-stopped

  mcpo:
    image: ghcr.io/open-webui/mcpo:main
    container_name: mcpo
    ports:
      - "8081:8080"
    volumes:
      - ./mcpo/config.json:/app/config.json:ro
    depends_on:
      - mcp-excalidraw
    restart: unless-stopped</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">mcp-excalidraw:</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">build:</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">context:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">.</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">dockerfile:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Dockerfile.mcp-excalidraw</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">container_name:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">mcp-excalidraw</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">ports:</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">3001:3000</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">environment:</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">CANVAS_PORT=</span><span style="color: #B48EAD">3000</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">EXCALIDRAW_DB_PATH=/app/data/excalidraw.db</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">volumes:</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">/chemin/vers/votre/data:/app/data</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">restart:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">unless-stopped</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">mcpo:</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">image:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">ghcr.io/open-webui/mcpo:main</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">container_name:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">mcpo</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">ports:</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">8081:8080</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">volumes:</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">./mcpo/config.json:/app/config.json:ro</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">depends_on:</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">mcp-excalidraw</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">restart:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">unless-stopped</span></span></code></pre></div>



<p class="wp-block-paragraph">Il ne faut pas oublier de créer le fichier <code>./mcpo/config.json</code> pour dire à mcpo d&rsquo;aller chercher le serveur Excalidraw:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>{
  "mcpServers": {
    "excalidraw": {
      "type": "sse",
      "url": "http://mcp-excalidraw:3000/sse"
    }
  }
}</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">&quot;mcpServers&quot;</span><span style="color: #88C0D0">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">&quot;excalidraw&quot;</span><span style="color: #88C0D0">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">&quot;type&quot;</span><span style="color: #88C0D0">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">sse</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">&quot;url&quot;</span><span style="color: #88C0D0">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">http://mcp-excalidraw:3000/sse</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">  }</span></span>
<span class="line"><span style="color: #D8DEE9FF">}</span></span></code></pre></div>



<h2 class="wp-block-heading">Étape 3 : Le Tool Python « Agentic » (La Touche Finale)</h2>



<p class="wp-block-paragraph" id="p-rc_bd3390bc77cb145e-181">Après pas mal de tests, j&rsquo;ai réalisé que pour avoir un contrôle total, rien ne vaut un <strong>Tool Python</strong> personnalisé dans Open-WebUI. Cela permet d&rsquo;éviter les erreurs de protocole et de formater les requêtes exactement comme l&rsquo;API du serveur MCP l&rsquo;attend.</p>



<h3 class="wp-block-heading">Pourquoi ce script ?</h3>



<p class="wp-block-paragraph" id="p-rc_bd3390bc77cb145e-182">J&rsquo;ai découvert deux bugs critiques en analysant les logs:</p>



<ol start="1" class="wp-block-list">
<li>L&rsquo;API attend un objet pour le texte : <code>{"label": {"text": "votre texte"}}</code> et non une simple string.</li>



<li>Pour le Mermaid, le champ doit s&rsquo;appeler <code>mermaidDiagram</code>.</li>
</ol>



<p class="wp-block-paragraph" id="p-rc_bd3390bc77cb145e-185">Voici le script <code>excalidraw_tool.py</code> corrigé que j&rsquo;utilise<sup></sup><sup></sup><sup></sup><sup></sup>:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>"""
title: Excalidraw Canvas Tool
author: tazmen
description: Contrôle le canvas Excalidraw local
version: 1.2.0
"""
import json
import requests
import time

EXCALIDRAW_API = "http://mcp-excalidraw:3000"

class Tools:
    def add_element(self, type: str, label: str = "", x: int = 100, y: int = 100, width: int = 200, height: int = 100):
        """Ajoute un élément sur le canvas."""
        try:
            payload = {
                "type": type,
                "label": {"text": label}, # Formatage correct pour l'API
                "x": x, "y": y,
                "width": width, "height": height
            }
            r = requests.post(f"{EXCALIDRAW_API}/api/elements", json=payload, timeout=5)
            return "Élément ajouté."
        except Exception as e:
            return f"Erreur: {e}"

    def create_diagram_from_mermaid(self, mermaid_code: str) -> str:
        """Convertit un code Mermaid en schéma Excalidraw."""
        try:
            r = requests.post(
                f"{EXCALIDRAW_API}/api/elements/from-mermaid",
                json={"mermaidDiagram": mermaid_code}, # Champ corrigé
                timeout=10
            )
            time.sleep(2) # On laisse le temps au rendu
            return "Schéma généré."
        except Exception as e:
            return f"Erreur: {e}"

    def clear_canvas(self):
        """Vide le tableau blanc."""
        requests.delete(f"{EXCALIDRAW_API}/api/elements/clear", timeout=5)
        return "Canvas nettoyé."</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">&quot;&quot;&quot;</span></span>
<span class="line"><span style="color: #88C0D0">title: Excalidraw Canvas Tool</span></span>
<span class="line"><span style="color: #88C0D0">author: tazmen</span></span>
<span class="line"><span style="color: #88C0D0">description: Contrôle le canvas Excalidraw local</span></span>
<span class="line"><span style="color: #88C0D0">version: 1.2.0</span></span>
<span class="line"><span style="color: #88C0D0">&quot;&quot;&quot;</span></span>
<span class="line"><span style="color: #88C0D0">import</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">json</span></span>
<span class="line"><span style="color: #88C0D0">import</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">requests</span></span>
<span class="line"><span style="color: #88C0D0">import</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">time</span></span>
<span class="line"></span>
<span class="line"><span style="color: #88C0D0">EXCALIDRAW_API</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">http://mcp-excalidraw:3000</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #88C0D0">class</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Tools:</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">def</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">add_element</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">self,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">type:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">str,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">label:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">str</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;&quot;</span><span style="color: #A3BE8C">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">x:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">100</span><span style="color: #A3BE8C">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">y:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">100</span><span style="color: #A3BE8C">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">width:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">200</span><span style="color: #A3BE8C">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">height:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">100</span><span style="color: #ECEFF4">)</span><span style="color: #A3BE8C">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">&quot;&quot;&quot;Ajoute un élément sur le canvas.&quot;&quot;&quot;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">try:</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #88C0D0">payload</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">                </span><span style="color: #88C0D0">&quot;type&quot;</span><span style="color: #88C0D0">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">type,</span></span>
<span class="line"><span style="color: #D8DEE9FF">                </span><span style="color: #88C0D0">&quot;label&quot;</span><span style="color: #88C0D0">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">text</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">label},</span><span style="color: #D8DEE9FF"> </span><span style="color: #616E88"># Formatage correct pour l&#39;API</span></span>
<span class="line"><span style="color: #D8DEE9FF">                </span><span style="color: #88C0D0">&quot;x&quot;</span><span style="color: #88C0D0">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">x,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">y</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">y,</span></span>
<span class="line"><span style="color: #D8DEE9FF">                </span><span style="color: #88C0D0">&quot;width&quot;</span><span style="color: #88C0D0">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">width,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">height</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">height</span></span>
<span class="line"><span style="color: #D8DEE9FF">            }</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #88C0D0">r</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">requests.post</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">f</span><span style="color: #88C0D0">&quot;{EXCALIDRAW_API}/api/elements&quot;</span><span style="color: #88C0D0">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">json=payload,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">timeout=</span><span style="color: #B48EAD">5</span><span style="color: #ECEFF4">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Élément ajouté.</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">except</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Exception</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">as</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">e:</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">f</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Erreur: {e}</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">def</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">create_diagram_from_mermaid</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">self,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">mermaid_code:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">str</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> -</span><span style="color: #81A1C1">&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">str:</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">&quot;&quot;&quot;Convertit un code Mermaid en schéma Excalidraw.&quot;&quot;&quot;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">try:</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #88C0D0">r</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">requests.post</span><span style="color: #ECEFF4">(</span></span>
<span class="line"><span style="color: #D8DEE9FF">                </span><span style="color: #88C0D0">f</span><span style="color: #88C0D0">&quot;{EXCALIDRAW_API}/api/elements/from-mermaid&quot;</span><span style="color: #88C0D0">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">                </span><span style="color: #D8DEE9">json</span><span style="color: #81A1C1">=</span><span style="color: #A3BE8C">{</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">mermaidDiagram</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">mermaid_code},</span><span style="color: #D8DEE9FF"> </span><span style="color: #616E88"># Champ corrigé</span></span>
<span class="line"><span style="color: #D8DEE9FF">                </span><span style="color: #D8DEE9">timeout</span><span style="color: #81A1C1">=</span><span style="color: #B48EAD">10</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #ECEFF4">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">            time.sleep</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">2</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #616E88"># On laisse le temps au rendu</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Schéma généré.</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">except</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Exception</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">as</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">e:</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">f</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Erreur: {e}</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">def</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">clear_canvas</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">self</span><span style="color: #ECEFF4">)</span><span style="color: #A3BE8C">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">&quot;&quot;&quot;Vide le tableau blanc.&quot;&quot;&quot;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">requests.delete(f</span><span style="color: #88C0D0">&quot;{EXCALIDRAW_API}/api/elements/clear&quot;</span><span style="color: #88C0D0">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">timeout=</span><span style="color: #B48EAD">5</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Canvas nettoyé.</span><span style="color: #ECEFF4">&quot;</span></span></code></pre></div>



<figure class="wp-block-video"><video height="810" style="aspect-ratio: 1440 / 810;" width="1440" controls src="https://tazmenworld.com/wp-content/uploads/2026/04/outil-webui.mp4" class="lws-optimize-lazyload"></video></figure>



<h2 class="wp-block-heading">Les Galères et le Troubleshooting (Le mode survie)</h2>



<p class="wp-block-paragraph">Si vous faites ça, vous allez forcément tomber sur des erreurs de permissions. C&rsquo;est mathématique.</p>



<ul class="wp-block-list">
<li><strong>Erreur SQLITE_CANTOPEN</strong> : Le conteneur <code>mcp-excalidraw</code> essaie d&rsquo;écrire la base de données sur votre disque mais il n&rsquo;a pas les droits. Comme le process Node.js tourne souvent avec l&rsquo;UID 1001 , il faut lui donner la propriété du dossier: <code>sudo chown -R 1001:1001 ~/tazmen-ai-station/mcp-excalidraw/data</code>.</li>



<li><strong>L&rsquo;IA qui refuse de dessiner</strong> : Si votre modèle (Mistral ou Qwen) vous dit qu&rsquo;il « ne peut pas dessiner ici », c&rsquo;est qu&rsquo;il n&rsquo;est pas assez directif. Il faut lui forcer la main dans le <strong>System Prompt</strong>.</li>
</ul>



<h3 class="wp-block-heading">Mon System Prompt de « Grosse Flemme »</h3>



<p class="wp-block-paragraph" id="p-rc_bd3390bc77cb145e-189">Ajoutez ceci à votre modèle personnalisé dans Open-WebUI:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph" id="p-rc_bd3390bc77cb145e-190"><em>« Tu es un assistant spécialisé dans la création de schémas sur Excalidraw. RÈGLE ABSOLUE : Quand on te demande un schéma, utilise TOUJOURS <code>create_diagram_from_mermaid</code>. Ne montre jamais le code, dessine direct. »</em>.</p>
</blockquote>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">La Démo Finale : Ça en jette !</h2>



<p class="wp-block-paragraph">Une fois que tout est vert, le résultat est magique. Pendant ma formation, je dis simplement : <em>« Fais-moi un schéma d&rsquo;une architecture active directory avec les rôles FSMO »</em><sup></sup>. L&rsquo;IA réfléchit, génère le Mermaid, et paf, les boîtes apparaissent sur mon Excalidraw sur <code>localhost:8000</code> ou <code>3001</code><sup></sup>.</p>



<figure class="wp-block-video"><video height="810" style="aspect-ratio: 1440 / 810;" width="1440" controls src="https://tazmenworld.com/wp-content/uploads/2026/04/export-1776809953006.mp4" class="lws-optimize-lazyload"></video></figure>



<h2 class="wp-block-heading">Conclusion</h2>



<p class="wp-block-paragraph">Voilà comment on passe d&rsquo;une tablette graphique sympa à une station de travail agentique complète. C&rsquo;est du boulot à installer, mais quel plaisir de voir ses idées prendre forme sans avoir à se battre avec l&rsquo;alignement des rectangles !</p>



<p class="wp-block-paragraph" id="p-rc_bd3390bc77cb145e-193">Si vous avez des questions sur les variables d&rsquo;environnement ou les quantisations de modèles (j&rsquo;utilise <strong>Qwen 3.5 9B</strong> pour que ça rentre dans mes 16 Go de VRAM <sup></sup>), posez-les en commentaire.</p>



<p class="wp-block-paragraph">À plus pour de nouvelles aventures en local !</p>
]]></content:encoded>
					
					<wfw:commentRss>https://tazmenworld.com/2026/04/22/diagrammes-auto-generes-comment-piloter-excalidraw-en-local-avec-une-ia-sans-aucun-effort/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		<enclosure url="https://tazmenworld.com/wp-content/uploads/2026/04/outil-webui.mp4" length="11821123" type="video/mp4" />
<enclosure url="https://tazmenworld.com/wp-content/uploads/2026/04/export-1776809953006.mp4" length="6902806" type="video/mp4" />

			</item>
		<item>
		<title>IA &#038; Vie Privée : Pourquoi (et comment) j&#8217;ai déporté mon assistant Mistral sur Slack</title>
		<link>https://tazmenworld.com/2026/04/19/ia-vie-privee-pourquoi-et-comment-jai-deporte-mon-assistant-mistral-sur-slack/</link>
					<comments>https://tazmenworld.com/2026/04/19/ia-vie-privee-pourquoi-et-comment-jai-deporte-mon-assistant-mistral-sur-slack/#respond</comments>
		
		<dc:creator><![CDATA[tazmen3]]></dc:creator>
		<pubDate>Sun, 19 Apr 2026 21:36:11 +0000</pubDate>
				<category><![CDATA[Intelligence Artificielle (IA)]]></category>
		<guid isPermaLink="false">https://tazmenworld.com/?p=213</guid>

					<description><![CDATA[Si vous avez suivi les deux premiers articles, vous avez maintenant une bête de course sous Linux qui fait tourner Mistral Nemo au doigt et à l&#8217;œil grâce à Ollama. On a optimisé la VRAM, on a une interface WebUI qui n&#8217;a rien à envier à ChatGPT, mais il manque encore un petit quelque chose&#8230; [&#8230;]]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-large"><img width="1024" height="571"  alt="" class="wp-image-222"/ loading="lazy" decoding="async" src="https://tazmenworld.com/wp-content/uploads/2026/04/4p68fp4p68fp4p68_cleanup-1024x571.png" srcset="https://tazmenworld.com/wp-content/uploads/2026/04/4p68fp4p68fp4p68_cleanup-1024x571.png 1024w, https://tazmenworld.com/wp-content/uploads/2026/04/4p68fp4p68fp4p68_cleanup-300x167.png 300w, https://tazmenworld.com/wp-content/uploads/2026/04/4p68fp4p68fp4p68_cleanup-768x428.png 768w, https://tazmenworld.com/wp-content/uploads/2026/04/4p68fp4p68fp4p68_cleanup-1536x857.png 1536w, https://tazmenworld.com/wp-content/uploads/2026/04/4p68fp4p68fp4p68_cleanup-2048x1142.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">Si vous avez suivi les deux premiers articles, vous avez maintenant une bête de course sous Linux qui fait tourner <strong>Mistral Nemo</strong> au doigt et à l&rsquo;œil grâce à <strong>Ollama</strong>. On a optimisé la VRAM, on a une interface WebUI qui n&rsquo;a rien à envier à ChatGPT, mais il manque encore un petit quelque chose&#8230;</p>



<p class="wp-block-paragraph">L&rsquo;accessibilité.</p>



<p class="wp-block-paragraph">Ouvrir un navigateur, c&rsquo;est bien. Mais pouvoir interpeller son propre modèle d&rsquo;IA directement depuis son outil de travail quotidien, là où se passent les discussions, c&rsquo;est un tout autre niveau. Aujourd&rsquo;hui, on va voir comment transformer cette infrastructure locale en un assistant Slack ultra-réactif, totalement privé et surtout, <strong>sécurisé</strong>.</p>



<h2 class="wp-block-heading">Le défi de la sécurité : Pourquoi le « Socket Mode » ?</h2>



<p class="wp-block-paragraph">Quand on parle de connecter un serveur local à un service cloud comme Slack, le premier réflexe est souvent de se dire : « Je vais devoir ouvrir un port sur ma box, gérer un DNS dynamique, un certificat SSL&#8230; ».</p>



<p class="wp-block-paragraph"><strong>Oubliez tout ça.</strong> Ouvrir des ports, c&rsquo;est créer des trous dans votre muraille de Chine personnelle. Pour cet article, on va utiliser le <strong>Socket Mode</strong>. C&rsquo;est une technologie qui permet à notre petit bot Python, bien au chaud derrière votre pare-feu local, d&rsquo;ouvrir lui-même une connexion vers Slack pour récupérer les messages. C&rsquo;est le bot qui « écoute » Slack via une connexion sortante, et non Slack qui « appelle » votre serveur.</p>



<p class="wp-block-paragraph">Résultat : Sécurité maximale. Votre IP reste cachée, aucun port n&rsquo;est ouvert, et votre IA reste souveraine.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">Étape 1 : Préparer le terrain sur Slack</h2>



<p class="wp-block-paragraph">Avant de toucher au code, il faut donner une existence légale à notre assistant sur l&rsquo;interface développeur de Slack.</p>



<ol start="1" class="wp-block-list">
<li>Rendez-vous sur le portail API de Slack et créez une application « From Scratch ».</li>



<li><strong>Activer le Socket Mode</strong> : C&rsquo;est l&rsquo;option la plus importante dans le menu de gauche. En l&rsquo;activant, Slack vous donnera un premier token (commençant par <code>xapp-</code>). C&rsquo;est la clé de votre tunnel sécurisé.</li>



<li><strong>Permissions (Scopes)</strong> : Votre bot a besoin de voir les mentions (<code>app_mentions:read</code>) et de pouvoir répondre (<code>chat:write</code>). Si vous voulez lui parler en privé, ajoutez aussi les permissions liées aux messages directs (<code>im:history</code>).</li>
</ol>



<figure class="wp-block-image size-full"><img width="656" height="537"  alt="" class="wp-image-215"/ loading="lazy" decoding="async" src="https://tazmenworld.com/wp-content/uploads/2026/04/Capture-decran-du-2026-04-19-22-53-10.png" srcset="https://tazmenworld.com/wp-content/uploads/2026/04/Capture-decran-du-2026-04-19-22-53-10.png 656w, https://tazmenworld.com/wp-content/uploads/2026/04/Capture-decran-du-2026-04-19-22-53-10-300x246.png 300w" sizes="auto, (max-width: 656px) 100vw, 656px" /></figure>



<figure class="wp-block-image size-full"><img width="830" height="835"  alt="" class="wp-image-214"/ loading="lazy" decoding="async" src="https://tazmenworld.com/wp-content/uploads/2026/04/Capture-decran-du-2026-04-18-19-50-20.png" srcset="https://tazmenworld.com/wp-content/uploads/2026/04/Capture-decran-du-2026-04-18-19-50-20.png 830w, https://tazmenworld.com/wp-content/uploads/2026/04/Capture-decran-du-2026-04-18-19-50-20-298x300.png 298w, https://tazmenworld.com/wp-content/uploads/2026/04/Capture-decran-du-2026-04-18-19-50-20-150x150.png 150w, https://tazmenworld.com/wp-content/uploads/2026/04/Capture-decran-du-2026-04-18-19-50-20-768x773.png 768w" sizes="auto, (max-width: 830px) 100vw, 830px" /></figure>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">Étape 2 : L&rsquo;architecture Docker (La modularité avant tout)</h2>



<p class="wp-block-paragraph">Dans l&rsquo;article précédent, on a vu que Docker était notre meilleur allié pour isoler nos services. Pour ajouter le bot Slack, on ne va pas polluer notre conteneur Ollama. On va créer un nouveau service dédié.</p>



<p class="wp-block-paragraph">Voici à quoi ressemble notre infrastructure mise à jour. J&rsquo;ai anonymisé les chemins et les clés, mais la structure est celle que j&rsquo;utilise au quotidien.</p>



<h5 class="wp-block-heading">1. Le fichier <code>docker-compose.yml</code></h5>



<p class="wp-block-paragraph">C&rsquo;est le chef d&rsquo;orchestre. Il définit comment Ollama et ton Bot communiquent dans un réseau privé.</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly># docker-compose.yml (Extrait)
services:
  # Votre moteur IA que nous avons configuré auparavant
  ollama:
    image: ollama/ollama
    container_name: ollama
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: all
              capabilities: &#91;gpu&#93;

  # Le nouveau venu : Notre pont Python personnalisé
  slack-bot:
    build: ./slack-bot
    container_name: slack-bot
    depends_on:
      - ollama
    environment:
      - SLACK_BOT_TOKEN=xoxb-votre-cle-secrete # Token de l'App
      - SLACK_APP_TOKEN=xapp-votre-cle-tunnel # Token Socket Mode
      - PYTHONUNBUFFERED=1 # Pour voir les logs en temps réel
    restart: unless-stopped</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #616E88"># docker-compose.yml (Extrait)</span></span>
<span class="line"><span style="color: #8FBCBB">services</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #ECEFF4">  </span><span style="color: #616E88"># Votre moteur IA que nous avons configuré auparavant</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #8FBCBB">ollama</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">image</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">ollama/ollama</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">container_name</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">ollama</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">deploy</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #8FBCBB">resources</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #8FBCBB">reservations</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">          </span><span style="color: #8FBCBB">devices</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #ECEFF4">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">driver</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">nvidia</span></span>
<span class="line"><span style="color: #D8DEE9FF">              </span><span style="color: #8FBCBB">count</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">all</span></span>
<span class="line"><span style="color: #D8DEE9FF">              </span><span style="color: #8FBCBB">capabilities</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&#91;</span><span style="color: #A3BE8C">gpu</span><span style="color: #ECEFF4">&#93;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">  </span><span style="color: #616E88"># Le nouveau venu : Notre pont Python personnalisé</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #8FBCBB">slack-bot</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">build</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">./slack-bot</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">container_name</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">slack-bot</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">depends_on</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #ECEFF4">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">ollama</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">environment</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #ECEFF4">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">SLACK_BOT_TOKEN=xoxb-votre-cle-secrete</span><span style="color: #D8DEE9FF"> </span><span style="color: #616E88"># Token de l&#39;App</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #ECEFF4">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">SLACK_APP_TOKEN=xapp-votre-cle-tunnel</span><span style="color: #D8DEE9FF"> </span><span style="color: #616E88"># Token Socket Mode</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #ECEFF4">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">PYTHONUNBUFFERED=1</span><span style="color: #D8DEE9FF"> </span><span style="color: #616E88"># Pour voir les logs en temps réel</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">restart</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">unless-stopped</span></span></code></pre></div>



<h5 class="wp-block-heading">2. Le fichier <code>slack-bot/requirements.txt</code></h5>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>slack_bolt
requests</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">slack_bolt</span></span>
<span class="line"><span style="color: #88C0D0">requests</span></span></code></pre></div>



<h5 class="wp-block-heading">3. Le fichier <code>slack-bot/Dockerfile</code></h5>



<p class="wp-block-paragraph">Les instructions pour construire l&rsquo;image de ton bot.</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY bot.py .
CMD &#91;"python", "bot.py"&#93;</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9FF">FROM python</span><span style="color: #ECEFF4">:</span><span style="color: #B48EAD">3.11</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF">slim</span></span>
<span class="line"><span style="color: #D8DEE9FF">WORKDIR </span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9FF">app</span></span>
<span class="line"><span style="color: #D8DEE9FF">COPY requirements</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">txt </span><span style="color: #ECEFF4">.</span></span>
<span class="line"><span style="color: #D8DEE9FF">RUN pip install </span><span style="color: #D8DEE9">--</span><span style="color: #D8DEE9FF">no</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF">cache</span><span style="color: #81A1C1">-</span><span style="color: #88C0D0">dir</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF">r requirements</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">txt</span></span>
<span class="line"><span style="color: #D8DEE9FF">COPY bot</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">py </span><span style="color: #ECEFF4">.</span></span>
<span class="line"><span style="color: #D8DEE9FF">CMD </span><span style="color: #ECEFF4">&#91;</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">python</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">bot.py</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">&#93;</span></span></code></pre></div>



<h5 class="wp-block-heading">4. Le fichier <code>slack-bot/bot.py</code> (Version avec Mémoire)</h5>



<p class="wp-block-paragraph">C&rsquo;est ici que la magie opère. Ce script gère les messages directs, les mentions, et conserve l&rsquo;historique pour que l&rsquo;IA ait du contexte.</p>



<p class="wp-block-paragraph">Les dépendances Python nécessaires pour faire tourner le bot.</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>import os
import requests
from slack_bolt import App
from slack_bolt.adapter.socket_mode import SocketModeHandler

# Configuration
app = App(token=os.environ.get("SLACK_BOT_TOKEN"))
OLLAMA_URL = "http://ollama:11434/api/chat"
MODEL_NAME = "ministral-3:14b-instruct-2512-q4_K_M"

# Mémoire locale (Dictionnaire par utilisateur)
history_db = {}

def get_ai_response(user_id, user_text):
    # Initialiser l'historique si nouveau
    if user_id not in history_db:
        history_db&#91;user_id&#93; = []
    
    # Ajouter le message utilisateur
    history_db&#91;user_id&#93;.append({"role": "user", "content": user_text})
    
    # Garder les 10 derniers messages pour le contexte
    history_db&#91;user_id&#93; = history_db&#91;user_id&#93;&#91;-10:&#93;

    payload = {
        "model": MODEL_NAME,
        "messages": history_db&#91;user_id&#93;,
        "stream": False
    }

    try:
        r = requests.post(OLLAMA_URL, json=payload)
        r.raise_for_status()
        bot_response = r.json()&#91;'message'&#93;&#91;'content'&#93;
        
        # Mémoriser la réponse de l'IA
        history_db&#91;user_id&#93;.append({"role": "assistant", "content": bot_response})
        return bot_response
    except Exception as e:
        return f"Désolé, j'ai eu un souci technique : {e}"

# Écouteur pour les messages directs (DM)
@app.event("message")
def handle_message(event, say):
    if event.get("channel_type") == "im" and "bot_id" not in event:
        response = get_ai_response(event&#91;'user'&#93;, event&#91;'text'&#93;)
        say(response)

# Écouteur pour les mentions (@MonBot)
@app.event("app_mention")
def handle_mention(event, say):
    # On nettoie la mention pour ne garder que la question
    text = event&#91;'text'&#93;.split('> ')&#91;-1&#93; if '>' in event&#91;'text'&#93; else event&#91;'text'&#93;
    response = get_ai_response(event&#91;'user'&#93;, text)
    say(response)

if __name__ == "__main__":
    handler = SocketModeHandler(app, os.environ.get("SLACK_APP_TOKEN"))
    handler.start()</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">import</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">os</span></span>
<span class="line"><span style="color: #88C0D0">import</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">requests</span></span>
<span class="line"><span style="color: #88C0D0">from</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">slack_bolt</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">import</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">App</span></span>
<span class="line"><span style="color: #88C0D0">from</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">slack_bolt.adapter.socket_mode</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">import</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">SocketModeHandler</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88"># Configuration</span></span>
<span class="line"><span style="color: #88C0D0">app</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">App</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9">token</span><span style="color: #81A1C1">=</span><span style="color: #A3BE8C">os.environ.get</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">&quot;SLACK_BOT_TOKEN&quot;</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #88C0D0">OLLAMA_URL</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">http://ollama:11434/api/chat</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"><span style="color: #88C0D0">MODEL_NAME</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">ministral-3:14b-instruct-2512-q4_K_M</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88"># Mémoire locale (Dictionnaire par utilisateur)</span></span>
<span class="line"><span style="color: #88C0D0">history_db</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #88C0D0">def</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">get_ai_response</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">user_id,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">user_text</span><span style="color: #ECEFF4">)</span><span style="color: #A3BE8C">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #616E88"># Initialiser l&#39;historique si nouveau</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">user_id</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">not</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">in</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">history_db:</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">history_db&#91;user_id&#93;</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> []</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #616E88"># Ajouter le message utilisateur</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">history_db&#91;user_id&#93;.append(</span><span style="color: #D8DEE9FF">{&quot;</span><span style="color: #88C0D0">role</span><span style="color: #88C0D0">&quot;: &quot;</span><span style="color: #88C0D0">user</span><span style="color: #88C0D0">&quot;, &quot;</span><span style="color: #88C0D0">content</span><span style="color: #88C0D0">&quot;: user_text})</span></span>
<span class="line"><span style="color: #88C0D0">    </span></span>
<span class="line"><span style="color: #88C0D0">    # Garder les 10 derniers messages pour le contexte</span></span>
<span class="line"><span style="color: #88C0D0">    history_db&#91;user_id&#93; = history_db&#91;user_id&#93;&#91;-10:&#93;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #88C0D0">    payload = {</span></span>
<span class="line"><span style="color: #88C0D0">        &quot;</span><span style="color: #88C0D0">model</span><span style="color: #88C0D0">&quot;: MODEL_NAME,</span></span>
<span class="line"><span style="color: #88C0D0">        &quot;</span><span style="color: #88C0D0">messages</span><span style="color: #88C0D0">&quot;: history_db&#91;user_id&#93;,</span></span>
<span class="line"><span style="color: #88C0D0">        &quot;</span><span style="color: #88C0D0">stream</span><span style="color: #88C0D0">&quot;: False</span></span>
<span class="line"><span style="color: #88C0D0">    }</span></span>
<span class="line"></span>
<span class="line"><span style="color: #88C0D0">    try:</span></span>
<span class="line"><span style="color: #88C0D0">        r = requests.post(OLLAMA_URL, json=payload)</span></span>
<span class="line"><span style="color: #88C0D0">        r.raise_for_status()</span></span>
<span class="line"><span style="color: #88C0D0">        bot_response = r.json()&#91;&#39;message&#39;&#93;&#91;&#39;content&#39;&#93;</span></span>
<span class="line"><span style="color: #88C0D0">        </span></span>
<span class="line"><span style="color: #88C0D0">        # Mémoriser la réponse de l&#39;IA</span></span>
<span class="line"><span style="color: #88C0D0">        history_db&#91;user_id&#93;.append({&quot;</span><span style="color: #88C0D0">role</span><span style="color: #88C0D0">&quot;: &quot;</span><span style="color: #88C0D0">assistant</span><span style="color: #88C0D0">&quot;, &quot;</span><span style="color: #88C0D0">content</span><span style="color: #88C0D0">&quot;: bot_response})</span></span>
<span class="line"><span style="color: #88C0D0">        return bot_response</span></span>
<span class="line"><span style="color: #88C0D0">    except Exception as e:</span></span>
<span class="line"><span style="color: #88C0D0">        return f&quot;</span><span style="color: #88C0D0">Désolé,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">j</span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">ai eu un souci technique : {e}&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #A3BE8C"># Écouteur pour les messages directs (DM)</span></span>
<span class="line"><span style="color: #A3BE8C">@app.event(&quot;message&quot;)</span></span>
<span class="line"><span style="color: #A3BE8C">def handle_message(event, say):</span></span>
<span class="line"><span style="color: #A3BE8C">    if event.get(&quot;channel_type&quot;) == &quot;im&quot; and &quot;bot_id&quot; not in event:</span></span>
<span class="line"><span style="color: #A3BE8C">        response = get_ai_response(event&#91;</span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">user</span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">&#93;, event&#91;</span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">text</span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">&#93;)</span></span>
<span class="line"><span style="color: #A3BE8C">        say(response)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #A3BE8C"># Écouteur pour les mentions (@MonBot)</span></span>
<span class="line"><span style="color: #A3BE8C">@app.event(&quot;app_mention&quot;)</span></span>
<span class="line"><span style="color: #A3BE8C">def handle_mention(event, say):</span></span>
<span class="line"><span style="color: #A3BE8C">    # On nettoie la mention pour ne garder que la question</span></span>
<span class="line"><span style="color: #A3BE8C">    text = event&#91;</span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">text</span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">&#93;.split(</span><span style="color: #ECEFF4">&#39;</span><span style="color: #81A1C1">&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">)&#91;-1&#93; if </span><span style="color: #ECEFF4">&#39;</span><span style="color: #81A1C1">&gt;</span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C"> in event&#91;</span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">text</span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">&#93; else event&#91;</span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">text</span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">&#93;</span></span>
<span class="line"><span style="color: #A3BE8C">    response = get_ai_response(event&#91;</span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">user</span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">&#93;, text)</span></span>
<span class="line"><span style="color: #A3BE8C">    say(response)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #A3BE8C">if __name__ == &quot;__main__&quot;:</span></span>
<span class="line"><span style="color: #A3BE8C">    handler = SocketModeHandler(app, os.environ.get(&quot;SLACK_APP_TOKEN&quot;))</span></span>
<span class="line"><span style="color: #A3BE8C">    handler.start()</span></span></code></pre></div>



<p class="wp-block-paragraph">L&rsquo;avantage de cette méthode ? Si vous voulez changer de modèle d&rsquo;IA ou mettre à jour Ollama, votre bot Slack n&rsquo;a pas besoin d&rsquo;être modifié. Il attend simplement que le moteur soit prêt.</p>



<figure class="wp-block-image size-large"><img width="1024" height="423"  alt="" class="wp-image-216"/ loading="lazy" decoding="async" src="https://tazmenworld.com/wp-content/uploads/2026/04/image-14-1024x423.png" srcset="https://tazmenworld.com/wp-content/uploads/2026/04/image-14-1024x423.png 1024w, https://tazmenworld.com/wp-content/uploads/2026/04/image-14-300x124.png 300w, https://tazmenworld.com/wp-content/uploads/2026/04/image-14-768x317.png 768w, https://tazmenworld.com/wp-content/uploads/2026/04/image-14.png 1238w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading">Étape 3 : Donner un cerveau (et une mémoire) au Bot</h2>



<p class="wp-block-paragraph">C&rsquo;est là que le côté « humain » intervient. Un bot qui répond à une question, c&rsquo;est bien. Un bot qui se souvient que vous lui avez parlé d&rsquo;un projet de blog il y a trois messages, c&rsquo;est mieux.</p>



<p class="wp-block-paragraph">Par défaut, les API de LLM sont « amnésiques ». Chaque question repart de zéro. Pour corriger ça, on utilise un script Python qui va stocker les derniers échanges dans une petite structure de données (un dictionnaire) avant d&rsquo;envoyer le tout à l&rsquo;API <code>/api/chat</code> d&rsquo;Ollama.</p>



<p class="wp-block-paragraph">Le script va filtrer les mentions, nettoyer le texte et s&rsquo;assurer que si vous l&rsquo;appelez dans un canal public ou en message privé, il sache qui vous êtes.</p>



<p class="wp-block-paragraph"><strong>Note sur l&rsquo;anonymisation :</strong> Dans le code, on ne manipule jamais de noms réels, seulement des <code>user_id</code> fournis par Slack. C&rsquo;est une couche de confidentialité supplémentaire.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">Étape 4 : Le premier démarrage (Et les logs magiques)</h2>



<p class="wp-block-paragraph">Une fois le code prêt, on lance la machine : <code>docker compose up -d --build</code></p>



<p class="wp-block-paragraph">C&rsquo;est le moment de vérité. On regarde les logs du conteneur. Si vous voyez s&rsquo;afficher <code>⚡️ Bolt app is running!</code>, félicitations : votre GPU est désormais branché sur Slack.</p>



<figure class="wp-block-image size-full"><img width="820" height="305"  alt="" class="wp-image-217"/ loading="lazy" decoding="async" src="https://tazmenworld.com/wp-content/uploads/2026/04/Capture-decran-du-2026-04-18-23-33-44.png" srcset="https://tazmenworld.com/wp-content/uploads/2026/04/Capture-decran-du-2026-04-18-23-33-44.png 820w, https://tazmenworld.com/wp-content/uploads/2026/04/Capture-decran-du-2026-04-18-23-33-44-300x112.png 300w, https://tazmenworld.com/wp-content/uploads/2026/04/Capture-decran-du-2026-04-18-23-33-44-768x286.png 768w" sizes="auto, (max-width: 820px) 100vw, 820px" /></figure>



<h2 class="wp-block-heading">Étape 5 : L&rsquo;IA en action (Tests et ressentis)</h2>



<p class="wp-block-paragraph">En testant avec Mistral Nemo (en version instruct, quantifié en Q8 pour garder de la précision), les réponses sont bluffantes.</p>



<p class="wp-block-paragraph">Ce qui change tout par rapport à une interface web, c&rsquo;est la fluidité. On pose une question technique sur un bout de code, on continue sa discussion avec ses collègues, et on voit la petite notification Slack arriver quand l&rsquo;IA a fini de « réfléchir ». C&rsquo;est moins intrusif et beaucoup plus intégré au flux de travail.</p>



<figure class="wp-block-image size-large"><img width="1024" height="855"  alt="" class="wp-image-218"/ loading="lazy" decoding="async" src="https://tazmenworld.com/wp-content/uploads/2026/04/image-15-1024x855.png" srcset="https://tazmenworld.com/wp-content/uploads/2026/04/image-15-1024x855.png 1024w, https://tazmenworld.com/wp-content/uploads/2026/04/image-15-300x250.png 300w, https://tazmenworld.com/wp-content/uploads/2026/04/image-15-768x641.png 768w, https://tazmenworld.com/wp-content/uploads/2026/04/image-15.png 1363w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading">Conclusion : Souveraineté et Futur</h2>



<p class="wp-block-paragraph">En trois étapes, nous sommes passés d&rsquo;une machine Linux brute à un assistant personnel capable de rivaliser avec les meilleurs services payants, le coût du cloud et l&rsquo;espionnage en moins.</p>



<p class="wp-block-paragraph">Ce projet montre qu&rsquo;en 2026, l&rsquo;IA locale n&rsquo;est plus une curiosité pour les geeks du dimanche. C&rsquo;est un outil de production sérieux, sécurisé, et totalement personnalisable. La prochaine étape ? Pourquoi ne pas donner à ce bot la capacité de lire vos documents locaux ou d&rsquo;automatiser vos déploiements Docker ?</p>



<p class="wp-block-paragraph">Mais ça, c&rsquo;est peut-être le sujet d&rsquo;un futur article&#8230;</p>



<p class="wp-block-paragraph">D&rsquo;ici là, reprenez le contrôle de vos données, et amusez-vous bien avec votre nouveau collègue de bureau virtuel !</p>
]]></content:encoded>
					
					<wfw:commentRss>https://tazmenworld.com/2026/04/19/ia-vie-privee-pourquoi-et-comment-jai-deporte-mon-assistant-mistral-sur-slack/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>🚀 Retour sur mon expérience au Global Azure France 2026 ! #GlobalAzure</title>
		<link>https://tazmenworld.com/2026/04/19/%f0%9f%9a%80-retour-sur-mon-experience-au-global-azure-france-2026-globalazure/</link>
					<comments>https://tazmenworld.com/2026/04/19/%f0%9f%9a%80-retour-sur-mon-experience-au-global-azure-france-2026-globalazure/#respond</comments>
		
		<dc:creator><![CDATA[tazmen3]]></dc:creator>
		<pubDate>Sun, 19 Apr 2026 18:11:44 +0000</pubDate>
				<category><![CDATA[Cloud Computing]]></category>
		<category><![CDATA[Infrastructure IT]]></category>
		<guid isPermaLink="false">https://tazmenworld.com/?p=199</guid>

					<description><![CDATA[Ce week-end, j&#8217;ai eu l&#8217;opportunité de participer au meetup Global Azure France 2026. L&#8217;événement était vraiment sympa et m&#8217;a permis de faire le plein de connaissances. Voici un petit récapitulatif des différents sujets abordés lors des sessions auxquelles j&#8217;ai pu assister. 🧠 Du POC à l’industrialisation : bâtir une infrastructure Azure prête pour la GenAI [&#8230;]]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-large"><img width="1024" height="512"  alt="" class="wp-image-211"/ loading="lazy" decoding="async" src="https://tazmenworld.com/wp-content/uploads/2026/04/1774622839954-1024x512.jpeg" srcset="https://tazmenworld.com/wp-content/uploads/2026/04/1774622839954-1024x512.jpeg 1024w, https://tazmenworld.com/wp-content/uploads/2026/04/1774622839954-300x150.jpeg 300w, https://tazmenworld.com/wp-content/uploads/2026/04/1774622839954-768x384.jpeg 768w, https://tazmenworld.com/wp-content/uploads/2026/04/1774622839954.jpeg 1280w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">Ce week-end, j&rsquo;ai eu l&rsquo;opportunité de participer au meetup <strong>Global Azure France 2026</strong>. L&rsquo;événement était vraiment sympa et m&rsquo;a permis de faire le plein de connaissances. Voici un petit récapitulatif des différents sujets abordés lors des sessions auxquelles j&rsquo;ai pu assister.</p>



<h3 class="wp-block-heading">🧠 Du POC à l’industrialisation : bâtir une infrastructure Azure prête pour la GenAI et les agents IA</h3>



<figure class="wp-block-image size-large"><img width="1024" height="771"  alt="" class="wp-image-203"/ loading="lazy" decoding="async" src="https://tazmenworld.com/wp-content/uploads/2026/04/PXL_20260418_0754217383-1024x771.jpg" srcset="https://tazmenworld.com/wp-content/uploads/2026/04/PXL_20260418_0754217383-1024x771.jpg 1024w, https://tazmenworld.com/wp-content/uploads/2026/04/PXL_20260418_0754217383-300x226.jpg 300w, https://tazmenworld.com/wp-content/uploads/2026/04/PXL_20260418_0754217383-768x578.jpg 768w, https://tazmenworld.com/wp-content/uploads/2026/04/PXL_20260418_0754217383-1536x1157.jpg 1536w, https://tazmenworld.com/wp-content/uploads/2026/04/PXL_20260418_0754217383-2048x1542.jpg 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph"><em>Animé par <a href="https://www.linkedin.com/in/ibnmbodji/" type="link" id="https://www.linkedin.com/in/ibnmbodji/">Ibrahima Mbodji</a></em></p>



<p class="wp-block-paragraph">C&rsquo;était particulièrement intéressant d&rsquo;avoir un retour d&rsquo;expérience concret sur l&rsquo;intégration d&rsquo;infrastructures d&rsquo;<strong>IA</strong> dans Azure, notamment avec AI Foundry. C&rsquo;est un sujet très actuel mais sur lequel il est encore difficile d&rsquo;obtenir du recul. Ibrahima a détaillé deux types d&rsquo;intégration :</p>



<ul class="wp-block-list">
<li>Avec la Landing Zone <em>« Enterprise-Scale »</em>.</li>



<li>Sans la Landing Zone, en mode <em>« Start Small and Expand »</em>.</li>
</ul>



<p class="wp-block-paragraph">Avoir une idée « grosse maille » des infrastructures de test et de production IA dans Azure apporte une vraie valeur ajoutée pour se projeter.</p>



<h3 class="wp-block-heading">☁️ Azure Local – Le Cloud Souverain by Microsoft</h3>



<figure class="wp-block-image size-large"><img width="1024" height="771"  alt="" class="wp-image-204"/ loading="lazy" decoding="async" src="https://tazmenworld.com/wp-content/uploads/2026/04/PXL_20260418_0842558032-1-1024x771.jpg" srcset="https://tazmenworld.com/wp-content/uploads/2026/04/PXL_20260418_0842558032-1-1024x771.jpg 1024w, https://tazmenworld.com/wp-content/uploads/2026/04/PXL_20260418_0842558032-1-300x226.jpg 300w, https://tazmenworld.com/wp-content/uploads/2026/04/PXL_20260418_0842558032-1-768x578.jpg 768w, https://tazmenworld.com/wp-content/uploads/2026/04/PXL_20260418_0842558032-1-1536x1157.jpg 1536w, https://tazmenworld.com/wp-content/uploads/2026/04/PXL_20260418_0842558032-1-2048x1542.jpg 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph"><em>Animé par <a href="https://www.linkedin.com/in/jonathan-jehanno-57465238/" type="link" id="https://www.linkedin.com/in/jonathan-jehanno-57465238/">Jonathan JEHANNO</a></em></p>



<p class="wp-block-paragraph">Pour être honnête, j&rsquo;avais gardé quelques mauvais souvenirs d&rsquo;Azure Stack. Mais la démonstration de Jonathan sur Azure Local m&rsquo;a vraiment fait changer d&rsquo;avis (et le fait d&rsquo;avoir une démo en direct, c&rsquo;est toujours un gros plus !).</p>



<p class="wp-block-paragraph">Au vu de l&rsquo;augmentation récente des tarifs de certains hyperviseurs classiques et de Citrix, Azure Local tient vraiment la route en termes de <em>licencing</em> pour de l&rsquo;AVD (Azure Virtual Desktop). C&rsquo;est particulièrement pertinent pour les clients qui disposent de la Software Assurance. Même si Microsoft a annoncé en <em>preview</em> limitée l&rsquo;AVD pour les environnements hybrides, le véritable atout d&rsquo;Azure Local réside dans sa capacité à offrir un environnement totalement déconnecté, un point crucial pour les enjeux de <strong>sécurité</strong> et de souveraineté. Nous avons également eu un aperçu d&rsquo;Office 365 en local. Les fonctionnalités sont encore limitées pour le moment, mais j&rsquo;espère que la solution évoluera dans le futur.</p>



<h3 class="wp-block-heading">💻 Design. Co-Pilot. Deploy. No Slides. Just Blazor.</h3>



<figure class="wp-block-image size-large"><img width="1024" height="771"  alt="" class="wp-image-205"/ loading="lazy" decoding="async" src="https://tazmenworld.com/wp-content/uploads/2026/04/PXL_20260418_0926389902-1024x771.jpg" srcset="https://tazmenworld.com/wp-content/uploads/2026/04/PXL_20260418_0926389902-1024x771.jpg 1024w, https://tazmenworld.com/wp-content/uploads/2026/04/PXL_20260418_0926389902-300x226.jpg 300w, https://tazmenworld.com/wp-content/uploads/2026/04/PXL_20260418_0926389902-768x578.jpg 768w, https://tazmenworld.com/wp-content/uploads/2026/04/PXL_20260418_0926389902-1536x1157.jpg 1536w, https://tazmenworld.com/wp-content/uploads/2026/04/PXL_20260418_0926389902-2048x1542.jpg 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph"><em>Animé par <a href="https://www.linkedin.com/in/mabroukmahdhi/" type="link" id="https://www.linkedin.com/in/mabroukmahdhi/">Mabrouk Mahdhi</a></em></p>



<p class="wp-block-paragraph">Une session très interactive et sans PowerPoint ! Mabrouk nous a fait une belle démonstration de <em>vibe coding</em> avec l&rsquo;outil UX Pilot. C&rsquo;est une solution vraiment sympa et facile d&rsquo;accès. Le petit détail qui fait plaisir : à l&rsquo;inscription, il est possible de créer un projet gratuitement pour tester la solution immédiatement.</p>



<h3 class="wp-block-heading">🛠️ Improving Ops with Azure Copilot and GitHub Copilot</h3>



<figure class="wp-block-image size-large"><img width="1024" height="771"  alt="" class="wp-image-206"/ loading="lazy" decoding="async" src="https://tazmenworld.com/wp-content/uploads/2026/04/PXL_20260418_1014472082-1024x771.jpg" srcset="https://tazmenworld.com/wp-content/uploads/2026/04/PXL_20260418_1014472082-1024x771.jpg 1024w, https://tazmenworld.com/wp-content/uploads/2026/04/PXL_20260418_1014472082-300x226.jpg 300w, https://tazmenworld.com/wp-content/uploads/2026/04/PXL_20260418_1014472082-768x578.jpg 768w, https://tazmenworld.com/wp-content/uploads/2026/04/PXL_20260418_1014472082-1536x1157.jpg 1536w, https://tazmenworld.com/wp-content/uploads/2026/04/PXL_20260418_1014472082-2048x1542.jpg 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph"><em>Animé par <a href="https://www.linkedin.com/in/achrafbenalaya/" type="link" id="https://www.linkedin.com/in/achrafbenalaya/">Achraf Ben Alaya</a></em></p>



<p class="wp-block-paragraph">Achraf a partagé d&rsquo;excellentes recommandations sur l&rsquo;utilisation de l&rsquo;IA pour améliorer les opérations. La session était riche en démonstrations pratiques. C&rsquo;est toujours utile de prendre de bonnes pratiques sur ces outils d&rsquo;assistance au quotidien.</p>



<h3 class="wp-block-heading">📊 Le challenge du ROI de l’IA</h3>



<figure class="wp-block-image size-large"><img width="1024" height="771"  alt="" class="wp-image-210"/ loading="lazy" decoding="async" src="https://tazmenworld.com/wp-content/uploads/2026/04/PXL_20260418_1114041582-1024x771.jpg" srcset="https://tazmenworld.com/wp-content/uploads/2026/04/PXL_20260418_1114041582-1024x771.jpg 1024w, https://tazmenworld.com/wp-content/uploads/2026/04/PXL_20260418_1114041582-300x226.jpg 300w, https://tazmenworld.com/wp-content/uploads/2026/04/PXL_20260418_1114041582-768x578.jpg 768w, https://tazmenworld.com/wp-content/uploads/2026/04/PXL_20260418_1114041582-1536x1157.jpg 1536w, https://tazmenworld.com/wp-content/uploads/2026/04/PXL_20260418_1114041582-2048x1542.jpg 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph"><em>Animé par <a href="https://www.linkedin.com/in/jeanlucboucho/">Jean-Luc Boucho</a></em></p>



<p class="wp-block-paragraph">C&rsquo;est l&rsquo;une des sessions que j&rsquo;ai le plus appréciées. Il est assez rare d&rsquo;avoir une vue « haut niveau » sur ce type de projet en entreprise. Jean-Luc a partagé un retour d&rsquo;expérience transparent, en n&rsquo;hésitant pas à soulever les différents « warnings » et points de vigilance lors de l&rsquo;intégration de projets IA. La présentation s&rsquo;est terminée par des exemples concrets et un petit quiz. Le format était un peu court à mon goût, j&rsquo;en aurais volontiers pris davantage !</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">En conclusion</h3>



<p class="wp-block-paragraph">Nous avons eu droit à des sessions très sympas, parfois un peu courtes, mais toujours denses. C&rsquo;était extrêmement pertinent d&rsquo;avoir des retours terrain sur des technologies et des projets que l&rsquo;on n&rsquo;a pas forcément encore l&rsquo;habitude de voir tourner en production, car ces technologies sont encore très jeunes.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://tazmenworld.com/2026/04/19/%f0%9f%9a%80-retour-sur-mon-experience-au-global-azure-france-2026-globalazure/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Reprendre le contrôle : mon IA locale avec Mistral NeMo, Ollama et Open WebUI</title>
		<link>https://tazmenworld.com/2026/04/16/reprendre-le-controle-mon-ia-locale-avec-mistral-nemo-ollama-et-open-webui/</link>
					<comments>https://tazmenworld.com/2026/04/16/reprendre-le-controle-mon-ia-locale-avec-mistral-nemo-ollama-et-open-webui/#respond</comments>
		
		<dc:creator><![CDATA[tazmen3]]></dc:creator>
		<pubDate>Thu, 16 Apr 2026 21:43:22 +0000</pubDate>
				<category><![CDATA[Intelligence Artificielle (IA)]]></category>
		<guid isPermaLink="false">https://tazmenworld.com/?p=188</guid>

					<description><![CDATA[Cet article fait suite à la Partie 2 : Passer sous Linux pour libérer votre GPU. Maintenant que le système est propre, que l&#8217;interface graphique ne vient plus grignoter vos précieux gigaoctets de mémoire vidéo, on va s&#8217;attaquer au « cerveau » de la machine. L&#8217;idée ici n&#8217;est pas de suivre un tuto de plus sur l&#8217;IA, [&#8230;]]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-large"><img width="1024" height="572"  alt="" class="wp-image-194"/ loading="lazy" decoding="async" src="https://tazmenworld.com/wp-content/uploads/2026/04/kkkfi2kkkfi2kkkf_cleanup-1024x572.png" srcset="https://tazmenworld.com/wp-content/uploads/2026/04/kkkfi2kkkfi2kkkf_cleanup-1024x572.png 1024w, https://tazmenworld.com/wp-content/uploads/2026/04/kkkfi2kkkfi2kkkf_cleanup-300x167.png 300w, https://tazmenworld.com/wp-content/uploads/2026/04/kkkfi2kkkfi2kkkf_cleanup-768x429.png 768w, https://tazmenworld.com/wp-content/uploads/2026/04/kkkfi2kkkfi2kkkf_cleanup-1536x857.png 1536w, https://tazmenworld.com/wp-content/uploads/2026/04/kkkfi2kkkfi2kkkf_cleanup-2048x1143.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">Cet article fait suite à la <a target="_blank" rel="noreferrer noopener" href="https://tazmenworld.com/2026/04/15/vram-tuning-partie-2-passer-sous-linux-pour-liberer-votre-gpu/">Partie 2 : Passer sous Linux pour libérer votre GPU</a>.</p>



<p class="wp-block-paragraph">Maintenant que le système est propre, que l&rsquo;interface graphique ne vient plus grignoter vos précieux gigaoctets de mémoire vidéo, on va s&rsquo;attaquer au « cerveau » de la machine. L&rsquo;idée ici n&rsquo;est pas de suivre un tuto de plus sur l&rsquo;IA, mais de comprendre comment orchestrer une stack qui tient la route pour de la production réelle.</p>



<h2 class="wp-block-heading">Reprendre le contrôle : mon IA locale avec Mistral NeMo, Ollama et Open WebUI</h2>



<p class="wp-block-paragraph">Le passage à une IA 100 % locale n&rsquo;est pas qu&rsquo;une question de confidentialité. C&rsquo;est avant tout une question de confort et de précision. Quand on travaille sur des projets sérieux, on ne peut pas se permettre d&rsquo;avoir une IA qui « oublie » le début de la conversation ou qui répond avec le ton policé d&rsquo;un département de relations publiques californien.</p>



<p class="wp-block-paragraph">Voici comment j&rsquo;ai structuré mon environnement pour exploiter au maximum mes 16 Go de VRAM.</p>



<figure class="wp-block-image size-full"><img width="978" height="508"  alt="" class="wp-image-180"/ loading="lazy" decoding="async" src="https://tazmenworld.com/wp-content/uploads/2026/04/image-4.png" srcset="https://tazmenworld.com/wp-content/uploads/2026/04/image-4.png 978w, https://tazmenworld.com/wp-content/uploads/2026/04/image-4-300x156.png 300w, https://tazmenworld.com/wp-content/uploads/2026/04/image-4-768x399.png 768w" sizes="auto, (max-width: 978px) 100vw, 978px" /></figure>



<figure class="wp-block-image size-large"><img width="1024" height="470"  alt="" class="wp-image-181"/ loading="lazy" decoding="async" src="https://tazmenworld.com/wp-content/uploads/2026/04/image-5-1024x470.png" srcset="https://tazmenworld.com/wp-content/uploads/2026/04/image-5-1024x470.png 1024w, https://tazmenworld.com/wp-content/uploads/2026/04/image-5-300x138.png 300w, https://tazmenworld.com/wp-content/uploads/2026/04/image-5-768x353.png 768w, https://tazmenworld.com/wp-content/uploads/2026/04/image-5-1536x705.png 1536w, https://tazmenworld.com/wp-content/uploads/2026/04/image-5.png 1675w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading">1. Pourquoi le choix « Européen » : Mistral vs Llama vs Qwen</h2>



<p class="wp-block-paragraph">C&rsquo;est un point crucial qu&rsquo;on aborde rarement. Tous les modèles d&rsquo;IA ne se valent pas, et ce n&rsquo;est pas qu&rsquo;une question de « benchmarks ». C&rsquo;est une question de culture et de structure de langue.</p>



<ul class="wp-block-list">
<li><strong>Llama (Meta) :</strong> Très puissant, mais formaté par une vision américaine de la « safety ». Le modèle a tendance à être trop verbeux, à s&rsquo;excuser pour un rien et à utiliser des tournures de phrases très (trop) amicales qui sonnent faux en français comme Gemini ou Chatgpt.</li>



<li><strong>Qwen (Alibaba) :</strong> Techniquement impressionnant, surtout en code, mais on sent parfois une structure de pensée différente, presque « traduite », qui peut manquer de naturel sur des nuances rédactionnelles complexes en Europe.</li>



<li><strong>Mistral (Mistral AI) :</strong> C&rsquo;est mon choix par défaut. Pourquoi ? Parce que Mistral est conçu en Europe. On retrouve dans ses réponses une structure logique et une concision qui collent beaucoup mieux à notre façon de nous exprimer. Le ton est plus direct, plus pragmatique, et surtout, il maîtrise les subtilités de la langue française (et européenne en général) sans avoir besoin d&rsquo;en faire des tonnes. C&rsquo;est un modèle qui « réfléchit » de manière plus proche de la nôtre.</li>
</ul>



<h2 class="wp-block-heading">2. La stratégie de stockage : Le NVMe de 4 To dédié</h2>



<p class="wp-block-paragraph">On en a parlé rapidement, mais le stockage est le moteur silencieux de votre IA. Charger un modèle de 14 Go doit être une opération transparente.</p>



<p class="wp-block-paragraph">J&rsquo;utilise un <strong>disque NVMe de 4 To</strong> entièrement dédié à l&rsquo;IA. Voici pourquoi c&rsquo;est un choix pragmatique :</p>



<ul class="wp-block-list">
<li><strong>Éviter l&rsquo;asphyxie du système :</strong> Les modèles sont lourds. Si vous téléchargez trois ou quatre versions de Mistral ou de Codestral pour comparer, vous perdez 50 Go en dix minutes. Sur un disque système, c&rsquo;est le crash assuré.</li>



<li><strong>Vitesse de swap :</strong> Même avec 16 Go de VRAM, il arrive qu&rsquo;on ait besoin de charger/décharger des modèles pour passer du texte à l&rsquo;image. Le NVMe permet de le faire sans avoir l&rsquo;impression que le PC a figé.</li>



<li><strong>Anonymisation des chemins :</strong> Pour Docker, j&rsquo;ai monté ce disque sur un point propre (type <code>/mnt/storage-ia/</code>). Cela permet de garder un fichier de configuration lisible et de déplacer l&rsquo;intégralité de sa bibliothèque de modèles d&rsquo;une machine à l&rsquo;autre simplement en déplaçant le disque et en mettant à jour une ligne dans le <code>.env</code>.</li>
</ul>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<figure class="wp-block-image size-full"><img width="762" height="283"  alt="" class="wp-image-189"/ loading="lazy" decoding="async" src="https://tazmenworld.com/wp-content/uploads/2026/04/image-9.png" srcset="https://tazmenworld.com/wp-content/uploads/2026/04/image-9.png 762w, https://tazmenworld.com/wp-content/uploads/2026/04/image-9-300x111.png 300w" sizes="auto, (max-width: 762px) 100vw, 762px" /></figure>
</blockquote>



<h2 class="wp-block-heading">3. L&rsquo;architecture Docker : Le pilotage de la VRAM</h2>



<p class="wp-block-paragraph">Docker est indispensable pour isoler les pilotes NVIDIA. Sans lui, une mise à jour d&rsquo;Ubuntu peut casser votre installation CUDA. Voici la structure de mon <code>docker-compose.yml</code>. Notez bien la gestion de ComfyUI : il est là, mais il ne démarre que si je l&rsquo;appelle.</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>services:
  # Moteur d'inférence (Le coeur)
  ollama:
    image: ollama/ollama
    container_name: ollama
    volumes:
      - /chemin/anonymise/ssd-ia/models:/root/.ollama
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: all
              capabilities: &#91;gpu&#93;
    restart: unless-stopped

  # Interface utilisateur (Le visage)
  open-webui:
    image: ghcr.io/open-webui/open-webui:main
    container_name: open-webui
    volumes:
      - ./open-webui-data:/app/backend/data
    depends_on:
      - ollama
    ports:
      - "3000:8080"
    environment:
      - 'OLLAMA_BASE_URL=http://ollama:11434'
    restart: unless-stopped

  # Génération d'images (Démarrage manuel pour préserver les 16 Go de VRAM)
  comfyui:
    build: .
    container_name: comfyui
    runtime: nvidia
    restart: "no" # &lt;--- Crucial : ne consomme rien au repos</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9FF">services</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">  # </span><span style="color: #D8DEE9">Moteur</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">d</span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">inférence (Le coeur</span><span style="color: #D8DEE9">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">  ollama</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">    image</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">ollama</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">ollama</span></span>
<span class="line"><span style="color: #D8DEE9FF">    container_name</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">ollama</span></span>
<span class="line"><span style="color: #D8DEE9FF">    volumes</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">chemin</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">anonymise</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">ssd</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">ia</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9FF">models</span><span style="color: #ECEFF4">:</span><span style="color: #ECEFF4">/</span><span style="color: #EBCB8B">root</span><span style="color: #ECEFF4">/</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">ollama</span></span>
<span class="line"><span style="color: #D8DEE9FF">    deploy</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">      resources</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">        reservations</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">          devices</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF"> driver</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">nvidia</span></span>
<span class="line"><span style="color: #D8DEE9FF">              count</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">all</span></span>
<span class="line"><span style="color: #D8DEE9FF">              capabilities</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> &#91;</span><span style="color: #D8DEE9">gpu</span><span style="color: #D8DEE9FF">&#93;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    restart</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">unless</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">stopped</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">  # </span><span style="color: #D8DEE9">Interface</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">utilisateur</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">Le</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">visage</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">open</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF">webui</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">    image</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">ghcr</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">io</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">open</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">webui</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">open</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF">webui</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9">main</span></span>
<span class="line"><span style="color: #D8DEE9FF">    container_name</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">open</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">webui</span></span>
<span class="line"><span style="color: #D8DEE9FF">    volumes</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">.</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">open</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">webui</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF">data</span><span style="color: #ECEFF4">:</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">app</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">backend</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">data</span></span>
<span class="line"><span style="color: #D8DEE9FF">    depends_on</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">ollama</span></span>
<span class="line"><span style="color: #D8DEE9FF">    ports</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">3000:8080</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    environment</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">OLLAMA_BASE_URL=http://ollama:11434</span><span style="color: #ECEFF4">&#39;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    restart</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">unless</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">stopped</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">  # </span><span style="color: #D8DEE9">Génération</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">d</span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">images (Démarrage manuel pour préserver les 16 Go de VRAM</span><span style="color: #D8DEE9">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">  comfyui</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">    build</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">.</span></span>
<span class="line"><span style="color: #D8DEE9FF">    container_name</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">comfyui</span></span>
<span class="line"><span style="color: #D8DEE9FF">    runtime</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">nvidia</span></span>
<span class="line"><span style="color: #D8DEE9FF">    restart</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">no</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF"> # </span><span style="color: #81A1C1">&lt;---</span><span style="color: #D8DEE9FF"> Crucial </span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">ne</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">consomme</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">rien</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">au</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">repos</span></span></code></pre></div>



<figure class="wp-block-image size-full"><img width="771" height="481"  alt="" class="wp-image-196"/ loading="lazy" decoding="async" src="https://tazmenworld.com/wp-content/uploads/2026/04/infra_IA-1.jpg" srcset="https://tazmenworld.com/wp-content/uploads/2026/04/infra_IA-1.jpg 771w, https://tazmenworld.com/wp-content/uploads/2026/04/infra_IA-1-300x187.jpg 300w, https://tazmenworld.com/wp-content/uploads/2026/04/infra_IA-1-768x479.jpg 768w" sizes="auto, (max-width: 771px) 100vw, 771px" /><figcaption class="wp-element-caption">Configuration globale : Ollama en local, OpenWeb UI et  Cumfyui avec Nvidia Container Toolkit sur Docker rootless.</figcaption></figure>



<h2 class="wp-block-heading">4. Tableau comparatif des modèles utilisés</h2>



<p class="wp-block-paragraph">Voici comment je répartis la charge de travail sur ma carte de 16 Go. L&rsquo;idée est d&rsquo;avoir le bon outil pour la bonne tâche, sans jamais saturer la mémoire inutilement.</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>Modèle</th><th>Taille</th><th>Usage Principal</th><th>Pourquoi ce choix ?</th><th>Occupation VRAM (Q8)</th></tr></thead><tbody><tr><td><strong>Mistral NeMo 12B</strong></td><td>12B</td><td>Rédaction &amp; Chat quotidien</td><td><strong>Le plus naturel.</strong> Structure de phrase européenne, concis et intelligent.</td><td>~13 Go</td></tr><tr><td><strong>Ministral-3 14B</strong></td><td>14B</td><td>Analyse &amp; Code complexe</td><td><strong>Logique pure.</strong> Énorme contexte (256k) pour avaler des docs entiers.</td><td>~15 Go</td></tr><tr><td><strong>Llama 3.1 8B</strong></td><td>8B</td><td>Tâches de tri basiques</td><td><strong>Rapidité.</strong> Utilisé quand la nuance importe peu mais que la vitesse est clé.</td><td>~8 Go</td></tr></tbody></table></figure>



<figure class="wp-block-image size-full"><img width="941" height="271"  alt="" class="wp-image-192"/ loading="lazy" decoding="async" src="https://tazmenworld.com/wp-content/uploads/2026/04/image-12.png" srcset="https://tazmenworld.com/wp-content/uploads/2026/04/image-12.png 941w, https://tazmenworld.com/wp-content/uploads/2026/04/image-12-300x86.png 300w, https://tazmenworld.com/wp-content/uploads/2026/04/image-12-768x221.png 768w" sizes="auto, (max-width: 941px) 100vw, 941px" /></figure>



<h2 class="wp-block-heading">5. Pourquoi ces modèles et pas d&rsquo;autres ?</h2>



<p class="wp-block-paragraph">Le choix de <strong>Mistral NeMo 12B</strong> est le résultat de nombreux tests. Sur une carte de 16 Go, c&rsquo;est le « sweet spot ».</p>



<ul class="wp-block-list">
<li><strong>En Q8_0 (8-bit) :</strong> Le modèle est quasi identique à la version non compressée. On a une précision chirurgicale.</li>



<li><strong>Le style :</strong> Contrairement à Llama qui a tendance à donner des conseils de vie non sollicités ou à faire de longs préambules (« En tant qu&rsquo;intelligence artificielle, je&#8230; »), Mistral NeMo répond à la question. Point. C&rsquo;est ce gain de temps et cette clarté qui font la différence en milieu pro.</li>
</ul>



<p class="wp-block-paragraph">Le <strong>Ministral-3 14B</strong>, lui, est mon joker pour les dossiers lourds. Sa capacité à gérer <strong>256 000 tokens</strong> change la façon dont on travaille. On ne lui donne plus une question, on lui donne un contexte global. C&rsquo;est le modèle que je sollicite pour auditer des fichiers de configuration Docker ou pour résumer des échanges techniques interminables.</p>



<h2 class="wp-block-heading">6. Gestion du workflow : Priorité au texte</h2>



<p class="wp-block-paragraph">Dans ma configuration, la VRAM est une ressource précieuse qu&rsquo;on ne gaspille pas. Le fait d&rsquo;avoir mis <strong>ComfyUI</strong> (ou tout autre service d&rsquo;image) en démarrage manuel est un choix pragmatique. Faire de l&rsquo;image demande souvent de charger des modèles SDXL ou Flux qui prennent 10 à 12 Go de VRAM. Si Ollama a déjà réservé 13 Go pour Mistral, le crash est inévitable.</p>



<p class="wp-block-paragraph">Mon workflow est donc linéaire :</p>



<p class="wp-block-paragraph"><strong>Phase créative :</strong> Je coupe les modèles texte (Ollama libère la VRAM automatiquement après quelques minutes d&rsquo;inactivité) et je lance ComfyUI.</p>



<p class="wp-block-paragraph"><strong>Phase de réflexion/rédaction :</strong> 100 % de la VRAM pour Mistral via Open WebUI.</p>



<figure class="wp-block-image size-full"><img width="975" height="280"  alt="" class="wp-image-193"/ loading="lazy" decoding="async" src="https://tazmenworld.com/wp-content/uploads/2026/04/image-13.png" srcset="https://tazmenworld.com/wp-content/uploads/2026/04/image-13.png 975w, https://tazmenworld.com/wp-content/uploads/2026/04/image-13-300x86.png 300w, https://tazmenworld.com/wp-content/uploads/2026/04/image-13-768x221.png 768w" sizes="auto, (max-width: 975px) 100vw, 975px" /></figure>



<h2 class="wp-block-heading">7. Vers une mémoire infinie : Le RAG (Prochainement)</h2>



<p class="wp-block-paragraph">Vous avez sans doute remarqué l&rsquo;option « Documents » dans Open WebUI. C&rsquo;est ce qu&rsquo;on appelle le <strong>RAG (Retrieval-Augmented Generation)</strong>. L&rsquo;idée est simple : au lieu de tout demander au modèle, on lui permet de fouiller dans nos propres fichiers stockés sur le SSD de 4 To.</p>



<p class="wp-block-paragraph">C&rsquo;est un sujet tellement vaste et puissant (transformer son PC en base de connaissances souveraine) que j&rsquo;ai décidé de lui consacrer un <strong>article entier</strong>. On y verra comment indexer des milliers de documents sans que cela ne ralentisse l&rsquo;IA et comment poser des questions à sa propre archive technique.</p>



<h2 class="wp-block-heading">Conclusion</h2>



<figure class="wp-block-image size-large"><img width="1024" height="559"  alt="" class="wp-image-197"/ loading="lazy" decoding="async" src="https://tazmenworld.com/wp-content/uploads/2026/04/Capture-decran-du-2026-04-16-18-52-31-1024x559.png" srcset="https://tazmenworld.com/wp-content/uploads/2026/04/Capture-decran-du-2026-04-16-18-52-31-1024x559.png 1024w, https://tazmenworld.com/wp-content/uploads/2026/04/Capture-decran-du-2026-04-16-18-52-31-300x164.png 300w, https://tazmenworld.com/wp-content/uploads/2026/04/Capture-decran-du-2026-04-16-18-52-31-768x419.png 768w, https://tazmenworld.com/wp-content/uploads/2026/04/Capture-decran-du-2026-04-16-18-52-31.png 1276w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">Reprendre le contrôle de son IA, c&rsquo;est d&rsquo;abord arrêter de subir les choix des géants du cloud. Avec une carte de 16 Go, un bon disque NVMe et une stack Docker bien réglée, on a entre les mains un outil de travail plus performant et plus respectueux de notre culture que n&rsquo;importe quel abonnement à 20$/mois.</p>



<p class="wp-block-paragraph">Mistral NeMo et Ministral-3 ne sont pas juste des noms sur un benchmark, ce sont des outils calibrés pour notre façon de travailler en Europe. Optimisez votre VRAM, soignez votre stockage, et laissez l&rsquo;IA bosser pour vous, pas l&rsquo;inverse. 🚀🛠️</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p class="wp-block-paragraph"><em>Note technique : Pour ceux qui veulent tester le Ministral-3 14B dès maintenant sur leur config Docker, la commande <code>ollama run ministral-3:14b</code> est votre point de départ.</em></p>
]]></content:encoded>
					
					<wfw:commentRss>https://tazmenworld.com/2026/04/16/reprendre-le-controle-mon-ia-locale-avec-mistral-nemo-ollama-et-open-webui/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>VRAM Tuning (Partie 2) : Passer sous Linux pour libérer votre GPU</title>
		<link>https://tazmenworld.com/2026/04/15/vram-tuning-partie-2-passer-sous-linux-pour-liberer-votre-gpu/</link>
					<comments>https://tazmenworld.com/2026/04/15/vram-tuning-partie-2-passer-sous-linux-pour-liberer-votre-gpu/#comments</comments>
		
		<dc:creator><![CDATA[tazmen3]]></dc:creator>
		<pubDate>Wed, 15 Apr 2026 06:28:01 +0000</pubDate>
				<category><![CDATA[Intelligence Artificielle (IA)]]></category>
		<guid isPermaLink="false">https://tazmenworld.com/?p=179</guid>

					<description><![CDATA[On se retrouve pour la suite de notre dossier sur l’optimisation de la VRAM. Dans la partie 1, on a vu comment gratter chaque Mo possible sur Windows. Mais soyons honnêtes : au bout d&#8217;un moment, on se cogne contre les limites du système lui-même. 🛑 Le constat : Windows est trop gourmand Même avec [&#8230;]]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-large"><img width="1024" height="572"  alt="" class="wp-image-185"/ loading="lazy" decoding="async" src="https://tazmenworld.com/wp-content/uploads/2026/04/xq1h9xq1h9xq1h9-1024x572.png" srcset="https://tazmenworld.com/wp-content/uploads/2026/04/xq1h9xq1h9xq1h9-1024x572.png 1024w, https://tazmenworld.com/wp-content/uploads/2026/04/xq1h9xq1h9xq1h9-300x167.png 300w, https://tazmenworld.com/wp-content/uploads/2026/04/xq1h9xq1h9xq1h9-768x429.png 768w, https://tazmenworld.com/wp-content/uploads/2026/04/xq1h9xq1h9xq1h9-1536x857.png 1536w, https://tazmenworld.com/wp-content/uploads/2026/04/xq1h9xq1h9xq1h9-2048x1143.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">On se retrouve pour la suite de notre dossier sur l’optimisation de la VRAM. Dans la <a target="_blank" rel="noreferrer noopener" href="https://tazmenworld.com/2026/01/04/vram-tuning-partie-1-maximiser-votre-nouveau-gpu-pour-lia-headless-scripting/">partie 1</a>, on a vu comment gratter chaque Mo possible sur Windows. Mais soyons honnêtes : au bout d&rsquo;un moment, on se cogne contre les limites du système lui-même. 🛑</p>



<h3 class="wp-block-heading">Le constat : Windows est trop gourmand</h3>



<p class="wp-block-paragraph">Même avec 32 Go de RAM et un nettoyage complet des applications au démarrage, Windows a cette fâcheuse tendance à s&rsquo;étendre. Chez moi, il finit par occuper entre <strong>9 et 10 Go de RAM</strong> juste pour « exister », malgré toutes les optimisations possibles.</p>



<p class="wp-block-paragraph">Côté VRAM, c&rsquo;est le même combat. Même en suivant les astuces de mon article précédent pour réduire la consommation de l&rsquo;interface, Windows garde toujours une « taxe » de <strong>400 à 500 Mo</strong> sur votre GPU. Ça paraît peu ? Sur une carte de 16 Go comme la <strong>RTX 5070 Ti</strong> ou la <strong>RTX 5080</strong>, c&rsquo;est pourtant la différence entre charger un gros modèle Flux ou avoir une erreur « Out of Memory ». 📉</p>



<p class="wp-block-paragraph">En comparaison, une installation <strong>Ubuntu</strong> bien configurée ne consomme que <strong>20 Mo de VRAM</strong>. Le calcul est vite fait : on rend son potentiel brut à la carte graphique.</p>



<h3 class="wp-block-heading">Pourquoi Ubuntu + Docker ?</h3>



<p class="wp-block-paragraph">Si vous avez une carte performante avec 16 Go de VRAM, utiliser Ubuntu est le meilleur choix pour l&rsquo;IA. Pour garder un système propre, j&rsquo;ai opté pour <strong>Docker</strong>. C’est la méthode la plus robuste : on évite les conflits de versions Python (le fameux « Python hell ») et on garde un environnement isolé. 🐳</p>



<p class="wp-block-paragraph">Ce guide vous explique comment installer ComfyUI, configurer l&rsquo;accès au GPU et lier vos modèles déjà existants (issus de Stability Matrix par exemple) pour ne pas gaspiller d&rsquo;espace disque.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">1. Vérification des prérequis matériels 🖥️</h2>



<p class="wp-block-paragraph">Avant de commencer, on doit s&rsquo;assurer que ta carte graphique est bien reconnue par Ubuntu. C&rsquo;est la base indispensable pour que tout le reste fonctionne.</p>



<p class="wp-block-paragraph">Ouvre un terminal et tape :</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>nvidia-smi</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">nvidia</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">smi</span></span></code></pre></div>



<figure class="wp-block-image size-full"><img width="978" height="508"  alt="" class="wp-image-180"/ loading="lazy" decoding="async" src="https://tazmenworld.com/wp-content/uploads/2026/04/image-4.png" srcset="https://tazmenworld.com/wp-content/uploads/2026/04/image-4.png 978w, https://tazmenworld.com/wp-content/uploads/2026/04/image-4-300x156.png 300w, https://tazmenworld.com/wp-content/uploads/2026/04/image-4-768x399.png 768w" sizes="auto, (max-width: 978px) 100vw, 978px" /></figure>



<p class="wp-block-paragraph">Tu devrais voir un tableau s&rsquo;afficher. Ce qui nous intéresse ici, c&rsquo;est que le nom de ta carte apparaisse bien et que la <strong>Driver Version</strong> soit à jour (idéalement au-dessus de 550 pour les cartes récentes). Si ce tableau s&rsquo;affiche, ton pilote est opérationnel.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">2. Installation de Docker : Le moteur de ton projet ⚙️</h2>



<p class="wp-block-paragraph">Docker va nous permettre d&rsquo;isoler ComfyUI. Au lieu d&rsquo;installer des dizaines de bibliothèques directement sur ton Ubuntu, on va créer un « conteneur » qui contiendra tout le nécessaire.</p>



<h3 class="wp-block-heading">Pourquoi Docker ?</h3>



<ul class="wp-block-list">
<li><strong>Propreté :</strong> Si tu veux supprimer ComfyUI un jour, tu supprimes juste le conteneur, et ton système reste comme neuf.</li>



<li><strong>Isolation :</strong> Pas de conflit entre tes différents projets IA.</li>



<li><strong>Simplicité :</strong> On utilise une « recette » précise qui fonctionne à tous les coups.</li>
</ul>



<h3 class="wp-block-heading">Les étapes d&rsquo;installation</h3>



<p class="wp-block-paragraph">Tape ces commandes pour installer Docker de manière propre (version officielle) :</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly># Mise à jour des dépôts
sudo apt-get update
sudo apt-get install ca-certificates curl gnupg

# Ajout de la clé GPG officielle de Docker
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

# Configuration du dépôt stable
echo \
  "deb &#91;arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg&#93; https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release &amp;&amp; echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# Installation finale
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9FF"># </span><span style="color: #D8DEE9">Mise</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">à</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">jour</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">des</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">dépôts</span></span>
<span class="line"><span style="color: #D8DEE9">sudo</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">apt</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">get</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">update</span></span>
<span class="line"><span style="color: #D8DEE9">sudo</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">apt</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">get</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">install</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">ca</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">certificates</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">curl</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">gnupg</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF"># </span><span style="color: #D8DEE9">Ajout</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">de</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">la</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">clé</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">GPG</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">officielle</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">de</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Docker</span></span>
<span class="line"><span style="color: #D8DEE9">sudo</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">install</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">m</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0755</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">d</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">etc</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">apt</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">keyrings</span></span>
<span class="line"><span style="color: #D8DEE9">curl</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">fsSL</span><span style="color: #D8DEE9FF"> https</span><span style="color: #ECEFF4">:</span><span style="color: #616E88">//download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg</span></span>
<span class="line"><span style="color: #D8DEE9">sudo</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">chmod</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">a</span><span style="color: #81A1C1">+</span><span style="color: #D8DEE9">r</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">etc</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">apt</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">keyrings</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">docker</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">gpg</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF"># </span><span style="color: #D8DEE9">Configuration</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">du</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">dépôt</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">stable</span></span>
<span class="line"><span style="color: #D8DEE9">echo</span><span style="color: #D8DEE9FF"> \</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">deb &#91;arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg&#93; https://download.docker.com/linux/ubuntu </span><span style="color: #EBCB8B">\</span></span>
<span class="line"><span style="color: #A3BE8C">  $(. /etc/os-release &amp;&amp; echo </span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9">$VERSION_CODENAME</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">) stable</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">|</span><span style="color: #D8DEE9FF"> \</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">sudo</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">tee</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">etc</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">apt</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">sources</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">list</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">d</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">docker</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">list</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">dev</span><span style="color: #81A1C1">/null</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF"># </span><span style="color: #D8DEE9">Installation</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">finale</span></span>
<span class="line"><span style="color: #D8DEE9">sudo</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">apt</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">get</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">update</span></span>
<span class="line"><span style="color: #D8DEE9">sudo</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">apt</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">get</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">install</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">docker</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">ce</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">docker</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">ce</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">cli</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">containerd</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">io</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">docker</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">buildx</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">plugin</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">docker</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">compose</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">plugin</span></span></code></pre></div>



<h2 class="wp-block-heading">3. Le pont vers le GPU : NVIDIA Container Toolkit 🌉</h2>



<p class="wp-block-paragraph">Par défaut, Docker ne peut pas voir ta carte graphique. Il faut installer un « pont » qui permet au conteneur d&rsquo;utiliser la puissance de calcul de ta RTX.</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly># Configuration du dépôt NVIDIA
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \
    sed 's#deb https://#deb &#91;signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg&#93; https://#g' | \
    sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list

# Installation et configuration
sudo apt-get update
sudo apt-get install -y nvidia-container-toolkit
sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9FF"># </span><span style="color: #D8DEE9">Configuration</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">du</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">dépôt</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">NVIDIA</span></span>
<span class="line"><span style="color: #D8DEE9">curl</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">fsSL</span><span style="color: #D8DEE9FF"> https</span><span style="color: #ECEFF4">:</span><span style="color: #616E88">//nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg</span></span>
<span class="line"><span style="color: #D8DEE9">curl</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">s</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">L</span><span style="color: #D8DEE9FF"> https</span><span style="color: #ECEFF4">:</span><span style="color: #616E88">//nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">sed</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">s#deb https://#deb &#91;signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg&#93; https://#g</span><span style="color: #ECEFF4">&#39;</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">|</span><span style="color: #D8DEE9FF"> \</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">sudo</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">tee</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">etc</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">apt</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">sources</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">list</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">d</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">nvidia</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">container</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">toolkit</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">list</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF"># </span><span style="color: #D8DEE9">Installation</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">et</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">configuration</span></span>
<span class="line"><span style="color: #D8DEE9">sudo</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">apt</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">get</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">update</span></span>
<span class="line"><span style="color: #D8DEE9">sudo</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">apt</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">get</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">install</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">y</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">nvidia</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">container</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">toolkit</span></span>
<span class="line"><span style="color: #D8DEE9">sudo</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">nvidia</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">ctk</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">runtime</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">configure</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">--</span><span style="color: #D8DEE9">runtime</span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9">docker</span></span>
<span class="line"><span style="color: #D8DEE9">sudo</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">systemctl</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">restart</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">docker</span></span></code></pre></div>



<h2 class="wp-block-heading">4. Préparation de l&rsquo;environnement ComfyUI 🎨<sup></sup></h2>



<p class="wp-block-paragraph">On va créer un dossier dédié pour notre installation. On va y placer deux fichiers : un pour construire l&rsquo;image et un pour gérer le lancement.</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>mkdir ~/comfyui-station &amp;&amp; cd ~/comfyui-station</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">mkdir</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">~/</span><span style="color: #D8DEE9">comfyui</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">station</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&amp;&amp;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">cd</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">~/</span><span style="color: #D8DEE9">comfyui</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">station</span></span></code></pre></div>



<h3 class="wp-block-heading">Le fichier Dockerfile</h3>



<p class="wp-block-paragraph">Ce fichier contient la « recette » de notre environnement. Il va télécharger une base NVIDIA/PyTorch stable et y installer ComfyUI.</p>



<p class="wp-block-paragraph">Tape <code>nano Dockerfile</code> et colle ceci :</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly># On part d'une base CUDA solide
FROM pytorch/pytorch:2.2.1-cuda12.1-cudnn8-runtime

# Installation des dépendances système pour OpenCV et Git
RUN apt-get update &amp;&amp; apt-get install -y \
    git \
    libgl1-mesa-glx \
    libglib2.0-0 \
    &amp;&amp; rm -rf /var/lib/apt/lists/*

# Clonage de ComfyUI
WORKDIR /opt
RUN git clone https://github.com/comfyanonymous/ComfyUI.git

# Installation des dépendances Python de base
WORKDIR /opt/ComfyUI
RUN pip install --no-cache-dir -r requirements.txt

# --- AJOUT CRUCIAL POUR TON BLOG ---
# On installe les bibliothèques requises par les extensions populaires
# (Manager, Crystools, Lora Manager, etc.)
RUN pip install --no-cache-dir piexif deepdiff py-cpuinfo natsort pynvml toml GitPython

# Lancement du serveur
EXPOSE 8188
CMD &#91;"python", "main.py", "--listen", "0.0.0.0"&#93;</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9FF"># </span><span style="color: #D8DEE9">On</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">part</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">d</span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">une base CUDA solid</span><span style="color: #D8DEE9">e</span></span>
<span class="line"><span style="color: #D8DEE9">FROM</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">pytorch</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9FF">pytorch</span><span style="color: #ECEFF4">:</span><span style="color: #B48EAD">2.2</span><span style="color: #ECEFF4">.</span><span style="color: #B48EAD">1</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">cuda12</span><span style="color: #ECEFF4">.</span><span style="color: #B48EAD">1</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">cudnn8</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">runtime</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF"># </span><span style="color: #D8DEE9">Installation</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">des</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">dépendances</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">système</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">pour</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">OpenCV</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">et</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Git</span></span>
<span class="line"><span style="color: #D8DEE9">RUN</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">apt</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">get</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">update</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&amp;&amp;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">apt</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">get</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">install</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">y</span><span style="color: #D8DEE9FF"> \</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">git</span><span style="color: #D8DEE9FF"> \</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">libgl1</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">mesa</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">glx</span><span style="color: #D8DEE9FF"> \</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">libglib2</span><span style="color: #ECEFF4">.</span><span style="color: #B48EAD">0</span><span style="color: #81A1C1">-</span><span style="color: #B48EAD">0</span><span style="color: #D8DEE9FF"> \</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">&amp;&amp;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">rm</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">rf</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">/var</span><span style="color: #D8DEE9FF">/</span><span style="color: #D8DEE9">lib</span><span style="color: #D8DEE9FF">/apt/lists</span><span style="color: #616E88">/*</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88"># Clonage de ComfyUI</span></span>
<span class="line"><span style="color: #616E88">WORKDIR /opt</span></span>
<span class="line"><span style="color: #616E88">RUN git clone https://github.com/comfyanonymous/ComfyUI.git</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88"># Installation des dépendances Python de base</span></span>
<span class="line"><span style="color: #616E88">WORKDIR /opt/ComfyUI</span></span>
<span class="line"><span style="color: #616E88">RUN pip install --no-cache-dir -r requirements.txt</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88"># --- AJOUT CRUCIAL POUR TON BLOG ---</span></span>
<span class="line"><span style="color: #616E88"># On installe les bibliothèques requises par les extensions populaires</span></span>
<span class="line"><span style="color: #616E88"># (Manager, Crystools, Lora Manager, etc.)</span></span>
<span class="line"><span style="color: #616E88">RUN pip install --no-cache-dir piexif deepdiff py-cpuinfo natsort pynvml toml GitPython</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88"># Lancement du serveur</span></span>
<span class="line"><span style="color: #616E88">EXPOSE 8188</span></span>
<span class="line"><span style="color: #616E88">CMD &#91;&quot;python&quot;, &quot;main.py&quot;, &quot;--listen&quot;, &quot;0.0.0.0&quot;&#93;</span></span></code></pre></div>



<h2 class="wp-block-heading">5. Mapping des modèles existants (Stability Matrix) 🧠</h2>



<p class="wp-block-paragraph">C&rsquo;est l&rsquo;étape cruciale pour ne pas perdre de place. Si tu as déjà tes modèles (Checkpoints, Lora, VAE) sur un disque dur séparé, on va les « monter » directement dans le conteneur.</p>



<h3 class="wp-block-heading">Le fichier docker-compose.yml</h3>



<p class="wp-block-paragraph">Tape <code>nano docker-compose.yml</code> et adapte les chemins vers ton disque de données :</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>services:
  comfyui:
    build: .
    container_name: comfyui
    runtime: nvidia
    environment:
      - NVIDIA_VISIBLE_DEVICES=all
    ports:
      - "8188:8188"
    volumes:
      # --- STOCKAGE DES MODÈLES (À adapter selon votre disque) ---
      # Remplacez /media/NOM_UTILISATEUR/DISQUE/ par votre chemin réel
      - /media/user/DATA/Models/StableDiffusion:/opt/ComfyUI/models/checkpoints
      - /media/user/DATA/Models/Lora:/opt/ComfyUI/models/loras
      - /media/user/DATA/Models/VAE:/opt/ComfyUI/models/vae
      
      # --- DONNÉES LOCALES (Persistance dans le dossier du projet) ---
      - ./custom_nodes:/opt/ComfyUI/custom_nodes # Vos extensions
      - ./user:/opt/ComfyUI/user                 # Vos réglages (langue, thèmes)
      - ./output:/opt/ComfyUI/output             # Vos images générées

    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: all
              capabilities: &#91;gpu&#93;
    
    # "no" pour garder le contrôle manuel, "unless-stopped" pour un démarrage auto
    restart: "no"</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9FF">services</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">  comfyui</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">    build</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">.</span></span>
<span class="line"><span style="color: #D8DEE9FF">    container_name</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">comfyui</span></span>
<span class="line"><span style="color: #D8DEE9FF">    runtime</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">nvidia</span></span>
<span class="line"><span style="color: #D8DEE9FF">    environment</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">NVIDIA_VISIBLE_DEVICES</span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9">all</span></span>
<span class="line"><span style="color: #D8DEE9FF">    ports</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">8188:8188</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    volumes</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">      # </span><span style="color: #81A1C1">---</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">STOCKAGE</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">DES</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">MODÈLES</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">À</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">adapter</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">selon</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">votre</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">disque</span><span style="color: #D8DEE9FF">) </span><span style="color: #81A1C1">---</span></span>
<span class="line"><span style="color: #D8DEE9FF">      # </span><span style="color: #D8DEE9">Remplacez</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">media</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">NOM_UTILISATEUR</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">DISQUE</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">par</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">votre</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">chemin</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">réel</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">media</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">user</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">DATA</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">Models</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9FF">StableDiffusion</span><span style="color: #ECEFF4">:</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">opt</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">ComfyUI</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">models</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">checkpoints</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">media</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">user</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">DATA</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">Models</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9FF">Lora</span><span style="color: #ECEFF4">:</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">opt</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">ComfyUI</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">models</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">loras</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">media</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">user</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">DATA</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">Models</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9FF">VAE</span><span style="color: #ECEFF4">:</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">opt</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">ComfyUI</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">models</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">vae</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span></span>
<span class="line"><span style="color: #D8DEE9FF">      # </span><span style="color: #81A1C1">---</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">DONNÉES</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">LOCALES</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">Persistance</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">dans</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">le</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">dossier</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">du</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">projet</span><span style="color: #D8DEE9FF">) </span><span style="color: #81A1C1">---</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">.</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9FF">custom_nodes</span><span style="color: #ECEFF4">:</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">opt</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">ComfyUI</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">custom_nodes</span><span style="color: #D8DEE9FF"> # </span><span style="color: #D8DEE9">Vos</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">extensions</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">.</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9FF">user</span><span style="color: #ECEFF4">:</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">opt</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">ComfyUI</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">user</span><span style="color: #D8DEE9FF">                 # </span><span style="color: #D8DEE9">Vos</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">réglages</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">langue</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">thèmes</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">.</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9FF">output</span><span style="color: #ECEFF4">:</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">opt</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">ComfyUI</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">output</span><span style="color: #D8DEE9FF">             # </span><span style="color: #D8DEE9">Vos</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">images</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">générées</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    deploy</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">      resources</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">        reservations</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">          devices</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF"> driver</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">nvidia</span></span>
<span class="line"><span style="color: #D8DEE9FF">              count</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">all</span></span>
<span class="line"><span style="color: #D8DEE9FF">              capabilities</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> &#91;</span><span style="color: #D8DEE9">gpu</span><span style="color: #D8DEE9FF">&#93;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span></span>
<span class="line"><span style="color: #D8DEE9FF">    # </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">no</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">pour</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">garder</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">le</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">contrôle</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">manuel</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">unless-stopped</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">pour</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">un</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">démarrage</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">auto</span></span>
<span class="line"><span style="color: #D8DEE9FF">    restart</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">no</span><span style="color: #ECEFF4">&quot;</span></span></code></pre></div>



<h2 class="wp-block-heading">6. Lancement et Monitoring 📊</h2>



<p class="wp-block-paragraph">Tout est prêt. On lance la construction et le démarrage :</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>sudo docker compose up -d --build</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">sudo</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">docker</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">compose</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">up</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">d</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">--</span><span style="color: #D8DEE9">build</span></span></code></pre></div>



<p class="wp-block-paragraph">Docker va maintenant télécharger les composants (plusieurs Go) et préparer ton serveur. Tu peux suivre l&rsquo;avancée avec :</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>sudo docker logs -f comfyui</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">sudo</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">docker</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">logs</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">f</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">comfyui</span></span></code></pre></div>



<p class="wp-block-paragraph"></p>



<h3 class="wp-block-heading">Surveiller tes ressources</h3>



<p class="wp-block-paragraph">Une fois que ComfyUI est lancé sur <code>http://localhost:8188</code>, il est important de surveiller la charge de ta carte. Je te conseille d&rsquo;installer <strong>nvtop</strong> sur ton Ubuntu :</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>sudo apt install nvtop
nvtop</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">sudo</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">apt</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">install</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">nvtop</span></span>
<span class="line"><span style="color: #D8DEE9">nvtop</span></span></code></pre></div>



<figure class="wp-block-image size-large"><img width="1024" height="470"  alt="" class="wp-image-181"/ loading="lazy" decoding="async" src="https://tazmenworld.com/wp-content/uploads/2026/04/image-5-1024x470.png" srcset="https://tazmenworld.com/wp-content/uploads/2026/04/image-5-1024x470.png 1024w, https://tazmenworld.com/wp-content/uploads/2026/04/image-5-300x138.png 300w, https://tazmenworld.com/wp-content/uploads/2026/04/image-5-768x353.png 768w, https://tazmenworld.com/wp-content/uploads/2026/04/image-5-1536x705.png 1536w, https://tazmenworld.com/wp-content/uploads/2026/04/image-5.png 1675w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">Cela t&rsquo;affichera des graphiques magnifiques sur l&rsquo;utilisation de ta VRAM et de ton GPU en temps réel.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">7. Installation du Manager et de Crystools 🛠️</h2>



<p class="wp-block-paragraph">Pour que ton expérience soit complète, tu as besoin du <strong>ComfyUI-Manager</strong>. Puisque nous avons mappé le dossier <code>custom_nodes</code>, tu peux l&rsquo;installer directement depuis ton Ubuntu :</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>cd ~/comfyui-station/custom_nodes
git clone https://github.com/ltdrdata/ComfyUI-Manager.git</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">cd</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">~/</span><span style="color: #D8DEE9">comfyui</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">station</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">custom_nodes</span></span>
<span class="line"><span style="color: #D8DEE9">git</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">clone</span><span style="color: #D8DEE9FF"> https</span><span style="color: #ECEFF4">:</span><span style="color: #616E88">//github.com/ltdrdata/ComfyUI-Manager.git</span></span></code></pre></div>



<figure class="wp-block-image size-large"><img width="1024" height="558"  alt="" class="wp-image-182"/ loading="lazy" decoding="async" src="https://tazmenworld.com/wp-content/uploads/2026/04/image-6-1024x558.png" srcset="https://tazmenworld.com/wp-content/uploads/2026/04/image-6-1024x558.png 1024w, https://tazmenworld.com/wp-content/uploads/2026/04/image-6-300x164.png 300w, https://tazmenworld.com/wp-content/uploads/2026/04/image-6-768x419.png 768w, https://tazmenworld.com/wp-content/uploads/2026/04/image-6.png 1198w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">Redémarre le conteneur (<code>sudo docker compose restart</code>) et tu verras le bouton Manager apparaître. Utilise-le pour installer <strong>Crystools</strong>, qui te permettra d&rsquo;avoir tes statistiques de ressources directement dans l&rsquo;interface web.</p>



<figure class="wp-block-image size-large"><img width="1024" height="58"  alt="" class="wp-image-183"/ loading="lazy" decoding="async" src="https://tazmenworld.com/wp-content/uploads/2026/04/image-7-1024x58.png" srcset="https://tazmenworld.com/wp-content/uploads/2026/04/image-7-1024x58.png 1024w, https://tazmenworld.com/wp-content/uploads/2026/04/image-7-300x17.png 300w, https://tazmenworld.com/wp-content/uploads/2026/04/image-7-768x43.png 768w, https://tazmenworld.com/wp-content/uploads/2026/04/image-7.png 1117w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">8. Garder le contrôle : Le mode « Démarrage Manuel » 🕹️</h2>



<p class="wp-block-paragraph">Avoir ComfyUI qui tourne en arrière-plan, c&rsquo;est pratique, mais sur une machine de guerre, on veut parfois récupérer <strong>100 % de sa VRAM</strong> pour lancer un jeu gourmand ou un logiciel de montage sans que Docker ne vienne grignoter des ressources.</p>



<p class="wp-block-paragraph">Voici comment configurer ton installation pour qu&rsquo;elle ne s&rsquo;allume que lorsque <strong>tu</strong> le décides.</p>



<h3 class="wp-block-heading">1. Modifier la règle de redémarrage</h3>



<p class="wp-block-paragraph">Par défaut, nous avons configuré Docker pour qu&rsquo;il relance ComfyUI automatiquement au démarrage du PC. Pour changer cela, ouvre ton fichier de configuration :</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>nano ~/comfyui-station/docker-compose.yml</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">nano</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">~/</span><span style="color: #D8DEE9">comfyui</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">station</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">docker</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">compose</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">yml</span></span></code></pre></div>



<p class="wp-block-paragraph">Modifie la ligne <code>restart</code> tout en bas :</p>



<ul class="wp-block-list">
<li><strong>Ancienne version :</strong> <code>restart: unless-stopped</code></li>



<li><strong>Nouvelle version :</strong> <code>restart: "no"</code></li>
</ul>



<p class="wp-block-paragraph">Applique le changement avec un petit : <code>sudo docker compose up -d</code>. Désormais, au prochain démarrage d&rsquo;Ubuntu, ComfyUI restera sagement éteint.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">2. Le pilotage « Clic-Bouton » avec Portainer</h3>



<p class="wp-block-paragraph">C&rsquo;est là que <strong>Portainer</strong> prend tout son sens. Au lieu de taper des lignes de commande, tu as maintenant une télécommande visuelle :</p>



<ol start="1" class="wp-block-list">
<li>Ouvre ton interface Portainer.</li>



<li>Dans l&rsquo;onglet <strong>Containers</strong>, tu verras ton conteneur <code>comfyui</code> avec un voyant gris (<strong>stopped</strong>).</li>



<li>Quand tu as une idée de création : coche la case et clique sur <strong>Start</strong>.</li>



<li>Une fois ta session finie : clique sur <strong>Stop</strong>. Ta carte graphique retombe instantanément à 0% d&rsquo;utilisation.</li>
</ol>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading"></h3>



<h2 class="wp-block-heading">Conclusion 🏁</h2>



<p class="wp-block-paragraph">Tu as maintenant une installation de ComfyUI professionnelle :</p>



<ol start="1" class="wp-block-list">
<li><strong>Performante :</strong> Accès direct au GPU via NVIDIA Container Toolkit.</li>



<li><strong>Organisée :</strong> Tes modèles restent sur ton disque DATA.</li>



<li><strong>Évolutive :</strong> Tu peux mettre à jour ComfyUI ou tester d&rsquo;autres versions sans jamais polluer ton système Ubuntu principal.</li>
</ol>



<p class="wp-block-paragraph">Il ne te reste plus qu&rsquo;à charger ton premier modèle et à laisser libre cours à ta créativité !</p>



<figure class="wp-block-image size-large"><img width="1024" height="158"  alt="" class="wp-image-184"/ loading="lazy" decoding="async" src="https://tazmenworld.com/wp-content/uploads/2026/04/image-8-1024x158.png" srcset="https://tazmenworld.com/wp-content/uploads/2026/04/image-8-1024x158.png 1024w, https://tazmenworld.com/wp-content/uploads/2026/04/image-8-300x46.png 300w, https://tazmenworld.com/wp-content/uploads/2026/04/image-8-768x118.png 768w, https://tazmenworld.com/wp-content/uploads/2026/04/image-8-1536x237.png 1536w, https://tazmenworld.com/wp-content/uploads/2026/04/image-8-2048x315.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph"><strong>Dernier conseil de sécurité :</strong> Pense à faire une copie de ton dossier <code>~/comfyui-station</code> (surtout les fichiers <code>Dockerfile</code> et <code>docker-compose.yml</code>) sur une clé USB ou un cloud. Si tu réinstalles ton Ubuntu un jour, tu récupéreras ton usine à images en exactement 2 minutes.</p>



<p class="wp-block-paragraph"></p>
]]></content:encoded>
					
					<wfw:commentRss>https://tazmenworld.com/2026/04/15/vram-tuning-partie-2-passer-sous-linux-pour-liberer-votre-gpu/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
	</channel>
</rss>
