Le premier problème lié à l’exécution de plusieurs agents est qu’ils oublient. Chaque session commence vide. Le contexte d'un outil ne s'applique pas à un autre. Les décisions prises hier sont invisibles aujourd’hui. On finit par réexpliquer les mêmes choses, ou pire, les agents se contredisent car ni l'un ni l'autre n'a accès à ce que l'autre a écrit.

C’est le problème du stockage, et il faut d’abord le résoudre. Vous avez besoin d'une couche d'état dans laquelle chaque agent peut écrire des observations et chaque agent peut interroger le contexte. Les faits doivent persister à travers les sessions, les outils et les machines. La récupération doit fonctionner quel que soit l'agent qui a écrit les données ou le moment. [Neotoma](/posts/truth-layer-agent-memory) existe pour résoudre ce problème : un substrat indépendant du schéma qui stocke, sert et vous permet d'interroger la vérité sur l'ensemble de votre pile d'agents.

Mais une fois que le stockage fonctionne, vous vous heurtez à un deuxième mur. Lorsqu'un agent écrit une nouvelle observation, les autres agents n'en sont pas informés jusqu'à ce qu'ils vérifient. « Vérifier » signifie interrogation : ré-interrogation à intervalles réguliers, au début de la session ou sur un déclencheur manuel. La plupart de ces sondages ne donnent rien. Ceux qui comptent arrivent avec des minutes ou des heures de retard. L'écart entre « état modifié » et « avis d'agent » est un temps mort, et il crée un plafond sur ce que les agents peuvent faire ensemble.

Ce n'est pas un problème de récupération. Les données sont là. C'est un problème de coordination au niveau de la couche infrastructure, et tous les systèmes de mémoire homebrew que j'ai vus le gèrent de la même manière : ce n'est pas le cas.

## Le plafond de coordination

La coordination basée sur les sondages entraîne trois coûts qui s’aggravent avec l’échelle.

**Latence.** L'intervalle entre un changement d'état et le moment où un agent en prend conscience est limité par la fréquence d'interrogation. Si un agent vérifie toutes les cinq minutes, une observation critique peut passer inaperçue pendant quatre minutes et cinquante-neuf secondes. Pour les agents qui se coordonnent sur un état urgent, comme un rapport de bug qui vient d'être soumis ou une transaction financière qui nécessite un rapprochement, cette latence constitue le goulot d'étranglement.

**Calcul gaspillé.** La plupart des sondages ne renvoient aucun changement. Un agent qui vérifie toutes les trente secondes au cours d'une journée de travail effectue près d'un millier de requêtes, dont l'écrasante majorité confirme que rien ne s'est passé. Ceci est tolérable pour un seul agent. A dix agents, c'est une taxe. À une centaine, il s’agit d’une surcharge d’infrastructure qui évolue linéairement sans aucune valeur.

**Plafond de coordination.** La combinaison de la latence et du gaspillage crée une limite pratique au comportement des agents collaboratifs. Les modèles qui seraient naturels avec une connaissance basée sur les événements, comme « L'agent B réagit à l'écriture de l'agent A en quelques secondes », nécessitent une colle personnalisée : des minuteries, des hacks de webhook, des déclencheurs manuels ou des démons d'interrogation dédiés qui nécessitent eux-mêmes une maintenance. Les modèles de coordination que vous souhaitez sont simples. La plomberie nécessaire pour les faire fonctionner avec les sondages ne l'est pas.

Si vous avez construit une pile multi-agents, vous vous heurtez à ce mur. La couche d’état stocke la vérité de manière fiable. Il reste silencieux sur les changements apportés à cette vérité.

## Que signifie la signalisation

Le correctif est simple dans son concept. Après chaque écriture, la couche d'état émet un événement structuré décrivant ce qui a changé. Les consommateurs, agents, démons et instances homologues enregistrés reçoivent l'événement et décident quoi faire à ce sujet. La couche d'état délivre le signal. Le consommateur décide de la réponse.

Il s'agit d'une primitive standard dans les systèmes qui gèrent l'état à grande échelle. PostgreSQL émet des entrées WAL et prend en charge LISTEN/NOTIFY. Personne ne prétend que PostgreSQL « agit » lorsqu'il fait cela. Il fournit une observabilité dans ses propres transitions d'état. Un courtier de messages comme Kafka fait la même chose à une échelle différente. Le système étatique rapporte ce qui s'est passé. Les consommateurs en aval filtrent, priorisent et agissent. La couche de reporting ne raisonne pas sur les événements. Il tire et oublie.

L’analogie biologique est utile ici. Un système nerveux stocke et signale. Le cerveau détient la mémoire. Les neurones sensoriels transmettent la conscience de ce qui a changé. Ni l’un ni l’autre ne décide de bouger un muscle. Le système moteur agit. Le cerveau et les nerfs sensoriels constituent une couche d’état qui stocke la vérité et signale les changements. Les agents qui décident quoi faire face à ces signaux sont le système moteur.

