Guide d'ingénierie

Dépôts navigables par les agents

Donnez aux agents de code et aux examinateurs un chemin fiable d'une tâche jusqu'au plus petit code pertinent, aux vérifications et aux preuves de livraison.

Publié le
Mis à jour le
Temps de lecture
16 min de lecture
Sur cette page

Un dépôt est navigable par agent lorsqu'un contributeur — humain ou automatisé — peut découvrir ses règles de fonctionnement, localiser le sous-système pertinent, exécuter la bonne validation et laisser un changement vérifiable sans s'appuyer sur un savoir tribal caché. Il ne s'agit pas d'optimiser le texte pour un modèle : il s'agit de rendre les contraintes de livraison logicielle explicites et exécutables, pour les humains, la CI et les agents à la fois.

Cette discipline compte le plus à l'échelle où tourne une couche d'orchestration edge managée : des dizaines de services y partagent une même surface de livraison, et une frontière introuvable devient un trafic que personne ne surveille. Optimi applique cette même exigence à ses propres dépôts : le travail de Performance, de Sécurité et de Visibilité ne vaut que ce que vaut le chemin qu'un agent a suivi pour le produire.

Le fil conducteur de ce guide est un scénario Acme Shop : sur le ticket ACME-1842, l'API checkout-api doit rejeter un panier dont le pays est manquant avant de calculer la taxe. Un agent bien outillé retrouve seul le bon module à partir des instructions racine, exécute la vérification déclarée et transmet à l'examinateur un résultat reproductible sans avoir chargé le monorepo entier — à condition qu'un fichier d'instructions racine versionné, des exceptions locales limitées aux vraies différences de comportement, des métadonnées de responsabilité et un outillage épinglé soient déjà en place.

Ce qui rend les dépôts navigables par agent

Les dépôts navigables par agent s'appuient sur une convention existante, pas sur un nouveau format : la plupart des agents de code lisent un fichier d'instructions en Markdown simple — souvent nommé AGENTS.md — à la racine du dépôt et dans les répertoires imbriqués, le fichier le plus proche du changement l'emportant en cas de conflit. Aucun champ n'y est obligatoire, ce qui explique pourquoi la discipline compte plus que la syntaxe : des règles repérables, un chemin vers le bon sous-système en une ou deux étapes, une vérification exécutable qui correspond à la CI, et une passation que l'examinateur peut relire plutôt qu'une transcription à rejouer.

Une étude comparant des fichiers d'instructions rédigés par des développeurs à des fichiers générés par IA a montré qu'ils ne sont pas interchangeables : les fichiers écrits à la main produisaient un gain modeste mais mesurable sur le taux de réussite des tâches, alors que les fichiers générés automatiquement — souvent une simple reformulation du README — poussaient les agents à explorer davantage et à consommer plus de tokens sans terminer plus vite ni plus fiablement que des agents privés de tout contexte. La leçon : une carte ne mérite sa place que si un responsable humain l'a relue et qu'elle dit quelque chose que l'arborescence du code ne montre pas déjà.

Fournir des instructions locales et par niveaux

Utilisez un court fichier d'instructions à la racine pour les commandes à l'échelle du dépôt, les limites d'architecture et les règles de sécurité — c'est le socle du contexte pour agent de code que chaque contributeur peut lire avant de commencer. Ajoutez des consignes au niveau des répertoires uniquement lorsque les règles changent réellement, par exemple pour un service avec une commande de test distincte ou un répertoire de clients générés. Gardez les fichiers assez courts pour être lus avant le début du travail et liez des documents plus détaillés au lieu de les dupliquer.

Sur ACME-1842, les instructions racine d'Acme Shop déclarent la commande de référence, le gestionnaire de packages et les chemins restreints — infra/**, services/payments/**, les fichiers .env* — ainsi que le format de passation attendu. Le fichier local de checkout-api n'ajoute que ce qui diffère réellement : le responsable du service, la commande de test ciblée sur la taxe, l'obligation de préserver les codes d'erreur TAX_* et la règle interdisant toute donnée réelle dans les fixtures. Rien n'est répété entre les deux niveaux ; l'agent lit la racine, puis le fichier local le plus proche du chemin modifié, qui l'emporte en cas de conflit.

De bonnes instructions répondent à des questions opérationnelles, pas à des préférences génériques :

  • Comment un agent doit-il établir une référence propre ?
  • Quelles commandes doivent être exécutées pour un changement dans ce répertoire ?
  • Quels chemins sont générés, fournis par un tiers ou restreints ?
  • Quelles API, migrations ou contrats de compatibilité nécessitent l'examen d'un responsable ?
  • Quelles données ne doivent jamais entrer dans les fixtures, journaux, prompts ou snapshots de test ?
  • Quel est le format attendu du changement et de la passation ?

