Lorsqu’un produit d’agents IA arrive à maturité, ce qui coûte le plus cher, ce ne sont pas les fonctionnalités, mais les fondations. Cet article retrace la refonte complète menée par Orkas dans sa série de versions 1.0 : une révision de fond de l’invocation des modèles, de la boucle d’agent, de l’orchestration multi-agents et de l’écosystème d’outils, ainsi que les compromis derrière chaque décision.
Pourquoi toucher aux fondations
Orkas est un espace de travail de bureau pour agents IA privilégiant le stockage local : tout le travail des agents s’exécute dans un processus sur la machine de l’utilisateur, les données résident localement et la synchronisation cloud de bout en bout se fait à la demande. Les fonctionnalités se sont rapidement accumulées dans les premières versions — bibliothèque de Skills, base de connaissances, connecteurs, multi-agents sous forme de discussion de groupe —, mais plus nous avancions, plus le constat devenait clair : le véritable goulot d’étranglement n’était pas une fonctionnalité particulière, mais trois éléments fondamentaux.
Si la couche d’invocation des modèles suit l’ancien schéma conversationnel, elle se retrouve entravée par une série d’hypothèses erronées. Appeler un grand modèle comme s’il s’agissait d’une discussion « une question, une réponse » introduit un ensemble de réglages par défaut pertinents pour un chat, mais pas pour un agent : plafond fixe de tokens de sortie, appels d’outils séquentiels, délais d’expiration cachés, fournisseur unique codé en dur. Un agent est un flux de longue durée qui enchaîne des dizaines de tours, approche régulièrement la limite de contexte, doit lire des fichiers en parallèle et peut être interrompu par l’utilisateur à tout instant. Chacun de ces réglages finit par poser problème en production. Pire encore, les capacités les plus précieuses d’un agent de bureau — opérations fines sur les fichiers, recherche locale, exécution d’un shell, travail parallèle de plusieurs exécutants, résolution de tâches de longue durée — sont précisément celles que cette couche d’hypothèses empêche.
L’orchestration reposait sur une « planification statique ». La première version était un moteur de plans/DAG : le modèle décomposait d’abord la tâche en graphe de planification, puis un exécuteur distribuait le travail selon ce graphe. L’idée paraît ordonnée, mais la réalité d’un agent est très dynamique : la lecture d’un fichier révèle qu’il faut changer de direction, et le résultat d’une sous-tâche détermine à qui confier la suivante. Figer les décisions dans un graphe prégénéré oblige à corriger dans l’exécuteur chaque situation où « le plan ne suit plus la réalité ».
L’écosystème était un catalogue fermé. Les Skills ne pouvaient provenir que de la marketplace officielle, les connecteurs formaient un catalogue codé en dur et les outils d’agents externes déjà présents sur la machine étaient des boîtes noires pour Orkas. Brancher un projet tiers ou son propre serveur MCP, ou permettre à un agent déjà installé de rappeler les Skills et la base de connaissances d’Orkas : rien de tout cela n’était possible dans cette architecture.
L’idée directrice de cette refonte est simple : reprendre en main les fondations de l’agent. Elle se concrétise en quatre axes liés entre eux : un environnement d’exécution interne développé par nos soins, une couche de modèles indépendante des fournisseurs, une orchestration dynamique par discussion de groupe et le passage d’un catalogue fermé à un hôte ouvert. Examinons-les un par un.
1. Apporter au bureau toutes les capacités d’un agent de développement
Le bureau est le terrain naturel de l’agent : il dispose d’un véritable système de fichiers, d’un véritable shell et d’une véritable chaîne d’outils locale. Un assistant qui ne fait que discuter sous-exploite cet environnement. Pour tirer parti du bureau, il faut un ensemble complet de capacités d’agent de développement : lecture et écriture de fichiers jusqu’à la plage de caractères, recherche entre fichiers, exécution de bash et d’outils système, lancement de plusieurs exécutants en parallèle et résolution de problèmes de longue durée permettant d’enchaîner des dizaines de tours jusqu’à l’achèvement réel d’une tâche complexe.
Le livrable central de cette refonte vise précisément à apporter ces capacités nativement dans le propre processus d’Orkas : un environnement d’exécution d’agents autonome, chargeable dynamiquement et interne au processus, appelé core-agent dans le code. Ce n’est pas une couche de chat supplémentaire ; c’est un moteur d’agents qu’Orkas contrôle lui-même.
La décision architecturale essentielle a été de le diviser en deux couches :
- Couche moteur (paquet autonome) : les mécanismes purs de l’agent — boucle d’appels d’outils, événements en streaming, compactage du contexte, classification des erreurs et nouvelles tentatives, abstraction des fournisseurs, bac à sable, détection des Skills, mémoire, auto-évolution. Elle ne connaît rien de la logique métier d’Orkas : elle ne lit pas ses répertoires de données, ne comprend pas le format des fichiers de conversation et ne touche jamais à l’IPC.
- Couche d’adaptation (dans le processus principal) : elle relie le moteur à Orkas — persistance des sessions, rotation des fournisseurs, autorisations d’outils, registre des Skills, connecteurs, base de connaissances et différents outils de génération. Elle traduit les événements natifs du moteur dans les formats d’événements propres à Orkas, de sorte que la couche métier ne voie qu’une interface stable.
Cette frontière entre moteur et adaptateur est à l’origine de toute la souplesse qui suit. Le moteur peut être testé et évoluer indépendamment ; la couche d’adaptation peut absorber sans risque la complexité propre à Orkas — rotation, temporisation, bac à sable, autorisations — sans contaminer le moteur. La revue d’architecture de l’équipe l’a résumé en une phrase : cette complexité est justifiée, ne fusionnez pas ces couches.
Ce que recouvre réellement cet ensemble de capacités
Maîtriser notre environnement d’exécution ne sert pas à faire étalage de savoir-faire, mais à permettre à l’agent de véritablement « mettre les mains dans le cambouis » sur le bureau. Les capacités se répartissent en quatre grands groupes :
- Opérations fines sur les fichiers et recherche locale.
read_filepermet la lecture par plage de caractères et extrait automatiquement le texte des documents PDF / Office ;edit_fileeffectue un remplacement précis « ancienne chaîne → nouvelle chaîne » et exige une lecture avant toute écriture ;write_fileenregistre le livrable et en conserve la trace ;stat_fileen vérifie la taille ;search_filesrecherche par nom ou motif glob, etgrep_filesrecherche dans le contenu de plusieurs fichiers. Cet ensemble permet à l’agent de « fouiller le code et modifier les fichiers » dans un véritable espace de travail, comme un ingénieur, plutôt que d’absorber et de produire uniquement des blocs entiers. - Bash et outils système. Un exécuteur de shell en bac à sable, avec un mode d’exécution en arrière-plan — les tâches longues se détachent du tour en cours et les journaux sont écrits dans un fichier — et un contrôle des opérations dangereuses gradué selon le risque. Une grande partie de l’efficacité d’un agent de bureau vient précisément de sa capacité à commander directement la chaîne d’outils système.
- Plusieurs exécutants en parallèle. Au sein d’un même tour, les outils indépendants en lecture seule s’exécutent simultanément ; au niveau de la tâche, le commandant peut aussi répartir des sous-tâches indépendantes entre plusieurs exécutants en parallèle (voir la section 3). Paralléliser là où c’est sûr est essentiel pour ramener les tâches de longue durée à un temps réel acceptable.
- Raisonnement et résolution de tâches de longue durée. Une boucle capable d’enchaîner des dizaines de tours, de gérer son propre contexte, de se remettre d’erreurs et de ne jamais rester bloquée à tourner en rond : voilà ce qui sépare « mener à bien une mission complexe » de « répondre à une question ».
Comment l’ingénierie l’a rendu apte à la production
« Écrire sa propre boucle » peut sembler chercher les ennuis, et cela a bien un coût de maintenance. Mais cela apporte un contrôle fin sur tout le cycle de vie de l’agent. Ce contrôle n’a rien d’abstrait : il prend la forme d’améliorations concrètes, chacune déterminant si l’une des capacités précédentes tient réellement en production :
Fenêtre de contexte réelle et compactage à 80% seulement. Le moteur lit la fenêtre de contexte réelle de chaque modèle, y compris ceux dont la fenêtre atteint un million de tokens, et ne déclenche le compactage qu’à 80% d’utilisation, au lieu de commencer prudemment à 60% et de jeter 40% du contexte utile. Un garde-fou évite aussi le « compactage sans gain » : si la fin d’historique conservée remplit déjà la fenêtre — par exemple un résultat de lecture de fichier très volumineux —, le compactage ne peut rien libérer. Il journalise alors un avertissement et passe son tour, sans gaspiller un appel de résumé. La capacité d’une tâche longue à « se souvenir de ce qui précède » dépend entièrement de ce mécanisme.
Outils adjacents en lecture seule exécutés en parallèle. Lorsque le modèle lance dans un même tour une lecture de fichier, une recherche de fichiers et une recherche web — plusieurs outils indépendants en lecture seule —, le moteur regroupe les outils adjacents parallélisables pour les exécuter simultanément ; les outils d’écriture forment des barrières naturelles et conservent l’ordre déclaré. Les appels d’outils et leurs résultats sont enregistrés strictement dans cet ordre, de sorte que la concurrence ne rompe jamais le protocole. Les outils en lecture seule les plus courants passent ainsi du séquentiel au parallèle, avec une baisse sensible du temps réel de tout le lot.
Lecture avant écriture et contrôle optimiste de concurrence. Avant de modifier un fichier, vous devez le lire ; le moteur enregistre un état de référence à la lecture et vérifie qu’il n’a pas changé au moment de la modification. Si des exécutants parallèles modifient simultanément le même fichier, le perdant reçoit une erreur explicite d’état « périmé » au lieu d’écraser silencieusement les changements de l’autre. Avec plusieurs exécutants travaillant en parallèle dans le même espace, cette protection est indispensable.
Interruption en cours d’exécution intégrée immédiatement. Lorsque l’utilisateur ajoute un message pendant que l’agent travaille, le moteur intègre ce message en attente dans l’entrée du tour en cours, à la frontière de la boucle d’outils, au lieu d’attendre pour lancer un tour distinct. « Corriger la trajectoire pendant l’exécution » devient ainsi une interaction naturelle.
Détection des boucles. Si le même appel d’outil se répète à la suite, le moteur émet d’abord un rappel au 3e, puis impose l’arrêt au 5e ; toute signature différente remet le compteur à zéro. Les variations légitimes, comme la pagination ou l’interrogation périodique, ne déclenchent donc pas de faux positifs. Un modèle bloqué ne consomme plus silencieusement des tokens.
Suppression du plafond strict de sortie du tour principal. La sortie du tour principal n’est plus limitée à un petit plafond : les longs rapports et les modifications volumineuses ne sont donc plus tronqués silencieusement. Les appels auxiliaires — compactage, réflexion — conservent prudemment un plafond réduit.
Un détail très « local » mérite d’être mentionné : l’estimation des tokens pour les textes mêlant chinois et anglais. Une estimation générique sous-évalue de deux à trois fois une conversation entièrement en chinois ; le moteur distingue les caractères chinois et anglais selon leur classe, ce qui rend fiable le seuil de compactage. C’est le genre de détail auquel un SDK générique ne pensera pas pour vous.
Ensemble, ces améliorations répondent à la question « pourquoi ne pas simplement utiliser un SDK existant ? » : parce que les capacités les plus fortes d’un agent de bureau se trouvent précisément dans la couche qu’un SDK n’expose pas ; pour les rendre aptes à la production, il faut maîtriser la boucle.
2. Garder le modèle disponible : l’enveloppe de fournisseurs à plusieurs couches
L’objectif de la couche de modèles tient en une phrase : quel que soit le problème touchant une clé, un fournisseur ou un réseau, ce tour de conversation doit survivre autant que possible. Pour cela, la couche d’adaptation superpose plusieurs enveloppes à l’abstraction des fournisseurs du moteur : rotation, temporisation, enregistrement et adaptation externe.
Le choix le plus crucial est que le mécanisme de rotation se situe sous l’exécuteur. Le moteur écrit le message utilisateur dans la session persistante avant tout appel à un fournisseur. Gérer les nouvelles tentatives ou la rotation au niveau du moteur conduirait donc à soumettre de nouveau ce message, ou imposerait un mécanisme complet de retour arrière de session. En plaçant la rotation sous le moteur, le message utilisateur n’est écrit qu’une seule fois et « réessayer avec un autre candidat » reste totalement transparent pour l’état de la session.
Le mécanisme de rotation reste également mesuré dans ses décisions, avec pour frontière le premier événement de contenu :
- Un échec avant que le modèle n’émette un contenu substantiel — texte ou appel d’outil — permet de passer sans risque au candidat suivant ;
- Dès que le premier événement de contenu est émis, la rotation s’arrête et l’erreur remonte, car le modèle a peut-être déjà exécuté un tour complet ; recommencer répéterait ses effets de bord.
La classification des erreurs détermine s’il faut « changer de candidat, ne pas changer ou réessayer ». Les échecs liés au compte — authentification, solde insuffisant, limitation de débit, abonnement expiré — déclenchent une temporisation et une rotation ; les erreurs réseau transitoires, comme une connexion réinitialisée, n’entraînent pas de temporisation et font l’objet de quelques nouvelles tentatives sans état au même endroit. En revanche, les requêtes mal formées, les refus liés aux règles de contenu et les erreurs serveur 5xx, qui échoueraient de la même manière avec une autre clé, sont transmis directement sans rotation. La temporisation est un signal de dix minutes, interne au processus et non persistant : c’est une indication à court terme qui ne mérite pas une écriture disque à chaque échec, et le redémarrage du processus est précisément le bon moment pour retester.
Du côté du « répertoire » des fournisseurs, la refonte ramène trois types de sources à une abstraction unifiée :
- LLM géré par Orkas : un proxy côté serveur, prêt à l’emploi après connexion, avec routage serveur entre modèles de texte et d’image ;
- Votre propre clé : les grands fournisseurs de modèles classiques ;
- Adaptateurs externes à connexion directe : un ensemble de modèles qui exigent une connexion directe ou leur propre facturation, adaptés manuellement à la même interface de fournisseur.
Pour les couches supérieures, tout cela se résume à une paire stable (provider, model) : rotation, temporisation et adaptation externe restent cachées dans la couche d’adaptation.
3. La discussion de groupe comme orchestration : du plan-DAG statique au commandant dans la boucle
C’est la partie de la refonte qui demande le plus de changer de perspective.
L’ancien modèle reposait sur la planification statique : le modèle générait d’abord un plan/DAG, puis l’exécuteur suivait le graphe. Le nouveau modèle supprime entièrement ce graphe et le remplace par une orchestration dynamique par discussion de groupe, avec le commandant dans la boucle.
Sa métaphore est celle d’un salon de discussion de groupe :
- Le Commander est l’hôte du salon, pas un intergiciel invisible ;
- Les agents exécutants sont des membres à part entière et de même rang dans le salon ;
- Toutes les interactions sont des messages asynchrones, mis en file via un bus de messages unique ; il n’existe aucun chemin privé de répartition parallèle.
L’« attribution » du commandant n’est pas un @somebody écrit dans une phrase : un LLM qui écrit @AgentA dans le corps du texte ne produit que du Markdown issu de ses données d’entraînement, auquel on ne peut pas se fier. Le véritable signal d’attribution est un appel d’outil structuré. Après la refonte, il se décline en trois actions au sens clair :
dispatch_to— envoyer un agent exécuter une tâche jusqu’au bout et en retourner le résultat, que le commandant synthétise. Plusieurs tâches indépendantes peuvent être réparties simultanément.run_worker— une sous-tâche dont le commandant garde lui-même la responsabilité, avec un résultat renvoyé de façon synchrone ; un exécutant anonyme est la « main » du commandant, invisible à l’utilisateur, tandis qu’un exécutant nommé est un spécialiste visible.hand_off_to— passer la conversation à l’agent ; le commandant se retire et l’agent répond directement à l’utilisateur, sans synthèse supplémentaire pour ce tour.
Pourquoi une discussion de groupe plutôt qu’un orchestrateur ou un arbre de sous-agents
Donner au multi-agents la forme d’une discussion de groupe apporte plusieurs avantages inaccessibles à un orchestrateur classique ou à un arbre de sous-agents :
- Vues par visibilité. Chaque message n’est ajouté qu’à la vue de « ceux qui peuvent le voir ». Au démarrage, un agent exécutant ne rejoue que sa propre vue : les sorties volumineuses d’un autre agent ne polluent donc pas son contexte. Le commandant voit tout.
- État minimal. L’état central de toute l’orchestration se limite à « qui a actuellement la parole » et à un registre de tâches léger. Aucun DAG, aucune machine à états complexe.
- Rejeu et synchronisation naturels. Les messages se trient naturellement par horodatage ; le rechargement et la synchronisation entre appareils s’appuient donc directement sur le flux de messages. La télécommande mobile repose précisément sur ce flux : tous les calculs des agents s’exécutent sur le bureau, et le mobile n’est qu’un affichage miroir, sans protocole d’orchestration particulier.
La revue d’architecture de l’équipe a été tout aussi directe sur ce point : un bus de discussion de groupe associé à un commandant dans la boucle constitue l’architecture multi-agents d’Orkas. Ajouter dans le processus un autre chemin parallèle d’attribution aux sous-agents violerait au contraire l’invariant « un seul chemin d’attribution par discussion de groupe ».
La nouveauté de cette version : le passage de relais interactif
Le dernier ajout à cette série est le passage de relais interactif entre agents.
Le problème est concret : un agent de type « tuteur » enseigne quelque chose pendant un tour, l’utilisateur veut poursuivre avec d’autres questions, mais le système redonne de force la parole au commandant. L’utilisateur doit alors rappeler l’agent avec @ à chaque message.
La solution combine une attribution de la parole faisant autorité côté serveur et un destinataire décidé par le modèle :
- Le détenteur de la parole devient un champ d’état persistant, conservé après rechargement, et utilise l’événement existant de changement d’état pour se synchroniser automatiquement sur tous les clients, sans nouveau type d’événement.
- Après que le commandant a utilisé
hand_off_topour donner la parole à un agent interactif, les messages suivants de l’utilisateur sans@vont directement à cet agent, jusqu’à ce qu’il rende la main de lui-même ou que l’utilisateur s’adresse de nouveau au commandant. - L’agent rend le contrôle avec un marqueur
<handback />; l’analyse vérifie strictement qu’il s’agit d’une correspondance réelle, afin qu’un<handbackisolé dans une phrase ne soit pas interprété à tort comme un passage de relais. - Si le registre contient encore une tâche inachevée au moment du retour, le commandant la reprend et poursuit le travail.
Une amélioration de l’expérience accompagne ce changement : les bulles de boucle du commandant. Sa boucle « attribuer → lire le résultat → attribuer de nouveau » au sein d’un tour était auparavant aplatie en une seule bulle, qui pouvait même se retrouver déplacée en bas après rechargement. La refonte découpe un tour en plusieurs segments à chaque frontière d’attribution visible, chacun étant un message autonome à horodatage croissant. Pour la première fois, l’utilisateur voit le commandant « parcourir sa boucle d’orchestration », et l’ordre reste correct après rechargement.
Enfin, deux filets de sécurité s’appliquent partout : l’arrêt de groupe est le seul chemin d’arrêt de tous les acteurs — dès que l’utilisateur appuie sur Arrêter, le signal d’annulation de chaque exécutant est déclenché, y compris celui des sous-exécutants anonymes grâce à une correspondance de secours — et le mécanisme interrupt-steer déjà évoqué, qui intègre l’intervention de l’utilisateur au tour en cours.
4. D’un catalogue fermé à un hôte ouvert
Si les trois premiers axes visaient à consolider les fondations, celui-ci ouvre toutes les portes et fenêtres : transformer Orkas d’un catalogue fermé en un hôte ouvert, sans céder un pouce sur la frontière de sécurité.
La refonte a systématiquement supprimé plusieurs goulets d’étranglement « fermés » :
Paquets externes. L’utilisateur fournit l’adresse d’un dépôt, et Orkas l’héberge localement, cloné à l’identique dans un dossier : jamais normalisé, jamais réécrit, jamais synchronisé dans le cloud, car il contient des répertoires de dépendances tierces. Un outil en ligne de commande autonome gère le cycle installation, mise à jour, démarrage et arrêt, détecte s’il s’agit d’un « Skill » avec fichier de description ou d’une « CLI » avec point d’entrée exécutable, et écrit les métadonnées dans un registre extérieur au répertoire du paquet, pour éviter les conflits lors des mises à jour par pull. L’installation des dépendances suit une confirmation en deux étapes « demander une fois, mémoriser ». Des scripts relais sont générés pour les points d’entrée exécutables et ajoutés au PATH de l’outil bash, afin que le modèle puisse appeler directement ces CLI tierces.
Chargement de Skills depuis plusieurs racines. Le point d’entrée unique d’exécution des Skills est passé de deux racines reconnues à quatre niveaux — personnalisé / marketplace / paquet externe / global — résolus par priorité. Les scripts d’un paquet externe privilégient l’environnement de dépendances fourni par le paquet lui-même. C’est le point de passage au risque de régression le plus élevé ; une matrice complète de jeux de test le couvre.
Interopérabilité avec les Skills globaux. Orkas lit directement les répertoires globaux de Skills déjà gérés par d’autres outils d’agents sur la machine, permettant une interopérabilité à ce niveau : un Skill accumulé ailleurs est également utilisable dans Orkas. Le fait que l’utilisateur place un Skill dans ces répertoires constitue l’autorisation : l’accès est donc activé par défaut, avec un interrupteur général disponible. Ces descriptions de Skills tiers sont une surface non fiable d’injection de prompt. Elles passent donc par le chargeur « open-tier », ne sont visibles que du commandant et ne peuvent structurellement pas entrer dans la liste des Skills autorisés d’un agent.
MCP configuré par l’utilisateur. Les connecteurs ne forment plus un catalogue codé en dur. L’utilisateur peut ajouter tout serveur MCP : distant via HTTP, à faible risque, ou local sous forme de sous-processus, à risque élevé. Le formulaire est lui-même l’interface de consentement : la commande saisie manuellement y apparaît à l’identique. Toute la configuration du transport, secrets compris, est stockée chiffrée. Les instances personnalisées portent toujours un préfixe fixe afin de ne jamais pouvoir se faire passer pour un connecteur officiel du catalogue.
Passerelle inverse : permettre aux agents externes de la machine d’accéder à leur tour à Orkas. C’est l’élément le plus intéressant. Les outils d’agents externes déjà installés étaient auparavant des boîtes noires pour Orkas ; désormais, lorsqu’Orkas leur attribue du travail, il injecte un canal qui leur permet en sens inverse de lister, lire et exécuter les Skills d’Orkas, d’appeler les connecteurs et de rechercher dans la base de connaissances. Cette passerelle utilise un canal interprocessus local, sans ouvrir de port réseau, authentifié par un identifiant à usage unique propre à chaque exécution et détruit à sa fin. Chaque appel de connecteur ayant un effet externe passe par une boîte de confirmation utilisateur : il ne s’agit pas d’un jugement heuristique lecture/écriture fondé sur le nom de l’outil, qui serait trop permissif, mais d’une confirmation par paire (agent, connecteur), avec une option « toujours autoriser ».
Approche de développement pour les cas rares. L’arbre de décision du commandant gagne une branche : en l’absence d’agent, de Skill ou de connecteur adapté, évaluer une résolution directe avec bash et un court script, l’effectuer dans le tour, vérifier la sortie et proposer éventuellement d’en faire un Skill personnalisé. Cela s’accompagne de l’exécution bash en arrière-plan — les tâches longues se détachent du tour et leurs journaux vont dans un fichier — et de répertoires autorisés par l’utilisateur.
Ouvert, mais toujours encadré
Quand on ouvre portes et fenêtres, on redoute les courants d’air. La discipline de cette refonte est la suivante : aucun des points de passage obligés pour lancer des « actions dangereuses » n’est modifié. MCP démarre depuis un seul endroit, l’exécution des Skills passe par un seul exécuteur et bash par un seul exécuteur en bac à sable. Plusieurs couches de protection supplémentaires s’y ajoutent :
- Les opérations sur les fichiers passent toujours par le bac à sable des chemins — espace de travail, pièces jointes actuelles et répertoires explicitement autorisés par l’utilisateur —, tandis que les répertoires d’identifiants, les répertoires système et ceux d’Orkas ne peuvent pas être autorisés ;
- Les commandes bash dangereuses — exfiltration, suppression destructrice, élévation de privilèges, chemins sensibles — déclenchent une confirmation d’autorisation, avec les choix « cette fois seulement / pour cette exécution / refuser ». Les journaux n’enregistrent que la catégorie et la longueur, jamais le texte de la commande ;
- L’installation de paquets externes se ferme par sécurité et refuse catégoriquement les paquets contenant des liens symboliques, afin d’éviter qu’ils servent à inclure des fichiers sensibles hors du bac à sable ; la source du clone est limitée à une liste de protocoles autorisés ;
- Tous les transports et secrets contenant des identifiants sont chiffrés au repos, et les identifiants de passerelle sont isolés par exécution ;
- La distribution open source / hébergée retire les capacités exclusives à l’hôte selon une règle d’élagage.
En une phrase : chaque action explicite de l’utilisateur — installer, autoriser, envoyer un formulaire, cliquer pour confirmer — constitue la preuve du consentement, et chaque consentement reste confiné à son périmètre légitime.
5. Progresser entre les sessions : mémoire et auto-évolution
La refonte des fondations a également remanié deux sous-systèmes qui « rendent l’agent plus intelligent à mesure qu’on l’utilise », avec la même discipline d’ingénierie : désactivés par défaut, délimités, observables.
La mémoire intersessions utilise une recherche hybride : recherche sémantique vectorielle et recherche par mots-clés (BM25), fusionnées par RRF (fusion des rangs réciproques) pour éviter les défaillances d’un canal isolé. Elle est stockée localement avec un index de texte intégral. Elle comporte deux types de données — les notes de l’agent et le profil de préférences utilisateur —, chacun plafonné en caractères, analysé pour détecter les menaces d’injection avant écriture et injecté sous forme figée dans le prompt système au début de chaque tour. L’ensemble sert uniquement à mieux comprendre l’utilisateur actuel ; les données restent toujours locales, et l’utilisateur peut les consulter, les modifier et les exporter à tout moment dans les paramètres.
L’auto-évolution associe une bibliothèque de Skills privée à l’agent, stockée séparément de la bibliothèque partagée de la plateforme, à une couche de réflexion métacognitive. Le moteur décide de réfléchir à partir de signaux pondérés : correction de l’utilisateur, au poids le plus élevé, récupération après une erreur non triviale, complexité de la tâche, faiblesse connue déclenchée ou surmontée, inefficacité d’un Skill… La réflexion ne se déclenche que si les signaux pondérés dépassent un seuil. Elle constitue elle-même une tâche périodique en arrière-plan — environ un cycle toutes les 12 heures, un délai de plusieurs heures entre cycles et un déclenchement de secours après plusieurs jours — qui utilise un petit modèle peu coûteux pour lire un résumé de l’activité récente et décider de créer ou de corriger un Skill et de mettre à jour le « profil de compétences » de l’agent.
Le point de sécurité le plus important : l’auto-évolution n’est activée que pour les sessions explicitement rattachées à un agent ; la session du commandant par défaut n’évolue pas. La réflexion est soumise à un double plafond de tokens, par nombre et au total, l’échec d’un agent ne bloque pas les autres et le coût par exécution est extrêmement réduit. Rendre l’agent plus intelligent, sans le laisser s’emballer.
Philosophie d’ingénierie : une complexité justifiée ne se supprime pas au nom de la simplicité
L’équipe a mené plusieurs cycles de revue d’architecture pendant la refonte. Une conclusion est revenue sans cesse et mérite d’être isolée : distinguer « l’hypertrophie organisationnelle » de la « complexité justifiée », et ne toucher qu’à la première.
- Les multiples stratégies de fusion du moteur de synchronisation, la boucle d’agent développée en interne, l’enveloppe de fournisseurs à plusieurs couches, la frontière de la télécommande mobile : tout cela paraît complexe, mais chaque couche a sa raison d’être — cohérence éventuelle entre appareils, intégration poussée, rotation entre plusieurs clés, frontière de client décidée par le produit. Les « simplifier » de force ne ferait que perdre des données et brouiller les couches.
- Ce qu’il faut réellement corriger, ce sont les modules omnipotents et les duplications locales : extraire les fonctions pures sans état du bus de discussion de groupe devenu trop volumineux — assemblage des prompts, outils du commandant, tour CLI — et regrouper les multiples copies du modèle de « boîte de confirmation » en un composant partagé.
Ce jugement repose sur des règles strictes inscrites dans le document de contraintes du projet : frontières — processus unique, IPC comme seul chemin, chargement exclusivement dynamique de l’environnement d’exécution —, couches et sens de leurs dépendances, source de vérité unique pour les catégories, la taxonomie de télémétrie et les domaines, ainsi qu’un « audit des prompts » obligatoire pour chaque commit touchant aux prompts. Ce qui permet de refondre les fondations sans effondrement n’est pas une conception ingénieuse : c’est le maintien continu de ces invariants.
Conclusion
Réunis, ces quatre axes dotent Orkas d’un socle d’agents maîtrisé en interne, indépendant des fournisseurs, orchestré dynamiquement, ouvert sur l’extérieur et capable d’auto-évolution :
- Un environnement d’exécution interne au processus, à deux couches moteur/adaptateur, qui apporte nativement au bureau toutes les forces d’un agent de développement — opérations sur les fichiers, recherche locale, outils système, exécutants parallèles, résolution de longue durée — et rend chacune apte à la production ;
- Une couche de modèles à plusieurs niveaux qui maintient autant que possible la conversation malgré les problèmes de clés, de fournisseurs ou de réseau ;
- Une orchestration multi-agents par discussion de groupe avec le commandant dans la boucle, qui remplace la « planification statique » par la « décision dynamique » et rend pour la première fois naturels les passages de relais entre agents ;
- Un écosystème passant d’un catalogue fermé à un hôte ouvert, avec accès aux paquets externes, aux Skills globaux, au MCP personnalisé et à la passerelle inverse, tandis que les points de passage obligés de lancement restent inchangés ;
- Et une mémoire et une auto-évolution désactivées par défaut, délimitées et observables.
Les fonctionnalités peuvent s’ajouter une à une, mais des fondations ne méritent une refonte sérieuse qu’une fois. Une fois celle-ci achevée, tout ce qui se construit dessus avance plus vite : c’était précisément le résultat recherché.