📑 Table des matières

19 - Extensions et Plugins Hermes Agent : Étendre Votre Agent IA

Hermes Agent 🟡 Intermédiaire ⏱️ 10 min de lecture 📅 2026-05-05

Extensions et Plugins Hermes Agent : Étendre Votre Agent IA

Le système de plugins d'Hermes Agent est l'une de ses fonctionnalités les plus puissantes. Plutôt qu'un agent monolithique figé dans ses capacités, Hermes se veut modulaire par conception : chaque fonctionnalité avancée peut être ajoutée, retirée ou remplacée via des plugins indépendants. Que vous souhaitiez intégrer Spotify, ajouter un adapter de plateforme messaging, activer l'observabilité via Langfuse, ou créer vos propres outils — le système de plugins vous le permet sans toucher au code source d'Hermes.

Cet article détaille l'architecture du système de plugins, les quatre sources de découverte, les différents types de plugins, les hooks de cycle de vie, et comment créer et installer vos propres extensions.

Architecture du système de plugins

Le plugin manager (PluginManager) est un singleton global qui gère la découverte, le chargement et l'invocation de tous les plugins. Il est défini dans hermes_cli/plugins.py et exposé via des fonctions module-level comme discover_plugins() et invoke_hook().

Chaque plugin est découvert dans l'un des quatre emplacements suivants :

1. Plugins bundled (intégrés)

Les plugins livrés avec le dépôt Hermes résident dans <repo>/plugins/<nom>/. Ils sont disponibles immédiatement après installation. On y trouve :

  • disk-cleanup : nettoyage automatique des fichiers temporaires (scripts de test, sorties, logs cron) via hooks post_tool_call et on_session_end
  • spotify : intégration native avec 7 outils de contrôle de lecture via l'API Spotify Web + OAuth PKCE
  • image_gen/openai, image_gen/xai, image_gen/openai-codex : backends de génération d'images (GPT Image, Grok)
  • platforms/irc, platforms/teams : adapters gateway pour IRC et Microsoft Teams
  • google_meet : jointure de calls Google Meet, transcription live, parole temps réel
  • langfuse : observabilité des conversations, appels LLM et usage des outils

2. Plugins utilisateur

Chaque utilisateur peut installer des plugins supplémentaires dans ~/.hermes/plugins/<nom>/. C'est l'emplacement par défaut pour les plugins tiers installés via hermes plugins install.

3. Plugins projet

Les plugins spécifiques à un projet peuvent être placés dans ./.hermes/plugins/<nom>/. Ce mode est opt-in via la variable d'environnement HERMES_ENABLE_PROJECT_PLUGINS. Pratique pour un plugin de build ou d'intégration propre à un dépôt.

4. Plugins pip (entry points)

Les packages Python installés via pip peuvent déclarer un entry point dans le groupe hermes_agent.plugins. Hermes les détecte automatiquement via importlib.metadata.entry_points(). C'est le format idéal pour distribuer un plugin Hermes sur PyPI.

Priorité de chargement et collisions

L'ordre de découverte est immuable : bundled → utilisateur → projet → pip. En cas de collision (même clé de plugin), les sources ultérieures écrasent les précédentes. Un plugin utilisateur nommé disk-cleanup remplacera le plugin bundled du même nom. C'est un mécanisme explicite et volontaire — pas un bug.

La clé d'un plugin est dérivée de son chemin : un plugin à plugins/image_gen/openai/ a pour clé image_gen/openai, tandis qu'un plugin à plugins/disk-cleanup/ a pour clé disk-cleanup. Cela permet à tts/openai et image_gen/openai de coexister sans collision.

Le fichier manifest : plugin.yaml

Chaque plugin basé sur un répertoire doit contenir un fichier plugin.yaml (ou plugin.yml) et un __init__.py avec une fonction register(ctx). Le manifest décrit les métadonnées du plugin :