N'utilisez pas les instructions pour accorder une autorité de sécurité. Un fichier local peut dire « ne touchez pas aux paiements » sans que cela empêche techniquement une modification : c'est le sandbox qui limite l'accès au système de fichiers et au réseau, et la CI qui impose les portes de chemin, de test et de revue. Deux dérives méritent une vigilance particulière : un fichier local qui contredit silencieusement la racine au lieu de la préciser, invisible jusqu'à un audit, et une exception temporaire qui survit à sa raison d'être parce que rien ne force son expiration — traitez-la comme un feature flag, avec une échéance de revue, et n'accordez à un fichier imbriqué sa place que s'il énonce ce qui diffère réellement, rien de plus.

Publier une carte de dépôt pour agents, pas une encyclopédie

Les grands dépôts submergent humains et agents lorsque la première réponse contient des milliers de fichiers. Publiez une carte de dépôt pour agents compacte, qui identifie les services déployables, la responsabilité des packages, les principaux points d'entrée, les frontières de données et les commandes de build. Liez chaque composant à ses tests, sa configuration d'exécution et son runbook opérationnel.

Pour Acme Shop, la carte associe checkout-api à son point d'entrée, ses tests, sa responsabilité — validation du panier et contrat de calcul de taxe — et sa dépendance vers l'adaptateur de fournisseur de taxe ; elle indique pour payments-api que l'équipe paiements en est responsable et qu'aucune écriture de checkout-api n'y est autorisée ; et pour infra/, elle rappelle qu'un changement y passe par une tâche revue séparément. Un agent doit démarrer par la tâche et la carte, puis recourir à une recherche ciblée : charger un monorepo entier dans le contexte augmente le coût et peut enfouir la contrainte qui compte.

Préférez des conventions stables à un index qui exige un crawler spécifique au modèle. Des répertoires prévisibles, des noms de packages clairs, des métadonnées de responsabilité et des graphes de dépendances générés fonctionnent dans les IDE, la CI et les outils d'agents. Si un document d'architecture est obsolète, dites-le et pointez vers la source de référence plutôt que de présenter une fiction assurée. Résistez à la tentation de laisser la carte grossir en encyclopédie : elle ne doit consigner que ce que l'arborescence du code ne montre pas déjà. Quand l'équipe commerce-platform a ajouté loyalty-service, la carte n'a gagné qu'une entrée, un responsable et une arête de dépendance — pas une réécriture.

Rendre la référence reproductible

Un agent de code ne peut pas distinguer de façon fiable une nouvelle défaillance d'une défaillance préexistante sans référence connue. Fournissez une commande d'amorçage qui installe les dépendances déclarées, identifie les services requis et signale les prérequis. Fournissez une vérification de santé rapide exécutable avant les modifications, et consignez le résultat attendu lorsqu'une exception connue existe.

Épinglez ou déclarez l'environnement d'exécution, le gestionnaire de packages, le formateur, le compilateur et l'exécuteur de tests. Utilisez des vérifications hermétiques ou conteneurisées pour les dépendances difficiles à reproduire. Évitez les étapes qui dépendent silencieusement du profil shell d'un développeur, d'une base de données locale en cours d'exécution ou d'un identifiant non suivi.

