Multi-agent
Routage multi-agents
Exécutez plusieurs agents isolés dans un même processus Gateway, chacun avec son propre espace de travail, son propre répertoire d’état (agentDir) et son propre historique de sessions stocké dans SQLite, ainsi que plusieurs comptes de canal (par exemple, deux numéros WhatsApp). Les messages entrants sont acheminés vers l’agent approprié au moyen de liaisons.
Un agent représente le périmètre complet d’une persona : fichiers de l’espace de travail, profils d’authentification, registre de modèles et stockage des sessions. Une liaison associe un compte de canal (un espace de travail Slack, un numéro WhatsApp, etc.) à l’un de ces agents.
Qu’est-ce qu’un agent
Chaque agent possède ses propres éléments :
- Espace de travail : fichiers,
AGENTS.md/SOUL.md/USER.md, notes locales, règles de persona. - Répertoire d’état (
agentDir) : profils d’authentification, registre de modèles, configuration propre à l’agent. - Stockage des sessions : historique des conversations et état du routage dans
~/.openclaw/agents/<agentId>/agent/openclaw-agent.sqlite.
Les profils d’authentification sont propres à chaque agent et sont lus depuis :
~/.openclaw/agents/<agentId>/agent/auth-profiles.jsonLes Skills sont chargées depuis l’espace de travail de chaque agent ainsi que depuis des racines partagées telles que ~/.openclaw/skills, puis filtrées selon la liste d’autorisation de Skills effective de l’agent. Utilisez agents.defaults.skills pour définir une base de référence partagée et agents.list[].skills pour effectuer un remplacement propre à chaque agent (les entrées explicites remplacent la valeur par défaut, elles ne sont pas fusionnées). Consultez Skills : propres à chaque agent ou partagées et Skills : listes d’autorisation des agents.
Le stockage géré par un Plugin suit la configuration de ce Plugin ; l’ajout d’un second agent ne sépare pas automatiquement tous les stockages globaux des Plugins. Par exemple, configurez des coffres Memory Wiki propres à chaque agent lorsque les personas ne doivent pas partager les connaissances de wiki compilées.
Chemins
| Élément | Valeur par défaut | Remplacement |
|---|---|---|
| Configuration | ~/.openclaw/openclaw.json |
OPENCLAW_CONFIG_PATH |
| Répertoire d’état | ~/.openclaw |
OPENCLAW_STATE_DIR |
| Espace de travail de l’agent par défaut | ~/.openclaw/workspace (ou workspace-<profile> lorsque OPENCLAW_PROFILE est défini) |
agents.list[].workspace, puis agents.defaults.workspace, ou OPENCLAW_WORKSPACE_DIR |
| Espace de travail des autres agents | <stateDir>/workspace-<agentId> (ou <agents.defaults.workspace>/<agentId> lorsqu’il est défini) |
agents.list[].workspace |
| Répertoire de l’agent | ~/.openclaw/agents/<agentId>/agent |
agents.list[].agentDir |
| Sessions et transcriptions | ~/.openclaw/agents/<agentId>/agent/openclaw-agent.sqlite |
— |
| Artefacts de session hérités/archivés | ~/.openclaw/agents/<agentId>/sessions |
— |
Mode agent unique (par défaut)
Si vous ne configurez rien, OpenClaw exécute un seul agent :
- La valeur par défaut de
agentIdestmain. - Les sessions utilisent des clés de la forme
agent:main:<mainKey>(la valeur par défaut demainKeyestmain). - L’espace de travail par défaut est
~/.openclaw/workspace(ouworkspace-<profile>lorsqueOPENCLAW_PROFILEest défini sur une valeur autre quedefault). - L’état est stocké par défaut dans
~/.openclaw/agents/main/agent.
Assistant de gestion des agents
Ajoutez un nouvel agent isolé :
openclaw agents add workOptions : --workspace <dir>, --model <id>, --agent-dir <dir>, --bind <channel[:accountId]> (répétable), --non-interactive (nécessite --workspace).
Ajoutez des bindings pour acheminer les messages entrants (l’assistant vous propose de le faire), puis vérifiez :
openclaw agents list --bindingsDémarrage rapide
Créer l’espace de travail de chaque agent
openclaw agents add codingopenclaw agents add socialChaque agent dispose de son propre espace de travail avec SOUL.md, AGENTS.md et éventuellement USER.md, ainsi que d’un agentDir dédié et d’un stockage de sessions sous ~/.openclaw/agents/<agentId>.
Créer les comptes de canal
Créez un compte par agent sur les canaux de votre choix :
- Discord : un bot par agent, activez Message Content Intent et copiez chaque jeton.
- Telegram : un bot par agent via BotFather, puis copiez chaque jeton.
- WhatsApp : associez chaque numéro de téléphone au compte correspondant.
openclaw channels login --channel whatsapp --account workConsultez les guides des canaux : Discord, Telegram, WhatsApp.
Ajouter les agents, les comptes et les liaisons
Ajoutez les agents sous agents.list, les comptes de canal sous channels.<channel>.accounts, puis reliez-les avec bindings (voir les exemples ci-dessous).
Redémarrer et vérifier
openclaw gateway restartopenclaw agents list --bindingsopenclaw channels status --probePlusieurs agents, plusieurs personas
Chaque agentId configuré constitue une limite de persona distincte pour l’état principal de l’agent :
- Comptes différents par canal (selon
accountId). - Personnalités différentes (
AGENTS.md/SOUL.mdpropres à chaque agent). - Authentification et sessions séparées, l’accès entre agents n’étant activé que par des fonctionnalités explicites ou par la configuration d’un Plugin.
Cela permet à plusieurs personnes de partager un même Gateway tout en conservant séparément l’état principal de chaque agent.
Coffres Memory Wiki propres à chaque agent
Memory Wiki utilise par défaut un coffre global unique. Pour séparer les connaissances compilées d’un agent d’assistance de celles d’un agent marketing, définissez plugins.entries.memory-wiki.config.vault.scope sur agent :
{ plugins: { entries: { "memory-wiki": { enabled: true, config: { vault: { scope: "agent", path: "~/.openclaw/wiki", }, }, }, }, },}Le chemin configuré correspond au répertoire parent. OpenClaw lui ajoute l’identifiant normalisé de l’agent, produisant des chemins tels que ~/.openclaw/wiki/support et ~/.openclaw/wiki/marketing. Les opérations de la CLI et du Gateway limitées à un agent nécessitent de spécifier explicitement un agent lorsque plusieurs agents sont configurés. Consultez Coffres Memory Wiki propres à chaque agent pour plus de détails sur le filtrage du pont, la migration et les limites de confiance.
Recherche de mémoire QMD entre agents
Pour permettre à un agent de rechercher les transcriptions de sessions QMD d’un autre agent, ajoutez des collections supplémentaires sous agents.list[].memorySearch.qmd.extraCollections. Utilisez agents.defaults.memorySearch.qmd.extraCollections lorsque tous les agents doivent partager les mêmes collections.
{ 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" }], // résolu dans l’espace de travail -> collection nommée "notes-main" }, }, }, { id: "family", workspace: "~/workspaces/family" }, ], }, memory: { backend: "qmd", qmd: { includeDefaultMemory: false }, },}Le chemin d’une collection supplémentaire peut être partagé entre plusieurs agents, mais son name reste explicite lorsque le chemin se trouve hors de l’espace de travail de l’agent. Les chemins situés dans l’espace de travail restent propres à l’agent afin que chacun conserve son propre ensemble de recherche de transcriptions.
Un numéro WhatsApp, plusieurs personnes (répartition des messages privés)
Acheminez différents messages privés WhatsApp vers différents agents sur un seul compte WhatsApp en faisant correspondre l’expéditeur au format E.164 (+15551234567) avec peer.kind: "direct". Les réponses proviennent toujours du même numéro WhatsApp : il n’existe pas d’identité d’expéditeur propre à chaque agent.
{ 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"], }, },}Le contrôle d’accès aux messages privés (association/liste d’autorisation) est global pour chaque compte WhatsApp, et non propre à chaque agent. Pour les groupes partagés, associez le groupe à un seul agent ou utilisez les Groupes de diffusion.
Règles de routage
Les liaisons sont déterministes et la correspondance la plus spécifique l’emporte. Consultez Routage des canaux pour connaître l’ordre complet des niveaux (pair exact, pair parent, caractère générique de pair, serveur+rôles, serveur, équipe, compte, canal, agent par défaut). Voici quelques règles importantes :
- Si plusieurs liaisons correspondent au même niveau, la première dans l’ordre de la configuration l’emporte.
- Si une liaison définit plusieurs champs de correspondance (par exemple
peer+guildId), tous les champs spécifiés doivent correspondre (sémantiqueAND). - Une liaison qui omet
accountIdcorrespond uniquement au compte par défaut, et non à tous les comptes. UtilisezaccountId: "*"pour définir une solution de repli à l’échelle du canal, ouaccountId: "<name>"pour un compte précis. L’ajout de la même liaison avec un identifiant de compte explicite met à niveau la liaison existante limitée au canal au lieu de la 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 est acheminé vers son propre agent, ce qui permet à un serveur d’héberger plusieurs numéros de téléphone sans mélanger les sessions.
Définissez channels.<channel>.defaultAccount pour choisir le compte utilisé lorsque accountId est omis. Si cette valeur n’est pas définie, OpenClaw utilise default s’il existe ; sinon, il utilise le premier identifiant de compte configuré selon l’ordre de tri.
Canaux prenant en charge plusieurs comptes : discord, feishu, googlechat, imessage, irc, line, mattermost, matrix, nextcloud-talk, nostr, signal, slack, telegram, whatsapp, zalo, zalouser.
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 WhatsApppersonalpar rapport àbiz).binding: achemine les messages entrants vers unagentIdselon(channel, accountId, peer), et éventuellement selon les identifiants de serveur/d’équipe.- Les conversations directes sont regroupées dans
agent:<agentId>:<mainKey>(session « principale » propre à l’agent ; voirsession.mainKey).
Exemples par plateforme
Bots Discord par agent
Chaque compte de bot Discord correspond à un accountId unique. Associez chaque compte à un agent et conservez des listes d’autorisation propres à chaque 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 sur le serveur et activez Message Content Intent.
- Les jetons se trouvent dans
channels.discord.accounts.<id>.token(le compte par défaut peut utiliserDISCORD_BOT_TOKEN).
Bots Telegram par 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 utiliserTELEGRAM_BOT_TOKEN). - Pour plusieurs bots dans le même groupe Telegram, invitez chaque bot et mentionnez celui qui doit répondre.
- Désactivez Privacy Mode de BotFather pour chaque bot de groupe (
/setprivacy-> Disable), puis supprimez et ajoutez de nouveau le bot afin que Telegram applique le paramètre. - Autorisez les groupes avec
channels.telegram.groups, ou utilisezgroupPolicy: "open"uniquement pour les déploiements de groupes de confiance. - Placez les identifiants utilisateur des expéditeurs dans
groupAllowFrom. Les identifiants de groupe et de supergroupe doivent figurer danschannels.telegram.groups, et non dansgroupAllowFrom. - Associez selon
accountIdafin que chaque bot achemine les messages vers son propre agent.
Numéros WhatsApp par agent
Associez chaque compte avant de démarrer le Gateway :
openclaw channels login --channel whatsapp --account personalopenclaw 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", }, ], }, // Routage déterministe : la première correspondance l’emporte (la plus précise en premier). bindings: [ { agentId: "home", match: { channel: "whatsapp", accountId: "personal" } }, { agentId: "work", match: { channel: "whatsapp", accountId: "biz" } }, // Remplacement facultatif par pair (exemple : envoyer un groupe précis à l’agent de travail). { agentId: "work", match: { channel: "whatsapp", accountId: "personal", peer: { kind: "group", id: "1203630...@g.us" }, }, }, ], // Désactivé par défaut : la messagerie entre agents doit être explicitement activée et autorisée. tools: { agentToAgent: { enabled: false, allow: ["home", "work"], }, }, channels: { whatsapp: { accounts: { personal: { // Remplacement facultatif. Valeur par défaut : ~/.openclaw/credentials/whatsapp/personal // authDir: "~/.openclaw/credentials/whatsapp/personal", }, biz: { // Remplacement facultatif. Valeur par défaut : ~/.openclaw/credentials/whatsapp/biz // authDir: "~/.openclaw/credentials/whatsapp/biz", }, }, }, },}Modèles courants
WhatsApp au quotidien + travail approfondi sur Telegram
Répartissez par canal : acheminez WhatsApp vers un agent rapide pour les tâches quotidiennes 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", accountId: "*" } }, { agentId: "opus", match: { channel: "telegram", accountId: "*" } }, ],}Ces exemples utilisent accountId: "*" afin que les associations continuent de fonctionner si vous ajoutez des comptes ultérieurement. Pour acheminer un seul message direct/groupe vers Opus tout en conservant le reste sur l’agent de conversation, ajoutez une association match.peer pour cette pair — les correspondances de pair l’emportent toujours sur les règles couvrant l’ensemble du canal.
Même canal, une pair vers Opus
Conservez WhatsApp sur l’agent rapide, mais acheminez 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", accountId: "*", peer: { kind: "direct", id: "+15551234567" } }, }, { agentId: "chat", match: { channel: "whatsapp", accountId: "*" } }, ],}Les associations de pair l’emportent toujours ; conservez-les donc au-dessus de la règle couvrant l’ensemble du canal.
Agent familial associé à un groupe WhatsApp
Associez un agent familial dédié à un seul groupe WhatsApp, avec une obligation de 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: "120363999999999999@g.us" }, }, }, ],}Les listes d’autorisation/de refus d’outils concernent des outils, et non des Skills. Si une compétence doit exécuter un binaire, vérifiez que exec est autorisé et que le binaire existe dans le bac à sable. Pour un filtrage plus strict, définissez agents.list[].groupChat.mentionPatterns et conservez les listes d’autorisation de groupes activées pour le canal.
Configuration du bac à sable et des outils par agent
Chaque agent peut disposer de ses propres restrictions de bac à sable et d’outils :
{ agents: { list: [ { id: "personal", workspace: "~/.openclaw/workspace-personal", sandbox: { mode: "off", // Aucun bac à sable pour l’agent personnel }, // Aucune restriction d’outil : tous les outils sont disponibles }, { id: "family", workspace: "~/.openclaw/workspace-family", sandbox: { mode: "all", // Toujours dans un bac à sable scope: "agent", // Un conteneur par agent docker: { // Configuration initiale facultative après la création du conteneur setupCommand: "apt-get update && apt-get install -y git curl", }, }, tools: { allow: ["read"], // Uniquement l’outil de lecture deny: ["exec", "write", "edit", "apply_patch"], // Refuser les autres }, }, ], },}Cela vous offre :
- Isolation de sécurité : restreignez les outils pour les agents non fiables.
- Contrôle des ressources : placez certains agents dans un bac à sable tout en conservant les autres sur l’hôte.
- Politiques flexibles : définissez des autorisations différentes pour chaque agent.
Consultez Bac à sable et outils multi-agents pour obtenir des exemples détaillés.
Rubriques associées
- Agents ACP — exécution de harnais de programmation externes
- Routage des canaux — acheminement des messages 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