Qu’est-ce que la conception de boucles IA ?
Définition de la conception de boucles IA : déclencheur, périmètre, vérification et budget d’un agent qui répète ses tâches, plutôt qu’un simple prompt.
Ce que signifie la conception de boucles
La conception de boucles consiste à définir le cycle répétitif d’un agent IA : ce qui le réveille, les éléments auxquels il peut accéder, la manière dont sa sortie est vérifiée et ce qui l’arrête. La conception de prompts façonne un message destiné à un modèle. La conception de boucles façonne le processus qui envoie des milliers de messages pendant votre sommeil. L’unité de travail n’est plus le prompt, mais la boucle.
En bref : vous cessez d’écrire des instructions et commencez à écrire un système de contrôle. L’agent a toujours besoin de bonnes instructions, mais celles-ci deviennent un composant d’un cycle qui s’exécute selon un calendrier, travaille dans une copie isolée de votre code, vérifie son propre résultat avec un test et s’arrête lorsque le budget est épuisé.
Pourquoi le terme est apparu en 2026
Le nom est actuellement en train de s’imposer dans le domaine public. Le dépôt GitHub cobusgreyling/loop-engineering a dépassé 9,600 étoiles en moins de deux mois après sa première apparition (chiffres de juillet 2026) et en affichait environ 11,600 le 2026-10-27, avec la formule « Stop prompting. Design the loop. Get a score. » En juillet 2026, son README regroupait cette évolution en six éléments : planification, worktrees, skills, plugins et connecteurs, sous-agents, et mémoire persistante conservée en dehors de la conversation. Le README actuel ne contient plus cette liste (vérification effectuée le 2026-10-27), mais il conserve toujours l’état de la boucle dans un fichier situé en dehors de la conversation.
Le dépôt cite Boris Cherny, responsable de Claude Code chez Anthropic, parmi ses sources d’inspiration. La phrase qui lui est largement attribuée est la suivante :
I don't prompt Claude anymore. I have loops running that prompt Claude.
Un deuxième dépôt, AI-Builder-Club/skills, approche les 1,300 étoiles (au 2026-10-27) et nomme directement les deux rôles : un « codebase harness » qui permet à un agent d’exécuter des tests et des déploiements dans un dépôt en toute sécurité, et un « loop engineer » qui construit des workflows qui se déclenchent, effectuent le travail, puis écrivent ce qu’ils ont appris dans un fichier partagé afin que la boucle suivante puisse le lire.
Aucun des deux dépôts n’a inventé cette pratique. Toute personne qui a déjà exécuté un build nocturne, un linter dans une intégration continue ou une tâche cron qui ouvre un ticket en connaît déjà le principe. Ce qui est nouveau, c’est que le worker de la boucle est désormais non déterministe, ce qui change les tâches que doit assurer l’infrastructure environnante.
Les quatre éléments d’une boucle
Toute boucle fonctionnelle comporte ces quatre éléments. Une boucle qui en omet un est celle qui vous réveille à 3am.
- Déclencheur. L’événement qui démarre une exécution : un timer, un webhook, une nouvelle pull request ou une alerte.
- Périmètre. Les fichiers, les identifiants et le réseau auxquels l’agent peut accéder pendant cette exécution.
- Vérification. Un contrôle avec un exit code qui détermine si le résultat de l’exécution est conservé ou rejeté.
- Budget. La limite de tokens, de temps et d’argent qui met fin à l’exécution, qu’elle ait réussi ou non.
Transformez ces quatre éléments en questions : vous obtenez une revue de conception pour tout agent que vous vous apprêtez à laisser s’exécuter.
Déclencheur : ce qui réveille l’agent
Un timer est le déclencheur le plus simple. Sur un serveur Linux, un timer systemd est préférable à cron, car il journalise les exécutions, réessaie selon vos paramètres et ne lance pas une seconde instance d’une unité qui s’exécute encore. Cette dernière propriété élimine le problème de chevauchement le plus courant dans les boucles d’agent : deux exécutions qui modifient la même branche.
Commencez par créer un utilisateur dédié à l’agent. Cet utilisateur fait partie de la boundary : il possède /srv/agent, et rien d’autre :
sudo useradd --system --home-dir /srv/agent --shell /usr/sbin/nologin agent
sudo chown -R agent:agent /srv/agentÉcrivez ensuite l’unité dans /etc/systemd/system/agent-loop.service :
[Unit]
Description=Agent loop: triage open issues
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
User=agent
WorkingDirectory=/srv/agent/repo
ExecStart=/srv/agent/bin/loop.sh
TimeoutStartSec=1800Puis le timer dans /etc/systemd/system/agent-loop.timer :
[Unit]
Description=Run the triage loop every 30 minutes
[Timer]
OnBootSec=5min
OnUnitActiveSec=30min
Unit=agent-loop.service
[Install]
WantedBy=timers.targetsudo systemctl daemon-reload
sudo systemctl enable --now agent-loop.timer
systemctl list-timers agent-loop.timersystemctl list-timers doit afficher une colonne NEXT avec une heure future et une colonne LEFT indiquant le compte à rebours. Un résultat vide signifie que le timer n’est pas activé, car enable sans --now le programme uniquement pour le prochain boot. TimeoutStartSec=1800 est plus important qu’il n’y paraît. Un service Type=oneshot est considéré comme en cours de démarrage jusqu’à la fin de son script. Par défaut, systemd désactive le délai maximal de démarrage pour les unités oneshot. Sans cette ligne, un agent bloqué en attente d’une entrée conserve donc l’unité indéfiniment dans l’état activating. À chaque déclenchement suivant du timer, systemd constate qu’il s’exécute encore et ne lance rien. Avec cette ligne, systemd termine l’exécution au bout de 30 minutes et la marque comme échouée. Si vous remplacez un jour l’unité par le type par défaut Type=simple, TimeoutStartSec ne couvre plus l’exécution elle-même. C’est alors RuntimeMaxSec= qui la limite. Consultez une exécution avec journalctl -u agent-loop.service -n 50.
Si vous pilotez plutôt la boucle avec cron, ajoutez votre propre protection contre les chevauchements, car cron lancera volontiers une seconde instance :
*/30 * * * * /usr/bin/flock -n /tmp/agent-loop.lock /srv/agent/bin/loop.shflock -n se termine immédiatement avec le statut 1 lorsque le lock est déjà détenu. La seconde exécution disparaît donc silencieusement au lieu d’entrer en concurrence avec la première. La même configuration de service et de timer systemd s’applique à tout job de longue durée sur la machine, agent ou non.
Frontière : attribuer sa propre copie à chaque exécution
Un agent qui modifie votre arbre de travail peut écraser votre travail non validé. Les worktrees Git règlent ce problème à moindre coût : chaque exécution dispose de son propre répertoire et de sa propre branche, tout en partageant un même object store.
cd /srv/agent/repo
git worktree add -b loop/triage-01 /srv/agent/work/triage-01 origin/main
git worktree listgit worktree list affiche une ligne par arbre, avec son chemin, son commit et sa branche. À la fin de l’exécution, git worktree remove /srv/agent/work/triage-01 supprime le worktree, mais uniquement s’il est propre. Si l’arbre contient des fichiers non suivis ou des fichiers suivis modifiés, ou s’il contient des submodules, Git refuse l’opération tant que vous n’ajoutez pas --force. C’est pourquoi le script de contrôle ci-dessous force la suppression uniquement sur le chemin utilisé pour abandonner l’exécution. git worktree prune supprime les entrées dont le répertoire a disparu. Les boucles parallèles deviennent sûres à ce stade, car deux agents travaillant sur deux branches dans deux répertoires ne peuvent pas s’écraser mutuellement.
La frontière concerne également les identifiants d’accès. Une boucle exécutée sans surveillance contient des tokens persistants, et chaque exécution peut en divulguer un dans un journal, un commit ou le contexte d’un modèle. Limitez le token au seul dépôt utilisé par la boucle. Lorsque c’est possible, empêchez-le d’apparaître dans l’environnement visible par le shell de l’agent. Consultez comment empêcher les agents IA d’accéder aux secrets avant d’accorder à une boucle un accès à la production. Pour renforcer l’isolation, exécutez toute la boucle dans une VM jetable que vous pouvez détruire après chaque exécution. L’outil utilisé définit lui aussi une partie de cette frontière avant même que vous écriviez quoi que ce soit. Il est donc utile de lire comment le sandbox géré de Cowork se compare à Claude Code sur votre propre machine avant de décider du niveau d’isolation à mettre en place vous-même.
Vérification : le contrôle qui rend la boucle sûre
C’est la partie qui distingue une boucle d’un cron qui saisit des commandes. La sortie de l’agent est une proposition. Le contrôle prend la décision.
#!/usr/bin/env bash
set -euo pipefail
repo=/srv/agent/repo
branch="loop/$(date -u +%Y%m%dT%H%M%SZ)"
tree="/srv/agent/work/$(basename "$branch")"
cd "$repo"
git fetch --quiet origin
git worktree add -b "$branch" "$tree" origin/main
cd "$tree"
# the agent's own command runs here, in non-interactive mode
if ! npm test; then
echo "gate failed: discarding $branch" >&2
cd "$repo"
git worktree remove --force "$tree"
exit 1
fi
git push origin "$branch"
cd "$repo"
git worktree remove "$tree"set -euo pipefail effectue un vrai travail dans ce script. Sans -e, un git fetch en échec est ignoré et l’exécution continue avec un origin/main obsolète. Sans -u, une faute de frappe dans un nom de variable est remplacée par une chaîne vide, puis le nettoyage s’exécute sur le mauvais chemin au lieu d’échouer explicitement. La dernière ligne n’a volontairement pas de --force : si l’exécution a laissé des fichiers non suivis ou non validés dans l’arborescence, git refuse de la supprimer, et -e termine l’exécution avec une erreur après le push au lieu de supprimer silencieusement du travail que personne n’a validé.
Le bloc if ! npm test contient toute l’idée. Le code de sortie d’un contrôle auquel vous faites déjà confiance, votre suite de tests ou votre vérificateur de types, détermine si la branche est poussée ou supprimée. Une boucle sans contrôle produit du travail que personne n’a le temps de relire, ce qui est pire que l’absence de travail. Une boucle avec un contrôle produit une branche qui a déjà satisfait le même niveau d’exigence que celui imposé à la branche d’un contributeur humain. Un contrôle au vert ne dit rien de la quantité de code que l’agent a modifiée pour y parvenir. Il est donc utile d’associer ce contrôle à une instruction permanente comme la règle qui oblige un agent à appliquer la plus petite modification fonctionnelle, afin que le diff reste assez petit pour être relu rapidement.
Choisissez un contrôle qui échoue de manière fiable. Une suite de tests qui réussit avec un diff vide apprend à la boucle que ne rien faire est un succès. Les dépôts dont les tests sont faibles produisent des boucles faibles. C’est pourquoi les dépôts populaires placent « rendre la base de code prête pour les agents » avant « écrire la boucle ». Si vous voulez savoir si votre suite détecterait réellement une régression au lieu de se contenter d’exécuter les lignes concernées, le mutation testing est le contrôle qui répond à cette question. Un agent qui renvoie un rapport de preuves réexécutable au lieu de vous demander de lire son diff transforme ensuite ce résultat en élément que vous pouvez vérifier vous-même.
Budget : ce qui arrête une exécution
Un agent qui réessaie indéfiniment génère une facture sans limite. Donnez à chaque boucle une durée maximale, imposée par TimeoutStartSec ci-dessus ; ajoutez un compteur de tentatives dans votre script ; et définissez un plafond de dépenses au niveau du compte fournisseur. Journalisez ensuite le coût de chaque exécution afin de détecter une dérive de la boucle avant de la voir apparaître sur la facture. Contrôler les coûts d’un VPS avec un agent actif en permanence traite l’aspect comptable, tandis que gérer le contexte qu’un agent conserve entre deux tours couvre le principal levier du coût par exécution : une boucle qui relit le même dépôt toutes les 30 minutes le paie toutes les 30 minutes.
Le coût explique pourquoi les boucles sont généralement préférables à une longue session. Une exécution qui démarre dans un contexte vierge, effectue une tâche précise, puis se termine conserve un contexte réduit. Une session laissée ouverte pendant huit heures conserve dans son historique toutes les erreurs précédentes et facture l’intégralité de la transcription à chaque tour.
Les modèles formalisés par les dépôts en vogue
Le dépôt consacré au loop engineering répertorie huit modèles de production (au 2026-10-27), qu’il vaut mieux lire comme un menu plutôt que comme un manifeste. Triage quotidien. Une boucle légère qui s’exécute comme une GitHub Action et ne conserve aucun fichier d’état. Un assistant de pull request qui surveille les commentaires de review et y répond. Un outil de contrôle de l’intégration continue qui récupère les builds en échec. Un outil de contrôle des dépendances. Un outil de rédaction du changelog. Le nettoyage post-merge. Le triage des issues.
Ils ont en commun une tâche limitée et une condition de validation évidente. « Corriger le build en échec » possède une condition de réussite que la machine peut lire. « Améliorer le codebase » n’en possède pas ; cette tâche ne devient donc jamais une boucle. Elle devient un désordre exécuté selon un planning.
Ils ont également en commun une trace écrite. Les deux dépôts déplacent l’état hors de la conversation et le stockent dans des fichiers du dépôt : ce qui a été exécuté, ce qui a été trouvé, ce qui a été décidé. Ce fichier constitue la mémoire de la boucle. C’est ce qui permet à une seconde boucle de s’appuyer sur le travail de la première au lieu de le redécouvrir. C’est aussi ainsi que vous pouvez auditer un agent a posteriori, puisque le contexte du modèle disparaît dès que l’exécution se termine. La coordination en temps réel utilise un canal distinct, et une session Claude Code peut transmettre du travail à une autre sur la même machine pendant qu’elles sont encore toutes les deux en cours d’exécution, mais rien de cet échange ne subsiste après la fin de l’une ou l’autre session. Le fichier reste donc l’élément que vous pourrez relire ultérieurement.
Quand les boucles échouent
Les échecs sont prévisibles et se répètent d’une équipe à l’autre.
- Aucune barrière. La sortie s’accumule, personne ne la vérifie, la confiance disparaît et la boucle est désactivée.
- Chevauchement. Deux exécutions sur une même branche, ou deux agents dans le même working tree, produisent des conflits que l’agent tente ensuite de résoudre.
- Dérive silencieuse. La boucle continue de réussir parce que le contrôle est trop faible pour échouer.
- Périmètre illimité. Un trigger qui se déclenche à chaque commit dans un dépôt très actif devient un problème de coûts en une journée.
La correction est toujours la même : réduire la tâche, rendre le contrôle plus précis et journaliser l’exécution. Si vous ne pouvez pas décrire la condition de réussite en une phrase, la tâche n’est pas prête à être automatisée.
Débuter sans le vocabulaire
Vous n’avez pas besoin d’un framework. Un petit serveur Linux toujours allumé, un dépôt git dont la suite de tests échoue quand elle le devrait, un timer systemd et un script shell contenant un if forment une boucle complète. C’est réellement par là que la plupart des utilisateurs devraient commencer, car les choix d’architecture se tranchent en exécutant le système plutôt qu’en choisissant un outil. Une fois une boucle stable, en exécuter une deuxième consiste principalement à ajouter un autre timer et un autre worktree. Consultez comment exécuter un agent d’IA de programmation sur un VPS pour la configuration de base, et les options actuelles d’agents d’IA auto-hébergés si vous voulez que l’agent s’exécute lui-même sur du matériel que vous contrôlez.
FAQ
L’ingénierie des boucles est-elle différente de l’ingénierie des prompts ?
L’ingénierie des prompts optimise un message : formulation, exemples et format de sortie. L’ingénierie des boucles optimise le cycle autour du message : le déclencheur qui démarre une exécution, la sandbox dans laquelle elle s’exécute, le contrôle qui accepte ou rejette sa sortie et le budget qui y met fin. Vous avez toujours besoin d’un bon prompt dans la boucle. Mais le prompt n’est plus l’élément que vous ajustez au quotidien, car le contrôle et le déclencheur ont davantage d’effet sur le résultat.
Ai-je besoin d’un framework pour créer une boucle d’agent ?
Non. Un timer systemd, un git worktree par exécution, un script shell qui se termine par une commande de test et un plafond de dépenses sur le compte du fournisseur couvrent tous les éléments de la définition. Les frameworks ajoutent des interfaces de planification, des formats de mémoire partagée et du routage entre agents. Ces fonctions deviennent utiles lorsque vous exécutez plusieurs boucles. Elles ne sont pas nécessaires pour commencer.
Qu’est-ce qu’un harness de codebase ?
C’est l’ensemble des éléments qui permettent à un agent de travailler dans un repository sans présence humaine : une configuration en une commande, des tests exécutables sans interaction et qui échouent explicitement, un linter, ainsi qu’un moyen de déployer ou de prévisualiser une modification. Le terme vient de la même vague de repositories de 2026 que l’ingénierie des boucles. Le test pratique est simple : si un nouveau contributeur humain ne peut pas passer du clone à des tests au vert avec une seule commande, un agent ne le peut pas non plus.
Comment empêcher une boucle d’agent de générer une facture élevée ?
Plafonnez-la à trois endroits. Définissez TimeoutStartSec sur une unité systemd Type=oneshot comme celle présentée plus haut afin de tuer une exécution bloquée. Pour un service Type=simple, l’équivalent est RuntimeMaxSec. Limitez le nombre de retries dans le script au lieu de boucler jusqu’à la réussite. Définissez une limite de dépenses stricte sur le compte API, car c’est le seul plafond que l’agent ne peut pas contourner en argumentant. Journalisez ensuite le coût de chaque exécution : lorsqu’une boucle double son coût, son périmètre s’est généralement élargi discrètement.
Quels jobs faut-il transformer en boucle en premier ?
Choisissez un job avec une condition de réussite lisible par une machine et un faible blast radius. Corriger un build en échec, mettre à jour une dépendance et régénérer un changelog conviennent tous, car une suite de tests ou un diff peut prouver le résultat. Les tâches ouvertes, comme le refactoring ou la conception, ne conviennent pas encore : le contrôle n’a rien à vérifier. Une boucle sans contrôle est un moyen coûteux de générer de la dette de review.