Skip to content

配置 🔧

OpenClaw 从 ~/.openclaw/openclaw.json 读取可选的 JSON5 配置文件(允许注释和尾随逗号)。

如果文件缺失,OpenClaw 使用相对安全的默认值(内嵌的 Pi 代理 + 按发送者的会话 + 工作空间 ~/.openclaw/workspace)。通常只需要配置来:

  • 限制谁可以触发机器人(channels.whatsapp.allowFromchannels.telegram.allowFrom 等)
  • 控制群组白名单 + 提及行为(channels.whatsapp.groupschannels.telegram.groupschannels.discord.guildsagents.list[].groupChat)
  • 自定义消息前缀(messages)
  • 设置代理的工作空间(agents.defaults.workspaceagents.list[].workspace)
  • 调整内嵌代理默认值(agents.defaults)和会话行为(session)
  • 设置每个代理的身份(agents.list[].identity)

配置新手? 查看配置示例指南,了解带详细说明的完整示例!

严格的配置验证

OpenClaw 只接受完全符合模式的配置。 未知的键、格式错误的类型或无效的值会导致网关拒绝启动以确保安全。

当验证失败时:

  • 网关不会启动。
  • 只允许诊断命令(例如:openclaw doctoropenclaw logsopenclaw healthopenclaw statusopenclaw serviceopenclaw help)。
  • 运行 openclaw doctor 查看确切的问题。
  • 运行 openclaw doctor --fix(或 --yes)应用迁移/修复。

Doctor 永远不会写入更改,除非你明确选择 --fix/--yes

模式 + UI 提示

网关通过 config.schema 公开配置的 JSON Schema 表示,供 UI 编辑器使用。 控制 UI 从此模式渲染表单,并提供 原始 JSON 编辑器作为应急方案。

频道插件和扩展可以为其配置注册模式 + UI 提示,因此频道设置 在应用程序间保持模式驱动,无需硬编码表单。

提示(标签、分组、敏感字段)与模式一起发布,因此客户端可以渲染 更好的表单,而无需硬编码配置知识。

应用 + 重启(RPC)

使用 config.apply 一步验证 + 写入完整配置并重启网关。 它会写入重启哨兵,并在网关恢复后 ping 最后活动的会话。

警告:config.apply 替换整个配置。如果你只想更改几个键, 使用 config.patchopenclaw config set。保留 ~/.openclaw/openclaw.json 的备份。

参数:

  • raw(string)— 整个配置的 JSON5 负载
  • baseHash(可选)— 来自 config.get 的配置哈希(当配置已存在时需要)
  • sessionKey(可选)— 用于唤醒 ping 的最后活动会话键
  • note(可选)— 包含在重启哨兵中的注释
  • restartDelayMs(可选)— 重启前的延迟(默认 2000)

示例(通过 gateway call):

bash
openclaw gateway call config.get --params '{}' # capture payload.hash
openclaw gateway call config.apply --params '{
  "raw": "{\\n  agents: { defaults: { workspace: \\"~/.openclaw/workspace\\" } }\\n}\\n",
  "baseHash": "<hash-from-config.get>",
  "sessionKey": "agent:main:whatsapp:dm:+15555550123",
  "restartDelayMs": 1000
}'

部分更新(RPC)

使用 config.patch 将部分更新合并到现有配置中,而不破坏 无关的键。它应用 JSON 合并补丁语义:

  • 对象递归合并
  • null 删除键
  • 数组替换 类似 config.apply,它验证、写入配置、存储重启哨兵并安排 网关重启(当提供 sessionKey 时可选唤醒)。

参数:

  • raw(string)— 仅包含要更改的键的 JSON5 负载
  • baseHash(必需)— 来自 config.get 的配置哈希
  • sessionKey(可选)— 用于唤醒 ping 的最后活动会话键
  • note(可选)— 包含在重启哨兵中的注释
  • restartDelayMs(可选)— 重启前的延迟(默认 2000)

示例:

bash
openclaw gateway call config.get --params '{}' # capture payload.hash
openclaw gateway call config.patch --params '{
  "raw": "{\\n  channels: { telegram: { groups: { \\"*\\": { requireMention: false } } } }\\n}\\n",
  "baseHash": "<hash-from-config.get>",
  "sessionKey": "agent:main:whatsapp:dm:+15555550123",
  "restartDelayMs": 1000
}'

最小配置(推荐起点)

json5
{
  agents: { defaults: { workspace: "~/.openclaw/workspace" } },
  channels: { whatsapp: { allowFrom: ["+15555550123"] } },
}

使用以下命令一次性构建默认镜像:

bash
scripts/sandbox-setup.sh

自聊模式(推荐用于群组控制)

防止机器人在群组中响应 WhatsApp @提及(仅响应特定文本触发器):

