engineering architecture

Architecture orientée traits : comment ZeroClaw rend les agents IA extensibles sans plugins

ZeroClaws.io

ZeroClaws.io

@zeroclaws

February 25, 2026

8 min de lecture

Architecture orientée traits : comment ZeroClaw rend les agents IA extensibles sans plugins

Quand ClawHub a lancé, ça semblait être la façon évidente d’étendre un runtime d’agent IA. Un marché de skills — installez ce dont vous avez besoin, ignorez le reste, contribuez les vôtres. Le modèle fonctionnait pour les extensions de navigateur, les plugins VS Code, les packages npm. Pourquoi pas pour les agents IA ?

Début 2026, la réponse était claire. Des chercheurs en sécurité ont trouvé que 41,7 % des skills ClawHub publiés contenaient des vulnérabilités. Des centaines étaient franchement malveillants — des packages uploadés spécifiquement pour compromettre les utilisateurs qui les installaient. Le modèle plugin, il s’avère, a un problème fondamental quand il est appliqué à des logiciels qui tournent avec des permissions élevées sur votre machine.

ZeroClaw a été conçu avec ce mode d’échec en tête. Au lieu d’un système de plugins, il utilise des traits Rust.

Ce qui ne va pas avec les systèmes de plugins à l’exécution

Le problème fondamental des systèmes de plugins traditionnels n’est pas la qualité de l’implémentation — c’est le modèle lui-même. Quand vous installez un plugin, vous téléchargez du code depuis internet et l’exécutez dans le processus de votre application, avec les permissions de votre application. Le plugin peut lire vos fichiers, accéder à votre réseau, lire vos variables d’environnement, et faire tout ce que votre application peut faire.

C’est bien pour un plugin d’éditeur de texte qui ajoute de la coloration syntaxique. Ce n’est pas bien pour un runtime d’agent IA qui a accès à vos identifiants, votre système de fichiers, et vos canaux de chat.

Les modes d’échec spécifiques sont prévisibles. Le chargement de code à l’exécution signifie que les plugins exécutent du code arbitraire dans le processus hôte — pas de sandbox, pas d’isolation, pas de modèle de capacité. La confiance par défaut signifie qu’une fois un plugin installé, il a les mêmes permissions que l’application hôte. Les attaques sur la chaîne d’approvisionnement sont triviales : publiez un package avec un nom similaire à un populaire, attendez que des utilisateurs l’installent. Les conflits de versions entre plugins créent un enfer de dépendances difficile à déboguer et impossible à prévenir au niveau de la plateforme.

Le ClawHub d’OpenClaw a démontré chacun de ces modes d’échec en 2026. Les skills malveillants n’étaient pas sophistiqués — c’étaient juste des packages qui se trouvaient être installés par des utilisateurs qui faisaient confiance au marché.

Les traits : un modèle différent

Un trait Rust est un contrat d’interface appliqué par le compilateur. Il définit quelles méthodes une implémentation doit fournir, quels types ces méthodes acceptent et retournent, et quelles garanties de sécurité des threads elles doivent respecter. Voici le trait de canal de ZeroClaw, simplifié :

```rust pub trait Channel: Send + Sync + 'static { fn name(&self) -> &str; async fn connect(&mut self) -> Result<()>; async fn receive(&self) -> Result; async fn send(&self, msg: Response) -> Result<()>; async fn disconnect(&self) -> Result<()>; } ```

Chaque canal — Telegram, Discord, WhatsApp, Signal, Matrix, IRC — implémente ce trait. Le compilateur garantit la sécurité des types (vous ne pouvez pas envoyer une réponse Discord à un canal Telegram), la sécurité des threads (les bornes ```end + Sync` garantissent un accès concurrent sûr), et la complétude (chaque méthode requise doit être implémentée — pas d’erreurs “méthode introuvable” à l’exécution).

Crucial : les nouveaux canaux sont compilés dans le binaire, pas chargés à l’exécution. Pas d’injection de code, pas de chargement dynamique, pas de décision de confiance à prendre au moment de l’installation. L’extension est vérifiée par le compilateur avant de jamais s’exécuter.

Ajouter un nouveau canal

L’expérience pratique d’étendre ZeroClaw consiste à implémenter le trait. Voici à quoi ressemble un adaptateur de canal Matrix :

