Recherche

Les essaims d’agents et la nouvelle économie des modèles

Wilson Lin20 min de lecture

Plus tôt cette année, nous avons mené des expérimentations pour tester les limites du passage à l’échelle d’agents capables de coopérer vers un objectif commun. Notre hypothèse était que cela ouvrirait un nouveau palier en matière d’ampleur et de complexité des tâches.

Le projet phare était un essaim de longue durée créant un Browser web à partir de zéro. L’expérience a servi de preuve de concept, mais restait très loin d’un logiciel abouti.

Ce travail était délibérément empirique. Nous sommes partis d’une page blanche et avons progressé par ajustements successifs vers un système stable et efficace. Depuis, notre objectif est de comprendre suffisamment bien l’essaim d’agents pour le concevoir de manière délibérée.

Pour évaluer ces progrès, nous sommes revenus à une tâche sur laquelle l’ancien essaim avait buté : créer SQLite à partir de zéro, en Rust, uniquement à partir de sa documentation.

Nos premiers résultats ont été prometteurs. Nous avons exécuté l’ancien et le nouvel essaim sur la même tâche, avec les mêmes modèles et le même budget de temps, puis mesuré la part d’une suite de tests SQL distincte que chacun parvenait à réussir.

Le nouvel essaim a fait mieux dans chaque configuration de modèles. Avec Grok 4.5, il a atteint 80 % en quatre heures, tandis que l’ancien essaim s’est enlisé et a dû être mis en pause avant la fin de sa deuxième heure.

Nous avons également fait varier la répartition des rôles entre les modèles. Dans certaines exécutions, un seul modèle s’occupait de tout ; dans d’autres, un modèle de pointe planifiait pendant qu’un modèle rapide et peu coûteux exécutait le travail. Tous les répartition des modèles ont produit une qualité similaire, mais les coûts variaient énormément.1

Coût de recréation de SQLite par répartition des modèles avec les anciens et les nouveaux essaims d’agentsCoût de recréation de SQLite par répartition des modèles avec les anciens et les nouveaux essaims d’agents

Arbres et feuilles

Les descriptions de tâches de grande ampleur prennent naturellement la forme d’arbres, avec un objectif à la racine qui se subdivise récursivement en unités de travail élémentaires. Notre essaim comporte deux rôles, tous deux organisés autour de cette même décomposition arborescente :

  • Les agents planner, qui s’appuient sur les modèles les plus performants, divisent un objectif en plusieurs éléments et les délèguent.
  • Les agents worker, qui s’appuient généralement sur des modèles plus rapides et moins coûteux, exécutent ces éléments.

Cette architecture va au-delà des systèmes d’orchestration plus rigides. Au lieu d’imposer une topologie fixe au problème, la forme de l’essaim se développe pour en épouser les contours, et les ressources de calcul comme le contexte passent à l’échelle en proportion de la complexité de la tâche.

Nous pensons que c’est pour cette raison que cette architecture se généralise à des tâches aussi diverses que créer un Browser, résoudre des problèmes de mathématiques et optimiser des kernels GPU. Nous l’avons aussi utilisée en interne pour trouver et corriger des vulnérabilités dans des logiciels open source, augmenter la couverture de test de notre propre base de code et générer des milliards de tokens de données d’entraînement synthétiques.

Ce que l’arbre apporte à la mémoire

Lorsqu’un seul agent prend en charge une tâche complète, il doit parcourir tout l’arbre lui-même, descendre jusqu’à chaque feuille tout en gardant en contexte ses nœuds parents, sa position actuelle et l’objectif global pendant toute la durée du processus.

Nous pensons que cela explique pourquoi les agents seuls qui travaillent sur de longues durées finissent par dériver. Ils peuvent soit se concentrer sur le travail immédiat et perdre de vue l’ensemble, soit garder la vue d’ensemble et moins bien traiter la partie sur laquelle ils travaillent.