json5
{
  agents: {
    defaults: { workspace: "~/.openclaw/workspace" },
    list: [
      {
        id: "main",
        groupChat: { mentionPatterns: ["@openclaw", "reisponde"] },
      },
    ],
  },
  channels: {
    whatsapp: {
      // Allowlist is DMs only; including your own number enables self-chat mode.
      allowFrom: ["+15555550123"],
      groups: { "*": { requireMention: true } },
    },
  },
}

配置包含($include)

使用 $include 指令将配置拆分为多个文件。这适用于:

  • 组织大型配置(例如,每个客户端的代理定义)
  • 跨环境共享通用设置
  • 将敏感配置单独保存

基本用法

json5
// ~/.openclaw/openclaw.json
{
  gateway: { port: 18789 },

  // Include a single file (replaces the key's value)
  agents: { $include: "./agents.json5" },

  // Include multiple files (deep-merged in order)
  broadcast: {
    $include: ["./clients/mueller.json5", "./clients/schmidt.json5"],
  },
}
json5
// ~/.openclaw/agents.json5
{
  defaults: { sandbox: { mode: "all", scope: "session" } },
  list: [{ id: "main", workspace: "~/.openclaw/workspace" }],
}

合并行为

  • 单个文件:替换包含 $include 的对象
  • 文件数组:按顺序深度合并文件(后面的文件覆盖前面的文件)
  • 带同级键:同级键在包含后合并(覆盖包含的值)
  • 同级键 + 数组/原始值:不支持(包含的内容必须是对象)
json5
// Sibling keys override included values
{
  $include: "./base.json5", // { a: 1, b: 2 }
  b: 99, // Result: { a: 1, b: 99 }
}

嵌套包含

包含的文件本身可以包含 $include 指令(最多 10 层深):

json5
// clients/mueller.json5
{
  agents: { $include: "./mueller/agents.json5" },
  broadcast: { $include: "./mueller/broadcast.json5" },
}

路径解析

  • 相对路径:相对于包含文件解析
  • 绝对路径:按原样使用
  • 父目录:../ 引用按预期工作
json5
{ "$include": "./sub/config.json5" }      // relative
{ "$include": "/etc/openclaw/base.json5" } // absolute
{ "$include": "../shared/common.json5" }   // parent dir

错误处理

  • 缺少文件:显示已解析路径的清晰错误
  • 解析错误:显示哪个包含的文件失败
  • 循环包含:检测并报告包含链

示例:多客户端法律设置

json5
// ~/.openclaw/openclaw.json
{
  gateway: { port: 18789, auth: { token: "secret" } },

  // Common agent defaults
  agents: {
    defaults: {
      sandbox: { mode: "all", scope: "session" },
    },
    // Merge agent lists from all clients
    list: { $include: ["./clients/mueller/agents.json5", "./clients/schmidt/agents.json5"] },
  },

  // Merge broadcast configs
  broadcast: {
    $include: ["./clients/mueller/broadcast.json5", "./clients/schmidt/broadcast.json5"],
  },

  channels: { whatsapp: { groupPolicy: "allowlist" } },
}
json5
// ~/.openclaw/clients/mueller/agents.json5
[
  { id: "mueller-transcribe", workspace: "~/clients/mueller/transcribe" },
  { id: "mueller-docs", workspace: "~/clients/mueller/docs" },
]
json5
// ~/.openclaw/clients/mueller/broadcast.json5
{
  "120363403215116621@g.us": ["mueller-transcribe", "mueller-docs"],
}

常见选项

环境变量 + .env

OpenClaw 从父进程(shell、launchd/systemd、CI 等)读取环境变量。

此外,它加载:

  • 来自当前工作目录的 .env(如果存在)
  • 来自 ~/.openclaw/.env(也称为 $OPENCLAW_STATE_DIR/.env)的全局后备 .env

两个 .env 文件都不会覆盖现有的环境变量。

你也可以在配置中提供内联环境变量。这些仅在 进程环境缺少该键时应用(相同的非覆盖规则):

json5
{
  env: {
    OPENROUTER_API_KEY: "sk-or-...",
    vars: {
      GROQ_API_KEY: "gsk-...",
    },
  },
}

完整优先级和来源请参见 /environment

env.shellEnv(可选)

选择性便利:如果启用且尚未设置任何预期键,OpenClaw 运行你的登录 shell 并仅导入缺失的预期键(永不覆盖)。 这有效地导入了你的 shell 配置文件。

json5
{
  env: {
    shellEnv: {
      enabled: true,
      timeoutMs: 15000,
    },
  },
}

等效环境变量:

  • OPENCLAW_LOAD_SHELL_ENV=1
  • OPENCLAW_SHELL_ENV_TIMEOUT_MS=15000

配置中的环境变量替换

