Nous avons réécrit notre agent pour qu'il s'exécute entièrement dans un Durable Object avec Pi, Agents SDK et Code Mode

@Vercantez
ANGLAISil y a 1 jour · 28 juil. 2026
424K
1.4K
136
64
3.0K

TL;DR

Une analyse technique de la migration de camelAI d'une infrastructure basée sur des machines virtuelles vers une pile native Cloudflare, remplaçant Bash par JavaScript pour optimiser les coûts et les performances.

Nous avons récemment terminé de déplacer l'agent camelAI hors des machines virtuelles. L'agent s'exécute désormais à l'intérieur d'un Cloudflare Durable Object, son système de fichiers réside dans SQLite et R2, et il écrit du JavaScript au lieu de bash. La plupart des équipes font tourner leurs agents de codage dans une VM Linux complète ou un bac à sable conteneurisé, et nous faisions de même.

Nous voulions nous débarrasser des VM parce qu'offrir à chaque utilisateur une machine toujours allumée avec un disque attaché était trop coûteux à passer à l'échelle. La difficulté est que les agents de codage partent du principe que Linux est présent. Ils sont entraînés à utiliser bash, et le harnais sur lequel nous avons lancé nécessitait une VM complète, donc nous avons dû passer par trois refontes pour arriver ici. Le compromis, c'est que l'agent ne peut désormais faire que les choses pour lesquelles nous avons construit une méthode explicite, ce qui semble limitant mais s'est avéré bénéfique pour le produit.

Je suis Miguel, CTO de camelAI. Notre codebase est récemment devenue open source, donc tout ce qui est dans cet article est du code que vous pouvez lire sur github.com/qaml-ai/camelAI. Je vais lier les fichiers pertinents au fur et à mesure. Voici la progression.

Étape zéro : l'ère des VM

Nous avons lancé sur le harnais Claude Code, qui nécessite une machine virtuelle complète pour fonctionner. Nous avons essayé plusieurs fournisseurs de VM, aucun ne correspondait à nos exigences de persistance et de performance, et nous avons fini par construire notre propre service de conteneurs. Cet article est toujours en ligne, mais nous n'exploitons plus aucune de cette infrastructure.

Le service de conteneurs fonctionnait, mais il était lourd. Une VM toujours allumée pour chaque utilisateur est coûteuse, et conserver les fichiers de chaque utilisateur sur un disque rapide attaché l'est tout autant. Passer à l'échelle signifie passer à l'échelle des machines réelles avec des disques réels, ce qui allait être prohibitif pour les nombres d'utilisateurs que nous visons. Alors au lieu de devenir malins sur l'orchestration de VM, nous avons commencé à concevoir pour ne pas avoir besoin de VM du tout.

Première étape : sortir l'agent de la VM

Le harnais Claude Code est inséparable de sa VM, donc la première manœuvre a été de construire notre propre harnais. Nous l'avons construit sur pi, l'agent de codage open source de Mario Zechner. pi est une pile de bibliothèques. La couche la plus haute suppose un système d'exploitation normal, mais les couches inférieures vous donnent les primitives de l'agent, comme la boucle d'agent et la gestion d'état, sans se soucier de l'endroit où elles s'exécutent. Nous n'avons modifié aucun code de pi. Nous avons importé ces couches inférieures et construit notre propre harnais par-dessus, fonctionnant à l'intérieur d'un Cloudflare Durable Object au lieu d'un environnement Linux.

Un Durable Object est une petite instance de calcul avec état qui se lance sur le edge de Cloudflare, près de l'utilisateur qui l'a créée. Chaque fil de discussion obtient son propre Durable Object, ce qui a réduit la latence par rapport au routage via un hôte de VM centralisé.

À ce stade, nous avons gardé les VM, mais l'agent ne vivait plus à l'intérieur d'une. Il appelait la VM à distance quand il avait besoin d'exécuter des commandes. Anthropic décrit cette même séparation pour ses agents gérés, le cerveau séparé des mains. Cela nous a donné de belles propriétés :

  • L'agent commence à répondre avant que la VM soit prête, car il n'attend pas le démarrage d'une machine.
  • La VM peut se rendormir pendant que l'agent continue à travailler, ou ne jamais se réveiller si le tour n'a besoin d'aucune commande.
  • Un cerveau peut contrôler plusieurs mains. Un seul agent pouvait faire fonctionner plusieurs VM à la fois.