name: spotify
version: 1.0.0
description: "Native Spotify integration  7 tools using Spotify Web API + PKCE OAuth."
author: NousResearch
kind: backend
provides_tools:
  - spotify_playback
  - spotify_devices
  - spotify_queue
  - spotify_search
  - spotify_playlists
  - spotify_albums
  - spotify_library
requires_env:
  - SPOTIFY_CLIENT_ID
  - SPOTIFY_CLIENT_SECRET

Les champs possibles du manifest :

  • name : nom du plugin (défaut = nom du répertoire)
  • version : version sémantique
  • description : description du plugin
  • author : auteur
  • kind : type de plugin (voir section suivante)
  • provides_tools : liste des outils exposés
  • provides_hooks : liste des hooks utilisés
  • requires_env : variables d'environnement nécessaires
  • platforms : plateformes supportées (linux, macos, etc.)

Les quatre types de plugins

Le champ kind dans le manifest définit le comportement de chargement et la portée du plugin.

standalone (défaut)

Le plugin classique : il enregistre ses propres hooks et outils. Son activation est opt-in via plugins.enabled dans config.yaml. C'est le type le plus courant pour les extensions utilisateur.

backend

Un plugin backend fournit une implémentation alternative pour un outil existant. Les backends bundled s'activent automatiquement — ils doivent « juste fonctionner » sans configuration supplémentaire. La sélection du backend actif se fait via la clé de config correspondante (ex: image_gen.provider: openai).

Les backends utilisateur installés dans ~/.hermes/plugins/ restent opt-in via plugins.enabled.

exclusive

Réservé aux fournisseurs de mémoire (memory providers). Un seul provider actif par catégorie. La sélection se fait via <category>.provider dans config.yaml. Le système de découverte memory gère son propre cycle de vie — le PluginManager général ne les charge pas lui-même.

Hermes embarque 8 providers mémoire bundled : Honcho, Mem0, Supermemory, Holographic, Hindsight, Byterover, OpenViking et RetainDB.

platform

Les adapters de plateforme messaging pour le gateway. Les platforms bundled s'activent automatiquement (IRC, Teams) pour être disponibles immédiatement. Les platforms installées manuellement dans ~/.hermes/plugins/ restent opt-in.

Le plugin s'enregistre via ctx.register_platform() qui accepte une factory d'adapter, une fonction de vérification des dépendances, et des métadonnées.

Le PluginContext : l'API d'enregistrement

Quand un plugin est chargé, le manager appelle sa fonction register(ctx) en lui passant une instance de PluginContext. Ce contexte est la façade par laquelle le plugin interagit avec le framework :

  • ctx.register_tool() : enregistre un outil dans le registre global, aux côtés des outils natifs. Accepte un nom, un toolset, un schéma JSON, un handler, et des options (async, check_fn, requires_env, description, emoji)
  • ctx.register_hook() : enregistre un callback pour un hook de cycle de vie
  • ctx.register_command() : enregistre une commande slash (ex: /lcm) utilisable en CLI et gateway. Les conflits avec les commandes natives sont rejetés automatiquement
  • ctx.register_cli_command() : enregistre une sous-commande CLI (ex: hermes honcho ...)
  • ctx.register_platform() : enregistre un adapter de plateforme gateway
  • ctx.register_skill() : enregistre un skill en lecture seule accessible via skill_view('plugin:nom')
  • ctx.register_context_engine() : enregistre un moteur de contexte alternatif (un seul autorisé)
  • ctx.register_image_gen_provider() : enregistre un backend de génération d'images
  • ctx.dispatch_tool() : appelle un outil du registre avec le contexte de l'agent parent
  • ctx.inject_message() : injecte un message dans la conversation active

Les hooks de cycle de vie

Les hooks sont des points d'insertion dans le cycle de vie de l'agent. Un plugin peut enregistrer des callbacks pour intercepter ou observer les événements suivants :

