Multi-agent

Routage multi-agent

Exécutez plusieurs agents isolés — chacun avec son propre espace de travail, répertoire d’état (agentDir) et historique de session — ainsi que plusieurs comptes de canal (par exemple deux comptes WhatsApp) dans un seul Gateway en cours d’exécution. Les messages entrants sont routés vers le bon agent via des bindings.

Un agent, ici, correspond au périmètre complet d’une persona : fichiers de l’espace de travail, profils d’authentification, registre des modèles et stockage des sessions. agentDir est le répertoire d’état sur disque qui contient cette configuration propre à l’agent dans ~/.openclaw/agents/<agentId>/. Un binding associe un compte de canal (par exemple un espace de travail Slack ou un numéro WhatsApp) à l’un de ces agents.

Qu’est-ce qu’« un agent » ?

Un agent est un cerveau entièrement délimité, avec son propre :

  • Espace de travail (fichiers, AGENTS.md/SOUL.md/USER.md, notes locales, règles de persona).
  • Répertoire d’état (agentDir) pour les profils d’authentification, le registre des modèles et la configuration propre à l’agent.
  • Stockage des sessions (historique de chat + état de routage) sous ~/.openclaw/agents/<agentId>/sessions.

Les profils d’authentification sont propres à chaque agent. Chaque agent lit depuis son propre fichier :

~/.openclaw/agents/<agentId>/agent/auth-profiles.json

Les Skills sont chargées depuis chaque espace de travail d’agent ainsi que depuis les racines partagées comme ~/.openclaw/skills, puis filtrées par la liste d’autorisation effective des compétences de l’agent lorsqu’elle est configurée. Utilisez agents.defaults.skills pour une base partagée et agents.list[].skills pour un remplacement propre à l’agent. Consultez Skills : par agent ou partagées et Skills : listes d’autorisation des compétences d’agent.

Le Gateway peut héberger un agent (par défaut) ou plusieurs agents côte à côte.

Chemins (carte rapide)

  • Configuration : ~/.openclaw/openclaw.json (ou OPENCLAW_CONFIG_PATH)
  • Répertoire d’état : ~/.openclaw (ou OPENCLAW_STATE_DIR)
  • Espace de travail : ~/.openclaw/workspace (ou ~/.openclaw/workspace-<agentId>)
  • Répertoire de l’agent : ~/.openclaw/agents/<agentId>/agent (ou agents.list[].agentDir)
  • Sessions : ~/.openclaw/agents/<agentId>/sessions

Mode agent unique (par défaut)

Si vous ne faites rien, OpenClaw exécute un seul agent :

  • agentId vaut main par défaut.
  • Les sessions sont indexées sous la forme agent:main:<mainKey>.
  • L’espace de travail vaut ~/.openclaw/workspace par défaut (ou ~/.openclaw/workspace-<profile> quand OPENCLAW_PROFILE est défini).
  • L’état vaut ~/.openclaw/agents/main/agent par défaut.

Assistant d’agent

Utilisez l’assistant d’agent pour ajouter un nouvel agent isolé :

openclaw agents add work

Ajoutez ensuite des bindings (ou laissez l’assistant le faire) pour router les messages entrants.

Vérifiez avec :

openclaw agents list --bindings

