freedzhost.cloud

L'état d'un agent comme fichier portable : déplacer un agent en marche entre machines

Niveau AvancéTemps estimé 2 hÀ lire avant Tailscale comme colonne vertébrale : tout en privé, joignable de partoutUn mot inconnu ? Lexique

La plupart des outils d'agents rangent une conversation dans une ligne de base de données. Trois choses deviennent pénibles : la déplacer vers une autre machine, changer de modèle à mi-chemin, lui faire confiance après un plantage. Les trois deviennent plus simples quand l'état est un dossier de fichiers simples que n'importe qui peut ouvrir.

Ce que vous obtenez. Un format de capsule que l'on inspecte avec tar, une passation qui rejoue la même histoire pour n'importe quel fournisseur, un protocole de déplacement qui ne peut pas exécuter un agent deux fois, et une façon de tester les cas de panne au lieu de l'espérer.

1. La capsule : un état lisible

Une capsule est un dossier (ou son tar) :

manifest.json                    identité, détenteur, une empreinte pour chaque autre fichier
memory/working_memory.md         les notes de l'agent
memory/timeline_events.jsonl     le journal : un événement immuable par ligne
memory/vector_index/index.json   index sémantique local
artifacts/snapshot.json          l'espace de travail : chemin vers empreinte de contenu
artifacts/blobs/<sha256>        corps des fichiers, stockés une fois par contenu
environment/spec.json            comment reconstruire le bac à sable

2. Changer de modèle en pleine conversation

Le journal enregistre ce qui s'est passé (un message, un appel d'outil, un résultat), pas la façon dont un fournisseur l'écrit. Le rendu pour un fournisseur est une fonction pure du journal : on change et on revient sans perte. Trois règles :

3. Déplacer un agent en marche

L'invariant : au plus une machine exécute l'agent, toujours. Le protocole est un commit en deux phases avec une époque de verrouillage (« fencing »).

geler sur la source  ->  proposer(époque+1) à la cible
n'envoyer que les blobs que la cible n'a pas  ->  la cible vérifie chaque empreinte
la cible prépare (rend le journal, construit le bac à sable)
--- point de non-retour ---
activer(époque+1) sur la cible  ->  la source se déclare retirée

Toute panne avant le point de non-retour annule : la cible jette son espace de préparation et la source reprend à son ancienne époque, comme si rien ne s'était passé. Une proposition refusée, un morceau corrompu et un lien coupé se traitent de la même façon.

4. L'unique moment ambigu

Si la réponse à activer est perdue, la source ne sait pas si la cible a pris le relais. Deviner dans un sens ou l'autre risque deux copies. Il faut demander à la cible quelle époque elle détient :

Une machine isolée qui se réveille avec une vieille époque peut proposer un déplacement, mais la cible refuse toute époque qui n'est pas plus récente que celle qu'elle détient. Une époque se compare, elle ne s'attend pas : c'est pourquoi elle est plus sûre qu'un verrou à délai.

5. Tester les pannes, pas relire le code

Enveloppez la cible dans un double de test qui fait échouer un appel nommé, soit avant son exécution (la requête est perdue), soit après (la réponse est perdue). Pilotez ensuite le vrai code à travers chaque phase et vérifiez l'invariant : un seul détenteur, une zone de préparation vide, une capsule qui se vérifie encore. Ajoutez un morceau corrompu, une époque périmée et un plantage qui perd le registre du détenteur. Écrire ces tests a révélé un vrai bug dans notre première version : la source et la cible désignaient l'agent par des identifiants différents, donc la cible ne reconnaissait jamais l'époque.

Pièges

Écrivez chaque fichier de façon atomique (fichier temporaire, puis renommage). Un plantage doit laisser un fichier complet ou absent, jamais à moitié écrit.

Une signature sur une capsule atteste un état exporté. Une capsule qui continue de tourner change de détenteur et de journal : signez à l'export, pas au repos.

Authentifier un lien n'est pas le chiffrer. Faites passer le transport par un réseau privé comme votre tailnet, ou un tunnel TLS.

Source, MIT : git.freedzhost.cloud/bengua/inari-core. À lire aussi : Inari, auto-hébergé et le glossaire.

Utile ? Dites-nous ce qu'il faut mesurer ensuite.