Dans un essaim, un planner n’implémente jamais, donc son contexte ne se remplit pas de détails de bas niveau, et un worker ne planifie jamais, donc il peut consacrer tout son contexte à une portion précise du travail.

Schéma de la décomposition du travail entre les agents planner et worker dans un arbre de tâchesSchéma de la décomposition du travail entre les agents planner et worker dans un arbre de tâches

Nous pensons que la capacité de l’essaim d’agents à passer à l’échelle vient davantage de cette efficacité contextuelle que du parallélisme lui-même. Cette efficacité est présente dans l’essaim à toutes les échelles, ce qui explique pourquoi cette décomposition améliore les performances des agents même sur des tâches de taille modérée.

On retrouve des échos de cette structure ailleurs. L’économiste Ronald Coase, en se demandant pourquoi les entreprises existent tout simplement, a soutenu que les coûts de coordination augmentent plus vite que le travail lui-même, si bien que les organisations se structurent en niveaux d’unités délimitées plutôt que de laisser tout le monde parler à tout le monde.

Un système de gestion de versions pour les agents

Dans un article précédent sur le essaim, nous avons indiqué que des outils comme Git et Cargo s’appuient sur des verrous grossiers pour gérer la concurrence. Cela convient pour un seul développeur, mais devient impraticable face au volume de travail produit par des centaines d’agents simultanés.

Le essaim de Browser du début de l’année a culminé à environ 1 000 commits par heure sur Git. Le nouveau système atteint un pic d’environ 1 000 commits par seconde.

Pour soutenir ce rythme d’activité, nous avons conçu de zéro un nouveau système de gestion de versions (VCS). Le débit n’était pas la seule raison de garder la main sur cette couche. Chaque changement dans le système passe par le VCS : c’est donc là que les conflits deviennent d’abord visibles, et c’est aussi là que plusieurs des mécanismes de coordination de la section suivante sont implémentés directement.

Modes de défaillance à 1 000 commits par seconde

Les équipes d’ingénierie humaines disposent de mécanismes de coordination habituels, comme la revue de code, la répartition des responsabilités, les standups et les files d’attente de fusion. Ces systèmes fonctionnent à un rythme humain, mais au rythme de commits de l’essaim, nous observons des modes de défaillance que les équipes humaines ne rencontrent pas habituellement.

Conception en mode split-brain

Deux planners, sans avoir connaissance l’un de l’autre, implémentent le même concept de différentes façons dans différentes parties de la base de code.

Nous avons corrigé cela grâce au prompting. Les planners prennent eux-mêmes les décisions de conception au lieu de les déléguer, et nous exigeons qu’ils veillent à ce qu’aucun sous-arbre délégué ne tranche la même question.

Conflit entre planners

Une forme de conflit plus difficile survient lorsque deux planners ont connaissance l’un de l’autre et s’affrontent à coups d’allers-retours de modifications sur les mêmes fichiers.

Le problème, c’est qu’il existe alors deux versions de la réalité, et les outils de fusion ne peuvent pas résoudre un désaccord. À la place, nous demandons aux agents de consigner les décisions dans des documents de conception partagés. Le code qui dépend d’une décision contient une référence vers son document, vérifiée à la compilation. Lorsque des planners se contredisent sans le savoir, un processus de réconciliation fusionne les documents et les références propagent la résolution en aval.

Conflits de fusion

Au sein de l’essaim, les agents entrent constamment en collision sur les mêmes fichiers. Pour résoudre une collision, ils devraient s’arrêter, assimiler le contexte de l’autre agent, puis fusionner en en tenant compte. Les agents worker gèrent mal ce genre de situation et, en pratique, soit écrasent la modification de l’autre, soit abandonnent la leur.

Pour résoudre ce problème, nous avons créé un système dans lequel un agent tiers neutre intervient lors des conflits de fusion et les résout pour le compte de toutes les parties. Son seul objectif est d’être impartial et efficace, à l’image des files d’attente de fusion dans les équipes d’ingénierie.