## La ligne qui doit rester

Une couche d’état qui signale peut facilement devenir un orchestrateur, un moteur de workflow ou un agent à part entière. La tentation est réelle. Une fois que vous pouvez émettre des événements, vous souhaitez les filtrer, les hiérarchiser, les acheminer, ajouter une logique de nouvelle tentative, créer une livraison conditionnelle. Chaque étape semble raisonnable isolément. Ensemble, ils transforment le substrat en quelque chose qui prend des décisions sur ce qui compte et ce qui ne l'est pas.

Cette ligne doit rester.

Qu'est-ce que la signalisation :

- **Observation du changement d'état, pas action sur l'état.** Le substrat rapporte ce qui a changé. Il n'évalue pas si le changement est important.
- **Livraison Fire and Forget.** Si un consommateur n'est pas disponible, le substrat enregistre la panne. Il ne réessaye pas avec escalade, ne revient pas à des actions alternatives ou ne modifie pas son propre comportement.
- **Une sortie dérivée du pipeline d'écriture.** Le pipeline existant est l'écriture, le recalcul d'instantané et l'insertion de la chronologie. L'émission d'événements est une entrée supplémentaire dans cette séquence, de la même manière qu'un instantané dérive des données d'une observation. Il s'exécute après la validation de la transaction d'écriture, pas pendant. Si l'écriture échoue, aucun événement ne se déclenche. Si une livraison échoue, l’écriture est toujours valable. Le signal traîne la vérité ; il ne le ferme jamais.

Ce que la signalisation n'est pas :

- **Pas de prise de décision.** Le substrat ne filtre pas quels événements valent la peine d'être envoyés. Il les émet tous. Les consommateurs filtrent.
- **Pas le comportement de l'agent.** Le substrat ne s'abonne pas à ses propres événements. Il ne fait pas de boucles. Cela ne raisonne pas.
- **Pas d'orchestration.** Pas de priorisation, pas de planification, pas de routage conditionnel. Les démons qui traitent les événements et prennent des mesures sont des consommateurs de la couche opérationnelle et ne font pas partie du substrat.

Le test est propre. Si la suppression de l'émission d'événements signifie que le substrat a moins d'observabilité dans ses propres transitions d'état, il s'agit d'une primitive de substrat. Si le supprimer signifie qu’un utilisateur manque un rappel ou qu’un agent manque une date limite, c’est une stratégie.

## La frontière affinée

L’ancienne frontière : le substrat stocke et sert la vérité.

La nouvelle frontière : le substrat stocke, sert et signale la vérité. Lorsque la vérité change, le substrat rapporte le changement. Ce qui se passe ensuite relève de la responsabilité du consommateur.

Il s’agit d’une extension et non d’une contradiction. Le pipeline d'écriture existant effectue déjà un travail dérivé après chaque écriture : recalcul d'instantanés, création d'événements de chronologie, génération d'intégration, liaison automatique. L'émission d'événements est une entrée supplémentaire dans la liste. Cela ne nécessite aucun nouveau modèle de données. Cela ne change pas ce qui est stocké ni la façon dont les requêtes sont résolues. Il ajoute un canal sortant pour la sensibilisation aux changements d'état.

La terminologie compte. « Signal » et « émettre » plutôt que « notifier » ou « alerter ». Notifier implique un jugement sur l’importance. L’alerte implique une évaluation de l’urgence. Le signal est neutre. Le substrat signale. Le consommateur interprète.

Il vaut la peine d’être explicite quant à la place de la stratégie dans ce tableau. Les plans, les règles permanentes, les préférences et les décisions antérieures sont eux-mêmes des États. Ce sont des entités stockées dans le substrat comme les autres, interrogées, réduites et signalées de la même manière. Ils ne fonctionnent pas dans une couche distincte. La frontière n’est pas entre « la stratégie vit dans un autre système » et « l’État vit dans le substrat ». C'est entre « le substrat stocke et signale » et « les consommateurs décident et agissent en fonction de ce qu'ils lisent ». Cela permet aux artefacts de stratégie d'être inspectés, rejouables et partagés entre tous les consommateurs qui les lisent, sans avoir à forcer le substrat à prendre une décision.

## De la mémoire au système nerveux

La plupart des personnes qui construisent des systèmes multi-agents décrivent encore le substrat partagé comme de la « mémoire ». Ce cadrage est précis dans la mesure du possible. La mémoire est un outil de stockage et de récupération : le système enregistre ce qui s'est passé et les agents l'interrogent lorsqu'ils ont besoin de contexte. C’est la base, et cela doit fonctionner avant que toute autre chose compte.

