OpenClawSkills
GitHub
Conceptos Básicos • 5 min de lectura

Enrutamiento Multi-Agente

Enrutamiento Multi-Agente: Agentes aislados, cuentas de canal, bindings.

Objetivo: múltiples agentes _aislados_ (espacio de trabajo separado + ''agentDir'' + sesiones), más múltiples cuentas de canal (ej. dos WhatsApps) en un Gateway en ejecución. La entrada se enruta a un agente via bindings.

Tutorial.step

¿Qué es "un agente"?

Un agente es un cerebro completamente delimitado con su propio:

- Espacio de trabajo (archivos, AGENTS.md/SOUL.md/USER.md, notas locales, reglas de persona).

- ''Directorio de estado'' (''agentDir'') para perfiles de auth, registro de modelos, y configuración por agente.

- ''Almacén de sesiones'' (historial de chat + estado de enrutamiento) bajo ''~/.openclaw/agents/<agentId>/sessions''.

Los perfiles de auth son por agente. Cada agente lee de su propio:

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

Las credenciales del agente principal ''no'' se comparten automáticamente. Nunca reutilices ''agentDir'' entre agentes (causa colisiones de auth/sesión). Si quieres compartir credenciales,

copia ''auth-profiles.json'' al ''agentDir'' del otro agente.

Las habilidades son por agente via la carpeta ''skills/'' de cada espacio de trabajo, con habilidades compartidas disponibles en ''~/.openclaw/skills''. Ver ''Habilidades: por agente vs compartidas''.

El Gateway puede alojar un agente (predeterminado) o muchos agentes en paralelo.

''Nota sobre espacio de trabajo:'' el espacio de trabajo de cada agente es el ''cwd predeterminado'', no un sandbox estricto. Las rutas relativas se resuelven dentro del espacio de trabajo, pero las rutas absolutas pueden alcanzar otras ubicaciones del host a menos que el sandboxing esté habilitado. Ver ''Sandboxing''.

El Gateway puede alojar **un agente** (predeterminado) o **muchos agentes** en paralelo.

**Nota sobre espacio de trabajo:** el espacio de trabajo de cada agente es el **cwd predeterminado**, no un sandbox

estricto. Las rutas relativas se resuelven dentro del espacio de trabajo, pero las rutas absolutas pueden

alcanzar otras ubicaciones del host a menos que el sandboxing esté habilitado. Ver

''Sandboxing''.

Tutorial.step

Rutas (mapa rápido)

- Config: ''~/.openclaw/openclaw.json'' (o ''OPENCLAW_CONFIG_PATH'')

- Directorio de estado: ''~/.openclaw'' (o ''OPENCLAW_STATE_DIR'')

- Espacio de trabajo: ''~/.openclaw/workspace'' (o ''~/.openclaw/workspace-<agentId>'')

- Directorio de agente: ''~/.openclaw/agents/<agentId>/agent'' (o ''agents.list[].agentDir'')

- Sesiones: ''~/.openclaw/agents/<agentId>/sessions''

#

Tutorial.step

Modo de agente único (predeterminado)

Si no haces nada, OpenClaw ejecuta un solo agente:

- ''agentId'' por defecto es ''''main''''.

- Las sesiones se clavean como ''agent:main:<mainKey>''.

- El espacio de trabajo por defecto es ''~/.openclaw/workspace'' (o ''~/.openclaw/workspace-<profile>'' cuando ''OPENCLAW_PROFILE'' está configurado).

Tutorial.step

Ayudante de agente

Usa el asistente de agente para añadir un nuevo agente aislado:

Bash
openclaw agents add work

Luego añade ''bindings'' (o deja que el asistente lo haga) para enrutar mensajes entrantes.

Verifica con:

Bash
openclaw agents list --bindings
Tutorial.step

Múltiples agentes = múltiples personas, múltiples personalidades

Con ''múltiples agentes'', cada ''agentId'' se convierte en una ''persona completamente aislada'':

- ''Diferentes números de teléfono/cuentas'' (por ''accountId'' de canal).

- ''Diferentes personalidades'' (archivos de espacio de trabajo por agente como ''AGENTS.md'' y ''SOUL.md'').

- Auth + sesiones separadas (sin cruzamiento a menos que se habilite explícitamente).

Esto permite que múltiples personas compartan un servidor Gateway mientras mantienen sus "cerebros" de IA y datos aislados.