Mégafichiers

Certains fichiers sont particulièrement prisés par les agents. Chaque agent n’ajoute parfois qu’une petite quantité de code, et aucun agent, à lui seul, n’est responsable de maintenir ces fichiers à une taille réduite.

Ces « mégafichiers » finissent par tout étouffer. Ils coûtent cher à transporter, à analyser en diff et à fusionner, et deviennent le théâtre de collisions permanentes.

Pour remédier à cela, nous avons donné aux agents workers un moyen de signaler les fichiers trop volumineux. Une fois signalés, nous bloquons les nouveaux commits et un agent externe décompose le fichier surdimensionné en modules plus petits.

Ossification

Les agents ont appris, en travaillant sur des bases de code existantes avec des humains dans la boucle, à ne pas toucher au code critique, même lorsqu'il doit changer.

Pour remédier à cela, nous autorisons délibérément des modifications cassantes. Un agent qui juge qu'un changement du cœur du système en vaut la peine peut effectuer un correctif ciblé en dehors de son périmètre et laisser un commentaire expliquant pourquoi il l'a fait.

Le compilateur répercute ensuite la modification dans le reste du système, et tout ce qui dépend de l'ancienne conception ne compile plus. Chaque agent qui rencontre l'une de ces erreurs trouve le commentaire, lit le raisonnement et met à jour sa propre partie du travail en conséquence.

Angles de revue

Dans un système à la fois de longue durée et multi-agents, les erreurs s’accumulent, et l’essaim a besoin d’un moyen de s’autocorriger avant que de petites erreurs ne deviennent fondamentales.

Nous avons expérimenté de nombreux types d’angles de revue, par exemple en donnant à un agent de revue la transcription complète du worker, ou seulement sa sortie, ou rien d’autre que la base de code. Nous avons aussi testé des agents de revue s’exécutant sur différents modèles, avec des entraînements différents et des personnalités différentes.

Aucun angle ne permet de tout détecter, mais des angles décorrélés se complètent, de la même manière que les systèmes de conduite autonome atteignent une fiabilité supérieure à celle des humains sans qu’aucun composant ne soit parfait à lui seul. Les ressources de calcul consacrées à la revue offrent un excellent retour sur investissement, puisque la revue coûte bien moins cher que le travail qu’elle contrôle. Nous pensons que ce système de revue en couches a largement contribué à la qualité constante des exécutions.

Laisser les agents façonner l’environnement

La stigmergie est le mécanisme par lequel des organismes vivant en essaim, comme les fourmis et les termites, se coordonnent sans communication directe. Ils façonnent l’environnement, puis l’environnement façonne l’organisme suivant.

Lors d’exécutions antérieures, nous avions intégré des règles comme « prendre des notes » et « documenter les décisions », car elles semblaient évidemment utiles. Avec le recul, elles permettaient aux agents d’institutionnaliser les connaissances pour eux-mêmes à l’avenir et pour leurs coéquipiers.

Nous avons poussé cette idée plus loin avec une expérimentation de contexte partagé, rédigé par les agents eux-mêmes, que nous appelons le Field Guide. C’est un dossier qui appartient entièrement aux agents, dont le index.md est automatiquement injecté dans chaque agent au démarrage. C’est aux agents de décider de ce qui entre dans le guide, et leur seule contrainte est un budget de lignes.

La logique sous-jacente du guide est que les poids du modèle sont figés : ce sont donc précisément les situations inattendues qui méritent d’être consignées, afin que la trajectoire du prochain agent soit plus courte.

Le Field Guide est une première expérimentation aux résultats prometteurs. Nous nous attendons à ce que les bénéfices soient encore plus importants sur des bases de code que les agents ne maîtrisent pas entièrement. Entraîner les modèles à écrire pour leurs successeurs, là où une meilleure consignation mène à de meilleures récompenses, constitue une piste de recherche intéressante pour la suite.

