TL;DR — Un modèle local (gemma-4-12b) a réalisé une clôture de session complète en mode agentique : il a appelé un outil pour lire l'état réel du dépôt, un autre pour lancer les tests, puis un troisième pour écrire le handoff. Le résultat était factuel et ancré sur les vrais commits — pas inventé. Deux choses ont cassé en chemin : une lecture de fichier qui corrompait les accents, et un modèle plus bavard qui a glissé des balises dans ses arguments.
Le problème : un agent local peut-il clore proprement ?
La clôture d'une session, chez nous, c'est un geste écrit : mesurer l'état du dépôt, vérifier que les tests passent, produire un handoff daté qui dit ce qui a été fait, ce qui ne l'a pas été, et la prochaine action exacte. Rien de magique — mais tout repose sur une discipline : ne rien déduire, tout mesurer.
La question de cette session était simple : un modèle local, de petite taille, peut-il suivre cette discipline ? Pas de « il a l'air de comprendre » : on le met au travail et on regarde ce qu'il écrit.
La méthode : trois outils, pas de zone grise
On n'a donné à l'agent que trois outils, chacun borné à un geste :
repo_status— lit l'état réel du dépôt :git status, les derniers commits, la liste des handoffs et des fichiers suivis. L'agent ne peut pas inventer un commit : il le lit.run_tests— exécute la suite de tests du dépôt et renvoie le code retour et les dernières lignes. La vérification est un fait, pas une déclaration.write_handoff— écrit le handoff danshandoffs/, avec un nom de fichier assaini.
Le prompt impose l'ordre : mesurer d'abord, tester ensuite, écrire enfin. Chaque outil expose tous ses paramètres requis — un paramètre manquant, et le modèle devine (mal).
Ce qui a marché
En environ vingt secondes, le modèle a déroulé la boucle complète : repo_status, puis run_tests
(retour exit=0), puis write_handoff, puis un résumé final. Le handoff produit citait les vrais
commits de la session — ceux lus via l'outil — et sa section « Vérifications » contenait le
résultat réel des tests, pas une intention. La boucle s'est fermée d'elle-même : plus d'appel d'outil,
une réponse finale, fin.
C'est exactement ce qu'on attendait : un modèle qui agit sur du réel au lieu de le raconter.
Ce qui a cassé, et pourquoi c'est plus utile
Premier cas : les accents corrompus. Le premier handoff écrit affichait Réalisé au lieu de
Réalisé. Le modèle n'y était pour rien : la faute était dans notre code de lecture. Sous
PowerShell 5.1, Get-Content -Raw lit un fichier UTF-8 comme de l'ANSI. La réponse du modèle, écrite
en UTF-8 par curl, était donc relue de travers. Correction : lire explicitement en UTF-8
([System.IO.File]::ReadAllText($p, UTF8)). Leçon : quand une sortie semble « corrompue par le
modèle », vérifier d'abord qui a corrompu — c'est souvent l'outil de mesure lui-même.
Second cas : le modèle trop bavard. Avec un modèle plus gros, la boucle a fonctionné aussi — mais
en glissant des balises XML (</parameter>) dans la valeur de ses arguments. Résultat : un nom de
fichier pollué, illisible. Le modèle a même rappelé un outil après avoir déjà écrit, par excès de
zèle. C'est une limite du modèle, pas du protocole : on l'a mesurée et consignée, au lieu de la
maquiller.
Pourquoi ça compte
Ce n'est pas une démonstration de force. C'est la preuve qu'un petit modèle local peut exécuter un geste de méthode — mesurer, vérifier, écrire — à condition que les outils soient petits, bornés et complets, et que le prompt impose l'ordre. La fiabilité ne vient pas de la taille du modèle : elle vient de la surface qu'on lui donne. Trois outils nets battent un gros modèle avec une API floue.
Et il reste un garde-fou humain : l'agent écrit, mais il ne pousse pas. La décision de publier reste à la personne. Le modèle propose ; l'humain dispose.
Les chiffres, sans arrondi flatteur
| Mesure | Valeur |
|---|---|
| Modèle de clôture retenu | gemma-4-12b, local, sans réseau |
| Boucle complète | ~20 s (même protocole : ~70 s sur le modèle plus gros) |
| Outils exposés | 3 (repo_status, run_tests, write_handoff) |
| Vérification | tests → exit=0, cité dans le handoff |
| Défauts trouvés | 1 bug de lecture (moi) + 1 limite de modèle (balises) |
Un agent local qui se mesure lui-même, qui se trompe, et dont on écrit l'erreur noir sur blanc : c'est le seul genre d'agent auquel on peut confier une clôture.