```rust pub struct MatrixChannel { homeserver: String, client: MatrixClient, }

impl Channel for MatrixChannel { fn name(&self) -> &str { “matrix” }

async fn connect(&mut self) -> Result<()> { self.client = MatrixClient::new(&self.homeserver).await?; self.client.login().await?; Ok(()) }

async fn receive(&self) -> Result { let event = self.client.next_message().await?; Ok(Message::from(event)) }

async fn send(&self, msg: Response) -> Result<()> { self.client.send_text(&msg.channel_id, &msg.text).await?; Ok(()) }

async fn disconnect(&self) -> Result<()> { self.client.logout().await } } ```

C’est environ 50 lignes pour un adaptateur de canal complet. Le compilateur vérifie que l’implémentation est correcte avant que le code soit livré. Si vous oubliez d’implémenter une méthode, ou retournez le mauvais type, ou violez une contrainte de sécurité des threads, vous obtenez une erreur de compilation — pas un crash en production.

Le même schéma pour chaque point d’extension

ZeroClaw utilise des traits pour chaque endroit où le système doit être extensible. Les fournisseurs IA implémentent un trait `Provider` :

```rust pub trait Provider: Send + Sync { async fn complete(&self, messages: &[ChatMessage]) -> Result; async fn embed(&self, text: &str) -> Result>; fn model_name(&self) -> &str; } ```

Passer d’OpenAI à Anthropic à Ollama, c’est implémenter le même trait avec des appels HTTP différents. Le reste de ZeroClaw ne sait pas et ne se soucie pas quel fournisseur est actif — il appelle juste les méthodes du trait.

Les outils implémentent un trait `Tool` qui exige de déclarer les permissions à l’avance :

```rust pub trait Tool: Send + Sync { fn name(&self) -> &str; fn description(&self) -> &str; async fn execute(&self, args: Value) -> Result; fn permissions(&self) -> Permissions; } ```

Chaque outil déclare ce dont il a besoin — accès aux fichiers, accès réseau, chemins spécifiques — avant de s’exécuter. Le runtime applique des listes d’autorisation basées sur ces déclarations. Un outil qui prétend avoir besoin d’un accès en lecture à `~/documents` ne peut pas accéder silencieusement à `~/.ssh`.

Les backends de mémoire implémentent un trait `MemoryBackend`, c’est pourquoi SQLite est la valeur par défaut mais des backends alternatifs sont possibles sans changer aucun autre code.

La comparaison sécurité

| Aspect | Système de plugins | Système de traits | |--------|--------------|-------------| | Origine du code | Téléchargé à l’exécution | Compilé au build | | Vérification | Basée sur la confiance | Vérifiée par le compilateur | | Permissions | Exécution, souvent non vérifiées | Déclarées dans les types, appliquées | | Chaîne d’approvisionnement | Vulnérable | Pas de chargement de code externe | | Sécurité des types | Erreurs à l’exécution | Erreurs à la compilation | | Concurrence | Conditions de course possibles | Courses de données impossibles |

L’insight clé est simple : vous ne pouvez pas avoir d’attaque sur la chaîne d’approvisionnement si vous n’avez pas de chaîne d’approvisionnement. Les extensions de ZeroClaw sont compilées dedans, pas téléchargées. Pas de marché à compromettre, pas de packages à typosquatter, pas de décision de confiance à prendre au moment de l’installation.

Le vrai compromis

L’approche par traits signifie que vous ne pouvez pas installer un nouveau canal en téléchargeant un fichier. Ajouter une extension personnalisée nécessite d’écrire du Rust, de l’ajouter au code source de ZeroClaw, et de compiler un nouveau binaire. Pour la plupart des utilisateurs, les 30+ canaux et outils intégrés couvrent tout ce dont ils ont besoin. Pour les développeurs qui ont besoin d’extensions personnalisées, le système de traits fournit un contrat clair et type-safe à implémenter.

Ce compromis est intentionnel. Une surface d’extension plus petite et vérifiée vaut mieux qu’une grande et non vérifiée. Le ClawHub d’OpenClaw a prouvé ce qui se passe quand on optimise pour la taille de l’écosystème plutôt que pour la sécurité. ZeroClaw optimise pour l’inverse, et le nombre de CVE reflète ce choix.

Restez informé

Recevez les mises à jour sur les nouvelles releases, intégrations et l'infrastructure d'agents en Rust. Pas de spam, désinscription à tout moment.