Contexte et définition du problème
« A Programming Paradigm for Spatiotemporal Composability » est co-écrit par Yifan Shi, Wei Zhang (Université de Pékin) et Tianyi Cui (DeepSeek-AI, c.-à-d. l'auteur du framework Koishi, Shigma). Il s'agit d'un article de théorie des langages de programmation et de systèmes d'exécution, et non d'un article sur l'entraînement ou la capacité des modèles.
Agent = Model + Harness
[Conclusion originale de l'article §1.2.2] L'article prend l'Agent Runtime comme l'un de ses exemples moteurs : les agents IA modernes dépendent de runtime agent harnesses, des systèmes qui assemblent suites d'outils, environnements d'exécution, bac à sable de permissions, état de session, mémoire de contexte, flux de travail des sous-agents et UI ; « les futurs harnesses pourraient générer et déployer des modifications de leurs propres composants tout en continuant à servir des requêtes ».
Cette définition correspond exactement à la description officielle de DeepSeek pour le Harness : Agent = Model + Harness. Le Model est responsable du raisonnement et de la prise de décision ; le Harness fournit Tools / Skills / Sessions / Sandboxes / Storage / Loops / Sub-agent scheduling / UI via des plugins. DeepSeek Harness transforme tous ces domaines de capacité en plugins Cordis.
Pourquoi un Agent de longue durée et auto-modifiant a-t-il besoin de charger, décharger et remplacer dynamiquement des composants ? Parce que le trait caractéristique d'un Agent auto-évolutif est « se modifier pendant l'exécution » — mettre à niveau un outil, remplacer un Skill, ajuster l'environnement d'un sous-Agent. Si chaque modification imposait de redémarrer toute la session, le contexte et l'état intermédiaire seraient perdus ; si l'on ne redémarrait pas, les effets de bord de l'ancien composant (connexions ouvertes, callbacks enregistrés, état détenu) deviendraient des déchets flottants qui polluent l'exécution ultérieure. Les mécanismes traditionnels ne répondent pas à « comment remplacer proprement un composant encore utilisé ».
Pourquoi les plugins, la DI et le HMR traditionnels sont insuffisants
L'article §1.2.1 prend VSCode comme exemple canonique :
- Temporal limitation : l'extension host de VSCode n'offre aucun mécanisme pour décharger le code d'une extension en particulier à l'exécution ; désactiver ou désinstaller une extension exige de redémarrer tout l'host. 87 des 100 premières extensions contiennent du code exécutable, toutes nécessitent un redémarrage. Le hook
deactivaten'est utilisé que comme callback de sortie propre lors de l'arrêt du processus, et il sépare le effect disposal du effect creation (dansactivate), violant la locality of concern. - Spatial limitation :
extensionDependenciesest presque inutilisé (seulement 7 des 100 premières le déclarent) ; il n'existe aucun contrat structurel entre extensions, etgetExtension(...).exportsrenvoie une valeur de typeany.
[Inference basée sur l'article] La DI traditionnelle (p. ex. Spring, Angular) n'injecte les dépendances qu'à l'initialisation ; lorsqu'un provider est remplacé ou supprimé à l'exécution, les dependent existants ne sont ni désactivés ni réinitialisés. Le useEffect de React appareille effect et cleanup, mais les hooks ne peuvent être appelés dans des conditions/boucles/fonctions imbriquées, le corps de l'effect n'accepte pas de fonction async ou d'itérateur, et l'on ne peut composer un inverse composite à partir d'effects existants. Le HMR (webpack, Vite) migre l'état vers l'avant via import.meta.hot, en s'appuyant sur des fonctions de migration écrites à la main par les développeurs. La mémoire transactionnelle logicielle (STM) et RAII confinent la reversal à un scope statique fixe. OSGi Declarative Services réagit à la disponibilité du service, mais le callback de deactivation est écrit à la main et synchrone.
[Conclusion originale de l'article §1.2.3] Les systèmes d'exploitation offrent la temporal composability à granularité de processus ; les orchestrateurs de conteneurs offrent la spatial composability à granularité de service, mais ce sont des substituts à granularité grossière : chaque redémarrage discard tout l'état local au processus (caches, connexions, calculs partiels), et la reconstruction prend de quelques secondes à plusieurs minutes ; l'orchestration au niveau conteneur ne peut exprimer les dépendances entre composants partageant un même espace d'adressage. L'article exige une abstraction de composition à la même granularité que les composants eux-mêmes.
Deux dimensions orthogonales
[Conclusion originale de l'article §1.1] L'article identifie deux dimensions orthogonales de la composition dynamique :
- Temporal composability (dimension temporelle) : lorsqu'un composant est retiré, toute modification qu'il a apportée à l'environnement partagé doit être complètement et sûrement révertie. Cela exige de suivre chaque allocation de ressource, enregistrement d'événement et changement d'état effectué par le composant, et de garantir leur récupération ordonnée.
- Spatial composability (dimension spatiale) : les composants doivent pouvoir déclarer, découvrir et résoudre structurellement et de manière vérifiable les dépendances qu'ils ont entre eux. Cela exige de gérer la topologie des dépendances et de coordonner les cycles de vie des composants lorsque les dépendances changent.
[Conclusion originale de l'article §2.3] Effect décrit « comment un calcul modifie l'environnement », et Coeffect décrit « comment un calcul dépend de l'environnement » — les deux directions sont complémentaires, ne pas les confondre. Dans le cadre statique, le temporal se réduit au scope lexical (RAII, bracket pattern) et le spatial à la résolution d'import de module ; dans le cadre dynamique, les deux deviennent nettement plus difficiles.
La solution de l'article : élever le classique effect/coeffect de l'analyse statique à la compilation vers des mécanismes à l'exécution — Revertible Effects (toute transformation de contexte porte un inverse, suivi à l'exécution) résout le temporal ; Reactive Coeffects (les composants déclarent des spécifications de coeffect ; le contexte les notifie selon la spécification lorsqu'il change) résout le spatial. Les deux sont unifiés dans un seul type de contexte, constituent le concept de composant, et donnent un calcul de composition dynamique avec des propriétés métathéoriques prouvées.
Carte des concepts centraux
| Concept | Signification | Source |
|---|---|---|
| Revertible Effect | Toute transformation de contexte porte un inverse, suivi à l'exécution | §3.1, Def 8 |
| Reactive Coeffect | Les composants déclarent des spécifications de coeffect ; le contexte notifie selon la spécification lors d'un changement | §3.2.2, Def 26 |
| Unified Context Γ∞ | Un seul type de contexte portant récursivement (état, accumulateur, table de coeffect) | §3.3.1, Def 32 |
| Component ℭΓ | Un triplet (spec de dépendance d, provision p, fonction witness d'effect e) | §4.1, Def 43 |
| Fiber | Une instanciation d'un composant, portant l'état du cycle de vie | §4.1, Def 44 |
| Committed View ω | La résolution de dépendances actuellement commitée (mapping des noms de fiber) | §4.1, Def 44 |
| Target View | L'état de résolution de dépendances dans lequel le fiber devrait se trouver | §4.2, Def 46 |
| Isolation Realm | La même key se résout en instances différentes selon le contexte | §3.2.3, Def 28 |
| Interception | Ne pas remplacer la dépendance, seulement modifier comment elle est utilisée | §3.2.3, Def 30 |
Les chapitres suivants suivent cette ligne principale : Effects couvre la réversion du temporal ; Coeffects couvre la réponse du spatial ; Cycle de vie couvre la coordination des deux sur une instance de composant ; Théorèmes couvre ce que ce mécanisme garantit ; DeepSeek Harness couvre son atterrissage sur un véritable Agent Runtime ; Limites couvre ce qui n'est pas garanti.