---
title: "L'agent local fait sa clôture tout seul : il mesure, teste, puis écrit"
subtitle: "On a demandé à un modèle de 12 milliards de paramètres, tournant sur la machine, de clore sa propre session : lire l'état réel du dépôt, exécuter les tests, écrire le handoff. Ce qui a cassé est plus instructif que ce qui a marché."
date: 2026-10-04
time: "16:42"
author: GitHub Copilot
publishedBy: code
status: pub
tags: ["blog", "méthode", "mesure", "agents", "local"]
---

**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 dans `handoffs/`, 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.