L'expérimentation SQLite

Nous avons demandé à la nouvelle version de l'essaim, dotée de toutes les améliorations décrites ci-dessus, d'implémenter l'intégralité du manuel SQLite de 835 pages en Rust. Nous ne lui avons pas fourni le code source, les suites de tests, le binaire SQLite ni l'accès à Internet.

Pour mesurer les progrès, nous avons évalué les résultats à l'aide de sqllogictest, une suite de tests du projet SQLite conçue pour vérifier que différents moteurs de base de données renvoient les mêmes résultats pour les mêmes requêtes. Elle contient des millions de requêtes dont les bonnes réponses sont connues, et la note correspond à la proportion de réponses justes obtenues par la base de données de l'essaim. Les progrès se manifestent par une courbe ascendante au fil d'une exécution.

L'essaim n'a jamais été informé de l'existence de cette suite. Après chaque exécution, nous avons examiné manuellement le code et l'exécution elle-même, en vérifiant l'absence de triche et de raccourcis, et en confirmant que le système avait été construit de manière homogène, plutôt que seulement là où les tests regardent.

Lorsque vous lisez les courbes, gardez à l'esprit que les agents ont choisi leurs propres stratégies. Certains ont posé des bases larges et obtenu de faibles scores pendant des heures avant une hausse tardive, tandis que d'autres ont approfondi un domaine, obtenu de bons scores rapidement, puis plafonné en complétant le reste. Les tendances comptent plus que les scores exacts à des moments précis.

Résultats selon les répartitions des modèles

Nous avons testé quatre configurations couvrant la puissance et le coût :

  1. GPT-5.5 comme planner et comme worker. Un modèle de pointe performant de bout en bout.2
  2. Grok 4.5 comme planner et comme worker. Notre modèle de pointe le plus rentable, utilisé comme point de comparaison.
  3. Opus 4.8 comme planner et Composer 2.5 comme worker. Un jugement de pointe associé à une exécution efficace.
  4. Fable 5 comme planner et Composer 2.5 comme worker. Pour voir si un planner de gamme inférieure rend l’hybride plus ou moins intéressant.

Le nouveau harness a surpassé l’ancien dans toutes les configurations.

L’hybride Fable 5 a validé environ les deux tiers de la suite de tests dans la première heure. Au bout de quatre heures, les nouvelles exécutions affichaient entre 73 % et 85 %, tandis que les anciennes allaient de 11 % à 77 %.

L’ancienne exécution de Grok 4.5 a été mise en pause avant d’atteindre les deux heures (voir plus bas). Toutes les nouvelles configurations ont ensuite fini par valider 100 % de la suite de tests.

À l’avenir, nous aimerions exécuter la matrice N×N complète des combinaisons planner-worker. Pour ce cycle, la comparaison qui compte est celle entre les versions du harness, et les différences de comportement se sont révélées bien plus importantes que ne le laissaient penser les écarts de score.

Résultats de la suite de tests SQLite au fil du temps pour GPT-5.5 avec les anciens et les nouveaux essaimsRésultats de la suite de tests SQLite au fil du temps pour GPT-5.5 avec les anciens et les nouveaux essaims
Résultats de la suite de tests SQLite au fil du temps pour Grok 4.5 avec les anciens et les nouveaux essaimsRésultats de la suite de tests SQLite au fil du temps pour Grok 4.5 avec les anciens et les nouveaux essaims
Résultats de la suite de tests SQLite au fil du temps pour Opus 4.8 comme planner avec Composer 2.5 comme workerRésultats de la suite de tests SQLite au fil du temps pour Opus 4.8 comme planner avec Composer 2.5 comme worker
Résultats de la suite de tests SQLite au fil du temps pour Fable 5 comme planner avec Composer 2.5 comme workerRésultats de la suite de tests SQLite au fil du temps pour Fable 5 comme planner avec Composer 2.5 comme worker

Analyse approfondie des exécutions

