配置 🔧
OpenClaw 会读取一个可选的 JSON5 配置文件 ~/.openclaw/openclaw.json(支持注释和尾随逗号)。
如果文件不存在,OpenClaw 会使用相对安全的默认值(内嵌 Pi agent + 按发送者分 session + workspace ~/.openclaw/workspace)。你通常只需要配置文件来:
- 限制谁可以触发机器人(
channels.whatsapp.allowFrom、channels.telegram.allowFrom等) - 控制群组白名单和提及行为(
channels.whatsapp.groups、channels.telegram.groups、channels.discord.guilds、agents.list[].groupChat) - 自定义消息前缀(
messages) - 设置 agent 的 workspace(
agents.defaults.workspace或agents.list[].workspace) - 调整内嵌 agent 默认值(
agents.defaults)和 session 行为(session) - 设置每个 agent 的身份(
agents.list[].identity)
刚接触配置? 查看 配置示例 指南,里面有完整示例和详细说明!
严格的配置验证
OpenClaw 只接受完全符合 schema 的配置。 未知的键、错误的类型或无效的值会导致 Gateway 拒绝启动,以确保安全。
当验证失败时:
- Gateway 不会启动
- 只允许诊断命令(例如:
openclaw doctor、openclaw logs、openclaw health、openclaw status、openclaw service、openclaw help) - 运行
openclaw doctor查看具体问题 - 运行
openclaw doctor --fix(或--yes)应用迁移/修复
Doctor 不会写入任何更改,除非你明确选择 --fix/--yes。
Schema + UI 提示
Gateway 通过 config.schema 暴露配置的 JSON Schema 表示,供 UI 编辑器使用。
Control UI 会根据这个 schema 渲染表单,并提供 Raw JSON 编辑器作为备用方案。
Channel 插件和扩展可以为它们的配置注册 schema + UI 提示,这样 channel 设置就能在各个应用中保持 schema 驱动,而不需要硬编码表单。
提示(标签、分组、敏感字段)会随 schema 一起提供,这样客户端就能渲染更好的表单,而不需要硬编码配置知识。
Apply + restart (RPC)
使用 config.apply 一步完成验证、写入完整配置并重启 Gateway。
它会写入一个重启标记,并在 Gateway 恢复后 ping 最后活跃的 session。
警告:config.apply 会替换整个配置。如果你只想改几个键,用 config.patch 或 openclaw config set。记得备份 ~/.openclaw/openclaw.json。
参数:
raw(string)— 整个配置的 JSON5 内容baseHash(可选)— 从config.get获取的配置哈希(当配置已存在时必需)sessionKey(可选)— 用于唤醒 ping 的最后活跃 session keynote(可选)— 包含在重启标记中的备注restartDelayMs(可选)— 重启前的延迟(默认 2000)
示例(通过 gateway call):
openclaw gateway call config.get --params '{}' # 获取 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 merge patch 语义:
- 对象递归合并
null删除一个键- 数组替换
和 config.apply 一样,它会验证、写入配置、存储重启标记,并安排 Gateway 重启(当提供 sessionKey 时可选唤醒)。
参数:
raw(string)— 只包含要更改的键的 JSON5 内容baseHash(必需)— 从config.get获取的配置哈希sessionKey(可选)— 用于唤醒 ping 的最后活跃 session keynote(可选)— 包含在重启标记中的备注restartDelayMs(可选)— 重启前的延迟(默认 2000)
示例:
openclaw gateway call config.get --params '{}' # 获取 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
}'
最小配置(推荐起点)
{
agents: { defaults: { workspace: "~/.openclaw/workspace" } },
channels: { whatsapp: { allowFrom: ["+15555550123"] } },
}
用以下命令构建默认镜像一次:
scripts/sandbox-setup.sh
自聊模式(推荐用于群组控制)
要防止机器人响应 WhatsApp 群组中的 @-提及(只响应特定文本触发器):
{
agents: {
defaults: { workspace: "~/.openclaw/workspace" },
list: [
{
id: "main",
groupChat: { mentionPatterns: ["@openclaw", "reisponde"] },
},
],
},
channels: {
whatsapp: {
// 白名单只包含 DM;包含你自己的号码会启用自聊模式
allowFrom: ["+15555550123"],
groups: { "*": { requireMention: true } },
},
},
}
配置包含($include)
使用 $include 指令将配置拆分到多个文件。这对以下场景很有用:
- 组织大型配置(例如,按客户的 agent 定义)
- 跨环境共享通用设置
- 将敏感配置分开
基本用法
// ~/.openclaw/openclaw.json
{
gateway: { port: 18789 },
// 包含单个文件(替换键的值)
agents: { $include: "./agents.json5" },
// 包含多个文件(按顺序深度合并)
broadcast: {
$include: ["./clients/mueller.json5", "./clients/schmidt.json5"],
},
}
// ~/.openclaw/agents.json5
{
defaults: { sandbox: { mode: "all", scope: "session" } },
list: [{ id: "main", workspace: "~/.openclaw/workspace" }],
}
合并行为
- 单个文件:替换包含
$include的对象 - 文件数组:按顺序深度合并文件(后面的文件覆盖前面的)
- 带兄弟键:兄弟键在包含后合并(覆盖包含的值)
- 兄弟键 + 数组/原始值:不支持(包含的内容必须是对象)
// 兄弟键覆盖包含的值
{
$include: "./base.json5", // { a: 1, b: 2 }
b: 99, // 结果:{ a: 1, b: 99 }
}
嵌套包含
包含的文件本身可以包含 $include 指令(最多 10 层深):
// clients/mueller.json5
{
agents: { $include: "./mueller/agents.json5" },
broadcast: { $include: "./mueller/broadcast.json5" },
}
路径解析
- 相对路径:相对于包含文件解析
- 绝对路径:按原样使用
- 父目录:
../引用按预期工作
{ "$include": "./sub/config.json5" } // 相对
{ "$include": "/etc/openclaw/base.json5" } // 绝对
{ "$include": "../shared/common.json5" } // 父目录
错误处理
- 文件缺失:清晰的错误信息,包含解析后的路径
- 解析错误:显示哪个包含的文件失败
- 循环包含:检测并报告包含链
示例:多客户法律设置
// ~/.openclaw/openclaw.json
{
gateway: { port: 18789, auth: { token: "secret" } },
// 通用 agent 默认值
agents: {
defaults: {
sandbox: { mode: "all", scope: "session" },
},
// 合并所有客户的 agent 列表
list: { $include: ["./clients/mueller/agents.json5", "./clients/schmidt/agents.json5"] },
},
// 合并广播配置
broadcast: {
$include: ["./clients/mueller/broadcast.json5", "./clients/schmidt/broadcast.json5"],
},
channels: { whatsapp: { groupPolicy: "allowlist" } },
}
// ~/.openclaw/clients/mueller/agents.json5
[
{ id: "mueller-transcribe", workspace: "~/clients/mueller/transcribe" },
{ id: "mueller-docs", workspace: "~/clients/mueller/docs" },
]
// ~/.openclaw/clients/mueller/broadcast.json5
{
"[email protected]": ["mueller-transcribe", "mueller-docs"],
}
常用选项
环境变量 + .env
OpenClaw 从父进程(shell、launchd/systemd、CI 等)读取环境变量。
此外,它还会加载:
- 当前工作目录中的
.env(如果存在) ~/.openclaw/.env的全局后备.env(即$OPENCLAW_STATE_DIR/.env)
这两个 .env 文件都不会覆盖现有的环境变量。
你也可以在配置中提供内联环境变量。这些变量只在进程环境中缺少该键时才应用(相同的非覆盖规则):
{
env: {
OPENROUTER_API_KEY: "sk-or-...",
vars: {
GROQ_API_KEY: "gsk-...",
},
},
}
查看 /environment 了解完整的优先级和来源。
env.shellEnv(可选)
选择性便利功能:如果启用且预期的键都未设置,OpenClaw 会运行你的登录 shell 并只导入缺失的预期键(永不覆盖)。 这实际上会 source 你的 shell 配置文件。
{
env: {
shellEnv: {
enabled: true,
timeoutMs: 15000,
},
},
}
环境变量等效:
OPENCLAW_LOAD_SHELL_ENV=1OPENCLAW_SHELL_ENV_TIMEOUT_MS=15000
配置中的环境变量替换
你可以使用 ${VAR_NAME} 语法在任何配置字符串值中直接引用环境变量。变量在配置加载时、验证前被替换。
{
models: {
providers: {
"vercel-gateway": {
apiKey: "${VERCEL_GATEWAY_API_KEY}",
},
},
},
gateway: {
auth: {
token: "${OPENCLAW_GATEWAY_TOKEN}",
},
},
}
规则:
- 只匹配大写环境变量名:
[A-Z_][A-Z0-9_]* - 缺失或空的环境变量会在配置加载时抛出错误
- 用
$${VAR}转义以输出字面量${VAR} - 与
$include配合使用(包含的文件也会进行替换)
内联替换:
{
models: {
providers: {
custom: {
baseUrl: "${CUSTOM_API_BASE}/v1", // → "https://api.example.com/v1"
},
},
},
}
认证存储(OAuth + API keys)
OpenClaw 将每个 agent 的认证配置文件(OAuth + API keys)存储在:
<agentDir>/auth-profiles.json(默认:~/.openclaw/agents/<agentId>/agent/auth-profiles.json)
旧版 OAuth 导入:
~/.openclaw/credentials/oauth.json(或$OPENCLAW_STATE_DIR/credentials/oauth.json)
内嵌 Pi agent 在以下位置维护运行时缓存:
<agentDir>/auth.json(自动管理;不要手动编辑)
旧版 agent 目录(多 agent 之前):
~/.openclaw/agent/*(由openclaw doctor迁移到~/.openclaw/agents/<defaultAgentId>/agent/*)
覆盖:
- OAuth 目录(仅旧版导入):
OPENCLAW_OAUTH_DIR - Agent 目录(默认 agent 根覆盖):
OPENCLAW_AGENT_DIR(首选)、PI_CODING_AGENT_DIR(旧版)
首次使用时,OpenClaw 会将 oauth.json 条目导入到 auth-profiles.json。
auth
认证配置文件的可选元数据。这不存储密钥;它将配置文件 ID 映射到 provider + 模式(和可选的 email),并定义用于故障转移的 provider 轮换顺序。
{
auth: {
profiles: {
"anthropic:[email protected]": { provider: "anthropic", mode: "oauth", email: "[email protected]" },
"anthropic:work": { provider: "anthropic", mode: "api_key" },
},
order: {
anthropic: ["anthropic:[email protected]", "anthropic:work"],
},
},
}
agents.list[].identity
用于默认值和 UX 的可选每个 agent 身份。这由 macOS 引导助手写入。
如果设置,OpenClaw 会派生默认值(仅当你没有明确设置时):
messages.ackReaction从活跃 agent 的identity.emoji(回退到 👀)agents.list[].groupChat.mentionPatterns从 agent 的identity.name/identity.emoji(这样 “@Samantha” 就能在 Telegram/Slack/Discord/Google Chat/iMessage/WhatsApp 的群组中工作)identity.avatar接受相对于 workspace 的图片路径或远程 URL/data URL。本地文件必须在 agent workspace 内
identity.avatar 接受:
- 相对于 workspace 的路径(必须在 agent workspace 内)
http(s)URLdata:URI
{
agents: {
list: [
{
id: "main",
identity: {
name: "Samantha",
theme: "helpful sloth",
emoji: "🦥",
avatar: "avatars/samantha.png",
},
},
],
},
}
wizard
由 CLI 向导(onboard、configure、doctor)写入的元数据。
{
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(正则表达式字符串数组;覆盖默认值)
{
logging: {
level: "info",
file: "/tmp/openclaw/openclaw.log",
consoleLevel: "info",
consoleStyle: "pretty",
redactSensitive: "tools",
redactPatterns: [
// 示例:用你自己的规则覆盖默认值
"\\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 配对请求默认限制为每个 channel 3 个。
配对批准:
openclaw pairing list whatsappopenclaw pairing approve whatsapp <code>
channels.whatsapp.allowFrom
可以触发 WhatsApp 自动回复的 E.164 电话号码白名单(仅 DM)。
如果为空且 channels.whatsapp.dmPolicy="pairing",未知发送者将收到配对码。
对于群组,使用 channels.whatsapp.groupPolicy + channels.whatsapp.groupAllowFrom。
{
channels: {
whatsapp: {
dmPolicy: "pairing", // pairing | allowlist | open | disabled
allowFrom: ["+15555550123", "+447700900123"],
textChunkLimit: 4000, // 可选的出站分块大小(字符)
chunkMode: "length", // 可选的分块模式(length | newline)
mediaMaxMb: 50, // 可选的入站媒体上限(MB)
},
},
}
channels.whatsapp.sendReadReceipts
控制入站 WhatsApp 消息是否标记为已读(蓝色勾号)。默认:true。
自聊模式始终跳过已读回执,即使启用。
每个账户覆盖:channels.whatsapp.accounts.<id>.sendReadReceipts。
{
channels: {
whatsapp: { sendReadReceipts: false },
},
}
channels.whatsapp.accounts(多账户)
在一个 gateway 中运行多个 WhatsApp 账户:
{
channels: {
whatsapp: {
accounts: {
default: {}, // 可选;保持默认 id 稳定
personal: {},
biz: {
// 可选覆盖。默认:~/.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
每个 channel 运行多个账户(每个账户有自己的 accountId 和可选的 name):
{
channels: {
telegram: {
accounts: {
default: {
name: "Primary bot",
botToken: "123456:ABC...",
},
alerts: {
name: "Alerts bot",
botToken: "987654:XYZ...",
},
},
},
},
}
注意:
- 当省略
accountId时使用default(CLI + routing) - 环境变量 token 只应用于 default 账户
- 基础 channel 设置(群组策略、提及门控等)应用于所有账户,除非每个账户覆盖
- 使用
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)
{
messages: {
groupChat: { historyLimit: 50 },
},
agents: {
list: [{ id: "main", groupChat: { mentionPatterns: ["@openclaw", "openclaw"] } }],
},
}
messages.groupChat.historyLimit 设置群组历史上下文的全局默认值。Channel 可以用 channels.<channel>.historyLimit(或多账户的 channels.<channel>.accounts.*.historyLimit)覆盖。设置 0 禁用历史包装。
DM 历史限制
DM 对话使用 agent 管理的基于 session 的历史。你可以限制每个 DM session 保留的用户轮次数:
{
channels: {
telegram: {
dmHistoryLimit: 30, // 将 DM session 限制为 30 个用户轮次
dms: {
"123456789": { historyLimit: 50 }, // 每用户覆盖(用户 ID)
},
},
},
}
解析顺序:
- 每个 DM 覆盖:
channels.<provider>.dms[userId].historyLimit - Provider 默认值:
channels.<provider>.dmHistoryLimit - 无限制(保留所有历史)
支持的 provider:telegram、whatsapp、discord、slack、signal、imessage、msteams。
每个 agent 覆盖(设置时优先,即使是 []):
{
agents: {
list: [
{ id: "work", groupChat: { mentionPatterns: ["@workbot", "\\+15555550123"] } },
{ id: "personal", groupChat: { mentionPatterns: ["@homebot", "\\+15555550999"] } },
],
},
}
提及门控默认值存在于每个 channel(channels.whatsapp.groups、channels.telegram.groups、channels.imessage.groups、channels.discord.guilds)。当设置 *.groups 时,它也充当群组白名单;包含 "*" 以允许所有群组。
要仅响应特定文本触发器(忽略原生 @-提及):
{
channels: {
whatsapp: {
// 包含你自己的号码以启用自聊模式(忽略原生 @-提及)
allowFrom: ["+15555550123"],
groups: { "*": { requireMention: true } },
},
},
agents: {
list: [
{
id: "main",
groupChat: {
// 只有这些文本模式会触发响应
mentionPatterns: ["reisponde", "@openclaw"],
},
},
],
},
}
群组策略(每个 channel)
使用 channels.*.groupPolicy 控制是否接受群组/房间消息:
{
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: ["[email protected]"],
},
discord: {
groupPolicy: "allowlist",
guilds: {
GUILD_ID: {
channels: { help: { allow: true } },
},
},
},
slack: {
groupPolicy: "allowlist",
channels: { "#general": { allow: true } },
},
},
}
注意:
"open":群组绕过白名单;提及门控仍然适用"disabled":阻止所有群组/房间消息"allowlist":只允许匹配配置白名单的群组/房间channels.defaults.groupPolicy在 provider 的groupPolicy未设置时设置默认值- WhatsApp/Telegram/Signal/iMessage/Microsoft Teams 使用
groupAllowFrom(回退:显式allowFrom) - Discord/Slack 使用 channel 白名单(
channels.discord.guilds.*.channels、channels.slack.channels) - 群组 DM(Discord/Slack)仍由
dm.groupEnabled+dm.groupChannels控制 - 默认是
groupPolicy: "allowlist"(除非被channels.defaults.groupPolicy覆盖);如果没有配置白名单,群组消息会被阻止
多 Agent routing(agents.list + bindings)
在一个 Gateway 内运行多个隔离的 agent(独立的 workspace、agentDir、session)。
入站消息通过 bindings 路由到 agent。
agents.list[]:每个 agent 覆盖id:稳定的 agent id(必需)default:可选;当设置多个时,第一个生效并记录警告。如果没有设置,列表中的第一个条目是默认 agentname:agent 的显示名称workspace:默认~/.openclaw/workspace-<agentId>(对于main,回退到agents.defaults.workspace)agentDir:默认~/.openclaw/agents/<agentId>/agentmodel:每个 agent 的默认模型,覆盖该 agent 的agents.defaults.model- 字符串形式:
"provider/model",只覆盖agents.defaults.model.primary - 对象形式:
{ primary, fallbacks }(fallbacks 覆盖agents.defaults.model.fallbacks;[]禁用该 agent 的全局 fallbacks)
- 字符串形式:
identity:每个 agent 的名称/主题/emoji(用于提及模式 + ack 反应)groupChat:每个 agent 的提及门控(mentionPatterns)sandbox:每个 agent 的 sandbox 配置(覆盖agents.defaults.sandbox)mode:"off"|"non-main"|"all"workspaceAccess:"none"|"ro"|"rw"scope:"session"|"agent"|"shared"workspaceRoot:自定义 sandbox workspace 根目录docker:每个 agent 的 docker 覆盖(例如image、network、env、setupCommand、限制;当scope: "shared"时忽略)browser:每个 agent 的沙盒浏览器覆盖(当scope: "shared"时忽略)prune:每个 agent 的 sandbox 清理覆盖(当scope: "shared"时忽略)
subagents:每个 agent 的 sub-agent 默认值allowAgents:从此 agent 的sessions_spawn的 agent id 白名单(["*"]= 允许任何;默认:仅相同 agent)
tools:每个 agent 的工具限制(在 sandbox 工具策略之前应用)profile:基础工具配置文件(在 allow/deny 之前应用)allow:允许的工具名称数组deny:拒绝的工具名称数组(deny 优先)
agents.defaults:共享 agent 默认值(model、workspace、sandbox 等)bindings[]:将入站消息路由到agentIdmatch.channel(必需)match.accountId(可选;*= 任何账户;省略 = 默认账户)match.peer(可选;{ kind: dm|group|channel, id })match.guildId/match.teamId(可选;特定于 channel)
确定性匹配顺序:
match.peermatch.guildIdmatch.teamIdmatch.accountId(精确,无 peer/guild/team)match.accountId: "*"(channel 范围,无 peer/guild/team)- 默认 agent(
agents.list[].default,否则第一个列表条目,否则"main")
在每个匹配层级内,bindings 中的第一个匹配条目获胜。
每个 agent 访问配置文件(多 agent)
每个 agent 可以携带自己的 sandbox + 工具策略。使用它在一个 gateway 中混合访问级别:
- 完全访问(个人 agent)
- 只读工具 + workspace
- 无文件系统访问(仅消息/session 工具)
查看 多 Agent Sandbox & 工具 了解优先级和更多示例。
完全访问(无 sandbox):
{
agents: {
list: [
{
id: "personal",
workspace: "~/.openclaw/workspace-personal",
sandbox: { mode: "off" },
},
],
},
}
只读工具 + 只读 workspace:
{
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"],
},
},
],
},
}
无文件系统访问(启用消息/session 工具):
{
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 账户 → 两个 agent:
{
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(可选)
Agent 到 agent 的消息传递是选择性加入的:
{
tools: {
agentToAgent: {
enabled: false,
allow: ["home", "work"],
},
},
}
messages.queue
控制当 agent 运行已经活跃时入站消息的行为。
{
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
对来自同一发送者的快速入站消息进行防抖,这样多个连续消息会变成单个 agent 轮次。防抖的范围是每个 channel + 对话,并使用最新的消息进行回复线程/ID。
{
messages: {
inbound: {
debounceMs: 2000, // 0 禁用
byChannel: {
whatsapp: 5000,
slack: 1500,
discord: 1500,
},
},
},
}
注意:
- 防抖批处理纯文本消息;媒体/附件立即刷新
- 控制命令(例如
/queue、/new)绕过防抖,因此它们保持独立
commands(聊天命令处理)
控制如何在连接器之间启用聊天命令。
{
commands: {
native: "auto", // 在支持时注册原生命令(auto)
text: true, // 解析聊天消息中的斜杠命令
bash: false, // 允许 !(别名:/bash)(仅主机;需要 tools.elevated 白名单)
bashForegroundMs: 2000, // bash 前台窗口(0 立即后台)
config: false, // 允许 /config(写入磁盘)
debug: false, // 允许 /debug(仅运行时覆盖)
restart: false, // 允许 /restart + gateway 重启工具
useAccessGroups: true, // 对命令强制执行访问组白名单/策略
},
}
注意:
- 文本命令必须作为独立消息发送,并使用前导
/(没有纯文本别名) commands.text: false禁用解析聊天消息中的命令commands.native: "auto"(默认)为 Discord/Telegram 启用原生命令,Slack 保持关闭;不支持的 channel 保持纯文本- 设置
commands.native: true|false强制全部启用或禁用,或使用channels.discord.commands.native、channels.telegram.commands.native、channels.slack.commands.native(bool 或"auto")按 channel 覆盖。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控制由该 channel 发起的配置修改(默认:true)。这适用于/config set|unset以及特定于 provider 的自动迁移(Telegram 超级群组 ID 更改、Slack channel ID 更改)commands.debug: true启用/debug(仅运行时覆盖)commands.restart: true启用/restart和 gateway 工具重启操作commands.useAccessGroups: false允许命令绕过访问组白名单/策略- 斜杠命令和指令仅对授权发送者有效。授权来自 channel 白名单/pairing 加上
commands.useAccessGroups
web(WhatsApp web channel 运行时)
WhatsApp 通过 gateway 的 web channel(Baileys Web)运行。当存在已链接的 session 时,它会自动启动。
设置 web.enabled: false 以默认保持关闭。
{
web: {
enabled: true,
heartbeatSeconds: 60,
reconnect: {
initialMs: 2000,
maxMs: 120000,
factor: 1.4,
jitter: 0.2,
maxAttempts: 0,
},
},
}
channels.telegram(bot 传输)
OpenClaw 仅在存在 channels.telegram 配置部分时启动 Telegram。bot token 从 channels.telegram.botToken(或 channels.telegram.tokenFile)解析,默认账户回退到 TELEGRAM_BOT_TOKEN。
设置 channels.telegram.enabled: false 以禁用自动启动。
多账户支持位于 channels.telegram.accounts 下(见上面的多账户部分)。环境变量 token 仅应用于默认账户。
设置 channels.telegram.configWrites: false 以阻止 Telegram 发起的配置写入(包括超级群组 ID 迁移和 /config set|unset)。
{
channels: {
telegram: {
enabled: true,
botToken: "your-bot-token",
dmPolicy: "pairing", // pairing | allowlist | open | disabled
allowFrom: ["tg:123456789"], // 可选;"open" 需要 ["*"]
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, // 包含最后 N 条群组消息作为上下文(0 禁用)
replyToMode: "first", // off | first | all
linkPreview: true, // 切换出站链接预览
streamMode: "partial", // off | partial | block(草稿 streaming;与 block streaming 分开)
draftChunk: {
// 可选;仅用于 streamMode=block
minChars: 200,
maxChars: 800,
breakPreference: "paragraph", // paragraph | newline | sentence
},
actions: { reactions: true, sendMessage: true }, // 工具操作门控(false 禁用)
reactionNotifications: "own", // off | own | all
mediaMaxMb: 5,
retry: {
// 出站重试策略
attempts: 3,
minDelayMs: 400,
maxDelayMs: 30000,
jitter: 0.1,
},
network: {
// 传输覆盖
autoSelectFamily: false,
},
proxy: "socks5://localhost:9050",
webhookUrl: "https://example.com/telegram-webhook", // 需要 webhookSecret
webhookSecret: "secret",
webhookPath: "/telegram-webhook",
},
},
}
草稿 streaming 注意事项:
- 使用 Telegram
sendMessageDraft(草稿气泡,不是真实消息) - 需要私聊主题(DM 中的 message_thread_id;bot 启用了主题)
/reasoning stream将推理流式传输到草稿中,然后发送最终答案
重试策略默认值和行为记录在 重试策略 中。
channels.discord(bot 传输)
通过设置 bot token 和可选门控来配置 Discord bot:
多账户支持位于 channels.discord.accounts 下(见上面的多账户部分)。环境变量 token 仅应用于默认账户。
{
channels: {
discord: {
enabled: true,
token: "your-bot-token",
mediaMaxMb: 8, // 限制入站媒体大小
allowBots: false, // 允许 bot 创作的消息
actions: {
// 工具操作门控(false 禁用)
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, // false 时禁用所有 DM
policy: "pairing", // pairing | allowlist | open | disabled
allowFrom: ["1234567890", "steipete"], // 可选 DM 白名单("open" 需要 ["*"])
groupEnabled: false, // 启用群组 DM
groupChannels: ["openclaw-dm"], // 可选群组 DM 白名单
},
guilds: {
"123456789012345678": {
// guild id(首选)或 slug
slug: "friends-of-openclaw",
requireMention: false, // 每个 guild 的默认值
reactionNotifications: "own", // off | own | all | allowlist
users: ["987654321098765432"], // 可选的每个 guild 用户白名单
channels: {
general: { allow: true },
help: {
allow: true,
requireMention: true,
users: ["987654321098765432"],
skills: ["docs"],
systemPrompt: "Short answers only.",
},
},
},
},
historyLimit: 20, // 包含最后 N 条 guild 消息作为上下文
textChunkLimit: 2000, // 可选的出站文本分块大小(字符)
chunkMode: "length", // 可选的分块模式(length | newline)
maxLinesPerMessage: 17, // 每条消息的软最大行数(Discord UI 裁剪)
retry: {
// 出站重试策略
attempts: 3,
minDelayMs: 500,
maxDelayMs: 30000,
jitter: 0.1,
},
},
},
}
OpenClaw 仅在存在 channels.discord 配置部分时启动 Discord。token 从 channels.discord.token 解析,默认账户回退到 DISCORD_BOT_TOKEN(除非 channels.discord.enabled 为 false)。在为 cron/CLI 命令指定交付目标时使用 user:<id>(DM)或 channel:<id>(guild channel);裸数字 ID 是模糊的,会被拒绝。
Guild slug 是小写的,空格替换为 -;channel 键使用 slug 化的 channel 名称(没有前导 #)。优先使用 guild id 作为键以避免重命名歧义。
默认情况下忽略 bot 创作的消息。使用 channels.discord.allowBots 启用(自己的消息仍然被过滤以防止自我回复循环)。
反应通知模式:
off:无反应事件own:对 bot 自己消息的反应(默认)all:对所有消息的所有反应allowlist:来自guilds.<id>.users的对所有消息的反应(空列表禁用)
出站文本由 channels.discord.textChunkLimit(默认 2000)分块。设置 channels.discord.chunkMode="newline" 以在长度分块之前在空行(段落边界)上拆分。Discord 客户端可能会裁剪非常高的消息,因此 channels.discord.maxLinesPerMessage(默认 17)会拆分长的多行回复,即使在 2000 字符以下。
重试策略默认值和行为记录在 重试策略 中。
channels.googlechat(Chat API webhook)
Google Chat 通过 HTTP webhook 运行,使用应用级认证(服务账户)。
多账户支持位于 channels.googlechat.accounts 下(见上面的多账户部分)。环境变量仅应用于默认账户。
{
channels: {
googlechat: {
enabled: true,
serviceAccountFile: "/path/to/service-account.json",
audienceType: "app-url", // app-url | project-number
audience: "https://gateway.example.com/googlechat",
webhookPath: "/googlechat",
botUser: "users/1234567890", // 可选;改进提及检测
dm: {
enabled: true,
policy: "pairing", // pairing | allowlist | open | disabled
allowFrom: ["users/1234567890"], // 可选;"open" 需要 ["*"]
},
groupPolicy: "allowlist",
groups: {
"spaces/AAAA": { allow: true, requireMention: true },
},
actions: { reactions: true },
typingIndicator: "message",
mediaMaxMb: 20,
},
},
}
注意:
- 服务账户 JSON 可以是内联的(
serviceAccount)或基于文件的(serviceAccountFile) - 默认账户的环境变量回退:
GOOGLE_CHAT_SERVICE_ACCOUNT或GOOGLE_CHAT_SERVICE_ACCOUNT_FILE audienceType+audience必须匹配 Chat 应用的 webhook 认证配置- 在设置交付目标时使用
spaces/<spaceId>或users/<userId|email>
channels.slack(socket 模式)
Slack 在 Socket 模式下运行,需要 bot token 和 app token:
{
channels: {
slack: {
enabled: true,
botToken: "xoxb-...",
appToken: "xapp-...",
dm: {
enabled: true,
policy: "pairing", // pairing | allowlist | open | disabled
allowFrom: ["U123", "U456", "*"], // 可选;"open" 需要 ["*"]
groupEnabled: false,
groupChannels: ["G123"],
},
channels: {
C123: { allow: true, requireMention: true, allowBots: false },
"#general": {
allow: true,
requireMention: true,
allowBots: false,
users: ["U123"],
skills: ["docs"],
systemPrompt: "Short answers only.",
},
},
historyLimit: 50, // 包含最后 N 条 channel/群组消息作为上下文(0 禁用)
allowBots: false,
reactionNotifications: "own", // off | own | all | allowlist
reactionAllowlist: ["U123"],
replyToMode: "off", // off | first | all
thread: {
historyScope: "thread", // thread | channel
inheritParent: false,
},
actions: {
reactions: true,
messages: true,
pins: true,
memberInfo: true,
emojiList: true,
},
slashCommand: {
enabled: true,
name: "openclaw",
sessionPrefix: "slack:slash",
ephemeral: true,
},
textChunkLimit: 4000,
chunkMode: "length",
mediaMaxMb: 20,
},
},
}
多账户支持位于 channels.slack.accounts 下(见上面的多账户部分)。环境变量 token 仅应用于默认账户。
OpenClaw 在 provider 启用且两个 token 都设置时启动 Slack(通过配置或 SLACK_BOT_TOKEN + SLACK_APP_TOKEN)。在为 cron/CLI 命令指定交付目标时使用 user:<id>(DM)或 channel:<id>。
设置 channels.slack.configWrites: false 以阻止 Slack 发起的配置写入(包括 channel ID 迁移和 /config set|unset)。
默认情况下忽略 bot 创作的消息。使用 channels.slack.allowBots 或 channels.slack.channels.<id>.allowBots 启用。
反应通知模式:
off:无反应事件own:对 bot 自己消息的反应(默认)all:对所有消息的所有反应allowlist:来自channels.slack.reactionAllowlist的对所有消息的反应(空列表禁用)
Thread session 隔离:
channels.slack.thread.historyScope控制 thread 历史是每个 thread(thread,默认)还是跨 channel 共享(channel)channels.slack.thread.inheritParent控制新 thread session 是否继承父 channel 记录(默认:false)
Slack 操作组(控制 slack 工具操作):
| 操作组 | 默认 | 注意 |
|---|---|---|
| reactions | 启用 | 反应 + 列出反应 |
| messages | 启用 | 读取/发送/编辑/删除 |
| pins | 启用 | 固定/取消固定/列出 |
| memberInfo | 启用 | 成员信息 |
| emojiList | 启用 | 自定义 emoji 列表 |
channels.mattermost(bot token)
Mattermost 作为插件提供,不包含在核心安装中。
首先安装它:openclaw plugins install @openclaw/mattermost(或从 git checkout 的 ./extensions/mattermost)。
Mattermost 需要 bot token 加上服务器的 base URL:
{
channels: {
mattermost: {
enabled: true,
botToken: "mm-token",
baseUrl: "https://chat.example.com",
dmPolicy: "pairing",
chatmode: "oncall", // oncall | onmessage | onchar
oncharPrefixes: [">", "!"],
textChunkLimit: 4000,
chunkMode: "length",
},
},
}
OpenClaw 在账户配置(bot token + base URL)且启用时启动 Mattermost。token + base URL 从 channels.mattermost.botToken + channels.mattermost.baseUrl 或默认账户的 MATTERMOST_BOT_TOKEN + MATTERMOST_URL 解析(除非 channels.mattermost.enabled 为 false)。
聊天模式:
oncall(默认):仅在 @提及时响应 channel 消息onmessage:响应每条 channel 消息onchar:当消息以触发前缀开头时响应(channels.mattermost.oncharPrefixes,默认[">", "!"])
访问控制:
- 默认 DM:
channels.mattermost.dmPolicy="pairing"(未知发送者获得配对码) - 公开 DM:
channels.mattermost.dmPolicy="open"加上channels.mattermost.allowFrom=["*"] - 群组:默认
channels.mattermost.groupPolicy="allowlist"(提及门控)。使用channels.mattermost.groupAllowFrom限制发送者
多账户支持位于 channels.mattermost.accounts 下(见上面的多账户部分)。环境变量仅应用于默认账户。
在指定交付目标时使用 channel:<id> 或 user:<id>(或 @username);裸 id 被视为 channel id。
channels.signal(signal-cli)
Signal 反应可以发出系统事件(共享反应工具):
{
channels: {
signal: {
reactionNotifications: "own", // off | own | all | allowlist
reactionAllowlist: ["+15551234567", "uuid:123e4567-e89b-12d3-a456-426614174000"],
historyLimit: 50, // 包含最后 N 条群组消息作为上下文(0 禁用)
},
},
}
反应通知模式:
off:无反应事件own:对 bot 自己消息的反应(默认)all:对所有消息的所有反应allowlist:来自channels.signal.reactionAllowlist的对所有消息的反应(空列表禁用)
channels.imessage(imsg CLI)
OpenClaw 生成 imsg rpc(通过 stdio 的 JSON-RPC)。不需要 daemon 或端口。
{
channels: {
imessage: {
enabled: true,
cliPath: "imsg",
dbPath: "~/Library/Messages/chat.db",
remoteHost: "user@gateway-host", // 使用 SSH 包装器时通过 SCP 获取远程附件
dmPolicy: "pairing", // pairing | allowlist | open | disabled
allowFrom: ["+15555550123", "[email protected]", "chat_id:123"],
historyLimit: 50, // 包含最后 N 条群组消息作为上下文(0 禁用)
includeAttachments: false,
mediaMaxMb: 16,
service: "auto",
region: "US",
},
},
}
多账户支持位于 channels.imessage.accounts 下(见上面的多账户部分)。
注意:
- 需要对 Messages DB 的完全磁盘访问权限
- 第一次发送会提示 Messages 自动化权限
- 优先使用
chat_id:<id>目标。使用imsg chats --limit 20列出聊天 channels.imessage.cliPath可以指向包装脚本(例如ssh到运行imsg rpc的另一台 Mac);使用 SSH 密钥以避免密码提示- 对于远程 SSH 包装器,设置
channels.imessage.remoteHost以在启用includeAttachments时通过 SCP 获取附件
包装器示例:
#!/usr/bin/env bash
exec ssh -T gateway-host imsg "$@"
agents.defaults.workspace
设置 agent 用于文件操作的单个全局 workspace 目录。
默认:~/.openclaw/workspace。
{
agents: { defaults: { workspace: "~/.openclaw/workspace" } },
}
如果启用了 agents.defaults.sandbox,非 main session 可以使用 agents.defaults.sandbox.workspaceRoot 下的每个 scope workspace 覆盖此设置。
agents.defaults.repoRoot
可选的仓库根目录,显示在系统 prompt 的 Runtime 行中。如果未设置,OpenClaw 会尝试通过从 workspace(和当前工作目录)向上遍历来检测 .git 目录。路径必须存在才能使用。
{
agents: { defaults: { repoRoot: "~/Projects/openclaw" } },
}
agents.defaults.skipBootstrap
禁用自动创建 workspace 引导文件(AGENTS.md、SOUL.md、TOOLS.md、IDENTITY.md、USER.md 和 BOOTSTRAP.md)。
用于预先填充的部署,其中 workspace 文件来自仓库。
{
agents: { defaults: { skipBootstrap: true } },
}
agents.defaults.bootstrapMaxChars
每个 workspace 引导文件在截断前注入到系统 prompt 中的最大字符数。默认:20000。
当文件超过此限制时,OpenClaw 会记录警告并注入带有标记的截断头/尾。
{
agents: { defaults: { bootstrapMaxChars: 20000 } },
}
agents.defaults.userTimezone
设置用户的时区用于系统 prompt 上下文(不用于消息信封中的时间戳)。如果未设置,OpenClaw 在运行时使用主机时区。
{
agents: { defaults: { userTimezone: "America/Chicago" } },
}
agents.defaults.timeFormat
控制系统 prompt 的 Current Date & Time 部分显示的时间格式。
默认:auto(操作系统偏好)。
{
agents: { defaults: { timeFormat: "auto" } }, // auto | 12 | 24
}
messages
控制入站/出站前缀和可选的 ack 反应。 查看 Messages 了解队列、session 和 streaming 上下文。
{
messages: {
responsePrefix: "🦞", // 或 "auto"
ackReaction: "👀",
ackReactionScope: "group-mentions",
removeAckAfterReply: false,
},
}
responsePrefix 应用于跨 channel 的所有出站回复(工具摘要、block streaming、最终回复),除非已经存在。
如果未设置 messages.responsePrefix,默认不应用前缀。WhatsApp 自聊回复是例外:当设置时默认为 [{identity.name}],否则为 [openclaw],这样同一电话的对话保持清晰。
将其设置为 "auto" 以为路由的 agent 派生 [{identity.name}](当设置时)。
模板变量
responsePrefix 字符串可以包含动态解析的模板变量:
| 变量 | 描述 | 示例 |
|---|---|---|
{model} | 短模型名称 | claude-opus-4-5、gpt-4o |
{modelFull} | 完整模型标识符 | anthropic/claude-opus-4-5 |
{provider} | Provider 名称 | anthropic、openai |
{thinkingLevel} | 当前思考级别 | high、low、off |
{identity.name} | Agent 身份名称 | (与 "auto" 模式相同) |
变量不区分大小写({MODEL} = {model})。{think} 是 {thinkingLevel} 的别名。
未解析的变量保持为字面文本。
{
messages: {
responsePrefix: "[{model} | think:{thinkingLevel}]",
},
}
示例输出:[claude-opus-4-5 | think:high] Here's my response...
WhatsApp 入站前缀通过 channels.whatsapp.messagePrefix 配置(已弃用:messages.messagePrefix)。默认保持不变:当 channels.whatsapp.allowFrom 为空时为 "[openclaw]",否则为 ""(无前缀)。当使用 "[openclaw]" 时,如果路由的 agent 设置了 identity.name,OpenClaw 将改用 [{identity.name}]。
ackReaction 在支持反应的 channel(Slack/Discord/Telegram/Google Chat)上发送尽力而为的 emoji 反应以确认入站消息。当设置时默认为活跃 agent 的 identity.emoji,否则为 "👀"。将其设置为 "" 以禁用。
ackReactionScope 控制何时触发反应:
group-mentions(默认):仅当群组/房间需要提及且 bot 被提及时group-all:所有群组/房间消息direct:仅私聊消息all:所有消息
removeAckAfterReply 在发送回复后删除 bot 的 ack 反应(仅 Slack/Discord/Telegram/Google Chat)。默认:false。
messages.tts
为出站回复启用文本转语音。启用后,OpenClaw 使用 ElevenLabs 或 OpenAI 生成音频并将其附加到响应中。Telegram 使用 Opus 语音笔记;其他 channel 发送 MP3 音频。
{
messages: {
tts: {
auto: "always", // off | always | inbound | tagged
mode: "final", // final | all(包括工具/block 回复)
provider: "elevenlabs",
summaryModel: "openai/gpt-4.1-mini",
modelOverrides: {
enabled: true,
},
maxTextLength: 4000,
timeoutMs: 30000,
prefsPath: "~/.openclaw/settings/tts.json",
elevenlabs: {
apiKey: "elevenlabs_api_key",
baseUrl: "https://api.elevenlabs.io",
voiceId: "voice_id",
modelId: "eleven_multilingual_v2",
seed: 42,
applyTextNormalization: "auto",
languageCode: "en",
voiceSettings: {
stability: 0.5,
similarityBoost: 0.75,
style: 0.0,
useSpeakerBoost: true,
speed: 1.0,
},
},
openai: {
apiKey: "openai_api_key",
model: "gpt-4o-mini-tts",
voice: "alloy",
},
},
},
}
注意:
messages.tts.auto控制自动 TTS(off、always、inbound、tagged)/tts off|always|inbound|tagged设置每个 session 的自动模式(覆盖配置)messages.tts.enabled是旧版;doctor 将其迁移到messages.tts.autoprefsPath存储本地覆盖(provider/limit/summarize)maxTextLength是 TTS 输入的硬上限;摘要会被截断以适应summaryModel覆盖agents.defaults.model.primary用于自动摘要- 接受
provider/model或来自agents.defaults.models的别名
- 接受
modelOverrides启用模型驱动的覆盖,如[[tts:...]]标签(默认启用)/tts limit和/tts summary控制每个用户的摘要设置apiKey值回退到ELEVENLABS_API_KEY/XI_API_KEY和OPENAI_API_KEYelevenlabs.baseUrl覆盖 ElevenLabs API base URLelevenlabs.voiceSettings支持stability/similarityBoost/style(0..1)、useSpeakerBoost和speed(0.5..2.0)
talk
Talk 模式的默认值(macOS/iOS/Android)。未设置时,Voice ID 回退到 ELEVENLABS_VOICE_ID 或 SAG_VOICE_ID。
未设置时,apiKey 回退到 ELEVENLABS_API_KEY(或 gateway 的 shell 配置文件)。
voiceAliases 让 Talk 指令使用友好名称(例如 "voice":"Clawd")。
{
talk: {
voiceId: "elevenlabs_voice_id",
voiceAliases: {
Clawd: "EXAVITQu4vr4xnSDxMaL",
Roger: "CwhRBWXzGAHq8TQ4Fs17",
},
modelId: "eleven_v3",
outputFormat: "mp3_44100_128",
apiKey: "elevenlabs_api_key",
interruptOnSpeech: true,
},
}
agents.defaults
控制内嵌 agent 运行时(model/thinking/verbose/timeouts)。
agents.defaults.models 定义配置的模型目录(并充当 /model 的白名单)。
agents.defaults.model.primary 设置默认模型;agents.defaults.model.fallbacks 是全局故障转移。
agents.defaults.imageModel 是可选的,仅在主模型缺少图像输入时使用。
每个 agents.defaults.models 条目可以包括:
alias(可选的模型快捷方式,例如/opus)params(可选的特定于 provider 的 API 参数,传递给模型请求)
params 也应用于 streaming 运行(内嵌 agent + compaction)。目前支持的键:temperature、maxTokens。这些与调用时选项合并;调用者提供的值获胜。temperature 是高级旋钮——除非你知道模型的默认值并需要更改,否则不要设置。
示例:
{
agents: {
defaults: {
models: {
"anthropic/claude-sonnet-4-5-20250929": {
params: { temperature: 0.6 },
},
"openai/gpt-5.2": {
params: { maxTokens: 8192 },
},
},
},
},
}
Z.AI GLM-4.x 模型会自动启用思考模式,除非你:
- 设置
--thinking off,或 - 自己定义
agents.defaults.models["zai/<model>"].params.thinking
OpenClaw 还附带了一些内置别名简写。默认值仅在模型已存在于 agents.defaults.models 中时应用:
opus->anthropic/claude-opus-4-5sonnet->anthropic/claude-sonnet-4-5gpt->openai/gpt-5.2gpt-mini->openai/gpt-5-minigemini->google/gemini-3-pro-previewgemini-flash->google/gemini-3-flash-preview
如果你自己配置相同的别名名称(不区分大小写),你的值获胜(默认值永不覆盖)。
MiniMax 认证:设置 `MINIMAX_API_KEY`(环境变量)或配置 `models.providers.minimax`。
#### `agents.defaults.cliBackends`(CLI 回退)
可选的 CLI 后端,用于纯文本回退运行(无 tool 调用)。当 API 提供商失败时,这些作为备用路径很有用。当你配置接受文件路径的 `imageArg` 时,支持图像透传。
注意:
- CLI 后端是 **文本优先** 的;tools 始终被禁用。
- 当设置 `sessionArg` 时支持 Sessions;session ids 按后端持久化。
- 对于 `claude-cli`,默认值已内置。如果 PATH 最小化(launchd/systemd),请覆盖命令路径。
示例:
```json5
{
agents: {
defaults: {
cliBackends: {
"claude-cli": {
command: "/opt/homebrew/bin/claude",
},
"my-cli": {
command: "my-cli",
args: ["--json"],
output: "json",
modelArg: "--model",
sessionArg: "--session",
sessionMode: "existing",
systemPromptArg: "--system",
systemPromptWhen: "first",
imageArg: "--image",
imageMode: "repeat",
},
},
},
},
}
{
agents: {
defaults: {
models: {
"anthropic/claude-opus-4-5": { alias: "Opus" },
"anthropic/claude-sonnet-4-1": { alias: "Sonnet" },
"openrouter/deepseek/deepseek-r1:free": {},
"zai/glm-4.7": {
alias: "GLM",
params: {
thinking: {
type: "enabled",
clear_thinking: false,
},
},
},
},
model: {
primary: "anthropic/claude-opus-4-5",
fallbacks: [
"openrouter/deepseek/deepseek-r1:free",
"openrouter/meta-llama/llama-3.3-70b-instruct:free",
],
},
imageModel: {
primary: "openrouter/qwen/qwen-2.5-vl-72b-instruct:free",
fallbacks: ["openrouter/google/gemini-2.0-flash-vision:free"],
},
thinkingDefault: "low",
verboseDefault: "off",
elevatedDefault: "on",
timeoutSeconds: 600,
mediaMaxMb: 5,
heartbeat: {
every: "30m",
target: "last",
},
maxConcurrent: 3,
subagents: {
model: "minimax/MiniMax-M2.1",
maxConcurrent: 1,
archiveAfterMinutes: 60,
},
exec: {
backgroundMs: 10000,
timeoutSec: 1800,
cleanupMs: 1800000,
},
contextTokens: 200000,
},
},
}
agents.defaults.contextPruning(tool-result 修剪)
agents.defaults.contextPruning 在请求发送到 LLM 之前,从内存中的 context 中修剪 旧的 tool results。它 不会 修改磁盘上的 session 历史记录(*.jsonl 保持完整)。
这旨在减少随时间累积大量 tool 输出的健谈 agents 的 token 使用量。
高层概述:
- 永不触碰 user/assistant 消息。
- 保护最后
keepLastAssistants条 assistant 消息(该点之后的 tool results 不会被修剪)。 - 保护 bootstrap 前缀(第一条 user 消息之前的内容不会被修剪)。
- 模式:
adaptive:当估计的 context 比率超过softTrimRatio时,软修剪超大的 tool results(保留头/尾)。 然后当估计的 context 比率超过hardClearRatio且 有足够的可修剪 tool-result 批量(minPrunableToolChars)时,硬清除最旧的符合条件的 tool results。aggressive:始终用hardClear.placeholder替换截止点之前符合条件的 tool results(无比率检查)。
软修剪 vs 硬修剪(发送到 LLM 的 context 中的变化):
- 软修剪:仅针对 超大 的 tool results。保留开头 + 结尾,在中间插入
...。- 之前:
toolResult("…very long output…") - 之后:
toolResult("HEAD…\n...\n…TAIL\n\n[Tool result trimmed: …]")
- 之前:
- 硬清除:用占位符替换整个 tool result。
- 之前:
toolResult("…very long output…") - 之后:
toolResult("[Old tool result content cleared]")
- 之前:
注意 / 当前限制:
- 包含 image blocks 的 Tool results 会被跳过(目前永不修剪/清除)。
- 估计的 “context 比率” 基于 字符(近似),而非精确 tokens。
- 如果 session 尚未包含至少
keepLastAssistants条 assistant 消息,则跳过修剪。 - 在
aggressive模式下,hardClear.enabled被忽略(符合条件的 tool results 始终被替换为hardClear.placeholder)。
默认(adaptive):
{
agents: { defaults: { contextPruning: { mode: "adaptive" } } },
}
禁用:
{
agents: { defaults: { contextPruning: { mode: "off" } } },
}
默认值(当 mode 为 "adaptive" 或 "aggressive" 时):
keepLastAssistants:3softTrimRatio:0.3(仅 adaptive)hardClearRatio:0.5(仅 adaptive)minPrunableToolChars:50000(仅 adaptive)softTrim:{ maxChars: 4000, headChars: 1500, tailChars: 1500 }(仅 adaptive)hardClear:{ enabled: true, placeholder: "[Old tool result content cleared]" }
示例(aggressive,最小化):
{
agents: { defaults: { contextPruning: { mode: "aggressive" } } },
}
示例(adaptive 调优):
{
agents: {
defaults: {
contextPruning: {
mode: "adaptive",
keepLastAssistants: 3,
softTrimRatio: 0.3,
hardClearRatio: 0.5,
minPrunableToolChars: 50000,
softTrim: { maxChars: 4000, headChars: 1500, tailChars: 1500 },
hardClear: { enabled: true, placeholder: "[Old tool result content cleared]" },
// 可选:限制修剪到特定 tools(deny 优先;支持 "*" 通配符)
tools: { deny: ["browser", "canvas"] },
},
},
},
}
参见 /concepts/session-pruning 了解行为详情。
agents.defaults.compaction(预留空间 + memory flush)
agents.defaults.compaction.mode 选择 compaction 摘要策略。默认为 default;设置 safeguard 以启用对非常长历史记录的分块摘要。参见 /concepts/compaction。
agents.defaults.compaction.reserveTokensFloor 为 Pi compaction 强制执行最小 reserveTokens 值(默认:20000)。设置为 0 以禁用下限。
agents.defaults.compaction.memoryFlush 在自动 compaction 之前运行一个 静默 的 agentic 轮次,指示模型将持久 memories 存储到磁盘(例如 memory/YYYY-MM-DD.md)。当 session token 估计值超过 compaction 限制以下的软阈值时触发。
遗留默认值:
memoryFlush.enabled:truememoryFlush.softThresholdTokens:4000memoryFlush.prompt/memoryFlush.systemPrompt:内置默认值,带有NO_REPLY- 注意:当 session workspace 为只读时(
agents.defaults.sandbox.workspaceAccess: "ro"或"none"),memory flush 会被跳过。
示例(调优):
{
agents: {
defaults: {
compaction: {
mode: "safeguard",
reserveTokensFloor: 24000,
memoryFlush: {
enabled: true,
softThresholdTokens: 6000,
systemPrompt: "Session nearing compaction. Store durable memories now.",
prompt: "Write any lasting notes to memory/YYYY-MM-DD.md; reply with NO_REPLY if nothing to store.",
},
},
},
},
}
Block streaming:
agents.defaults.blockStreamingDefault:"on"/"off"(默认 off)。- Channel 覆盖:
*.blockStreaming(以及每账户变体)以强制启用/禁用 block streaming。 非 Telegram channels 需要显式*.blockStreaming: true才能启用 block 回复。 agents.defaults.blockStreamingBreak:"text_end"或"message_end"(默认:text_end)。agents.defaults.blockStreamingChunk:流式 blocks 的软分块。默认为 800–1200 字符,优先选择段落分隔符(\n\n),然后是换行符,然后是句子。 示例:{ agents: { defaults: { blockStreamingChunk: { minChars: 800, maxChars: 1200 } } }, }agents.defaults.blockStreamingCoalesce:在发送前合并流式 blocks。 默认为{ idleMs: 1000 },并从blockStreamingChunk继承minChars,maxChars上限为 channel 文本限制。 Signal/Slack/Discord/Google Chat 默认为minChars: 1500,除非被覆盖。 Channel 覆盖:channels.whatsapp.blockStreamingCoalesce、channels.telegram.blockStreamingCoalesce、channels.discord.blockStreamingCoalesce、channels.slack.blockStreamingCoalesce、channels.mattermost.blockStreamingCoalesce、channels.signal.blockStreamingCoalesce、channels.imessage.blockStreamingCoalesce、channels.msteams.blockStreamingCoalesce、channels.googlechat.blockStreamingCoalesce(以及每账户变体)。agents.defaults.humanDelay:第一个 block 回复 之后的随机暂停。 模式:off(默认)、natural(800–2500ms)、custom(使用minMs/maxMs)。 每 agent 覆盖:agents.list[].humanDelay。 示例:
参见 /concepts/streaming 了解行为 + 分块详情。{ agents: { defaults: { humanDelay: { mode: "natural" } } }, }
Typing indicators:
agents.defaults.typingMode:"never" | "instant" | "thinking" | "message"。直接聊天/提及默认为instant,未提及的群聊默认为message。session.typingMode:每 session 的模式覆盖。agents.defaults.typingIntervalSeconds:typing 信号刷新频率(默认:6s)。session.typingIntervalSeconds:每 session 的刷新间隔覆盖。 参见 /concepts/typing-indicators 了解行为详情。
agents.defaults.model.primary 应设置为 provider/model(例如 anthropic/claude-opus-4-5)。
别名来自 agents.defaults.models.*.alias(例如 Opus)。
如果省略 provider,OpenClaw 目前假定为 anthropic 作为临时弃用回退。
Z.AI 模型可用作 zai/<model>(例如 zai/glm-4.7),需要环境变量中的 ZAI_API_KEY(或旧版 Z_AI_API_KEY)。
agents.defaults.heartbeat 配置定期 heartbeat 运行:
every:持续时间字符串(ms、s、m、h);默认单位为分钟。默认:30m。设置0m以禁用。model:heartbeat 运行的可选覆盖模型(provider/model)。includeReasoning:当为true时,heartbeats 也会在可用时传递单独的Reasoning:消息(与/reasoning on形状相同)。默认:false。session:可选的 session 键,用于控制 heartbeat 在哪个 session 中运行。默认:main。to:可选的接收者覆盖(channel 特定 id,例如 WhatsApp 的 E.164,Telegram 的 chat id)。target:可选的传递 channel(last、whatsapp、telegram、discord、slack、msteams、signal、imessage、none)。默认:last。prompt:heartbeat 主体的可选覆盖(默认:Read HEARTBEAT.md if it exists (workspace context). Follow it strictly. Do not infer or repeat old tasks from prior chats. If nothing needs attention, reply HEARTBEAT_OK.)。覆盖会逐字发送;如果仍想读取文件,请包含Read HEARTBEAT.md行。ackMaxChars:传递前HEARTBEAT_OK之后允许的最大字符数(默认:300)。
每 agent 的 heartbeats:
- 设置
agents.list[].heartbeat以启用或覆盖特定 agent 的 heartbeat 设置。 - 如果任何 agent 条目定义了
heartbeat,仅这些 agents 运行 heartbeats;defaults 成为这些 agents 的共享基线。
Heartbeats 运行完整的 agent 轮次。较短的间隔会消耗更多 tokens;请注意 every,保持 HEARTBEAT.md 精简,和/或选择更便宜的 model。
tools.exec 配置后台 exec 默认值:
backgroundMs:自动后台化前的时间(ms,默认 10000)timeoutSec:此运行时间后自动终止(秒,默认 1800)cleanupMs:在内存中保留已完成 sessions 的时间(ms,默认 1800000)notifyOnExit:当后台化的 exec 退出时,将系统事件入队 + 请求 heartbeat(默认 true)applyPatch.enabled:启用实验性apply_patch(仅 OpenAI/OpenAI Codex;默认 false)applyPatch.allowModels:可选的模型 ids 允许列表(例如gpt-5.2或openai/gpt-5.2) 注意:applyPatch仅在tools.exec下。
tools.web 配置 web 搜索 + 获取 tools:
tools.web.search.enabled(默认:当 key 存在时为 true)tools.web.search.apiKey(推荐:通过openclaw configure --section web设置,或使用BRAVE_API_KEY环境变量)tools.web.search.maxResults(1–10,默认 5)tools.web.search.timeoutSeconds(默认 30)tools.web.search.cacheTtlMinutes(默认 15)tools.web.fetch.enabled(默认 true)tools.web.fetch.maxChars(默认 50000)tools.web.fetch.timeoutSeconds(默认 30)tools.web.fetch.cacheTtlMinutes(默认 15)tools.web.fetch.userAgent(可选覆盖)tools.web.fetch.readability(默认 true;禁用以仅使用基本 HTML 清理)tools.web.fetch.firecrawl.enabled(默认:当设置 API key 时为 true)tools.web.fetch.firecrawl.apiKey(可选;默认为FIRECRAWL_API_KEY)tools.web.fetch.firecrawl.baseUrl(默认 https://api.firecrawl.dev)tools.web.fetch.firecrawl.onlyMainContent(默认 true)tools.web.fetch.firecrawl.maxAgeMs(可选)tools.web.fetch.firecrawl.timeoutSeconds(可选)
tools.media 配置入站 media 理解(image/audio/video):
tools.media.models:共享模型列表(能力标记;在每能力列表之后使用)。tools.media.concurrency:最大并发能力运行数(默认 2)。tools.media.image/tools.media.audio/tools.media.video:enabled:退出开关(默认:当配置了模型时为 true)。prompt:可选 prompt 覆盖(image/video 自动附加maxChars提示)。maxChars:最大输出字符数(默认:image/video 为 500;audio 未设置)。maxBytes:发送的最大 media 大小(默认:image 10MB,audio 20MB,video 50MB)。timeoutSeconds:请求超时(默认:image 60s,audio 60s,video 120s)。language:可选 audio 提示。attachments:attachment 策略(mode、maxAttachments、prefer)。scope:可选门控(首次匹配获胜),带有match.channel、match.chatType或match.keyPrefix。models:有序的模型条目列表;失败或超大 media 会回退到下一个条目。
- 每个
models[]条目:- Provider 条目(
type: "provider"或省略):provider:API provider id(openai、anthropic、google/gemini、groq等)。model:模型 id 覆盖(image 必需;audio providers 默认为gpt-4o-mini-transcribe/whisper-large-v3-turbo,video 默认为gemini-3-flash-preview)。profile/preferredProfile:auth profile 选择。
- CLI 条目(
type: "cli"):command:要运行的可执行文件。args:模板化参数(支持{{MediaPath}}、{{Prompt}}、{{MaxChars}}等)。
capabilities:可选列表(image、audio、video)以门控共享条目。省略时的默认值:openai/anthropic/minimax→ image,google→ image+audio+video,groq→ audio。prompt、maxChars、maxBytes、timeoutSeconds、language可以按条目覆盖。
- Provider 条目(
如果未配置模型(或 enabled: false),则跳过理解;模型仍会接收原始 attachments。
Provider 认证遵循标准模型认证顺序(auth profiles、环境变量如 OPENAI_API_KEY/GROQ_API_KEY/GEMINI_API_KEY,或 models.providers.*.apiKey)。
示例:
{
tools: {
media: {
audio: {
enabled: true,
maxBytes: 20971520,
scope: {
default: "deny",
rules: [{ action: "allow", match: { chatType: "direct" } }],
},
models: [
{ provider: "openai", model: "gpt-4o-mini-transcribe" },
{ type: "cli", command: "whisper", args: ["--model", "base", "{{MediaPath}}"] },
],
},
video: {
enabled: true,
maxBytes: 52428800,
models: [{ provider: "google", model: "gemini-3-flash-preview" }],
},
},
},
}
agents.defaults.subagents 配置 sub-agent 默认值:
model:生成的 sub-agents 的默认模型(字符串或{ primary, fallbacks })。如果省略,sub-agents 继承调用者的模型,除非按 agent 或按调用覆盖。maxConcurrent:最大并发 sub-agent 运行数(默认 1)archiveAfterMinutes:N 分钟后自动归档 sub-agent sessions(默认 60;设置0以禁用)- 每 subagent 的 tool 策略:
tools.subagents.tools.allow/tools.subagents.tools.deny(deny 优先)
tools.profile 在 tools.allow/tools.deny 之前设置 基础 tool 允许列表:
minimal:仅session_statuscoding:group:fs、group:runtime、group:sessions、group:memory、imagemessaging:group:messaging、sessions_list、sessions_history、sessions_send、session_statusfull:无限制(与未设置相同)
每 agent 覆盖:agents.list[].tools.profile。
示例(默认仅 messaging,也允许 Slack + Discord tools):
{
tools: {
profile: "messaging",
allow: ["slack", "discord"],
},
}
示例(coding profile,但在所有地方拒绝 exec/process):
{
tools: {
profile: "coding",
deny: ["group:runtime"],
},
}
tools.byProvider 允许你 进一步限制 特定 providers(或单个 provider/model)的 tools。
每 agent 覆盖:agents.list[].tools.byProvider。
顺序:基础 profile → provider profile → allow/deny 策略。
Provider 键接受 provider(例如 google-antigravity)或 provider/model(例如 openai/gpt-5.2)。
示例(保持全局 coding profile,但对 Google Antigravity 使用 minimal tools):
{
tools: {
profile: "coding",
byProvider: {
"google-antigravity": { profile: "minimal" },
},
},
}
示例(provider/model 特定的允许列表):
{
tools: {
allow: ["group:fs", "group:runtime", "sessions_list"],
byProvider: {
"openai/gpt-5.2": { allow: ["group:fs", "sessions_list"] },
},
},
}
tools.allow / tools.deny 配置全局 tool 允许/拒绝策略(deny 优先)。
匹配不区分大小写,支持 * 通配符("*" 表示所有 tools)。
即使 Docker sandbox 关闭,这也会应用。
示例(在所有地方禁用 browser/canvas):
{
tools: { deny: ["browser", "canvas"] },
}
Tool groups(简写)在 全局 和 每 agent 的 tool 策略中有效:
group:runtime:exec、bash、processgroup:fs:read、write、edit、apply_patchgroup:sessions:sessions_list、sessions_history、sessions_send、sessions_spawn、session_statusgroup:memory:memory_search、memory_getgroup:web:web_search、web_fetchgroup:ui:browser、canvasgroup:automation:cron、gatewaygroup:messaging:messagegroup:nodes:nodesgroup:openclaw: 所有内置 OpenClaw tools(排除 provider plugins)
tools.elevated 控制 elevated(主机)exec 访问:
enabled:允许 elevated 模式(默认 true)allowFrom:每 channel 的允许列表(空 = 禁用)whatsapp:E.164 号码telegram:chat ids 或 usernamesdiscord:user ids 或 usernames(如果省略,则回退到channels.discord.dm.allowFrom)signal:E.164 号码imessage:handles/chat idswebchat:session ids 或 usernames
示例:
{
tools: {
elevated: {
enabled: true,
allowFrom: {
whatsapp: ["+15555550123"],
discord: ["steipete", "1234567890123"],
},
},
},
}
每 agent 覆盖(进一步限制):
{
agents: {
list: [
{
id: "family",
tools: {
elevated: { enabled: false },
},
},
],
},
}
注意:
tools.elevated是全局基线。agents.list[].tools.elevated只能进一步限制(两者都必须允许)。/elevated on|off|ask|full按 session 键存储状态;内联指令应用于单个消息。- Elevated
exec在主机上运行并绕过 sandboxing。 - Tool 策略仍然适用;如果
exec被拒绝,则无法使用 elevated。
agents.defaults.maxConcurrent 设置可以跨 sessions 并行执行的嵌入式 agent 运行的最大数量。每个 session 仍然是串行的(每次一个 session 键一个运行)。默认:1。
agents.defaults.sandbox
可选的嵌入式 agent 的 Docker sandboxing。用于非 main sessions,使它们无法访问你的主机系统。
详情:Sandboxing
默认值(如果启用):
- scope:
"agent"(每个 agent 一个容器 + workspace) - 基于 Debian bookworm-slim 的镜像
- agent workspace 访问:
workspaceAccess: "none"(默认)"none":在~/.openclaw/sandboxes下使用每 scope 的 sandbox workspace"ro":将 sandbox workspace 保留在/workspace,并将 agent workspace 以只读方式挂载到/agent(禁用write/edit/apply_patch)"rw":将 agent workspace 以读/写方式挂载到/workspace
- 自动修剪:空闲 > 24h 或年龄 > 7d
- tool 策略:仅允许
exec、process、read、write、edit、apply_patch、sessions_list、sessions_history、sessions_send、sessions_spawn、session_status(deny 优先)- 通过
tools.sandbox.tools配置,通过agents.list[].tools.sandbox.tools按 agent 覆盖 - sandbox 策略中支持 tool group 简写:
group:runtime、group:fs、group:sessions、group:memory(参见 Sandbox vs Tool Policy vs Elevated)
- 通过
- 可选的 sandboxed browser(Chromium + CDP,noVNC 观察器)
- 加固旋钮:
network、user、pidsLimit、memory、cpus、ulimits、seccompProfile、apparmorProfile
警告:scope: "shared" 意味着共享容器和共享 workspace。没有跨 session 隔离。使用 scope: "session" 进行每 session 隔离。
遗留:仍支持 perSession(true → scope: "session",false → scope: "shared")。
setupCommand 在容器创建后 运行一次(通过 sh -lc 在容器内)。
对于软件包安装,确保网络出口、可写的根 FS 和 root 用户。
{
agents: {
defaults: {
sandbox: {
mode: "non-main", // off | non-main | all
scope: "agent", // session | agent | shared (agent 是默认值)
workspaceAccess: "none", // none | ro | rw
workspaceRoot: "~/.openclaw/sandboxes",
docker: {
image: "openclaw-sandbox:bookworm-slim",
containerPrefix: "openclaw-sbx-",
workdir: "/workspace",
readOnlyRoot: true,
tmpfs: ["/tmp", "/var/tmp", "/run"],
network: "none",
user: "1000:1000",
capDrop: ["ALL"],
env: { LANG: "C.UTF-8" },
setupCommand: "apt-get update && apt-get install -y git curl jq",
// 每 agent 覆盖(多 agent):agents.list[].sandbox.docker.*
pidsLimit: 256,
memory: "1g",
memorySwap: "2g",
cpus: 1,
ulimits: {
nofile: { soft: 1024, hard: 2048 },
nproc: 256,
},
seccompProfile: "/path/to/seccomp.json",
apparmorProfile: "openclaw-sandbox",
dns: ["1.1.1.1", "8.8.8.8"],
extraHosts: ["internal.service:10.0.0.5"],
binds: ["/var/run/docker.sock:/var/run/docker.sock", "/home/user/source:/source:rw"],
},
browser: {
enabled: false,
image: "openclaw-sandbox-browser:bookworm-slim",
containerPrefix: "openclaw-sbx-browser-",
cdpPort: 9222,
vncPort: 5900,
noVncPort: 6080,
headless: false,
enableNoVnc: true,
allowHostControl: false,
allowedControlUrls: ["http://10.0.0.42:18791"],
allowedControlHosts: ["browser.lab.local", "10.0.0.42"],
allowedControlPorts: [18791],
autoStart: true,
autoStartTimeoutMs: 12000,
},
prune: {
idleHours: 24, // 0 禁用空闲修剪
maxAgeDays: 7, // 0 禁用最大年龄修剪
},
},
},
},
tools: {
sandbox: {
tools: {
allow: [
"exec",
"process",
"read",
"write",
"edit",
"apply_patch",
"sessions_list",
"sessions_history",
"sessions_send",
"sessions_spawn",
"session_status",
],
deny: ["browser", "canvas", "nodes", "cron", "discord", "gateway"],
},
},
},
}
使用以下命令构建默认 sandbox 镜像一次:
scripts/sandbox-setup.sh
注意:sandbox 容器默认为 network: "none";如果 agent 需要出站访问,请将 agents.defaults.sandbox.docker.network 设置为 "bridge"(或你的自定义网络)。
注意:入站 attachments 被暂存到活动 workspace 的 media/inbound/*。使用 workspaceAccess: "rw" 时,这意味着文件被写入 agent workspace。
注意:docker.binds 挂载额外的主机目录;全局和每 agent 的 binds 会被合并。
使用以下命令构建可选的 browser 镜像:
scripts/sandbox-browser-setup.sh
当 agents.defaults.sandbox.browser.enabled=true 时,browser tool 使用 sandboxed Chromium 实例(CDP)。如果启用了 noVNC(当 headless=false 时默认启用),noVNC URL 会被注入到 system prompt 中,以便 agent 可以引用它。
这不需要主配置中的 browser.enabled;sandbox 控制 URL 按 session 注入。
agents.defaults.sandbox.browser.allowHostControl(默认:false)允许 sandboxed sessions 通过 browser tool(target: "host")显式定位 主机 browser 控制服务器。如果你想要严格的 sandbox 隔离,请关闭此选项。
远程控制的允许列表:
allowedControlUrls:允许用于target: "custom"的精确控制 URLs。allowedControlHosts:允许的主机名(仅主机名,无端口)。allowedControlPorts:允许的端口(默认:http=80,https=443)。 默认值:所有允许列表均未设置(无限制)。allowHostControl默认为 false。
models(自定义 providers + base URLs)
OpenClaw 使用 pi-coding-agent 模型目录。你可以通过编写 ~/.openclaw/agents/<agentId>/agent/models.json 或在 OpenClaw 配置的 models.providers 下定义相同的 schema 来添加自定义 providers(LiteLLM、本地 OpenAI 兼容服务器、Anthropic 代理等)。
按 provider 概述 + 示例:/concepts/model-providers。
当 models.providers 存在时,OpenClaw 在启动时将 models.json 写入/合并到 ~/.openclaw/agents/<agentId>/agent/:
- 默认行为:merge(保留现有 providers,按名称覆盖)
- 设置
models.mode: "replace"以覆盖文件内容
通过 agents.defaults.model.primary(provider/model)选择模型。
{
agents: {
defaults: {
model: { primary: "custom-proxy/llama-3.1-8b" },
models: {
"custom-proxy/llama-3.1-8b": {},
},
},
},
models: {
mode: "merge",
providers: {
"custom-proxy": {
baseUrl: "http://localhost:4000/v1",
apiKey: "LITELLM_KEY",
api: "openai-completions",
models: [
{
id: "llama-3.1-8b",
name: "Llama 3.1 8B",
reasoning: false,
input: ["text"],
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
contextWindow: 128000,
maxTokens: 32000,
},
],
},
},
},
}
OpenCode Zen(多模型代理)
OpenCode Zen 是一个具有每模型端点的多模型 gateway。OpenClaw 使用 pi-ai 的内置 opencode provider;从 https://opencode.ai/auth 设置 OPENCODE_API_KEY(或 OPENCODE_ZEN_API_KEY)。
注意:
- 模型引用使用
opencode/<modelId>(示例:opencode/claude-opus-4-5)。 - 如果你通过
agents.defaults.models启用允许列表,请添加你计划使用的每个模型。 - 快捷方式:
openclaw onboard --auth-choice opencode-zen。
{
agents: {
defaults: {
model: { primary: "opencode/claude-opus-4-5" },
models: { "opencode/claude-opus-4-5": { alias: "Opus" } },
},
},
}
Z.AI(GLM-4.7)— provider 别名支持
Z.AI 模型可通过内置的 zai provider 使用。在你的环境中设置 ZAI_API_KEY 并通过 provider/model 引用模型。
快捷方式:openclaw onboard --auth-choice zai-api-key。
{
agents: {
defaults: {
model: { primary: "zai/glm-4.7" },
models: { "zai/glm-4.7": {} },
},
},
}
注意:
z.ai/*和z-ai/*是接受的别名,并规范化为zai/*。- 如果缺少
ZAI_API_KEY,对zai/*的请求将在运行时失败并显示认证错误。 - 示例错误:
No API key found for provider "zai". - Z.AI 的通用 API 端点是
https://api.z.ai/api/paas/v4。GLM coding 请求使用专用的 Coding 端点https://api.z.ai/api/coding/paas/v4。 内置的zaiprovider 使用 Coding 端点。如果你需要通用端点,请在models.providers中定义自定义 provider 并覆盖 base URL(参见上面的自定义 providers 部分)。 - 在文档/配置中使用假占位符;永远不要提交真实的 API keys。
Moonshot AI(Kimi)
使用 Moonshot 的 OpenAI 兼容端点:
{
env: { MOONSHOT_API_KEY: "sk-..." },
agents: {
defaults: {
model: { primary: "moonshot/kimi-k2.5" },
models: { "moonshot/kimi-k2.5": { alias: "Kimi K2.5" } },
},
},
models: {
mode: "merge",
providers: {
moonshot: {
baseUrl: "https://api.moonshot.ai/v1",
apiKey: "${MOONSHOT_API_KEY}",
api: "openai-completions",
models: [
{
id: "kimi-k2.5",
name: "Kimi K2.5",
reasoning: false,
input: ["text"],
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
contextWindow: 256000,
maxTokens: 8192,
},
],
},
},
},
}
注意:
- 在环境中设置
MOONSHOT_API_KEY或使用openclaw onboard --auth-choice moonshot-api-key。 - 模型引用:
moonshot/kimi-k2.5。 - 如果你需要中国端点,请使用
https://api.moonshot.cn/v1。
Kimi Coding
使用 Moonshot AI 的 Kimi Coding 端点(Anthropic 兼容,内置 provider):
{
env: { KIMI_API_KEY: "sk-..." },
agents: {
defaults: {
model: { primary: "kimi-coding/k2p5" },
models: { "kimi-coding/k2p5": { alias: "Kimi K2.5" } },
},
},
}
注意:
- 在环境中设置
KIMI_API_KEY或使用openclaw onboard --auth-choice kimi-code-api-key。 - 模型引用:
kimi-coding/k2p5。
Synthetic(Anthropic 兼容)
使用 Synthetic 的 Anthropic 兼容端点:
{
env: { SYNTHETIC_API_KEY: "sk-..." },
agents: {
defaults: {
model: { primary: "synthetic/hf:MiniMaxAI/MiniMax-M2.1" },
models: { "synthetic/hf:MiniMaxAI/MiniMax-M2.1": { alias: "MiniMax M2.1" } },
},
},
models: {
mode: "merge",
providers: {
synthetic: {
baseUrl: "https://api.synthetic.new/anthropic",
apiKey: "${SYNTHETIC_API_KEY}",
api: "anthropic-messages",
models: [
{
id: "hf:MiniMaxAI/MiniMax-M2.1",
name: "MiniMax M2.1",
reasoning: false,
input: ["text"],
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
contextWindow: 192000,
maxTokens: 65536,
},
],
},
},
},
}
注意:
- 设置
SYNTHETIC_API_KEY或使用openclaw onboard --auth-choice synthetic-api-key。 - 模型引用:
synthetic/hf:MiniMaxAI/MiniMax-M2.1。 - Base URL 应省略
/v1,因为 Anthropic 客户端会附加它。
本地模型(LM Studio)— 推荐设置
参见 /gateway/local-models 了解当前的本地指南。简而言之:在严肃的硬件上通过 LM Studio Responses API 运行 MiniMax M2.1;保持托管模型合并以进行回退。
MiniMax M2.1
直接使用 MiniMax M2.1,无需 LM Studio:
{
agent: {
model: { primary: "minimax/MiniMax-M2.1" },
models: {
"anthropic/claude-opus-4-5": { alias: "Opus" },
"minimax/MiniMax-M2.1": { alias: "Minimax" },
},
},
models: {
mode: "merge",
providers: {
minimax: {
baseUrl: "https://api.minimax.io/anthropic",
apiKey: "${MINIMAX_API_KEY}",
api: "anthropic-messages",
models: [
{
id: "MiniMax-M2.1",
name: "MiniMax M2.1",
reasoning: false,
input: ["text"],
// 定价:如果你需要精确的成本跟踪,请在 models.json 中更新。
cost: { input: 15, output: 60, cacheRead: 2, cacheWrite: 10 },
contextWindow: 200000,
maxTokens: 8192,
},
],
},
},
},
}
注意:
- 在环境中设置
MINIMAX_API_KEY或使用openclaw onboard --auth-choice minimax-api。 - 可用模型:
MiniMax-M2.1(默认)。 - 如果你需要精确的成本跟踪,请在
models.json中更新定价。
Cerebras(GLM 4.6 / 4.7)
通过 Cerebras 的 OpenAI 兼容端点使用:
{
env: { CEREBRAS_API_KEY: "sk-..." },
agents: {
defaults: {
model: {
primary: "cerebras/zai-glm-4.7",
fallbacks: ["cerebras/zai-glm-4.6"],
},
models: {
"cerebras/zai-glm-4.7": { alias: "GLM 4.7 (Cerebras)" },
"cerebras/zai-glm-4.6": { alias: "GLM 4.6 (Cerebras)" },
},
},
},
models: {
mode: "merge",
providers: {
cerebras: {
baseUrl: "https://api.cerebras.ai/v1",
apiKey: "${CEREBRAS_API_KEY}",
api: "openai-completions",
models: [
{ id: "zai-glm-4.7", name: "GLM 4.7 (Cerebras)" },
{ id: "zai-glm-4.6", name: "GLM 4.6 (Cerebras)" },
],
},
},
},
}
注意:
- 使用
cerebras/zai-glm-4.7用于 Cerebras;使用zai/glm-4.7用于 Z.AI 直连。 - 在环境或配置中设置
CEREBRAS_API_KEY。
注意:
- 支持的 APIs:
openai-completions、openai-responses、anthropic-messages、google-generative-ai - 使用
authHeader: true+headers来满足自定义认证需求。 - 如果你想将
models.json存储在其他位置,请使用OPENCLAW_AGENT_DIR(或PI_CODING_AGENT_DIR)覆盖 agent 配置根目录(默认:~/.openclaw/agents/main/agent)。
session
控制 session 作用域、重置策略、重置触发器以及 session 存储的写入位置。
{
session: {
scope: "per-sender",
dmScope: "main",
identityLinks: {
alice: ["telegram:123456789", "discord:987654321012345678"],
},
reset: {
mode: "daily",
atHour: 4,
idleMinutes: 60,
},
resetByType: {
thread: { mode: "daily", atHour: 4 },
dm: { mode: "idle", idleMinutes: 240 },
group: { mode: "idle", idleMinutes: 120 },
},
resetTriggers: ["/new", "/reset"],
// 默认已经是每 agent 在 ~/.openclaw/agents/<agentId>/sessions/sessions.json 下
// 你可以使用 {agentId} 模板覆盖:
store: "~/.openclaw/agents/{agentId}/sessions/sessions.json",
// 直接聊天折叠为 agent:<agentId>:<mainKey>(默认:"main")。
mainKey: "main",
agentToAgent: {
// 请求者/目标之间的最大乒乓回复轮次(0–5)。
maxPingPongTurns: 5,
},
sendPolicy: {
rules: [{ action: "deny", match: { channel: "discord", chatType: "group" } }],
default: "allow",
},
},
}
字段:
mainKey:直接聊天桶键(默认:"main")。当你想”重命名”主 DM 线程而不更改agentId时很有用。- Sandbox 注意:
agents.defaults.sandbox.mode: "non-main"使用此键来检测主 session。任何不匹配mainKey的 session 键(groups/channels)都会被沙箱化。
- Sandbox 注意:
dmScope:DM sessions 如何分组(默认:"main")。main:所有 DMs 共享主 session 以保持连续性。per-peer:按发送者 id 跨 channels 隔离 DMs。per-channel-peer:按 channel + 发送者隔离 DMs(推荐用于多用户收件箱)。per-account-channel-peer:按 account + channel + 发送者隔离 DMs(推荐用于多账户收件箱)。
identityLinks:将规范 ids 映射到 provider 前缀的 peers,以便在使用per-peer、per-channel-peer或per-account-channel-peer时,同一个人跨 channels 共享 DM session。- 示例:
alice: ["telegram:123456789", "discord:987654321012345678"]。
- 示例:
reset:主重置策略。默认在 gateway 主机本地时间凌晨 4:00 每日重置。mode:daily或idle(默认:当reset存在时为daily)。atHour:每日重置边界的本地小时(0-23)。idleMinutes:滑动空闲窗口(分钟)。当同时配置 daily + idle 时,先到期的获胜。
resetByType:dm、group和thread的每 session 覆盖。- 如果你只设置遗留的
session.idleMinutes而没有任何reset/resetByType,OpenClaw 会保持仅空闲模式以保持向后兼容性。
- 如果你只设置遗留的
heartbeatIdleMinutes:heartbeat 检查的可选空闲覆盖(启用时每日重置仍然适用)。agentToAgent.maxPingPongTurns:请求者/目标之间的最大回复轮次(0–5,默认 5)。sendPolicy.default:当没有规则匹配时的allow或deny回退。sendPolicy.rules[]:按channel、chatType(direct|group|room)或keyPrefix(例如cron:)匹配。首个 deny 获胜;否则 allow。
skills(skills 配置)
控制捆绑的允许列表、安装偏好、额外 skill 文件夹和每 skill 覆盖。适用于 捆绑 skills 和 ~/.openclaw/skills(workspace skills 在名称冲突时仍然获胜)。
字段:
allowBundled:仅用于 捆绑 skills 的可选允许列表。如果设置,只有这些捆绑 skills 符合条件(managed/workspace skills 不受影响)。load.extraDirs:要扫描的额外 skill 目录(最低优先级)。install.preferBrew:在可用时优先使用 brew 安装程序(默认:true)。install.nodeManager:node 安装程序偏好(npm|pnpm|yarn,默认:npm)。entries.<skillKey>:每 skill 的配置覆盖。
每 skill 字段:
enabled:设置false以禁用 skill,即使它是捆绑/已安装的。env:为 agent 运行注入的环境变量(仅当尚未设置时)。apiKey:声明主环境变量的 skills 的可选便利(例如nano-banana-pro→GEMINI_API_KEY)。
示例:
{
skills: {
allowBundled: ["gemini", "peekaboo"],
load: {
extraDirs: ["~/Projects/agent-scripts/skills", "~/Projects/oss/some-skill-pack/skills"],
},
install: {
preferBrew: true,
nodeManager: "npm",
},
entries: {
"nano-banana-pro": {
apiKey: "GEMINI_KEY_HERE",
env: {
GEMINI_API_KEY: "GEMINI_KEY_HERE",
},
},
peekaboo: { enabled: true },
sag: { enabled: false },
},
},
}
plugins(扩展)
控制 plugin 发现、allow/deny 和每 plugin 配置。Plugins 从 ~/.openclaw/extensions、<workspace>/.openclaw/extensions 以及任何 plugins.load.paths 条目加载。配置更改需要重启 gateway。
参见 /plugin 了解完整用法。
字段:
enabled:plugin 加载的主开关(默认:true)。allow:可选的 plugin id 白名单;设置后,仅加载列出的 plugins。deny:可选的 plugin id 黑名单(deny 优先)。load.paths:要加载的额外 plugin 文件或目录(绝对路径或~)。entries.<pluginId>:每 plugin 覆盖配置。enabled:设为false可禁用。config:plugin 特定的配置对象(如提供,由 plugin 验证)。
示例:
{
plugins: {
enabled: true,
allow: ["voice-call"],
load: {
paths: ["~/Projects/oss/voice-call-extension"],
},
entries: {
"voice-call": {
enabled: true,
config: {
provider: "twilio",
},
},
},
},
}
browser(openclaw 管理的浏览器)
OpenClaw 可以为 openclaw 启动一个专用、隔离的 Chrome/Brave/Edge/Chromium 实例,并暴露一个小型 loopback 控制服务。
Profiles 可以通过 profiles.<name>.cdpUrl 指向远程 Chromium 浏览器。远程 profiles 仅支持附加(禁用 start/stop/reset)。
browser.cdpUrl 保留用于旧版单 profile 配置,以及作为仅设置 cdpPort 的 profiles 的基础 scheme/host。
默认值:
- enabled:
true - evaluateEnabled:
true(设为false可禁用act:evaluate和wait --fn) - control service: 仅 loopback(端口从
gateway.port派生,默认18791) - CDP URL:
http://127.0.0.1:18792(control service + 1,旧版单 profile) - profile color:
#FF4500(lobster-orange) - Note: control server 由运行中的 gateway 启动(OpenClaw.app 菜单栏,或
openclaw gateway)。 - Auto-detect 顺序:默认浏览器(如果是 Chromium 系);否则 Chrome → Brave → Edge → Chromium → Chrome Canary。
{
browser: {
enabled: true,
evaluateEnabled: true,
// cdpUrl: "http://127.0.0.1:18792", // legacy single-profile override
defaultProfile: "chrome",
profiles: {
openclaw: { cdpPort: 18800, color: "#FF4500" },
work: { cdpPort: 18801, color: "#0066CC" },
remote: { cdpUrl: "http://10.0.0.42:9222", color: "#00AA00" },
},
color: "#FF4500",
// Advanced:
// headless: false,
// noSandbox: false,
// executablePath: "/Applications/Brave Browser.app/Contents/MacOS/Brave Browser",
// attachOnly: false, // set true when tunneling a remote CDP to localhost
},
}
ui(外观)
可选的强调色,用于原生应用的 UI chrome(例如 Talk Mode 气泡色调)。
如果未设置,客户端会回退到柔和的浅蓝色。
{
ui: {
seamColor: "#FF4500", // hex (RRGGBB or #RRGGBB)
// Optional: Control UI assistant identity override.
// If unset, the Control UI uses the active agent identity (config or IDENTITY.md).
assistant: {
name: "OpenClaw",
avatar: "CB", // emoji, short text, or image URL/data URI
},
},
}
gateway(Gateway 服务器模式 + 绑定)
使用 gateway.mode 显式声明此机器是否应运行 Gateway。
默认值:
- mode: 未设置(视为”不自动启动”)
- bind:
loopback - port:
18789(WS + HTTP 单端口)
{
gateway: {
mode: "local", // or "remote"
port: 18789, // WS + HTTP multiplex
bind: "loopback",
// controlUi: { enabled: true, basePath: "/openclaw" }
// auth: { mode: "token", token: "your-token" } // token gates WS + Control UI access
// tailscale: { mode: "off" | "serve" | "funnel" }
},
}
Control UI base path:
gateway.controlUi.basePath设置 Control UI 服务的 URL 前缀。- 示例:
"/ui"、"/openclaw"、"/apps/openclaw"。 - 默认:根路径(
/)(不变)。 gateway.controlUi.allowInsecureAuth允许在省略设备身份时对 Control UI 使用仅 token 认证(通常通过 HTTP)。默认:false。优先使用 HTTPS(Tailscale Serve)或127.0.0.1。gateway.controlUi.dangerouslyDisableDeviceAuth禁用 Control UI 的设备身份检查(仅 token/password)。默认:false。仅紧急情况使用。
相关文档:
Trusted proxies:
gateway.trustedProxies:在 Gateway 前终止 TLS 的反向代理 IP 列表。- 当连接来自这些 IP 之一时,OpenClaw 使用
x-forwarded-for(或x-real-ip)来确定客户端 IP,用于本地 pairing 检查和 HTTP auth/local 检查。 - 仅列出你完全控制的代理,并确保它们覆写传入的
x-forwarded-for。
Notes:
openclaw gateway拒绝启动,除非gateway.mode设为local(或你传递覆盖标志)。gateway.port控制用于 WebSocket + HTTP(control UI、hooks、A2UI)的单个多路复用端口。- OpenAI Chat Completions endpoint:默认禁用;使用
gateway.http.endpoints.chatCompletions.enabled: true启用。 - 优先级:
--port>OPENCLAW_GATEWAY_PORT>gateway.port> 默认18789。 - Gateway auth 默认必需(token/password 或 Tailscale Serve 身份)。非 loopback 绑定需要共享 token/password。
- onboarding wizard 默认生成 gateway token(即使在 loopback 上)。
gateway.remote.token仅用于远程 CLI 调用;它不启用本地 gateway auth。gateway.token被忽略。
Auth and Tailscale:
gateway.auth.mode设置握手要求(token或password)。未设置时,假定为 token auth。gateway.auth.token存储用于 token auth 的共享 token(由同一机器上的 CLI 使用)。- 当设置
gateway.auth.mode时,仅接受该方法(加上可选的 Tailscale headers)。 gateway.auth.password可以在此设置,或通过OPENCLAW_GATEWAY_PASSWORD(推荐)。gateway.auth.allowTailscale允许 Tailscale Serve 身份 headers(tailscale-user-login)在请求到达 loopback 且带有x-forwarded-for、x-forwarded-proto和x-forwarded-host时满足 auth。 OpenClaw 在接受前通过tailscale whois解析x-forwarded-for地址来验证身份。 当为true时,Serve 请求不需要 token/password;设为false以要求显式凭据。 当tailscale.mode = "serve"且 auth mode 不是password时,默认为true。gateway.tailscale.mode: "serve"使用 Tailscale Serve(仅 tailnet,loopback 绑定)。gateway.tailscale.mode: "funnel"公开暴露 dashboard;需要 auth。gateway.tailscale.resetOnExit在关闭时重置 Serve/Funnel 配置。
Remote client defaults(CLI):
gateway.remote.url在gateway.mode = "remote"时为 CLI 调用设置默认 Gateway WebSocket URL。gateway.remote.transport选择 macOS 远程传输(ssh默认,direct用于 ws/wss)。 当为direct时,gateway.remote.url必须是ws://或wss://。ws://host默认端口18789。gateway.remote.token为远程调用提供 token(不设置则无 auth)。gateway.remote.password为远程调用提供 password(不设置则无 auth)。
macOS app 行为:
- OpenClaw.app 监视
~/.openclaw/openclaw.json,当gateway.mode或gateway.remote.url更改时实时切换模式。 - 如果
gateway.mode未设置但gateway.remote.url已设置,macOS app 将其视为 remote 模式。 - 当你在 macOS app 中更改连接模式时,它会将
gateway.mode(以及 remote 模式下的gateway.remote.url+gateway.remote.transport)写回配置文件。
{
gateway: {
mode: "remote",
remote: {
url: "ws://gateway.tailnet:18789",
token: "your-token",
password: "your-password",
},
},
}
Direct transport 示例(macOS app):
{
gateway: {
mode: "remote",
remote: {
transport: "direct",
url: "wss://gateway.example.ts.net",
token: "your-token",
},
},
}
gateway.reload(配置热重载)
Gateway 监视 ~/.openclaw/openclaw.json(或 OPENCLAW_CONFIG_PATH)并自动应用更改。
模式:
hybrid(默认):热应用安全更改;关键更改需重启 Gateway。hot:仅应用热安全更改;需要重启时记录日志。restart:任何配置更改时重启 Gateway。off:禁用热重载。
{
gateway: {
reload: {
mode: "hybrid",
debounceMs: 300,
},
},
}
Hot reload matrix(文件 + 影响)
监视的文件:
~/.openclaw/openclaw.json(或OPENCLAW_CONFIG_PATH)
热应用(无需完整 gateway 重启):
hooks(webhook auth/path/mappings)+hooks.gmail(Gmail watcher 重启)browser(browser control server 重启)cron(cron service 重启 + 并发更新)agents.defaults.heartbeat(heartbeat runner 重启)web(WhatsApp web channel 重启)telegram、discord、signal、imessage(channel 重启)agent、models、routing、messages、session、whatsapp、logging、skills、ui、talk、identity、wizard(动态读取)
需要完整 Gateway 重启:
gateway(port/bind/auth/control UI/tailscale)bridge(legacy)discoverycanvasHostplugins- 任何未知/不支持的配置路径(为安全起见默认重启)
Multi-instance isolation(多实例隔离)
要在一台主机上运行多个 gateways(用于冗余或救援 bot),隔离每实例状态 + 配置并使用唯一端口:
OPENCLAW_CONFIG_PATH(每实例配置)OPENCLAW_STATE_DIR(sessions/creds)agents.defaults.workspace(memories)gateway.port(每实例唯一)
便捷标志(CLI):
openclaw --dev …→ 使用~/.openclaw-dev+ 从基础19001偏移端口openclaw --profile <name> …→ 使用~/.openclaw-<name>(端口通过 config/env/flags)
参见 Gateway runbook 了解派生的端口映射(gateway/browser/canvas)。 参见 Multiple gateways 了解 browser/CDP 端口隔离详情。
示例:
OPENCLAW_CONFIG_PATH=~/.openclaw/a.json \
OPENCLAW_STATE_DIR=~/.openclaw-a \
openclaw gateway --port 19001
hooks(Gateway webhooks)
在 Gateway HTTP 服务器上启用简单的 HTTP webhook endpoint。
默认值:
- enabled:
false - path:
/hooks - maxBodyBytes:
262144(256 KB)
{
hooks: {
enabled: true,
token: "shared-secret",
path: "/hooks",
presets: ["gmail"],
transformsDir: "~/.openclaw/hooks",
mappings: [
{
match: { path: "gmail" },
action: "agent",
wakeMode: "now",
name: "Gmail",
sessionKey: "hook:gmail:{{messages[0].id}}",
messageTemplate: "From: {{messages[0].from}}\nSubject: {{messages[0].subject}}\n{{messages[0].snippet}}",
deliver: true,
channel: "last",
model: "openai/gpt-5.2-mini",
},
],
},
}
请求必须包含 hook token:
Authorization: Bearer <token>或x-openclaw-token: <token>或?token=<token>
Endpoints:
POST /hooks/wake→{ text, mode?: "now"|"next-heartbeat" }POST /hooks/agent→{ message, name?, sessionKey?, wakeMode?, deliver?, channel?, to?, model?, thinking?, timeoutSeconds? }POST /hooks/<name>→ 通过hooks.mappings解析
/hooks/agent 总是将摘要发布到主 session(并可通过 wakeMode: "now" 可选触发立即 heartbeat)。
Mapping notes:
match.path匹配/hooks后的子路径(例如/hooks/gmail→gmail)。match.source匹配 payload 字段(例如{ source: "gmail" }),这样你可以使用通用的/hooks/ingest路径。- 像
{{messages[0].subject}}这样的模板从 payload 读取。 transform可以指向返回 hook action 的 JS/TS 模块。deliver: true将最终回复发送到 channel;channel默认为last(回退到 WhatsApp)。- 如果没有先前的投递路由,显式设置
channel+to(Telegram/Discord/Google Chat/Slack/Signal/iMessage/MS Teams 需要)。 model覆盖此 hook 运行的 LLM(provider/model或别名;如果设置了agents.defaults.models则必须被允许)。
Gmail helper config(由 openclaw webhooks gmail setup / run 使用):
{
hooks: {
gmail: {
account: "[email protected]",
topic: "projects/<project-id>/topics/gog-gmail-watch",
subscription: "gog-gmail-watch-push",
pushToken: "shared-push-token",
hookUrl: "http://127.0.0.1:18789/hooks/gmail",
includeBody: true,
maxBytes: 20000,
renewEveryMinutes: 720,
serve: { bind: "127.0.0.1", port: 8788, path: "/" },
tailscale: { mode: "funnel", path: "/gmail-pubsub" },
// Optional: use a cheaper model for Gmail hook processing
// Falls back to agents.defaults.model.fallbacks, then primary, on auth/rate-limit/timeout
model: "openrouter/meta-llama/llama-3.3-70b-instruct:free",
// Optional: default thinking level for Gmail hooks
thinking: "off",
},
},
}
Model override for Gmail hooks:
hooks.gmail.model指定用于 Gmail hook 处理的 model(默认为 session primary)。- 接受
provider/model引用或来自agents.defaults.models的别名。 - 在 auth/rate-limit/timeouts 时回退到
agents.defaults.model.fallbacks,然后是agents.defaults.model.primary。 - 如果设置了
agents.defaults.models,将 hooks model 包含在 allowlist 中。 - 启动时,如果配置的 model 不在 model catalog 或 allowlist 中会发出警告。
hooks.gmail.thinking设置 Gmail hooks 的默认 thinking 级别,并被每 hook 的thinking覆盖。
Gateway auto-start:
- 如果
hooks.enabled=true且设置了hooks.gmail.account,Gateway 在启动时启动gog gmail watch serve并自动续订 watch。 - 设置
OPENCLAW_SKIP_GMAIL_WATCHER=1可禁用 auto-start(用于手动运行)。 - 避免在 Gateway 旁边运行单独的
gog gmail watch serve;它会因listen tcp 127.0.0.1:8788: bind: address already in use失败。
Note: 当 tailscale.mode 开启时,OpenClaw 默认 serve.path 为 /,这样 Tailscale 可以正确代理 /gmail-pubsub(它会剥离 set-path 前缀)。
如果你需要后端接收带前缀的路径,设置 hooks.gmail.tailscale.target 为完整 URL(并对齐 serve.path)。
canvasHost(LAN/tailnet Canvas 文件服务器 + 实时重载)
Gateway 通过 HTTP 提供 HTML/CSS/JS 目录,这样 iOS/Android nodes 可以简单地 canvas.navigate 到它。
默认 root: ~/.openclaw/workspace/canvas
默认 port: 18793(选择此端口以避免 openclaw browser CDP 端口 18792)
服务器监听 gateway bind host(LAN 或 Tailnet),这样 nodes 可以访问它。
服务器:
- 提供
canvasHost.root下的文件 - 向提供的 HTML 注入一个小型实时重载客户端
- 监视目录并通过
/__openclaw__/ws的 WebSocket endpoint 广播重载 - 当目录为空时自动创建启动
index.html(这样你可以立即看到内容) - 还在
/__openclaw__/a2ui/提供 A2UI,并作为canvasHostUrl广告给 nodes(nodes 总是用它来访问 Canvas/A2UI)
如果目录很大或遇到 EMFILE,禁用实时重载(和文件监视):
- config:
canvasHost: { liveReload: false }
{
canvasHost: {
root: "~/.openclaw/workspace/canvas",
port: 18793,
liveReload: true,
},
}
对 canvasHost.* 的更改需要 gateway 重启(配置重载会重启)。
禁用方式:
- config:
canvasHost: { enabled: false } - env:
OPENCLAW_SKIP_CANVAS_HOST=1
bridge(legacy TCP bridge,已移除)
当前构建不再包含 TCP bridge 监听器;bridge.* 配置键被忽略。
Nodes 通过 Gateway WebSocket 连接。本节保留用于历史参考。
Legacy 行为:
- Gateway 可以为 nodes(iOS/Android)暴露一个简单的 TCP bridge,通常在端口
18790。
默认值:
- enabled:
true - port:
18790 - bind:
lan(绑定到0.0.0.0)
Bind 模式:
lan:0.0.0.0(可在任何接口上访问,包括 LAN/Wi‑Fi 和 Tailscale)tailnet: 仅绑定到机器的 Tailscale IP(推荐用于 Vienna ⇄ London)loopback:127.0.0.1(仅本地)auto: 如果存在则优先使用 tailnet IP,否则使用lan
TLS:
bridge.tls.enabled: 为 bridge 连接启用 TLS(启用时仅 TLS)。bridge.tls.autoGenerate: 当没有 cert/key 时生成自签名证书(默认:true)。bridge.tls.certPath/bridge.tls.keyPath: bridge 证书 + 私钥的 PEM 路径。bridge.tls.caPath: 可选的 PEM CA bundle(自定义 roots 或未来的 mTLS)。
当启用 TLS 时,Gateway 在 discovery TXT 记录中广告 bridgeTls=1 和 bridgeTlsSha256,这样 nodes 可以固定证书。
手动连接使用 trust-on-first-use,如果尚未存储指纹。
自动生成的证书需要 PATH 中有 openssl;如果生成失败,bridge 将不会启动。
{
bridge: {
enabled: true,
port: 18790,
bind: "tailnet",
tls: {
enabled: true,
// Uses ~/.openclaw/bridge/tls/bridge-{cert,key}.pem when omitted.
// certPath: "~/.openclaw/bridge/tls/bridge-cert.pem",
// keyPath: "~/.openclaw/bridge/tls/bridge-key.pem"
},
},
}
discovery.mdns(Bonjour / mDNS 广播模式)
控制 LAN mDNS discovery 广播(_openclaw-gw._tcp)。
minimal(默认):从 TXT 记录中省略cliPath+sshPortfull: 在 TXT 记录中包含cliPath+sshPortoff: 完全禁用 mDNS 广播- Hostname: 默认为
openclaw(广告openclaw.local)。使用OPENCLAW_MDNS_HOSTNAME覆盖。
{
discovery: { mdns: { mode: "minimal" } },
}
discovery.wideArea(Wide-Area Bonjour / unicast DNS‑SD)
当启用时,Gateway 使用配置的 discovery domain(例如:openclaw.internal.)在 ~/.openclaw/dns/ 下为 _openclaw-gw._tcp 写入 unicast DNS-SD zone。
要使 iOS/Android 跨网络发现(Vienna ⇄ London),将此与以下配对:
- gateway 主机上的 DNS 服务器,提供你选择的 domain(推荐 CoreDNS)
- Tailscale split DNS,这样客户端通过 gateway DNS 服务器解析该 domain
一次性设置助手(gateway 主机):
openclaw dns setup --apply
{
discovery: { wideArea: { enabled: true } },
}
Template variables(模板变量)
模板占位符在 tools.media.*.models[].args 和 tools.media.models[].args(以及任何未来的模板化参数字段)中展开。
| 变量 | 描述 |
|---|---|
{{Body}} | 完整入站消息正文 |
{{RawBody}} | 原始入站消息正文(无历史/发送者包装;最适合命令解析) |
{{BodyStripped}} | 去除群组提及的正文(agents 的最佳默认值) |
{{From}} | 发送者标识符(WhatsApp 为 E.164;每个 channel 可能不同) |
{{To}} | 目标标识符 |
{{MessageSid}} | Channel 消息 id(如果可用) |
{{SessionId}} | 当前 session UUID |
{{IsNewSession}} | 创建新 session 时为 "true" |
{{MediaUrl}} | 入站媒体伪 URL(如果存在) |
{{MediaPath}} | 本地媒体路径(如果已下载) |
{{MediaType}} | 媒体类型(image/audio/document/…) |
{{Transcript}} | 音频转录(启用时) |
{{Prompt}} | CLI 条目的已解析媒体 prompt |
{{MaxChars}} | CLI 条目的已解析最大输出字符数 |
{{ChatType}} | "direct" 或 "group" |
{{GroupSubject}} | 群组主题(尽力而为) |
{{GroupMembers}} | 群组成员预览(尽力而为) |
{{SenderName}} | 发送者显示名称(尽力而为) |
{{SenderE164}} | 发送者电话号码(尽力而为) |
{{Provider}} | Provider 提示(whatsapp | telegram | discord | googlechat | slack | signal | imessage | msteams | webchat | …) |
Cron(Gateway 调度器)
Cron 是 Gateway 拥有的调度器,用于唤醒和计划任务。参见 Cron jobs 了解功能概述和 CLI 示例。
{
cron: {
enabled: true,
maxConcurrentRuns: 2,
},
}