<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>Blog — Guillaume Besseau</title>
<link>https://guillaume-besseau.fr/blog/index.html</link>
<description>Blog de Guillaume Besseau : réflexions sur le développement, l'intelligence artificielle et la musique, entre pratique professionnelle et projets personnels.</description>
<language>fr-fr</language>
<lastBuildDate>Sun, 27 Sep 2026 12:00:00 GMT</lastBuildDate>
<atom:link href="https://guillaume-besseau.fr/blog/rss.xml" rel="self" type="application/rss+xml"/>

<item>
<title>Pourquoi je n'ai jamais vectorisé ma doc</title>
<link>https://guillaume-besseau.fr/blog/markdown-curation-vs-rag-vectoriel-graphrag.html</link>
<guid>https://guillaume-besseau.fr/blog/markdown-curation-vs-rag-vectoriel-graphrag.html</guid>
<pubDate>Sun, 27 Sep 2026 12:00:00 GMT</pubDate>
<description><![CDATA[


<p>
Chez le client, ma façon de préparer le terrain pour l'IA est toujours
la même : je sors l'information dans un format plus petit, filtré,
organisé à la main — pas une base vectorielle, pas d'indexation
automatique. Ça marche, et plutôt bien. Le problème, c'est que je fais
ça un peu à contre-courant : autour de moi, la conversation part vite
sur les bases vectorielles, les graphes de connaissances, les
frameworks d'agents, comme si ne pas les utiliser relevait du retard
plutôt que d'un choix. Je me suis demandé si mon instinct de data
engineer tenait vraiment la route, ou si je me racontais une histoire.
J'ai creusé quatre fils précis pour trancher.
</p>

<p>
Le premier m'a surpris par sa source. Anthropic elle-même a abandonné
le RAG plus base vectorielle pour Claude Code, au profit de la
recherche agentique — grep, ls, cat, en boucle, un peu comme un
développeur explore un repo à la main. Boris Cherny, qui dirige Claude
Code, l'a écrit noir sur blanc : les premières versions utilisaient RAG
et une base vectorielle locale, "mais on a vite découvert que la
recherche agentique fonctionne généralement mieux". Les raisons
données ne sont pas cosmétiques : un index vectoriel devient obsolète
dès que le code ou la doc bouge, la recherche sémantique retourne des
"snippets similaires" là où il faut des références exactes, et la
recherche agentique évite toute la complexité opérationnelle de
maintenir un index à jour — plus simple, plus sûr aussi côté
confidentialité. Fabio Akita est arrivé au même endroit par un chemin
différent, en partant des capacités de contexte des modèles actuels
plutôt que du choix d'architecture d'Anthropic : un bon grep plus une
fenêtre de contexte généreuse bat, dans la plupart des cas, une pile
RAG complète. Deux angles distincts, une même conclusion. La
contrepartie honnête existe : mal cadrée, une recherche agentique peut
explorer trop et consommer plus de tokens qu'un lookup vectoriel bien
réglé — mais c'est un problème de cadrage, pas un argument pour revenir
à la vectorisation par défaut.
</p>

<p>
Deuxième fil, plus terre-à-terre mais probablement le plus rentable des
quatre : avant même de se poser la question du retrieval, convertir un
document en markdown réduit sa taille en tokens de 65 à 90%, selon le
format de départ. Un exemple parlant : un article de 500 mots pèse
autour de 700 tokens une fois converti en markdown, et peut dépasser
8000 tokens dans son HTML brut d'origine — la faute aux balises, aux
attributs, à tout ce qui sert l'affichage et rien à la compréhension.
Les DOCX et les PDF texte tirent aussi leur épingle du jeu, dans des
proportions un peu moindres. Des outils font ce travail sans qu'on ait
à y penser : MarkItDown, l'outil open source de Microsoft — qui tourne
en local, y compris comme serveur MCP directement dans Claude Code —,
Pandoc, Marker. C'est le levier le plus simple à activer, et il agit
avant même d'avoir choisi une stratégie de recherche.
</p>

<figure class="schema-figure" aria-label="Schéma : réduction de tokens obtenue en convertissant en markdown, selon le format source">
<h4>Réduction de tokens en convertissant en markdown, selon le format source</h4>
<div class="schema-range-row">
<span class="schema-range-label">HTML brut</span>
<div class="schema-range-track"><div class="schema-range-fill" style="left: 75%; width: 15%;"></div></div>
<span class="schema-range-value">75–90%</span>
</div>
<div class="schema-range-row">
<span class="schema-range-label">DOCX</span>
<div class="schema-range-track"><div class="schema-range-fill schema-range-fill--soft" style="left: 50%; width: 20%;"></div></div>
<span class="schema-range-value">50–70%</span>
</div>
<div class="schema-range-row">
<span class="schema-range-label">PDF texte standard</span>
<div class="schema-range-track"><div class="schema-range-fill schema-range-fill--soft" style="left: 40%; width: 25%;"></div></div>
<span class="schema-range-value">40–65%</span>
</div>
<div class="schema-range-scale"><span>0% réduction</span><span>100% réduction</span></div>
<div class="schema-example">
<p class="schema-example-title">Exemple concret — article de 500 mots</p>
<div class="schema-mesure-row">
<span class="schema-mesure-label">HTML brut</span>
<div class="schema-mesure-track"><div class="schema-mesure-fill schema-mesure-fill--full" style="width: 100%;"><span>8000+ tokens</span></div></div>
</div>
<div class="schema-mesure-row">
<span class="schema-mesure-label">Markdown</span>
<div class="schema-mesure-track"><div class="schema-mesure-fill" style="width: 9%;"><span>~700 tokens</span></div></div>
</div>
</div>
<div class="schema-example">
<p class="schema-example-title">Autre exemple — fiche produit de 10 pages en DOCX</p>
<div class="schema-mesure-row">
<span class="schema-mesure-label">DOCX brut</span>
<div class="schema-mesure-track"><div class="schema-mesure-fill schema-mesure-fill--full" style="width: 100%;"><span>12 000 tokens</span></div></div>
</div>
<div class="schema-mesure-row">
<span class="schema-mesure-label">Markdown</span>
<div class="schema-mesure-track"><div class="schema-mesure-fill" style="width: 33%;"><span>&lt; 4000 tokens</span></div></div>
</div>
</div>
<figcaption>Fourchettes et exemples publiés par MindStudio, « How to Convert Files to Markdown to Reduce AI Token Usage by Up to 90% » (voir Références) — mesurés sur des documents réels, pas des cas théoriques.</figcaption>
</figure>

<p>
Troisième fil : les graphes de connaissances façon GraphRAG, présentés
comme l'étape d'après pour qui veut un vrai "cerveau" documentaire. Le
coût d'indexation, historiquement, est aberrant — environ 1544$ par
million de tokens pour construire un graphe complet, contre environ
1,45$ par million de tokens pour un RAG vectoriel classique, un facteur
qui tourne autour de mille. Un cas concret, documenté sur le dépôt
officiel de Microsoft GraphRAG : indexer un seul dossier juridique de
5 Go de texte revenait, avec GPT-4o-mini, à environ 33 000$. Une
variante publiée par Microsoft Research fin 2024, LazyGraphRAG, a fait
tomber ce coût au niveau d'un RAG vectoriel classique en repoussant
l'essentiel du travail LLM au moment de la requête plutôt qu'à
l'indexation — et cette baisse tient toujours en 2026, elle n'a rien
d'un correctif ponctuel. Mais faire baisser le prix ne répond pas à la
vraie question, celle qui a justifié tout un papier de recherche à
elle seule en 2026 : un graphe ne vaut son coût que sur des
questions vraiment transversales à tout un corpus — comparaisons,
motifs qui traversent plusieurs documents — jamais sur du lookup
simple, qui reste mon usage dominant. Et il garde un risque propre,
symétrique à la vectorisation à l'aveugle : l'extraction du graphe se
fait elle aussi par un LLM, qui peut très bien relier deux entités par
une relation qui ne tient pas vraiment dans le texte source.
</p>

<p>
Le quatrième fil est celui qui m'a le plus servi à comprendre ce que je
fais déjà sans le nommer ainsi : mon wiki personnel, à la Obsidian,
n'est pas un GraphRAG déguisé, même si les deux finissent par produire
un graphe qu'on peut visualiser. La mécanique est différente à la
racine. Chaque nœud est un fichier markdown, chaque arête est un lien
que j'écris moi-même, après avoir compris le contenu — pas un LLM qui
infère une relation depuis un texte qu'il vient de lire une fois. Coût
d'extraction nul, risque d'hallucination nul, parce que la
compréhension précède le lien plutôt que l'inverse. Les plugins qui
promettent de découvrir des liens "cachés" par embeddings, comme
InfraNodus sur Obsidian, réintroduisent à mes yeux le même risque que
GraphRAG, juste déplacé du serveur vers le plugin. Andrej Karpathy a
formalisé cette approche en avril 2026, dans un texte qu'il présente
explicitement comme une alternative à la vectorisation et au contexte
long : une mémoire d'agent persistante sur disque, en markdown et
wikilinks, chargée au fur et à mesure que l'agent navigue plutôt que
toute entière en contexte. Une implémentation communautaire de ce
patron tourne à 100% en local via Ollama — la preuve que ça ne suppose
pas un modèle frontier, seulement un agent bien réglé pour savoir quel
lien suivre et quand s'arrêter.
</p>

<figure class="schema-figure" aria-label="Schéma : quatre façons de retrouver l'information, comparées sur les mêmes critères">
<h4>Quatre façons de retrouver l'information, un seul jeu de critères</h4>
<div class="schema-matrix">
<div class="schema-matrix-card">
<h5>Recherche agentique</h5>
<div class="schema-matrix-dim"><strong>Structure</strong>Aucune — exploration en direct (grep/ls/cat)</div>
<div class="schema-matrix-dim"><strong>Fraîcheur</strong>Toujours à jour, lit les fichiers réels</div>
<div class="schema-matrix-dim"><strong>Coût de mise à jour</strong>Nul</div>
<div class="schema-matrix-dim"><strong>Risque</strong>Sur-explore et gonfle les tokens si mal cadrée</div>
<div class="schema-matrix-dim"><strong>Bon usage</strong>Lookup exact, code/doc qui bouge souvent</div>
</div>
<div class="schema-matrix-card">
<h5>RAG vectoriel</h5>
<div class="schema-matrix-dim"><strong>Structure</strong>Embeddings pré-calculés à l'indexation</div>
<div class="schema-matrix-dim"><strong>Fraîcheur</strong>Obsolète dès que les documents changent</div>
<div class="schema-matrix-dim"><strong>Coût de mise à jour</strong>~1,45$ / million de tokens</div>
<div class="schema-matrix-dim"><strong>Risque</strong>Renvoie des « snippets similaires », pas des références exactes</div>
<div class="schema-matrix-dim"><strong>Bon usage</strong>Recherche floue sur corpus stable</div>
</div>
<div class="schema-matrix-card">
<h5>GraphRAG</h5>
<div class="schema-matrix-dim"><strong>Structure</strong>Un LLM extrait les relations à l'indexation</div>
<div class="schema-matrix-dim"><strong>Fraîcheur</strong>Dépend de la fréquence de ré-indexation</div>
<div class="schema-matrix-dim"><strong>Coût de mise à jour</strong>~1544$/M tokens — ramené à la parité par LazyGraphRAG</div>
<div class="schema-matrix-dim"><strong>Risque</strong>Peut relier deux entités par une relation hallucinée</div>
<div class="schema-matrix-dim"><strong>Bon usage</strong>Questions transversales à tout un corpus</div>
</div>
<div class="schema-matrix-card">
<h5>Wiki manuel</h5>
<div class="schema-matrix-dim"><strong>Structure</strong>Chaque lien écrit à la main, après compréhension</div>
<div class="schema-matrix-dim"><strong>Fraîcheur</strong>Aussi à jour que la dernière mise à jour manuelle</div>
<div class="schema-matrix-dim"><strong>Coût de mise à jour</strong>Nul</div>
<div class="schema-matrix-dim"><strong>Risque</strong>Reporté sur l'auteur humain, pas sur un LLM</div>
<div class="schema-matrix-dim"><strong>Bon usage</strong>Mémoire personnelle ou d'agent, navigation lente et sûre</div>
</div>
</div>
<figcaption>Synthèse des quatre fils de ce billet sur les mêmes critères — chaque approche a un vrai bon cas d'usage, aucune n'est strictement meilleure que les trois autres.</figcaption>
</figure>

<p>
Un aparté qui n'est pas le sujet de ce billet, mais qui l'illustre
bien : mon CV décrivait cette pratique comme "RAG (passif)". Un
screening IA que j'ai fait tourner sur mon propre site —
<a href="cv-2026-screening-ia-et-avis-rh.html">je raconte le protocole
complet ici</a> — a lu ce mot comme un aveu de faiblesse plutôt que
comme de la précision honnête, et ça m'a coûté des points de score.
J'avais choisi de garder le mot tel quel à l'époque, en toute
connaissance de cause. Mais cette session de recherche m'a donné de
quoi trancher autrement : "RAG (markdown-based)" décrit exactement la
même pratique, sans ce risque de lecture, alors j'ai changé le mot sur
mon CV. La pratique n'a pas bougé d'un pouce ; c'est le vocabulaire
autour qui a vieilli plus vite qu'elle.
</p>

<p>
Ces quatre fils ne prouvent pas que le markdown gagne partout : la
recherche agentique a ses limites de cadrage, LazyGraphRAG a sa place
quand le corpus le justifie vraiment, InfraNodus rend un vrai service
tant qu'on sait ce qu'il fait sous le capot. Ce qu'ils confirment, plus
précisément, c'est que mon réflexe de data engineer — sortir l'info
dans un format plus petit, curé à la main, versionnable — tient debout
point par point, sur les quatre fils que j'ai vérifiés. Il reste, pour
l'instant, le point de départ le plus rentable avant même de se
demander si on a vraiment besoin de vectoriser quoi que ce soit.
</p>

<h2>Références</h2>
<ul>
<li><a href="https://x.com/bcherny/status/2017824286489383315">Boris Cherny (X) — citation d'origine sur l'abandon de RAG + vector DB pour Claude Code</a></li>
<li><a href="https://robertheubanks.substack.com/p/anthropic-replaced-their-rag-pipeline">Robert H. Eubanks — Anthropic Replaced Their RAG Pipeline with Agentic Search</a></li>
<li><a href="https://akitaonrails.com/en/2026/04/06/rag-is-dead-long-context/">Fabio Akita — RAG is dead, long context wins</a></li>
<li><a href="https://www.mindstudio.ai/blog/convert-files-markdown-reduce-ai-tokens">MindStudio — How to Convert Files to Markdown to Reduce AI Token Usage by Up to 90%</a></li>
<li><a href="https://github.com/microsoft/markitdown">Microsoft — MarkItDown (dépôt officiel)</a></li>
<li><a href="https://dev.to/saurabh_naik_b213f3bbeafe/graphrag-vs-vector-rag-when-the-knowledge-graph-pays-for-itself-3386">GraphRAG vs Vector RAG: When the Knowledge Graph Pays for Itself</a> — chiffres de coût d'indexation ($1544/M tokens vs $1,45/M tokens)</li>
<li><a href="https://github.com/microsoft/graphrag/discussions/1817">Microsoft GraphRAG (discussion officielle) — le cas des 33 000$ pour indexer 5 Go de documents légaux</a></li>
<li><a href="https://www.microsoft.com/en-us/research/blog/lazygraphrag-setting-a-new-standard-for-quality-and-cost/">Microsoft Research — LazyGraphRAG: Setting a new standard for quality and cost</a></li>
<li><a href="https://arxiv.org/abs/2609.18099">arXiv — When Is Graph Structure Worth Its Cost? The Case for Structure Pricing in Retrieval-Augmented Generation</a></li>
<li><a href="https://infranodus.com/use-case/visualize-knowledge-graphs-pkm">InfraNodus — Visualize Knowledge Graphs for Personal Knowledge Management</a></li>
<li><a href="https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f">Andrej Karpathy — LLM Wiki (gist d'origine, avril 2026)</a></li>
<li><a href="https://github.com/kytmanov/obsidian-llm-wiki-local">kytmanov/obsidian-llm-wiki-local — implémentation 100% locale via Ollama</a></li>
</ul>

]]></description>
</item>

<item>
<title>CV en 2026 : écrire pour un humain pressé et pour un robot qui score</title>
<link>https://guillaume-besseau.fr/blog/cv-2026-screening-ia-et-avis-rh.html</link>
<guid>https://guillaume-besseau.fr/blog/cv-2026-screening-ia-et-avis-rh.html</guid>
<pubDate>Sat, 12 Sep 2026 12:00:00 GMT</pubDate>
<description><![CDATA[

<p>
Un portfolio perso, en 2026, ne sert pas qu'à montrer un parcours. Le
mien reprend la main sur ma présence en ligne plutôt que de la laisser
se deviner par d'autres, prépare le volet musique que je développerai
plus tard, et tient ce blog où je pose mes questionnements sur l'IA au
fur et à mesure. Trois buts différents, un seul site — et des
orchestrations vers d'autres services ou sites plus tard. La difficulté
pour un site comme celui-ci, c'est qu'il doit parler aux humains et aux
machines en même temps, avec des besoins qui ne se recouvrent pas
toujours. Comment on synthétise
un CV pour un humain pressé de trente secondes tout en montrant toute
l'info à un robot qui, lui, scanne tout sans qu'on sache vraiment ce
qu'il en retient ?
</p>

<p>
J'avais déjà construit un skill <code>agent-rh</code>, nourri de ma propre veille,
pour m'améliorer au fil du temps sur mon CV. Il a fini par pointer un
vrai problème que je devais corriger : il donnait tout en synthèse en
devinant ce que vient chercher la personne qui regarde mon CV — et ça,
c'est impossible à deviner de façon fiable, puisque ça dépend entièrement
de qui regarde et pourquoi. Alors j'ai testé autre chose : simuler un
vrai outil de screening CV par IA, façon Greenhouse, Ashby ou Workday,
directement sur mon site public, et regarder comment mon skill RH réagit
à ce que cet outil produit — pas en lisant mon CV lui-même, en ne
lisant que sa synthèse. Reproduire fidèlement ce qu'un recruteur humain
ferait en 2026, pas ce que je voudrais qu'il fasse.
</p>

<p>
L'hypothèse tient debout : 87% des entreprises utilisent l'IA à un
moment ou un autre de leur processus de recrutement, et le pipeline
type ressemble à ceci — parsing du document, résumé ou score produit
par un LLM, puis lecture humaine de ce résumé, la décision finale
restant humaine. Ce que ça change concrètement, c'est qu'optimiser un
CV pour un lecteur humain de trente secondes et l'optimiser pour un
parseur IA ne sont pas tout à fait le même exercice. Parfois les deux
se renforcent. Parfois ils s'opposent frontalement, comme on va le
voir.
</p>

<p>
Le protocole que j'ai suivi : un agent générique fraîchement instancié,
sans aucune mémoire de la conversation, qui lit uniquement ce qui est
publié publiquement sur mon site — le CV, la page d'accueil, tous les
billets du blog. Il produit un rapport structuré, exactement au format
qu'un vrai outil de tri sortirait : un Fit Score chiffré et justifié,
les compétences détectées en distinguant déclaratives (section
Compétences) et inférées (citées seulement en prose dans une puce
d'expérience), les points forts, les gaps, et une recommandation. Ce
format n'est pas inventé : une compétence nommée dans une section
dédiée et prouvée dans une puce d'expérience compte pour plus forte que
l'une des deux prise seule — précisément ce que la fonctionnalité que
je décris plus bas est venue corriger. Une fois ce rapport produit, je
me mettais à la place du recruteur : je ne réagissais qu'à cette
synthèse, jamais au CV brut. Cinq lectures ont été faites ainsi, sur
cinq agents fraîchement instanciés, aucun ne se souvenant des passes
précédentes.
</p>

<p>
Trois premières passes ont eu lieu au fil de mes corrections du CV, le
même jour. Score de départ : 61 sur 100, avant toute section
Compétences, sans ville ni région précisées, sans cloud provider nommé,
sans orchestrateur cité. Après ajout d'une section Compétences, de
Nantes, d'Azure et de GitLab CI/CD : 70 sur 100. Puis, après avoir
supprimé un bloc "Stack technique" jugé redondant pour gagner en
lisibilité : 63 sur 100 — alors que rien d'important n'avait disparu
en substance, les mots-clés du bloc supprimé avaient été recopiés dans
la section Compétences avant suppression.
</p>

<figure class="schema-figure" aria-label="Schéma : trois passes de score sur le même CV au fil des corrections">
<h4>Round 1 — trois passes, un score qui bouge tout seul</h4>
<div class="schema-bar-row">
<span class="schema-bar-label">Passe 1 — avant corrections</span>
<div class="schema-bar-track"><div class="schema-bar-fill schema-bar-fill--soft" style="width: 61%;"><span>61/100</span></div></div>
</div>
<div class="schema-bar-row">
<span class="schema-bar-label">Passe 2 — après Compétences/Nantes/Azure/CI-CD</span>
<div class="schema-bar-track"><div class="schema-bar-fill" style="width: 70%;"><span>70/100</span></div></div>
</div>
<div class="schema-bar-row">
<span class="schema-bar-label">Passe 3 — après simplification lisibilité</span>
<div class="schema-bar-track"><div class="schema-bar-fill schema-bar-fill--soft" style="width: 63%;"><span>63/100</span></div></div>
</div>
<p class="schema-bar-note">Le score <strong>baisse</strong> entre la passe 2 et la passe 3 alors qu'aucune information importante n'a été perdue en substance — juste réorganisée. Ces outils sont probabilistes, pas déterministes : la précision affichée d'un chiffre comme « 63/100 » masque une vraie variance d'une exécution à l'autre.</p>
<figcaption>Cinq agents <code>general-purpose</code> fraîchement instanciés, chacun sans mémoire de la conversation ni des passes précédentes — protocole détaillé dans le corps du billet.</figcaption>
</figure>

<p>
Ce que la troisième passe a mis en évidence, c'est la vraie tension du
billet. La règle "trois à cinq puces par poste, curées, pas une liste
exhaustive" est une norme bien établie pour un CV lu par un humain
pressé. Le problème, c'est qu'en simplifiant pour respecter cette règle,
j'ai fait disparaître les puces de prose qui donnaient du contexte
narratif à une dizaine de compétences listées par ailleurs dans la
section Compétences — Docker, Kubernetes, TDD/DDD, Talend, Power BI.
L'outil a signalé explicitement que ces tags "n'ont aucune trace dans
les puces d'expérience" et a baissé sa confiance sur chacun d'eux pris
individuellement. Un lecteur humain pressé, lui, préfère justement la
version courte.
</p>

<p>
J'ai un principe qui s'oppose frontalement à cette lecture, et je le
tiens : les compétences n'ont pas besoin d'avoir une ligne dans un
contexte de synthèse, les mots sont une synthèse pour respecter les
trente secondes — si les RH ont des questions, c'est à l'entretien
qu'elles se posent. C'est un choix de design que je défends. Mais
l'exercice montre concrètement qu'un lecteur IA ne sait pas "attendre
l'entretien" — il note ce qu'il voit, au moment où il le voit. Ce n'est
l'erreur de personne : deux lecteurs différents optimisent pour des
choses différentes, et mon CV ne peut pas être parfaitement optimal
pour les deux à la fois.
</p>

<p>
La question suivante m'intéressait plus encore : ce score est-il une
propriété stable de mon CV, ou dépend-il de ce qu'on cherche ? J'ai
rejoué la même lecture — même CV, même page d'accueil, même blog, rien
n'a changé entre les trois — en ne faisant varier qu'un seul paramètre
du prompt : le poste cible donné à l'agent. Trois formulations, trois
scores très différents.
</p>

<figure class="schema-figure" aria-label="Schéma : trois recherches différentes sur un CV strictement identique">
<h4>Un même CV, trois recherches, 23 points d'écart</h4>
<div class="schema-bar-row">
<span class="schema-bar-label">Data Engineer généraliste</span>
<div class="schema-bar-track"><div class="schema-bar-fill schema-bar-fill--soft" style="width: 58%;"><span>58/100</span></div></div>
</div>
<div class="schema-bar-row">
<span class="schema-bar-label">Développeur expérimenté / senior</span>
<div class="schema-bar-track"><div class="schema-bar-fill" style="width: 41%;"><span>41/100</span></div></div>
</div>
<div class="schema-bar-row">
<span class="schema-bar-label">Context Engineer / Dev IA</span>
<div class="schema-bar-track"><div class="schema-bar-fill schema-bar-fill--soft" style="width: 64%;"><span>64/100</span></div></div>
</div>
<p class="schema-bar-note">Le score le plus bas (41) vient presque entièrement du <strong>titre de poste littéral</strong> — "Data Engineer" ne matche pas "Développeur" — malgré une stack backend jugée cohérente par le même rapport. Le score le plus haut (64) doit sa position au contenu du blog, qui compense un déficit de vocabulaire outillage.</p>
<figcaption>Trois agents fraîchement instanciés, un seul paramètre variant : le poste cible donné dans le prompt.</figcaption>
</figure>

<p>
Vingt-trois points d'écart sur un document strictement identique, en
changeant seulement la cible de recherche. La conclusion que je retiens
de ce chiffre : le score d'un outil de screening n'est pas une propriété
du CV, c'est une propriété de la rencontre entre le CV et une recherche
précise. Je n'ai pas "un score", j'en ai autant que de recherches
possibles. Et le matching par titre de poste littéral semble peser plus
lourd que le matching sémantique sur les compétences réelles — le
rapport lui-même le dit, à propos du score le plus bas : l'écart pourrait
venir d'un problème de formulation du CV plutôt que d'un déficit de
compétence réel, mais ce n'est pas vérifiable à la seule lecture.
</p>

<p>
J'ai voulu corriger ce que je pouvais corriger sans mentir sur rien :
la tension "tags sans preuve narrative" repérée au round 1. Plutôt que
de rajouter de la prose — ce qui aurait recréé le problème de longueur
qui m'avait fait simplifier au départ — j'ai rendu le lien structurel.
Chaque tag de la section Compétences est devenu un vrai lien HTML
statique vers l'expérience précise où cette compétence a été utilisée,
avec un survol qui surligne l'entrée visée sans jamais masquer le reste.
J'ai rejoué les trois mêmes recherches sur des agents fraîchement
instanciés, CV identique par ailleurs.
</p>

<figure class="schema-figure" aria-label="Tableau : scores avant et après l'ajout du lien compétence vers expérience">
<h4>Round 2 — après le lien compétence ↔ expérience</h4>
<table class="schema-table">
<thead>
<tr><th>Recherche ciblée</th><th>Round 1</th><th>Round 2</th><th>Delta</th></tr>
</thead>
<tbody>
<tr><td>Data Engineer généraliste</td><td class="score">58</td><td class="score">58</td><td class="delta-zero">0</td></tr>
<tr><td>Développeur expérimenté / senior</td><td class="score">41</td><td class="score">58</td><td class="delta-pos">+17</td></tr>
<tr><td>Context Engineer / Dev IA</td><td class="score">64</td><td class="score">61</td><td class="delta-neg">-3</td></tr>
</tbody>
</table>
<figcaption>Même protocole que le round 1 : trois agents fraîchement instanciés, un seul changement entre les deux rounds — le lien HTML statique entre chaque tag de compétence et l'expérience où elle a été utilisée (voir <code>site/cv/skills.js</code>).</figcaption>
</figure>

<p>
Le gain le plus net de toute la session : dix-sept points sur la
recherche "développeur", exactement celle où le round 1 avait identifié
le problème. Le rapport du round 2 l'écrit noir sur blanc à propos de
TDD/DDD : liés à trois expériences distinctes, donc "traçables et non
déclaratifs". Les deux autres scores, eux, ne bougent quasiment pas —
logique, puisque les gaps qu'ils pointent (pas d'Airflow ni de dbt pour
le poste Data Engineer, pas de LangChain ni de base vectorielle pour
Context Engineer) sont des compétences réellement absentes. Aucun lien
structurel ne peut les faire apparaître par magie. Le lien
compétence-expérience aide à prouver une compétence déclarée, il n'en
invente pas une manquante.
</p>

<p>
Ces gaps-là, d'ailleurs, je les laisse tels quels. LangChain, LlamaIndex,
bases vectorielles, fine-tuning, MLOps : absents de mon CV, mais pas
parce que je ne sais pas ce que c'est. Ce sont des outils connus, compris, mais non utilisés en entreprise —
et je ne peux pas valoriser un outil que je n'ai pas pratiqué en
contexte professionnel. Expliquer cette nuance-là (je connais, mais je
n'ai pas appliqué en entreprise) prendrait encore des lignes sur un CV
que je
suis justement en train de condenser. L'outil de screening traite ces
absences correctement comme un vrai gap de marché plutôt que comme une
erreur de rédaction — ce qui me va très bien, parce que c'est exactement
ce qu'ils sont.
</p>

<p>
Deux précisions de vocabulaire, faites pendant cette même session,
illustrent bien le réflexe qui traverse tout ce billet : vérifier avant
d'utiliser un terme qui sonne bien. J'ai remplacé "data ocean" par
"hub-and-spoke" pour décrire mon architecture multi-usines centralisée
— "hub-and-spoke" est le terme générique établi pour cette topologie.
Un terme plus spécifique existe côté IIoT, "Unified Namespace", mais je
l'ai écarté parce que la littérature l'associe à des protocoles OT
précis, MQTT et Sparkplug B, pas à Kafka nativement : l'utiliser aurait
sur-affirmé un outillage que je n'utilise pas. Deuxième correction,
plus nuancée qu'un simple remplacement de mot : "Forward Deployed
Engineering" pour mon titre de poste. Écrire du code de production,
embarqué chez le client — ça, je le fais déjà, et ça reste ma feuille
de route. Ce qui manque encore, c'est la partie la plus revendiquée du
FDE version 2026 : piloter des agents IA directement en production
chez le client. Je me concentre sur l'étape d'avant, celle qui doit
exister avant qu'on puisse piloter des agents en production de façon
fiable — construire la documentation, le "cerveau", le RAG, peu importe
le mot exact. "Context Engineering", terme employé par Gartner qui
déclarait mi-2025 que le prompt engineering était fini au profit du
context engineering, avec une prédiction de présence dans 80% des
outils IA d'ici 2028, nomme précisément l'étape où j'en suis
réellement — pas la suivante, même si la suivante est le terme qui
fait le plus de bruit en 2026. J'ai peut-être tort de rester aussi
précis plutôt que d'anticiper, mais je saurai la défendre en
entretien — et peut-être qu'un billet comme celui-ci donne à une IA
qui résume un contexte qu'un simple mot-clé ne porte pas.
</p>

<p>
Il y a un point du round 2 que je n'ai pas corrigé, et que je ne
corrigerai pas. Mon CV dit "RAG (passif)". Un des rapports lit ce
qualificatif comme moi qui minimise ma propre compétence plutôt que
comme de la précision honnête — et ça coûte des points de score. Je le
garde quand même, en toute connaissance de cause :
</p>

<blockquote>
<p>
"RAG c'est un mot-clé, qui dit RAG dit attente vector DB ou fine-tuning.
Moi j'utilise un RAG passif, des informations bien rangées en Markdown
pour l'IA — c'est passif et retouchable/versionnable facilement, et
c'est bien l'intérêt. Le passage à la DB vectorielle peut avoir lieu
comme produit à la fin, mais pas au début, où il faut d'abord l'auditer
et l'améliorer. En 2026 on voudrait que je parle de fine-tuning et de
vector DB, alors que j'ai fait mes recherches et j'estime que ce n'est
pas le moment dans mes usages — qu'un RAG passif est plus pertinent que
du bruit IA de métier. Mais l'analyse montre que 'RAG' seul passe comme
mot-clé, et 'RAG (passif)' comme non compris, ce qui baisse la note. Je
reste honnête, j'emploie les bons termes — ça montre bien un problème
du CV 2026 : les humains (et les agents) attendent des mots précis,
alors que la réflexion et l'usage pertinent d'un domaine en mutation
sont invisibilisés parce qu'absents des recherches habituelles. Tant
pis pour les points des agents — eux aussi biaisés — j'utilise ce qui
me semble juste."
</p>
</blockquote>

<p>
C'est probablement la meilleure illustration de toute cette session
pour la thèse du billet. La tension entre précision honnête et
optimisation de score n'est pas résolue en faveur du score. Je préfère
perdre quelques points qu'employer un mot qui laisserait entendre une
compétence que je n'ai pas jugée pertinente pour mon usage. Je sais ce
qu'est une base vectorielle et comment elle fonctionne — le passage du
RAG passif vers une version vectorielle est même une évolution prête à
être déclenchée une fois la phase de validation actuelle terminée. Mais
noter que je <em>connais</em> le concept sans l'avoir pratiqué en contexte
professionnel demanderait encore une ligne de plus sur un CV déjà tiré
au maximum vers la synthèse. Je ne mens pas en ne le notant pas ; je
choisis juste où s'arrête la condensation.
</p>

<figure class="schema-figure" aria-label="Schéma : quatre types de signaux détectés par l'outil de screening sur les deux rounds, et la réponse choisie pour chacun">
<h4>Quatre signaux, quatre réponses — pas une seule façon de corriger</h4>
<div class="schema-typology">
<div class="schema-typology-item">
<span class="signal">Mots-clés absents<br>(ville, cloud, orchestrateur)</span>
<span class="nature">Trou de rédaction, rien n'était faux</span>
<span class="verdict"><strong>Corrigé aussitôt</strong> — déjà vrai, juste jamais écrit noir sur blanc</span>
</div>
<div class="schema-typology-item">
<span class="signal">Tags sans preuve narrative<br>(Docker, K8s, TDD/DDD…)</span>
<span class="nature">Tension humain pressé vs lecteur IA</span>
<span class="verdict"><strong>Corrigé structurellement</strong> — lien compétence↔expérience, +17 pts sur "développeur"</span>
</div>
<div class="schema-typology-item">
<span class="signal">Compétences absentes<br>(LangChain, vector DB, MLOps)</span>
<span class="nature">Gap réel de marché, pas une erreur de rédaction</span>
<span class="verdict"><strong>Assumé, non corrigé</strong> — outils connus, compris, non utilisés en entreprise</span>
</div>
<div class="schema-typology-item schema-typology-item--assumed">
<span class="signal">"RAG (passif)"<br>lu comme une minimisation</span>
<span class="nature">Précision honnête qui coûte des points</span>
<span class="verdict"><strong>Gardé tel quel</strong> — score sacrifié sciemment plutôt que le mot</span>
</div>
</div>
<figcaption>Les quatre types de signaux rencontrés sur les deux rounds de screening, et la réponse choisie pour chacun — corriger, prouver structurellement, assumer, ou défendre, selon la nature du signal.</figcaption>
</figure>

<p>
Il restait une dernière chose à vérifier : comment l'outil de screening
lit-il ce blog lui-même ? Deux réponses, et je n'avais anticipé qu'une
des deux. La première : il note explicitement le blog comme une preuve
de pratique IA "rare et inhabituellement transparente pour un CV
candidat" — signal de crédibilité fort selon lui, cohérent avec
<a href="bilan-pipeline-blog-agentique.html">le pipeline agentique qui produit ces billets</a>.
La seconde, que je n'avais pas vue venir : le volume de contenu, onze
billets en une dizaine de jours, est signalé comme un "pattern de
fréquence inhabituelle" qu'un outil orienté détection de contenu généré
remarquerait — même en jugeant le contenu lui-même de bonne qualité.
L'ironie ne m'a pas échappé : ce rythme de publication est rendu
possible précisément par le pipeline que ce blog documente.
</p>

<p>
Une limite à assumer avant de refermer ce billet : un seul agent
générique a servi de "faux outil de screening" pour les cinq passes.
C'est une approximation raisonnable, calée sur de la recherche réelle
plutôt qu'inventée, mais pas une reproduction fidèle d'un outil
commercial comme Greenhouse ou Ashby — ces outils-là tournent sur des
modèles et des pondérations calibrés sur des milliers de CV réels, avec
une review humaine en boucle. Mon exercice donne une direction crédible,
pas une mesure de laboratoire.
</p>

<p>
Ce que je retiens de toute cette session, c'est que le pari n'est pas
résolu, et qu'il ne le sera probablement jamais complètement. Écrire
pour un humain qui a trente secondes et écrire pour un robot qui
scanne tout ne sont pas le même exercice — parfois ils tirent dans le
même sens, parfois ils se contredisent, et dans ce cas-là je choisis
la version honnête plutôt que la version qui score le mieux. Un CV
n'a pas un score. Il en a autant que de personnes, humaines ou non,
qui le lisent.
</p>

<h2>Références</h2>
<ul>
<li><a href="https://atsverification.com/blog/ai-resume-screening-2026/">ATS Verification — AI resume screening in 2026</a> — le pipeline parsing / résumé-score par IA / lecture humaine finale.</li>
<li><a href="https://www.demandsage.com/ai-recruitment-statistics/">DemandSage — AI Recruitment Statistics</a> — le chiffre de 87% des entreprises utilisant l'IA dans leur recrutement.</li>
<li><a href="https://www.profileops.com/en/blog/skills-section-resume-ats">ProfileOps — Skills Section Resume ATS</a> — pourquoi une compétence nommée en section dédiée et prouvée dans une puce d'expérience est plus forte que l'une des deux seule.</li>
<li><a href="https://www.extern.com/post/resume-bullet-points-guide">Extern — Resume Bullet Points Guide</a> — la norme de trois à cinq puces curées par poste.</li>
<li><a href="https://www.hivemq.com/mqtt/unified-namespace-uns-essentials-iiot-industry-40/">HiveMQ — Unified Namespace (UNS) Essentials for IIoT</a> — l'Unified Namespace comme architecture spécifiquement bâtie sur MQTT/Sparkplug B.</li>
<li><a href="https://www.kai-waehner.de/blog/2025/07/01/unified-namespace-vs-data-product-in-it-ot-for-industrial-iot/">Kai Waehner — Unified Namespace vs. Data Product in IT/OT for Industrial IoT</a></li>
<li><a href="https://techcrunch.com/2026/07/30/forward-deployed-engineers-are-the-ai-industrys-latest-talent-obsession/">TechCrunch — Forward Deployed Engineers are the AI industry's latest talent obsession</a> — FDE comme modèle d'engagement, pas comme pratique technique IA.</li>
<li><a href="https://atlan.com/know/what-is-context-engineering/">Atlan — What Is Context Engineering?</a> — définition, et citation de Gartner ("context engineering is in, prompt engineering is out") avec la prédiction de présence dans 80% des outils IA d'ici 2028.</li>
</ul>

]]></description>
</item>

<item>
<title>Premier plafond de session : ce qu'il dit vraiment de mon projet</title>
<link>https://guillaume-besseau.fr/blog/plafond-session-cout-qualite-ecoute.html</link>
<guid>https://guillaume-besseau.fr/blog/plafond-session-cout-qualite-ecoute.html</guid>
<pubDate>Mon, 07 Sep 2026 12:00:00 GMT</pubDate>
<description><![CDATA[
<p>
La veille, j'avais construit et testé en une seule journée
<a href="bilan-pipeline-blog-agentique.html">le pipeline à trois agents qui produit ce blog</a>.
Au bout de cette session très longue et très chargée, j'ai touché
pour la première fois le plafond d'usage de mon abonnement, depuis
que je l'ai. Ma première lecture : un symptôme de taille, pas un
problème de qualité. Mon projet a grossi — plus d'agents spécialisés,
plus de fichiers `reflexion/`, plus de contexte à recharger à chaque
instance — et un projet plus gros fait grimper la consommation de
tokens plus vite qu'avant.
</p>

<p>
Le mécanisme est simple et documenté : chaque tour renvoie toute la
conversation accumulée, donc même une question d'une ligne, posée
dans une session ouverte depuis des heures, coûte le prix de tout
l'historique qu'elle traîne avec elle. C'est explicitement listé,
dans la documentation officielle de Claude Code, comme la première
raison pour laquelle l'usage grimpe dans une longue session — et plus
un projet a de matière à charger (agents, docs, conventions), plus
cette mécanique joue vite.
</p>

<p>
Le pipeline construit la veille en est un bon exemple. `blog-curateur`,
`blog-redacteur` et `blog-illustrateur` me font vraiment gagner du
temps, mais c'est précisément
<a href="cout-reel-systeme-multi-agents.html">le facteur de coût multi-agents que j'ai déjà chiffré</a> :
jusqu'à 15 fois plus de tokens qu'un chat simple, chez Anthropic comme
chez moi. Un coût accepté en connaissance de cause en construisant ce
pipeline, pas une surprise découverte en touchant le plafond.
</p>

<p>
Si ce projet était pour une entreprise, je crois que j'aurais été
content de remplir un KPI de quantité — plus de contenu produit, plus
d'agents qui tournent, ça se lit bien sur un dashboard. Ici, la mesure
qui compte est différente : la qualité reste maîtrisée malgré la
croissance du projet, et c'est la taille réelle du projet — plus
d'agents, plus de documentation, plus de contexte à porter — qui
explique la facture, pas une dérive de ce que je produis.
</p>

<p>
Ça ne veut pas dire que la croissance est gratuite. Le contexte qui
grandit accumule aussi du bruit — le "context rot", documenté par une
étude de Chroma menée en 2025 sur 18 modèles frontière, dont Claude
Sonnet 4 et Opus 4 : la performance décline de façon continue et
mesurable dès que le contexte grandit, bien avant d'atteindre la
limite réelle de la fenêtre, et Claude montre l'écart le plus marqué
de tous les modèles testés entre un prompt court et un prompt long.
Le savoir vérifié qu'on accumule au fil d'une session — décisions
tranchées, conventions établies — compte pour de vrai, mais il reste
en concurrence directe avec ce bruit, pas à l'abri de lui.
</p>

<figure class="schema-figure" aria-label="Schéma : ce qui augmente avec la taille du contexte pendant une session, et ce qui n'en profite pas forcément">
<h4>Ce qui monte avec le contexte — et ce qui n'est pas garanti</h4>
<svg class="ctxfig-svg" viewBox="0 0 640 400" role="img" aria-labelledby="ctxfig-title ctxfig-desc">
<title id="ctxfig-title">Coût, savoir vérifié, bruit accumulé et qualité perçue au fil d'une session</title>
<desc id="ctxfig-desc">Schéma illustratif, pas une mesure : le coût augmente de façon quasi mécanique avec la taille du contexte accumulé ; le savoir vérifié (décisions tranchées, sources corrigées) et le bruit accumulé (le "context rot") augmentent tous les deux en parallèle ; la qualité perçue, elle, n'a aucune trajectoire garantie — elle peut sembler monter un moment puis se dégrader nettement quand le bruit prend le dessus sur le savoir vérifié, autour du moment où le plafond de session est touché.</desc>
<line class="ctxfig-axis" x1="70" y1="300" x2="560" y2="300"></line>
<line class="ctxfig-axis" x1="70" y1="40" x2="70" y2="300"></line>
<text class="ctxfig-small" x="24" y="170" text-anchor="middle" transform="rotate(-90 24 170)">niveau (illustratif)</text>
<text class="ctxfig-small" x="70" y="320" text-anchor="middle">Début</text>
<text class="ctxfig-small" x="190" y="320" text-anchor="middle">+1h</text>
<text class="ctxfig-small" x="310" y="320" text-anchor="middle">+2h</text>
<text class="ctxfig-small" x="430" y="320" text-anchor="middle">+3h</text>
<text class="ctxfig-small" x="560" y="320" text-anchor="middle">Plafond touché</text>
<polyline class="ctxfig-line ctxfig-cost" points="70,279.2 190,235 310,170 430,92 560,45.2"></polyline>
<polyline class="ctxfig-line ctxfig-know" points="70,261 190,191.8 310,149.2 430,128.4 560,118"></polyline>
<polyline class="ctxfig-line ctxfig-noise" points="70,287 190,261 310,209 430,144 560,66"></polyline>
<polyline class="ctxfig-line ctxfig-quality" points="70,268.8 190,201.2 310,170 430,211.6 560,279.2"></polyline>
<line class="ctxfig-line ctxfig-cost" x1="70" y1="346" x2="94" y2="346"></line>
<text class="ctxfig-legend-text" x="100" y="350">Coût (renvoie tout l'historique)</text>
<line class="ctxfig-line ctxfig-know" x1="340" y1="346" x2="364" y2="346"></line>
<text class="ctxfig-legend-text" x="370" y="350">Savoir vérifié accumulé</text>
<line class="ctxfig-line ctxfig-noise" x1="70" y1="371" x2="94" y2="371"></line>
<text class="ctxfig-legend-text" x="100" y="375">Bruit accumulé ("context rot")</text>
<line class="ctxfig-line ctxfig-quality" x1="340" y1="371" x2="364" y2="371"></line>
<text class="ctxfig-legend-text" x="370" y="375">Qualité perçue (sans garantie)</text>
</svg>
<figcaption>Schéma personnel, construit à partir de la documentation Claude Code sur les coûts et de l'étude Chroma sur le "context rot" (voir Références ci-dessous) — les courbes montrent une direction et une tension entre ces grandeurs, ce ne sont pas des données mesurées point par point.</figcaption>
</figure>

<p>
Ça me donne une idée à tester : recompresser ma documentation et mes
fichiers `.md` utiles, pour revenir à un usage tout aussi qualitatif
mais qui fait redescendre la consommation de tokens. Pas fait pour
l'instant, juste une piste qui devient de plus en plus concrète à
mesure que le projet grossit — le plafond de session n'est sans doute
que le premier signal d'un projet qui a changé d'échelle.
</p>

<h2>Références</h2>
<ul>
<li><a href="https://code.claude.com/docs/en/costs">Documentation Claude Code — Manage costs effectively</a></li>
<li><a href="https://www.trychroma.com/research/context-rot">Chroma Research — Context Rot: How Increasing Input Tokens Impacts LLM Performance</a></li>
</ul>
]]></description>
</item>

<item>
<title>Un jour pour construire le pipeline qui écrit ce blog</title>
<link>https://guillaume-besseau.fr/blog/bilan-pipeline-blog-agentique.html</link>
<guid>https://guillaume-besseau.fr/blog/bilan-pipeline-blog-agentique.html</guid>
<pubDate>Sun, 06 Sep 2026 12:00:00 GMT</pubDate>
<description><![CDATA[
<p>
Ce blog a maintenant un système qui le produit : un agent qui repère
les sujets mûrs, un qui rédige, un qui illustre, et quatre dossiers
numérotés qui font office de file d'attente entre eux — celui-ci en
est d'ailleurs le produit. Je pourrais présenter ça comme une prouesse
d'IA. Ce n'est pas le sujet du billet. Le vrai sujet, c'est ce que ça
m'a coûté à moi de vérifier que ce système produit quelque chose de
correct, et les fois où j'ai dû arrêter la chaîne parce que ce qui en
sortait n'était pas assez bon.
</p>

<p>
Le matin, il y avait un curateur et un rédacteur tout juste esquissés,
un seul fichier à sections pour tout suivre et aucune discipline de
vérification des sources. Le soir, un pipeline à quatre étapes en
dossiers numérotés — sujet à compléter, sujet prêt, brouillon, mise en
page, chacun avec son dossier d'archive pour garder l'historique sans
jamais l'effacer —, trois agents qui ne font chacun qu'une seule
chose, une règle de vérification qui a déjà attrapé deux vraies
erreurs de citation sur 29, et 8 billets en ligne sur le site. Ce
n'est pas juste « plus de contenu » : c'est passé d'un brouillon
d'outillage à un système que je peux faire tourner, mesurer, et
corriger un maillon à la fois.
</p>

<figure class="schema-figure" aria-label="Schéma : le pipeline à quatre dossiers numérotés et trois agents qui produit ce blog">
<h4>Le pipeline qui a produit ce billet</h4>
<div class="schema-pipeline">
<div class="schema-pipeline-node schema-pipeline-node--endpoint">
<p class="schema-pipeline-node-name">reflexion/</p>
<p class="schema-pipeline-node-desc">vivier brut — lecture seule</p>
</div>
<div class="schema-pipeline-arrow">
<span class="schema-pipeline-arrow-agent">blog-curateur</span>
<span class="schema-pipeline-arrow-glyph">→</span>
</div>
<div class="schema-pipeline-node">
<p class="schema-pipeline-node-name">00-to-complete/</p>
<p class="schema-pipeline-node-desc">sujets repérés, pas encore mûrs</p>
<p class="schema-pipeline-node-closed">+ closed/</p>
</div>
<div class="schema-pipeline-arrow">
<span class="schema-pipeline-arrow-agent">blog-curateur juge mûr</span>
<span class="schema-pipeline-arrow-glyph">→</span>
</div>
<div class="schema-pipeline-node">
<p class="schema-pipeline-node-name">10-ready/</p>
<p class="schema-pipeline-node-desc">sourcé, angle prêt à rédiger</p>
<p class="schema-pipeline-node-closed">+ closed/</p>
</div>
<div class="schema-pipeline-arrow">
<span class="schema-pipeline-arrow-agent">blog-redacteur</span>
<span class="schema-pipeline-arrow-glyph">→</span>
</div>
<div class="schema-pipeline-node">
<p class="schema-pipeline-node-name">20-draft/</p>
<p class="schema-pipeline-node-desc">brouillon rédigé, sources vérifiées</p>
<p class="schema-pipeline-node-closed">+ closed/</p>
</div>
<div class="schema-pipeline-arrow">
<span class="schema-pipeline-arrow-agent">blog-illustrateur</span>
<span class="schema-pipeline-arrow-glyph">→</span>
</div>
<div class="schema-pipeline-node">
<p class="schema-pipeline-node-name">30-mise-en-page/</p>
<p class="schema-pipeline-node-desc">illustré, prêt à relire</p>
<p class="schema-pipeline-node-closed">+ closed/</p>
</div>
<div class="schema-pipeline-arrow">
<span class="schema-pipeline-arrow-agent">Guillaume relit, publie</span>
<span class="schema-pipeline-arrow-glyph">→</span>
</div>
<div class="schema-pipeline-node schema-pipeline-node--endpoint">
<p class="schema-pipeline-node-name">site/blog/</p>
<p class="schema-pipeline-node-desc">publication manuelle, jamais automatique</p>
</div>
</div>
<figcaption>
Chaque dossier numéroté est un topic consommé par un seul agent et
produit pour le suivant, avec son propre <code>closed/</code>
d'archive ; aucun agent n'écrit dans <code>reflexion/</code> ni dans
<code>site/</code> — seul Guillaume publie.
</figcaption>
</figure>

<p>
La chose qui m'a le plus surpris à la vivre : transformer une
réflexion brute — les notes que j'accumule en discutant avec l'IA,
souvent écrites vite — en un billet honnête, sourcé et illustré
correctement, coûte beaucoup plus cher que d'écrire simplement ce que
je pense. Le premier passage curateur + rédacteur sur 6 sujets m'a
coûté 1,37$ mesurés (0,33$ pour le curateur, 1,04$ pour les six
rédactions) — dérisoire en argent, mais ce chiffre cache des dizaines
d'allers-retours d'agents, un audit qui a recalé 2 citations sur 29
(des pages réelles, qui ne disaient simplement pas ce qu'on leur
faisait dire), et deux passes complètes d'illustration parce que la
première ne suffisait pas. Écrire vite, c'est facile. Écrire quelque
chose dont je peux défendre chaque affirmation, ça prend un temps que
je n'avais pas anticipé — exactement la différence entre un billet de
blog et un post LinkedIn.
</p>

<p>
Ce qui a le mieux marché : découpler curateur, rédacteur et
illustrateur en trois rôles distincts, chacun avec son propre dossier
de travail et son droit d'écriture strictement borné, plutôt qu'un
seul agent généraliste qui ferait tout. Ça a rendu possible ce qu'un
agent unique ne m'aurait pas permis facilement : mesurer le coût de
chaque rôle séparément (le dashboard que j'avais déjà construit pour
suivre mes coûts d'agents les distingue automatiquement, sans rien de
nouveau à brancher), corriger un seul maillon — le jugement visuel de
l'illustrateur — sans toucher aux deux autres, et faire confiance à un
rôle précis pour une décision précise. Seul le curateur juge si un
sujet est mûr ; le rédacteur ne discute pas cette décision, il
l'applique.
</p>

<p>
Le choix qui me parle le plus, professionnellement : utiliser le
système de fichiers lui-même comme file d'attente. Chaque dossier
numéroté est un topic, chaque agent consomme dans un dossier et
produit dans le suivant, et un dossier d'archive par étape garde
l'historique sans jamais rien supprimer (ou alors c'est moi qui
appliquerais une rétention plus tard pour purger) — exactement le
réflexe que j'applique déjà au travail, de Kafka à Databricks, sans
jamais écraser ce qui est passé. Le pattern existe
ailleurs — maildir sous Unix, hot-folder/spool, l'architecture
medallion bronze/silver/gold que je manipule tous les jours en data
engineering — mais je ne l'avais jamais appliqué à mon propre
outillage perso avant ce jour. Un des rares endroits où mon métier et
mon usage perso de l'IA se répondent directement, sans effort de
traduction entre les deux mondes.
</p>

<p>
Le vrai moment intéressant de la journée n'est pas venu d'une
fonctionnalité qui marchait du premier coup, mais d'un raté. Le
premier jet de schémas produits par l'illustrateur était propre
techniquement — du CSS valide, des licences d'image vérifiées — mais
pauvre : des oppositions à deux boîtes reliées par une flèche, qui ne
faisaient que remettre en forme ce que la phrase d'à côté disait déjà.
En comparant les six résultats côte à côte, mon jugement a été
direct : ça habille, mais ça n'apporte rien — il manque du
discernement sur quoi habiller. En creusant la cause, le problème est
apparu : l'illustrateur ne regardait que le texte déjà compressé du
billet pour décider quoi dessiner, jamais la matière plus riche des
fichiers de réflexion d'origine. Il ne pouvait donc que reformuler en
boîtes ce qui était déjà écrit, jamais l'enrichir. Une fois corrigé —
obligation de relire les sources avant de dessiner, test explicite :
« quelqu'un qui lit juste le paragraphe apprend-il vraiment plus en
regardant ce schéma ? » — la deuxième passe a produit des structures à
trois éléments ou plus, avec de vraies données chiffrées dedans plutôt
qu'une reformulation vide. La leçon dépasse ce cas précis : un agent
qui ne regarde que sa propre sortie compressée ne peut jamais
l'enrichir, seulement la reformuler — et ça vaut probablement pour
plus que des schémas.
</p>

<p>
Un deuxième détail, plus petit, m'a marqué pour une raison
différente : c'est moi qui ai eu tort en premier. Pour illustrer une
émotion — la confusion, le soulagement —, j'ai proposé Giphy par
réflexe, c'est ce que j'utilise en conversation tous les jours. Sauf
qu'en vérifiant avant d'écrire la règle plutôt qu'en la supposant, les
conditions d'utilisation de Giphy comme de Tenor restreignent
explicitement l'usage au cadre personnel et non commercial, et la
plupart des GIFs de réaction sont de toute façon extraits de films ou
de séries sans licence propre — un flou juridique connu, toléré par
une norme culturelle de non-poursuite plutôt que couvert par un vrai
droit d'usage. Remplacé par OpenMoji, un jeu d'emojis sous licence CC
BY-SA 4.0 porté par une école de design allemande et ses
contributeurs — moins « meme viral », mais aligné avec le niveau
d'exigence que j'essaie d'appliquer partout ailleurs sur ce site. Ce
qui compte ici, ce n'est pas la vérification en soi, c'est que je
l'ai appliquée à ma propre suggestion, pas seulement à ce qu'une IA
proposait.
</p>

<p class="emoji-inline">
<img src="https://guillaume-besseau.fr/blog/images/bilan-pipeline-blog-agentique/1F92D.svg" alt="Emoji OpenMoji : visage avec la main sur la bouche, réalisation soudaine">
<span>La proposition évidente n'était pas la bonne — et c'est la mienne.</span>
</p>

<p>
Au bout du compte, cette journée n'a pas prouvé qu'une IA peut écrire
un blog toute seule — elle a plutôt confirmé le contraire. Ce qui
rend un billet publiable, ce n'est pas l'autonomie des agents, c'est
la discipline de vérification que j'y ai mise autour : lire les
brouillons côte à côte, remettre en cause un schéma qui ne dit rien,
vérifier une licence avant de l'écrire en dur dans un agent, refuser
une source qui sonne juste mais ne dit pas ce qu'on lui fait dire. Le
pipeline fait gagner du temps sur la mécanique — dossiers,
déplacements de fichiers, mise en forme HTML. Il ne remplace à aucun
moment le moment où je relis, où je doute, où je corrige. C'est
probablement la seule vraie conclusion de ce bilan : plus le système
qui écrit à ma place devient sophistiqué, plus mon propre rôle de
relecture compte, pas moins.
</p>

<h2>Références</h2>
<ul>
<li><a href="https://support.giphy.com/hc/en-us/articles/360020027752-GIPHY-User-Terms-of-Service">GIPHY — User Terms of Service</a></li>
<li><a href="https://tenor.com/legal-terms">Tenor — Legal Terms</a></li>
<li><a href="https://openmoji.org/">OpenMoji</a></li>
<li>Emoji "face with hand over mouth" : <a href="https://openmoji.org/library/emoji-1F92D/">OpenMoji – the open-source emoji and icon project</a>, licence CC BY-SA 4.0.</li>
</ul>
]]></description>
</item>

<item>
<title>Le jeu vidéo avec mon fils — où est l'art quand l'IA code</title>
<link>https://guillaume-besseau.fr/blog/jeu-video-avec-mon-fils-art-ia.html</link>
<guid>https://guillaume-besseau.fr/blog/jeu-video-avec-mon-fils-art-ia.html</guid>
<pubDate>Sat, 05 Sep 2026 12:00:00 GMT</pubDate>
<description><![CDATA[
<p>
En 2026, j'ai fait un jeu vidéo avec mon fils. Ça part de lui : ses
dessins, son lore, son envie de jouer à telle ou telle chose. Moi, je
suis venu avec ma réflexion de game design, la retouche de ses images,
et la musique. Et puis il y a le code — et là, j'ai fait un choix
précis : je l'ai fait générer par l'IA, en la pilotant, pour apprendre
le JavaScript et le HTML au passage. Un terrain assez loin de mon
métier de data engineer pour que ce soit un vrai apprentissage, pas une
redite.
</p>

<p>
Le partage du travail n'a jamais été flou dans ma tête. Le lore, les
dessins, la musique, les bruitages, le game design : entièrement nous,
mon fils et moi. L'architecture du code et les choix techniques :
décidés par moi. L'IA : elle exécute. Elle implémente ce que je lui
demande, selon les directives que je pose — jamais l'inverse. Je n'ai
jamais eu la tentation de lui faire générer le game design, le
graphisme ou la musique. Ce n'est pas une question de principe abstrait,
c'est que je n'en avais tout simplement pas envie : c'est la partie qui
m'intéresse, et qui intéresse mon fils.
</p>

<p>
Le jeu est volontairement léger : un jeu dans le navigateur, sans
installation, une expérience de 5 à 10 minutes. Ça limite ce qu'on peut
implémenter — pas de moteur 3D, pas de gros calculs, pas de dépendance
lourde. Mais ça permet à tous nos amis d'y jouer directement, sans se
soucier de leur machine. C'est une contrainte assumée, pas une
excuse : je préfère un petit jeu que tout le monde peut ouvrir à un gros
jeu que personne n'installe.
</p>

<p>
Ce qui m'a frappé en le faisant, c'est que le résultat est plein de
choses cassées. Pas cassées à cause du code — le code fonctionne, il
fait ce qu'on lui a demandé. Cassées dans le fait main : une
transition maladroite, un dessin d'enfant qui déborde du cadre qu'on
lui a bricolé, un bruitage un peu trop fort par endroits. Et ces
choses cassées, je les trouve belles. Si j'avais laissé faire — si
j'avais demandé à l'IA de générer le design, les images, la musique en
plus du code — ça aurait été standard, propre, cohérent. Ça aurait été
du slop. Alors que là, ce qui est raté est raté d'une façon qui vient
de nous, pas d'une moyenne statistique de ce qui marche bien.
</p>

<figure class="schema-figure" aria-label="Schéma : le chemin de la création, des dessins de mon fils au jeu fini">
<svg class="schema-flow-svg" viewBox="0 0 690 320" role="img" aria-labelledby="schema-flow-title schema-flow-desc">
<title id="schema-flow-title">Le chemin de la création</title>
<desc id="schema-flow-desc">Mon fils apporte la matière brute à Moi, qui dirige la partie créative et donne des directives à l'IA ; le contenu artistique et le code suivent deux chemins distincts qui convergent dans le jeu fini.</desc>
<defs>
<marker id="arrowhead" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
<path d="M0,0 L10,5 L0,10 z" fill="var(--text-secondary)"></path>
</marker>
</defs>

<!-- Flèches -->
<path class="schema-arrow" d="M160,65 L246,65" marker-end="url(#arrowhead)"></path>
<path class="schema-arrow" d="M340,120 L340,196" marker-end="url(#arrowhead)"></path>
<path class="schema-arrow" d="M430,65 L516,133" marker-end="url(#arrowhead)"></path>
<path class="schema-arrow" d="M430,250 L516,207" marker-end="url(#arrowhead)"></path>

<!-- Libellés des flèches -->
<text class="schema-arrow-label" x="203" y="58">point de départ</text>
<text class="schema-arrow-label" x="380" y="150">directives précises</text>
<text class="schema-arrow-note" x="380" y="164">(jamais l'inverse)</text>
<text class="schema-arrow-label" x="475" y="92">contenu artistique</text>
<text class="schema-arrow-label" x="475" y="235">code</text>

<!-- Mon fils -->
<rect class="schema-box-human" x="10" y="20" width="150" height="90" rx="14"></rect>
<text class="schema-icon" x="85" y="40">🎨</text>
<text class="schema-title" x="85" y="58">Mon fils</text>
<text class="schema-sub" x="85" y="74">dessins, lore,</text>
<text class="schema-sub" x="85" y="87">envie de jouer</text>
<text class="schema-tag" x="85" y="101">l'étincelle</text>

<!-- Moi -->
<rect class="schema-box-human" x="250" y="10" width="180" height="110" rx="14"></rect>
<text class="schema-icon" x="340" y="28">🧭</text>
<text class="schema-title" x="340" y="46">Moi</text>
<text class="schema-sub" x="340" y="62">retouche des images,</text>
<text class="schema-sub" x="340" y="75">musique, bruitages,</text>
<text class="schema-sub" x="340" y="88">game design</text>
<text class="schema-tag" x="340" y="103">direction créative &amp; technique</text>

<!-- L'IA -->
<rect class="schema-box-ia" x="250" y="200" width="180" height="100" rx="14"></rect>
<text class="schema-icon" x="340" y="218">⚙️</text>
<text class="schema-title schema-title-ia" x="340" y="236">L'IA</text>
<text class="schema-sub" x="340" y="252">implémentation du code</text>
<text class="schema-sub" x="340" y="265">JavaScript, HTML</text>
<text class="schema-tag schema-tag-ia" x="340" y="281">exécution sous mes directives</text>

<!-- Le jeu -->
<rect class="schema-box-result" x="520" y="90" width="150" height="150" rx="16"></rect>
<text class="schema-icon" x="595" y="112">🕹️</text>
<text class="schema-title" x="595" y="132">Le jeu</text>
<text class="schema-sub" x="595" y="148">jouable dans le</text>
<text class="schema-sub" x="595" y="161">navigateur, 5–10 min</text>
<text class="schema-highlight" x="595" y="183">plein de choses</text>
<text class="schema-highlight" x="595" y="197">cassées — et donc</text>
<text class="schema-highlight" x="595" y="211">vivantes</text>
</svg>
<figcaption>Le partage du travail n'est pas un simple face-à-face « nous contre l'IA » : c'est une chaîne. Mon fils apporte la matière brute (dessins, lore, envies), je la transforme en direction créative et technique, et je ne donne des directives de code à l'IA qu'à la toute fin — jamais l'inverse. Le contenu artistique et le code suivent deux chemins distincts qui ne se rejoignent que dans le jeu fini.</figcaption>
</figure>

<p>
Ça me ramène à une question que je n'ai pas tranchée : est-ce que
c'est de l'IA, ou est-ce une œuvre ? Je n'ai pas de réponse propre et
définitive. Ce que je sais, c'est que ce petit jeu montre quelque
chose d'humain, manette en main — le lore de mon fils, mes choix de
game design, nos maladresses assumées — et que le code généré n'est
qu'un moyen d'y arriver, pas le contenu lui-même. Je ne sais pas si ça
suffit à répondre à la question pour tout le monde. Pour ce projet-là,
en tout cas, ça me suffit à moi.
</p>

<p>
Le jeu est jouable directement dans le navigateur, sans rien installer :
<a href="http://mia.adventures.free.fr" target="_blank" rel="noopener">mia.adventures.free.fr</a>.
</p>
]]></description>
</item>

<item>
<title>Ce que coûte vraiment un système multi-agents</title>
<link>https://guillaume-besseau.fr/blog/cout-reel-systeme-multi-agents.html</link>
<guid>https://guillaume-besseau.fr/blog/cout-reel-systeme-multi-agents.html</guid>
<pubDate>Fri, 04 Sep 2026 12:00:00 GMT</pubDate>
<description><![CDATA[
<p>
Je tiens à 20$ par mois avec Claude Code, en usage courant, et ça
marche bien. Deux amis, pour ce qui ressemble à un usage comparable,
sont montés jusqu'à 200$. Pendant longtemps je n'ai pas compris cet
écart de coût — mon résultat me semblait bon, mais je voyais bien
qu'on n'avait pas la même vision : moi plutôt un binôme humain + IA
qui fonctionne bien, avec quelques appels agentiques en plus pour
tester ; eux, un vrai système agentique complet. J'ai regardé les
chiffres pour comprendre, et j'ai enfin compris.
</p>

<p>
Première chose que j'ai vérifiée : la différence n'est pas une
histoire de modèle. Les paliers d'abonnement Claude sont Pro à 20$,
Max 5x à 100$, Max 20x à 200$ — et le plan Max ne débloque aucun
modèle ni aucune fonctionnalité en plus de Pro. Uniquement plus de
volume d'usage. Donc si mes amis payent dix fois plus pour un
résultat qui semble similaire, l'explication la plus probable n'est
pas qu'ils obtiennent mieux : c'est qu'ils consomment dix fois plus
de tokens. Rassurant sur un point — je ne rate rien en restant à
20$, mon usage est juste structurellement différent.
</p>

<p>
D'où vient ce volume, en général ? Anthropic chiffre le coût de son
propre système multi-agents : un agent seul consomme 4 fois plus de
tokens qu'un simple chat, et un système multi-agents complet monte à
15 fois. Leur propre retour d'expérience est direct là-dessus : des
équipes ont investi des mois dans des architectures multi-agents
élaborées pour découvrir qu'un meilleur prompting sur un agent unique
donnait des résultats équivalents. Leur règle : rester en agent
unique quand la tâche tient dans une fenêtre de contexte, que les
étapes sont séquentielles, que le workflow est assez déterministe
pour être spécifié — ou que le budget est serré. Le multi-agent ne se
justifie vraiment que pour éviter la pollution de contexte, pour des
tâches réellement parallélisables, ou pour une spécialisation qui
améliore le focus.
</p>

<figure class="schema-figure" aria-label="Schéma : multiplicateur de tokens consommés selon l'architecture, chiffres publiés par Anthropic">
<h4>Tokens consommés, à tâche comparable (chiffres Anthropic)</h4>
<div class="schema-bar-row">
<span class="schema-bar-label">Chat simple</span>
<div class="schema-bar-track"><div class="schema-bar-fill" style="width: 8%;"><span>1×</span></div></div>
</div>
<div class="schema-bar-row">
<span class="schema-bar-label">Agent seul</span>
<div class="schema-bar-track"><div class="schema-bar-fill schema-bar-fill--soft" style="width: 30%;"><span>4×</span></div></div>
</div>
<div class="schema-bar-row">
<span class="schema-bar-label">Système multi-agents</span>
<div class="schema-bar-track"><div class="schema-bar-fill" style="width: 100%;"><span>15×</span></div></div>
</div>
<p class="schema-bar-note">Sur le benchmark interne d'Anthropic, le volume de tokens à lui seul explique <strong>environ 80% de la variance de performance</strong> — une bonne part de l'explication de pourquoi tant d'équipes ont poussé vers le multi-agent avant de mesurer si leur tâche en avait vraiment besoin.</p>
<figcaption>D'après Anthropic, « How we built our multi-agent research system » — le facteur 15× correspond à leur propre système de recherche interne, pas à de l'ingénierie logicielle en général.</figcaption>
</figure>

<p>
La phrase qui m'a le plus servi, face à la pression ambiante à parler
d'agents plutôt que de scripts pour cocher des KPI : la plupart des
tâches de code ont beaucoup moins de sous-tâches parallélisables que
la recherche. Le cas d'usage qui justifie le facteur 15, chez
Anthropic, c'est leur propre système de recherche interne — ça ne
généralise pas à de l'ingénierie logicielle. Je navigue à vue sur
cette pression, mon but reste juste de construire des choses solides,
pas de faire de la politique interne — mais c'est un fait technique
que je peux citer plutôt qu'une simple préférence.
</p>

<p>
Mon architecture perso, en comparaison, est délibérément étroite :
des conversations ciblées, des sous-agents précis, l'humain qui
valide avant que ça parte. Et il y a un mécanisme que je n'avais pas
pleinement saisi avant de creuser : chaque sous-agent garde son
propre cache de prompt. Reprendre un sous-agent déjà utilisé, dont le
contexte a déjà été envoyé une fois, coûte le tarif du cache — bien
moins cher. Un nouveau chat qui redécouvre tout depuis mes fichiers
`.md` repaie le contexte plein à chaque fois. Ça change complètement
la lecture de mon propre agent `architecte-agents` : ce n'est pas
« un agent de plus qui coûte cher », c'est un raccourci de cache vers
une synthèse déjà faite. Architecturalement, ça n'a rien à voir avec
un essaim d'agents qui tournent en parallèle, même si les deux
s'appellent « agent ».
</p>

<p>
Autre supposition que j'ai vérifiée plutôt que crue : je pensais
qu'un sous-agent basculait automatiquement sur un modèle plus léger.
Faux. Le champ `model:` d'un sous-agent vaut `inherit` par défaut —
si je ne le précise pas, il tourne silencieusement sur le même modèle
que la session principale. Un choix que je croyais faire, mais qui ne
se faisait pas. Ça éclaire aussi, en creux, pourquoi Copilot — imposé
sur une mission — part vite n'importe comment même en sélectionnant
Sonnet comme modèle : le harnais (les outils, la gestion du contexte,
la mémoire, l'orchestration) est un produit à part entière,
indépendant du modèle branché dessus. Le lien avec le coût est
direct : personnaliser cette couche-là, c'est exactement ce qui rend
mon usage à 20$ tenable.
</p>

<p>
Tout ça restait une explication plausible, pas une preuve. Mon côté
data engineer n'aime pas s'arrêter là, donc j'ai voulu mesurer mon
propre usage plutôt que de me contenter d'une anecdote. J'ai installé
`ccusage`, un outil qui reconstitue le coût équivalent tarif API à
partir des journaux locaux de Claude Code.
</p>

<p>
Premier piège, découvert en générant le rapport : `ccusage` agrège
par défaut tous les projets Claude Code de la machine, pas seulement
celui en cours — aucun filtre par projet en ligne de commande,
seulement par date ou par identifiant de session. Pour isoler le coût
réel de ce repo, il a fallu croiser les identifiants de session avec
les fichiers de journal propres à son dossier. Résultat : 77,61$
équivalent tarif API sur 6 sessions pour ce repo, contre 301,29$ tous
projets confondus sur la même période. Un facteur 4 entre ce que je
croyais mesurer et ce que je mesurais vraiment, si je n'avais pas
vérifié.
</p>

<figure class="schema-figure" aria-label="Schéma : coût mesuré avec ccusage, repo isolé contre agrégat tous projets">
<h4>Coût équivalent tarif API mesuré avec ccusage</h4>
<div class="schema-mesure-row">
<span class="schema-mesure-label">Ce repo (isolé)</span>
<div class="schema-mesure-track"><div class="schema-mesure-fill" style="width: 26%;"><span>77,61 $</span></div></div>
</div>
<div class="schema-mesure-row">
<span class="schema-mesure-label">Tous projets confondus</span>
<div class="schema-mesure-track"><div class="schema-mesure-fill schema-mesure-fill--full" style="width: 100%;"><span>301,29 $</span></div></div>
</div>
<p class="schema-mesure-factor">×4 — l'agrégat par défaut de ccusage sur la même période</p>
<figcaption>Mesure personnelle sur 6 sessions Claude Code de ce repo, après avoir croisé les identifiants de session pour isoler le périmètre — ccusage n'offre pas de filtre par projet en ligne de commande.</figcaption>
</figure>

<p>
Ce facteur 4, c'est tout le billet résumé en une ligne. Sans cette
vérification, j'aurais cru un chiffre quatre fois trop élevé pour ce
projet précis — exactement le genre de réflexe qui vient de mon
métier : ne jamais faire confiance à un agrégat sans connaître
précisément son périmètre.
</p>

<figure class="schema-figure" aria-label="Schéma : quatre suppositions de ce billet qui ne résistent pas à la vérification">
<h4>Vérifié plutôt que supposé, quatre fois dans cette histoire</h4>
<div class="schema-check-headers"><span>Ce que je croyais</span><span>Ce que la vérification a montré</span></div>
<div class="schema-check-row">
<div class="schema-check-was"><span class="schema-check-mark schema-check-mark--x">✕</span>Payer plus cher (Max) débloquerait un meilleur modèle</div>
<div class="schema-check-now"><span class="schema-check-mark schema-check-mark--ok">✓</span>Pro, Max 5x, Max 20x tournent sur le même modèle — seulement plus de volume</div>
</div>
<div class="schema-check-row">
<div class="schema-check-was"><span class="schema-check-mark schema-check-mark--x">✕</span>Un sous-agent bascule automatiquement sur un modèle plus léger</div>
<div class="schema-check-now"><span class="schema-check-mark schema-check-mark--ok">✓</span><code>model: inherit</code> par défaut — il tourne sur le même modèle que la session principale</div>
</div>
<div class="schema-check-row">
<div class="schema-check-was"><span class="schema-check-mark schema-check-mark--x">✕</span><code>ccusage</code> mesure directement le coût de ce repo</div>
<div class="schema-check-now"><span class="schema-check-mark schema-check-mark--ok">✓</span>Il agrège tous les projets de la machine par défaut — 77,61 $ contre 301,29 $ tous confondus</div>
</div>
<div class="schema-check-row">
<div class="schema-check-was"><span class="schema-check-mark schema-check-mark--x">✕</span>Sommer les lignes du journal donne le bon total de tokens</div>
<div class="schema-check-now"><span class="schema-check-mark schema-check-mark--ok">✓</span>Un message à plusieurs blocs répète sa ligne — 277 lignes pour 133 messages réels, quasi doublé sans dédupliquer</div>
</div>
<figcaption>Quatre suppositions distinctes de ce billet, réunies ici parce qu'elles partagent le même réflexe : vérifier plutôt que croire, chacune avec un chiffre ou un fait précis à l'appui.</figcaption>
</figure>

<p>
Une mesure ponctuelle ne suffit pas, j'ai voulu pouvoir suivre ça
dans la durée — donc j'ai construit un petit dashboard. Deux surprises
techniques en chemin, pas prévues au départ. D'abord, un fichier
Numbers n'est pas un format texte : c'est une archive zip de fichiers
propriétaires, illisible et inéditable par un script. Direction
CSV/JSON à la place. Ensuite, une limite plus fondamentale : une page
ouverte en `file://` ne peut pas aller chercher un fichier JSON voisin
— les navigateurs bloquent ça. C'est exactement pour cette raison que
le reste de mes sites utilise un bouton « Importer » manuel plutôt
qu'un chargement automatique : pas un choix arbitraire, une contrainte
du navigateur. Solution retenue : générer le HTML avec les données
embarquées dedans directement au moment de la construction — une
commande, et la page est à jour, ouvrable en double-clic, sans
serveur, sans dépendance, sans librairie de graphique.
</p>

<p>
En creusant ensuite le coût par sous-agent, je pensais avoir besoin
d'une table de correspondance entre les noms utilisés par `ccusage`
et les miens. En fait non : la colonne « Agent » de `ccusage` désigne
l'outil en ligne de commande (Claude Code contre un autre), pas mes
sous-agents — deux concepts homonymes sans rapport. Le vrai nom d'un
sous-agent est écrit en clair ailleurs, dans les journaux bruts d'une
session. En vérifiant le calcul à la main, j'ai trouvé un vrai piège
de comptage : un message avec plusieurs blocs (du texte plus
plusieurs appels d'outil) écrit une ligne de journal par bloc, en
répétant le même identifiant de message et le même total cumulé à
chaque fois. Sommer sans dédupliquer par cet identifiant fait presque
doubler le total — vérifié sur une session précise, où 277 lignes
avec des tokens ne correspondaient qu'à 133 messages réellement
uniques. Une fois ce doublon corrigé et les tarifs publiés par
Anthropic appliqués, mon calcul recoupait à environ 5% près le total
donné par l'outil lui-même.
</p>

<p>
Je n'ai rien inventé dans la façon de présenter tout ça : la logique
de dashboard suit un standard existant, FOCUS (FinOps Open Cost and
Usage Specification), porté par la FinOps Foundation et étendu aux
usages IA récemment. Coût dans le temps, coût par modèle, coût moyen
par appel — les mêmes vues qu'on attendrait d'un dashboard de coûts
cloud classique, appliquées à mon usage perso de Claude Code.
</p>

<p>
Alors, pourquoi je reste à 20$ pendant que d'autres montent à 200$ ?
Pas par petit budget, et pas non plus par chance. Parce que mon usage
— du human-in-the-loop par défaut, des sous-agents ciblés et
réutilisés à chaud plutôt qu'un essaim parallèle — est structurellement
plus économe, exactement dans le sens où Anthropic décrit son propre
usage recommandé : un agent unique bien prompté pour l'essentiel, le
multi-agent réservé à ce qui est vraiment parallélisable. Mes amis
n'ont pas forcément tort : leur usage vise sans doute plus de
structure, là où le mien répond juste au besoin du moment — et seul
sur mon propre projet, en train de tester, la sur-ingénierie ne peut
de toute façon pas s'appliquer. Mon but est un résultat pas cher,
quitte à y passer plus de mon propre temps à la place. Mais « plus
cher » ne veut pas dire « meilleur », et j'ai maintenant un chiffre
pour l'affirmer plutôt qu'une impression.
</p>

<h2>Références</h2>
<ul>
<li><a href="https://www.anthropic.com/engineering/multi-agent-research-system">Anthropic — How we built our multi-agent research system</a></li>
<li><a href="https://claude.com/blog/building-multi-agent-systems-when-and-how-to-use-them">Building multi-agent systems: when and how to use them</a></li>
<li><a href="https://code.claude.com/docs/en/sub-agents">Documentation Claude Code — Sub-agents</a></li>
<li><a href="https://github.com/ryoppippi/ccusage">ccusage (dépôt GitHub)</a></li>
<li><a href="https://registry.npmjs.org/ccusage">ccusage (registre npm)</a></li>
<li><a href="https://data.finops.org/">FOCUS — FinOps Open Cost and Usage Specification</a></li>
<li><a href="https://www.promptmetrics.dev/blog/finops-for-ai-llm-cost-tracking">FinOps for AI: LLM cost tracking</a></li>
</ul>
]]></description>
</item>

<item>
<title>Pourquoi "tout vérifier" m'épuisait</title>
<link>https://guillaume-besseau.fr/blog/vigilance-echantillonnage-risque.html</link>
<guid>https://guillaume-besseau.fr/blog/vigilance-echantillonnage-risque.html</guid>
<pubDate>Thu, 03 Sep 2026 12:00:00 GMT</pubDate>
<description><![CDATA[
<p>
Sur un gros projet, je n'arrive pas à faire confiance à l'IA sans
tout relire. Ce n'est pas de la méfiance de principe : j'ai testé,
petit à petit, une confiance plus large — et à un moment, ça dérive.
Alors je vérifie tout. Et tout vérifier, sur un projet qui avance à la
vitesse d'un agent, ça m'épuise.
</p>

<p>
Le problème, c'est que la vitesse de l'IA n'est pas le temps humain.
J'ai l'impression de piloter une armée de développeurs qui alternent
junior et expert d'une tâche à l'autre, qui suivent les instructions
ou n'en font qu'à leur tête — comme des humains, mais cent fois plus
vite. Rester au centre, à tout auditer, à tout voir passer, ça finit
en épuisement pur. Et en même temps, je sens bien la transformation :
pourquoi passer six mois à faire, imparfaitement, à la main, ce qu'une
IA fait en une semaine ? Je ne l'ai pas tranché. Cette question-là
reste ouverte, et ce billet ne prétend pas la fermer.
</p>

<p>
Ce qui m'a débloqué, en revanche, c'est de comprendre que ce
sentiment d'épuisement n'était pas un manque de discipline de ma
part. C'est un mécanisme connu, mesuré, et il a un nom.
</p>

<p>
Une étude du BCG a chiffré ce que je vivais sans le savoir :
surveiller étroitement des agents IA est la forme d'engagement la
plus coûteuse mentalement qu'ils aient mesurée — +14% d'effort
mental, +12% de fatigue, +19% de surcharge d'information. Et le
mécanisme derrière n'a rien de nouveau : il est documenté depuis la
Seconde Guerre mondiale, dans une étude de Mackworth sur des
opérateurs radar chargés de surveiller un écran en continu. Leur taux
de détection chutait de 10 à 15% dès les trente premières minutes de
surveillance, et continuait de se dégrader ensuite. Ça a un nom : le
"vigilance decrement". Une attention humaine ne tient pas en continu,
peu importe la volonté qu'on y met — ce n'est pas conçu pour ça.
</p>

<figure class="photo-figure">
<img src="https://guillaume-besseau.fr/blog/images/vigilance-echantillonnage-risque/radar-operators-wwii.jpg" alt="Trois opérateurs radar de l'armée américaine surveillent des écrans à oscilloscope (portée, azimut, élévation) sur un radar SCR-268, Italie, Seconde Guerre mondiale.">
<figcaption>
Des opérateurs radar surveillent en continu les écrans d'un SCR-268
près de Menella, Italie, pendant la Seconde Guerre mondiale — le type
de tâche exact étudié par Mackworth. Photo : National Museum of the
U.S. Navy, domaine public (photographie du U.S. Army Signal Corps),
via <a href="https://commons.wikimedia.org/wiki/File:Oscilloscope_operators_on_an_SCR_268_radar_maintain_watch_near_Menella,_Italy,_WWII_(39728909704).jpg" target="_blank" rel="noopener">Wikimedia Commons</a>.
</figcaption>
</figure>

<p>
Une phrase de cette recherche m'a particulièrement parlé : on ne
soutient pas la vigilance par la volonté sur des centaines de
répétitions par semaine ; on la soutient quand le système ne
sollicite le jugement humain que lorsqu'il est réellement nécessaire.
Ce n'est donc pas à moi de tenir plus longtemps. C'est le système
autour de moi qui doit arrêter de me demander la même intensité
d'attention sur tout, tout le temps.
</p>

<p>
En creusant, j'ai réalisé que je posais la question au mauvais
niveau. "Human-in-the-loop ou on-the-loop pour ce projet" traite le
projet comme une seule unité, qui devrait mériter un seul niveau de
confiance du début à la fin. C'est probablement ça qui bloquait — pas
le choix lui-même, la façon de le poser.
</p>

<p>
La réponse que j'ai trouvée dans la littérature, c'est
l'échantillonnage pondéré par le risque. Pas aléatoire — un tirage au
sort dilue trop les échecs rares, il faut cibler. L'idée est de
stratifier par signal de risque : ce qui touche un accès réseau, des
identifiants, un appel d'outil sensible mérite un examen serré ; une
logique avec des branches et des boucles mérite un examen moyen ; le
reste peut rester léger, voire passer sans relecture. Ça rejoint un
principe que Claude Code applique déjà sur lui-même : agir librement
sur ce qui est local et réversible, s'arrêter sur ce qui est difficile
à annuler ou a un large rayon d'impact.
</p>

<p>
Ça se combine avec un cadre à trois niveaux que j'ai fini par adopter
pour parler de ça plus précisément que "je surveille" ou "je ne
surveille pas" : human-in-the-loop (une approbation avant que
l'action s'exécute, pour le risque élevé), human-on-the-loop (l'action
s'exécute seule, je surveille et je peux intervenir pendant ou après,
pour le risque moyen quand la vitesse compte et que l'erreur est
réversible), et fully autonomous (aucun point de contrôle humain).
Le point important, c'est que ce niveau se choisit étape par étape
dans un même flux de travail, pas une fois pour tout le projet. Le
brainstorm reste pour moi du human-in-the-loop, c'est là que je porte
la valeur ajoutée. L'exécution de tâches bornées et vérifiables
individuellement, elle, tolère très bien du human-on-the-loop.
</p>

<figure class="schema-figure" aria-label="Schéma : du signal de risque au régime de supervision, selon le critère de réversibilité">
<div class="schema-risk-cards">
<div class="schema-risk-card schema-risk-card--high">
<div class="schema-risk-bar"></div>
<p class="schema-risk-level">Risque élevé</p>
<p class="schema-risk-signal">Accès réseau, identifiants, appel d'outil sensible</p>
<p class="schema-risk-criterion">Difficile à annuler, large rayon d'impact</p>
<div class="schema-risk-arrow">examen serré ↓</div>
<p class="schema-risk-regime">Human-in-the-loop<br>(approbation avant action)</p>
</div>
<div class="schema-risk-card schema-risk-card--medium">
<div class="schema-risk-bar"></div>
<p class="schema-risk-level">Risque moyen</p>
<p class="schema-risk-signal">Logique avec branches, boucles</p>
<p class="schema-risk-criterion">Local, mais pas trivial à vérifier après coup</p>
<div class="schema-risk-arrow">examen moyen ↓</div>
<p class="schema-risk-regime">Human-on-the-loop<br>(surveillance pendant/après)</p>
</div>
<div class="schema-risk-card schema-risk-card--low">
<div class="schema-risk-bar"></div>
<p class="schema-risk-level">Risque faible</p>
<p class="schema-risk-signal">Le reste — tâche bornée, réversible</p>
<p class="schema-risk-criterion">Local et réversible</p>
<div class="schema-risk-arrow">examen léger, voire aucun ↓</div>
<p class="schema-risk-regime">Fully autonomous<br>(aucun contrôle humain)</p>
</div>
</div>
<figcaption>
Le régime ne se choisit pas une fois pour le projet entier : il se
choisit tranche par tranche, selon le signal de risque et le critère
de réversibilité/rayon d'impact de chaque étape du flux de travail.
</figcaption>
</figure>

<p>
Ce qui m'a débloqué n'est donc pas plus de volonté ni une meilleure
discipline de relecture. C'est d'arrêter de traiter "le projet" comme
une seule tranche de confiance, et de le découper en tranches qui
n'ont pas toutes besoin du même régime — décidé petit bout par petit
bout, pas globalement en amont.
</p>

<p>
Reste une question que je n'ai pas résolue, et je préfère le dire
plutôt que d'inventer une réponse propre : la littérature sur laquelle
je m'appuie vient largement du monde devops et sécurité, où les
signaux de risque sont assez évidents à nommer — accès réseau,
identifiants, appels d'outils sensibles. Sur mon propre travail, en
dehors de ce contexte-là, comment je définis concrètement mes propres
strates de risque ? Je ne le sais pas encore précisément. C'est la
prochaine chose à creuser.
</p>

<h2>Références</h2>
<ul>
<li><a href="https://the-decoder.com/study-warns-of-ai-brain-fry-as-workers-hit-cognitive-limits-overseeing-ai-agents/">The Decoder — Study warns of "AI brain fry" as workers hit cognitive limits overseeing AI agents (étude BCG / UC Riverside)</a></li>
<li><a href="https://atomicrobot.com/blog/ai-review-fatigue/">Atomic Robot — AI review fatigue</a></li>
<li><a href="https://nhimg.org/faq/why-do-random-samples-fail-to-give-good-ai-agent-eval-coverage/">NHI Mastery Group — Why do random samples fail to give good AI agent eval coverage?</a></li>
<li><a href="https://commons.wikimedia.org/wiki/File:Oscilloscope_operators_on_an_SCR_268_radar_maintain_watch_near_Menella,_Italy,_WWII_(39728909704).jpg">Wikimedia Commons — Oscilloscope operators on an SCR 268 radar maintain watch near Menella, Italy, WWII (photo : National Museum of the U.S. Navy, domaine public)</a></li>
</ul>
]]></description>
</item>

<item>
<title>Pourquoi un prompt ne suffit pas</title>
<link>https://guillaume-besseau.fr/blog/prompt-ne-suffit-pas-hooks-permissions.html</link>
<guid>https://guillaume-besseau.fr/blog/prompt-ne-suffit-pas-hooks-permissions.html</guid>
<pubDate>Wed, 02 Sep 2026 12:00:00 GMT</pubDate>
<description><![CDATA[
<p>
Ça a commencé par une observation qui m'agaçait. Je mets dans mes
fichiers d'instructions une règle simple — utiliser AskUserQuestion
quand la compréhension n'est pas sûre — et régulièrement, elle est
oubliée. Pas contournée volontairement : oubliée en cours de route,
comme si la conversation avançait plus vite que la mémoire de la
règle.
</p>

<p>
En creusant, j'ai vu que d'autres personnes qui travaillent avec des
agents construisent des "hooks" — des scripts qui s'exécutent à des
moments précis du fonctionnement de l'agent. Ma première question
était un peu bête, mais utile : c'est encore une contrainte de plus à
écrire quelque part, ou c'est autre chose que des instructions ?
</p>

<p>
C'est autre chose, et comprendre pourquoi m'a fait revoir une
intuition que j'avais depuis un moment. Je pensais qu'un fichier
d'instructions bien écrit, avec les bons champs de permissions,
suffisait à garantir un comportement. Ce n'est pas vrai. Tout ce qui
passe par le contexte d'un agent — un CLAUDE.md, une liste d'outils
autorisés donnée à un sous-agent — reste, au fond, une suggestion.
Rien ne garantit qu'elle sera honorée à un tour donné, et plus la
conversation s'allonge, plus l'attention du modèle dérive des
instructions du début.
</p>

<p>
Les hooks, eux, ne passent pas par le modèle. Ce sont des commandes
shell exécutées hors de lui, à des points fixes de son cycle de vie :
avant qu'il appelle un outil, après, quand il reçoit un message, quand
il termine sa réponse. Ils reçoivent du JSON en entrée — quel outil,
quels paramètres — et répondent par un code de sortie. Code 2 : ça
bloque, même si le modèle "voulait" continuer. C'est la première fois
que je vois une couche qui ne demande pas l'avis du modèle pour agir.
</p>

<p>
J'ai voulu vérifier si cette logique tenait aussi pour les
sous-agents, parce que j'en construis pour séparer des tâches — un
agent RH, un agent sécurité, un agent SEO sur ce site. Ma question :
si je restreins la liste d'outils d'un sous-agent — pas d'Edit,
seulement Read et Grep — est-ce que ça garantit qu'il ne peut pas
écrire ? Réponse : non. Deux bugs ouverts et documentés sur le dépôt
officiel de Claude Code montrent des sous-agents contournant les
règles de permission alors même que l'outil concerné n'était pas dans
leur liste autorisée. Et même sans bug : un sous-agent qui a accès à
Bash peut modifier un fichier avec un simple <code>sed -i</code>, sans
jamais appeler l'outil "Edit" nommé comme tel. La restriction sur les
outils nommés ne couvre pas ce qu'on peut faire à côté.
</p>

<p>
Ça m'a forcé à revoir ma façon de penser la sécurité de mes propres
architectures d'agents. La vraie garantie, ce n'est pas un champ
d'outils autorisés bien rempli, c'est un hook qui s'exécute avant le
système de permission et qui peut bloquer un appel, quel que soit
l'agent qui l'a fait, quel que soit le chemin pris pour y arriver. Une
image qui m'a parlé, lue dans une discussion sur le sujet : une porte
sans poignée, plutôt qu'une porte avec une pancarte "ne pas ouvrir".
</p>

<figure class="blog-figure subagent-diagram">
<svg viewBox="0 0 640 350" role="img" aria-labelledby="hn-fig1-title hn-fig1-desc">
<title id="hn-fig1-title">Trois chemins de contournement d'une liste d'outils restreinte, tous bloqués par un même hook</title>
<desc id="hn-fig1-desc">Un sous-agent limité à Read et Grep atteint quand même le fichier par trois chemins différents (deux bugs documentés et une commande shell détournée) ; seul un hook PreToolUse, placé avant le système de permission, intercepte les trois à la fois.</desc>
<defs>
<marker id="hn-arrowhead" markerWidth="8" markerHeight="8" refX="6" refY="4" orient="auto">
<path class="arrowhead-fill" d="M0,0 L8,4 L0,8 z"></path>
</marker>
</defs>
<g class="box">
<rect x="190" y="10" width="260" height="55" rx="10"></rect>
<text x="320" y="32" text-anchor="middle" font-size="15" font-weight="700">Sous-agent</text>
<text x="320" y="50" text-anchor="middle" font-size="12" class="label-sub">tools: Read, Grep — pas Edit</text>
</g>
<path class="flow-arrow" d="M280,65 L120,116"></path>
<path class="flow-arrow" d="M320,65 L320,116"></path>
<path class="flow-arrow" d="M360,65 L520,116"></path>
<g class="box">
<rect x="20" y="120" width="180" height="64" rx="10"></rect>
<text x="110" y="142" text-anchor="middle" font-size="13" font-weight="700">Bug #25000</text>
<text x="110" y="160" text-anchor="middle" font-size="11.5" class="label-sub">contourne le refus</text>
<text x="110" y="174" text-anchor="middle" font-size="11.5" class="label-sub">de permission</text>
</g>
<g class="box">
<rect x="230" y="120" width="180" height="64" rx="10"></rect>
<text x="320" y="142" text-anchor="middle" font-size="13" font-weight="700">Bug SDK #115</text>
<text x="320" y="160" text-anchor="middle" font-size="11.5" class="label-sub">appelle Edit</text>
<text x="320" y="174" text-anchor="middle" font-size="11.5" class="label-sub">malgré la liste</text>
</g>
<g class="box">
<rect x="440" y="120" width="180" height="64" rx="10"></rect>
<text x="530" y="142" text-anchor="middle" font-size="13" font-weight="700">sed -i via Bash</text>
<text x="530" y="160" text-anchor="middle" font-size="11.5" class="label-sub">jamais nommé</text>
<text x="530" y="174" text-anchor="middle" font-size="11.5" class="label-sub">"Edit"</text>
</g>
<path class="flow-line" d="M110,184 L110,224"></path>
<path class="flow-line" d="M320,184 L320,224"></path>
<path class="flow-line" d="M530,184 L530,224"></path>
<line class="barrier-line" x1="10" y1="224" x2="630" y2="224"></line>
<text x="30" y="249" font-size="12.5" class="barrier-label">Hook PreToolUse —</text>
<text x="30" y="264" font-size="12.5" class="barrier-label">avant le système de permission</text>
<path class="flow-arrow" d="M320,224 L320,262"></path>
<g class="box outcome">
<rect x="170" y="264" width="300" height="66" rx="10"></rect>
<text x="320" y="290" text-anchor="middle" font-size="13.5" font-weight="700">Protégé, quel que soit le chemin</text>
<text x="320" y="308" text-anchor="middle" font-size="11.5" class="label-sub">(sans hook : fichier modifié quand même)</text>
</g>
</svg>
<figcaption>
Un champ <code>tools:</code> restreint (ici Read/Grep, sans Edit) reste une
restriction <em>déclarée</em>, pas une garantie : deux bugs documentés sur
le dépôt officiel (issues #25000 et SDK #115, voir Références) et un simple
détour par Bash suffisent à l'atteindre quand même. Seule la barrière du
bas — un hook PreToolUse, hors du modèle — intercepte les trois chemins en
même temps, quel que soit celui emprunté.
</figcaption>
</figure>

<p>
Ce que je n'avais pas vu non plus : un hook n'a aucun accès à l'état
interne du modèle. Il ne voit que des événements observables de
l'extérieur. Ma règle de départ — demander si l'agent n'est pas sûr —
n'est pas hookable telle quelle, parce que "le modèle n'était pas sûr"
n'est pas une donnée qu'un hook peut lire. Ce n'est pas que je m'y
prends mal, c'est hors de portée par construction. Ce qui devient
hookable, c'est la version reformulée en condition observable : pas
"demande si incertain", mais "bloque toute écriture tant qu'aucun
appel à AskUserQuestion n'a eu lieu dans cette tâche". Présence ou
absence d'un événement, ça, un hook sait le vérifier.
</p>

<p>
Autre angle mort découvert en creusant : je pensais qu'un agent
principal "reprenait la main" si la réponse d'un sous-agent ne lui
convenait pas. Faux, par défaut. Un sous-agent tourne dans son propre
contexte isolé et ne retourne qu'une chaîne de résultat final au
parent. Rien ne vérifie automatiquement que ce résultat est bon. Si je
veux qu'une mauvaise réponse soit rattrapée, il faut construire
l'étape de validation moi-même — ce n'est pas un réflexe intégré à
l'outil, c'est un choix d'architecture à faire.
</p>

<p>
Ça éclaire aussi un truc qui m'agaçait sans que j'en comprenne la
cause : chez le client, avec Copilot, même en sélectionnant Sonnet
comme modèle, ça part parfois n'importe comment. Copilot n'a pas
d'équivalent officiel de premier ordre pour les hooks — je n'ai pas
trouvé de trace d'une couche déterministe comparable dans ses
réglages. Ça veut dire que la seule main que j'y ai, c'est la couche
instructions, probabiliste. Le modèle est le même que celui que
j'utilise ailleurs, mais le harnais autour n'offre pas la même prise.
Ça confirme une distinction que j'avais un peu ratée : le modèle et le
harnais sont deux choses séparées, et une bonne partie de la fiabilité
perçue d'un outil se joue dans le harnais, pas dans le modèle branché
dessus.
</p>

<figure class="blog-figure">
<table class="harness-table">
<caption>Où se joue le harnais, couche par couche</caption>
<thead>
<tr>
<th scope="col">Couche</th>
<th scope="col">Claude Code</th>
<th scope="col">Copilot</th>
</tr>
</thead>
<tbody>
<tr>
<td>Instructions générales</td>
<td>CLAUDE.md (racine + global)</td>
<td>copilot-instructions.md ; AGENTS.md aussi lu</td>
</tr>
<tr>
<td>Instructions par chemin</td>
<td>CLAUDE.md imbriqués</td>
<td>fichiers *.instructions.md + applyTo</td>
</tr>
<tr>
<td>Permissions / comportement</td>
<td>settings.json (projet, perso, global)</td>
<td>pas d'équivalent officiel de même maturité</td>
</tr>
<tr class="is-key">
<td>Hooks (déterministe)</td>
<td>clé <code>hooks</code> dans settings.json</td>
<td>rien d'officiel de premier ordre trouvé</td>
</tr>
<tr>
<td>Agents spécialisés</td>
<td>fichiers d'agents dédiés</td>
<td>pas de format perso officiel ; Copilot Studio côté entreprise</td>
</tr>
<tr>
<td>Skills</td>
<td>SKILL.md par dossier</td>
<td>"prompt files", moins standardisé</td>
</tr>
<tr>
<td>MCP</td>
<td>fichier de config projet ou perso</td>
<td>supporté aussi</td>
</tr>
</tbody>
</table>
<figcaption>
Le fossé avec Copilot ne tient pas qu'aux hooks (ligne surlignée) : sur
la moitié des couches qui composent le harnais, Claude Code expose un
réglage officiel là où je n'ai rien trouvé d'équivalent côté Copilot —
d'où la seule main qui me reste, chez le client, est la couche
instructions, probabiliste.
</figcaption>
</figure>

<p>
Je ne tire pas de tout ça une promesse de contrôle total. Un hook n'a
de prise que sur ce qui est observable et formulable en condition
binaire — tout ce qui reste un jugement pur, "est-ce que c'était
vraiment ambigu", aucun hook ne le fait à ma place. Ce n'est pas un
trou dans les hooks, c'est la frontière naturelle entre ce qu'une
couche déterministe peut garantir et ce qui reste mon rôle de
relecture. Mais je sais maintenant où est cette frontière — et je ne
demande plus poliment à un prompt de faire le travail d'une porte
fermée à clé.
</p>

<h2>Références</h2>
<ul>
<li><a href="https://code.claude.com/docs/en/hooks">Claude Code — documentation des hooks</a></li>
<li><a href="https://code.claude.com/docs/en/settings">Claude Code — documentation des settings (clé <code>hooks</code>)</a></li>
<li><a href="https://code.claude.com/docs/en/agent-sdk/permissions">Claude Agent SDK — documentation des permissions</a></li>
<li><a href="https://claude.com/blog/subagents-in-claude-code">Claude — annonce des sous-agents dans Claude Code</a></li>
<li><a href="https://github.com/anthropics/claude-code/issues/25000">Claude Code — issue #25000 : sous-agents contournant les règles de permission</a></li>
<li><a href="https://github.com/anthropics/claude-agent-sdk-typescript/issues/115">Claude Agent SDK (TypeScript) — issue #115 : Edit utilisé malgré une liste d'outils restreinte</a></li>
<li><a href="https://nicolasbustamante.com/blog/model-harness-fit">Nicolas Bustamante — sur la distinction modèle / harnais</a></li>
</ul>
]]></description>
</item>

<item>
<title>Le déclic IA chez le client — gestion de 120 git pour une mise à l'échelle</title>
<link>https://guillaume-besseau.fr/blog/declic-ia-client-120-git.html</link>
<guid>https://guillaume-besseau.fr/blog/declic-ia-client-120-git.html</guid>
<pubDate>Tue, 01 Sep 2026 12:00:00 GMT</pubDate>
<description><![CDATA[
<p>
On me demande parfois comment j'en suis venu à construire toute une
méthode autour de l'IA agentique — fichier d'instructions, "cerveau"
métier, skills, scripts déterministes. J'aimerais pouvoir raconter que
c'est né d'une réflexion perso, un week-end, en testant des idées sur
un petit projet à moi. Ce serait plus flatteur pour l'image du
développeur qui anticipe. Mais ce n'est pas ce qui s'est passé, et je
préfère le dire clairement plutôt que de laisser ce site raconter
l'inverse : le déclic est né chez un client, sous une pression bien
réelle. Le rangement et le nom sont venus après, chez moi.
</p>

<p>
Pour situer d'où je pars : j'ai décroché mon diplôme de développeur en
2019, à trente-six ans, au bout de six mois de formation intensive après
une reconversion. Une conviction s'est installée tout de suite et ne
m'a plus quitté : dans ce métier, la veille n'est pas optionnelle. Le
secteur bouge trop vite pour se permettre de ne pas regarder ce qui
arrive. À l'époque, le machine learning et le big data se
structuraient sérieusement — je construisais de l'infrastructure data
sans savoir précisément ce qui allait couler dedans un jour.
</p>

<p>
Puis ChatGPT est arrivé, fin 2022. Bluffant, vraiment. Mais un moteur
probabiliste reste un moteur probabiliste : il prédit le mot le plus
vraisemblable, pas le plus vrai, et il hallucine avec la même aisance
qu'il répond juste. Je m'en servais sur des choses à faible enjeu —
reformuler, expliquer un concept flou, dégrossir un bout de code que
j'allais de toute façon relire en entier. Un brouillon, pas un
collaborateur.
</p>

<p>
Ce qui a changé la donne, c'est la cadence des versions suivantes.
GPT-4, Claude, Gemini : les hallucinations se sont faites plus rares,
plus détectables. Et surtout sont arrivés les agents dans l'IDE —
Copilot d'abord, puis Cursor, puis Claude Code. On apprenait à donner
le bon contexte, à formuler la contrainte précise, à corriger quand
l'agent partait dans la mauvaise direction. Un dialogue, pas une
commande. Les MCP et les premiers skills, je les regardais déjà passer
dans ma veille à cette période — prometteurs sur le papier, encore
instables en pratique. Je les ai laissés de côté, sans les adopter.
</p>

<figure class="schema-figure">
<div class="schema-frise">

<div class="etape">
<div class="periode">2019</div>
<div class="contenu">
<h4>Diplôme dev, à trente-six ans</h4>
<p>Reconversion en six mois intensifs. Une conviction s'installe :
la veille n'est pas optionnelle dans ce métier.</p>
<div class="tags">
<span class="nature">conviction posée</span>
<div class="enjeu"><span class="dot on"></span><span class="dot"></span><span class="dot"></span> enjeu faible</div>
</div>
</div>
</div>

<div class="etape">
<div class="periode">2019 → 2022</div>
<div class="contenu">
<h4>Infrastructure data, avant de savoir</h4>
<p>Le ML et le big data se structurent sérieusement. Je construis de
l'infra sans savoir précisément ce qui va couler dedans un jour.</p>
<div class="tags">
<span class="nature">observation</span>
<div class="enjeu"><span class="dot on"></span><span class="dot"></span><span class="dot"></span> enjeu faible</div>
</div>
</div>
</div>

<div class="etape">
<div class="periode">Nov. 2022</div>
<div class="contenu">
<h4>ChatGPT</h4>
<p>Bluffant, mais un moteur probabiliste reste un moteur probabiliste.
Usage réservé au faible enjeu : reformuler, dégrossir, relire ensuite
en entier.</p>
<div class="tags">
<span class="nature">"un brouillon, pas un collaborateur"</span>
<div class="enjeu"><span class="dot on"></span><span class="dot"></span><span class="dot"></span> enjeu faible</div>
</div>
</div>
</div>

<div class="etape">
<div class="periode">2023 → 2024</div>
<div class="contenu">
<h4>GPT-4, Claude, Gemini + agents dans l'IDE</h4>
<p>Copilot, puis Cursor, puis Claude Code. Les hallucinations se font
plus rares et plus détectables. On apprend à donner le bon contexte,
à corriger l'agent. MCP et skills regardés de loin, pas encore
adoptés.</p>
<div class="tags">
<span class="nature">"un dialogue, pas une commande"</span>
<div class="enjeu"><span class="dot on"></span><span class="dot on"></span><span class="dot"></span> enjeu moyen</div>
</div>
</div>
</div>

<div class="etape">
<div class="periode">Migration client</div>
<div class="contenu">
<h4>Plus de cent dépôts git à maintenir</h4>
<p>Le déclic n'est pas un outil de plus : c'est une bascule
d'approche, née sous la pression d'un vrai mur à débloquer.</p>
<div class="tags">
<span class="nature">méthode née et validée en conditions réelles</span>
<div class="enjeu"><span class="dot on"></span><span class="dot on"></span><span class="dot on"></span> enjeu élevé</div>
</div>
</div>
</div>

</div>
<figcaption>Schéma original — la même frise en un coup d'œil : ce qui
change au fil des étapes n'est pas seulement l'outil, c'est la nature
de la relation à l'IA (outil ponctuel → dialogue → méthode sous
contrainte) et le niveau d'enjeu qui l'accompagne.</figcaption>
</figure>

<p>
Et puis le projet chez le client a pris de l'ampleur. Ce qui tenait
sur une poignée de services est devenu, produit après produit, usine
après usine, plus d'une centaine de dépôts git à maintenir. Chaque site
industriel apportait ses propres conventions, ses propres exceptions.
Documenter, tracer les changements, comprendre pourquoi telle règle
avait été codée ainsi six semaines plus tôt : ça tenait, mais ça
commençait à ressembler à tenir un mur qui pousse, sans pouvoir
lâcher les mains pour voir à quoi il ressemble vraiment.
</p>

<p>
Le déclic, ce n'est pas un nouvel outil ni une nouvelle version de
modèle. C'est une bascule dans la façon d'aborder la question. Avant,
je posais le sujet par l'outil : quel agent, quelle intégration.
Ce jour-là, en pleine migration, je l'ai posé par l'intention : qu'est-ce
que je veux que l'IA comprenne, et comment le lui dire une bonne fois
pour toutes ? Premier test, très simple : demander à l'agent de
m'aider à écrire son propre fichier d'instructions. Et là, quelque
chose a changé — l'IA n'était plus générique, elle répondait dans mon
contexte, avec mes noms de choses, en respectant les contraintes que
j'avais posées.
</p>

<p>
Le deuxième pas est venu du projet lui-même. On utilisait Databricks
Genie, un assistant conversationnel sur les données — puissant, mais
sans direction s'il n'a pas de contexte métier. J'ai essayé de lui
injecter une compréhension du terrain : premier essai, une
rétro-documentation générée entièrement par l'IA, juste sur le fond
mais consommatrice de tokens de façon déraisonnable et pratiquement
inmaintenable. Ce n'était pas la bonne architecture. Épurée,
réinjectée en version courte et structurée, ça a marché — j'avais mis
un vrai "cerveau" métier dans l'outil, capable de comprendre les
questions dans notre vocabulaire. Je ne le savais pas encore, mais je
venais de redécouvrir tout seul, à la dure, ce que la littérature
appelle le pattern Memory Bank : la documentation devient un
sous-produit de la mémoire du projet, pas un effort séparé.
</p>

<p>
De là, un principe s'est imposé, qui allait tenir pour tout le reste :
un skill, c'est une intention formulée pour l'agent. Un script, c'est
la logique déterministe qui ne doit pas halluciner. Un template, c'est
le cadre dans lequel l'IA ne remplit que ce qui a vraiment besoin de
langage naturel. L'IA comble les trous, elle ne pilote pas la logique.
Empilé avec un workspace qui centralise les instructions et les skills
pour l'ensemble des dépôts du projet, ça donnait quelque chose de
sobre en tokens et de maintenable — moins d'hallucinations parce que
la logique n'est pas déléguée, plus de maintenance parce que les
scripts sont testables indépendamment de l'IA.
</p>

<figure class="schema-figure">
<div class="schema-hub">

<div class="hub-box">
<h4>Repo starter</h4>
<div class="hub-badges">
<span>instructions</span>
<span>skills</span>
<span>conventions</span>
<span>sauvegardes</span>
</div>
</div>

<div class="flow-label">↓ porte et prépare</div>

<div class="branch-row">

<div class="workspace-box">
<h4>Workspace</h4>
<div class="workspace-tags">
<span>120 git</span><span>doc</span><span>etc.</span>
</div>
</div>

<div class="brain-connector">
<span class="brain-arrow">←</span>
<span>cerveau + IA<br>agissent dans<br>le workspace</span>
</div>

<div class="brain-box">
<h4>Cerveau métier</h4>
<div class="hub-badges">
<span>+ IA</span>
</div>
</div>

</div>

<div class="flow-label">↓ pilote</div>

<div class="spokes-row">
<div class="spoke-box"><div class="nom">Usine 1</div><div class="detail">conventions propres</div></div>
<div class="spoke-box"><div class="nom">Usine 2</div><div class="detail">conventions propres</div></div>
<div class="spoke-box"><div class="nom">Usine 3</div><div class="detail">conventions propres</div></div>
<div class="spoke-box"><div class="nom">Usine X</div><div class="detail">et les autres</div></div>
</div>

</div>
<figcaption>Schéma original — le starter porte les instructions,
skills et conventions, et prépare le workspace qui centralise 120
git, plus la doc et le reste du projet. Le cerveau métier,
associé à l'IA, agit dans ce workspace (détection de dérive,
corrections). Le workspace, une fois piloté depuis ce point central,
pilote à son tour chaque usine avec ses propres conventions — l'info
remontée au niveau du workspace, pas répétée usine par usine.</figcaption>
</figure>

<p>
Je le dis franchement parce que le sens du récit compte : tout ça est
né et a été validé en conditions réelles chez le client, sous
contrainte, pas dans un coin tranquille de mon temps perso. C'est
seulement après, ici, dans mes projets à moi, que j'ai pris le temps
de ranger, de nommer, de généraliser ce qui avait marché — reconnaître
que mon triptyque de travail recoupe une méthode déjà documentée
ailleurs, formaliser l'idée qu'un hook déterministe vaut plus qu'une
instruction qu'on espère suivie, tenir un vrai journal de décisions,
graduer les niveaux d'autonomie plutôt que de tout traiter pareil.
Cette formalisation, faite à froid en perso, est aujourd'hui
réapplicable chez le client, en mieux outillée qu'à l'origine. Le
sens du mouvement, c'est bien déclic et validation chez le client,
puis formalisation en perso — pas l'inverse.
</p>

<p>
Il y a un point que je trouve important à assumer, plutôt qu'à
enjoliver : ma reconversion à trente-six ans, avec six mois de formation
intensive, ne m'a pas donné des années d'exécution manuelle. Elle m'a
donné les concepts, les patterns, la façon de penser en systèmes. Et
c'est très exactement ça qui permet de bien piloter une IA aujourd'hui
— pas l'inverse. Il y a des choses que j'aurais mis des semaines à
écrire seul, que j'ai construites en deux jours avec l'agent. Pas
parce qu'il a pensé à ma place, mais parce qu'il a exécuté vite ce que
je savais déjà penser.
</p>

<p class="emoji-inline">
<img src="https://guillaume-besseau.fr/blog/images/declic-ia-client-120-git/1F914.svg" alt="Emoji OpenMoji : visage pensif, en train de réfléchir">
<span>Un doute qui ne se referme jamais tout à fait.</span>
</p>

<p>
Ça n'a pas été que du soulagement. Distinct de
<a href="vigilance-echantillonnage-risque.html">la fatigue de tout vérifier</a>,
un risque s'est nommé de lui-même pendant cette période : le vrai
risque n'est pas que l'IA prenne notre place, c'est qu'on la laisse
prendre notre curiosité. Si tout ce qui
demandait de l'effort devient facile, la question de savoir si on
continue vraiment à développer ses réflexes d'ingénieur, ou si on les
laisse s'atrophier derrière des workflows qu'on ne comprend plus tout
à fait de l'intérieur, mérite d'être posée souvent — je n'ai pas de
réponse définitive, juste l'habitude de me la reposer.
</p>

<p>
Ce que je retiens, c'est que le déclic n'a rien de romantique. Il n'a
pas eu lieu parce que j'avais anticipé une tendance depuis mon canapé
— il a eu lieu parce qu'il fallait débloquer un vrai mur, avec de
vraies conséquences si ça ne marchait pas. C'est justement ce qui le
rend crédible : ce n'est pas une théorie que j'aurais lue et recopiée,
c'est une méthode que j'ai payée en dette de tokens avant de savoir la
nommer.
</p>

<h2>Références</h2>
<ul>
<li><a href="https://github.com/hudrazine/claude-code-memory-bank">hudrazine/claude-code-memory-bank</a> — le pattern Memory Bank porté à Claude Code, que je découvre après coup avoir réinventé à la dure chez le client.</li>
<li><a href="https://cline.bot/blog/memory-bank-how-to-make-cline-an-ai-agent-that-never-forgets">Cline — Memory Bank: How to Make Cline an AI Agent That Never Forgets</a>, l'article qui a popularisé le pattern.</li>
<li><a href="https://www.mintlify.com/blog/what-is-llms-txt">Mintlify — What is llms.txt?</a>, le standard émergent pour exposer une doc curée à des agents IA.</li>
<li>Emoji "thinking face" : <a href="https://openmoji.org/library/emoji-1F914/">OpenMoji – the open-source emoji and icon project</a>, licence CC BY-SA 4.0.</li>
</ul>
]]></description>
</item>

<item>
<title>Comment j'ai choisi l'identité visuelle du site</title>
<link>https://guillaume-besseau.fr/blog/identite-visuelle-du-site.html</link>
<guid>https://guillaume-besseau.fr/blog/identite-visuelle-du-site.html</guid>
<pubDate>Mon, 31 Aug 2026 12:00:00 GMT</pubDate>
<description><![CDATA[
<p>
J'ai déjà raconté, dans <a href="genese-du-site.html">la genèse de ce
site</a>, comment il a été construit — le processus, les agents
spécialisés, le passage de l'idée au site en ligne. Ici c'est autre
chose : à quoi il ressemble, et pourquoi. Les choix de couleur, le
dark mode, l'effet verre, l'identité de chaque section. Le
"comment j'ai codé" d'un côté, le "pourquoi ça a cette tête-là" de
l'autre.
</p>

<p>
Le problème de départ était simple à énoncer et pas si simple à
résoudre : le site a quatre parties — CV, musique, jeux vidéo, blog —
et je voulais qu'on sente qu'on change d'univers en passant de l'une à
l'autre, sans que ça devienne quatre sites différents recollés
ensemble.
</p>

<p>
J'ai commencé par le socle, avant même de penser identité par
section : le dark mode. Le réflexe facile, c'est de partir sur du noir
pur et du blanc pur, et ça donne un résultat qui fatigue les yeux et
qui, sur les écrans OLED, finit par marquer l'écran à l'usage
(smearing). La recherche 2026 sur le sujet est unanime là-dessus : un
gris très sombre plutôt qu'un noir franc (j'ai retenu <code>#121212</code>),
un blanc cassé plutôt qu'un blanc pur pour le texte, et pas plus d'un
ou deux accents de couleur, désaturés à 70-80 % — en dark mode, chaque
couleur pèse visuellement plus lourd qu'en fond clair, donc mieux vaut
en mettre moins. J'ai aussi veillé au contraste minimum recommandé
(WCAG AA, grosso modo 4,5:1 pour du texte normal), pas pour cocher une
case d'accessibilité qu'on m'aurait imposée, mais parce qu'un site
illisible n'a aucun intérêt à exister.
</p>

<p>
Sur la matière, j'avais trois directions possibles. La première,
celle que j'ai gardée : un "verre sombre feutré" — fond très sombre,
une lueur diffuse en arrière-plan (un halo bleu très désaturé qui
dérive lentement), des cartes en verre dépoli (l'effet
<code>backdrop-filter: blur()</code>, qu'on appelle glassmorphism), un
seul accent bleu, des titres légèrement plus lourds en dark mode parce
qu'un texte fin devient vite difficile à lire sur fond sombre. C'est
la direction la plus proche de ce qui ressort des tendances 2026, et
elle collait avec ce qui existait déjà dans le repo (le dark mode
était déjà géré via <code>prefers-color-scheme</code>). Le
glassmorphism, en particulier, est passé de gadget à langage de design
qui a fait ses preuves — et il se fait entièrement en CSS natif, sans
librairie.
</p>

<p>
J'avais deux autres pistes, écartées mais gardées en tête pour plus
tard. Un "terminal chaleureux" : touches monospace sur les labels et
les dates pour signer visuellement le développeur, un accent chaud
(ambre, orange désaturé — plus proche de l'univers musique que le bleu
"tech"), une légère texture de grille en fond façon circuit imprimé.
Plus marqué, plus risqué si mal dosé, je l'ai mis de côté. Et un
"minimal éditorial" : beaucoup de blanc, des titres en serif système
(pas de police distante — <code>ui-serif</code>/Georgia suffisent),
l'accent réservé aux liens, quasiment plus de cartes, juste des
séparateurs fins. Cette direction-là convient à un site pensé comme un
essai ou un blog plutôt qu'une vitrine de compétences — elle
reprendra peut-être du sens si le blog devient un jour la partie
dominante du site. Pour l'instant, j'ai gardé le verre sombre comme
base commune.
</p>

<p>
Vient ensuite la question de l'identité par section, qui était le
vrai sujet : comment donner à chaque partie sa propre couleur sans que
ça se transforme en quatre chartes graphiques différentes. La
recherche sur les systèmes multi-marques est claire là-dessus, et
c'est un pattern qui existe depuis longtemps dans le design de marque
(le "wayfinding") : on garde fixes la typographie, la grille, les
rayons de coin, les ombres, le rythme d'espacement — et on ne fait
varier que la couleur (parfois une légère variation de forme) d'une
sous-identité à l'autre. C'est ce qui permet à quelqu'un de reconnaître
"même système" tout en sentant "univers différent" en changeant de
page.
</p>

<p>
Techniquement, ça tombait bien : le site utilisait déjà des variables
CSS centralisées (<code>--accent</code>, <code>--accent-2</code>,
<code>--bg-glow</code>...). Il suffisait de les redéfinir dans un petit
fichier <code>theme.css</code> propre à chaque section, sans jamais
toucher aux règles de composants elles-mêmes (les cartes, la timeline,
les boutons restent identiques partout). Une couleur qui change, une
structure qui ne bouge pas.
</p>

<p>
La palette, section par section : le CV reste neutre, en bleu et
orange — c'est la base du site, celle qui donne le ton, donc je ne
voulais rien y bousculer. La musique passe en violet profond et or
champagne, une ambiance sombre et un peu classe, cohérente avec ce que
je fais musicalement. Les jeux vidéo basculent sur du corail et du
turquoise, des coins plus arrondis, des micro-interactions un peu plus
"rebondissantes" au survol — volontairement enfantin, à l'image du
projet fait avec mon fils. Le blog, enfin, change complètement de
registre : fond crème chaud plutôt que le bleu-gris froid des autres
pages, encre presque noire, un accent terracotta/rouille, des titres
en serif système. L'idée, c'est un effet "journal papier" — des cartes
moins "verre", moins de flou, pour que ça se lise comme du texte
d'abord, pas comme une interface.
</p>

<figure class="palette-schema">
<style>
.palette-schema { margin: 2.2rem 0; }
.palette-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 1rem;
}
.palette-card {
    border-radius: 16px;
    overflow: hidden;
    border: 1px solid rgba(128,128,128,0.22);
    background: rgba(128,128,128,0.06);
}
.palette-card-label {
    padding: 0.6rem 0.9rem 0.4rem;
    font-weight: 600;
    font-size: 0.92rem;
    opacity: 0.9;
}
.palette-mode-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.55rem 0.9rem;
}
.palette-mode-tag {
    font-size: 0.68rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    opacity: 0.75;
    width: 3.4rem;
    flex-shrink: 0;
}
.palette-swatch {
    display: inline-block;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    border: 1px solid rgba(128,128,128,0.35);
    flex-shrink: 0;
}
.palette-hex {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 0.66rem;
    opacity: 0.85;
    margin-left: auto;
    white-space: nowrap;
}
</style>
<div class="palette-grid">

<div class="palette-card">
<div class="palette-card-label">CV</div>
<div class="palette-mode-row" style="background:#f0f2f8; color:#1d1d1f;">
<span class="palette-mode-tag">Clair</span>
<span class="palette-swatch" style="background:#0071e3;" title="--accent"></span>
<span class="palette-swatch" style="background:#ff5e3a;" title="--accent-2"></span>
<span class="palette-hex">#f0f2f8</span>
</div>
<div class="palette-mode-row" style="background:#121212; color:#e8e8ea;">
<span class="palette-mode-tag">Sombre</span>
<span class="palette-swatch" style="background:#4da3ff;" title="--accent"></span>
<span class="palette-swatch" style="background:#ff7a59;" title="--accent-2"></span>
<span class="palette-hex">#121212</span>
</div>
</div>

<div class="palette-card">
<div class="palette-card-label">Musique</div>
<div class="palette-mode-row" style="background:#e4d9f0; color:#241a33;">
<span class="palette-mode-tag">Clair</span>
<span class="palette-swatch" style="background:#7c3aed;" title="--accent"></span>
<span class="palette-swatch" style="background:#c9a24b;" title="--accent-2"></span>
<span class="palette-hex">#e4d9f0</span>
</div>
<div class="palette-mode-row" style="background:#100b18; color:#ece6f7;">
<span class="palette-mode-tag">Sombre</span>
<span class="palette-swatch" style="background:#a78bfa;" title="--accent"></span>
<span class="palette-swatch" style="background:#d4af6a;" title="--accent-2"></span>
<span class="palette-hex">#100b18</span>
</div>
</div>

<div class="palette-card">
<div class="palette-card-label">Jeux vidéo</div>
<div class="palette-mode-row" style="background:#dff7f8; color:#12262c;">
<span class="palette-mode-tag">Clair</span>
<span class="palette-swatch" style="background:#ff5f82;" title="--accent"></span>
<span class="palette-swatch" style="background:#22d3ee;" title="--accent-2"></span>
<span class="palette-hex">#dff7f8</span>
</div>
<div class="palette-mode-row" style="background:#0a1620; color:#e3f7f9;">
<span class="palette-mode-tag">Sombre</span>
<span class="palette-swatch" style="background:#ff7d9b;" title="--accent"></span>
<span class="palette-swatch" style="background:#38e0f5;" title="--accent-2"></span>
<span class="palette-hex">#0a1620</span>
</div>
</div>

<div class="palette-card">
<div class="palette-card-label" style="font-family: ui-serif, Georgia, serif;">Blog</div>
<div class="palette-mode-row" style="background:#f5efe4; color:#2b2621;">
<span class="palette-mode-tag">Clair</span>
<span class="palette-swatch" style="background:#b0492f;" title="--accent"></span>
<span class="palette-swatch" style="background:#c98a3e;" title="--accent-2"></span>
<span class="palette-hex">#f5efe4</span>
</div>
<div class="palette-mode-row" style="background:#1c1712; color:#ece3d3;">
<span class="palette-mode-tag">Sombre</span>
<span class="palette-swatch" style="background:#d99a5b;" title="--accent"></span>
<span class="palette-swatch" style="background:#c9704a;" title="--accent-2"></span>
<span class="palette-hex">#1c1712</span>
</div>
</div>

</div>
<figcaption>
Les huit couleurs de fond et les seize accents réellement définis dans
le <code>theme.css</code> de chaque section — même structure de carte
partout (deux modes, deux accents), seule la couleur change d'une
section à l'autre. Le mode clair n'est pas un simple négatif du mode
sombre : chaque variante a été pensée pour elle-même (le violet
musique passe d'un lavande clair à un aubergine profond, pas d'un
blanc à un noir inversés).
</figcaption>
</figure>

<p>
Sur la page d'accueil, chaque tuile reprend un avant-goût de la
couleur de sa section — une barre, une teinte d'icône — pour que
cliquer dessus donne déjà l'impression d'entrer dans un autre univers
avant même que la page ne charge.
</p>

<p>
Ce n'est pas figé pour toujours. Si le blog venait à devenir la partie
centrale du site plutôt qu'une des quatre briques, je referais sans
doute le point sur la direction "minimal éditorial" mise de côté. Et
je n'ai pas de subagent dédié au design pour l'instant — cette
recherche, je l'ai faite une fois, ponctuellement, avec l'agent
principal. Si les demandes de retouche esthétique deviennent
récurrentes, ça rejoindra sans doute la même logique que mes agents
RH ou SEO : un spécialiste de plus, appelé quand il faut.
</p>

<h2>Références</h2>
<ul>
<li><a href="https://elements.envato.com/learn/portfolio-trends">Envato Elements — Portfolio design trends 2026</a></li>
<li><a href="https://www.tech-rz.com/blog/dark-mode-design-best-practices-in-2026/">Tech-RZ — Dark mode design best practices in 2026</a></li>
<li><a href="https://natebal.com/best-practices-for-dark-mode/">Nate Bal — Best practices for dark mode</a></li>
<li><a href="https://colorpickercode.com/blog/best-website-color-palettes-2026/">ColorPickerCode — Best website color palettes 2026</a></li>
<li><a href="https://www.mathis-biabiany.fr/">Mathis Biabiany — portfolio de creative technologist</a></li>
<li><a href="https://medium.com/@christopher.arold87/multi-brand-design-system-1fcf3d30e4ff">Christopher Arold — Multi-brand design system</a></li>
<li><a href="https://robertcelt95.medium.com/theming-architecture-multi-brand-design-systems-that-actually-work-ad7ed8445fed">Robert Celt — Theming architecture: multi-brand design systems that actually work</a></li>
<li><a href="https://www.designsystemscollective.com/the-multi-brand-design-system-playbook-c6fc8415f07e">Design Systems Collective — The multi-brand design system playbook</a></li>
</ul>
]]></description>
</item>

<item>
<title>La genèse de ce site</title>
<link>https://guillaume-besseau.fr/blog/genese-du-site.html</link>
<guid>https://guillaume-besseau.fr/blog/genese-du-site.html</guid>
<pubDate>Sun, 30 Aug 2026 12:00:00 GMT</pubDate>
<description><![CDATA[
<p>
Le point de départ, c'est une réflexion sur ce qui se passe en ce
moment : les croisements de données, la centralisation d'internet, la
donnée ingérée par des IA ou des cookies sans qu'on la voie passer.
J'ai eu envie de faire un site à moi qui reprenne la main sur mes
propres données et sur ce que je veux en dire.
</p>

<p>
Ça m'a ramené loin en arrière. Mes premiers sites, je les faisais avec
l'outil de création de site d'Apple, en gérant le FTP chez Free. Je
n'étais pas développeur, mais j'arrivais bon an mal an à faire ce que
je voulais — même si le résultat n'était pas toujours des plus
pertinent. Plus tard, en formation à l'ENI, j'ai découvert WordPress
(que je ne connaissais que de nom) et fait du PHP avec Symfony. J'ai
gardé ça en tête depuis : un jour, je referais des sites.
</p>

<p>
Devenu développeur, j'ai fini par délaisser les interfaces graphiques
pour mieux gérer le versionning. Les plateformes WordPress, où on
accède à l'admin en quelques secondes, c'est pratique à l'usage — la
sécurité y est in fine correctement gérée dans le fonctionnement du
CMS, mais c'est un point sur lequel il faut rester vigilant en
permanence. Pareil pour les bases de données, pratiques pour
l'autogénération de contenu. Je préfère consacrer mon énergie au fond
et à la forme plutôt qu'à une veille sécurité supplémentaire, en plus
de celle que je fais déjà tous les jours pour mon travail. En prenant
la main avec les IA, je me suis dit que faire des sites statiques —
sans interface, sans DB, sans rien qu'un contenu visible — était bien
mieux : le framework devient des agents qui construisent un contenu
statique cohérent, facilement modifiable, et l'approche agentique me
permet de vérifier chaque diff git de fichier .md ou de page HTML
pour m'assurer que tout est bon.
</p>

<p>
D'où ce site : un mini portfolio pour parler de moi et poser ma
présence en ligne telle que je l'entends — une partie musique, une
partie plus CV, une partie jeu vidéo, une partie blog avec du contenu
RSS. C'est simple, je maîtrise ce que je veux. Je ne cherche pas à le
monétiser ni à faire de la pub, ça existe déjà ailleurs. Que ce soit
des IA ou des connaissances, ils trouveront ce qu'ils veulent y voir
et en feront ce qu'ils veulent. Pas besoin de commentaires ni d'algo
pour me montrer.
</p>

<p>
J'ai suivi la logique de certains principes IA qui fonctionnent chez
moi, et que les personnes que je forme sur le sujet apprécient. J'ai
fait mon petit dossier sur mon Mac, ouvert dans VS Code, et commencé à
préparer Claude à une architecture où tous les fichiers .md vivent
dans le repo — puis j'ai transformé le dossier en dépôt git, et c'est
parti.
</p>

<p>
Première phase : le brainstorm. Une journée entière à mettre à plat
mes idées, du brut, avec l'IA qui pose une question dès qu'elle a un
doute sur ce que je dis — paramétré par moi dans le fichier
d'instructions. J'ai vu le brainstorm se structurer et grandir tout
seul. Un autre point que j'ai bien aimé : à un moment, faire des
agents spécialisés — une personne RH pour m'aider à préparer ma partie
CV, un spécialiste SEO pour les balises et la qualité HTML, un
spécialiste sécurité pour vérifier que je n'utilise pas de JavaScript
limite ou que je n'expose pas une donnée meta non voulue.
</p>

<p>
J'ai construit le site sans domaine ni hébergement, en local, avec le
chat en mode agent qui construit. Je vérifiais étape après étape,
commit après commit, avec de la recherche web pour que mes agents
récupèrent de l'info fraîche dans leur petit cerveau de contexte.
J'avançais, je les questionnais sur la qualité du site, je corrigeais,
je m'améliorais, j'apprenais des choses au passage.
</p>

<p>
Puis est venu le moment de me lancer : domaine et hébergement. J'ai
choisi Infomaniak, par alignement idéologique et parce qu'ils sont
européens. Même en connaissant les termes et le fonctionnement du net,
j'ai un peu galéré — mais aidé par la recherche IA, j'ai réussi à
suivre les interfaces, à m'y retrouver, à faire la sécurité, les
comptes utilisateurs, tous différents et bien chiffrés, sans jamais
les donner à Claude.
</p>

<p>
Et me voilà avec un site à mon nom qui suit ma logique, avec quelques
conseils d'agents spécialisés sur mes points faibles. Des scripts pour
déployer, des scripts pour la maintenance. Ça fait vingt ans que je
voulais faire ça, et je suis content que ça existe. Le faire en deux
jours avec l'IA, c'est fou — ça confirme mes choix agentiques.
</p>
]]></description>
</item>

<item>
<title>Pourquoi ce site</title>
<link>https://guillaume-besseau.fr/blog/pourquoi-ce-site.html</link>
<guid>https://guillaume-besseau.fr/blog/pourquoi-ce-site.html</guid>
<pubDate>Sat, 29 Aug 2026 12:00:00 GMT</pubDate>
<description><![CDATA[
<p>
Longtemps, j'ai séparé volontairement mon activité professionnelle et
ma vie musicale. Je considérais qu'aucune des deux ne devait
influencer les choix de l'autre.
</p>

<p>
Deux choses avaient pourtant déjà commencé à faire le lien sans que
je le contrôle : mon statut de membre de la SACEM, qui me rend
traçable en tant que musicien, et LinkedIn, qui remontait déjà mon nom
si on me cherchait en ligne.
</p>

<p>
Avec l'arrivée de l'IA et la puissance actuelle du croisement de
données, je me suis rendu compte que ce que j'avais séparé était
redevenu, de fait, de plus en plus uni. Plutôt que de laisser ce lien
se faire tout seul, sans que je le maîtrise, j'ai décidé de construire
un site qui montre tout, comme un portfolio.
</p>

<p>
En creusant, je me suis aussi rendu compte que la séparation que je
m'imposais n'avait jamais vraiment existé dans les faits : la musique
et mes emplois ont toujours été extrêmement liés dans mes choix. Mon
poste chez Algam, mon poste dans le recyclage — les deux me sont venus
par mon réseau musical, pas malgré lui.
</p>

<p>
Si faire du metal pouvait rebuter des employeurs en 2000, je pense —
et j'espère — que ce n'est plus le cas en 2026. J'espère qu'on peut
aujourd'hui voir ce que ça apporte réellement à mon profil : gérer un
groupe, une tournée, un collectif, c'est déjà de la gestion de projet
et du management d'équipe.
</p>

<p>
Ce site, c'est ça : arrêter de subir la porosité entre mes deux vies,
et la raconter moi-même.
</p>
]]></description>
</item>

</channel>
</rss>