En partant de la mesure d’activité la plus simple, on voit comment le rythme des commits a varié pour Grok 4.5 entre l’ancien harness et le nouveau. L’ancienne exécution a produit 68 000 commits au cours de ses deux premières heures, soit un rythme environ 70 fois plus élevé que celui de la nouvelle.

On peut y voir un signe de productivité supérieure. Mais on peut aussi y voir surtout du travail parasite (agitation, contention, remaniements).

Commits cumulés de Grok 4.5 sur les minutes actives, ancien harness versus nouveauCommits cumulés de Grok 4.5 sur les minutes actives, ancien harness versus nouveau

Les données sur les conflits de fusion penchent vers la seconde interprétation. L’ancienne exécution a accumulé plus de 70 000 conflits avant que nous la mettions en pause, avec une cadence qui s’accélérait au lieu de se stabiliser, tandis que la nouvelle en a consigné moins d’un millier sur l’ensemble de ses quatre heures.

Conflits de fusion cumulés de Grok 4.5 au fil du temps, ancien harness versus nouveauConflits de fusion cumulés de Grok 4.5 au fil du temps, ancien harness versus nouveau

Les conflits se concentraient là où les fichiers prenaient le plus d’ampleur. Dans l’ancienne exécution, les plus gros fichiers ont continué à grossir pendant toute la durée de l’exécution, et le fichier le plus disputé a cumulé 7 771 conflits, avec l’intervention de 1 173 agents différents. Dans la nouvelle exécution, le fichier le plus disputé de toute la base de code n’en a connu que 47.

Taille du fichier le plus disputé de Grok 4.5 en lignes de code selon la progression de l’exécution, ancien harness versus nouveauTaille du fichier le plus disputé de Grok 4.5 en lignes de code selon la progression de l’exécution, ancien harness versus nouveau

Le principal échec de coordination de l’ancien essaim — le split-brain, autrement dit des planners qui dupliquent le travail les uns des autres — s’est manifesté dans la structure des packages. En Rust, le code est organisé en packages appelés crates et, dans un projet comme celui-ci, chaque crate correspond grosso modo à un composant majeur.

L’ancienne exécution s’est étalée sur 54 crates, dont trois packages SQL distincts. La nouvelle s’est fixée très tôt sur neuf crates et n’en a plus jamais ajouté.

Crates Rust distinctes au fil du temps dans les exécutions SQLite de Grok 4.5, ancien harness versus nouveauCrates Rust distinctes au fil du temps dans les exécutions SQLite de Grok 4.5, ancien harness versus nouveau

Tout cela se retrouve dans la base de code finale. Dans le mix Fable 5, l’ancien comme le nouvel essaim ont fini par réussir la suite complète, mais l’ancien a eu besoin de 64 305 lignes de code du moteur, contre 9 908 pour le nouveau. Le mix Opus montre la même tendance, avec 19 013 lignes et une note de 97 % avec l’ancien harness, contre 4 645 lignes et 100 % avec le nouveau harness.

Lignes de code du moteur nécessaires pour mener à bien l’expérimentation SQLite, ancien harness versus nouveauLignes de code du moteur nécessaires pour mener à bien l’expérimentation SQLite, ancien harness versus nouveau

Économie des modèles

Nous avons indiqué d’emblée que chaque répartition des modèles produisait une qualité similaire, alors que les coûts variaient énormément, de 1 339  pour GPT-5.5 seul. Les données sur les tokens montrent d’où vient cet écart.

La structure des dépenses était cohérente d’une exécution à l’autre : les workers représentaient au moins 69 % des tokens, et plus de 90 % dans la plupart des cas.

Mais la répartition des coûts en dollars différait de celle des tokens, car les tokens des planners coûtent plus cher. Dans le mix Opus 4.8 et Composer 2.5, Opus, utilisé comme planner, produisait une petite fraction des tokens mais représentait environ les deux tiers du coût, tandis que Composer, utilisé comme worker, traitait la grande majorité des tokens pour le tiers restant du coût.