Nous appelons ces mains des projets. Chaque projet était accompagné d'une VM pour exécuter des commandes et d'un dépôt git créé par programmation via Cloudflare Artifacts, un stockage compatible git que l'on peut provisionner à la volée depuis un Worker. L'agent ne savait pas vraiment qu'il tournait en dehors de la VM. Il avait toujours bash et fonctionnait comme n'importe quel autre agent de codage.

Le problème, c'est que cela a résolu la latence et rien d'autre. Nous avions toujours une VM par utilisateur, donc tous les problèmes de coût et de passage à l'échelle de la conception originale persistaient.

Deuxième étape : supprimer la VM

La version suivante a conservé la même structure de projet mais a supprimé la VM derrière. Chaque projet est désormais adossé à un système de fichiers qui vit à l'intérieur d'un Durable Object, avec R2 derrière pour les fichiers plus volumineux.

Nous n'avons pas inventé cela. L'équipe agents de Cloudflare a construit Shell, un système de fichiers et un runtime d'exécution expérimentaux pour Workers, et nous avons largement réutilisé leur code. Les mécanismes sont simples. Le stockage d'un Durable Object est une base de données SQLite avec une limite de 10 Go, et chaque ligne a une taille maximale. Les petits fichiers vivent directement dans les lignes SQLite. Les fichiers de plus d'environ 1,5 Mo sont écrits dans R2, et la ligne SQLite ne contient qu'un pointeur. Pour l'agent, cela ressemble à un système de fichiers normal, mais en dessous c'est une base de données et un stockage d'objets, donc la persistance est une donnée stockée plutôt qu'une infrastructure que nous devons maintenir en vie.

L'historique des versions passe toujours par Artifacts, donc chaque projet conserve un historique git sans que nous hébergions un serveur git.

Troisième étape : supprimer bash

Supprimer bash semblait radical. Les agents de codage sont entraînés à utiliser bash, et c'est pourquoi tout le monde les fait tourner dans des VM. C'était aussi un problème au-delà du coût. Un agent avec bash et accès réseau a besoin d'identifiants pour faire quoi que ce soit d'utile, et nos tentatives d'URL proxy authentifiées devenaient bancales et difficiles à appliquer.

Donc nous l'avons supprimé. Au lieu de bash, l'agent écrit du JavaScript, exécuté via Code Mode et les chargeurs de Workers dynamiques de Cloudflare. Chaque exécution tourne dans un nouvel isolate V8 qui démarre en quelques millisecondes et utilise quelques mégaoctets de mémoire. Le bac à sable est préchargé avec les connexions de données de l'utilisateur et avec des méthodes pour tout ce que la plateforme peut faire. Les identifiants n'entrent jamais dans le bac à sable. L'agent appelle les méthodes d'une connexion, et l'authentification se fait de notre côté.

Quand on regarde ce que les agents font réellement avec bash, sa perte coûte moins qu'on ne le pense. La plupart sont des opérations sur les fichiers, pour lesquelles l'agent dispose d'outils natifs. Nous lui donnons lecture, écriture et édition, plus nos propres implémentations de grep et glob. Cela couvre le 80-20. Le reste, ce sont des commandes spécifiques pour des tâches spécifiques, et elles sont devenues des méthodes explicites :

  • wrangler deploy via un proxy est devenu une méthode deploy_project que nous contrôlons entièrement. Comme nous savons exactement quand un déploiement a lieu, nous pouvons nous y accrocher et ouvrir un aperçu en direct automatiquement. Avant, nous devions renifler le trafic wrangler proxyfié pour deviner quel thread avait déployé quelque chose.
  • La construction de l'application de l'utilisateur et l'exécution de notebooks Python sont devenues leurs propres méthodes, toutes deux adossées à des conteneurs éphémères.