Hooks de communication LLM

  • pre_llm_call : avant chaque appel au modèle. Peut retourner du contexte injecté dans le message utilisateur (préserve le cache de prompt système)
  • post_llm_call : après chaque réponse du modèle. Utile pour les métriques de latence, le logging, la compression

Hooks d'outils

  • pre_tool_call : avant l'exécution d'un outil. Un plugin peut retourner {"action": "block", "message": "..."} pour bloquer l'appel. Idéal pour les politiques de sécurité, le rate limiting, les workflows d'approbation
  • post_tool_call : après l'exécution d'un outil. Pour le logging, le monitoring, le nettoyage automatique

Hooks d'API

  • pre_api_request : avant chaque requête HTTP vers le provider LLM. Langfuse s'en sert pour tracer les requêtes
  • post_api_request : après la réponse. Idéal pour capturer les tokens utilisés, les coûts, les erreurs

Hooks de session

  • on_session_start : au démarrage d'une session
  • on_session_end : à la fin d'une session. Le plugin disk-cleanup l'utilise pour nettoyer les fichiers temporaires
  • on_session_finalize : quand la session est finalisée en base
  • on_session_reset : au reset de session (commande /new)

Hooks avancés

  • pre_gateway_dispatch : avant le dispatch d'un message entrant dans le gateway. Permet de skip (ignorer), rewrite (réécrire le texte), ou allow (normal)
  • pre_approval_request / post_approval_response : observateurs du cycle d'approbation des commandes dangereuses
  • subagent_stop : quand un subagent (delegate_task) se termine
  • transform_terminal_output : transformation de la sortie terminal
  • transform_tool_result : transformation du résultat d'un outil avant de le renvoyer au modèle

Robustesse des hooks

Chaque callback est exécuté dans son propre try/except. Un plugin mal comporté ne peut pas casser la boucle principale de l'agent — les erreurs sont logguées et le hook suivant s'exécute normalement.

Configuration des plugins

Activation opt-in

Par défaut, les plugins standalone sont inactifs. L'activation se fait dans ~/.hermes/config.yaml :

plugins:
  enabled:
    - disk-cleanup
    - google_meet
    - observability/langfuse

Désactivation explicite

La clé disabled surcharge toujours enabled. Utile pour exclure un plugin même s'il est bundled :

plugins:
  disabled:
    - disk-cleanup

Auto-activation des backends et platforms

