C’est un runtime de tâches piloté par LLM — le routage, l’exécution et l’auto-réparation se font tout seuls. Un simple fichier Markdown sert de plan de contrôle, et l’ensemble tourne sans dépendre d’une session ouverte : on modifie le fichier, le travail continue en arrière-plan. Dans cette étude : comment j’ai conçu l’architecture, les arbitrages que j’ai faits, les résultats mesurés, et un comportement clé que je n’avais pas programmé mais que le système a fait émerger tout seul.
Contexte : en tant qu’opératrice solo, je pilote quatre chantiers en parallèle (production de contenu, brief de revue d’architecture pour un premier client, portfolio, études). L’état des tâches se retrouvait éparpillé entre différents outils, et il me fallait 15 à 30 minutes de « remise en route » à chaque reprise de contexte avant de pouvoir vraiment travailler.
Contrainte produit : je voulais un système de tâches avec deux propriétés : je peux ajouter du travail à tout moment, et les tâches confiées à l’automatisation s’exécutent toutes seules, sans que j’aie besoin de rester devant la machine. Je ferme l’ordinateur, je reviens quelques heures plus tard, et le travail est fait.
Pourquoi c’est un vrai sujet en design d’agents : la plupart des « assistants IA » s’arrêtent dès qu’on ferme la fenêtre de chat. Ils sont liés à une conversation, pas au travail lui-même. Construire un runtime d’agent qui ne dépend pas du cycle de vie de la session est un problème de conception complètement différent — et c’est précisément ce basculement qui fait passer un agent du statut d’« outil » à celui d’« infrastructure ».
La question de conception : un simple fichier texte, couplé à un protocole de machine à états et à une couche de décision LLM, peut-il servir de runtime d’agent persistant ? Si oui, le même pattern se généralise à n’importe quel workflow opérationnel — triage support, pipeline de contenu, automatisation d’opérations.
task-board.md modifié (source quelconque : moi, un autre agent, un cron)fswatch · debounce 2s · launchd fallback horairemkdirready / blocked:* / running:* / done / failed:*task-board.md · journal structuré events.jsonl · deadletter/ pour échecs terminauxQuatre arbitrages délibérés. Chacun avec une alternative spécifique que j’ai rejetée.
ready / blocked:siyao:send-brief / running:agent-a4b:2026-04-20T15:25Z / done / failed:exhausted_retriestask-board.md avec verrouillage distribué (flock, patterns d’append, CRDT).Suivi de base initié le 2026-04-20. Chiffres reflétant la première semaine d’exécution ; certains estimés à partir des premières exécutions, avec méthodologie annotée.
events.jsonl — délai de sauvegarde à l’événement file_changed_triggeredrunning:* bloqués réinitialisés. Aucune intervention manuelle requise.launchd).Avant le système : vérification manuelle de la liste de tâches + recherche routinière consommaient environ 8 à 12 heures/semaine. Après : les tâches routinières (recherche concurrentielle, rédaction de documents, scans de marché) sont routées vers des sous-agents parallèles sans supervision temps réel.
Production observée première semaine : 5 tâches substantielles de recherche/rédaction terminées sans supervision active (exemples : analyse concurrentielle de 260 lignes, étude de cas architecturale de 895 lignes, scan marché de 18 JD, évaluation portfolio perspective RH).
Méthodologie : estimations heures économisées sur base auto-rapportée. Quantification précise démarre semaine 2 (en cours).
J’ai programmé la couche de décision pour faire une seule chose : trouver les tâches marquées ready et les exécuter. Ignorer tout le reste.
À la première exécution en production, le système a fait ce que je ne lui avais pas programmé :
blocked:task:TASK-015, alors que TASK-015 était done. Le skill a signalé la rupture de la chaîne de dépendances, suggéré de promouvoir la tâche à ready, et demandé confirmation.ready : il a comparé le champ Measure aux entrées disponibles, remarqué qu’un artefact requis (URL portfolio) manquait, et refusé d’exécuter — en attendant clarification.running:claude-a:2026-04-20T15:25Z était en heure locale mais annoté UTC. Le skill a calculé que l’horodatage était 2 heures dans le futur par rapport à now, l’a signalé comme anomalie, et a demandé clarification.Aucun de ces comportements n’était dans le prompt. Ils ont émergé de la conception de la machine à états.
Même LLM, même task-board — et pourtant l’agent se comporte de manière radicalement différente selon que le statut est une étiquette ou un protocole. Un statut en langage naturel (« en attente », « en cours ») ne donne au modèle qu’un token à matcher ; un état typé avec sous-champs structurés lui donne un protocole sur lequel raisonner. Le point que j’emporterais pour une équipe produit : ce qui transforme un agent d’un simple exécuteur en véritable partenaire de raisonnement, c’est l’état structuré ; le prompt n’est qu’un réglage final.
La conclusion pratique pour un système d’agents : quand le comportement d’un agent déçoit, la plupart des équipes itèrent sur les prompts. Le levier le plus puissant est souvent ailleurs — dans le système de types au sein duquel l’agent opère.
L’architecture n’est volontairement pas spécifique à l’automatisation de tâches. Le même pattern à 5 couches (fichier plan de contrôle + ordonnanceur événementiel + exécuteur sans état + machine à états typée + journal d’audit append-only) se mappe directement à plusieurs catégories de workflows listées dans un brief client en cours (opérateur Shopify) dont je réalise la revue d’architecture :
| Workflow | Plan de contrôle | Tâche de la couche décision |
|---|---|---|
| Triage de tickets support | File d’attente helpdesk | Classifier + rédiger réponse + signaler pour revue |
| Gestion de précommandes | Tracker ETA fournisseur | Détecter delta + générer notifications client |
| Création produit depuis données fournisseur | File de tableurs entrants | Extraire champs + normaliser + pousser en brouillon |
| Intake « we buy collections » | Journal de demandes entrantes | Extraire + scorer + rédiger suivi |
La même discipline de machine à états (ready / blocked:* / running:* / done) s’applique à tous. Le seul composant workflow-spécifique est le template de prompt dans la couche de décision. L’infrastructure est partagée.
launchd, affichant débit de tâches, taux d’erreurs, distribution de latence dans le temps.events.jsonl valent mieux que des métriques précises ajoutées après coup — la mesure rétroactive force l’estimation.Avoir construit ce système m’a laissé une conclusion que je peux transférer à n’importe quel produit d’agents : la machine à états, c’est le produit lui-même. Prompts, sous-agents, couches d’ordonnancement — tous remplaçables. Ce qui persiste, ce qui passe à l’échelle, et ce qui détermine si le système peut raisonner ou seulement exécuter, c’est le contrat d’état entre l’intention humaine et l’action de l’agent.
Une clarification de périmètre, d’abord : c’est un runtime à opérateur unique, construit pour mon propre flux de travail — pas un produit de plateforme. Il résout la forme très spécifique d’une seule personne qui orchestre une poignée de workflows. La question que j’avais à trancher avant d’écrire la moindre ligne de code n’était pas « construire, ou lancer un concurrent à Coze ? » — c’était : « est-ce qu’un outil existant résout déjà cette forme, et si oui, lequel ? » Ce qui suit, c’est l’analyse que j’ai faite avant de décider de construire.
blocked:task:TASK-010 veut dire « TASK-010 n’est pas encore terminée » — le modèle peut aller vérifier), pas une étiquette de couleur ou un statut en texte libre.Ces trois plateformes abstraient le workflow derrière une UI et un schéma que l’on configure via cette UI. C’est le bon choix quand l’opérateur n’est pas technique, quand l’état doit être partagé au sein d’une équipe, ou quand le workflow est le produit. Aucune de ces conditions ne s’applique ici. Pour une opératrice solo dont l’état du workflow est déjà du texte, le coût d’introduire un second système d’état (canvas + stockage éditeur) l’emporte sur le confort des nœuds pré-construits.
Autrement dit : si ce runtime fait environ 300 lignes de shell + une définition de skill plutôt qu’un déploiement Dify, ce n’est pas parce que je pense pouvoir faire mieux. C’est parce que ma forme (une seule opératrice, natif Markdown, natif terminal, zéro éditeur) est précisément la forme que ces plateformes n’optimisent volontairement pas. Pour leur vraie audience — des équipes pluridisciplinaires livrant des agents orientés utilisateurs — elles restent le bon choix, et je les recommanderais.
La compétence transférable ici, ce n’est pas « j’ai construit une meilleure plateforme ». C’est un cadre de décision : avant d’écrire la moindre ligne de code, j’ai nommé les quatre choses dont j’avais réellement besoin, j’ai confronté chaque outil existant à ces quatre critères, et je n’ai choisi de construire que lorsque chaque outil échouait sur un critère précis. C’est exactement le même cadre build-vs-buy que j’appliquerais, dans un poste produit, à toute décision de plateforme d’agents — y compris pour déconseiller une construction sur-mesure lorsqu’un outil existant couvre le périmètre.
Siyao Zhang · Disponible à partir de septembre 2026, Pékin · Contact