你可以使用 ${VAR_NAME} 语法直接在任何配置字符串值中引用环境变量。变量在配置加载时、验证前替换。

json5
{
  models: {
    providers: {
      "vercel-gateway": {
        apiKey: "${VERCEL_GATEWAY_API_KEY}",
      },
    },
  },
  gateway: {
    auth: {
      token: "${OPENCLAW_GATEWAY_TOKEN}",
    },
  },
}

规则:

  • 仅匹配大写的环境变量名:[A-Z_][A-Z0-9_]*
  • 缺失或空的环境变量会在配置加载时抛出错误
  • 使用 ${VAR} 转义以输出字面 ${VAR}
  • $include 配合使用(包含的文件也会被替换)

内联替换:

json5
{
  models: {
    providers: {
      custom: {
        baseUrl: "${CUSTOM_API_BASE}/v1", // → "https://api.example.com/v1"
      },
    },
  },
}

认证存储(OAuth + API 密钥)

OpenClaw 将每个代理的认证配置文件(OAuth + API 密钥)存储在:

  • <agentDir>/auth-profiles.json(默认:~/.openclaw/agents/<agentId>/agent/auth-profiles.json)

另请参阅:/concepts/oauth

传统 OAuth 导入:

  • ~/.openclaw/credentials/oauth.json(或 $OPENCLAW_STATE_DIR/credentials/oauth.json)

内嵌的 Pi 代理在以下位置维护运行时缓存:

  • <agentDir>/auth.json(自动管理;不要手动编辑)

