<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>LLM on Zwindler's Reflection</title><link>https://blog.zwindler.fr/tags/llm/</link><description>Recent content in LLM on Zwindler's Reflection</description><generator>Hugo -- gohugo.io</generator><language>fr</language><copyright>Licensed under CC BY-SA 4.0</copyright><lastBuildDate>Tue, 17 Mar 2026 18:00:00 +0100</lastBuildDate><atom:link href="https://blog.zwindler.fr/tags/llm/index.xml" rel="self" type="application/rss+xml"/><item><title>GenAI et développement logiciel, épisode 2 : kubectl-debug-pvc, de l'idée à krew en 2x30 minutes</title><link>https://blog.zwindler.fr/2026/03/16/genai-llm-dev-kubectl-debug-pvc/</link><pubDate>Tue, 17 Mar 2026 18:00:00 +0100</pubDate><guid>https://blog.zwindler.fr/2026/03/16/genai-llm-dev-kubectl-debug-pvc/</guid><description>&lt;img src="https://blog.zwindler.fr/2026/03/kubectl-debug-pvc.webp" alt="Featured image of post GenAI et développement logiciel, épisode 2 : kubectl-debug-pvc, de l'idée à krew en 2x30 minutes" /&gt;&lt;h2 id="précédemment-dans-genai-et-dev"&gt;Précédemment, dans &amp;ldquo;GenAI et dev&amp;rdquo;
&lt;/h2&gt;&lt;p&gt;Dans &lt;a class="link" href="https://blog.zwindler.fr/2026/03/08/genai-llm-dev-podsweeper/" &gt;mon article précédent&lt;/a&gt;, je vous parlais de mon retour d&amp;rsquo;expérience avec PodSweeper, un projet développé avec OpenCode et Claude Opus. Le bilan était nuancé : vitesse brute impressionnante, mais race conditions, gestion d&amp;rsquo;erreur laxiste, et nécessité constante de supervision humaine (entre autres déconvenues).&lt;/p&gt;
&lt;p&gt;Aujourd&amp;rsquo;hui, je vous parle d&amp;rsquo;un deuxième projet, bien plus simple, né d&amp;rsquo;un vrai besoin en production. Et le constat est assez différent.&lt;/p&gt;
&lt;h2 id="lincident-qui-a-tout-déclenché"&gt;L&amp;rsquo;incident qui a tout déclenché
&lt;/h2&gt;&lt;p&gt;Vous connaissez peut-être cette situation : un pod en production, en état de fonctionnement, qui utilise un PVC en &lt;code&gt;ReadWriteOnce&lt;/code&gt;. Vous avez besoin d&amp;rsquo;aller regarder le contenu de ce volume. Bonne pratique de production : le pod en question ne dispose pas de shell (on réduit la surface d&amp;rsquo;attaque). Pas de &lt;code&gt;/bin/sh&lt;/code&gt;, pas de &lt;code&gt;/bin/bash&lt;/code&gt;, rien.&lt;/p&gt;
&lt;p&gt;Pas grave, on a &lt;code&gt;kubectl debug&lt;/code&gt; pour ça, me direz-vous !&lt;/p&gt;
&lt;p&gt;Ok, créons un conteneur éphémère dans le pod et&amp;hellip; ah non. &lt;code&gt;kubectl debug&lt;/code&gt; ne permet pas de monter les volumes du pod dans le conteneur éphémère. Il n&amp;rsquo;expose tout simplement pas l&amp;rsquo;option &lt;code&gt;volumeMounts&lt;/code&gt; pour les conteneurs éphémères.&lt;/p&gt;
&lt;p&gt;On pourrait couper le pod, ce qui permet de monter le PVC RWO dans un autre pod avec un shell, mais on n&amp;rsquo;a pas envie, c&amp;rsquo;est de la prod.&lt;/p&gt;
&lt;p&gt;Mon collègue Maxime (encore lui !) me propose une méthode de contournement. La procédure manuelle, c&amp;rsquo;est :&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Créer un conteneur éphémère sur le pod avec &lt;code&gt;kubectl debug&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Construire à la main un patch JSON pour ajouter des &lt;code&gt;volumeMounts&lt;/code&gt; au conteneur éphémère qu&amp;rsquo;on vient de créer&lt;/li&gt;
&lt;li&gt;Dans un autre terminal, se brancher &lt;del&gt;au cul du camion&lt;/del&gt; sur l&amp;rsquo;API de kube en direct avec &lt;code&gt;kubectl proxy&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Appliquer le patch via un curl sur l&amp;rsquo;API Kubernetes&lt;/li&gt;
&lt;li&gt;Attendre que le conteneur soit prêt, s&amp;rsquo;attacher au conteneur&lt;/li&gt;
&lt;li&gt;Se dire qu&amp;rsquo;il y avait quand même plus simple comme métier que patcheur de container à coup de curl.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Pour ceux qui pensent que c&amp;rsquo;est jouable, &amp;ldquo;téma la gueule du patch&amp;rdquo; comme disent (disaient ?) les jeunes :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;curl&lt;/span&gt; &lt;span class="err"&gt;http:&lt;/span&gt;&lt;span class="c1"&gt;//localhost:8001/api/v1/namespaces/&amp;lt;namespace&amp;gt;/pods/&amp;lt;pod&amp;gt;/ephemeralcontainers \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;-X&lt;/span&gt; &lt;span class="err"&gt;PATCH&lt;/span&gt; &lt;span class="err"&gt;\&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;-H&lt;/span&gt; &lt;span class="err"&gt;&amp;#39;Content-Type:&lt;/span&gt; &lt;span class="err"&gt;application/strategic-merge-patch+json&amp;#39;&lt;/span&gt; &lt;span class="err"&gt;\&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;-d&lt;/span&gt; &lt;span class="err"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;spec&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;ephemeralContainers&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;debugger&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;image&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;ubuntu&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;command&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;/bin/sh&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;targetContainerName&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&amp;lt;target-container&amp;gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;stdin&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;tty&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;volumeMounts&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&amp;lt;volume-name&amp;gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;mountPath&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;/debug/&amp;lt;volume-name&amp;gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Si vous pensez que c&amp;rsquo;est error prone, vous avez raison. Et si vous pensez que c&amp;rsquo;est pénible à faire sous pression pendant un incident de prod, vous avez encore plus raison.&lt;/p&gt;
&lt;h2 id="side-note"&gt;Side note
&lt;/h2&gt;&lt;p&gt;Les plus aguerri·es d&amp;rsquo;entre vous dans les versions récentes de Kubernetes ont peut être entendu parler du &lt;a class="link" href="https://kep.k8s.io/2590" target="_blank" rel="noopener"
&gt;KEP-2590&lt;/a&gt;, qui introduit un (relativement) nouveau flag &lt;code&gt;--subresource&lt;/code&gt; de &lt;code&gt;kubectl&lt;/code&gt;. En effet, les containers éphémères créés par la commande &lt;code&gt;kubectl debug&lt;/code&gt; ne sont pas des &lt;em&gt;resources&lt;/em&gt; (un pod, un deployment, &amp;hellip;) mais des &lt;em&gt;subresources&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Jusqu&amp;rsquo;à cette version 1.33, il était littéralement impossible de réaliser des opérations sur les subresources avec &lt;code&gt;kubectl&lt;/code&gt;, seulement les resources.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Kubernetes v1.33: Octarine&lt;/strong&gt; apporte le support du flag &amp;ndash;subresource, &lt;strong&gt;mais seulement&lt;/strong&gt; pour 3 subresources pour l&amp;rsquo;instant &lt;code&gt;status&lt;/code&gt;, &lt;code&gt;scale&lt;/code&gt; and &lt;code&gt;resize&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://kubernetes.io/blog/2025/04/23/kubernetes-v1-33-release/#subresource-support-in-kubectl" target="_blank" rel="noopener"
&gt;https://kubernetes.io/blog/2025/04/23/kubernetes-v1-33-release/#subresource-support-in-kubectl&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://kubernetes.io/docs/reference/kubectl/conventions/#subresources" target="_blank" rel="noopener"
&gt;https://kubernetes.io/docs/reference/kubectl/conventions/#subresources&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Pas de solution de ce côté-là non plus&amp;hellip;&lt;/p&gt;
&lt;h1 id="le-prompt-de-réunion"&gt;Le prompt de réunion
&lt;/h1&gt;&lt;p&gt;J&amp;rsquo;avais cette idée en tête depuis l&amp;rsquo;incident. Lundi matin, au début d&amp;rsquo;une réunion (pendant que les gens faisaient encore des blagues), j&amp;rsquo;ai lancé OpenCode avec Claude Opus et j&amp;rsquo;ai tapé un prompt qui décrivait :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Le problème : &lt;code&gt;kubectl debug&lt;/code&gt; ne monte pas les volumes PVC s&amp;rsquo;ils sont en RWO&lt;/li&gt;
&lt;li&gt;La procédure manuelle que je faisais à la main (les étapes douloureuses décrites un peu plus haut)&lt;/li&gt;
&lt;li&gt;Ce que je voulais : un outil qui automatise tout ça&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;OpenCode + Opus m&amp;rsquo;ont posé 2 questions (et j&amp;rsquo;ai ajouté une consigne) :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&amp;ldquo;Quel langage ?&amp;rdquo;&lt;/em&gt; → &lt;strong&gt;Go&lt;/strong&gt; (je persiste)&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&amp;ldquo;CLI seule ou TUI ?&amp;rdquo;&lt;/em&gt; → &lt;strong&gt;Les deux&lt;/strong&gt; (mode non-interactif pour le scripting, TUI pour l&amp;rsquo;usage quotidien)&lt;/li&gt;
&lt;li&gt;Et je lui ai demandé de toujours vérifier à chaque fois qu&amp;rsquo;il estime avoir fini de lancer le linter &lt;code&gt;golangci-lint&lt;/code&gt; (trauma de mon précédent test avec opencode)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Il est parti de lui-même sur l&amp;rsquo;idée d&amp;rsquo;une TUI avec &lt;a class="link" href="https://github.com/charmbracelet/bubbletea" target="_blank" rel="noopener"
&gt;Bubble Tea&lt;/a&gt;. Puis j&amp;rsquo;ai arrêté de regarder &amp;amp; j&amp;rsquo;ai suivi ma réunion.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;~30 minutes plus tard, fin de la réunion&lt;/strong&gt;, j&amp;rsquo;ai regardé le résultat. Le POC était fonctionnel.&lt;/p&gt;
&lt;h2 id="ce-quopus-a-produit-en-30-minutes"&gt;Ce qu&amp;rsquo;Opus a produit en 30 minutes
&lt;/h2&gt;&lt;p&gt;Sans aucune intervention de ma part, le LLM a scaffoldé un projet Go complet :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Structure propre&lt;/strong&gt; : &lt;code&gt;cmd/&lt;/code&gt; pour le CLI Cobra, &lt;code&gt;pkg/k8s/&lt;/code&gt; pour toute l&amp;rsquo;interaction Kubernetes, &lt;code&gt;pkg/tui/&lt;/code&gt; pour la TUI Bubble Tea&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Le coeur du sujet&lt;/strong&gt; : un appel direct à l&amp;rsquo;API Kubernetes pour patcher le subresource &lt;code&gt;ephemeralcontainers&lt;/code&gt; du pod avec un strategic merge patch incluant les &lt;code&gt;volumeMounts&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mode non-interactif&lt;/strong&gt; : &lt;code&gt;-n namespace -p pod -v volume:/mount/path&lt;/code&gt;, prêt pour le scripting&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;TUI complète&lt;/strong&gt; : navigation vim-style (&lt;code&gt;j&lt;/code&gt;/&lt;code&gt;k&lt;/code&gt;), filtrage fuzzy (&lt;code&gt;/&lt;/code&gt;), multi-sélection de volumes, spinner de chargement&amp;hellip;&lt;/li&gt;
&lt;li&gt;Makefile avec tout un tas de targets (vet, lint, test, build, install)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ce que je lui ai demandé d&amp;rsquo;ajouter :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Discovery intelligente&lt;/strong&gt; : au lieu de scanner tous les pods de tous les namespaces (lent sur un de mes gros cluster), l&amp;rsquo;outil liste d&amp;rsquo;abord les PVCs cluster-wide (un seul appel API) pour identifier les namespaces pertinents, PUIS les pods dans le namespace sélectionné. On réduit drastiquement le nombre d&amp;rsquo;appels à l&amp;rsquo;API server de kube et la TUI ne montre que les namespaces et pods qui ont des volumes PVC&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Héritage du &lt;code&gt;SecurityContext&lt;/code&gt;&lt;/strong&gt; : le conteneur éphémère copie le &lt;code&gt;securityContext&lt;/code&gt; du conteneur cible, ce qui lui permet de passer les PodSecurity policies (&lt;code&gt;restricted&lt;/code&gt;, &lt;code&gt;baseline&lt;/code&gt;&amp;hellip;). C&amp;rsquo;est un cas que je n&amp;rsquo;avais pas envisagé dans mon prompt initial et qui a planté immédiatement sur un cluster bien configuré.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Sans ces petites améliorations le tool était déjà utilisable (sauf pour le cas où vous avez configuré des SecurityContext), mais c&amp;rsquo;est nettement plus confortable à l&amp;rsquo;usage (parce que oui, je l&amp;rsquo;utilise).&lt;/p&gt;
&lt;p&gt;Le code de la mécanique centrale (le patch de l&amp;rsquo;API) fait quelques centaines de lignes de Go propre. Il récupère le pod, construit le patch JSON avec le conteneur éphémère et ses &lt;code&gt;volumeMounts&lt;/code&gt;, l&amp;rsquo;applique via &lt;code&gt;Patch()&lt;/code&gt; sur le subresource, attend que le conteneur soit Running, puis lance &lt;code&gt;kubectl attach&lt;/code&gt;. Rien de sorcier, c&amp;rsquo;est juste ce qu&amp;rsquo;il faut, bien fait du premier coup.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-golang" data-lang="golang"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ephemeralContainer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;corev1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;EphemeralContainer&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;EphemeralContainerCommon&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;corev1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;EphemeralContainerCommon&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;containerName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Command&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;/bin/sh&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Stdin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;TTY&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;VolumeMounts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;mounts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;SecurityContext&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;targetSecurityContext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;TargetContainerName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;targetContainer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Clientset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CoreV1&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;Pods&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Namespace&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;Patch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PodName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;types&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;StrategicMergePatchType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;patchBytes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;metav1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PatchOptions&lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;ephemeralcontainers&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="les-itérations-suivantes-30-minutes-ish"&gt;Les itérations suivantes (30 minutes-ish)
&lt;/h2&gt;&lt;p&gt;Une fois le POC validé, j&amp;rsquo;ai enchaîné quelques prompts ciblés. Je lui ai demandé ce qu&amp;rsquo;on pouvait améliorer. Il a proposé (et implémenté) :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;quelques corrections mineures de code qu&amp;rsquo;il avait mal codé (mais non bloquant)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Warnings&lt;/strong&gt; : si le SecurityContext hérité a &lt;code&gt;readOnlyRootFilesystem&lt;/code&gt;, &lt;code&gt;runAsNonRoot&lt;/code&gt;, ou autre mesure de sécurité, l&amp;rsquo;outil prévient l&amp;rsquo;utilisateur avant l&amp;rsquo;attach&lt;/li&gt;
&lt;li&gt;Ajouté une CI complète à base de &lt;code&gt;goreleaser&lt;/code&gt; et de github actions&lt;/li&gt;
&lt;li&gt;Ajouté de la documentation&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="la-cerise-sur-le-macdo--publication-sur-krew"&gt;La cerise sur le Macdo : publication sur Krew
&lt;/h2&gt;&lt;p&gt;Une fois que j&amp;rsquo;avais une version propre, j&amp;rsquo;ai demandé à Opus comment faciliter l&amp;rsquo;installation du plugin. Il m&amp;rsquo;a proposé &lt;code&gt;brew&lt;/code&gt;, ou alors &lt;a class="link" href="https://krew.sigs.k8s.io/" target="_blank" rel="noopener"
&gt;Krew&lt;/a&gt;, le gestionnaire de plugins kubectl.&lt;/p&gt;
&lt;p&gt;Je lui ai demandé si le processus d&amp;rsquo;acceptation du plugin était complexe. Il a dit que non, je lui ai dit &amp;ldquo;chiche !&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Il a &lt;strong&gt;réalisé l&amp;rsquo;intégralité du processus&lt;/strong&gt; :&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Création d&amp;rsquo;un fork de &lt;a class="link" href="https://github.com/kubernetes-sigs/krew-index" target="_blank" rel="noopener"
&gt;krew-index&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Rédaction du manifeste Krew (le fichier &lt;code&gt;.yaml&lt;/code&gt; qui décrit le plugin)&lt;/li&gt;
&lt;li&gt;Prise en compte de toutes les bonnes pratiques demandées par les maintainers de krew-index (format des URLs de téléchargement, descriptions courtes, checksums SHA256, etc.)&lt;/li&gt;
&lt;li&gt;Préparation de la PR, directement sur krew-index&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;J&amp;rsquo;ai juste regardé. La PR a été mergée 12 heures plus tard par les mainteneurs.&lt;/p&gt;
&lt;p&gt;Résultat : &lt;code&gt;kubectl krew install debug-pvc&lt;/code&gt; fonctionne.&lt;/p&gt;
&lt;h2 id="mini-échec---déléguer-aussi-la-démo"&gt;Mini échec - déléguer aussi la démo
&lt;/h2&gt;&lt;p&gt;Fort de ce succès avec la PR pour krew-index, je me suis demandé si on ne pourrait pas faire une démo visuelle (un GIF à ajouter dans le README.md du projet qui montre comment ça fonctionne) avec le LLM.&lt;/p&gt;
&lt;p&gt;Je lui ai demandé s&amp;rsquo;il pouvait le faire avec &lt;code&gt;asciinema&lt;/code&gt; et le LLM m&amp;rsquo;a répondu que &amp;ldquo;oui&amp;rdquo; (oui, je discute avec le LLM comme avec mes collègues). Banco, on a essayé.&lt;/p&gt;
&lt;p&gt;Le résultat était &lt;em&gt;presque&lt;/em&gt; bon, j&amp;rsquo;aurais pu m&amp;rsquo;en contenter si j&amp;rsquo;étais pas quelqu&amp;rsquo;un de pénible : c&amp;rsquo;était un poil lent. J&amp;rsquo;ai l&amp;rsquo;impression la réactivité du LLM dans ses actions était inégale, ce qui rendait le rendu un peu désagréable au visionnage. J&amp;rsquo;aurais pu insister jusqu&amp;rsquo;à avoir quelque chose de correct, mais j&amp;rsquo;ai finalement enregistré moi-même une vidéo, convertie en GIF avec &lt;code&gt;ffmpeg&lt;/code&gt;. C&amp;rsquo;était plus fluide et plus rapide que d&amp;rsquo;itérer.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2026/03/kubectl-debug-pvc-demo.gif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;h2 id="le-diff-avec-podsweeper"&gt;Le diff avec PodSweeper
&lt;/h2&gt;&lt;p&gt;La différence de ressenti entre ce projet et PodSweeper est frappante. Là où PodSweeper était un combat constant (race conditions, amnésie du LLM, fonctionnalités hors-spécifications), &lt;code&gt;kubectl-debug-pvc&lt;/code&gt; s&amp;rsquo;est déroulé sans accroc notable.&lt;/p&gt;
&lt;p&gt;Pourquoi ? Je pense que ça tient à la nature du projet :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Une seule chose à faire&lt;/strong&gt;, clairement définie : patcher un subresource Kubernetes avec des volumeMounts&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pas de logique concurrente&lt;/strong&gt; : on fait une requête API, on attend, on s&amp;rsquo;attache&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Un domaine bien documenté&lt;/strong&gt; : l&amp;rsquo;API Kubernetes, Cobra, Bubble Tea. Le LLM connaît tout ça par coeur&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pas d&amp;rsquo;état partagé complexe&lt;/strong&gt; : pas de goroutines qui se marchent dessus, pas de graceful shutdown à gérer, de microservices multiples&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Scope limité&lt;/strong&gt; : le projet entier tient dans une quinzaine de fichiers, CI et documentation incluses&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;C&amp;rsquo;est probablement le terrain de jeu idéal pour un LLM. Un problème bien cadré, un domaine technique bien balisé, une solution linéaire.&lt;/p&gt;
&lt;h2 id="quest-ce-que-jen-pense-"&gt;Qu&amp;rsquo;est-ce que j&amp;rsquo;en pense ?
&lt;/h2&gt;&lt;p&gt;Objectivement, ce genre de projet &amp;ldquo;simple&amp;rdquo; (une chose à faire, simple à comprendre) marche &lt;strong&gt;vraiment super bien&lt;/strong&gt; avec OpenCode + Opus. Je pense que c&amp;rsquo;est ce genre à cause (grâce) de ce genre de petits projets que la hype est tellement forte autour du développement agentique. On a une idée en tête qu&amp;rsquo;on avait la flemme de dev, on teste, ça marche. &amp;ldquo;WOW&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Mais je ne veux pas non plus minimiser le travail réalisé. Le fait qu&amp;rsquo;un outil fonctionnel, propre, publié sur Krew et utilisable par n&amp;rsquo;importe qui ait pu émerger d&amp;rsquo;un prompt lancé en début de réunion, c&amp;rsquo;est quand même assez dingue.&lt;/p&gt;
&lt;p&gt;Un peu flippant aussi, de se dire qu&amp;rsquo;un nombre hallucinant de micro tools vont apparaître dans les prochains mois, avec un niveau de qualité probablement inégal.&lt;/p&gt;
&lt;h2 id="le-projet"&gt;Le projet
&lt;/h2&gt;&lt;p&gt;Le code est disponible ici :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/zwindler/kubectl-debug-pvc" target="_blank" rel="noopener"
&gt;https://github.com/zwindler/kubectl-debug-pvc&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Installation :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Via Krew (recommandé)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl krew install debug-pvc
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Utilisation interactive (TUI)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl debug-pvc
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Utilisation non-interactive&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl debug-pvc -n my-namespace -p my-pod-0 -v data:/debug/data
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Si vous aussi vous avez déjà galéré à inspecter un PVC sur un pod sans shell, essayez. Et si vous trouvez des bugs, vous pourrez blâmer le LLM 😄.&lt;/p&gt;</description></item><item><title>GenAI et développement logiciel : retour d'expérience avec PodSweeper</title><link>https://blog.zwindler.fr/2026/03/08/genai-llm-dev-podsweeper/</link><pubDate>Sun, 08 Mar 2026 18:00:00 +0200</pubDate><guid>https://blog.zwindler.fr/2026/03/08/genai-llm-dev-podsweeper/</guid><description>&lt;img src="https://blog.zwindler.fr/2026/02/opencode.webp" alt="Featured image of post GenAI et développement logiciel : retour d'expérience avec PodSweeper" /&gt;&lt;h2 id="la-genai-cest-fantastique-"&gt;La GenAI, c&amp;rsquo;est fantastique ?
&lt;/h2&gt;&lt;p&gt;Pas mal de gens ont sorti leur avis sur la Gen AI pour dev en très peu de temps, alors je me rends compte qu&amp;rsquo;il est plus que temps que je poste ce brouillon commencé il y a plus de deux semaines 🙃.&lt;/p&gt;
&lt;p&gt;Pour le travail, j&amp;rsquo;utilise de plus en plus d&amp;rsquo;assistants IA pour m&amp;rsquo;épauler dans mes tâches du quotidien. En 2024, c&amp;rsquo;était surtout pour automatiser des tâches pénibles (scripter des trucs, faire une liste pénible de tâches répétitives sans coder ça proprement). Courant 2025, j&amp;rsquo;ai testé plusieurs fois de lui faire faire de l&amp;rsquo;Ops et, à chaque fois, les résultats étaient moyens, tant pour concevoir une infra cohérente, fiable et efficiente que pour de l&amp;rsquo;assistance à la résolution d&amp;rsquo;incident (cf. &lt;a class="link" href="https://blog.zwindler.fr/2025/08/15/ops-disparition-suite/#et-dans-linfra-" &gt;mon article sur le sujet&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;En 2026, sur ce dernier point, je trouve qu&amp;rsquo;on n&amp;rsquo;a toujours pas avancé, même si je reconnais qu&amp;rsquo;il existe des outils spécialisés que je n&amp;rsquo;ai pas encore suffisamment testés, open source ou non. Je peux citer &lt;a class="link" href="https://k8sgpt.ai/" target="_blank" rel="noopener"
&gt;k8sgpt&lt;/a&gt; et &lt;a class="link" href="https://github.com/HolmesGPT/holmesgpt" target="_blank" rel="noopener"
&gt;HolmesGPT&lt;/a&gt; en open source, et &lt;a class="link" href="https://www.anyshift.io/" target="_blank" rel="noopener"
&gt;Anyshift&lt;/a&gt; avec son agent SRE pour la détection de root cause et la résolution d&amp;rsquo;incident.&lt;/p&gt;
&lt;p&gt;Note : fun fact, dans son post &amp;ldquo;&lt;a class="link" href="https://alex.balmes.co/fr/blog/mon-positionnement-sur-l-intelligence-artificielle-generative#pour-les-ops" target="_blank" rel="noopener"
&gt;Mon positionnement sur l&amp;rsquo;Intelligence Artificielle Générative&lt;/a&gt;&amp;rdquo; posté juste avant moi, Alex cite une longue liste de métiers qui vont profiter de l&amp;rsquo;IA Gen, et les ops ont le droit à rien d&amp;rsquo;autre qu&amp;rsquo;un argument de plus pour passer sur Kube 😭.&lt;/p&gt;
&lt;p&gt;J&amp;rsquo;ai en revanche commencé à utiliser la GenAI pour réaliser plusieurs projets de sites web à 100% (&lt;em&gt;vibe coding&lt;/em&gt; ?), dont je vous ai d&amp;rsquo;ailleurs déjà parlé :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://blog.zwindler.fr/2025/12/02/jai-donn%C3%A9-1-heure-%C3%A0-des-agents-copilot-pour-migrer-un-site-de-bloggrify-%C3%A0-hugo/" &gt;Convertir un blog de Bloggrify à Hugo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://blog.zwindler.fr/2026/02/09/101-facons-de-deployer-kubernetes-nouvelle-ui/" &gt;Créer un site &amp;ldquo;joli&amp;rdquo;&lt;/a&gt; (largement au-delà de mes compétences) pour héberger les recherches que j&amp;rsquo;ai faites sur les différentes façons de déployer Kubernetes&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://blog.zwindler.fr/2026/02/20/securite-headers-http-observatory-hugo/" &gt;Améliorer la sécurité de mon site web&lt;/a&gt; en automatisant la modification du thème Hugo que j&amp;rsquo;utilise, de manière à avoir la meilleure note sur Mozilla HTTP Observatory&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Dans les 3 cas, le résultat est là. Ou plutôt, il &lt;em&gt;semble&lt;/em&gt; l&amp;rsquo;être pour le béotien que je suis.&lt;/p&gt;
&lt;p&gt;Je n&amp;rsquo;ai jamais caché que je n&amp;rsquo;ai aucune compétence en front, et peut-être que pour un expert du domaine, ce que j&amp;rsquo;ai fait avec l&amp;rsquo;IA est horrible (ou non ?). Dans tous les cas, ça ne peut pas être pire que les UIs que j&amp;rsquo;ai faites sans. Petit exemple 😄 :&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2026/02/groroti.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;h2 id="ou-alors--la-gêneai-"&gt;ou alors : la GêneAI ?
&lt;/h2&gt;&lt;p&gt;C&amp;rsquo;est le genre de retours qu&amp;rsquo;on voit fleurir de la part de toutes les personnes qui sont &lt;em&gt;vraiment&lt;/em&gt; expertes d&amp;rsquo;un domaine quand elles voient des novices s&amp;rsquo;extasier. On a de bons exemples avec les vidéos générées par IA : si on ne fait pas attention, on a l&amp;rsquo;impression que c&amp;rsquo;est incroyable. Mais n&amp;rsquo;importe qui avec un œil un peu critique voit tout de suite de &lt;strong&gt;GROS&lt;/strong&gt; problèmes de cohérence. Pareil pour la génération d&amp;rsquo;image, ou de musique.&lt;/p&gt;
&lt;p&gt;C&amp;rsquo;est aussi vrai pour le code, et on a de très bons exemples de projets &lt;em&gt;vibe codés&lt;/em&gt; qui sont d&amp;rsquo;immondes plats de spaghetti, et des passoires en termes de cybersécurité. Bref, vous l&amp;rsquo;aurez compris, j&amp;rsquo;ai beau être utilisateur (quotidien), je ne suis pas &amp;ldquo;incroyablé&amp;rdquo; (comme disent mes enfants) par les LLMs, même les meilleurs.&lt;/p&gt;
&lt;p&gt;Pourtant, j&amp;rsquo;ai plusieurs copains qui ne jurent que par ça, notamment des gens bien plus brillants / intelligents (appelez ça comme vous voulez) que moi. Donc je me dis &lt;em&gt;&amp;ldquo;OK, peut-être que je m&amp;rsquo;y prends mal. Essayons avec ce qui se fait de mieux&lt;/em&gt;&amp;rdquo; : un IDE type &amp;ldquo;Claude Code&amp;rdquo; et un modèle Opus.&lt;/p&gt;
&lt;h2 id="léditeur"&gt;L&amp;rsquo;éditeur
&lt;/h2&gt;&lt;p&gt;Après avoir fait une petite étude de marché rapide, on se rend compte que les options sont pléthoriques : Claude Code, OpenCode, Amp Code, &amp;hellip;&lt;/p&gt;
&lt;p&gt;Le problème de Claude Code, c&amp;rsquo;est le ticket d&amp;rsquo;entrée. Je ne suis pas encore prêt à lâcher 100 ou 200 € par mois pour l&amp;rsquo;usage que j&amp;rsquo;en ai aujourd&amp;rsquo;hui. Je ne sais pas si l&amp;rsquo;offre à 20€ me suffirait ou non. Au-delà de rares side projects perso que j&amp;rsquo;ai cités plus haut, je code peu. Le gros de mes geekeries, c&amp;rsquo;est de l&amp;rsquo;infra : installer des Kube et des OS de virtualisation. Des trucs difficiles à automatiser avec un LLM.&lt;/p&gt;
&lt;p&gt;On (Pierre surtout) m&amp;rsquo;a conseillé &lt;a class="link" href="https://ampcode.com/" target="_blank" rel="noopener"
&gt;Amp Code&lt;/a&gt; pour du perso, notamment parce que de base, il y a un tier gratuit avec un certain nombre de tokens et que si on n&amp;rsquo;est pas trop gourmand, c&amp;rsquo;est assez efficace. J&amp;rsquo;ai préféré n&amp;rsquo;en faire qu&amp;rsquo;à ma tête et tester plutôt sur &lt;strong&gt;OpenCode&lt;/strong&gt;, qui a l&amp;rsquo;avantage d&amp;rsquo;être plus flexible sur les providers de LLM et la consommation de tokens. Il est d&amp;rsquo;ailleurs possible de profiter de modèles locaux (gratuits, donc) ou &lt;a class="link" href="https://opencode.ai/docs/fr/zen/" target="_blank" rel="noopener"
&gt;des modèles inclus gratuitement (en tout cas pour l&amp;rsquo;instant) tels que GLM 5 Free&lt;/a&gt;, qui est plutôt bien placé dans les modèles de dev (surtout, c&amp;rsquo;est gratuit&amp;hellip;).&lt;/p&gt;
&lt;p&gt;OK, on a l&amp;rsquo;éditeur. Maintenant, le code ?&lt;/p&gt;
&lt;p&gt;Pour me faire une idée de la pertinence du code généré par mon LLM favori (Sonnet et Opus, depuis un moment), il me faut donc un langage &lt;strong&gt;et&lt;/strong&gt; un cas d&amp;rsquo;usage que je maîtrise, pour être capable de lui dire &lt;em&gt;&amp;ldquo;non mais là, c&amp;rsquo;est n&amp;rsquo;importe quoi !?&amp;rdquo;&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Cas d&amp;rsquo;usage que je maîtrise&amp;hellip; vous vous en doutez, il y aura forcément du &lt;strong&gt;Kubernetes&lt;/strong&gt; dedans.&lt;/p&gt;
&lt;p&gt;Langage que je maîtrise : j&amp;rsquo;ai appris Go en 2022 grâce à un collègue de chez Deezer (encore merci Martial !) et j&amp;rsquo;ai publié quelques outils et fait des contributions mineures. J&amp;rsquo;ai écrit une grande partie de l&amp;rsquo;outil &lt;a class="link" href="https://github.com/deezer/GroROTI" target="_blank" rel="noopener"
&gt;GroROTI&lt;/a&gt; et aussi commencé (mais jamais terminé) le développement d&amp;rsquo;un RPG en Go, fortement inspiré de Castle of the Winds, un jeu de mon enfance : &lt;a class="link" href="https://github.com/zwindler/gocastle" target="_blank" rel="noopener"
&gt;gocastle&lt;/a&gt;. Et j&amp;rsquo;ai une capacité professionnelle (même si ce n&amp;rsquo;est pas le coeur de mon métier) dans mon travail de tous les jours.&lt;/p&gt;
&lt;h2 id="après-le-contexte-le-projet"&gt;Après le contexte, le projet
&lt;/h2&gt;&lt;p&gt;OK, on a le contexte technique : Kube + Go. Reste donc l&amp;rsquo;idée à implémenter. Il faut un projet suffisamment volumineux pour que le test soit pertinent, suffisamment rigolo pour que j&amp;rsquo;aie envie d&amp;rsquo;y passer du temps perso, mais quand même un peu utile pour que j&amp;rsquo;aie envie d&amp;rsquo;en parler et de montrer l&amp;rsquo;avancement. Et surtout, un projet dont la logique métier reste à ma portée : pour évaluer honnêtement la qualité du code produit par l&amp;rsquo;IA, il faut que je sois capable de le relire et de le critiquer.&lt;/p&gt;
&lt;p&gt;Et là, dans mes tiroirs à idées débiles qui débordent de mon cerveau, je me suis souvenu de ce &amp;ldquo;pitch&amp;rdquo; de 2023-2024, que j&amp;rsquo;avais laissé moisir faute de temps :&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;PodSweeper&lt;/strong&gt; : la manière la plus complexe, over-engineerée et chaotique de jouer au démineur.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2026/02/Wat8.webp"
loading="lazy"
&gt;&lt;/p&gt;
&lt;h2 id="partez-pas-vous-allez-voir-cest-rigolo-si-"&gt;Partez pas, vous allez voir c&amp;rsquo;est rigolo. Si !
&lt;/h2&gt;&lt;p&gt;Au lieu d&amp;rsquo;une grille visuelle où on clique sur des cases en espérant ne pas tomber sur une &amp;ldquo;mine&amp;rdquo;, on a une &amp;ldquo;grille&amp;rdquo; virtuelle où chaque case est un Pod et le clic est un &lt;code&gt;kubectl delete&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Oui, c&amp;rsquo;est débile. Ça me plaît donc beaucoup :).&lt;/p&gt;
&lt;p&gt;Au-delà du troll assumé (over-engineering des enfers) de ce jeu, il y a quand même un objectif pédagogique derrière.&lt;/p&gt;
&lt;p&gt;Si, si, vraiment.&lt;/p&gt;
&lt;p&gt;J&amp;rsquo;ai pensé le jeu comme une &lt;strong&gt;introduction à la sécurité dans Kubernetes&lt;/strong&gt;, avec des niveaux de difficulté à débloquer, façon CTF de cybersécurité.&lt;/p&gt;
&lt;p&gt;Au début, vous pouvez &lt;strong&gt;tout&lt;/strong&gt; faire. Vous pouvez bien sûr jouer normalement (delete un Pod, voir s&amp;rsquo;il y a des mines à côté) pour vous faire la main. Vous pouvez aussi automatiser les actions (un script qui &amp;ldquo;clique sur une case&amp;rdquo; au hasard, récupère les hints de proximité de mines, clique à un endroit safe, &amp;hellip;).&lt;/p&gt;
&lt;p&gt;Mais vous pouvez aussi &lt;strong&gt;tricher&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Et c&amp;rsquo;est tout l&amp;rsquo;intérêt du jeu. Dans les premiers niveaux de difficulté, les manifests Kubernetes du jeu sont volontairement vulnérables. On peut donc gagner sans effort, si on sait où chercher.&lt;/p&gt;
&lt;p&gt;Cependant, très vite, les niveaux s&amp;rsquo;enchaînent et les restrictions avec. Assez rapidement, on arrive dans des bonnes pratiques de production qui empêchent toute &amp;ldquo;triche&amp;rdquo;. Et si vous trouvez des vulnérabilités non prévues dans le code du jeu lui-même&amp;hellip; eh bien, c&amp;rsquo;est du bonus 😈.&lt;/p&gt;
&lt;h2 id="le-processus-initial"&gt;Le processus initial
&lt;/h2&gt;&lt;p&gt;C&amp;rsquo;est probablement une erreur, mais j&amp;rsquo;ai fait toute la phase d&amp;rsquo;&lt;strong&gt;idéation avec Gemini&lt;/strong&gt; avant de lancer OpenCode. L&amp;rsquo;expérience aurait probablement été meilleure (a minima plus représentative) si j&amp;rsquo;avais commencé directement avec OpenCode.&lt;/p&gt;
&lt;p&gt;J&amp;rsquo;ai pondu tout ce que j&amp;rsquo;avais dans la tête, ainsi qu&amp;rsquo;un gros pavé informe de dizaines de lignes provenant de mes notes de quand j&amp;rsquo;ai eu l&amp;rsquo;idée en 2023, et je lui ai demandé de me sortir un fichier &lt;a class="link" href="https://github.com/zwindler/PodSweeper/blob/main/SPECIFICATION.md" target="_blank" rel="noopener"
&gt;SPECIFICATIONS.md&lt;/a&gt; avec toutes les infos importantes, remises dans l&amp;rsquo;ordre.&lt;/p&gt;
&lt;p&gt;Une fois les specs écrites, je lui ai demandé de détailler les différents niveaux et les difficultés que nous allions progressivement ajouter, dans &lt;a class="link" href="https://github.com/zwindler/PodSweeper/blob/main/GAMEPLAY.md" target="_blank" rel="noopener"
&gt;GAMEPLAY.md&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Enfin, j&amp;rsquo;ai demandé de faire un découpage du projet par &amp;ldquo;issues&amp;rdquo; et par priorité, de manière à avoir un MVP rapidement : &lt;a class="link" href="https://github.com/zwindler/PodSweeper/blob/main/ISSUES_PRIORITY.md" target="_blank" rel="noopener"
&gt;ISSUES_PRIORITY.md&lt;/a&gt;. Mon idée était de donner le plan de bataille très détaillé et découpé finement à OpenCode et de lui laisser dérouler.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Première déconvenue&lt;/strong&gt; : Gemini 3 Pro est assez mauvais pour ça. Les tâches étaient crédibles(-ish) mais ordonnées n&amp;rsquo;importe comment (dépendances entre tâches non respectées). J&amp;rsquo;ai donc lancé pour la première fois OpenCode dans mon repo et je lui ai dit &lt;em&gt;&amp;ldquo;voilà le contexte, voilà ce qu&amp;rsquo;on a imaginé comme tâches. Qu&amp;rsquo;est-ce que tu en penses ?&amp;rdquo;&lt;/em&gt;.&lt;/p&gt;
&lt;h2 id="le-bon-opencode"&gt;Le bon (open)code&amp;hellip;
&lt;/h2&gt;&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2026/02/opencode.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Dans les trucs assez chouettes : OpenCode + Claude Opus a tout de suite vu que le plan imaginé par Gemini était bancal, et m&amp;rsquo;a posé des questions et proposé un découpage encore imparfait mais déjà plus cohérent. C&amp;rsquo;est probablement là le gros de l&amp;rsquo;intérêt de ces logiciels. Ils embarquent des connaissances pour guider le développement logiciel et surtout (SURTOUT) apportent du cadre.&lt;/p&gt;
&lt;p&gt;Assez vite, on finit par se mettre d&amp;rsquo;accord sur un plan qui me plaît. OpenCode met à jour les documents et se met à développer (scaffolding, création des pipelines, premiers binaires et images Docker vides). On a un projet prêt à développer en un claquement de doigt, c&amp;rsquo;est assez enthousiasmant, de prime abord.&lt;/p&gt;
&lt;p&gt;Les assistants LLMs ont très envie de se jeter dans le code, ça reste vrai avec OpenCode+Opus. Alors même qu&amp;rsquo;on n&amp;rsquo;avait pas fini de discuter du plan et des options possibles, il me proposait de lui-même de passer au code. Cela dit, c&amp;rsquo;était pareil (voire pire) pour Gemini (à qui j&amp;rsquo;avais dit spécifiquement qu&amp;rsquo;on n&amp;rsquo;allait pas faire de code du tout).&lt;/p&gt;
&lt;p&gt;Très vite, les créations de fichiers s&amp;rsquo;enchaînent. J&amp;rsquo;ai du mal à suivre et à chaque pause (quand le LLM a fini une tâche et qu&amp;rsquo;il me demande s&amp;rsquo;il peut passer à la suivante), je prends de longues minutes à lire ce que le LLM a produit. C&amp;rsquo;est à la fois grisant et épuisant (relire tout ça, c&amp;rsquo;est dur pour mon cerveau rouillé).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;La vitesse brute est impressionnante.&lt;/strong&gt; En 3 sessions de 1 à 2h, j&amp;rsquo;ai un MVP fonctionnel. Je comprends qu&amp;rsquo;on parle régulièrement de 10x engineering quand on parle de génération de code avec les LLMs récents. Si on ne parle pas de génération de code brute (ce qui n&amp;rsquo;a pas vraiment de sens), à la louche, le code fonctionnel est généré entre 3x et 10x plus rapidement que ce que j&amp;rsquo;aurais pu faire seul. Des features qui mises bout à bout m&amp;rsquo;auraient pris des heures à implémenter (génération de la grille, logique de reveal, gestion des états de jeu) tombent en quelques minutes. Vous l&amp;rsquo;avez déjà lu ailleurs, je dis pareil - le goulot d&amp;rsquo;étranglement, ce n&amp;rsquo;est plus le code que je tape : c&amp;rsquo;est le code que je dois relire.&lt;/p&gt;
&lt;p&gt;De ce que j&amp;rsquo;ai lu, le code est correct, en particulier lors des premières itérations, un peu moins au bout d&amp;rsquo;un moment. Mais quand je dis &amp;ldquo;correct&amp;rdquo;, je sous-vends peut-être le truc : le code produit est du &lt;strong&gt;Go idiomatique&lt;/strong&gt;. Bonne structure en packages, conventions de nommage respectées, gestion d&amp;rsquo;erreur dans le style Go (quand elle est là&amp;hellip;), utilisation appropriée des interfaces. Ce n&amp;rsquo;est pas juste du code qui compile : c&amp;rsquo;est du code qu&amp;rsquo;un reviewer Go ne rejetterait pas d&amp;rsquo;emblée. On a pour objectif un MVP donc ça reste de la logique &amp;ldquo;métier&amp;rdquo; très simple, mais le socle est propre.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tout est testé&lt;/strong&gt;, très vite le projet contient une couverture parfaite et 100+ tests alors qu&amp;rsquo;on ne fait encore rien. Si c&amp;rsquo;était du code généré par un humain, je ne saurais pas dire si c&amp;rsquo;est une bonne chose. On est pas du tout dans du TDD, beaucoup de code teste des choses inutiles. Dans le cas du code généré par le LLM, c&amp;rsquo;est probablement pour le mieux, car le LLM a tendance à ajouter très régulièrement des régressions (on en reparlera). C&amp;rsquo;est donc intéressant ici, car :&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;ça ne coûte quasiment rien en temps de dev (ça va tellement vite à générer)&lt;/li&gt;
&lt;li&gt;cela permet au LLM de se rendre compte que son code introduit une régression, et de fixer de lui-même, sans attendre.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="-et-le-mauvais-opencode"&gt;&amp;hellip; et le mauvais (open)code
&lt;/h2&gt;&lt;p&gt;Côté outil et modèle d&amp;rsquo;abord, quelques &lt;strong&gt;irritants&lt;/strong&gt; :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Par défaut, OpenCode n&amp;rsquo;incite pas le LLM à lancer &lt;code&gt;golangci-lint&lt;/code&gt; à chaque commit. On corrige ça avec un pre-commit hook et/ou les fameux AGENTS.md / skills, mais ça aurait DÛ faire partie du kit de base d&amp;rsquo;un projet golang (il y a bien les tests&amp;hellip;).&lt;/li&gt;
&lt;li&gt;Le LLM (Claude Opus sur OpenCode, mais c&amp;rsquo;est un biais habituel même en dehors) &lt;strong&gt;adore&lt;/strong&gt; les versions de logiciels qui existaient au moment de son entraînement. Il faut continuellement lui répéter que les versions qu&amp;rsquo;il suggère sont obsolètes. C&amp;rsquo;est vrai pour tout : le code Go, les dépendances, les versions des actions GitHub.&lt;/li&gt;
&lt;li&gt;On tombe très souvent dans la limite des 100k tokens. On perd du temps à &amp;ldquo;compacter&amp;rdquo; et on perd de la précision. Typiquement : le LLM me demande s&amp;rsquo;il peut &lt;code&gt;git commit&lt;/code&gt; des modifs, le contexte se compacte avant que je réponde, et il commit sans mon autorisation en redéroulant le contexte. Sur du code aussi peu sensible, ça va. Mais sur de la prod, ça serait un vrai problème.&lt;/li&gt;
&lt;li&gt;Le LLM est souvent amnésique : il oublie qu&amp;rsquo;il a accès à un cluster kind pour faire des tests réels (alors qu&amp;rsquo;il l&amp;rsquo;a fait juste avant la précédente compaction, par exemple).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Côté &lt;strong&gt;qualité du code&lt;/strong&gt; produit, c&amp;rsquo;est plus préoccupant :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Gestion d&amp;rsquo;erreur laxiste.&lt;/strong&gt; Certaines erreurs qui auraient dû retourner un FATAL (controller qui n&amp;rsquo;arrive pas à s&amp;rsquo;initialiser correctement !) sont simplement logguées comme ERROR. On se retrouve à ship des versions qui échouent silencieusement. Là encore, ça doit pouvoir se fine tuner avec un AGENTS.md.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Race conditions.&lt;/strong&gt; Je suis tombé très vite sur des race conditions assez bêtes. Dans mon cas, des pods bloqués en terminating impactaient le jeu suivant (graceful shutdown mal géré). Opus est parti en boucle sans comprendre la source du problème. J&amp;rsquo;ai dû le stopper et lui spécifier qu&amp;rsquo;il ne fallait jamais lancer une nouvelle partie sans s&amp;rsquo;être assuré que la précédente était terminée.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Génération de code en dehors des clous.&lt;/strong&gt; Parfois, sans crier gare, le LLM ajoute une fonctionnalité qui n&amp;rsquo;est pas demandée, inutile, voire qui va à l&amp;rsquo;encontre de la SPECIFICATION écrite précédemment. On est obligé de lui remettre un taquet derrière la tête.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Une fois remis sur les rails, le LLM déroule à nouveau, mais ces épisodes montrent bien que sur du code concurrent ou en dehors de user stories hyper strictes (ce qui sort du workflow de base d&amp;rsquo;opencode), la supervision humaine reste indispensable.&lt;/p&gt;
&lt;p&gt;On me répondra que je débute avec ces outils, et que j&amp;rsquo;aurais pu éviter certains écueils en configurant mieux mon environnement (AGENTS.md, pre-commit hooks, etc.). C&amp;rsquo;est vrai.&lt;/p&gt;
&lt;p&gt;Mais c&amp;rsquo;est justement là que le bât blesse : une des promesses vantées de la GenAI appliquée au dev, c&amp;rsquo;est de permettre à des non-développeurs (ou des débutants) de produire du logiciel de qualité à grande vitesse, de manière à pouvoir ship des logiciels complets. Si pour en tirer le meilleur, il faut déjà être un développeur expérimenté qui sait configurer un environnement complexe (avec les spécificités de ces outils IA), anticiper les race conditions et relire du code concurrent&amp;hellip; on n&amp;rsquo;a pas démocratisé le développement, on a juste donné un outil de plus aux gens qui savaient déjà coder. Mon profil (ops qui code, pas dev pur jus) était précisément le public cible de cette promesse. Et aujourd&amp;rsquo;hui, &amp;ldquo;les calculs sont pas bons, Kévin&amp;rdquo;.&lt;/p&gt;
&lt;h2 id="où-jen-suis-"&gt;Où j&amp;rsquo;en suis ?
&lt;/h2&gt;&lt;p&gt;Depuis tout à l&amp;rsquo;heure, je vous parle de PodSweeper. Mais il en est où, ce projet ?&lt;/p&gt;
&lt;p&gt;Après 3 sessions de 1 à 2h max, sans compter l&amp;rsquo;idéation, j&amp;rsquo;ai un MVP fonctionnel. Comme je l&amp;rsquo;ai dit plus haut, le gain de productivité est indéniable, pour quelqu&amp;rsquo;un qui n&amp;rsquo;est pas &amp;ldquo;dev&amp;rdquo; de métier.&lt;/p&gt;
&lt;p&gt;Le code est probablement &amp;ldquo;globalement&amp;rdquo; de meilleure qualité que le code golang que j&amp;rsquo;aurais pu écrire, &lt;strong&gt;mais&lt;/strong&gt; le LLM laisse passer des trous béants dans la logique métier (tout simplement parce qu&amp;rsquo;il ne réfléchit pas, alors que moi, oui. Enfin, normalement). Dur pour la confiance&amp;hellip; Il faut vraiment rester très méfiant de tout ce qui est produit.&lt;/p&gt;
&lt;p&gt;Le code est disponible à l&amp;rsquo;adresse suivante :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/zwindler/PodSweeper/tree/main" target="_blank" rel="noopener"
&gt;https://github.com/zwindler/PodSweeper/tree/main&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2026/03/podsweeper.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Vous pouvez aller voir le code pour vous faire une idée. Si vous n&amp;rsquo;avez pas peur de vous spoiler, vous pouvez lire la &lt;a class="link" href="https://github.com/zwindler/PodSweeper/blob/main/SPECIFICATION.md" target="_blank" rel="noopener"
&gt;SPECIFICATION.md&lt;/a&gt; (spoilers), voire &lt;a class="link" href="https://github.com/zwindler/PodSweeper/blob/main/GAMEPLAY.md" target="_blank" rel="noopener"
&gt;GAMEPLAY.md&lt;/a&gt; (j&amp;rsquo;y détaille tous les niveaux donc c&amp;rsquo;est giga spoilers).&lt;/p&gt;
&lt;p&gt;Vous pouvez (normalement) jouer aux premiers niveaux de difficulté. Ça reste assez basique, si vous avez déjà manipulé &lt;code&gt;kubectl&lt;/code&gt; vous devriez trouver la solution très rapidement. Mon but est de rajouter des niveaux au fur et à mesure, j&amp;rsquo;en ai déjà imaginé 10, certains bien retors 😈 et d&amp;rsquo;autres viendront peut-être ensuite.&lt;/p&gt;
&lt;p&gt;Le code est en MPL v2.0 parce que c&amp;rsquo;est une licence copyleft que j&amp;rsquo;aime bien, &lt;a class="link" href="https://www.tldrlegal.com/license/mozilla-public-license-2-0-mpl-2" target="_blank" rel="noopener"
&gt;car elle est à la fois assez peu restrictive, OSI compliant et oblige quand même à reverser les modifs si on en fait dans son coin&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Voilà :) si vous aussi vous trouvez ça rigolo, n&amp;rsquo;hésitez pas à tester et/ou à me faire des retours.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ kubectl apply -k https://github.com/zwindler/podsweeper//deploy/base?ref&lt;span class="o"&gt;=&lt;/span&gt;v0.1.4
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;namespace/podsweeper-game created
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ kubectl &lt;span class="nb"&gt;wait&lt;/span&gt; --for&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;condition&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ready pod -l app.kubernetes.io/name&lt;span class="o"&gt;=&lt;/span&gt;podsweeper &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -n podsweeper-game --timeout&lt;span class="o"&gt;=&lt;/span&gt;60s
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pod/gamemaster-54f4dddcc4-6m88z condition met
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Have fun !&lt;/p&gt;</description></item><item><title>Réflexions sur le blogging technique à l’ère des LLMs</title><link>https://blog.zwindler.fr/2025/06/17/reflexions-blogging-technique-ere-llms/</link><pubDate>Tue, 17 Jun 2025 18:00:00 +0200</pubDate><guid>https://blog.zwindler.fr/2025/06/17/reflexions-blogging-technique-ere-llms/</guid><description>&lt;img src="https://blog.zwindler.fr/2025/06/bsky-a-quoi-ca-sert-blog-tech.webp" alt="Featured image of post Réflexions sur le blogging technique à l’ère des LLMs" /&gt;&lt;h2 id="introduction--quand-lia-rencontre-le-blogging-technique"&gt;Introduction : quand l&amp;rsquo;IA rencontre le blogging technique
&lt;/h2&gt;&lt;p&gt;Ce n&amp;rsquo;est un secret pour personne, &lt;em&gt;je ne suis pas hyper fan&lt;/em&gt; des blogueurs techs qui utilisent des LLMs pour rédiger des articles techniques à la pelle, sans saveur, parfois faux (parce que mal relus par l&amp;rsquo;humain derrière la machine). C&amp;rsquo;est la raison pour laquelle j&amp;rsquo;ai rédigé un &lt;a class="link" href="https://blog.zwindler.fr/ai-manifesto/" target="_blank" rel="noopener"
&gt;AI manifesto&lt;/a&gt; et qu&amp;rsquo;on pourrait résumer avec la phrase suivante :&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Je pars du principe que si je ne prends pas la peine d’écrire moi-même le contenu de ce blog, vous ne devriez pas prendre la peine de le lire.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Cependant, j&amp;rsquo;ai exceptionnellement brisé cette règle aujourd&amp;rsquo;hui pour la rédaction d&amp;rsquo;un article &amp;ldquo;technique&amp;rdquo;, comme support d&amp;rsquo;une réflexion plus large que j&amp;rsquo;ai depuis quelques semaines maintenant. Question que j&amp;rsquo;ai d&amp;rsquo;ailleurs &amp;ldquo;posée tout haut&amp;rdquo; sur Bluesky et qui a eu des retours intéressants et même parfois inattendus.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Vraie question : à quoi sert un blog technique (rédigé par un être humain, je veux dire) si même les technophiles considèrent que c&amp;rsquo;est plus simple de bypass la doc officielle et les gens qui partagent leur XP, avec de l&amp;rsquo;IA ?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://bsky.app/profile/zwindler.fr/post/3lpohy3efg22l" target="_blank" rel="noopener"
&gt;bsky.app/profile/zwindler.fr/post/3lpohy3efg22l&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Plus globalement, la question était &amp;ldquo;&lt;strong&gt;est-ce que je ne me fais pas un peu de mal à rédiger des trucs techniques si les gens préfèrent le style fade des LLMs ?&lt;/strong&gt;&amp;rdquo;&lt;/p&gt;
&lt;h2 id="vos-réponses-à-cette-question-qui-nen-attendait-pas-forcément"&gt;Vos réponses à cette question (qui n&amp;rsquo;en attendait pas forcément)
&lt;/h2&gt;&lt;p&gt;Je ne vais pas citer tout le monde, mais grosso modo, ce qui en ressort c&amp;rsquo;est :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;le blog tech, c&amp;rsquo;est avant tout pour son propre plaisir (d&amp;rsquo;écrire, d&amp;rsquo;apprendre)&lt;/li&gt;
&lt;li&gt;c&amp;rsquo;est une façon très efficace pour apprendre un nouveau sujet&lt;/li&gt;
&lt;li&gt;ça peut aider au moins une personne&lt;/li&gt;
&lt;li&gt;dans des cas très pointus ou niche, les LLMs ne rivalisent pas encore&lt;/li&gt;
&lt;li&gt;les LLMs ne peuvent pas &amp;ldquo;générer&amp;rdquo; un REX (enfin, pas un vrai :p)&lt;/li&gt;
&lt;li&gt;les LLMs ne vont pas faire des captures d&amp;rsquo;écrans pour les logiciels complexes qui ont des UIs&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Les 4 premières réponses, je les attendais. C&amp;rsquo;est ce qui me motive à écrire ce blog depuis maintenant plus de 15 ans et c&amp;rsquo;est d&amp;rsquo;ailleurs assez proche de &lt;a class="link" href="https://blog.zwindler.fr/2010/04/21/zwindlers-reflection/" &gt;ce que je dis dans mon tout premier billet de blog de 2010&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Les trois dernières, je ne les avais pas forcément vues venir et c&amp;rsquo;est vraiment sur ça que je vais peut-être maintenant plus me reconcentrer : des REX et des sujets très pointus (qui étaient là aussi dans l&amp;rsquo;ADN du blog, surtout au début).&lt;/p&gt;
&lt;p&gt;Mais il y a un point que personne n&amp;rsquo;a évoqué, c&amp;rsquo;est ce fameux style fade que je n&amp;rsquo;aime pas dans les LLMs. C&amp;rsquo;est générique, mécanique, lisse, (statistiquement) moyen.&lt;/p&gt;
&lt;p&gt;Est-ce qu&amp;rsquo;avec un bon LLM aujourd&amp;rsquo;hui, on arrive à contourner cette limitation ?&lt;/p&gt;
&lt;p&gt;Il se trouve que depuis peu, j&amp;rsquo;ai une licence Copilot pour le travail, avec accès à &lt;strong&gt;Claude Sonnet 4&lt;/strong&gt;. J&amp;rsquo;ai donc décidé de tester le mode &amp;ldquo;Agent&amp;rdquo; sur mon blog (la machine a accès à tous les fichiers de mon workspace et peut écrire dans le workspace).&lt;/p&gt;
&lt;p&gt;Note : c&amp;rsquo;est là où on voit que c&amp;rsquo;est pratique d&amp;rsquo;avoir tout en markdown dans un dépôt git !&lt;/p&gt;
&lt;p&gt;J&amp;rsquo;ai donc décidé de prendre un sujet d&amp;rsquo;actualité (pour mon travail), que je connais plutôt bien, plutôt théorique mais surtout très bien documenté. Un exemple parfait d&amp;rsquo;article qu&amp;rsquo;on pourrait voir sur un blog généraliste généré par IA.&lt;/p&gt;
&lt;h2 id="version-basique-en-2-prompts"&gt;Version basique (en 2 prompts)
&lt;/h2&gt;&lt;h3 id="prompt-1--demande-initiale"&gt;Prompt 1 : Demande initiale
&lt;/h3&gt;&lt;p&gt;Dans cette version basique, j&amp;rsquo;ai volontairement laissé beaucoup de liberté au LLM. Je lui ai juste donné le contexte du blog, lui ai demandé de &amp;ldquo;manger&amp;rdquo; quelques-uns de mes articles.&lt;/p&gt;
&lt;p&gt;Il en a &amp;ldquo;consommé&amp;rdquo; 6 entre 2025 et 2023 sur différents thèmes, et un de 2015. Personnellement, j&amp;rsquo;ai pensé que ça serait beaucoup trop peu car les 6 articles étaient vraiment hétérocites (il y avait un billet d&amp;rsquo;humeur politique et une recette de cuisine dans le lot).&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Contexte : Je suis auteur d&amp;#39;un blog technique, spécialisé dans l&amp;#39;observabilité et la virtualisation depuis 2010. Depuis 8 ans, je parle beaucoup de Kubernetes. De temps en temps j&amp;#39;écris des billets d&amp;#39;humeurs ou sur des sujets non tech. Le blog est rédigé en markdown avec hugo, dans le dossier content/post. La grande majorité des posts sont en Français.
Analyse le style d&amp;#39;écriture en lisant quelques posts.
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="réponse-1--analyse-du-style"&gt;Réponse 1 : Analyse du style
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;Ton et personnalité :&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ton décontracté et accessible&lt;/li&gt;
&lt;li&gt;Humour et auto-dérision réguliers&lt;/li&gt;
&lt;li&gt;Émotions transparentes&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Structure et organisation :&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Titres descriptifs et directs&lt;/li&gt;
&lt;li&gt;Introduction contextuelle&lt;/li&gt;
&lt;li&gt;Progression logique&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Vocabulaire et expressions récurrentes :&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&amp;ldquo;Fun fact&amp;rdquo; pour les anecdotes&lt;/li&gt;
&lt;li&gt;&amp;ldquo;Stay tuned&amp;rdquo; pour les annonces&lt;/li&gt;
&lt;li&gt;Parenthèses humoristiques&lt;/li&gt;
&lt;li&gt;Émojis utilisés avec parcimonie&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Évolution du style (2015 vs 2025) :&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;2015 : Plus formel, phrases longues&lt;/li&gt;
&lt;li&gt;2025 : Beaucoup plus décontracté et personnel&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ce qui est noté ici est un résumé. En réalité, l&amp;rsquo;analyse était bien plus longue et j&amp;rsquo;ai été un peu bluffé par la précision de la réponse.&lt;/p&gt;
&lt;p&gt;Il y a un peu de flagornerie par défaut dans les réponses des LLMs, il faut savoir lire entre les lignes, mais globalement c&amp;rsquo;était fidèle et intéressant d&amp;rsquo;avoir une analyse de la progression de mon style d&amp;rsquo;écriture.&lt;/p&gt;
&lt;p&gt;La version 1 est disponible ici :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/zwindler/blog.zwindler.fr/commit/335b4a94943628b5e462581508e899990ba1dee1" target="_blank" rel="noopener"
&gt;le commit qui va bien&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="prompt-2--création-de-larticle"&gt;Prompt 2 : Création de l&amp;rsquo;article
&lt;/h3&gt;&lt;p&gt;Pour écrire l&amp;rsquo;article, j&amp;rsquo;ai essayé d&amp;rsquo;écrire un prompt relativement rapide. J&amp;rsquo;ai un peu triché par contre, je lui ai dit de se baser sur mon talk &amp;ldquo;SRE ! SRE partout !&amp;rdquo; dans lequel j&amp;rsquo;introduis les principes que j&amp;rsquo;avais envie de voir dans l&amp;rsquo;article écrit.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Est-ce que tu penses pouvoir écrire un article daté du jour sur les concepts SLO / SLI / error budget / critical user journey en copiant mon style ?
Indique qu&amp;#39;il ne faut pas confondre SLA et SLO
Tu peux aussi t&amp;#39;inspirer en partie d&amp;#39;un talk que j&amp;#39;ai écrit sur le sujet et qu&amp;#39;on peut trouver ici :
static/talks/2022-sre-sre-partout/index.md (À partir de la ligne 303)
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="réponse-2--premier-article-généré"&gt;Réponse 2 : Premier article généré
&lt;/h3&gt;&lt;p&gt;L&amp;rsquo;IA a produit un article complet qui reprenait effectivement mon style avec :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ton décontracté&lt;/li&gt;
&lt;li&gt;Structure progressive&lt;/li&gt;
&lt;li&gt;Exemples concrets&lt;/li&gt;
&lt;li&gt;Vulgarisation accessible&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Le résultat est assez bluffant.&lt;/p&gt;
&lt;p&gt;Avec un peu d&amp;rsquo;habitude, on peut deviner que ce n&amp;rsquo;est pas moi qui ai écrit l&amp;rsquo;article. Ma femme (qui lit la plupart de mes articles, a minima en diagonale) n&amp;rsquo;a pas su le dire à première vue.&lt;/p&gt;
&lt;p&gt;Il y a quelques tournures que je n&amp;rsquo;aurais pas utilisées, mais surtout ça reste hyper généraliste (voire générique), lisse. En revanche, le ton est suffisamment décontracté pour que les détecteurs type ZeroGPT soient bernés :&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;12.62% : Votre Texte est probablement écrit par un humain, peut inclure des parties générées par une IA/GPT&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/06/zerogpt.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Les parties surlignées en jaune sont les seules détectées comme &amp;ldquo;générées&amp;rdquo;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Produire l&amp;rsquo;article dans cette version m&amp;rsquo;a pris à peu près 2 minutes chrono. Mais ça ne correspond toujours pas à mon standard de &amp;ldquo;blogging&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Donc j&amp;rsquo;ai décidé de pousser l&amp;rsquo;expérience jusqu&amp;rsquo;au bout, quitte à passer plus de temps à prompter et lui donner des instructions que ça ne m&amp;rsquo;aurait pris à l&amp;rsquo;écrire moi-même.&lt;/p&gt;
&lt;h2 id="avec-plus-de-prompts-version-itérative"&gt;Avec plus de prompts (version itérative)
&lt;/h2&gt;&lt;h3 id="prompt-x--demande-de-modifications"&gt;Prompt X : Demande de modifications
&lt;/h3&gt;&lt;p&gt;Il y a tellement de modifications demandées ici, certaines tellement directives (exemples que je lui demande d&amp;rsquo;inclure), que j&amp;rsquo;ai quasiment envie de dire que c&amp;rsquo;est moi qui ai écrit une bonne moitié de l&amp;rsquo;article, pas le LLM&amp;hellip; Mais c&amp;rsquo;était pour la science :p&lt;/p&gt;
&lt;p&gt;L&amp;rsquo;article final est disponible ici :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://blog.zwindler.fr/2025/06/17/slo-sli-error-budget-critical-user-journey-expliques-simplement/" &gt;SLO, SLI, Error Budget et Critical User Journey expliqués simplement et pourquoi ce ne sont pas des SLA !&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Garde ce fichier tel quel, c&amp;#39;est une bonne première version
Écris un nouveau fichier avec le premier comme base, mais en prenant en compte les modifications suivantes (Tu as le droit de donner ton avis sur ces modifications tant que c&amp;#39;est constructif) :
De manière générale, je trouve qu&amp;#39;il y a beaucoup de listes (bullet points) ce qui ne correspond pas forcément à mon style (j&amp;#39;en mets mais pas aussi souvent)
En intro, j&amp;#39;aime bien fixer le contexte :
- Explique que c&amp;#39;est suite à des discussions avec des collègues développeurs pour qui les concepts n&amp;#39;étaient pas clairs que j&amp;#39;ai voulu redéfinir les termes, tels qu&amp;#39;ils ont été conçus par Google.
- Explique dès l&amp;#39;introduction que le SRE et tous les concepts associés dont les SLO, ont été inventés par Google.
Au niveau de &amp;#34;Et au-delà d&amp;#39;un certain seuil, les utilisateurs ne voient même plus la différence !&amp;#34;, cite l&amp;#39;exemple d&amp;#39;un site web qui ne charge pas sur un smartphone. Au-delà d&amp;#39;un certain niveau de disponibilité, l&amp;#39;utilisateur ne saura pas dire si c&amp;#39;est son smartphone qui a un problème, son navigateur, le réseau 5G ou bien le site web qui rencontre un incident. Si recharger la page une fois de temps en temps suffit et que les utilisateurs ne sont pas plus impactés que ça, inutile d&amp;#39;investir dans plus de fiabilité
Explique également que pour les CUJ, la notion d&amp;#39;utilisateur du service n&amp;#39;est pas nécessairement &amp;#34;l&amp;#39;utilisateur final&amp;#34;. L&amp;#39;utilisateur pour la fiabilité d&amp;#39;un service backend, ce n&amp;#39;est pas forcément l&amp;#39;utilisateur final, ça peut être le front qui initie le call. L&amp;#39;utilisateur de la CI, ce ne sont pas directement les utilisateurs finaux non plus, c&amp;#39;est les devs qui veulent livrer une nouvelle version de l&amp;#39;appli.
Explique qu&amp;#39;un microservice ne doit pas avoir trop de SLI, 3-4 les plus pertinentes et qui ont un sens métiers (cf les CUJ). Seuls les membres de l&amp;#39;équipe qui fournissent le service / le développent peuvent savoir (dans le sens : on ne peut pas en imposer des génériques pour toute une entreprise)
Dans les conseils pour définir des SLO cite aussi les méthodes USE et RED pour aider à concevoir des SLI fiables (définis-les très brièvement)
Enlève la phrase &amp;#34;tags pour moi même&amp;#34; en conclusion qui ne correspond pas à mon style &amp;#34;habituel&amp;#34;
Pour calculer les SLA / SLO tu peux citer le site https://uptime.is/
Pour le lien &amp;#34;mon talk sur le SRE en 2022&amp;#34;, il faut mettre ce lien-là : /talks/2022-sre-sre-partout/index.html plutôt que /conferences/
Ajoute l&amp;#39;image /talks/2022-sre-sre-partout/binaries/simpsons.png dans la partie sur les error budgets qu&amp;#39;il faut consommer (c&amp;#39;est une blague qui montre une personne qui dit qu&amp;#39;elle casse régulièrement la prod pour finir sur le ton de l&amp;#39;humour)
Mets cette image en &amp;#34;image:&amp;#34; /talks/2022-sre-sre-partout/binaries/sre_sre_partout.jpg dans les métadonnées markdown des deux posts
Change le titre de la première version en y ajoutant &amp;#34;(en 2 prompts)&amp;#34;, et le titre du second en y ajoutant &amp;#34;(en plusieurs prompts)&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Après avoir écrit tout ça, le résultat n&amp;rsquo;est pas mal, proche de ce que j&amp;rsquo;aurais pu écrire &amp;ldquo;moi-même&amp;rdquo; ou presque.&lt;/p&gt;
&lt;p&gt;Si on compare le diff entre la version 1 et la version 2, on voit que quasiment TOUT a été réécrit.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/06/diff.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;h2 id="réflexions-sur-le-processus"&gt;Réflexions sur le processus
&lt;/h2&gt;&lt;p&gt;Ce qui marche VRAIMENT bien, c&amp;rsquo;est l&amp;rsquo;analyse de style : le LLM est capable d&amp;rsquo;identifier et de reproduire &lt;em&gt;mes patterns stylistiques&lt;/em&gt; avec une précision surprenante par rapport au peu d&amp;rsquo;articles qu&amp;rsquo;il a analysé, au point de berner ma chérie sur une première lecture rapide.&lt;/p&gt;
&lt;p&gt;Cependant, on reste sur quelque chose de super générique techniquement (qui a dit &amp;ldquo;chiant&amp;rdquo; ?). Sans guidage explicite, les exemples ne sont pas dingues, ça manque de contextualisation, etc. Il y a une grosse phase d&amp;rsquo;aller-retours avant que le résultat soit &amp;ldquo;correct&amp;rdquo; (aka &amp;ldquo;pas pénible à lire&amp;rdquo;) à mes yeux.&lt;/p&gt;
&lt;p&gt;Je pense aussi qu&amp;rsquo;on aurait encore pu améliorer le résultat en demandant au LLM de lire plus d&amp;rsquo;articles de mon blog (ou en lui pointant ceux qui sont pertinents).&lt;/p&gt;
&lt;p&gt;Enfin, Claude Sonnet 4 ne permet pas de générer des images donc si je voulais pousser l&amp;rsquo;expérience en ajoutant des schémas, il aurait fallu que je me contente d&amp;rsquo;outils textuels type mermaid, ou que je les ajoute à la main.&lt;/p&gt;
&lt;h2 id="conclusion-"&gt;Conclusion ?
&lt;/h2&gt;&lt;p&gt;Que dire de tout ça ?&lt;/p&gt;
&lt;p&gt;Déjà, Zero GPT ne sert à rien. Il a été totalement incapable de détecter que le texte avait été généré (à part quelques bribes).&lt;/p&gt;
&lt;p&gt;Ensuite, je n&amp;rsquo;ai pas vraiment prévu de changer ma manière de blogger, même si j&amp;rsquo;y réfléchirai peut être à deux fois si j&amp;rsquo;ai un sujet très généraliste en tête. Je ferai peut être un peu plus de sujets &amp;ldquo;niches&amp;rdquo; et de REX.&lt;/p&gt;
&lt;p&gt;Enfin, que &amp;ldquo;oui&amp;rdquo; on peut produire des articles plutôt pas mal (je trouve) avec un LLM, mais il faut (pour l&amp;rsquo;instant encore) :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;connaître le sujet&lt;/li&gt;
&lt;li&gt;passer pratiquement autant de temps (voire plus) à itérer sur le résultat pour avoir quelque chose de similaire à ce qu&amp;rsquo;un humain (moi) aurait pu écrire&lt;/li&gt;
&lt;/ul&gt;</description></item></channel></rss>