Démarrage rapide

  • Créer chaque espace de travail d’agent

    Utilisez l’assistant ou créez les espaces de travail manuellement :

    openclaw agents add coding
    openclaw agents add social
    

    Chaque agent obtient son propre espace de travail avec SOUL.md, AGENTS.md et éventuellement USER.md, ainsi qu’un agentDir dédié et un stockage de sessions sous ~/.openclaw/agents/<agentId>.

  • Créer les comptes de canal

    Créez un compte par agent sur vos canaux préférés :

    • Discord : un bot par agent, activez Message Content Intent, copiez chaque jeton.
    • Telegram : un bot par agent via BotFather, copiez chaque jeton.
    • WhatsApp : associez chaque numéro de téléphone par compte.
    openclaw channels login --channel whatsapp --account work
    

    Consultez les guides de canaux : Discord, Telegram, WhatsApp.

  • Ajouter les agents, les comptes et les bindings

    Ajoutez les agents sous agents.list, les comptes de canal sous channels.<channel>.accounts, puis connectez-les avec bindings (exemples ci-dessous).

  • Redémarrer et vérifier

    openclaw gateway restart
    openclaw agents list --bindings
    openclaw channels status --probe
    
  • Plusieurs agents = plusieurs personnes, plusieurs personnalités

    Avec plusieurs agents, chaque agentId devient une persona entièrement isolée :

    • Numéros de téléphone/comptes différents (par accountId de canal).
    • Personnalités différentes (fichiers d’espace de travail propres à l’agent comme AGENTS.md et SOUL.md).
    • Authentification + sessions séparées (aucune communication croisée sauf activation explicite).

    Cela permet à plusieurs personnes de partager un seul serveur Gateway tout en gardant leurs « cerveaux » d’IA et leurs données isolés.

    Recherche de mémoire QMD interagents

    Si un agent doit rechercher dans les transcripts de session QMD d’un autre agent, ajoutez des collections supplémentaires sous agents.list[].memorySearch.qmd.extraCollections. Utilisez agents.defaults.memorySearch.qmd.extraCollections uniquement lorsque chaque agent doit hériter des mêmes collections de transcripts partagées.

    {
      agents: {
        defaults: {
          workspace: "~/workspaces/main",
          memorySearch: {
            qmd: {
              extraCollections: [{ path: "~/agents/family/sessions", name: "family-sessions" }],
            },
          },
        },
        list: [
          {
            id: "main",
            workspace: "~/workspaces/main",
            memorySearch: {
              qmd: {
                extraCollections: [{ path: "notes" }], // resolves inside workspace -> collection named "notes-main"
              },
            },
          },
          { id: "family", workspace: "~/workspaces/family" },
        ],
      },
      memory: {
        backend: "qmd",
        qmd: { includeDefaultMemory: false },
      },
    }
    

    Le chemin de collection supplémentaire peut être partagé entre agents, mais le nom de la collection reste explicite lorsque le chemin est en dehors de l’espace de travail de l’agent. Les chemins situés dans l’espace de travail restent propres à l’agent afin que chaque agent conserve son propre ensemble de recherche de transcripts.

    Un numéro WhatsApp, plusieurs personnes (séparation des DM)

    Vous pouvez router différents DM WhatsApp vers différents agents tout en restant sur un seul compte WhatsApp. Faites correspondre l’expéditeur E.164 (comme +15551234567) avec peer.kind: "direct". Les réponses proviennent toujours du même numéro WhatsApp (pas d’identité d’expéditeur propre à l’agent).

    Exemple :

    {
      agents: {
        list: [
          { id: "alex", workspace: "~/.openclaw/workspace-alex" },
          { id: "mia", workspace: "~/.openclaw/workspace-mia" },
        ],
      },
      bindings: [
        {
          agentId: "alex",
          match: { channel: "whatsapp", peer: { kind: "direct", id: "+15551230001" } },
        },
        {
          agentId: "mia",
          match: { channel: "whatsapp", peer: { kind: "direct", id: "+15551230002" } },
        },
      ],
      channels: {
        whatsapp: {
          dmPolicy: "allowlist",
          allowFrom: ["+15551230001", "+15551230002"],
        },
      },
    }
    

    Notes :

    • Le contrôle d’accès aux DM est global par compte WhatsApp (appairage/liste d’autorisation), pas par agent.
    • Pour les groupes partagés, associez le groupe à un seul agent ou utilisez Groupes de diffusion.

    Règles de routage (comment les messages choisissent un agent)

    Les bindings sont déterministes et le plus spécifique l’emporte :

  • Correspondance peer

    Identifiant exact de DM/groupe/canal.

  • Correspondance parentPeer

    Héritage de thread.

  • guildId + rôles

    Routage par rôle Discord.

  • guildId

    Discord.

  • teamId

    Slack.

  • Correspondance accountId pour un canal

    Repli par compte.

  • Correspondance au niveau du canal

    accountId: "*".

  • Agent par défaut

    Repli vers agents.list[].default, sinon première entrée de liste, par défaut : main.

  • Départage et sémantique AND
    • Si plusieurs bindings correspondent au même niveau, le premier dans l’ordre de configuration l’emporte.
    • Si un binding définit plusieurs champs de correspondance (par exemple peer + guildId), tous les champs spécifiés sont requis (sémantique AND).
    Détail de portée du compte
    • Un binding qui omet accountId correspond uniquement au compte par défaut.
    • Utilisez accountId: "*" pour un repli à l’échelle du canal sur tous les comptes.
    • Si vous ajoutez plus tard le même binding pour le même agent avec un identifiant de compte explicite, OpenClaw met à niveau le binding existant limité au canal vers une portée de compte au lieu de le dupliquer.

    Plusieurs comptes / numéros de téléphone

    Les canaux qui prennent en charge plusieurs comptes (par exemple WhatsApp) utilisent accountId pour identifier chaque connexion. Chaque accountId peut être routé vers un agent différent, ce qui permet à un seul serveur d’héberger plusieurs numéros de téléphone sans mélanger les sessions.

    Si vous voulez un compte par défaut à l’échelle du canal lorsque accountId est omis, définissez channels.<channel>.defaultAccount (facultatif). S’il n’est pas défini, OpenClaw se replie sur default s’il est présent, sinon sur le premier identifiant de compte configuré (trié).

    Les canaux courants qui prennent en charge ce modèle incluent :

    • whatsapp, telegram, discord, slack, signal, imessage
    • irc, line, googlechat, mattermost, matrix, nextcloud-talk
    • bluebubbles, zalo, zalouser, nostr, feishu

    Concepts

    • agentId : un « cerveau » (espace de travail, authentification propre à l’agent, stockage de sessions propre à l’agent).
    • accountId : une instance de compte de canal (par exemple le compte WhatsApp "personal" par rapport à "biz").
    • binding : route les messages entrants vers un agentId par (channel, accountId, peer) et éventuellement par identifiants de serveur/équipe.
    • Les chats directs se replient sur agent:<agentId>:<mainKey> (« main » propre à l’agent ; session.mainKey).

    Exemples de plateformes

    Bots Discord par agent

    Chaque compte de bot Discord correspond à un accountId unique. Associez chaque compte à un agent et conservez les listes d’autorisation par bot.

    {
      agents: {
        list: [
          { id: "main", workspace: "~/.openclaw/workspace-main" },
          { id: "coding", workspace: "~/.openclaw/workspace-coding" },
        ],
      },
      bindings: [
        { agentId: "main", match: { channel: "discord", accountId: "default" } },
        { agentId: "coding", match: { channel: "discord", accountId: "coding" } },
      ],
      channels: {
        discord: {
          groupPolicy: "allowlist",
          accounts: {
            default: {
              token: "DISCORD_BOT_TOKEN_MAIN",
              guilds: {
                "123456789012345678": {
                  channels: {
                    "222222222222222222": { allow: true, requireMention: false },
                  },
                },
              },
            },
            coding: {
              token: "DISCORD_BOT_TOKEN_CODING",
              guilds: {
                "123456789012345678": {
                  channels: {
                    "333333333333333333": { allow: true, requireMention: false },
                  },
                },
              },
            },
          },
        },
      },
    }
    
    • Invitez chaque bot dans la guilde et activez l’Intent de contenu des messages.
    • Les jetons se trouvent dans channels.discord.accounts.<id>.token (le compte par défaut peut utiliser DISCORD_BOT_TOKEN).
    Telegram bots per agent
    {
      agents: {
        list: [
          { id: "main", workspace: "~/.openclaw/workspace-main" },
          { id: "alerts", workspace: "~/.openclaw/workspace-alerts" },
        ],
      },
      bindings: [
        { agentId: "main", match: { channel: "telegram", accountId: "default" } },
        { agentId: "alerts", match: { channel: "telegram", accountId: "alerts" } },
      ],
      channels: {
        telegram: {
          accounts: {
            default: {
              botToken: "123456:ABC...",
              dmPolicy: "pairing",
            },
            alerts: {
              botToken: "987654:XYZ...",
              dmPolicy: "allowlist",
              allowFrom: ["tg:123456789"],
            },
          },
        },
      },
    }
    
    • Créez un bot par agent avec BotFather et copiez chaque jeton.
    • Les jetons se trouvent dans channels.telegram.accounts.<id>.botToken (le compte par défaut peut utiliser TELEGRAM_BOT_TOKEN).
    WhatsApp numbers per agent

    Associez chaque compte avant de démarrer le Gateway :

    openclaw channels login --channel whatsapp --account personal
    openclaw channels login --channel whatsapp --account biz
    

    ~/.openclaw/openclaw.json (JSON5) :

    {
      agents: {
        list: [
          {
            id: "home",
            default: true,
            name: "Home",
            workspace: "~/.openclaw/workspace-home",
            agentDir: "~/.openclaw/agents/home/agent",
          },
          {
            id: "work",
            name: "Work",
            workspace: "~/.openclaw/workspace-work",
            agentDir: "~/.openclaw/agents/work/agent",
          },
        ],
      },
    
      // Deterministic routing: first match wins (most-specific first).
      bindings: [
        { agentId: "home", match: { channel: "whatsapp", accountId: "personal" } },
        { agentId: "work", match: { channel: "whatsapp", accountId: "biz" } },
    
        // Optional per-peer override (example: send a specific group to work agent).
        {
          agentId: "work",
          match: {
            channel: "whatsapp",
            accountId: "personal",
            peer: { kind: "group", id: "[email protected]" },
          },
        },
      ],
    
      // Off by default: agent-to-agent messaging must be explicitly enabled + allowlisted.
      tools: {
        agentToAgent: {
          enabled: false,
          allow: ["home", "work"],
        },
      },
    
      channels: {
        whatsapp: {
          accounts: {
            personal: {
              // Optional override. Default: ~/.openclaw/credentials/whatsapp/personal
              // authDir: "~/.openclaw/credentials/whatsapp/personal",
            },
            biz: {
              // Optional override. Default: ~/.openclaw/credentials/whatsapp/biz
              // authDir: "~/.openclaw/credentials/whatsapp/biz",
            },
          },
        },
      },
    }
    

    Modèles courants

    WhatsApp daily + Telegram deep work

    Séparez par canal : routez WhatsApp vers un agent quotidien rapide et Telegram vers un agent Opus.

    {
      agents: {
        list: [
          {
            id: "chat",
            name: "Everyday",
            workspace: "~/.openclaw/workspace-chat",
            model: "anthropic/claude-sonnet-4-6",
          },
          {
            id: "opus",
            name: "Deep Work",
            workspace: "~/.openclaw/workspace-opus",
            model: "anthropic/claude-opus-4-6",
          },
        ],
      },
      bindings: [
        { agentId: "chat", match: { channel: "whatsapp" } },
        { agentId: "opus", match: { channel: "telegram" } },
      ],
    }
    

    Remarques :

    • Si vous avez plusieurs comptes pour un canal, ajoutez accountId à l’association (par exemple { channel: "whatsapp", accountId: "personal" }).
    • Pour router un seul message direct/groupe vers Opus tout en gardant le reste sur chat, ajoutez une association match.peer pour ce pair ; les correspondances de pair priment toujours sur les règles à l’échelle du canal.

    Same channel, one peer to Opus

    Gardez WhatsApp sur l’agent rapide, mais routez un message direct vers Opus :

    {
      agents: {
        list: [
          {
            id: "chat",
            name: "Everyday",
            workspace: "~/.openclaw/workspace-chat",
            model: "anthropic/claude-sonnet-4-6",
          },
          {
            id: "opus",
            name: "Deep Work",
            workspace: "~/.openclaw/workspace-opus",
            model: "anthropic/claude-opus-4-6",
          },
        ],
      },
      bindings: [
        {
          agentId: "opus",
          match: { channel: "whatsapp", peer: { kind: "direct", id: "+15551234567" } },
        },
        { agentId: "chat", match: { channel: "whatsapp" } },
      ],
    }
    

    Les associations de pair priment toujours, gardez-les donc au-dessus de la règle à l’échelle du canal.

    Family agent bound to a WhatsApp group

    Associez un agent familial dédié à un seul groupe WhatsApp, avec un filtrage par mention et une politique d’outils plus stricte :

    {
      agents: {
        list: [
          {
            id: "family",
            name: "Family",
            workspace: "~/.openclaw/workspace-family",
            identity: { name: "Family Bot" },
            groupChat: {
              mentionPatterns: ["@family", "@familybot", "@Family Bot"],
            },
            sandbox: {
              mode: "all",
              scope: "agent",
            },
            tools: {
              allow: [
                "exec",
                "read",
                "sessions_list",
                "sessions_history",
                "sessions_send",
                "sessions_spawn",
                "session_status",
              ],
              deny: ["write", "edit", "apply_patch", "browser", "canvas", "nodes", "cron"],
            },
          },
        ],
      },
      bindings: [
        {
          agentId: "family",
          match: {
            channel: "whatsapp",
            peer: { kind: "group", id: "[email protected]" },
          },
        },
      ],
    }
    

    Remarques :

    • Les listes d’autorisation/refus d’outils concernent les outils, pas les Skills. Si une Skill doit exécuter un binaire, assurez-vous que exec est autorisé et que le binaire existe dans le sandbox.
    • Pour un filtrage plus strict, définissez agents.list[].groupChat.mentionPatterns et gardez les listes d’autorisation de groupe activées pour le canal.

    Configuration du sandbox et des outils par agent

    Chaque agent peut avoir ses propres restrictions de sandbox et d’outils :

    {
      agents: {
        list: [
          {
            id: "personal",
            workspace: "~/.openclaw/workspace-personal",
            sandbox: {
              mode: "off",  // No sandbox for personal agent
            },
            // No tool restrictions - all tools available
          },
          {
            id: "family",
            workspace: "~/.openclaw/workspace-family",
            sandbox: {
              mode: "all",     // Always sandboxed
              scope: "agent",  // One container per agent
              docker: {
                // Optional one-time setup after container creation
                setupCommand: "apt-get update && apt-get install -y git curl",
              },
            },
            tools: {
              allow: ["read"],                    // Only read tool
              deny: ["exec", "write", "edit", "apply_patch"],    // Deny others
            },
          },
        ],
      },
    }
    

    Avantages :

    • Isolation de sécurité : restreignez les outils pour les agents non approuvés.
    • Contrôle des ressources : placez certains agents dans un sandbox tout en gardant les autres sur l’hôte.
    • Politiques flexibles : permissions différentes par agent.

    Consultez Sandbox et outils multi-agent pour des exemples détaillés.

    Connexe

    • Agents ACP — exécution de harnais de codage externes
    • Routage des canaux — comment les messages sont routés vers les agents
    • Présence — présence et disponibilité des agents
    • Session — isolation et routage des sessions
    • Sous-agents — lancement d’exécutions d’agents en arrière-plan