传统代理目录(多代理前):

  • ~/.openclaw/agent/*(由 openclaw doctor 迁移到 ~/.openclaw/agents/<defaultAgentId>/agent/*)

覆盖:

  • OAuth 目录(仅传统导入):OPENCLAW_OAUTH_DIR
  • 代理目录(默认代理根覆盖):OPENCLAW_AGENT_DIR(首选)、PI_CODING_AGENT_DIR(传统)

首次使用时,OpenClaw 将 oauth.json 条目导入 auth-profiles.json

auth

认证配置文件的可选元数据。这存储机密;它将 配置文件 ID 映射到提供商 + 模式(和可选的电子邮件),并定义用于故障转移的提供商 轮换顺序。

json5
{
  auth: {
    profiles: {
      "anthropic:me@example.com": { provider: "anthropic", mode: "oauth", email: "me@example.com" },
      "anthropic:work": { provider: "anthropic", mode: "api_key" },
    },
    order: {
      anthropic: ["anthropic:me@example.com", "anthropic:work"],
    },
  },
}

agents.list[].identity

每个代理用于默认值和 UX 的可选身份。这由 macOS 入门助手写入。

如果设置,OpenClaw 派生默认值(仅当你未明确设置时):

  • 来自活动代理identity.emojimessages.ackReaction(回退到 👀)
  • 来自代理的 identity.name/identity.emojiagents.list[].groupChat.mentionPatterns(因此"@Samantha"在 Telegram/Slack/Discord/Google Chat/iMessage/WhatsApp 的群组中有效)
  • identity.avatar 接受工作空间相对图像路径或远程 URL/数据 URL。本地文件必须位于代理工作空间内。

identity.avatar 接受:

  • 工作空间相对路径(必须保持在代理工作空间内)
  • http(s) URL
  • data: URI
json5
{
  agents: {
    list: [
      {
        id: "main",
        identity: {
          name: "Samantha",
          theme: "helpful sloth",
          emoji: "🦥",
          avatar: "avatars/samantha.png",
        },
      },
    ],
  },
}

wizard

由 CLI 向导(onboardconfiguredoctor)写入的元数据。

json5
{
  wizard: {
    lastRunAt: "2026-01-01T00:00:00.000Z",
    lastRunVersion: "2026.1.4",
    lastRunCommit: "abc1234",
    lastRunCommand: "configure",
    lastRunMode: "local",
  },
}

logging

  • 默认日志文件:/tmp/openclaw/openclaw-YYYY-MM-DD.log
  • 如果需要稳定路径,将 logging.file 设置为 /tmp/openclaw/openclaw.log
  • 控制台输出可以通过以下方式单独调整:
    • logging.consoleLevel(默认为 info,当 --verbose 时提升到 debug)
    • logging.consoleStyle(pretty | compact | json)
  • 工具摘要可以编辑以避免泄露机密:
    • logging.redactSensitive(off | tools,默认:tools)
    • logging.redactPatterns(正则表达式字符串数组;覆盖默认值)
json5
{
  logging: {
    level: "info",
    file: "/tmp/openclaw/openclaw.log",
    consoleLevel: "info",
    consoleStyle: "pretty",
    redactSensitive: "tools",
    redactPatterns: [
      // Example: override defaults with your own rules.
      "\\bTOKEN\\b\\s*[=:]\\s*([\"']?)([^\\s\"']+)\\1",
      "/\\bsk-[A-Za-z0-9_-]{8,}\\b/gi",
    ],
  },
}

channels.whatsapp.dmPolicy

控制 WhatsApp 直接聊天(DM)的处理方式:

  • "pairing"(默认):未知发送者获得配对码;所有者必须批准
  • "allowlist":仅允许 channels.whatsapp.allowFrom 中的发送者(或配对允许存储)
  • "open":允许所有入站 DM(要求 channels.whatsapp.allowFrom 包含 "*")
  • "disabled":忽略所有入站 DM

配对码在 1 小时后过期;机器人仅在创建新请求时发送配对码。待处理的 DM 配对请求默认限制为每个频道 3 个

配对批准:

  • openclaw pairing list whatsapp
  • openclaw pairing approve whatsapp <code>

channels.whatsapp.allowFrom

可能触发 WhatsApp 自动回复的 E.164 电话号码白名单(仅限 DM)。 如果为空且 channels.whatsapp.dmPolicy="pairing",未知发送者将收到配对码。 对于群组,使用 channels.whatsapp.groupPolicy + channels.whatsapp.groupAllowFrom

json5
{
  channels: {
    whatsapp: {
      dmPolicy: "pairing", // pairing | allowlist | open | disabled
      allowFrom: ["+15555550123", "+447700900123"],
      textChunkLimit: 4000, // optional outbound chunk size (chars)
      chunkMode: "length", // optional chunking mode (length | newline)
      mediaMaxMb: 50, // optional inbound media cap (MB)
    },
  },
}

channels.whatsapp.sendReadReceipts

控制入站 WhatsApp 消息是否标记为已读(蓝色勾号)。默认:true

自聊模式始终跳过已读回执,即使启用时也是如此。

每个账户覆盖:channels.whatsapp.accounts.<id>.sendReadReceipts

json5
{
  channels: {
    whatsapp: { sendReadReceipts: false },
  },
}

channels.whatsapp.accounts(多账户)

在一个网关中运行多个 WhatsApp 账户:

json5
{
  channels: {
    whatsapp: {
      accounts: {
        default: {}, // optional; keeps the default id stable
        personal: {},
        biz: {
          // Optional override. Default: ~/.openclaw/credentials/whatsapp/biz
          // authDir: "~/.openclaw/credentials/whatsapp/biz",
        },
      },
    },
  },
}

注意:

  • 如果存在账户 default,出站命令默认使用该账户;否则使用第一个配置的账户 id(已排序)。
  • 传统的单账户 Baileys 认证目录由 openclaw doctor 迁移到 whatsapp/default

channels.telegram.accounts / channels.discord.accounts / channels.googlechat.accounts / channels.slack.accounts / channels.mattermost.accounts / channels.signal.accounts / channels.imessage.accounts

每个频道运行多个账户(每个账户有自己的 accountId 和可选的 name):

json5
{
  channels: {
    telegram: {
      accounts: {
        default: {
          name: "Primary bot",
          botToken: "123456:ABC...",
        },
        alerts: {
          name: "Alerts bot",
          botToken: "987654:XYZ...",
        },
      },
    },
  },
}

注意:

  • 当省略 accountId 时使用 default(CLI + 路由)。
  • 环境令牌仅适用于默认账户。
  • 基础频道设置(群组策略、提及门控等)适用于所有账户,除非每个账户覆盖。
  • 使用 bindings[].match.accountId 将每个账户路由到不同的 agents.defaults。

群聊提及门控(agents.list[].groupChat + messages.groupChat)

群组消息默认要求提及(元数据提及或正则表达式模式)。适用于 WhatsApp、Telegram、Discord、Google Chat 和 iMessage 群聊。

提及类型:

  • 元数据提及:原生平台 @提及(例如,WhatsApp 点击提及)。在 WhatsApp 自聊模式下忽略(参见 channels.whatsapp.allowFrom)。
  • 文本模式:agents.list[].groupChat.mentionPatterns 中定义的正则表达式模式。无论自聊模式如何都会检查。
  • 仅当提及检测可行时(原生提及或至少一个 mentionPattern)才强制执行提及门控。
json5
{
  messages: {
    groupChat: { historyLimit: 50 },
  },
  agents: {
    list: [{ id: "main", groupChat: { mentionPatterns: ["@openclaw", "openclaw"] } }],
  },
}

messages.groupChat.historyLimit 设置群组历史上下文的全局默认值。频道可以使用 channels.<channel>.historyLimit(或多账户的 channels.<channel>.accounts.*.historyLimit)覆盖。设置 0 以禁用历史包装。

DM 历史限制

DM 对话使用代理管理的基于会话的历史。你可以限制每个 DM 会话保留的用户轮数:

json5
{
  channels: {
    telegram: {
      dmHistoryLimit: 30, // limit DM sessions to 30 user turns
      dms: {
        "123456789": { historyLimit: 50 }, // per-user override (user ID)
      },
    },
  },
}

解析顺序:

  1. 每个 DM 覆盖:channels.<provider>.dms[userId].historyLimit
  2. 提供商默认:channels.<provider>.dmHistoryLimit
  3. 无限制(保留所有历史)

支持的提供商:telegramwhatsappdiscordslacksignalimessagemsteams

每个代理覆盖(设置时优先,即使 []):

json5
{
  agents: {
    list: [
      { id: "work", groupChat: { mentionPatterns: ["@workbot", "\\+15555550123"] } },
      { id: "personal", groupChat: { mentionPatterns: ["@homebot", "\\+15555550999"] } },
    ],
  },
}

提及门控默认值位于每个频道(channels.whatsapp.groupschannels.telegram.groupschannels.imessage.groupschannels.discord.guilds)。当设置 *.groups 时,它也充当群组白名单;包含 "*" 以允许所有群组。

仅响应特定文本触发器(忽略原生 @提及):

json5
{
  channels: {
    whatsapp: {
      // Include your own number to enable self-chat mode (ignore native @-mentions).
      allowFrom: ["+15555550123"],
      groups: { "*": { requireMention: true } },
    },
  },
  agents: {
    list: [
      {
        id: "main",
        groupChat: {
          // Only these text patterns will trigger responses
          mentionPatterns: ["reisponde", "@openclaw"],
        },
      },
    ],
  },
}

群组策略(每个频道)

使用 channels.*.groupPolicy 控制是否完全接受群组/房间消息:

json5
{
  channels: {
    whatsapp: {
      groupPolicy: "allowlist",
      groupAllowFrom: ["+15551234567"],
    },
    telegram: {
      groupPolicy: "allowlist",
      groupAllowFrom: ["tg:123456789", "@alice"],
    },
    signal: {
      groupPolicy: "allowlist",
      groupAllowFrom: ["+15551234567"],
    },
    imessage: {
      groupPolicy: "allowlist",
      groupAllowFrom: ["chat_id:123"],
    },
    msteams: {
      groupPolicy: "allowlist",
      groupAllowFrom: ["user@org.com"],
    },
    discord: {
      groupPolicy: "allowlist",
      guilds: {
        GUILD_ID: {
          channels: { help: { allow: true } },
        },
      },
    },
    slack: {
      groupPolicy: "allowlist",
      channels: { "#general": { allow: true } },
    },
  },
}

注意:

  • "open":群组绕过白名单;提及门控仍然适用。
  • "disabled":阻止所有群组/房间消息。
  • "allowlist":仅允许与配置的白名单匹配的群组/房间。
  • channels.defaults.groupPolicy 在提供商的 groupPolicy 未设置时设置默认值。
  • WhatsApp/Telegram/Signal/iMessage/Microsoft Teams 使用 groupAllowFrom(回退:显式 allowFrom)。
  • Discord/Slack 使用频道白名单(channels.discord.guilds.*.channelschannels.slack.channels)。
  • 群组 DM(Discord/Slack)仍由 dm.groupEnabled + dm.groupChannels 控制。
  • 默认为 groupPolicy: "allowlist"(除非由 channels.defaults.groupPolicy 覆盖);如果未配置白名单,则阻止群组消息。

多代理路由(agents.list + bindings)

在一个网关内运行多个隔离代理(单独的工作空间、agentDir、会话)。 入站消息通过绑定路由到代理。

  • agents.list[]:每个代理覆盖。
    • id:稳定的代理 id(必需)。
    • default:可选;当设置多个时,第一个获胜并记录警告。 如果未设置,列表中的第一个条目是默认代理。
    • name:代理的显示名称。
    • workspace:默认 ~/.openclaw/workspace-<agentId>(用于 main,回退到 agents.defaults.workspace)。
    • agentDir:默认 ~/.openclaw/agents/<agentId>/agent
    • model:每个代理的默认模型,覆盖该代理的 agents.defaults.model
      • 字符串形式:"provider/model",仅覆盖 agents.defaults.model.primary
      • 对象形式:{ primary, fallbacks }(回退覆盖 agents.defaults.model.fallbacks;[] 禁用该代理的全局回退)
    • identity:每个代理的名称/主题/表情符号(用于提及模式 + 确认反应)。
    • groupChat:每个代理的提及门控(mentionPatterns)。
    • sandbox:每个代理的沙箱配置(覆盖 agents.defaults.sandbox)。
      • mode:"off" | "non-main" | "all"
      • workspaceAccess:"none" | "ro" | "rw"
      • scope:"session" | "agent" | "shared"
      • workspaceRoot:自定义沙箱工作空间根目录
      • docker:每个代理的 docker 覆盖(例如 imagenetworkenvsetupCommand、限制;当 scope: "shared" 时忽略)
      • browser:每个代理的沙箱浏览器覆盖(当 scope: "shared" 时忽略)
      • prune:每个代理的沙箱修剪覆盖(当 scope: "shared" 时忽略)
    • subagents:每个代理的子代理默认值。
      • allowAgents:来自此代理的 sessions_spawn 的代理 id 白名单(["*"] = 允许任何;默认:仅相同代理)
    • tools:每个代理的工具限制(在沙箱工具策略之前应用)。
      • profile:基础工具配置文件(在允许/拒绝之前应用)
      • allow:允许的工具名称数组
      • deny:拒绝的工具名称数组(拒绝获胜)
  • agents.defaults:共享代理默认值(模型、工作空间、沙箱等)。
  • bindings[]:将入站消息路由到 agentId
    • match.channel(必需)
    • match.accountId(可选;* = 任何账户;省略 = 默认账户)
    • match.peer(可选;{ kind: dm|group|channel, id })
    • match.guildId / match.teamId(可选;特定于频道)

确定性匹配顺序:

  1. match.peer
  2. match.guildId
  3. match.teamId
  4. match.accountId(精确,无对等/公会/团队)
  5. match.accountId: "*"(频道范围,无对等/公会/团队)
  6. 默认代理(agents.list[].default,否则第一个列表条目,否则 "main")

在每个匹配层内,bindings 中的第一个匹配条目获胜。

每个代理的访问配置文件(多代理)

每个代理可以携带自己的沙箱 + 工具策略。使用此功能在一个网关中混合访问 级别:

  • 完全访问(个人代理)
  • 只读工具 + 工作空间
  • 无文件系统访问(仅消息/会话工具)

有关优先级和其他示例,请参见多代理沙箱和工具

完全访问(无沙箱):

json5
{
  agents: {
    list: [
      {
        id: "personal",
        workspace: "~/.openclaw/workspace-personal",
        sandbox: { mode: "off" },
      },
    ],
  },
}

只读工具 + 只读工作空间:

json5
{
  agents: {
    list: [
      {
        id: "family",
        workspace: "~/.openclaw/workspace-family",
        sandbox: {
          mode: "all",
          scope: "agent",
          workspaceAccess: "ro",
        },
        tools: {
          allow: [
            "read",
            "sessions_list",
            "sessions_history",
            "sessions_send",
            "sessions_spawn",
            "session_status",
          ],
          deny: ["write", "edit", "apply_patch", "exec", "process", "browser"],
        },
      },
    ],
  },
}

无文件系统访问(启用消息/会话工具):

json5
{
  agents: {
    list: [
      {
        id: "public",
        workspace: "~/.openclaw/workspace-public",
        sandbox: {
          mode: "all",
          scope: "agent",
          workspaceAccess: "none",
        },
        tools: {
          allow: [
            "sessions_list",
            "sessions_history",
            "sessions_send",
            "sessions_spawn",
            "session_status",
            "whatsapp",
            "telegram",
            "slack",
            "discord",
            "gateway",
          ],
          deny: [
            "read",
            "write",
            "edit",
            "apply_patch",
            "exec",
            "process",
            "browser",
            "canvas",
            "nodes",
            "cron",
            "gateway",
            "image",
          ],
        },
      },
    ],
  },
}

示例:两个 WhatsApp 账户 → 两个代理:

json5
{
  agents: {
    list: [
      { id: "home", default: true, workspace: "~/.openclaw/workspace-home" },
      { id: "work", workspace: "~/.openclaw/workspace-work" },
    ],
  },
  bindings: [
    { agentId: "home", match: { channel: "whatsapp", accountId: "personal" } },
    { agentId: "work", match: { channel: "whatsapp", accountId: "biz" } },
  ],
  channels: {
    whatsapp: {
      accounts: {
        personal: {},
        biz: {},
      },
    },
  },
}

tools.agentToAgent(可选)

代理间消息传递是选择性的:

json5
{
  tools: {
    agentToAgent: {
      enabled: false,
      allow: ["home", "work"],
    },
  },
}

messages.queue

控制当代理运行已激活时入站消息的行为方式。

json5
{
  messages: {
    queue: {
      mode: "collect", // steer | followup | collect | steer-backlog (steer+backlog ok) | interrupt (queue=steer legacy)
      debounceMs: 1000,
      cap: 20,
      drop: "summarize", // old | new | summarize
      byChannel: {
        whatsapp: "collect",
        telegram: "collect",
        discord: "collect",
        imessage: "collect",
        webchat: "collect",
      },
    },
  },
}

messages.inbound

对来自同一发送者的快速入站消息进行防抖,使多个连续 消息成为单个代理轮。防抖的作用域为每个频道 + 对话, 并使用最新消息进行回复线程/ID。

json5
{
  messages: {
    inbound: {
      debounceMs: 2000, // 0 disables
      byChannel: {
        whatsapp: 5000,
        slack: 1500,
        discord: 1500,
      },
    },
  },
}

注意:

  • 防抖批处理纯文本消息;媒体/附件立即刷新。
  • 控制命令(例如 /queue/new)绕过防抖,因此它们保持独立。

commands(聊天命令处理)

控制如何在连接器中启用聊天命令。

json5
{
  commands: {
    native: "auto", // register native commands when supported (auto)
    text: true, // parse slash commands in chat messages
    bash: false, // allow ! (alias: /bash) (host-only; requires tools.elevated allowlists)
    bashForegroundMs: 2000, // bash foreground window (0 backgrounds immediately)
    config: false, // allow /config (writes to disk)
    debug: false, // allow /debug (runtime-only overrides)
    restart: false, // allow /restart + gateway restart tool
    useAccessGroups: true, // enforce access-group allowlists/policies for commands
  },
}

注意:

  • 文本命令必须作为独立消息发送,并使用前导 /(无纯文本别名)。
  • commands.text: false 禁用解析聊天消息以获取命令。
  • commands.native: "auto"(默认)为 Discord/Telegram 启用原生命令,并保持 Slack 关闭;不支持的频道保持纯文本。
  • 设置 commands.native: true|false 以强制全部,或使用 channels.discord.commands.nativechannels.telegram.commands.nativechannels.slack.commands.native(布尔值或 "auto")按频道覆盖。false 在启动时清除 Discord/Telegram 上先前注册的命令;Slack 命令在 Slack 应用中管理。
  • channels.telegram.customCommands 添加额外的 Telegram 机器人菜单条目。名称已规范化;与原生命令的冲突将被忽略。
  • commands.bash: true 启用 ! <cmd> 以运行主机 shell 命令(/bash <cmd> 也可作为别名)。需要 tools.elevated.enabled 并在 tools.elevated.allowFrom.<channel> 中将发送者列入白名单。
  • commands.bashForegroundMs 控制 bash 在后台运行之前等待多长时间。当 bash 作业运行时,新的 ! <cmd> 请求将被拒绝(一次一个)。
  • commands.config: true 启用 /config(读取/写入 openclaw.json)。
  • channels.<provider>.configWrites 门控由该频道发起的配置突变(默认:true)。这适用于 /config set|unset 以及提供商特定的自动迁移(Telegram 超级群组 ID 更改、Slack 频道 ID 更改)。
  • commands.debug: true 启用 /debug(仅运行时覆盖)。
  • commands.restart: true 启用 /restart 和网关工具重启操作。
  • commands.useAccessGroups: false 允许命令绕过访问组白名单/策略。
  • 斜杠命令和指令仅对授权发送者有效。授权来自 频道白名单/配对加上 commands.useAccessGroups

web(WhatsApp Web 频道运行时)

WhatsApp 通过网关的 Web 频道(Baileys Web)运行。当存在链接会话时自动启动。 设置 web.enabled: false 以默认保持关闭。

json5
{
  web: {
    enabled: true,
    heartbeatSeconds: 60,
    reconnect: {
      initialMs: 2000,
      maxMs: 120000,
      factor: 1.4,
      jitter: 0.2,
      maxAttempts: 0,
    },
  },
}

channels.telegram(机器人传输)

OpenClaw 仅在存在 channels.telegram 配置部分时启动 Telegram。机器人令牌从 channels.telegram.botToken(或 channels.telegram.tokenFile)解析,默认账户的回退为 TELEGRAM_BOT_TOKEN。 设置 channels.telegram.enabled: false 以禁用自动启动。 多账户支持位于 channels.telegram.accounts 下(参见上面的多账户部分)。环境令牌仅适用于默认账户。 设置 channels.telegram.configWrites: false 以阻止 Telegram 发起的配置写入(包括超级群组 ID 迁移和 /config set|unset)。

json5
{
  channels: {
    telegram: {
      enabled: true,
      botToken: "your-bot-token",
      dmPolicy: "pairing", // pairing | allowlist | open | disabled
      allowFrom: ["tg:123456789"], // optional; "open" requires ["*"]
      groups: {
        "*": { requireMention: true },
        "-1001234567890": {
          allowFrom: ["@admin"],
          systemPrompt: "Keep answers brief.",
          topics: {
            "99": {
              requireMention: false,
              skills: ["search"],
              systemPrompt: "Stay on topic.",
            },
          },
        },
      },
      customCommands: [
        { command: "backup", description: "Git backup" },
        { command: "generate", description: "Create an image" },
      ],
      historyLimit: 50, // include last N group messages as context (0 disables)
      replyToMode: "first", // off | first | all
      linkPreview: true, // toggle outbound link previews
      streamMode: "partial", // off | partial | block (draft streaming; separate from block streaming)
      draftChunk: {
        // optional; only for streamMode=block
        minChars: 200,
        maxChars: 800,
        breakPreference: "paragraph", // paragraph | newline | sentence
      },
      actions: { reactions: true, sendMessage: true }, // tool action gates (false disables)
      reactionNotifications: "own", // off | own | all
      mediaMaxMb: 5,
      retry: {
        // outbound retry policy
        attempts: 3,
        minDelayMs: 400,
        maxDelayMs: 30000,
        jitter: 0.1,
      },
      network: {
        // transport overrides
        autoSelectFamily: false,
      },
      proxy: "socks5://localhost:9050",
      webhookUrl: "https://example.com/telegram-webhook", // requires webhookSecret
      webhookSecret: "secret",
      webhookPath: "/telegram-webhook",
    },
  },
}

草稿流式传输注意事项:

  • 使用 Telegram sendMessageDraft(草稿气泡,而不是真实消息)。
  • 需要私聊主题(DM 中的 message_thread_id;机器人已启用主题)。
  • /reasoning stream 将推理流式传输到草稿中,然后发送最终答案。 重试策略默认值和行为记录在重试策略中。

channels.discord(机器人传输)

通过设置机器人令牌和可选门控来配置 Discord 机器人: 多账户支持位于 channels.discord.accounts 下(参见上面的多账户部分)。环境令牌仅适用于默认账户。

json5
{
  channels: {
    discord: {
      enabled: true,
      token: "your-bot-token",
      mediaMaxMb: 8, // clamp inbound media size
      allowBots: false, // allow bot-authored messages
      actions: {
        // tool action gates (false disables)
        reactions: true,
        stickers: true,
        polls: true,
        permissions: true,
        messages: true,
        threads: true,
        pins: true,
        search: true,
        memberInfo: true,
        roleInfo: true,
        roles: false,
        channelInfo: true,
        voiceStatus: true,
        events: true,
        moderation: false,
      },
      replyToMode: "off", // off | first | all
      dm: {
        enabled: true, // disable all DMs when false
        policy: "pairing", // pairing | allowlist | open | disabled
        allowFrom: ["1234567890", "steipete"], // optional DM allowlist ("open" requires ["*"])
        groupEnabled: false, // enable group DMs
        groupChannels: ["openclaw-dm"], // optional group DM allowlist
      },
      guilds: {
        "123456789012345678": {
          // guild id (preferred) or slug
          slug: "friends-of-openclaw",
          requireMention: false, // per-guild default
          reactionNotifications: "own", // off | own | all | allowlist
          users: ["987654321098765432"], // optional per-guild user allowlist
          channels: {
            general: { allow: true },
            help: {
              allow: true,
              requireMention: true,
              users: ["987654321098765432"],
              skills: ["docs"],
              systemPrompt: "Short answers only.",
            },
          },
        },
      },
      historyLimit: 20, // include last N guild messages as context
      textChunkLimit: 2000, // optional outbound text chunk size (chars)
      chunkMode: "length", // optional chunking mode (length | newline)
      maxLinesPerMessage: 17, // soft max lines per message (Discord UI clipping)
      retry: {
        // outbound retry policy
        attempts: 3,
        minDelayMs: 500,
        maxDelayMs: 30000,
        jitter: 0.1,
      },
    },
  },
}

OpenClaw 仅在存在 channels.discord 配置部分时启动 Discord。令牌从 channels.discord.token 解析,默认账户的回退为 DISCORD_BOT_TOKEN(除非 channels.discord.enabledfalse)。在为 cron/CLI 命令指定发送目标时,使用 user:<id>(DM)或 channel:<id>(公会频道);纯数字 ID 是模糊的,会被拒绝。 公会 slug 是小写的,空格替换为 -;频道键使用 slug 化的频道名称(无前导 #)。首选公会 id 作为键以避免重命名歧义。 机器人发送的消息默认被忽略。使用 channels.discord.allowBots 启用(自身消息仍会被过滤以防止自我回复循环)。 反应通知模式:

  • off:无反应事件。
  • own:机器人自身消息上的反应(默认)。
  • all:所有消息上的所有反应。
  • allowlist:guilds.<id>.users 中用户在所有消息上的反应(空列表禁用)。 出站文本按 channels.discord.textChunkLimit(默认 2000)分块。设置 channels.discord.chunkMode="newline" 以在空行(段落边界)处分割,然后再进行长度分块。Discord 客户端可能会裁剪非常高的消息,因此 channels.discord.maxLinesPerMessage(默认 17)会分割长的多行回复,即使在 2000 字符以下。 重试策略默认值和行为记录在重试策略中。