Les backends bundled (image_gen/*) et les platform plugins bundled (IRC, Teams) s'activent automatiquement. Pas besoin de les lister dans enabled.

Gestion via la CLI

Hermes fournit des commandes dédiées :

hermes plugins list          # Lister tous les plugins découverts
hermes plugins install owner/repo   # Installer depuis GitHub
hermes plugins install https://github.com/owner/repo.git
hermes plugins enable nom    # Activer un plugin
hermes plugins disable nom   # Désactiver un plugin
hermes plugins remove nom    # Supprimer un plugin utilisateur

L'installation clone le dépôt Git dans ~/.hermes/plugins/<nom>/. Si le plugin contient un fichier after-install.md, il est affiché avec le rendu Rich Markdown pour guider la configuration.

Créer son propre plugin

Structure minimale

Un plugin standalone nécessite deux fichiers :

~/.hermes/plugins/mon-plugin/
├── plugin.yaml
└── __init__.py

plugin.yaml :

name: mon-plugin
version: 1.0.0
description: "Description de mon plugin"
author: "Votre Nom"
kind: standalone
requires_env:
  - MON_PLUGIN_API_KEY

init.py :

def register(ctx):
    """Point d'entrée appelé par le PluginManager."""

    # Enregistrer un hook
    ctx.register_hook("post_tool_call", on_tool_used)

    # Enregistrer un outil
    ctx.register_tool(
        name="mon_outil",
        toolset="custom",
        schema={
            "type": "object",
            "properties": {
                "query": {"type": "string", "description": "La requête"}
            },
            "required": ["query"]
        },
        handler=handle_mon_outil,
        description="Description de l'outil pour le LLM",
        emoji="🔧",
    )

    # Enregistrer une commande slash
    ctx.register_command(
        name="mon-action",
        handler=handle_command,
        description="Description de la commande",
        args_hint="<paramètre>",
    )

def on_tool_used(tool_name, args, result, **kwargs):
    """Callback appelé après chaque utilisation d'un outil."""
    print(f"Outil utilisé : {tool_name}")

def handle_mon_outil(args, **kwargs):
    """Handler de l'outil."""
    query = args.get("query", "")
    return f"Résultat pour : {query}"

def handle_command(raw_args):
    """Handler de la commande slash /mon-action."""
    return f"Action exécutée avec : {raw_args}"

Plugin de génération d'images (backend)

name: mon-backend-img
version: 1.0.0
description: "Backend de génération d'images personnalisé"
kind: backend
requires_env:
  - MON_IMG_API_KEY

Le __init__.py doit instancier une classe héritant de ImageGenProvider et l'enregistrer via ctx.register_image_gen_provider(provider). Le nom du provider est ce qui est comparé à la clé image_gen.provider dans config.yaml.

Plugin d'observabilité (hooks)

Le plugin Langfuse est un excellent exemple de plugin orienté hooks. Il s'accroche à six hooks (pre_api_request, post_api_request, pre_llm_call, post_llm_call, pre_tool_call, post_tool_call) pour tracer l'intégralité du flux conversationnel.

Plugin de plateforme (gateway)

Les adapters de plateforme (IRC, Teams) utilisent kind: platform et s'enregistrent via ctx.register_platform(). Le factory reçoit une PlatformConfig et doit retourner une instance de BasePlatformAdapter. Le gateway appelle la check_fn() avant instanciation pour vérifier que les dépendances sont satisfaites.

Bonnes pratiques

  • Isoler les dépendances : lister toutes les variables d'environnement nécessaires dans requires_env du manifest pour que l'utilisateur sache ce qu'il doit configurer
  • Gérer les erreurs gracieusement : un plugin ne doit jamais crasher l'agent. Utiliser des try/except dans les handlers et les callbacks de hooks
  • Ne pas polluer le namespace : les hooks de type observer ne doivent pas modifier les données — seulement les lire. Utiliser pre_tool_call avec un retour block pour les politiques
  • Tester le clé de collision : vérifier que la clé de votre plugin (déduite du chemin) ne collide pas avec un plugin existant
  • Documenter le after-install.md : fournir un guide post-installation pour les étapes de configuration non automatisables

Plugins embarqués

Hermes Agent embarque déjà une riche collection de plugins :

  • Memory providers (8) : Honcho, Mem0, Supermemory, Holographic, Hindsight, Byterover, OpenViking, RetainDB — chacun avec son approche de la mémoire cross-session
  • Image generation (3 backends) : OpenAI (GPT Image), OpenAI Codex (OAuth), xAI (Grok)
  • Plateformes (2) : IRC et Microsoft Teams
  • Utilitaires : disk-cleanup (nettoyage auto), example-dashboard (modèle de dashboard)
  • Observabilité : Langfuse (traces complètes)
  • Intégrations : Google Meet, Spotify

Cette collection couvre déjà la majorité des cas d'usage courants. Le système de plugins reste ouvert pour les besoins spécifiques que vous souhaitez ajouter.

Conclusion

Le système de plugins d'Hermes Agent transforme un agent IA déjà puissant en une plateforme véritablement extensible. Avec quatre sources de découverte, quatre types de plugins, seize hooks de cycle de vie et une API d'enregistrement complète via PluginContext, les possibilités d'extension sont vastes. Que vous souhaitiez surveiller les coûts via Langfuse, ajouter un adapter pour votre plateforme de chat interne, ou construire un outil métier spécialisé, le système de plugins est conçu pour cela — sans compromettre la stabilité du core. Chaque hook est isolé, chaque plugin est opt-in, et chaque collision est gérée explicitement.