Multi-agent
Trasowanie wieloagentowe
Uruchamiaj wielu izolowanych agentów w jednym procesie Gateway, z których każdy ma własny obszar roboczy, katalog stanu (agentDir) i historię sesji opartą na SQLite, a także wiele kont kanałów (np. dwa numery WhatsApp). Wiadomości przychodzące są kierowane do właściwego agenta za pomocą powiązań.
Agent obejmuje pełny zakres przypisany do persony: pliki obszaru roboczego, profile uwierzytelniania, rejestr modeli i magazyn sesji. Powiązanie przypisuje konto kanału (obszar roboczy Slack, numer WhatsApp itp.) do jednego z tych agentów.
Czym jest jeden agent
Każdy agent ma własne:
- Obszar roboczy: pliki,
AGENTS.md/SOUL.md/USER.md, lokalne notatki, reguły persony. - Katalog stanu (
agentDir): profile uwierzytelniania, rejestr modeli, konfiguracja agenta. - Magazyn sesji: historia czatów i stan routingu w
~/.openclaw/agents/<agentId>/agent/openclaw-agent.sqlite.
Profile uwierzytelniania są przypisane do poszczególnych agentów i odczytywane z:
~/.openclaw/agents/<agentId>/agent/auth-profiles.jsonSkills są ładowane z obszaru roboczego każdego agenta oraz ze współdzielonych katalogów głównych, takich jak ~/.openclaw/skills, a następnie filtrowane według obowiązującej listy dozwolonych Skills agenta. Użyj agents.defaults.skills jako współdzielonej konfiguracji bazowej, a agents.list[].skills jako zamiennika dla konkretnego agenta (jawne wpisy zastępują wartości domyślne, a nie są z nimi scalane). Zobacz Skills: przypisane do agenta a współdzielone oraz Skills: listy dozwolone dla agentów.
Magazyn należący do Pluginu podlega konfiguracji tego Pluginu; dodanie drugiego agenta nie powoduje automatycznego rozdzielenia wszystkich globalnych magazynów Pluginów. Na przykład należy skonfigurować sejfy Memory Wiki dla poszczególnych agentów, gdy persony nie mogą współdzielić skompilowanej wiedzy wiki.
Ścieżki
| Element | Wartość domyślna | Nadpisanie |
|---|---|---|
| Konfiguracja | ~/.openclaw/openclaw.json |
OPENCLAW_CONFIG_PATH |
| Katalog stanu | ~/.openclaw |
OPENCLAW_STATE_DIR |
| Obszar roboczy domyślnego agenta | ~/.openclaw/workspace (lub workspace-<profile>, gdy ustawiono OPENCLAW_PROFILE) |
agents.list[].workspace, następnie agents.defaults.workspace albo OPENCLAW_WORKSPACE_DIR |
| Obszar roboczy innych agentów | <stateDir>/workspace-<agentId> (lub <agents.defaults.workspace>/<agentId>, gdy ustawiono) |
agents.list[].workspace |
| Katalog agenta | ~/.openclaw/agents/<agentId>/agent |
agents.list[].agentDir |
| Sesje i transkrypty | ~/.openclaw/agents/<agentId>/agent/openclaw-agent.sqlite |
— |
| Starsze/archiwalne artefakty sesji | ~/.openclaw/agents/<agentId>/sessions |
— |
Tryb jednego agenta (domyślny)
Jeśli niczego nie skonfigurujesz, OpenClaw uruchamia jednego agenta:
agentIdma domyślnie wartośćmain.- Kluczem sesji jest
agent:main:<mainKey>(domyślną wartościąmainKeyjestmain). - Domyślnym obszarem roboczym jest
~/.openclaw/workspace(lubworkspace-<profile>, gdyOPENCLAW_PROFILEma wartość inną niżdefault). - Domyślnym katalogiem stanu jest
~/.openclaw/agents/main/agent.
Narzędzie pomocnicze agenta
Dodaj nowego izolowanego agenta:
openclaw agents add workFlagi: --workspace <dir>, --model <id>, --agent-dir <dir>, --bind <channel[:accountId]> (można powtarzać), --non-interactive (wymaga --workspace).
Dodaj bindings, aby kierować wiadomości przychodzące (kreator zaproponuje wykonanie tej czynności), a następnie zweryfikuj konfigurację:
openclaw agents list --bindingsSzybki start
Utwórz obszar roboczy każdego agenta
openclaw agents add codingopenclaw agents add socialKażdy agent otrzymuje własny obszar roboczy z plikami SOUL.md, AGENTS.md i opcjonalnym USER.md, a także dedykowany agentDir oraz magazyn sesji w ~/.openclaw/agents/<agentId>.
Utwórz konta kanałów
Utwórz po jednym koncie dla każdego agenta w preferowanych kanałach:
- Discord: jeden bot na agenta, włącz Message Content Intent i skopiuj każdy token.
- Telegram: jeden bot na agenta utworzony przez BotFather; skopiuj każdy token.
- WhatsApp: połącz każdy numer telefonu z odpowiednim kontem.
openclaw channels login --channel whatsapp --account workZobacz przewodniki po kanałach: Discord, Telegram, WhatsApp.
Dodaj agentów, konta i powiązania
Dodaj agentów w agents.list, konta kanałów w channels.<channel>.accounts i połącz je za pomocą bindings (przykłady poniżej).
Uruchom ponownie i zweryfikuj
openclaw gateway restartopenclaw agents list --bindingsopenclaw channels status --probeWielu agentów, wiele person
Każdy skonfigurowany agentId stanowi odrębną granicę persony dla podstawowego stanu agenta:
- Różne konta w poszczególnych kanałach (według
accountId). - Różne osobowości (pliki
AGENTS.md/SOUL.mdposzczególnych agentów). - Oddzielne uwierzytelnianie i sesje, przy czym dostęp między agentami jest włączany wyłącznie za pomocą jawnych funkcji lub konfiguracji Pluginu.
Dzięki temu wiele osób może współdzielić jeden Gateway, zachowując rozdzielenie podstawowego stanu agentów.
Sejfy Memory Wiki dla poszczególnych agentów
Memory Wiki domyślnie używa jednego globalnego sejfu. Aby skompilowana
wiedza agenta pomocy technicznej była oddzielona od wiedzy agenta marketingowego, ustaw
plugins.entries.memory-wiki.config.vault.scope na agent:
{ plugins: { entries: { "memory-wiki": { enabled: true, config: { vault: { scope: "agent", path: "~/.openclaw/wiki", }, }, }, }, },}Skonfigurowana ścieżka jest katalogiem nadrzędnym. OpenClaw dołącza znormalizowany
identyfikator agenta, tworząc ścieżki takie jak ~/.openclaw/wiki/support i
~/.openclaw/wiki/marketing. Operacje CLI i Gateway o zakresie agenta wymagają
jawnego wskazania agenta, gdy skonfigurowano wielu agentów. Szczegółowe informacje o
filtrowaniu mostka, migracji i granicach zaufania zawiera sekcja
Sejfy Memory Wiki dla poszczególnych agentów.
Wyszukiwanie pamięci QMD między agentami
Aby umożliwić jednemu agentowi przeszukiwanie transkryptów sesji QMD innego agenta, dodaj dodatkowe kolekcje w agents.list[].memorySearch.qmd.extraCollections. Użyj agents.defaults.memorySearch.qmd.extraCollections, gdy każdy agent powinien współdzielić te same kolekcje.
{ 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" }], // rozwiązywana wewnątrz obszaru roboczego -> kolekcja o nazwie "notes-main" }, }, }, { id: "family", workspace: "~/workspaces/family" }, ], }, memory: { backend: "qmd", qmd: { includeDefaultMemory: false }, },}Ścieżka dodatkowej kolekcji może być współdzielona przez agentów, ale jej name pozostaje jawnie określona, gdy ścieżka znajduje się poza obszarem roboczym agenta. Ścieżki wewnątrz obszaru roboczego zachowują zakres agenta, dzięki czemu każdy agent ma własny zestaw przeszukiwanych transkryptów.
Jeden numer WhatsApp, wiele osób (podział wiadomości prywatnych)
Kieruj wiadomości prywatne WhatsApp od różnych osób do różnych agentów na jednym koncie WhatsApp, dopasowując nadawcę E.164 (+15551234567) za pomocą peer.kind: "direct". Odpowiedzi nadal pochodzą z tego samego numeru WhatsApp — nie ma oddzielnej tożsamości nadawcy dla każdego agenta.
{ 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"], }, },}Kontrola dostępu do wiadomości prywatnych (parowanie/lista dozwolonych) jest globalna dla konta WhatsApp, a nie przypisana do agenta. W przypadku współdzielonych grup powiąż grupę z jednym agentem lub użyj grup rozgłoszeniowych.
Reguły routingu
Powiązania są deterministyczne, a najbardziej szczegółowe dopasowanie ma pierwszeństwo. Pełną kolejność poziomów (dokładny uczestnik, uczestnik nadrzędny, symbol wieloznaczny uczestnika, serwer+role, serwer, zespół, konto, kanał, domyślny agent) opisano w sekcji Routing kanałów. Warto podkreślić kilka reguł:
- Jeśli na tym samym poziomie pasuje wiele powiązań, pierwszeństwo ma pierwsze z nich w kolejności konfiguracji.
- Jeśli powiązanie określa wiele pól dopasowania (na przykład
peer+guildId), wszystkie wskazane pola muszą być zgodne (semantykaAND). - Powiązanie bez
accountIdpasuje wyłącznie do konta domyślnego, a nie do każdego konta. UżyjaccountId: "*"jako rezerwowego dopasowania dla całego kanału lubaccountId: "<name>"dla jednego konta. Ponowne dodanie tego samego powiązania z jawnym identyfikatorem konta aktualizuje istniejące powiązanie obejmujące tylko kanał, zamiast je duplikować.
Wiele kont / numerów telefonów
Kanały obsługujące wiele kont (np. WhatsApp) używają accountId do identyfikowania każdego logowania. Każdy accountId kieruje ruch do własnego agenta, dzięki czemu jeden serwer może obsługiwać wiele numerów telefonów bez mieszania sesji.
Ustaw channels.<channel>.defaultAccount, aby wybrać konto używane w przypadku pominięcia accountId. Jeśli ta wartość nie jest ustawiona, OpenClaw używa default, o ile jest dostępne, a w przeciwnym razie pierwszego identyfikatora skonfigurowanego konta (po posortowaniu).
Kanały obsługujące wiele kont: discord, feishu, googlechat, imessage, irc, line, mattermost, matrix, nextcloud-talk, nostr, signal, slack, telegram, whatsapp, zalo, zalouser.
Pojęcia
agentId: jeden „mózg” (obszar roboczy, uwierzytelnianie osobne dla każdego agenta, magazyn sesji osobny dla każdego agenta).accountId: jedna instancja konta kanału (np. konto WhatsApppersonalw odróżnieniu odbiz).binding: kieruje wiadomości przychodzące doagentIdwedług(channel, accountId, peer)oraz opcjonalnie identyfikatorów gildii/zespołu.- Czaty bezpośrednie są łączone w
agent:<agentId>:<mainKey>(„główną” sesję danego agenta; zob.session.mainKey).
Przykłady dla platform
Boty Discord dla poszczególnych agentów
Każde konto bota Discord jest mapowane na unikatowy accountId. Powiąż każde konto z agentem i utrzymuj osobne listy dozwolonych dla każdego bota.
{ 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 }, }, }, }, }, }, }, },}- Zaproś każdego bota do gildii i włącz Message Content Intent.
- Tokeny znajdują się w
channels.discord.accounts.<id>.token(konto domyślne może używaćDISCORD_BOT_TOKEN).
Boty Telegram dla poszczególnych agentów
{ 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"], }, }, }, },}- Utwórz po jednym bocie dla każdego agenta za pomocą BotFather i skopiuj każdy token.
- Tokeny znajdują się w
channels.telegram.accounts.<id>.botToken(konto domyślne może używaćTELEGRAM_BOT_TOKEN). - W przypadku wielu botów w tej samej grupie Telegram zaproś każdego bota i oznacz tego, który powinien odpowiedzieć.
- Wyłącz BotFather Privacy Mode dla każdego bota grupowego (
/setprivacy-> Disable), a następnie usuń i ponownie dodaj bota, aby Telegram zastosował ustawienie. - Zezwalaj na grupy za pomocą
channels.telegram.groupslub używajgroupPolicy: "open"wyłącznie we wdrożeniach z zaufanymi grupami. - Umieść identyfikatory użytkowników będących nadawcami w
groupAllowFrom. Identyfikatory grup i supergrup należy umieszczać wchannels.telegram.groups, a nie wgroupAllowFrom. - Powiąż według
accountId, aby każdy bot kierował wiadomości do własnego agenta.
Numery WhatsApp dla poszczególnych agentów
Połącz każde konto przed uruchomieniem 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", }, ], }, // Deterministyczne trasowanie: wygrywa pierwsze dopasowanie (najpierw najbardziej szczegółowe). bindings: [ { agentId: "home", match: { channel: "whatsapp", accountId: "personal" } }, { agentId: "work", match: { channel: "whatsapp", accountId: "biz" } }, // Opcjonalne nadpisanie dla konkretnego elementu równorzędnego (przykład: skierowanie określonej grupy do agenta służbowego). { agentId: "work", match: { channel: "whatsapp", accountId: "personal", peer: { kind: "group", id: "1203630...@g.us" }, }, }, ], // Domyślnie wyłączone: komunikację między agentami trzeba jawnie włączyć i dodać do listy dozwolonych. tools: { agentToAgent: { enabled: false, allow: ["home", "work"], }, }, channels: { whatsapp: { accounts: { personal: { // Opcjonalne nadpisanie. Wartość domyślna: ~/.openclaw/credentials/whatsapp/personal // authDir: "~/.openclaw/credentials/whatsapp/personal", }, biz: { // Opcjonalne nadpisanie. Wartość domyślna: ~/.openclaw/credentials/whatsapp/biz // authDir: "~/.openclaw/credentials/whatsapp/biz", }, }, }, },}Typowe wzorce
WhatsApp na co dzień i Telegram do intensywnej pracy
Rozdziel według kanału: kieruj WhatsApp do szybkiego agenta codziennego użytku, a Telegram do agenta 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: "*" } }, ],}W tych przykładach użyto accountId: "*", dzięki czemu powiązania będą nadal działać po późniejszym dodaniu kont. Aby skierować pojedynczą wiadomość bezpośrednią lub grupę do Opus, pozostawiając resztę na czacie, dodaj powiązanie match.peer dla tego elementu równorzędnego — dopasowania elementów równorzędnych zawsze mają pierwszeństwo przed regułami obejmującymi cały kanał.
Ten sam kanał, jeden element równorzędny kierowany do Opus
Pozostaw WhatsApp na szybkim agencie, ale skieruj jedną wiadomość bezpośrednią do 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: "*" } }, ],}Powiązania elementów równorzędnych zawsze mają pierwszeństwo, dlatego umieszczaj je nad regułą obejmującą cały kanał.
Agent rodzinny powiązany z grupą WhatsApp
Powiąż dedykowanego agenta rodzinnego z pojedynczą grupą WhatsApp, wymagając oznaczenia i stosując bardziej restrykcyjną politykę narzędzi:
{ 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" }, }, }, ],}Listy dozwolonych i zabronionych narzędzi dotyczą narzędzi, a nie umiejętności. Jeśli umiejętność musi uruchamiać plik binarny, upewnij się, że exec jest dozwolone, a plik binarny istnieje w piaskownicy. Aby zastosować bardziej restrykcyjną kontrolę dostępu, ustaw agents.list[].groupChat.mentionPatterns i pozostaw włączone listy dozwolonych grup dla kanału.
Konfiguracja piaskownicy i narzędzi dla poszczególnych agentów
Każdy agent może mieć własną piaskownicę i ograniczenia narzędzi:
{ agents: { list: [ { id: "personal", workspace: "~/.openclaw/workspace-personal", sandbox: { mode: "off", // Brak piaskownicy dla agenta osobistego }, // Brak ograniczeń narzędzi — dostępne są wszystkie narzędzia }, { id: "family", workspace: "~/.openclaw/workspace-family", sandbox: { mode: "all", // Zawsze w piaskownicy scope: "agent", // Jeden kontener na agenta docker: { // Opcjonalna jednorazowa konfiguracja po utworzeniu kontenera setupCommand: "apt-get update && apt-get install -y git curl", }, }, tools: { allow: ["read"], // Tylko narzędzie do odczytu deny: ["exec", "write", "edit", "apply_patch"], // Zablokuj pozostałe }, }, ], },}Zapewnia to:
- Izolację zabezpieczeń: ograniczenie narzędzi dla niezaufanych agentów.
- Kontrolę zasobów: uruchamianie określonych agentów w piaskownicy przy zachowaniu pozostałych na hoście.
- Elastyczne polityki: różne uprawnienia dla poszczególnych agentów.
Szczegółowe przykłady zawiera strona Piaskownica i narzędzia w konfiguracji wieloagentowej.
Powiązane
- Agenci ACP — uruchamianie zewnętrznych środowisk programistycznych
- Routing kanałów — sposób kierowania wiadomości do agentów
- Obecność — obecność i dostępność agentów
- Sesja — izolacja i routing sesji
- Podagenci — uruchamianie agentów w tle