Mais la mémoire est passive. Il contient la vérité. Il ne transmet pas la conscience des changements dans la vérité aux parties du système qui doivent réagir. Une couche mémoire qui stocke une nouvelle transaction financière n'indique pas à l'agent de rapprochement que la transaction est arrivée. Une couche mémoire qui enregistre un nouveau rapport de bogue n'indique pas au démon de triage que quelque chose nécessite une attention particulière. Les données sont là. La prise de conscience ne l'est pas.

Un système nerveux ajoute la couche de transmission. Il englobe tout ce que fait la mémoire, le stockage et la récupération restent, mais il étend la responsabilité du substrat pour inclure la signalisation. La couche étatique ne détient pas seulement la vérité. Il propage les changements de vérité aux consommateurs enregistrés en temps réel.

La bonne barre pour juger cela est l’intégrité de l’État, et non la qualité de la récupération. La mémoire est jugée selon si vous pouvez la réinterroger. Un système nerveux est jugé selon si le reste du système peut agir sur un changement au moment où le changement est durable, plutôt que quelques minutes plus tard lorsque quelque chose se pose. Ce sont des problèmes différents avec différents modes de défaillance.

Le cadrage biologique est précis, non décoratif. Un cerveau dépourvu de nerfs sensoriels peut parfaitement stocker des souvenirs tout en étant incapable de réagir à l’environnement. La pièce manquante n’est pas le stockage. C'est le chemin de signalisation entre ce qui a changé et ce qu'il faut savoir. C'est la pièce que vous finissez par construire à la main, une boucle d'interrogation à la fois, jusqu'à ce qu'il devienne évident qu'elle appartient au substrat.

## Ce que cela débloque

Si vous exécutez une pile multi-agents sur un état partagé, réfléchissez à ce qui devient possible lorsque la couche d'état signale l'écriture.

**Un démon qui traite le travail entrant dans les secondes suivant sa soumission.** Un utilisateur ou un agent externe soumet un rapport de bogue, une demande de fonctionnalité ou des commentaires structurés. La couche d'état stocke l'entité et émet un événement. Un démon de longue durée reçoit le webhook, crée un arbre de travail, exécute une session d'agent sur la base de code appropriée, ouvre un PR et met à jour l'état de l'entité. Pas de boucle de sondage. Pas de minuterie cron vérifiant toutes les cinq minutes. Le démon s'abonne une fois et réagit lorsque le travail arrive.

**Coordination cross-tool sans code colle.** Un agent de rapprochement financier s'abonne aux observations des transactions. Un agent de pipeline de contenu s'abonne aux brouillons de modifications d'état. Un agent de triage des problèmes s'abonne aux événements de création d'entités filtrés par type. Chaque consommateur enregistre son intérêt pour une portée, tous les événements, les événements pour un type d'entité spécifique, les événements pour une entité spécifique, et fournit un point de terminaison de livraison. Le substrat est à la hauteur. Le consommateur maintient la logique. Aucune intégration personnalisée par paire d'agents.

**Agents qui peuvent communiquer entre eux via le substrat.** La communication agent à agent fonctionne déjà via la couche d'état : fil de conversation, identité de l'expéditeur, sémantique des fils multipartites. Ce qui manque, c'est la poussée. Lorsque l'agent A écrit un message destiné à l'agent B, l'agent B ne devrait pas avoir à interroger pour le découvrir. Le substrat doit signaler l'écriture afin que la conversation se déroule à la vitesse de traitement et non à la vitesse d'interrogation.

** Soumissions d'invités structurées avec contrôle d'accès. ** Tout type d'entité, pas seulement un type à casse spéciale, peut être ouvert aux soumissions externes avec des politiques d'accès configurables. L'agent d'un client soumet des commentaires structurés. L'automatisation d'un partenaire soumet les données pour rapprochement. Le substrat détermine qui peut écrire quoi, suit la provenance des acteurs externes et enchaîne les conversations de suivi. La soumission est un état durable, pas un message qui disparaît.

## Au-delà de vos propres agents

Jusqu’à présent, cela donne l’impression que tous les agents vous appartiennent. Ils se trouvent dans votre éditeur, vos tâches cron, votre ordinateur portable. C'est le cas le plus simple. Ce n’est pas une vue d’ensemble.

La progression naturelle est une instance centrale sur votre machine ainsi que des instances satellites sur d'autres infrastructures : serveurs clients, droplets VPS d'équipe, agents distants que vous exploitez mais ne possédez pas. Une fois sur place, les sondages ne sont pas seulement du gaspillage. Il est structurellement aveugle. Vous vous connectez en SSH, exécutez des résumés, demandez « ce qui s'est passé entre ces dates » car le magasin distant ne renvoie jamais la sensibilisation à l'endroit où fonctionnent vos agents de coordination.

