Il y a quelques mois, j'ai écrit sur [ma pile agentique](/posts/what-my-agentic-stack-actually-does) : un monorepo privé où les agents d'IA gèrent mes e-mails, mes paiements et mes déploiements, avec [Neotoma](https://neotoma.io) comme mémoire structurée en dessous. Ce message s'est terminé sur une promesse. J'ai dit que j'étais la couche stratégique et que l'architecture était conçue pour que ce rôle puisse être remplacé par un logiciel. C'est le post sur la façon de le faire.

[Ateles](https://github.com/markmhendrickson/ateles) est mon deuxième produit, après Neotoma, et il s'appuie directement dessus. C'est un essaim d'agents personnels. Là où l'ancienne pile était composée d'un agent par session avec moi dans la boucle pour chaque tâche, Ateles est une flotte permanente d'agents définis par rôle, coordonnés via Neotoma, fonctionnant quotidiennement sous launchd. C'est la différence entre moi qui dirige chaque agent et moi qui dirige une équipe qui connaît déjà son métier.

Cet article explique pourquoi je l'ai construit, comment il fonctionne et où il va.

## Pourquoi la pile a arrêté d'évoluer

Le déclencheur était le volume. Après la [version développeur](/posts/neotoma-developer-release) de Neotoma fin février, mon attention s'est divisée sur trois modes qui n'ont pas grand-chose en commun : créer le produit, le commercialiser et gérer les relations avec les premiers utilisateurs. Je nourrissais également Neotoma de plus en plus de contexte sur ma vie, professionnellement et personnellement, et plus ma mémoire s'améliorait, plus n'importe quel agent pouvait en faire quelque chose. Cela n’a pas supprimé la contrainte, cela l’a déplacée. La limite n’était plus celle que connaissaient les agents. C'était moi, le seul à transformer ce qu'ils savaient en action, une séance à la fois.

L’ancienne approche consistait en un ensemble de règles et de compétences spécifiques aux pensions. Ils m'ont permis d'éviter de me répéter sur la procédure. Une compétence définissait les étapes du tri des e-mails ou du déploiement d'un site Web, et n'importe quelle session pouvait l'exécuter dans le contexte déjà présent dans Neotoma. Cela a fonctionné jusqu'à ce que les sessions soient chargées.

L’échec était spécifique. Lorsqu’un agent générique assume toutes les règles et tous les rôles à la fois, il ne les assume pas tous de manière égale. À tout moment, il se penche sur un type de travail et laisse le reste glisser. Il rédige bien l'e-mail et oublie la règle permanente sur la façon dont je signe. Il corrige le bug et ignore le test de régression. Il n’y a pas non plus eu de contrôle contradictoire. Un agent a planifié, exécuté et révisé son propre travail, sans rien pour le détecter lorsqu'il se trompait en toute confiance.

Deux autres choses ont poussé dans la même direction. J'ai déplacé mes opérations produit sur GitHub par défaut, en utilisant des problèmes et des demandes d'extraction au lieu de m'engager directement dans main. Cela a été en partie forcé par le [pipeline de problèmes que j'ai construit](/posts/agent-to-agent-issue-resolution-with-humans-at-the-edges), qui a commencé à acheminer de vrais rapports des utilisateurs et de leurs agents vers Neotoma et vers GitHub. Et je voulais que mon processus de développement soit lisible en public, afin que les utilisateurs de Neotoma puissent voir exactement quel travail était en cours. Les deux nécessitent une séquence d’agents spécialisés dans la conception, la gestion des produits, l’assurance qualité et la version. Un seul agent qui fait tout cela va à l’encontre du but recherché.

Ateles est donc la décision de créer une flotte et de définir cette flotte dans Neotoma lui-même.

## Neotoma comme tissu, pas seulement comme mémoire

Ce qui différencie Ateles, c'est que Neotoma détient deux choses à la fois. Il contient le contexte opérationnel dont l'essaim a besoin, les mêmes faits que mon ancienne pile lisait et écrivait. Et il détient lui-même l’essaim.

Les agents sont des entités Neotoma. Chacun est un « agent_definition » avec une invite, une liste autorisée d'outils et un ensemble d'octrois de fonctionnalités. La mise à jour du comportement d'un agent est un appel « correct() » contre cette entité, avec un historique complet des versions et l'attribution de l'auteur. Pas de commit, pas de redéploiement. Les fichiers SKILL.md sur le disque sont des miroirs générés de ces entités, et non de la source.

Leurs relations sont également des entités Neotoma. L'essaim a une hiérarchie, exprimée sous forme d'arbre, donc un coordinateur sait quels agents il envoie et une tâche sait quel agent en est propriétaire. Et le travail lui-même est constitué d'entités Neotoma : tâches, plans, définitions de flux de travail, enregistrements de participation. Un agent prend une tâche, l'exécute et écrit le résultat sous forme d'observation attribuée à son identité.

Le résultat est un graphique mondial pour tout. Les faits sur lesquels l'essaim agit, la définition de l'essaim qui agit sur eux et l'enregistrement de ce qu'il a fait se trouvent tous dans le même magasin en annexe uniquement. Cela donne à l’ensemble trois propriétés qui me tiennent à cœur. C’est transparent, car chaque action est une observation attribuée que vous pouvez relire. Il est auditable, car vous pouvez rejouer les actions de n'importe quel agent sur n'importe quelle fenêtre. Et c’est réversible, car rien n’écrase la vérité sur place. Si un agent passe un mauvais appel, je peux retracer l'événement qui l'a provoqué, inverser l'état et corriger la règle qui y a conduit, une seule fois.

L’identité est l’élément qui rend l’attribution réelle plutôt qu’ambitieuse. Chaque agent dispose d'une paire de clés [AAuth](/posts/know-which-of-your-agents-write-what) et signe chaque appel d'outil. Le harnais vérifie la signature avant d'agir et enregistre qui a prétendu agir aux côtés de qui a réellement agi sur GitHub. Un agent rédacteur de code n’agit plus seulement comme moi. Il agit comme lui-même, et le journal le dit.

## Les agents, par rôle

L'essaim est organisé en niveaux. T1 est l'hôte : le processus qui possède un canal et génère les agents, actuellement OpenClaw pour ceux avec qui je parle et lancé pour ceux en arrière-plan. Il s'agit d'une infrastructure, pas d'un agent ayant un rôle. Les agents eux-mêmes fonctionnent sur trois niveaux. Les agents T2 sont toujours disponibles et détiennent un personnage : Ateles lui-même est celui à qui je parle, et c'est le seul agent qui me bipe. Les démons T3 sont des processus d'arrière-plan pilotés par des événements, sans personnage, chacun étant abonné aux événements Neotoma ou à un webhook externe. Les agents T4 sont apatrides, générés par tâche, avec une identité et une mémoire stables qu'ils obtiennent en interrogeant Neotoma.

Quelques-uns des rôles en cours aujourd'hui :

**Produit.** Un démon coordinateur lit les définitions de flux de travail de Neotoma et répartit les portes dans l'ordre : conception, gestion de produit, assurance qualité, version. Le travail de code est confié à un responsable des problèmes qui ouvre les demandes d'extraction dans les dépôts. Chaque demande d'extraction fait l'objet d'un examen de base par un agent de révision distinct, avec des spécialistes du domaine qui se concentrent sur les chemins qui leur appartiennent. Le but de les séparer est le contrôle contradictoire que l’agent unique n’a jamais eu. Celui qui écrit le code n’est pas celui qui l’efface.

**Finance.** Un démon de paiement récurrent exécute des transferts Wise et Bitcoin déclenchés par des événements de calendrier et des dates d'échéance de tâches, chaque destinataire et montant étant chargés à partir d'entités de profil de paiement plutôt que de code. L'ajout d'un nouveau paiement récurrent est une nouvelle entité, pas un engagement. Un rôle de conseiller financier et un rôle de fiscalité et de déclaration sont définis pour la budgétisation et le rapprochement.

**Juridique et conformité.** Un rôle juridique couvre l'évaluation des risques et l'examen des conditions. Un rôle de conformité couvre la confidentialité et la gouvernance des données. Celles-ci sont plus importantes à partir du moment où un essaim peut agir sur les données des personnes, ce que fait la mienne.

**Stratégie.** C'est le rôle que j'ai décrit comme étant le mien dans le dernier message, et c'est celui que je cède le plus délibérément. Ce transfert est la version concrète d'un argument que j'ai avancé dans [The Human Inversion](/posts/series/the-human-inversion) : à mesure que les agents absorbent le milieu d'exécution, l'influence de l'humain se déplace vers les extrémités, des normes plus strictes entrent et un jugement plus dense sort. L’autonomie est calibrée par plan, et non globalement. Une entité de politique d'exécution déclare, pour un plan donné, ce qu'un agent est autorisé à faire par lui-même, quelle barre de qualité il doit franchir et où il doit s'arrêter et vérifier avec moi avant de continuer. La chaîne d'escalade va de l'agent agissant à un expert du domaine en passant par un gardien de la constitution, et chaque résolution est réécrite en tant qu'entité afin que l'instance suivante hérite du jugement.

Derrière ceux-ci se trouvent les démons d'ingestion et de support qui maintiennent le graphique alimenté : triage des e-mails, importation audio, préparation du calendrier, santé et forme physique, triage des problèmes. Chacun est un petit processus qui transforme un signal entrant en entités Neotoma sur lesquelles le reste de l’essaim peut agir.

## La colonne vertébrale des tâches

Ce qui lie la flotte, c'est la gestion des tâches, et c'est délibérément ennuyeux. Une tâche est une entité. Il a un propriétaire, un état, une priorité et un enregistrement indiquant pour qui il a été exécuté. Planifie les tâches de groupe et prend ses propres décisions et prochaines étapes. Les définitions de workflow déclarent les phases et les portes par lesquelles passe un travail.

Parce que tout cela se trouve dans le même magasin que tout le reste, l’essaim se coordonne sans base de données d’orchestration distincte. Un démon s'abonne aux événements de tâches via le flux d'événements de Neotoma. Lorsqu'une tâche apparaît, elle est acheminée vers le bon agent par domaine, derrière une porte qui évalue la confiance de l'agent par rapport aux dommages qu'une mauvaise action pourrait causer. Un faible rayon de souffle et une confiance élevée fonctionnent seuls. Un rayon de souffle élevé m'attend.

C’est autour de cette colonne vertébrale que je construis le reste de l’expérience.

## Où cela va-t-il

L'interface que je souhaite est simple à énoncer. Je donne une contribution à l'essaim, via le transport le plus proche, et l'essaim l'absorbe et agit. Une invite dans un terminal. Un e-mail. Un message télégramme. Un mémo audio enregistré lors d'une promenade, c'est ainsi que les notes de cet article ont commencé. Tout cela devrait atterrir dans le même graphique, et l'essaim devrait être proactif quant au travail que cela implique, sans que je tienne la main d'un agent à travers lui.

Deux propriétés rendent cela possible. L’essaim doit être auto-évolutif. À mesure qu'il s'adapte à un nouveau contexte et à de nouveaux types de travail, il doit fournir les capacités et développer les compétences dont il a besoin, en s'adaptant à mes corrections plutôt que d'attendre que je le reconfigure manuellement. Et ma contribution, toujours requise dans les moments qui nécessitent véritablement un jugement, ne devrait jamais avoir à être donnée deux fois. Je corrige une fois une façon de faire, elle devient une entité, et la correction tient.

La feuille de route la plus proche concerne la portée. Ateles a été construit pour mon propre usage, donc une bonne partie suppose toujours un seul opérateur, moi. Je [le conduis pour qu'il soit installable et multi-opérateur](https://github.com/markmhendrickson/ateles/blob/main/docs/multi_tenant.md) : un essaim que quelqu'un d'autre peut créer, pointer sur son propre Neotoma, fournir ses propres entités de contexte et s'exécuter. Étant donné que les agents sont indépendants de l'opérateur par politique et que rien de spécifique à l'opérateur n'est intégré dans le code, le cas de fork est principalement une question de contexte et non de réécriture. Le travail véritablement nouveau prend en charge plus d'un humain à l'intérieur d'un seul locataire, c'est pourquoi la limite des locataires est conçue maintenant plutôt que réaménagée plus tard.

Neotoma a créé des agents qui se souviennent, et Ateles est ce que cette mémoire a rendu possible : un essaim qui peut agir sur lui sans que je sois au milieu de chaque étape. Les deux se lèvent ensemble. Une meilleure mémoire n’est pas un problème résolu que j’ai surmonté. C'est le substrat sur lequel repose tout l'essaim, et chaque gain dans ce que Neotoma peut contenir et résoudre est un gain dans ce que l'essaim peut faire. La mémoire ne cesse de s’améliorer, et l’essaim continue de s’améliorer avec elle.