Pour ACME-1842, une trace représentative se lit dans cet ordre : instructions racine puis locales de checkout-api, responsable repéré via la carte, vérification ciblée sur la taxe passant sur douze tests, changement limité à services/checkout-api/**, puis passation indiquant le commit de base et l'absence de risque connu. Ces détails transforment le rapport « les tests sont passés » en une preuve qu'un examinateur peut reproduire sans relire chaque commande.

Une passation ne vaut que ce qu'on peut voir derrière elle

L'équipe plateforme d'Acme relit la passation d'un agent comme MYO d'Optimi observe le trafic edge : un tableau unique qui relie l'identifiant de tâche, le commit de base, la vérification exécutée et l'artefact produit, quel que soit l'agent ou l'exécuteur de CI à l'origine du changement — un seul endroit pour confirmer qu'une passation est fiable avant même de lire le diff.

Transformer les retours en boucle déterministe

Un agent a besoin d'un moyen rapide d'apprendre si son correctif améliore le dépôt. Organisez les vérifications de la moins coûteuse à la plus coûteuse : syntaxe et formatage, types, tests unitaires ciblés, analyse statique, tests de contrat, puis tests d'intégration ou de navigateur. Chaque commande doit échouer avec un code de sortie exploitable et signaler les fichiers pertinents sans inonder la fenêtre de contexte de sorties sans rapport.

Distinguez la boucle d'itération de la barrière d'acceptation. Un test ciblé est idéal lors de la modification d'un module ; un build complet ou une suite de compatibilité des migrations peut être obligatoire avant la fusion. Déclarez les deux, et documentez-les côte à côte : un agent qui voit sa vérification ciblée passer alors que la CI échoue n'apprend rien tant qu'il ne sait pas que la commande locale n'est pas la barrière d'acceptation réelle.

Lorsque les tests sont instables, classez et corrigez cette instabilité au lieu d'entraîner les agents à réessayer indéfiniment. Les tentatives masquent les régressions, gaspillent les budgets de latence et de coût et rendent les évaluations peu fiables.

Préserver l'état entre sessions sans polluer le contexte

Les sessions d'agents sont finies. Stockez l'état durable de livraison dans le dépôt et le système de livraison : liens vers les issues, enregistrement de tâche, commits, descriptions de pull request, artefacts de CI et passation concise du travail non résolu. Une passation doit identifier l'approche retenue, les chemins modifiés, la validation exécutée, les défaillances connues et la prochaine décision, sans reproduire chaque transcription de commande.

Anthropic décrit les fichiers d'avancement structurés comme un moyen de relier des sessions d'agents distinctes. Ce schéma peut être utile pour une branche de longue durée, mais il nécessite des règles de responsabilité et de nettoyage. Préférez les systèmes de référence existants lorsque possible. Un progress.md libre et permanent dans chaque répertoire peut devenir un contexte obsolète que les agents prennent pour la vérité actuelle.

Si une tâche franchit légitimement une frontière de responsabilité, créez un nouveau contrat avec le second responsable plutôt que d'élargir les instructions locales existantes : sur ACME-1843, payments-api avait besoin d'un champ produit par checkout-api pour son rapprochement comptable, et les deux équipes ont préféré une entrée de contrat d'événement versionnée à une écriture inter-services.

Valider la navigation et corriger les lacunes

La navigabilité se vérifie avec quatre types de contrôle : une validation positive, où un espace de travail neuf localise checkout-api depuis la carte racine sans invoquer de service non déclaré ; une validation négative, où une tâche visant services/payments-api/** est orientée vers le bon responsable puis rejetée par la politique de périmètre ; une validation de défaillance, où retirer le double de test du fournisseur de taxe fait s'arrêter l'exécution sur le prérequis manquant plutôt que d'inventer un identifiant de production ; et une validation de dérive, qui relit périodiquement la carte au regard de ce qui existe réellement — c'est ainsi que commerce-platform a découvert que la commande de test de loyalty-service avait changé sans que son fichier local soit mis à jour.

Corriger une lacune signifie réparer la carte ou le contrat d'amorçage dans un changement revu, puis relancer depuis un espace de travail propre plutôt que de rustiner le résultat en place.

Allouer délibérément contexte, latence et coût

La navigation dans un dépôt est un problème de budget. Fixez des tailles de sortie maximales pour les recherches et journaux, utilisez des filtres de fichiers et de symboles, et excluez par défaut les fichiers générés ou de verrouillage du contexte, sauf si la tâche les requiert. Mettez en cache les métadonnées immuables du dépôt par commit, mais invalidez-les lorsque les instructions, manifests de dépendances ou interfaces générées changent.

Suivez séparément le temps passé à l'amorçage, à la découverte du dépôt, à l'inférence du modèle, à l'exécution des tests et aux tentatives. Une exécution lente d'agent peut être due à une installation massive de dépendances ou à un environnement de test bloqué, plutôt qu'au raisonnement du modèle. Les contrôles de coût doivent préserver la correction : réduire le contexte en masquant les règles de responsabilité ou la sortie de test ne fait que créer plus tard un travail d'examen coûteux.

Examiner le dépôt comme une interface d'agent

Attribuez périodiquement une tâche bornée à un espace de travail d'agent neuf et doté du privilège minimal, puis observez où il se perd. Parmi les défauts fréquents figurent les instructions contradictoires entre niveaux, les prérequis de configuration manquants, les fichiers générés ambigus, les commandes de test exigeant un état non documenté, les passations trop volumineuses pour être relues et les instructions générées automatiquement qui ne font que reformuler le README sans rien apporter que l'arborescence ne montre déjà.

Mesurez la réussite de la référence au premier essai, le temps nécessaire pour localiser le composant responsable, le taux de réussite de validation, le contexte consommé avant la première modification, les reprises demandées par les examinateurs et les tâches abandonnées. Comparez ces métriques par révision du dépôt et version de l'environnement. Le but n'est pas de rendre chaque tâche autonome, mais de rendre le bon chemin contraint facile à suivre.

Liste de contrôle du dépôt

  • Gardez les instructions racine et locales concises, versionnées et cohérentes avec la CI.
  • Publiez la responsabilité des composants, les points d'entrée, les frontières de données et les commandes de validation.
  • Fournissez un amorçage propre et une vérification de référence rapide sans état local implicite.
  • Séparez les vérifications d'itération ciblées des barrières d'acceptation bloquant la fusion.
  • Stockez les passations durables dans les enregistrements de livraison existants et supprimez les notes temporaires obsolètes.
  • Limitez le contexte par défaut et la sortie des commandes tout en préservant les preuves nécessaires au débogage.
  • Imposez les limites de secrets, réseau et écriture par une politique, non par la seule documentation.
  • Détectez les contradictions entre fichiers d'instructions imbriqués avant la fusion, et ne conservez une carte ou un contenu généré automatiquement que s'il dit ce que l'arborescence ne montre pas déjà.

Références faisant autorité

Apportez la même discipline à votre surface de livraison edge

Optimi orchestre la Performance, la Sécurité et la Visibilité sur l'ensemble de votre pile de fournisseurs via MYO, pour donner aux équipes d'ingénierie et de plateforme un endroit unique où confirmer qu'un changement — humain ou produit par un agent — est sûr à livrer.

Parler à Optimi de la visibilité de livraison