Il s’agit d’une coordination au-delà des frontières de confiance, et pas seulement entre les processus. Lorsque l’écrivain est l’agent de quelqu’un d’autre, la « mémoire partagée » ne suffit pas. Vous avez besoin d’écritures que vous pouvez attribuer, inspecter et vérifier après coup. Cela signifie une identité d'auteur vérifiée sur chaque surface (MCP, HTTP, requêtes signées), des niveaux d'attribution qui distinguent un agent vérifié cryptographiquement d'un appelant anonyme, et des formes de conversation qui incluent des fils d'agent à agent et multipartites afin que la communication transfrontalière soit un état structuré plutôt que des messages ad hoc.

La signalisation complète le tableau. Une instance satellite qui émet des événements en écriture donne à vos consommateurs centraux la même primitive sur laquelle ils s'appuient déjà localement. Finalement, deux instances peuvent se synchroniser de manière bidirectionnelle : lorsqu'une entité change sur l'instance A, l'instance B est avertie et peut extraire la mise à jour sans intervention manuelle. Aucun hub central requis. N'importe quelle instance peut être un homologue.

La partie « ouverte » est une interopérabilité régie par des règles, et non une mêlée générale. Les surfaces ouvertes, l'identité explicite et la sémantique des fils de discussion permettent aux agents d'autres personnes de participer à un système nerveux sans prétendre que chaque appelant est également fiable ou également lisible. Le cadrage de la mémoire sous-tend cette exigence. Ce n’est pas le cas du cadrage du système nerveux.

## Ce que je construis

J'ajoute ces fonctionnalités à [Neotoma](/posts/truth-layer-agent-memory) dans l'ordre, chacune s'appuyant sur la précédente.

**Émission d'événement de chemin d'écriture.** Après chaque écriture, correction ou création de relation réussie, émettez un événement structuré : type d'entité, ID d'entité, type d'observation, horodatage et champs modifiés. Les consommateurs obtiennent suffisamment d’informations pour décider d’agir sans avoir besoin d’interroger à nouveau la couche d’état. C'est la couche de détection. Sans cela, chaque fonctionnalité en aval nécessite une interrogation. Avec lui, le substrat devient réactif.

**Livraison par abonnement et webhook.** Les agents enregistrent leur intérêt pour une étendue et fournissent un point de terminaison de livraison. Le substrat gère le registre et diffuse les événements via des rappels de webhook et SSE. Le consommateur maintient la logique. Les webhooks viennent en premier car ils fonctionnent pour les agents distants sur l'infrastructure VPS, les démons locaux sur votre ordinateur portable et la synchronisation entre instances entre pairs. Les notifications push SSE et MCP sont additives.

**Soumission d'entité généralisée.** À l'heure actuelle, des soumissions externes structurées (accès invité, politiques d'accès, fil de conversation, provenance d'acteur externe) existent mais sont liées à un seul type d'entité. L'étape suivante consiste à rendre ce type d'entité indépendant : tout type d'entité peut être ouvert aux soumissions d'invités avec des politiques d'accès configurables, des miroirs externes facultatifs et un fil de conversation. L'agent d'un client soumet des données structurées. L'automatisation d'un partenaire soumet des commentaires. Le substrat gère le contrôle d’accès et la provenance. L'opérateur configure ce qui est ouvert et ce qui ne l'est pas.

**Synchronisation bidirectionnelle entre instances.** L'infrastructure existante prend en charge la soumission à distance unidirectionnelle : une instance est poussée vers une autre. L'extension est bidirectionnelle. Lorsqu'une entité change sur l'instance A, l'instance B reçoit un webhook et peut extraire la mise à jour. Pas de hub central. N’importe quelle instance peut se connecter à n’importe quelle autre. C'est ainsi qu'une flotte d'instances satellites sur l'infrastructure client reste coordonnée avec une instance centrale sans SSH ni cron.

Rien de tout cela n’est la version la plus ambitieuse de ce que pourrait être un « système nerveux ». Routage, filtrage, transformation, garanties de livraison, files d'attente de lettres mortes : les courtiers de messages fournissent tout cela. Je ne construis intentionnellement rien de tout cela. Le rôle du substrat est de signaler, pas d'orchestrer. Chaque caractéristique qui franchit cette ligne rend le substrat moins fiable en tant que rapporteur neutre des transitions d’état.

La contrainte est la fonctionnalité. Une couche d'état qui signale mais ne décide pas est une couche d'état sur laquelle vous pouvez toujours raisonner. Ajoutez une logique de couche opérationnelle au chemin de signalisation et vous perdez la propriété qui a rendu le substrat utile en premier lieu : le comportement du substrat est entièrement déterminé par l'écriture, et non par la politique.