Publié 22 sept. 202620 min de lecture
Les agents IA sont les nouveaux consommateurs : pourquoi Vinkius est le runtime sécurisé pour les flux de travail d'agents
Comment les agents IA sont devenus les premiers consommateurs stochastiques d'une plateforme cloud, et pourquoi Vinkius a construit un runtime en isolates V8, un plan de contrôle de gouvernance à douze surfaces et l'architecture MVA de MCP Fusion comme système d'exploitation sécurisé que les agents ne peuvent ignorer.

Par Renato Marinho
Founder · Vinkius
Je suis entré dans les flux de travail des agents depuis six mois. Pas à regarder des démonstrations sur des diapositives. À vivre cela. À voir des agents qui prennent des réunions, écrivent du code, interrogent des bases de données, transmettent de l'argent, ouvrent des tickets et oublient le numéro du ticket à l'appel suivant. Et ce que j'ai appris est simple : les agents ne sont pas des modèles plus performants. Ils sont des acteurs qui exécutent des écrits dans le monde via des outils, et la question n'est plus de savoir si un agent peut planifier une tâche. La question est de savoir si l'infrastructure qui héberge ces outils peut survivre au moment où l'agent décide d'agir.
Ceci est l'article dans lequel j'explique comment Vinkius est devenu le système d'exploitation pour les agents IA, et pourquoi l'écart entre un agent en démonstration et un agent auquel vous donneriez des identifiants de production n'est pas un problème de modèle. C'est un problème d'infrastructure. Et la réponse réside dans l'architecture que nous avons construite pour MCP Fusion.
L'agent n'est pas un utilisateur. C'est une nouvelle catégorie de consommateur.
Toute plateforme SaaS des vingt dernières années a été conçue pour un type d'appelant : un humain derrière un navigateur, ou un compte de service derrière un script connu. Ces deux appelants se comportent comme l'intérieur d'un système. Ils font ce qu'on leur dit. Ils échouent rapidement quand le schéma se casse. Ils ne réessayent pas un appel qui a retourné une erreur quatre fois, parce qu'ils n'ont pas oublié cette erreur depuis trois tours. Ils ne perdent pas de vue quelles sont les outils après un transfert vers un spécialiste. Ils n'avalement pas un réponse de deux cent mille octets dans le contexte pour ensuite résumer une ligne qui n'existe pas, car la troncature leur est invisible.
Un agent IA n'est aucune de ces choses. Un agent est stochastique par construction. Il enverra "INV-999" comme identifiant de facture même qu'il vient de lister et n'en a vu que trois. Il réessaiera un appel qui a retourné 404 avec la même entrée, parce qu'il ne se souvient pas de ce 404 depuis trois tours. Il perdra de vue quelles outils existent après un transfert vers un spécialiste. Il bouclera sur un outil cassé jusqu'à ce que le budget tokens s'effondre.
Et puis il appellera votre base de données de production. Votre API de paiement. Votre pipeline CI.
Les agents agissent déjà. Ils agissent sur des dossiers CRM, sur des factures, sur l'état de l'infrastructure. La question n'est plus s'ils vont agir. La question est : la surface sur laquelle ils agissent est-elle conçue pour un principal non déterministe qui ne peut pas lire un schéma et ne peut pas se rappeler une conversation ?
Pourquoi MCP Fusion n'est pas un simple serveur MCP de plus
Le MCP a résolu le problème de découverte qui maintenait toute intégration LLM prisonnière de chaînes de prompts fragiles. Mais les serveurs MCP classiques héritent de tous les problèmes du modèle de serveur brut, et ces problèmes deviennent catastrophiques quand le consommateur est un agent plutôt qu'un humain. Un serveur brut fuit ce qu'il renvoie, car sa sortie est la ligne, sérialisée. Un serveur brut n'applique rien, car son middleware est une convention, pas une garantie. Un serveur brut ne peut pas voir son propre drift, car il n'a aucun mécanisme pour détecter que la surface qu'il expose aujourd'hui diffère de celle qu'il exposait hier. Un serveur brut répond aux erreurs avec des chaînes, et l'agent réessaie avec la même chaîne.
MCP Fusion corrige cela avec une architecture appelée MVA, et le nom est le point central. La séparation n'est pas arbitraire. C'est la séparation que le code applicatif connaît déjà, mais tournée vers un nouveau consommateur.
Le Model définit ce que la donnée est et ce qui peut quitter le processus. Il déclare des champs, des types et des descriptions. Ces descriptions ne sont pas une documentation pour un humain. Elles se compilent, juste à temps, en règles d'interprétation que l'agent reçoit avec chaque réponse. Le model déclare des champs cachés, des hachages de mots de passe, des indicateurs internes, des marqueurs de locataire, et ils ne traversent jamais la frontière. Une nouvelle colonne de base de données ne fuit pas vers un agent tant qu'un quelqu'un ne l'a pas déclarée dans le model. Un serveur brut n'a pas cette propriété.
Le Presenter définit ce que l'agent perçoit de la donnée. Avant toute sérialisation, le Presenter exécute son schéma sur le résultat brut en mode strip : quoi que la base ait renvoyé, l'agent ne voit que la surface déclarée. C'est le contrôle de egress au niveau de la mémoire, pas une couche de vue, pas un gabarit, pas une convention. Un champ que le schéma ne connaît pas ne peut pas traverser. Le Presenter attache également des règles système, des limites de travail et des affordances. suggestActions indique à l'agent ce qu'il peut faire ensuite avec ce qu'il vient de voir. C'est le HATEOAS pour les agents. La réponse n'est pas une charge utile. C'est une position dans un flux de travail. Les blocs de graphiques rendus par le serveur sont déterministes : le framework les rend, l'agent les lit, et aucun modèle intermédiaire ne génère les pixels.
Les Outils détiennent les verbes. f.query est en lecture seule par défaut. f.mutation est destructeur par défaut. f.action est neutre. Ce ne sont pas des étiquettes de métadonnées. Ils déterminent ce que la plateforme considère sûr de réessayer, ce que le pipeline d'observation marque, et ce qu'un outil de gouvernance signale quand une lecture devient une écriture.
Une règle garde la séparation honnête, et c'est une propriété de sécurité, pas une règle de style. Direction. Les outils importent les présentateurs, les présentateurs importent les modèles, les modèles importent le core, et rien n'importe en arrière. La couche qui touche vos données ne doit jamais être la couche qu'un agent peut piloter.
C'est l'architecture sur laquelle chaque connecteur déployé sur Vinkius Cloud est construit, et c'est pourquoi le runtime n'a pas besoin de faire confiance au code qu'il exécute.
La couche d'isolate V8 : où le code client rencontre le contrôle de la plateforme
Chaque serveur MCP qu'un client déploie sur Vinkius Cloud est, tôt ou tard, du code tiers exécuté sur notre infrastructure. Pas le nôtre. Pas une bibliothèque que nous contrôlons. Leur. Un cloud pour agents IA n'est utile que si les clients peuvent apporter leur propre logique, leurs propres connecteurs, leur propre collier entre un LLM et leurs systèmes. Une fois que cette capacité existe, la question devient : comment exécuter du JavaScript non fiable pour des milliers de locataires sur un petit nombre de serveurs sans donner à un seul la possibilité de blesser les autres, la machine, ou ses voisins ?
La réponse est un isolate V8 par locataire, construit sur Node.js avec isolated-vm, le binding C++ qui permet à un processus Node de posséder un isolate V8 natif. Pas un conteneur par locataire. Pas un processus par locataire. Un isolate. Un tas avec son propre ramasse-miettes, sa propre portée globale, et una limite de mémoire dure de 128 MB que le moteur impose, pas l'application. Quand le tas d'un locataire l'atteint, l'isolate de ce locataire cesse d'être servi. Les autres locataires continuent. Le globalThis d'un locataire n'est pas atteignable depuis l'isolate d'un autre, car il n'existe aucune frontière JavaScript partagée.
Le démarrage est divisé en deux phases, et seule la première apparaît dans les métriques de cold start. Phase un : le binaire V8 et la couche de polyfills s'initialisent, ce qui prend 50 à 100 millisecondes au premier contact avec un déploiement. Phase deux : le bundle du locataire est chargé, enveloppé et exécuté à l'intérieur de l'isolate, ce qui se produit à chaque requête car l'instantané ne peut pas capturer d'état asynchrone. La plateforme instantané l'environnement, pas le programme. La couche de polyfills est statique pour un déploiement donné. Ce qui change à chaque requête, c'est le code du locataire. L'hôte exécute le constructeur d'instantané sur l'environnement provisionné et cache le blob résultant sur le disque, indexé par l'ID de déploiement et horodaté de la version de V8. À la restauration, un nouvel isolate est créé à partir de ce blob en 15 à 25 millisecondes au total. Le bundle est réexécuté, car la création d'isolate à partir d'un instantané ne peut pas gérer l'await en haut niveau asynchrone, mais le travail de polyfill se produit exactement une fois par déploiement.
La version de V8 importe. Les isolates de V8 ne sont pas rétro-compatibles entre les versions majeures du moteur. Un instantané construit sur V8 version N ne peut pas être chargé par V8 version N+1. L'hôte horodote le blob d'instantané avec la version du moteur et refuse de charger un blob dont l'horodatage ne correspond pas à la version en cours d'exécution. Un non-correspondance est un cache miss, pas un plantage.
L'isolation n'est pas seulement mémoire. L'environnement vide que V8 donne à l'isolate n'a pas de fetch, pas de crypto, pas de timers, pas de process. Rien qui touche le monde extérieur n'existe à l'intérieur de l'isolate. Le fetch dans un bundle de locataire est un polyfill du côté invité, mais la requête elle-même se produit du côté hôte, à travers la passerelle hôte, comme une copie ArrayBuffer binaire sécurisée entre les frontières. Crypto.subtle.digest et HMAC, ceux dont la vérification de JWT a besoin, sont également du côté hôte, et l'hôte vérifie les signatures avec une comparaison à temps constant. Les timers sont des setTimeout côté hôte qui rappellent l'invité via un invoker enregistré, limités à cinq secondes au niveau du framework et trente secondes au niveau du dispatch. La règle est simple. Le polyfill fait paraître l'appel natif. L'hôte possède l'effet. Un locataire peut exprimer l'intention. Il ne peut pas atteindre le système d'exploitation.
Ce design est celui que j'ai décrit en détail dans le post sur les isolates V8. La limite de cinq secondes est la limite d'exécution par isolate. La limite de trente secondes est la limite de dispatch. La limite de dix mégaoctets de réponse est la limite d'egress. Les trois sont des politiques nommées dans la configuration du runtime, pas des nombres magiques, et les trois sont documentés à côté de la constante qui les définit.
Le garde-fou SSRF : le trafic sortant comme une politique, pas une option par défaut
La chose la plus dangereuse qu'un bundle de locataire puisse faire est une requête HTTP. Fetch est une source universelle de SSRF. Un bundle négligent ou malveillant pointant un outil vers le service de métadonnées AWS, à l'adresse 169.254.169.254, offre à l'agent d'un client un chemin de lecture vers les identifiants de l'instance.
Tout le trafic sortant passe par le garde-fou SSRF. Le garde-fou fonctionne selon un principe. Une adresse n'est valide que tant que la politique qui l'a approuvée l'est. Le garde-fou résout le DNS avant la requête et bloque les plages privées net : loopback, 10 slash 8, 172.16 slash 12, 192.168 slash 16, link-local 169.254 slash 16, zero slash 8 et leurs jumeaux IPv6. Il fixe ensuite l'IP approuvée dans la connexion, de sorte qu'une attaque de réattribution ne peut pas échanger l'adresse après l'inspection. Et il maintient SNI et TLS alignés avec l'adresse fixée, car une fixation au niveau de la socket sans fixer le nom générerait des erreurs de certificat à chaque requête.
Les réponses s'installent dans l'isolate avec un compteur d'octets en cours, limité à dix mégaoctets, avec un AbortController connecté à toute la voie de destruction. Quand un isolate est retiré, ses requêtes en cours sont interrompues dans le même appel. Quand un dispatch expire à la limite de trente secondes, un classifieur demande ce que l'isolate faisait au moment de la rupture. E/S sortante en cours, l'invité qui calcule, ou pression mémoire. L'erreur de l'outil qui revient à l'agent porte la réponse, plus une suggestion de récupération.
La durée de vie du cache DNS est liée à la durée de vie de la connexion. Une adresse triée est mise en cache exactement aussi longtemps que le pool tient un agent keep-alive pour elle, jusqu'à 65 secondes par défaut. Une adresse ne peut pas dépasser la politique de connexion qui a justifié sa fixation. Il n'existe pas de TTL indépendant par conception, et c'est la propriété qui ferme complètement la fenêtre de réattribution.
Le chemin d'audit cryptographique : une chaîne que vous ne pouvez pas forger
Toute la circulation des agents, tous les appels d'outils, toutes les données circulant entre et hors de chaque connecteur, coulent vers un daemon de streaming à thread unique. Ce daemon forge une chaîne SHA-256 et la signe avec une clé Ed25519 de session. La clé de session reste en RAM pendant vingt-quatre heures et est certifiée par la clé maîtresse au démarrage. Chaque hachage de requête est scellé à l'ingestion. Chaque enregistrement porte le hachage précédent et sa position dans la séquence. La chaîne est signée. Une altération n'est pas un problème de confidentialité. C'est un événement détectable.
L'entrée de la chaîne est la charge utile en base64 concatenée avec le hachage précédent et le numéro de séquence. Le hachage actuel est SHA-256 de cette entrée. La signature est Ed25519 sur la même entrée, en utilisant la clé privée de session. La clé de session tourne toutes les vingt-quatre heures, et la chaîne continue sans interruption. L'état de la chaîne est pointé sur Redis Streams, de sorte qu'un plantage reprend à partir du dernier événement accusé de réception au lieu de re-dérifier la chaîne. Les adaptateurs SIEM drainen cette même source derrière leurs propres disjoncteurs. Un point d'exportation défaillant est isolé plutôt que permettre à la voie d'audit de s'engorger.
L'audit est structuré autour de l'Article 73 du RGPD, le droit d'accès du personnes concernées. Quand un régulateur ou un client demande l'historique complet d'un connecteur, la réponse est une seule chaîne exportable et vérifiable, pas un projet.
Et voici la frontière dont je suis le plus fier. V8 ne touche jamais à la crypto. Le code du locataire peut calculer un hachage via les ponts hôtes, mais il ne peut pas signer, certifier ou falsifier quoi que ce soit. Le trajet d'audit est quelque chose que la plateforme fait au runtime, pas quelque chose que les locataires du runtime peuvent atteindre.
Le modèle complet des douze surfaces, la couche d'audit, la couche d'appât et le coffre sont décrits dans le post sur la gouvernance IA.
Les douze surfaces : la gouvernance comme système d'exploitation
Si vous avez lu le post sur la gouvernance IA, vous connaissez le plan de contrôle. Douze surfaces, huit qui rapportent et quatre qui décident, reposant sur des jetons de connexion à portée, un coffre scellé pour les credentials, un ledger encodé par hash et une couche d'appât qui contient les dégâts avant que vous les remarquiziez. Ce que je n'ai pas encore dit, c'est comment ces douze surfaces se mappent sur le nouveau consommateur, l'agent IA lui-même.
L'agent ne voit pas les douze surfaces directement. Il les voit comme des contraintes sur l'environnement dans lequel il opère. Et ces contraintes sont ce qui permet de remettre l'agent au quart de nuit, la requête de production, la réconciliation de paiement.
Attribution. Chaque appel d'outil porte l'identité du jeton qui l'a fait, le client derrière lui, l'humain ou le compte de service derrière ça. Il n'existe pas d'action anonyme en production. Un agent qui devrait tourner à chaque heure et appelle toutes les quatre-vingt-dix secondes apparaît sur Mission Control, et c'est là qu'une boucle incontrôlable est d'abord remarquée, avant qu'elle ne devienne une facture.
Protection des données. Les champs sensibles sont masqués en mémoire, sur la voie de sortie entre l'upstream et le modèle. La protection se fait avant que la réponse n'atteigne l'agent. La différence entre des données masquées et des données qui n'ont jamais été dans le contexte du modèle.
Contrôle des coûts. Le disjoncteur applique un budget de requêtes en fenêtre glissante par connecteur, avec une valeur par défaut de cinq mille requêtes toutes les cinq minutes et un refroidissement de quinze minutes. Quand le budget est dépassé, le disjoncteur se déclenche et informe l'agent, par un refus lisible par machine rédigé pour un modèle, que la ressource est ouverte et qu'il doit se replier. Un bon agent respecte cela. Une boucle qui ne peut pas lire le refus est arrêtée par le même déclenchement, c'est l'objectif. L'état du disjoncteur est partagé entre la flotte de passerelles, ainsi un budget est un budget, pas une limite par processus qui se réinitialise quand le trafic passe d'une instance à l'autre.
Récupération d'erreur. Un serveur brut répond à un appel erroné avec une chaîne platete. L'agent réessaie avec la même chaîne. MCP Fusion répond par une enveloppe auto-réparable. Un code précis, un message, une suggestion et une liste d'actions que l'agent peut entreprendre à la place. InvoiceNotFound dit à l'agent quelque chose que BAD_REQUEST ne peut pas dire, et la ligne de récupération enlève l'interprétation qui rend les boucles coûteuses. C'est le sujet du post sur l'architecture de connecteurs, où le modèle MVA complet est expliqué.
Le lockfile de capacité : la détection de drift comme une étape de compilation
L'un des échecs silencieux dans les systèmes agniques est le drift. Le serveur que vous avez déployé le mois dernier exposait douze outils. Aujourd'hui il expose dix-sept, parce que quelqu'un a ajouté cinq. L'agent appelle les nouveaux. Personne ne les a revus. La sortie est la même ligne, mais elle va dans un autre endroit, et le trajet d'audit enregistre l'appel, mais la surface revue en CI n'est pas la surface que l'agent peut atteindre.
Le CLI de MCP Fusion exécute une deuxième compilation introspective de chaque bundle. Il extrait les contrats des outils, les prompts et le schéma de credential et les écrit dans un lockfile de capacité. C'est un instantané déterministe de la surface comportementale du connecteur. Le lockfile est diffusable dans git. Un fusion lock --check en CI est la porte. La surface que votre code expose vraiment est comparée à la surface que vous avez commitée, et le diff est classé comme breaking, risky, safe ou cosmetic.
Le runtime qui exécute finalement ce programme, scellé et restauré par snapshot, est le même programme qui a produit ce lockfile. Le code source, le bundle compilé et le lockfile commité sont un seul artefact. Le drift est impossible parce qu'un drift voudrait dire que le lockfile et le code en cours d'exécution en étaient à des égards, et cette divergence échoue à la porte de CI.
Le connecteur voyage comme un seul artefact. La commande mcpfusion deploy regroupe le serveur dans un fichier auto-contenu : toutes les dépendances inlinées, les built-in Node remplacés par des stubs qui n'existent que pour satisfaire le bundler et ne sont jamais appelés, et le transport lui-même stubbé, car c'est la plateforme qui le fournit. Le bundle passe une porte de taille de 1,5 mégaoctets brut, qui est un budget, pas une spécification. Il est ensuite compressé, haché et envoyé vers le edge. Si le hachage correspond au hachage déployé, la plateforme signale une restauration instantanée : les mêmes octets, sans rechargement.
L'orchestration multi-agents : le SwarmGateway
Toute tâche ne peut pas être résolue par un seul agent. Certains problèmes ont besoin de spécialistes. Un spécialiste des finances, un spécialiste du devops, un spécialiste des opérations client. Chacun d'eux est son propre serveur MCP, son propre modèle, ses propres outils.
Le SwarmGateway implémente le modèle B2BUA. Il se présente au agent appelant comme un seul serveur MCP avec une liste d'outils préfixée. Quand l'agent appelle un outil préfixé, le gateway retire le préfixe et transmet l'appel au serveur spécialiste en amont. Quand l'agent a fini avec le spécialiste, un seul outil de retour ferme le tunnel et restaure la liste d'outils du gateway. Chaque transfert génère un jeton de délégation de courte durée, à portée uniquement pour ce domaine, valide soixante secondes. Le tunnel inactif expire après cinq minutes.
Deux propriétés de sécurité sont importantes ici. Premièrement, le jeton de délégation ne peut pas s'échapper de sa prison, car le gateway valide le domaine contre son registre à chaque appel. Deuxièmement, l'outil de retour est injecté par le gateway, pas par l'upstream, ce qui signifie qu'un spécialiste compromis ou bogué ne peut pas tromper l'agent pour appeler un gateway différent. Le réécrivain de namespace applique cela au niveau du nom de l'outil.
Et parce que le gateway parle le même contexte de trace que l'agent entrant, chaque span d'outil à travers le transfert du spécialiste se raccorde à la même trace. Vous pouvez suivre l'agent de la couche de triage au spécialiste des finances au spécialiste du devops et retour, le tout dans une trace distribuée. Ce travail, la propagation du contexte W3C Trace à travers le gateway, a été livré dans MCP Fusion 5.1.0, et les détails sont dans le post sur la corrélation de trace. Quand le swarm frappe le gateway à grande échelle, la couche de session doit fusionner chaque agent sans deadlock. Les mécanismes derrière le pooling de sessions, l'invalidation causale et le circuit breaker qui maintient un swarm incontrôlé sous contrôle sont dans l'article sur les sessions SwarmGateway.
L'agent comme principal gouverné
La plupart des conversations sur la gouvernance d'agents traitent l'agent comme un risque à contenir, et je ne vais pas prétendre le contraire. L'agent est un risque. Un principal non déterministe appelant des outils contre des systèmes de tiers sous un budget. C'est le risque.
Mais l'autre moitié de l'argument est celle que je mettrais dans un deck commercial : la gouvernance est ce qui transforme un agent de démonstration en employé.
La confiance est accordée en proportion de la preuve. Un opérateur remettra l'agent au quart de nuit, la requête de production, la réconciliation de paiement, dans la proportion exacte où chaque action qu'il a accomplie peut être attribuée, budgétisée, protégée et vérifiée après. Le reçu n'est pas un fardeau pour l'agent. C'est le credential qui lui donne la pièce plus grande.
L'enveloppe d'un agent gouverné est connaissable. Une politique déterministe autour d'un modèle non déterministe est la seule forme saine pour la production : le modèle planifie dans une boîte, et la boîte est stable. Le refus du disjoncteur est écrit dans la langue du modèle, de sorte que l'agent apprend le budget et le respecte, au lieu de le découvrir sous forme de facture. La troncature dans la garde FinOps signifie que le modèle reçoit une réponse dimensionnée au lieu d'un blob de deux cent mille octets, ce qu'est un problème d'intelligence, pas seulement de coût.
Et l'agent gagne lui-même la capacité qu'aucun système autonome n'a jamais eu en pratique. Il peut montrer son travail. Pour un agent qui opère dans des flux réglementés, le trajet d'audit n'est pas un overhead. C'est le produit. L'agent gouverné est le seul type d'agent auquel on peut donner une vraie autorité, et l'agent non gouverné est, pour toujours, une démonstration.
Direction
Ce que je viens de décrire est la stack qui tourne aujourd'hui. Pas le plan. Pas la feuille de route. La stack sur laquelle le serveur MCP d'un client, construit avec MCP Fusion, navigue vers le edge et s'exécute à l'intérieur.
La direction ouverte est l'état. Un état de locataire plus long voyant les crochets d'hibernation de l'isolate. Un empaquetage plus dense d'isolates vivants par hôte. Les équipes apportent leurs propres catalogues de connecteurs dans le marketplace sans attendre notre CI. La couche d'instantané porte déjà l'interface d'hibernation. La couche de synchronisation d'état comprend déjà l'invalidation causale. Ce qu'il reste, c'est la densité et l'expérience de développement.
La direction profonde est la passerelle de protocole A2A. MCP Fusion expose déjà n'importe quel serveur comme un agent compatible A2A, avec le endpoint de découverte standard au chemin well-known agent-card.json. Le SwarmGateway parle déjà le modèle B2BUA. Quand A2A mûrit et que les agents commencent à se découvrir mutuellement de façon autonome, le gateway ne change pas. Il gère déjà une flotte de spécialistes derrière une seule surface, avec des jetons de délégation à portée et la continuité de trace à travers chaque transfert.
La frontière
Je ne pense pas que les isolates V8 sont la réponse finale au code edge multi-tenant. Ils sont la réponse pour la forme que cette plateforme a, et la forme est là où je veux qu'elle reste. Des locataires bon marché. Des limites dures. Un démarrage à l'échelle de millisecondes. Parce que la patience d'un agent se mesure en secondes, et que la confiance aussi.
Les agents agissent déjà sur vos systèmes. La question n'est plus si vous pouvez vous permettre la gouvernance. C'est si vous pouvez vous permettre le jour où vous découvrirez que vous n'en aviez pas. Vinkius Cloud est le runtime qui livre cette gouvernance, et MCP Fusion est le framework qui le rend composable. Les deux sont le résultat de construire autour d'un invariant : le consommateur n'est pas un humain qui lit un écran. Le consommateur est un modèle qui ne peut pas lire un schéma et ne peut pas se rappeler une conversation. Tout le reste découle de cela.
Si vous construisez des agents qui agissent sur des systèmes de production, le système d'exploitation sur lequel ils tournent devrait être conçu pour ce consommateur, pas adapté après coup. C'est ce que nous avons construit. C'est ce que le code applique. Et c'est pourquoi le trajet d'audit est quelque chose que la plateforme fait au runtime, pas quelque chose que les locataires du runtime peuvent atteindre.
Le runtime derrière les serveurs MCP sur cloud.vinkius.com est ce que je viens de décrire. Le framework est open source sur github.com/vinkius-labs/mcpfusion. Les deux sont écrits selon le même invariant.