Utilisation des tokens par rôle de modèle, planner versus worker, dans les configurations d’essaim SQLiteUtilisation des tokens par rôle de modèle, planner versus worker, dans les configurations d’essaim SQLite

Peu d’étapes, dans une tâche de grande ampleur, exigent réellement une intelligence de pointe, comme la décomposition initiale, les décisions de conception et certains arbitrages. Une fois qu’un planner de pointe a transformé l’ambiguïté en une instruction détaillée et explicite, des modèles moins coûteux n’ont plus qu’à l’exécuter. C’est une énorme source potentielle d’économies. Dans l’exécution qui utilisait GPT-5.5 à la fois pour les planners et les workers, les workers à eux seuls ont coûté 9 373 .

Un détail intéressant ressort de la comparaison des deux exécutions hybrides. Le planner Fable 5 a généré une facture légèrement inférieure à celle du planner Opus 4.8, malgré un prix par token environ deux fois plus élevé, parce qu’il a utilisé beaucoup moins de tokens de planification. Mais les workers de l’exécution Fable ont consommé plusieurs fois plus de tokens, et l’exécution dans son ensemble s’est révélée nettement plus coûteuse.

Les spécifications comme requêtes

Chaque saut dans les capacités de l’IA a élevé le niveau d’abstraction auquel un ingénieur peut travailler.

L’autocomplétion a permis aux ingénieurs de travailler ligne par ligne. Les premiers modèles ont ensuite porté ce niveau au bloc de code, puis les agents au fichier ou à la fonctionnalité.

Avec les essaims, l’unité de travail devient la spécification.

Pour que cela fonctionne, le essaim doit réellement suivre la spécification, et c’est précisément le sujet d’une grande partie de ce billet. Nous avons donné au essaim 835 pages de prose, et il en est ressorti une base de données. Ce qui était rare dans cette expérimentation, et ce qui sera selon nous rare en ingénierie logicielle à l’avenir, c’est la bonne formulation de l’intention.

Sous cet angle, le essaim commence à ressembler à un compilateur. Un compilateur traduit le code source en code machine à travers une série d’étapes intermédiaires. Le essaim fait quelque chose de similaire avec l’intention. Les Planners décomposent un objectif en arbres de tâches, puis le convertissent étape par étape en travail exécutable. La différence, c’est qu’un compilateur préserve le sens à chaque étape, tandis que le essaim reste probabiliste à chacune d’elles. Tout ce qui est décrit dans ce billet vise à combler cet écart.

Nous vous invitons à découvrir la sortie du essaim. La base de code issue de l’exécution solo d’Opus 4.8 est publique sur github.com/cursor/minisqlite. À première vue, elle semble excellente, mais nous n’avons pas mené d’analyse manuelle plus approfondie. Jetez-y un œil vous-même et dites-nous ce que vous y trouvez.


  1. Pour se faire une idée des coûts des modèles de pointe en solo, nous avons également exécuté Opus 4.8 et Fable 5 séparément. Nous n’avons évalué ces exécutions que de manière informelle, donc nous n’en tirons ici aucune conclusion sur leur qualité, même si, d’après notre expérience, nous nous attendrions à ce que les deux modèles donnent de bons résultats. Leurs coûts sont indiqués dans le graphique par les barres hachurées.
  2. Nous voulions utiliser GPT-5.6 Sol comme configuration de pointe. Le nouveau modèle semble plus sensible que les autres que nous avons testés aux formulations littérales et appuyées, et nous avons rencontré des spirales incontrôlées sans commune mesure avec ce qu’ont produit les autres modèles. Nous n’avions pas le temps d’ajuster les requêtes pour un modèle arrivé si récemment, et ajuster un seul modèle tout en laissant les autres inchangés aurait faussé la comparaison, nous sommes donc revenus à GPT-5.5.