Par Valentin Brosseau / @c4software
Dans ce scénario, qui fait le travail répétitif ?
Avec un chat, vous êtes la boucle : copier, coller, lancer, revenir.
On ne lui demande plus un bout de code, on lui confie une tâche :
« Ajoute les codes promo au panier, avec les tests. »
Ce qui change : qui agit, et ce que le modèle voit.
Un agent va beaucoup plus vite… et vous voyez beaucoup moins ce qui se passe.
AGENTS.md.Une fonction décrite au modèle : un nom, une phrase, des paramètres.
{
"name": "read",
"description": "Read the contents of a file",
"parameters": {
"properties": { "path": { "type": "string" } }
}
}Quand un agent « lance les tests », qui exécute npm test ?
Le modèle n'a fait que demander l'appel.
Il ne voit que le résultat que l'agent lui renvoie.
Puisque c'est l'agent qui exécute, c'est lui qui décide de ce qui est autorisé.
git push : jamais.Dans OpenCode, par défaut… tout est autorisé. 🚨
Les règles de la maison, à la racine du dépôt :
# Boutique BTS
- Tous les montants sont des entiers en centimes.
- Lancez npm test après chaque modification.Recopié au début du contexte, à chaque tour.
Un AGENTS.md de 500 lignes, bonne idée ?
Court, et uniquement ce que le code ne dit pas.
Chaque tour de boucle = une requête HTTP vers l'API du fournisseur.
POST /v1/chat/completions"tool_calls": [{
"function": { "name": "read",
"arguments": "{\"path\": \"src/panier.js\"}" }
}],
"finish_reason": "tool_calls"tool_calls : le modèle attend un outil. stop : c'est fini.
Des messages, des outils, des appels d'outils : seuls les noms changent.
Que se passe-t-il si l'agent renvoie le contenu d'un autre fichier que celui demandé ?
Il n'a aucun moyen de vérifier.
Il fait entièrement confiance à ce qui entre dans son contexte.
Gardez cette idée pour plus tard… 😉
Vous aviez dit « le seuil de 50 € se calcule après la remise ».
Le résumé ne l'a pas gardé. 🚨
Une règle qui compte va dans AGENTS.md… ou dans un test.
Une après-midi d'agent : 150 tours, 40 000 tokens d'entrée par tour.
| Modèle | Une personne | Une classe de 30 |
|---|---|---|
| Claude Sonnet 5.5 | ~ 12,75 $ | ~ 380 $ |
| DeepSeek V4.1 Flash | ~ 1,89 $ | ~ 57 $ |
Pour une seule séance.

La clé d'API ne va jamais dans un fichier du projet.
export LLM_PROXY_API_KEY="votre-cle""apiKey": "{env:LLM_PROXY_API_KEY}"Un fichier du projet → Git → GitLab → n'importe qui.

C'est vous qui allez juger le travail de l'agent.
Si vous ne connaissez pas le projet, vous ne verrez pas ce qu'il casse.
Une bonne demande à un agent = une bonne demande à un collègue.
L'agent Plan lit et propose, sans modifier les fichiers.

« Livraison offerte à partir de 50 €. »
Avant ou après la remise ?
L'agent tranche presque toujours… sans le dire.
C'est une décision métier : à vous de la prendre, et de la faire tester.
git status
git diffOn annule et on reformule, plutôt que d'empiler les corrections.
git restore .Git est votre filet de sécurité.
npm test : vous-même, pas « l'agent dit que ça passe ».BTS10, bts10, un code inconnu…Tant mieux.
Voyons maintenant tout ce qui peut mal tourner. 😈
Un modèle produit le texte le plus probable, pas le texte vrai.
message.innerHTML = "Code inconnu : " + code;Bon signe ?
Ce que tape l'utilisateur est injecté dans la page.
Le code de l'agent se relit comme celui d'un inconnu.
assert.equal(summary(cart).shipping,
cart.subtotal < 5000 ? 490 : 0);Qu'en pensez-vous ?
Si le code se trompe de seuil, le test se trompe pareil… et passe.
assert.equal(summary(panierA4999).shipping, 490);
assert.equal(summary(panierA5000).shipping, 0);Une valeur écrite en dur, et les frontières.
Qu'avez-vous donné en échange ?
Lisez les conditions, à chaque fois.
.env lu = un secret compromis.Le modèle croit tout ce qui entre dans son contexte.
Votre demande, un fichier lu, une page web, un message d'erreur…
Aucune différence entre une donnée et une consigne.
Pas de parade parfaite : on limite les dégâts possibles.

{ "action": "shell", "resource": "*", "effect": "ask" },
{ "action": "shell", "resource": "npm test", "effect": "allow" },
{ "action": "shell", "resource": "rm *", "effect": "deny" },
{ "action": "read", "resource": "*.env", "effect": "deny" }La dernière règle qui correspond l'emporte.

Un deny sur rm * suffit-il à empêcher toute suppression ?
find -delete, git clean -fdx, node -e "…", un script npm…
Une liste noire se contourne toujours.
ask par défaut, une liste blanche courte, un conteneur, et Git.
Il ne se voit pas dans un git diff.
Pour bien utiliser un agent… il faut savoir faire sans.
Relire un diff, repérer un test complaisant, une faille, une ambiguïté : ça s'apprend en codant.
En épreuve comme en entretien : vous serez seul face au code.
Place au TP 🚀