Nous avons gardé des conteneurs pour ces deux tâches parce qu'elles ont vraiment besoin de Linux. Les applications utilisateur sont construites avec Vite, Tailwind et React Router, et ajouter des dépendances signifie exécuter bun install. Nous avons envisagé d'exécuter les builds à l'intérieur d'un Worker, puisque ce qui est construit est lui-même un Worker, mais cette voie n'est pas bien supportée, et les Workers ont une limite de mémoire de 128 Mo et une fraction de CPU. Les builds seraient lents et beaucoup de projets dépasseraient la limite de mémoire. Donc à la place, un build lance un conteneur via le Cloudflare Sandbox SDK, copie le projet dedans, exécute la tâche, retourne le résultat, et arrête le conteneur. Les exécutions de notebooks fonctionnent de la même manière. Nous utilisons toujours du Linux complet, mais seulement pour les secondes de travail qui en ont réellement besoin.

L'inconvénient réel est que nous devons anticiper ce dont l'agent a besoin. Avec bash, il pouvait se débrouiller seul. Maintenant, si une capacité manque, nous devons l'ajouter. En pratique, cette pression a été bonne pour le produit, car elle nous oblige à réfléchir à ce que les utilisateurs font et à construire un chemin de première classe pour cela au lieu de laisser l'agent improviser.

Il y a eu aussi un bénéfice inattendu. Bash est ouvert, et les modèles bon marché luttent dans des environnements ouverts. Avec un ensemble plus restreint de méthodes explicites, ils performent nettement mieux, ce qui est important car garder camelAI économique à faire fonctionner est le but de cette architecture.

Où cela nous mène

La pile est désormais composée de Durable Objects pour l'agent et son système de fichiers, R2 pour les gros fichiers, Artifacts pour l'historique git, pi comme harnais, et Code Mode avec des Workers dynamiques pour l'exécution. Elle se déploie comme n'importe quelle autre application Cloudflare, et il n'y a aucun service de conteneurs externe à gérer.

Les Workers dynamiques sont facturés par exécution, pas par seconde de disponibilité. Des milliers d'exécutions coûtent à peu près ce que quelques minutes de temps de conteneur coûtent sur les services que nous évaluions auparavant. La latence est faible car tout tourne sur le edge près de l'utilisateur, et le passage à l'échelle est le problème de Cloudflare, pas le nôtre.

Les utilisateurs construisent et déploient toujours des applications full-stack vers des URL en direct, et l'agent lit, écrit, grep et déploie toujours. Du côté de l'utilisateur, rien n'a changé.

TL;DR

Nous avons commencé avec le harnais Claude Code sur un service de VM auto-construit, qui était coûteux et difficile à passer à l'échelle. D'abord nous avons déplacé l'agent lui-même dans un Cloudflare Durable Object et lui avons permis de contrôler les VM à distance, ce qui a résolu la latence mais pas le coût. Ensuite nous avons remplacé les VM entièrement par un système de fichiers stocké dans SQLite de Durable Object et R2, basé sur le projet Shell de Cloudflare, avec un historique git via Cloudflare Artifacts. Enfin nous avons supprimé bash et donné à l'agent un bac à sable JavaScript via Code Mode et les Workers dynamiques, avec des méthodes explicites pour les déploiements, les builds et les notebooks. Le résultat est moins cher de plusieurs ordres de grandeur, une latence plus faible, plus simple à exploiter, et plus facile à piloter pour les petits modèles. Tout est open source sur github.com/qaml-ai/camelAI.

Enregistrer en un clic

Lire les articles viraux en profondeur avec l’IA de YouMind

Enregistrez la source, posez des questions ciblées, résumez l’argument et transformez un article viral en notes réutilisables dans un seul espace de travail IA.

Découvrir YouMind
Pour les créateurs

Transformez votre Markdown en un article 𝕏 impeccable

Quand vous publiez vos propres textes longs, la mise en forme 𝕏 des images, tableaux et blocs de code est pénible. YouMind transforme un brouillon Markdown complet en un article 𝕏 impeccable, prêt à publier.

Essayer Markdown vers 𝕏

D'autres patterns à décoder

Articles viraux récents

Explorer plus d'articles viraux