Tutorial.step

Un número de WhatsApp, múltiples personas (división DM)

Puedes enrutar ''diferentes DMs de WhatsApp'' a diferentes agentes mientras permaneces en ''una cuenta de WhatsApp''. Coincide con E.164 del remitente (como ''+15551234567'') con ''peer.kind: "dm"''. Las respuestas aún vienen del mismo número de WhatsApp (sin identidad de remitente por agente).

Detalle importante: los chats directos colapsan a la clave de sesión principal del agente, así que el aislamiento verdadero requiere un agente por persona.

Ejemplo:

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

Notas:

- El control de acceso DM es por cuenta de WhatsApp (emparejamiento/lista permitida), no por agente.

- Para grupos compartidos, enlaza el grupo a un agente o usa ''Grupos de difusión''.

Tutorial.step

Reglas de enrutamiento (cómo los mensajes eligen un agente)

Los bindings son deterministas y el más específico gana:

1. Coincidencia de ''peer'' (id exacto de DM/grupo/canal)

2. ''guildId'' (Discord)

3. ''teamId'' (Slack)

4. Coincidencia de ''accountId'' para un canal

5. Coincidencia a nivel de canal (''accountId: "*"'')

Tutorial.step

Múltiples cuentas / números de teléfono

Los canales que soportan ''múltiples cuentas'' (ej. WhatsApp) usan ''accountId'' para identificar cada inicio de sesión. Cada ''accountId'' puede enrutarse a un agente diferente, así que un servidor puede alojar múltiples números de teléfono sin mezclar sesiones.

Cada `accountId` puede enrutarse a un agente diferente, así que un servidor puede

alojar múltiples números de teléfono sin mezclar sesiones.

Tutorial.step

Conceptos

- ''agentId'': el "cerebro" (espacio de trabajo, auth por agente, almacenamiento de sesión por agente).

- ''accountId'': instancia de cuenta de canal (ej. cuenta de WhatsApp ''"personal"'' vs ''"negocio"'').

- ''binding'': enruta mensajes entrantes a un ''agentId'' via ''(channel, accountId, peer)'' y opcionalmente ids de guild/team.

- Los chats directos colapsan a ''agent:<agentId>:<mainKey>'' ("main" por agente; ''session.mainKey'').

Tutorial.step

Ejemplo: dos WhatsApps → dos agentes

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

Js
{
  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",
        },
      },
    },
  },
}
Tutorial.step

Ejemplo: WhatsApp para chat diario + Telegram para trabajo profundo

Divide por canal: enruta WhatsApp a un agente rápido cotidiano y Telegram a un agente Opus.

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

Notas:

- Si tienes múltiples cuentas para un canal, añade accountId al binding (ej. '{ channel: "whatsapp", accountId: "personal" }').

- Para enrutar un solo DM/grupo a Opus mientras mantienes el resto en chat, añade un binding ''match.peer'' para ese par; las coincidencias de par siempre ganan sobre reglas a nivel de canal.

Tutorial.step

Ejemplo: mismo canal, un par a Opus

Mantén WhatsApp en el agente rápido, pero enruta un DM a Opus:

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

Los bindings de par siempre ganan, así que colócalos encima de las reglas a nivel de canal.

Tutorial.step

Agente familiar enlazado a un grupo de WhatsApp

Enlaza un agente familiar dedicado a un solo grupo de WhatsApp, con gateo por mención y una política de herramientas más estricta:

Notas:

Json5
{
  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]" },
      },
    },
  ],
}

- Las listas de permitir/denegar herramientas son ''herramientas'', no habilidades. Si una habilidad necesita ejecutar un binario, asegúrate de que ''exec'' esté permitido y el binario exista en el sandbox.

- Para gateo más estricto, configura ''agents.list[].groupChat.mentionPatterns'' y mantén las listas permitidas de grupo habilitadas para el canal.

Asegúrate de que el binario exista, `exec` esté permitido, y el binario esté presente en el sandbox.

- Para gates más estrictos, configura `agents.list[].groupChat.mentionPatterns` y

Tutorial.step

Configuración de Sandbox y Herramientas Por Agente

A partir de v2026.1.6, cada agente puede tener su propio sandbox y restricciones de herramientas:

Js
{
  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
        },
      },
    ],
  },
}

Nota: ''setupCommand'' vive bajo ''sandbox.docker'' y se ejecuta una vez al crear el contenedor.