chore(i18n): refresh zh-CN translations

This commit is contained in:
openclaw-docs-i18n[bot] 2026-04-23 18:32:54 +00:00
parent 30f58a10fb
commit 5a2801681f
7 changed files with 2572 additions and 2664 deletions

View File

@ -1,20 +1,18 @@
---
read_when:
- 正在开发 Discord 渠道功能
- 开发 Discord 渠道功能
summary: Discord 机器人支持状态、功能和配置
title: Discord
x-i18n:
generated_at: "2026-04-23T08:25:07Z"
generated_at: "2026-04-23T18:24:14Z"
model: gpt-5.4
provider: openai
source_hash: 1160a0b221bc3251722a81c00c65ee7c2001efce345248727f1f3c8580a0e953
source_hash: 574f23a3a6388b02f92dba42a8b4fa97ca45dd52ac57e2be24c4dc5c1abf0790
source_path: channels/discord.md
workflow: 15
---
# DiscordBot API
状态:已就绪,可通过官方 Discord gateway 用于私信和服务器频道。
已准备好通过官方 Discord gateway 支持私信和服务器频道。
<CardGroup cols={3}>
<Card title="配对" icon="link" href="/zh-CN/channels/pairing">
@ -24,17 +22,17 @@ x-i18n:
原生命令行为和命令目录。
</Card>
<Card title="渠道故障排除" icon="wrench" href="/zh-CN/channels/troubleshooting">
跨渠道诊断修复流程。
跨渠道诊断修复流程。
</Card>
</CardGroup>
## 快速开始
你需要创建一个带机器人的新应用,将机器人添加到你的服务器,并将其与 OpenClaw 配对。我们建议将你的机器人添加到你自己的私有服务器。如果你还没有服务器,请先[创建一个](https://support.discord.com/hc/en-us/articles/204849977-How-do-I-create-a-server)(选择 **Create My Own > For me and my friends**)。
你需要创建一个带机器人的新应用,将机器人添加到你的服务器,并将其与 OpenClaw 配对。我们建议将你的机器人添加到你自己的私人服务器。如果你还没有,请先[创建一个](https://support.discord.com/hc/en-us/articles/204849977-How-do-I-create-a-server)(选择 **Create My Own > For me and my friends**)。
<Steps>
<Step title="创建 Discord 应用和机器人">
前往 [Discord Developer Portal](https://discord.com/developers/applications),然后点击 **New Application**。给它起一个类似 “OpenClaw” 的名字。
前往 [Discord Developer Portal](https://discord.com/developers/applications)点击 **New Application**。给它起一个类似 “OpenClaw” 的名字。
点击侧边栏中的 **Bot**。将 **Username** 设置为你对 OpenClaw 智能体的称呼。
@ -44,24 +42,24 @@ x-i18n:
仍然停留在 **Bot** 页面,向下滚动到 **Privileged Gateway Intents** 并启用:
- **Message Content Intent**(必需)
- **Server Members Intent**(推荐;角色允许列表和名称到 ID 匹配需要它
- **Server Members Intent**(推荐;角色 allowlist 和名称到 ID 匹配需要
- **Presence Intent**(可选;仅在需要在线状态更新时启用)
</Step>
<Step title="复制你的机器人令牌">
向上滚动回 **Bot** 页面并点击 **Reset Token**
向上滚动回 **Bot** 页面顶部并点击 **Reset Token**
<Note>
尽管名字叫这样,这会生成你的第一个令牌——并没有任何内容被“重置”。
尽管名字如此,这会生成你的第一个令牌——并没有任何东西被“重置”。
</Note>
复制该令牌并将其保存到某处。这就是你的 **Bot Token**,你很快就会用到它。
复制该令牌并将其保存在某处。这就是你的 **Bot Token**,稍后你会用到它。
</Step>
<Step title="生成邀请 URL并将机器人添加到你的服务器">
点击侧边栏中的 **OAuth2**。你将生成一个带有正确权限的邀请 URL用于将机器人添加到你的服务器。
<Step title="生成邀请 URL 并将机器人添加到你的服务器">
点击侧边栏中的 **OAuth2**。你将生成一个带有正确权限的邀请 URL以便将机器人添加到你的服务器。
向下滚动到 **OAuth2 URL Generator** 并启用:
@ -79,15 +77,15 @@ x-i18n:
- Attach Files
- Add Reactions可选
这是普通文本频道的基础权限集。如果你计划在 Discord 线程中发帖,包括会创建或继续线程的论坛或媒体频道工作流,还要启用 **Send Messages in Threads**
复制底部生成的 URL将其粘贴到浏览器中选择你的服务器然后点击 **Continue** 进行连接。现在你应该能在 Discord 服务器中看到你的机器人。
这是普通文本频道所需的基础权限集。如果你计划在 Discord 线程中发帖,包括会创建或继续线程的论坛或媒体频道工作流,还要启用 **Send Messages in Threads**
复制底部生成的 URL将其粘贴到浏览器中选择你的服务器然后点击 **Continue** 完成连接。现在你应该能在 Discord 服务器中看到你的机器人。
</Step>
<Step title="启用 Developer Mode 并收集你的 ID">
回到 Discord 应用中,你需要启用 Developer Mode这样你才能复制内部 ID。
<Step title="启用开发者模式并收集你的 ID">
回到 Discord 应用中,你需要启用开发者模式,这样才能复制内部 ID。
1. 点击 **User Settings**(头像旁边的齿轮图标)→ **Advanced** → 打开 **Developer Mode**
1. 点击 **User Settings**头像旁边的齿轮图标)→ **Advanced** → 打开 **Developer Mode**
2. 在侧边栏中右键点击你的**服务器图标** → **Copy Server ID**
3. 右键点击你自己的**头像** → **Copy User ID**
@ -96,14 +94,14 @@ x-i18n:
</Step>
<Step title="允许来自服务器成员的私信">
为了让配对正常工作Discord 需要允许你的机器人向你发送私信。右键点击你的**服务器图标** → **Privacy Settings** → 打开 **Direct Messages**
为了让配对生效Discord 需要允许你的机器人向你发送私信。右键点击你的**服务器图标** → **Privacy Settings** → 打开 **Direct Messages**
样服务器成员(包括机器人)就可以向你发送私信。如果你想通过 OpenClaw 使用 Discord 私信,请保持此设置开启。如果你只打算使用服务器频道,那么配对完成后可以关闭私信。
会允许服务器成员(包括机器人)向你发送私信。如果你想通过 OpenClaw 使用 Discord 私信,请保持启用。如果你只打算使用服务器频道,则可以在配对完成后关闭私信。
</Step>
<Step title="安全设置你的机器人令牌(不要在聊天中发送">
你的 Discord 机器人令牌是机密信息(就像密码一样)。在给你的智能体发送消息之前,先在运行 OpenClaw 的机器上设置它。
<Step title="安全设置你的机器人令牌(不要在聊天中发送)">
你的 Discord 机器人令牌是机密信息(类似密码)。在给你的智能体发消息之前,请先在运行 OpenClaw 的机器上设置它。
```bash
export DISCORD_BOT_TOKEN="YOUR_BOT_TOKEN"
@ -113,7 +111,7 @@ openclaw config set channels.discord.enabled true --strict-json
openclaw gateway
```
如果 OpenClaw 已作为后台服务运行,请通过 OpenClaw Mac 应用重启,或停止并重新启动 `openclaw gateway run` 进程。
如果 OpenClaw 已作为后台服务运行,请通过 OpenClaw Mac 应用重启,或停止并重新启动 `openclaw gateway run` 进程。
</Step>
@ -121,9 +119,9 @@ openclaw gateway
<Tabs>
<Tab title="询问你的智能体">
在任何现有渠道(例如 Telegram上与你的 OpenClaw 智能体聊天,并告诉它。如果 Discord 是你的第一个渠道,请改用 CLI / 配置标签页。
在任意现有渠道(例如 Telegram中与你的 OpenClaw 智能体聊天并告诉它。如果 Discord 是你的第一个渠道,请改用 CLI / 配置标签页。
> “我已经在配置中设置了 Discord 机器人令牌。请使用 User ID `<user_id>` 和 Server ID `<server_id>` 完成 Discord 设置。”
> “我已经在配置中设置了 Discord 机器人令牌。请使用 User ID `<user_id>` 和 Server ID `<server_id>` 完成 Discord 设置。”
</Tab>
<Tab title="CLI / 配置">
如果你更喜欢基于文件的配置,请设置:
@ -157,11 +155,11 @@ DISCORD_BOT_TOKEN=...
</Step>
<Step title="批准首次私信配对">
等待 Gateway 网关运行起来,然后在 Discord 中向你的机器人发送私信。它会回复一个配对码。
等待 Gateway 网关运行后,在 Discord 中向你的机器人发送私信。它会回复一个配对码。
<Tabs>
<Tab title="询问你的智能体">
在你现有的渠道中,配对码发送给你的智能体:
将配对码发送给你在现有渠道中的智能体:
> “批准这个 Discord 配对码:`<CODE>`”
</Tab>
@ -177,27 +175,27 @@ openclaw pairing approve discord <CODE>
配对码会在 1 小时后过期。
现在你应该已经可以通过 Discord 私信与你的智能体聊天了。
现在你应该可以通过私信在 Discord 中与你的智能体聊天了。
</Step>
</Steps>
<Note>
令牌解析具有账户感知能力。配置中的令牌值优先于环境变量回退。`DISCORD_BOT_TOKEN` 仅用于默认账户。
对于高级出站调用(消息工具/渠道操作),显式的每次调用 `token` 会用于该次调用。这适用于发送以及读取/探测类操作(例如 read/search/fetch/thread/pins/permissions。账户策略/重试设置仍来自活动运行时快照中选账户。
对于高级出站调用(消息工具/渠道操作),每次调用都会使用该次调用显式提供的 `token`。这适用于发送以及读取/探测类操作(例如 read/search/fetch/thread/pins/permissions。账户策略/重试设置仍来自活动运行时快照中选定的账户。
</Note>
## 推荐:设置服务器工作区
一旦私信工作正常,你就可以将 Discord 服务器设置为一个完整工作区,其中每个频道都会获得自己的智能体会话及其各自的上下文。对于只有你和机器人使用的私有服务器,我们推荐这样配置
当私信可用后,你可以将 Discord 服务器设置为完整工作区,其中每个频道都会获得各自独立的智能体会话和上下文。这非常适合只有你和你的机器人的私人服务器
<Steps>
<Step title="将你的服务器添加到服务器允许列表">
这样你的智能体就可以在服务器中的任何频道响应,而不仅仅是在私信中
<Step title="将你的服务器添加到 guild allowlist">
这样你的智能体就可以在你的服务器中的任意频道回复,而不只是私信
<Tabs>
<Tab title="询问你的智能体">
> “将我的 Discord Server ID `<server_id>` 添加到服务器允许列表
> “将我的 Discord Server ID `<server_id>` 添加到 guild allowlist
</Tab>
<Tab title="配置">
@ -223,14 +221,14 @@ openclaw pairing approve discord <CODE>
</Step>
<Step title="允许在不使用 @mention 的情况下回复">
默认情况下,你的智能体只会在被 @mention 时才在服务器频道中响应。对于私有服务器,你很可能希望它对每条消息都做出响应
默认情况下,你的智能体只会在被 @mentioned 时在 guild 频道中回复。对于私人服务器,你可能更希望它对每条消息都作出回复
<Tabs>
<Tab title="询问你的智能体">
> “允许我的智能体在这个服务器中无需被 @mention 也能回复”
> “允许我的智能体在这个服务器中无需被 @mentioned 也能回复”
</Tab>
<Tab title="配置">
在你的服务器配置中设置 `requireMention: false`
在你的 guild 配置中设置 `requireMention: false`
```json5
{
@ -251,37 +249,37 @@ openclaw pairing approve discord <CODE>
</Step>
<Step title="为服务器频道中的记忆做好规划">
默认情况下长期记忆MEMORY.md只会在私信会话中加载。服务器频道不会自动加载 MEMORY.md。
<Step title="规划 guild 频道中的记忆使用">
默认情况下长期记忆MEMORY.md只会在私信会话中加载。guild 频道不会自动加载 MEMORY.md。
<Tabs>
<Tab title="询问你的智能体">
> “当我在 Discord 频道中提问时,如果你需要来自 MEMORY.md 的长期上下文,请使用 memory_search 或 memory_get。”
</Tab>
<Tab title="手动">
如果你需要在每个频道中共享上下文,请将稳定的说明放入 `AGENTS.md``USER.md`(它们会注入到每个会话中)。将长期笔记保存在 `MEMORY.md` 中,并在需要时通过 memory 工具访问它们
如果你需要每个频道都共享上下文,请将稳定指令放入 `AGENTS.md``USER.md`(它们会注入到每个会话中)。将长期笔记保存在 `MEMORY.md` 中,并按需通过记忆工具访问
</Tab>
</Tabs>
</Step>
</Steps>
现在,在你的 Discord 服务器上创建一些频道并开始聊天吧。你的智能体可以看到频道名称,并且每个频道都会获得自己隔离的会话——因此你可以设置 `#coding`、`#home`、`#research`,或任何适合你工作流的频道。
现在,在你的 Discord 服务器上创建一些频道并开始聊天。你的智能体可以看到频道名称,而且每个频道都会获得自己独立隔离的会话——因此你可以设置 `#coding`、`#home`、`#research`,或任何适合你工作流的频道。
## 运行时模型
- Gateway 网关负责 Discord 连接。
- 回复路由是确定性的:来自 Discord 的入站回复会返回到 Discord。
- Gateway 网关拥有 Discord 连接。
- 回复路由是确定性的:来自 Discord 的入站消息会回复到 Discord。
- 默认情况下(`session.dmScope=main`),私聊共享智能体主会话(`agent:main:main`)。
- 服务器频道使用隔离的会话键(`agent:<agentId>:discord:channel:<channelId>`)。
- guild 频道使用隔离的会话键(`agent:<agentId>:discord:channel:<channelId>`)。
- 默认忽略群组私信(`channels.discord.dm.groupEnabled=false`)。
- 原生斜杠命令在隔离的命令会话中运行(`agent:<agentId>:discord:slash:<userId>`),同时仍携带 `CommandTargetSessionKey` 指向路由后的对话会话。
- 原生斜杠命令在隔离的命令会话中运行(`agent:<agentId>:discord:slash:<userId>`),同时仍通过 `CommandTargetSessionKey` 携带路由后的对话会话。
## 论坛频道
Discord 论坛和媒体频道只接受线程帖子。OpenClaw 支持两种创建方式:
- 向论坛父频道(`channel:<forumId>`)发送消息,以自动创建线程。线程标题使用你消息中的第一条非空行
- 向论坛父频道(`channel:<forumId>`)发送消息以自动创建线程。线程标题会使用你消息中的第一行非空内容
- 使用 `openclaw message thread create` 直接创建线程。不要为论坛频道传递 `--message-id`
示例:发送到论坛父频道以创建线程
@ -298,27 +296,27 @@ openclaw message thread create --channel discord --target channel:<forumId> \
--thread-name "Topic title" --message "Body of the post"
```
论坛父频道不接受 Discord 组件。如果你需要组件,请发送到线程本身(`channel:<threadId>`)。
论坛父频道不接受 Discord components。如果你需要 components,请发送到线程本身(`channel:<threadId>`)。
## 交互式组件
OpenClaw 为智能体消息支持 Discord components v2 容器。使用带有 `components` 负载的消息工具。交互结果会像普通入站消息一样路由回智能体,并遵循现有的 Discord `replyToMode` 设置。
OpenClaw 支持在智能体消息中使用 Discord components v2 容器。使用带有 `components` 负载的消息工具。交互结果会像普通入站消息一样路由回智能体,并遵循现有的 Discord `replyToMode` 设置。
支持的块:
支持的块:
- `text`、`section`、`separator`、`actions`、`media-gallery`、`file`
- 操作行最多允许 5 个按钮或单个选择菜单
- 操作行最多允许 5 个按钮或单个选择菜单
- 选择类型:`string`、`user`、`role`、`mentionable`、`channel`
默认情况下,组件只能使用一次。设置 `components.reusable=true` 可让按钮、选择器和表单在过期前被多次使用。
默认情况下,components 为一次性使用。设置 `components.reusable=true` 可允许按钮、选择器和表单在过期前被多次使用。
要限制谁可以点击按钮,请在该按钮上设置 `allowedUsers`Discord 用户 ID、标签`*`)。配置后,不匹配的用户会收到一条仅自己可见的拒绝提示
要限制谁可以点击按钮,请在该按钮上设置 `allowedUsers`Discord 用户 ID、标签或 `*`)。配置后,不匹配的用户会收到临时拒绝消息
`/model``/models` 斜杠命令会打开一个交互式模型选择器,其中包含提供商和模型下拉菜单以及一个提交步骤。除非设置 `commands.modelsWrite=false`,否则 `/models add` 也支持在聊天中添加新的提供商/模型条目,而且新添加的模型无需重启 Gateway 网关就会显示出来。选择器的回复仅自己可见,且只有调用该命令的用户可以使用它
`/model``/models` 斜杠命令会打开一个交互式模型选择器,其中包含提供商和模型下拉菜单以及提交步骤。除非设置 `commands.modelsWrite=false`,否则 `/models add` 也支持直接在聊天中添加新的提供商/模型条目,新添加的模型无需重启 Gateway 网关就会显示出来。选择器回复是临时的,且只有调用它的用户可以使用
文件附件:
- `file` 块必须指向一个附件引用(`attachment://<filename>`
- `file` 块必须指向一个附件引用(`attachment://<filename>`
- 通过 `media`/`path`/`filePath` 提供附件(单个文件);多个文件请使用 `media-gallery`
- 当上传名称应与附件引用匹配时,使用 `filename` 覆盖上传名称
@ -382,7 +380,7 @@ OpenClaw 为智能体消息支持 Discord components v2 容器。使用带有 `c
}
```
## 访问控制路由
## 访问控制路由
<Tabs>
<Tab title="私信策略">
@ -393,20 +391,20 @@ OpenClaw 为智能体消息支持 Discord components v2 容器。使用带有 `c
- `open`(要求 `channels.discord.allowFrom` 包含 `"*"`;旧版:`channels.discord.dm.allowFrom`
- `disabled`
如果私信策略不是 open未知用户会被阻止(或`pairing` 模式下提示进行配对)。
如果私信策略不是 open未知用户将被阻止(或者`pairing` 模式下提示进行配对)。
多账户优先级:
- `channels.discord.accounts.default.allowFrom` 仅适用于 `default` 账户。
- 命名账户自身 `allowFrom` 未设置时,会继承 `channels.discord.allowFrom`
- 命名账户在其自身 `allowFrom` 未设置时,会继承 `channels.discord.allowFrom`
- 命名账户不会继承 `channels.discord.accounts.default.allowFrom`
用于投递的私信目标格式:
- `user:<id>`
- `<@id>` 提及
- `<@id>` mention
数字 ID 存在歧义,除非显式提供 user/channel 目标类型,否则会被拒绝。
数字 ID 存在歧义,除非显式提供 user/channel 目标类型,否则会被拒绝。
</Tab>
@ -417,16 +415,16 @@ OpenClaw 为智能体消息支持 Discord components v2 容器。使用带有 `c
- `allowlist`
- `disabled`
当存在 `channels.discord` 时,安全基线 `allowlist`
当存在 `channels.discord` 时,安全基线 `allowlist`
`allowlist` 行为:
- 服务器必须匹配 `channels.discord.guilds`(优先使用 `id`,也接受 slug
- 可选的发送者允许列表`users`(推荐使用稳定 ID`roles`(仅角色 ID如果配置了其中任一项,当发送者匹配 `users``roles`即被允许
- 默认禁用直接名称/标签匹配;仅在作为紧急兼容模式时启用 `channels.discord.dangerouslyAllowNameMatching: true`
- `users` 支持名称/标签,但 ID 更安全;使用名称/标签条目时,`openclaw security audit` 会发出警告
- 如果某个服务器配置了 `channels`,则未列出的频道会被拒绝
- 如果某个服务器没有 `channels` 块,则该允许列表服务器中的所有频道都被允许
- guild 必须匹配 `channels.discord.guilds`(优先使用 `id`,也接受 slug
- 可选的发送者 allowlist`users`(推荐使用稳定 ID`roles`(仅角色 ID如果配置了其中任一项当发送者匹配 `users``roles` 时允许通过
- 默认禁用直接名称/tag 匹配;仅在紧急兼容模式下启用 `channels.discord.dangerouslyAllowNameMatching: true`
- `users` 支持名称/tag但 ID 更安全;当使用名称/tag 条目时,`openclaw security audit` 会发出警告
- 如果某个 guild 配置了 `channels`,则未列出的频道会被拒绝
- 如果某个 guild 没有 `channels` 块,则该 allowlist guild 中的所有频道都允许
示例:
@ -452,33 +450,33 @@ OpenClaw 为智能体消息支持 Discord components v2 容器。使用带有 `c
}
```
如果你只设置了 `DISCORD_BOT_TOKEN`,而没有创建 `channels.discord` 块,则运行时回退为 `groupPolicy="allowlist"`(日志中会有警告),即使 `channels.defaults.groupPolicy``open` 也是如此
如果你只设置了 `DISCORD_BOT_TOKEN` 而没有创建 `channels.discord` 块,即使 `channels.defaults.groupPolicy``open`,运行时回退仍将使用 `groupPolicy="allowlist"`(并在日志中给出警告)
</Tab>
<Tab title="提及和群组私信">
默认情况下,服务器消息需要提及才会触发
默认情况下,guild 消息受 mention 限制
提及检测包括:
mention 检测包括:
- 显式提及机器人
- 已配置的提及模式(`agents.list[].groupChat.mentionPatterns`,回退为 `messages.groupChat.mentionPatterns`
- 在支持情况下,隐式回复机器人行为
- 已配置的 mention 模式(`agents.list[].groupChat.mentionPatterns`,回退到 `messages.groupChat.mentionPatterns`
- 在支持情况下,隐式回复机器人行为
`requireMention`服务器/频道配置(`channels.discord.guilds...`)。
`ignoreOtherMentions` 可选地丢弃提及了其他用户/角色但未提及机器人的消息(不包括 @everyone/@here)。
`requireMention` guild/频道配置(`channels.discord.guilds...`)。
`ignoreOtherMentions` 可选地丢弃那些提及了其他用户/角色但未提及机器人的消息(不包括 @everyone/@here)。
群组私信:
- 默认:忽略(`dm.groupEnabled=false`
- 可选允许列表通过 `dm.groupChannels` 配置(频道 ID 或 slug
- 可选:通过 `dm.groupChannels` 设置 allowlist(频道 ID 或 slug
</Tab>
</Tabs>
### 基于角色的智能体路由
使用 `bindings[].match.roles` 按角色 ID 将 Discord 服务器成员路由到不同的智能体。基于角色的绑定仅接受角色 ID且会在 peer 或 parent-peer 绑定之后、guild-only 绑定之前进行评估。如果某个绑定还设置了其他匹配字段(例如 `peer` + `guildId` + `roles`),则所有已配置字段都必须匹配。
使用 `bindings[].match.roles` 按角色 ID 将 Discord guild 成员路由到不同智能体。基于角色的绑定仅接受角色 ID并在 peer 或 parent-peer 绑定之后、guild-only 绑定之前进行求值。如果某个绑定还设置了其他匹配字段(例如 `peer` + `guildId` + `roles`),则所有已配置字段都必须匹配。
```json5
{
@ -502,69 +500,15 @@ OpenClaw 为智能体消息支持 Discord components v2 容器。使用带有 `c
}
```
## Developer Portal 设置
<AccordionGroup>
<Accordion title="创建应用和机器人">
1. Discord Developer Portal -> **Applications** -> **New Application**
2. **Bot** -> **Add Bot**
3. 复制机器人令牌
</Accordion>
<Accordion title="特权 intents">
**Bot -> Privileged Gateway Intents** 中,启用:
- Message Content Intent
- Server Members Intent推荐
Presence intent 是可选的,只有当你希望接收在线状态更新时才需要。设置机器人在线状态(`setPresence`)并不要求为成员启用在线状态更新。
</Accordion>
<Accordion title="OAuth scopes 和基础权限">
OAuth URL 生成器:
- scopes`bot`、`applications.commands`
典型的基础权限:
**General Permissions**
- View Channels
**Text Permissions**
- Send Messages
- Read Message History
- Embed Links
- Attach Files
- Add Reactions可选
这是普通文本频道的基础权限集。如果你计划在 Discord 线程中发帖,包括会创建或继续线程的论坛或媒体频道工作流,还需要启用 **Send Messages in Threads**
除非明确需要,否则避免使用 `Administrator`
</Accordion>
<Accordion title="复制 ID">
启用 Discord Developer Mode然后复制
- server ID
- channel ID
- user ID
在 OpenClaw 配置中,优先使用数字 ID以获得可靠的审计和探测能力。
</Accordion>
</AccordionGroup>
## 原生命令和命令鉴权
- `commands.native` 默认为 `"auto"`,并且对 Discord 启用。
- `commands.native` 默认为 `"auto"`,并且对 Discord 启用。
- 按渠道覆盖:`channels.discord.commands.native`。
- `commands.native=false` 会显式清除先前已注册的 Discord 原生命令。
- 原生命令鉴权使用与普通消息处理相同的 Discord 允许列表/策略。
- 即使未授权用户仍可能在 Discord UI 中看到命令,执行时仍会强制应用 OpenClaw 鉴权,并返回 “not authorized”。
- 原生命令鉴权使用与普通消息处理相同的 Discord allowlist/策略。
- 即使用户未获授权,命令仍可能在 Discord UI 中可见;执行时仍会强制执行 OpenClaw 鉴权,并返回“未授权”。
参见 [Slash commands](/zh-CN/tools/slash-commands) 了解命令目录和行为
命令目录和行为参见[斜杠命令](/zh-CN/tools/slash-commands)。
默认斜杠命令设置:
@ -586,18 +530,18 @@ OpenClaw 为智能体消息支持 Discord components v2 容器。使用带有 `c
- `all`
- `batched`
注意:`off` 会禁用隐式回复线程。显式 `[[reply_to_*]]` 标签仍会被遵循。
`first` 总是将隐式原生回复引用附加到该轮的第一条 Discord 出站消息
`batched` 仅在入站轮次是由多条消息组成的去抖批次时,才附加 Discord 的隐式原生回复引用。这在你希望原生回复主要用于存在歧义的突发聊天,而不是每一个单条消息轮次时非常有用。
注意:`off` 会禁用隐式回复线程。显式 `[[reply_to_*]]` 标签仍会被遵循。
`first` 总是将隐式原生回复引用附加到该轮次发出的第一条 Discord 出站消息。
`batched` 仅在入站轮次是由多条消息去抖后合并成的批次时,才附加 Discord 的隐式原生回复引用。这在你主要希望为含糊不清的突发聊天使用原生回复、而不是为每个单条消息轮次都使用时非常有用。
消息 ID 会在上下文/历史记录中显示,因此智能体可以定位特定消息。
消息 ID 会在上下文/历史记录中显示,因此智能体可以定位特定消息。
</Accordion>
<Accordion title="实时流式预览">
OpenClaw 可以通过发送一条临时消息并在文本到达时编辑它来流式显示草稿回复。`channels.discord.streaming` 接受 `off`(默认)| `partial` | `block` | `progress`在 Discord 上,`progress` 会映射为 `partial``streamMode` 是旧版别名,会自动迁移。
OpenClaw 可以通过发送临时消息并在文本到达时对其进行编辑来流式传输草稿回复。`channels.discord.streaming` 接受 `off`(默认)| `partial` | `block` | `progress``progress` 在 Discord 上映射为 `partial``streamMode` 是旧版别名,会自动迁移。
默认保持`off`,因为当多个机器人或 Gateway 网关共享一个账户时Discord 预览编辑很快会触速率限制。
默认`off`,因为当多个机器人或 Gateway 网关共享一个账户时Discord 预览编辑很快会触速率限制。
```json5
{
@ -615,18 +559,18 @@ OpenClaw 为智能体消息支持 Discord components v2 容器。使用带有 `c
```
- `partial` 会在 token 到达时编辑单条预览消息。
- `block`发出草稿大小的分块(使用 `draftChunk` 调整大小和断点,并受 `textChunkLimit` 限制)。
- `block`输出草稿大小的分块(使用 `draftChunk` 调整大小和断点,并限制在 `textChunkLimit` 范围内)。
- 媒体、错误和显式回复的最终消息会取消待处理的预览编辑。
- `streaming.preview.toolProgress`(默认 `true`)控制工具/进度更新是否复用预览消息。
预览流式传输仅支持文本;媒体回复会回退为普通投递。当显式启用分块流式传输时OpenClaw 会跳过预览流,以避免双重流式传输。
预览流式传输仅支持文本;媒体回复会回退到普通投递方式。显式启用分块流式传输时OpenClaw 会跳过预览流,以避免双重流式传输。
</Accordion>
<Accordion title="历史记录、上下文和线程行为">
服务器历史上下文:
guild 历史上下文:
- `channels.discord.historyLimit` 默认值为 `20`
- `channels.discord.historyLimit` 默认 `20`
- 回退:`messages.groupChat.historyLimit`
- `0` 表示禁用
@ -638,24 +582,24 @@ OpenClaw 为智能体消息支持 Discord components v2 容器。使用带有 `c
线程行为:
- Discord 线程按频道会话路由,并继承父频道配置,除非被覆盖。
- `channels.discord.thread.inheritParent`(默认 `false`)可选择让新自动线程从父级对话记录播种。按账户覆盖位于 `channels.discord.accounts.<id>.thread.inheritParent`
- 消息工具的 reactions 可以解析 `user:<id>` 私信目标。
- `guilds.<guild>.channels.<channel>.requireMention: false` 会在回复阶段激活回退期间保留。
- `channels.discord.thread.inheritParent`(默认 `false`)可让新自动线程选择从父级对话记录播种。按账户覆盖位于 `channels.discord.accounts.<id>.thread.inheritParent`
- 消息工具反应可以解析 `user:<id>` 私信目标。
- `guilds.<guild>.channels.<channel>.requireMention: false` 会在回复阶段激活回退期间保留。
频道主题会作为**不受信任**的上下文注入。允许列表控制的是谁可以触发智能体,而不是完整的补充上下文脱敏边界。
频道主题会作为**不受信任**的上下文注入。allowlist 只控制谁可以触发智能体,并不是完整的补充上下文脱敏边界。
</Accordion>
<Accordion title="用于子智能体的线程绑定会话">
Discord 可以将线程绑定到个会话目标,以便该线程中的后续消息持续路由到同一个会话(包括子智能体会话)。
Discord 可以将线程绑定到个会话目标,以便该线程中的后续消息持续路由到同一个会话(包括子智能体会话)。
命令:
- `/focus <target>` 将当前/新线程绑定到子智能体/会话目标
- `/unfocus` 移除当前线程绑定
- `/agents` 显示活动运行和绑定状态
- `/session idle <duration|off>` 检查/更新聚焦绑定的空闲自动取消聚焦
- `/session max-age <duration|off>` 检查/更新聚焦绑定的硬性最长存活时间
- `/session idle <duration|off>` 查看/更新聚焦绑定在无活动时自动取消聚焦的设置
- `/session max-age <duration|off>` 查看/更新聚焦绑定的硬性最大存活时间
配置:
@ -685,20 +629,20 @@ OpenClaw 为智能体消息支持 Discord components v2 容器。使用带有 `c
- `session.threadBindings.*` 设置全局默认值。
- `channels.discord.threadBindings.*` 覆盖 Discord 行为。
- `sessions_spawn({ thread: true })` 自动创建/绑定线程,必须将 `spawnSubagentSessions` 设为 true
- 为 ACP`/acp spawn ... --thread ...` 或 `sessions_spawn({ runtime: "acp", thread: true })`)自动创建/绑定线程,必须将 `spawnAcpSessions` 设为 true
- `spawnSubagentSessions` 必须为 true才能`sessions_spawn({ thread: true })` 自动创建/绑定线程。
- `spawnAcpSessions` 必须为 true才能为 ACP`/acp spawn ... --thread ...` 或 `sessions_spawn({ runtime: "acp", thread: true })`)自动创建/绑定线程。
- 如果某个账户禁用了线程绑定,则 `/focus` 和相关线程绑定操作不可用。
参见 [Sub-agents](/zh-CN/tools/subagents)、[ACP Agents](/zh-CN/tools/acp-agents) 和 [Configuration Reference](/zh-CN/gateway/configuration-reference)。
参见[子智能体](/zh-CN/tools/subagents)、[ACP Agents](/zh-CN/tools/acp-agents) 和[配置参考](/zh-CN/gateway/configuration-reference)。
</Accordion>
<Accordion title="持久化 ACP 渠道绑定">
对于稳定的“始终在线” ACP 工作区,可配置顶层类型化 ACP 绑定,将目标指向 Discord 对话
对于稳定的“始终在线” ACP 工作区,可配置以 Discord 对话为目标的顶层类型化 ACP 绑定。
配置路径:
- 带有 `type: "acp"``match.channel: "discord"``bindings[]`
- `bindings[]`,其中 `type: "acp"``match.channel: "discord"`
示例:
@ -750,8 +694,8 @@ OpenClaw 为智能体消息支持 Discord components v2 容器。使用带有 `c
说明:
- `/acp spawn codex --bind here` 会就地绑定当前频道或线程,并让后续消息持续保留在同一个 ACP 会话中。线程消息会继承父频道绑定。
- 在已绑定的频道或线程中,`/new` 和 `/reset` 会就地重置同一个 ACP 会话。临时线程绑定在激活期间可以覆盖目标解析。
- `/acp spawn codex --bind here` 会就地绑定当前频道或线程,并让后续消息持续使用同一个 ACP 会话。线程消息会继承父频道绑定。
- 在已绑定的频道或线程中,`/new` 和 `/reset` 会就地重置同一个 ACP 会话。临时线程绑定在生效期间可以覆盖目标解析。
- 仅当 OpenClaw 需要通过 `--thread auto|here` 创建/绑定子线程时,才需要 `spawnAcpSessions`
有关绑定行为的详细信息,参见 [ACP Agents](/zh-CN/tools/acp-agents)。
@ -759,30 +703,30 @@ OpenClaw 为智能体消息支持 Discord components v2 容器。使用带有 `c
</Accordion>
<Accordion title="反应通知">
服务器配置的反应通知模式:
guild 配置的反应通知模式:
- `off`
- `own`(默认)
- `all`
- `allowlist`(使用 `guilds.<id>.users`
反应事件会转换为系统事件,并附加到已路由的 Discord 会话
反应事件会转换为系统事件,并附加到已路由的 Discord 会话。
</Accordion>
<Accordion title="确认反应">
`ackReaction` 会在 OpenClaw 处理入站消息时发送一个确认 emoji
`ackReaction` 会在 OpenClaw 处理入站消息时发送一个确认表情符号
解析顺序:
- `channels.discord.accounts.<accountId>.ackReaction`
- `channels.discord.ackReaction`
- `messages.ackReaction`
- 智能体身份 emoji 回退(`agents.list[].identity.emoji`,否则为 `"👀"`
- 智能体身份表情符号回退(`agents.list[].identity.emoji`,否则为 `"👀"`
说明:
- Discord 接受 unicode emoji 或自定义 emoji 名称。
- Discord 接受 Unicode 表情符号或自定义表情符号名称。
- 使用 `""` 可为某个渠道或账户禁用该反应。
</Accordion>
@ -807,7 +751,7 @@ OpenClaw 为智能体消息支持 Discord components v2 容器。使用带有 `c
</Accordion>
<Accordion title="Gateway 网关代理">
使用 `channels.discord.proxy` 通过 HTTP(S) 代理转发 Discord gateway WebSocket 流量和启动时的 REST 查询(应用 ID + allowlist 解析)。
使用 `channels.discord.proxy` 通过 HTTP(S) 代理路由 Discord gateway WebSocket 流量和启动时的 REST 查询(应用 ID + allowlist 解析)。
```json5
{
@ -838,7 +782,7 @@ OpenClaw 为智能体消息支持 Discord components v2 容器。使用带有 `c
</Accordion>
<Accordion title="PluralKit 支持">
启用 PluralKit 解析,将代理消息映射到系统成员身份:
启用 PluralKit 解析,将代理消息映射到系统成员身份:
```json5
{
@ -856,14 +800,14 @@ OpenClaw 为智能体消息支持 Discord components v2 容器。使用带有 `c
说明:
- allowlist 可以使用 `pk:<memberId>`
- 仅当 `channels.discord.dangerouslyAllowNameMatching: true` 时,才会按名称/slug 匹配成员显示名
- 仅当 `channels.discord.dangerouslyAllowNameMatching: true` 时,才会按名称/slug 匹配成员显示名
- 查询使用原始消息 ID并受时间窗口限制
- 如果查询失败,代理消息会被视为机器人消息并丢弃,除非设置了 `allowBots=true`
- 如果查询失败,代理消息会被视为机器人消息并丢弃,除非 `allowBots=true`
</Accordion>
<Accordion title="在线状态配置">
当你设置状态或活动字段,或启用自动在线状态时,将应用在线状态更新。
当你设置状态或活动字段,或者启用自动在线状态时,会应用在线状态更新。
仅状态示例:
@ -890,7 +834,7 @@ OpenClaw 为智能体消息支持 Discord components v2 容器。使用带有 `c
}
```
直播示例:
Streaming 示例:
```json5
{
@ -910,7 +854,7 @@ OpenClaw 为智能体消息支持 Discord components v2 容器。使用带有 `c
- 1Streaming需要 `activityUrl`
- 2Listening
- 3Watching
- 4Custom使用活动文本作为状态内容emoji 可选)
- 4Custom使用活动文本作为状态内容表情符号可选)
- 5Competing
自动在线状态示例(运行时健康信号):
@ -939,23 +883,23 @@ OpenClaw 为智能体消息支持 Discord components v2 容器。使用带有 `c
</Accordion>
<Accordion title="Discord 中的审批">
Discord 支持在私信中基于按钮处理审批,并且可选择在发起请求的频道中发布审批提示。
Discord 支持在私信中基于按钮处理审批,并且可以选择在发起审批的频道中发布审批提示。
配置路径:
- `channels.discord.execApprovals.enabled`
- `channels.discord.execApprovals.approvers`(可选;如果可能,会回退到 `commands.ownerAllowFrom`
- `channels.discord.execApprovals.approvers`(可选;在可能时回退到 `commands.ownerAllowFrom`
- `channels.discord.execApprovals.target``dm` | `channel` | `both`,默认:`dm`
- `agentFilter`、`sessionFilter`、`cleanupAfterResolve`
`enabled` 未设置或为 `"auto"`,并且至少可以解析出一个审批人时Discord 会自动启用原生 exec 审批;审批人可来自 `execApprovals.approvers``commands.ownerAllowFrom`。Discord 不会从渠道 `allowFrom`、旧版 `dm.allowFrom`直接消息的 `defaultTo` 推断 exec 审批人。若要显式禁用 Discord 作为原生审批客户端,请设置 `enabled: false`
`enabled` 未设置或为 `"auto"`,并且至少能从 `execApprovals.approvers``commands.ownerAllowFrom` 解析出一个审批人时Discord 会自动启用原生 exec 审批。Discord 不会从渠道 `allowFrom`、旧版 `dm.allowFrom`私信 `defaultTo` 推断 exec 审批人。设置 `enabled: false` 可显式禁用 Discord 作为原生审批客户端
`target``channel``both` 时,审批提示会显示在频道中。只有已解析的审批人可以使用按钮;其他用户会收到一条仅自己可见的拒绝提示。审批提示包含命令文本,因此仅应在受信任频道中启用频道投递。如果无法从会话键推导出频道 IDOpenClaw 会回退到私信投递。
`target``channel``both` 时,审批提示会显示在频道中。只有已解析的审批人可以使用这些按钮;其他用户会收到临时拒绝消息。审批提示包含命令文本,因此仅应在受信任频道中启用频道投递。如果无法从会话键推导出频道 IDOpenClaw 会回退到私信投递。
Discord 还会渲染其他聊天渠道共用的审批按钮。原生 Discord 适配器主要增加了审批人私信路由和频道扇出。
当这些按钮存在时,它们就是主要的审批 UX只有当工具结果表明聊天审批不可用手动审批是唯一途径时OpenClaw 才应包含手动 `/approve` 命令。
Discord 还会渲染其他聊天渠道使用的共享审批按钮。原生 Discord 适配器主要增加了审批人私信路由和频道扇出。
当这些按钮存在时,它们就是主要的审批 UX只有当工具结果表明聊天审批不可用者手动审批是唯一可行路径时OpenClaw 才应包含手动 `/approve` 命令。
Gateway 网关鉴权和审批解析遵循共享的 Gateway 网关客户端契约(`plugin:` ID 通过 `plugin.approval.resolve` 解析;其他 ID 通过 `exec.approval.resolve` 解析)。审批默认在 30 分钟后过期。
Gateway 网关鉴权和审批解析遵循共享的 Gateway 网关客户端契约(`plugin:` ID 通过 `plugin.approval.resolve` 解析;其他 ID 通过 `exec.approval.resolve` 解析)。审批默认在 30 分钟后过期。
参见 [Exec approvals](/zh-CN/tools/exec-approvals)。
@ -964,33 +908,33 @@ OpenClaw 为智能体消息支持 Discord components v2 容器。使用带有 `c
## 工具和操作门控
Discord 消息操作包括消息发送、频道管理、审核、在线状态和元数据操作。
Discord 消息操作包括消息处理、频道管理、内容审核、在线状态和元数据操作。
核心示例:
- 消息:`sendMessage`、`readMessages`、`editMessage`、`deleteMessage`、`threadReply`
- 消息处理`sendMessage`、`readMessages`、`editMessage`、`deleteMessage`、`threadReply`
- 反应:`react`、`reactions`、`emojiList`
- 审核:`timeout`、`kick`、`ban`
- 在线状态:`setPresence`
`event-create` 操作接受一个可选的 `image` 参数URL 或本地文件路径),用于设置计划事件封面图
`event-create` 操作接受可选的 `image` 参数URL 或本地文件路径),用于设置计划事件封面图。
操作门控位于 `channels.discord.actions.*` 下。
默认门控行为:
| 操作组 | 默认值 |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------- |
| reactions、messages、threads、pins、polls、search、memberInfo、roleInfo、channelInfo、channels、voiceStatus、events、stickers、emojiUploads、stickerUploads、permissions | 启用 |
| roles | 禁用 |
| moderation | 禁用 |
| presence | 禁用 |
| 操作组 | 默认值 |
| --- | --- |
| reactions、messages、threads、pins、polls、search、memberInfo、roleInfo、channelInfo、channels、voiceStatus、events、stickers、emojiUploads、stickerUploads、permissions | 启用 |
| roles | 禁用 |
| moderation | 禁用 |
| presence | 禁用 |
## Components v2 UI
OpenClaw 对 exec 审批和跨上下文标记使用 Discord components v2。Discord 消息操作也可以接受 `components` 用于自定义 UI高级用法需要通过 discord 工具构造组件负载);旧版 `embeds` 仍可用,但不推荐。
OpenClaw 对 exec 审批和跨上下文标记使用 Discord components v2。Discord 消息操作也可以接受 `components` 用于自定义 UI高级用法需要通过 discord 工具构造组件负载);旧版 `embeds`可用,但不推荐使用
- `channels.discord.ui.components.accentColor` 设置 Discord 组件容器使用的强调色(hex)。
- `channels.discord.ui.components.accentColor` 设置 Discord 组件容器使用的强调色(十六进制)。
- 可通过 `channels.discord.accounts.<id>.ui.components.accentColor` 按账户设置。
- 当存在 components v2 时,`embeds` 会被忽略。
@ -1012,7 +956,7 @@ OpenClaw 对 exec 审批和跨上下文标记使用 Discord components v2。Disc
## 语音
Discord 有两种不同的语音表面:实时**语音频道**(连续对话)和**语音消息附件**波形预览格式。Gateway 网关同时支持这两者。
Discord 有两种不同的语音交互界面:实时**语音频道**(持续对话)和**语音消息附件**波形预览格式。Gateway 网关两者都支持
### 语音频道
@ -1020,9 +964,9 @@ Discord 有两种不同的语音表面:实时**语音频道**(连续对话
- 启用原生命令(`commands.native` 或 `channels.discord.commands.native`)。
- 配置 `channels.discord.voice`
- 机器人在目标语音频道中需要 Connect 和 Speak 权限。
- 机器人需要在目标语音频道中拥有 Connect + Speak 权限。
使用 `/vc join|leave|status` 控制会话。该命令使用账户默认智能体,并遵循与其他 Discord 命令相同的 allowlist 和服务器策略规则。
使用 `/vc join|leave|status` 控制会话。该命令使用账户默认智能体,并遵循与其他 Discord 命令相同的 allowlist 和策略规则。
自动加入示例:
@ -1052,21 +996,21 @@ Discord 有两种不同的语音表面:实时**语音频道**(连续对话
说明:
- `voice.tts`对语音播放覆盖 `messages.tts`
- 语音转写轮次会从 Discord `allowFrom`(或 `dm.allowFrom`)派生所有者状态;非所有者说话者无法访问仅所有者可用的工具(例如 `gateway``cron`)。
- 默认启用语音;设置 `channels.discord.voice.enabled=false` 可禁用。
- `voice.tts`覆盖语音播放的 `messages.tts`
- 语音转录轮次从 Discord `allowFrom`(或 `dm.allowFrom`)推导所有者状态;非所有者说话者不能访问仅限所有者的工具(例如 `gateway``cron`)。
- 语音默认启用;设置 `channels.discord.voice.enabled=false` 可禁用。
- `voice.daveEncryption``voice.decryptionFailureTolerance` 会透传给 `@discordjs/voice` 的加入选项。
- 如果未设置,`@discordjs/voice` 的默认值是 `daveEncryption=true``decryptionFailureTolerance=24`
- OpenClaw 还会监视接收解密失败,并在短时间内重复失败后通过离开/重新加入语音频道自动恢复。
- 如果接收日志反复显示 `DecryptionFailed(UnencryptedWhenPassthroughDisabled)`可能是上游 `@discordjs/voice` 接收 bug见 [discord.js #11419](https://github.com/discordjs/discord.js/issues/11419)。
- 如果未设置,`@discordjs/voice` 默认值为 `daveEncryption=true``decryptionFailureTolerance=24`
- OpenClaw 还会监测接收解密失败,并在短时间内重复失败时通过离开/重新加入语音频道来自动恢复。
- 如果接收日志反复显示 `DecryptionFailed(UnencryptedWhenPassthroughDisabled)`可能是上游 `@discordjs/voice` 接收 bug见 [discord.js #11419](https://github.com/discordjs/discord.js/issues/11419)。
### 语音消息
Discord 语音消息会显示波形预览,并要求使用 OGG/Opus 音频。OpenClaw 会自动生成波形,但需要在 Gateway 网关主机上安装 `ffmpeg``ffprobe` 进行检测和转换。
Discord 语音消息会显示波形预览,并要求使用 OGG/Opus 音频。OpenClaw 会自动生成波形,但需要在 Gateway 网关主机上安装 `ffmpeg``ffprobe` 进行检测和转换。
- 提供**本地文件路径**(不接受 URL
- 不要附带文本内容Discord 会拒绝在同一负载中同时包含文本和语音消息)。
- 接受任意音频格式OpenClaw 会在需要时将其转换为 OGG/Opus。
- 不要包含文本内容Discord 会拒绝同一负载中的文本 + 语音消息)。
- 接受任意音频格式OpenClaw 会根据需要将其转换为 OGG/Opus。
```bash
message(action="send", channel="discord", target="channel:123", path="/path/to/audio.mp3", asVoice=true)
@ -1075,7 +1019,7 @@ message(action="send", channel="discord", target="channel:123", path="/path/to/a
## 故障排除
<AccordionGroup>
<Accordion title="使用了不允许的 intents或机器人看不到任何服务器消息">
<Accordion title="使用了不允许的 intents或机器人看不到 guild 消息">
- 启用 Message Content Intent
- 当你依赖用户/成员解析时,启用 Server Members Intent
@ -1083,14 +1027,14 @@ message(action="send", channel="discord", target="channel:123", path="/path/to/a
</Accordion>
<Accordion title="服务器消息被意外阻止">
<Accordion title="guild 消息被意外阻止">
- 验证 `groupPolicy`
- 验证 `channels.discord.guilds` 下的服务器 allowlist
- 如果存在服务器 `channels` 映射,则只允许其中列出的频道
- 验证 `requireMention` 行为和提及模式
- 检查 `groupPolicy`
- 检查 `channels.discord.guilds` 下的 guild allowlist
- 如果存在 guild `channels` 映射,则只允许列出的频道
- 检查 `requireMention` 行为和 mention 模式
有用的检查:
有用的检查命令
```bash
openclaw doctor
@ -1100,16 +1044,16 @@ openclaw logs --follow
</Accordion>
<Accordion title="已设置 require mention false但仍然被阻止">
<Accordion title="requireMention 为 false 但仍然被阻止">
常见原因:
- `groupPolicy="allowlist"`,但没有匹配的服务器/频道 allowlist
- `requireMention` 配置在错误位置(必须位于 `channels.discord.guilds` 或频道条目下
- 发送者被服务器/频道 `users` allowlist 阻止
- `groupPolicy="allowlist"` 但没有匹配的 guild/频道 allowlist
- `requireMention` 配置在了错误的位置(必须放在 `channels.discord.guilds` 下或频道条目中
- 发送者被 guild/频道 `users` allowlist 阻止
</Accordion>
<Accordion title="长时间运行的处理程序超时或出现重复回复">
<Accordion title="长时间运行的处理超时或出现重复回复">
典型日志:
@ -1117,16 +1061,16 @@ openclaw logs --follow
- `Slow listener detected ...`
- `discord inbound worker timed out after ...`
监听器预算控制项
监听器预算旋钮
- 单账户:`channels.discord.eventQueue.listenerTimeout`
- 多账户:`channels.discord.accounts.<accountId>.eventQueue.listenerTimeout`
Worker 运行超时控制项
worker 运行超时旋钮
- 单账户:`channels.discord.inboundWorker.runTimeoutMs`
- 多账户:`channels.discord.accounts.<accountId>.inboundWorker.runTimeoutMs`
- 默认`1800000`30 分钟);设为 `0` 可禁用
- 默认:`1800000`30 分钟);设`0` 可禁用
推荐基线:
@ -1149,14 +1093,14 @@ openclaw logs --follow
}
```
对于缓慢的监听器初始化,请使用 `eventQueue.listenerTimeout`;只有在你希望为排队的智能体轮次设置单独安全阀时,才使用 `inboundWorker.runTimeoutMs`
对于缓慢的监听器设置,请使用 `eventQueue.listenerTimeout`;仅当你希望为排队中的智能体轮次设置单独的安全阀时,才使用 `inboundWorker.runTimeoutMs`
</Accordion>
<Accordion title="权限审计不匹配">
`channels status --probe` 权限检查仅适用于数字频道 ID。
如果你使用 slug 键,运行时匹配仍然可能正常工作,但探测无法完整验证权限。
如果你使用 slug 键,运行时匹配仍然可以正常工作,但 probe 无法完整验证权限。
</Accordion>
@ -1171,31 +1115,29 @@ openclaw logs --follow
<Accordion title="机器人到机器人的循环">
默认情况下,会忽略由机器人发送的消息。
如果你设置了 `channels.discord.allowBots=true`,请使用严格的提及和 allowlist 规则以避免循环行为。
优先使用 `channels.discord.allowBots="mentions"`,这样只接受提及该机器人的机器人消息。
如果你设置了 `channels.discord.allowBots=true`,请使用严格的 mention 和 allowlist 规则以避免循环行为。
更推荐 `channels.discord.allowBots="mentions"`,这样只接受提及该机器人的机器人消息。
</Accordion>
<Accordion title="语音 STT 因 DecryptionFailed(...) 丢失">
- 保持 OpenClaw 为最新版本(`openclaw update`),以确保包含 Discord 语音接收恢复逻辑
- 确认 `channels.discord.voice.daveEncryption=true`(默认
- 从 `channels.discord.voice.decryptionFailureTolerance=24`(上游默认值)开始,仅在需要时调整
- 观察日志中的以下内容:
- 确认 `channels.discord.voice.daveEncryption=true`(默认)
- 从 `channels.discord.voice.decryptionFailureTolerance=24`(上游默认值)开始,仅在需要时调整
- 关注日志中的以下内容:
- `discord voice: DAVE decrypt failures detected`
- `discord voice: repeated decrypt failures; attempting rejoin`
- 如果自动重新加入后问题仍持续,请收集日志并与 [discord.js #11419](https://github.com/discordjs/discord.js/issues/11419) 对
- 如果自动重新加入后仍然失败,请收集日志,并与 [discord.js #11419](https://github.com/discordjs/discord.js/issues/11419) 进行比
</Accordion>
</AccordionGroup>
## 配置参考指引
## 配置参考
主要参考:
主要参考: [配置参考 - Discord](/zh-CN/gateway/configuration-reference#discord)。
- [Configuration reference - Discord](/zh-CN/gateway/configuration-reference#discord)
高信号 Discord 字段:
<Accordion title="高信号 Discord 字段">
- 启动/鉴权:`enabled`、`token`、`accounts.*`、`allowBots`
- 策略:`groupPolicy`、`dm.*`、`guilds.*`、`guilds.*.channels.*`
@ -1205,25 +1147,39 @@ openclaw logs --follow
- 回复/历史:`replyToMode`、`historyLimit`、`dmHistoryLimit`、`dms.*.historyLimit`
- 投递:`textChunkLimit`、`chunkMode`、`maxLinesPerMessage`
- 流式传输:`streaming`(旧版别名:`streamMode`)、`streaming.preview.toolProgress`、`draftChunk`、`blockStreaming`、`blockStreamingCoalesce`
- 媒体/重试:`mediaMaxMb`、`retry`
- `mediaMaxMb` 限制 Discord 出站上传大小(默认:`100MB`
- 媒体/重试:`mediaMaxMb`(限制 Discord 出站上传,默认 `100MB`)、`retry`
- 操作:`actions.*`
- 在线状态:`activity`、`status`、`activityType`、`activityUrl`
- UI`ui.components.accentColor`
- 功能:`threadBindings`、顶层 `bindings[]``type: "acp"`)、`pluralkit`、`execApprovals`、`intents`、`agentComponents`、`heartbeat`、`responsePrefix`
## 安全和运维
</Accordion>
- 将机器人令牌视为机密(在受监管环境中优先使用 `DISCORD_BOT_TOKEN`)。
## 安全与运维
- 将机器人令牌视为机密信息(在受监管环境中优先使用 `DISCORD_BOT_TOKEN`)。
- 授予最小权限的 Discord 权限。
- 如果命令部署/状态已过期,请重启 Gateway 网关,并使用 `openclaw channels status --probe` 重新检查。
## 相关内容
- [配对](/zh-CN/channels/pairing)
- [群组](/zh-CN/channels/groups)
- [渠道路由](/zh-CN/channels/channel-routing)
- [安全](/zh-CN/gateway/security)
- [多智能体路由](/zh-CN/concepts/multi-agent)
- [故障排除](/zh-CN/channels/troubleshooting)
- [斜杠命令](/zh-CN/tools/slash-commands)
<CardGroup cols={2}>
<Card title="配对" icon="link" href="/zh-CN/channels/pairing">
将 Discord 用户与 Gateway 网关配对。
</Card>
<Card title="群组" icon="users" href="/zh-CN/channels/groups">
群聊和 allowlist 行为。
</Card>
<Card title="渠道路由" icon="route" href="/zh-CN/channels/channel-routing">
将入站消息路由到智能体。
</Card>
<Card title="安全" icon="shield" href="/zh-CN/gateway/security">
威胁模型与加固。
</Card>
<Card title="多智能体路由" icon="sitemap" href="/zh-CN/concepts/multi-agent">
将 guild 和频道映射到智能体。
</Card>
<Card title="斜杠命令" icon="terminal" href="/zh-CN/tools/slash-commands">
原生命令行为。
</Card>
</CardGroup>

View File

@ -5,21 +5,21 @@ read_when:
summary: CI 作业图、范围门禁,以及本地等效命令
title: CI 流水线
x-i18n:
generated_at: "2026-04-23T17:53:30Z"
generated_at: "2026-04-23T18:24:28Z"
model: gpt-5.4
provider: openai
source_hash: 1de796d57e79eda0328f20172f9029af485a57a3996bc8615e3a7bce281b7d85
source_hash: 089e7b4dc59bf11ad643ced552537b761da62314717a15b7971e2abc7053a38b
source_path: ci.md
workflow: 15
---
# CI 流水线
CI 会在每次推送到 `main` 以及每个拉取请求时运行。它使用智能范围控制,在只改动了不相关区域时跳过高开销作业。
CI 会在每次推送到 `main` 以及每个拉取请求上运行。它使用智能范围划分,在仅有不相关区域变更时跳过开销较大的作业。
QA Lab 在主智能范围工作流之外有专用的 CI 通道。`Parity gate` 工作流会在匹配的 PR 变更手动触发时运行;它会构建私有 QA 运行时,并比较模拟的 GPT-5.4 和 Opus 4.6 智能体包。`QA-Lab - All Lanes` 工作流会在 `main` 上每晚运行,支持手动触发;它会将模拟 parity gate、实时 Matrix 通道和实时 Telegram 通道作为并行作业扇出执行。实时作业使用 `qa-live-shared` 环境,而 Telegram 通道使用 Convex 租约。`OpenClaw Release Checks` 也会在发布批准前运行同的 QA Lab 通道。
QA Lab 在主智能范围工作流之外有专用的 CI 通道。`Parity gate` 工作流会在匹配的 PR 变更以及手动触发时运行;它会构建私有 QA 运行时,并比较模拟的 GPT-5.4 和 Opus 4.6 智能体包。`QA-Lab - All Lanes` 工作流会在 `main` 上每晚运行,支持手动触发;它会将模拟 parity gate、实时 Matrix 通道和实时 Telegram 通道作为并行作业扇出执行。实时作业使用 `qa-live-shared` 环境,而 Telegram 通道使用 Convex 租约。`OpenClaw Release Checks` 也会在发布批准前运行同的 QA Lab 通道。
`Duplicate PRs After Merge` 工作流是一个供维护者使用的手动工作流,用于合并后的重复 PR 清理。它默认使用 dry-run,只有在 `apply=true` 时才会关闭明确列出的 PR。在修改 GitHub 之前,它会验证已落地 PR 确实已合并,并确认每个重复 PR 都具有共享的被引用 issue或存在重叠的变更代码块。
`Duplicate PRs After Merge` 工作流是一个供维护者使用的手动工作流,用于在合并后清理重复 PR。它默认以 dry-run 模式运行,只有在 `apply=true` 时才会关闭明确列出的 PR。在修改 GitHub 之前,它会验证已落地 PR 确实已合并,并确认每个重复 PR 都有共享的引用 issue 或重叠的变更代码块。
```bash
gh workflow run duplicate-after-merge.yml \
@ -32,59 +32,59 @@ gh workflow run duplicate-after-merge.yml \
| 作业 | 用途 | 运行时机 |
| -------------------------------- | -------------------------------------------------------------------------------------------- | ------------------------------------ |
| `preflight` | 检测是否仅为文档改动、已变更范围、已变更扩展,并构建 CI 清单 | 始终在非草稿 push 和 PR 上运行 |
| `security-scm-fast` | 通过 `zizmor` 进行私钥检测和工作流审计 | 始终在非草稿 push 和 PR 上运行 |
| `security-dependency-audit` | 针对 npm advisories 执行无依赖的生产 lockfile 审计 | 始终在非草稿 push 和 PR 上运行 |
| `security-fast` | 快速安全作业的必需汇总作业 | 始终在非草稿 push 和 PR 上运行 |
| `build-artifacts` | 构建 `dist/`、Control UI、已构建产物检查,以及可复用的下游产物 | 与 Node 相关的变更 |
| `preflight` | 检测是否仅有文档变更、变更范围、已变更扩展,并构建 CI 清单 | 在所有非草稿 push 和 PR 上始终运行 |
| `security-scm-fast` | 通过 `zizmor` 进行私钥检测和工作流审计 | 在所有非草稿 push 和 PR 上始终运行 |
| `security-dependency-audit` | 针对 npm advisories 进行无依赖的生产 lockfile 审计 | 在所有非草稿 push 和 PR 上始终运行 |
| `security-fast` | 快速安全作业的必需聚合作业 | 在所有非草稿 push 和 PR 上始终运行 |
| `build-artifacts` | 构建 `dist/`、Control UI、内置产物检查,以及可复用的下游产物 | 与 Node 相关的变更 |
| `checks-fast-core` | 快速 Linux 正确性通道,例如 bundled/plugin-contract/protocol 检查 | 与 Node 相关的变更 |
| `checks-fast-contracts-channels` | 分片的渠道契约检查,并提供稳定的聚合检查结果 | 与 Node 相关的变更 |
| `checks-node-extensions` | 针对整个扩展套件运行完整的内置插件测试分片 | 与 Node 相关的变更 |
| `checks-node-extensions` | 在整个扩展套件上运行完整的内置插件测试分片 | 与 Node 相关的变更 |
| `checks-node-core-test` | Core Node 测试分片,不包含渠道、内置、契约和扩展通道 | 与 Node 相关的变更 |
| `extension-fast` | 仅针对已变更的内置插件运行聚焦测试 | 带有扩展变更的拉取请求 |
| `extension-fast` | 仅针对已变更内置插件的聚焦测试 | 带有扩展变更的拉取请求 |
| `check` | 分片后的主本地门禁等效项生产类型、lint、守卫、测试类型和严格 smoke | 与 Node 相关的变更 |
| `check-additional` | 架构、边界、扩展表面守卫、包边界 gateway-watch 分片 | 与 Node 相关的变更 |
| `build-smoke` | 已构建 CLI smoke 测试和启动内存 smoke 测试 | 与 Node 相关的变更 |
| `checks` | 已构建产物渠道测试的校验器,以及仅在 push 时运行的 Node 22 兼容性检查 | 与 Node 相关的变更 |
| `check-docs` | 文档格式化、lint 和失效链接检查 | 文档有变更 |
| `skills-python` | 面向 Python 支 Skills 的 Ruff + pytest | 与 Python Skills 相关的变更 |
| `check-additional` | 架构、边界、扩展表面守卫、包边界以及 gateway-watch 分片 | 与 Node 相关的变更 |
| `build-smoke` | 已构建 CLI smoke 测试和启动内存 smoke 测试 | 与 Node 相关的变更 |
| `checks` | 已构建产物渠道测试验器,以及仅在 push 时运行的 Node 22 兼容性检查 | 与 Node 相关的变更 |
| `check-docs` | 文档格式化、lint 和断链检查 | 文档有变更时 |
| `skills-python` | 面向 Python 支持的 Skills 的 Ruff + pytest | 与 Python Skills 相关的变更 |
| `checks-windows` | Windows 专用测试通道 | 与 Windows 相关的变更 |
| `macos-node` | 使用共享构建产物的 macOS TypeScript 测试通道 | 与 macOS 相关的变更 |
| `macos-node` | 使用共享构建产物的 macOS TypeScript 测试通道 | 与 macOS 相关的变更 |
| `macos-swift` | macOS 应用的 Swift lint、构建和测试 | 与 macOS 相关的变更 |
| `android` | 两种 flavor 的 Android 单元测试,以及一个 debug APK 构建 | 与 Android 相关的变更 |
## Fail-Fast 顺序
## 快速失败顺序
作业的排序方式保证了低成本检查于高成本作业失败:
作业按顺序排列,以便让便宜的检查先失败,再决定是否运行昂贵的作业
1. `preflight` 决定哪些通道会存在。`docs-scope` 和 `changed-scope` 逻辑是这个作业的步骤,而不是独立作业。
2. `security-scm-fast`、`security-dependency-audit`、`security-fast`、`check`、`check-additional`、`check-docs` 和 `skills-python` 会快速失败,而无需等待更重的产物和平台矩阵作业。
3. `build-artifacts` 会与快速 Linux 通道并行执行,这样下游消费者可以在共享构建准备好后立开始。
4. 更重的平台和运行时通道会在之后扇出:`checks-fast-core`、`checks-fast-contracts-channels`、`checks-node-extensions`、`checks-node-core-test`、仅 PR 的 `extension-fast`、`checks`、`checks-windows`、`macos-node`、`macos-swift` 和 `android`
1. `preflight` 决定到底要创建哪些通道。`docs-scope` 和 `changed-scope` 逻辑是这个作业内部的步骤,而不是独立作业。
2. `security-scm-fast`、`security-dependency-audit`、`security-fast`、`check`、`check-additional`、`check-docs` 和 `skills-python` 会快速失败,而不必等待更重的产物和平台矩阵作业。
3. `build-artifacts` 会与快速 Linux 通道并行执行,这样下游消费者可以在共享构建准备好后立开始。
4. 更重的平台和运行时通道后扇出:`checks-fast-core`、`checks-fast-contracts-channels`、`checks-node-extensions`、`checks-node-core-test`、仅 PR 的 `extension-fast`、`checks`、`checks-windows`、`macos-node`、`macos-swift` 和 `android`
范围逻辑位于 `scripts/ci-changed-scope.mjs`,并由 `src/scripts/ci-changed-scope.test.ts` 中的单元测试覆盖。
CI 工作流编辑会验证 Node CI 作业图以及工作流 lint但它们本身不会强制触发 Windows、Android 或 macOS 原生构建;这些平台通道仍然仅针对平台源代码变更触发
Windows Node 检查的范围限定在 Windows 专用的进程/路径包装器、npm/pnpm/UI runner 辅助工具、包管理器配置,以及执行该通道的 CI 工作流表面不相关的源代码、plugin、install-smoke 和纯测试改动仍然保留在 Linux Node 通道中,这样就不会为了正常测试分片已经覆盖的内容而占用一个 16-vCPU 的 Windows worker。
单独的 `install-smoke` 工作流会通过它自己的 `preflight` 作业复用相同的范围脚本。它根据更窄的 changed-smoke 信号计算 `run_install_smoke`,因此 Docker/install smoke 会针对安装、打包、容器相关变更、内置扩展生产代码变更,以及 Docker smoke 作业所覆盖的 core plugin/channel/Gateway 网关/Plugin SDK 表面运行。纯测试和纯文档编辑不会占用 Docker workers。它的 QR 包 smoke 会强制 Docker `pnpm install` 层重新运行,同时保留 BuildKit pnpm store 缓存,因此仍然会执行安装流程,而不必在每次运行时重新下载依赖。它的 gateway-network e2e 会复用该作业中更早构建的运行时镜像,因此能够增加真实的容器到容器 WebSocket 覆盖,而无需再增加一次 Docker 构建。本地 `test:docker:all` 会预构建一个共享的 live-test 镜像和一个共享的 `scripts/e2e/Dockerfile` built-app 镜像,然后以 `OPENCLAW_SKIP_DOCKER_BUILD=1` 并行运行 live/E2E smoke 通道;默认并发数为 4可通过 `OPENCLAW_DOCKER_ALL_PARALLELISM` 调整。默认情况下,本地聚合器会在首次失败后停止调度新的池化通道,并且每个通道都有一个 120 分钟超时,可通过 `OPENCLAW_DOCKER_ALL_LANE_TIMEOUT_MS` 覆盖。对启动过程或提供商敏感的通道会在并行池之后以独占方式运行。可复用的 live/E2E 工作流也遵循共享镜像模式:它会在 Docker 矩阵之前构建并推送一个带 SHA 标签的 GHCR Docker E2E 镜像,然后以 `OPENCLAW_SKIP_DOCKER_BUILD=1` 运行矩阵。定时的 live/E2E 工作流每天都会运行完整的发布路径 Docker 套件。QR 和安装器 Docker 测试保留各自以安装为重点的 Dockerfile。另有一个单独的 `docker-e2e-fast` 作业,会在 120 秒命令超时限制下运行有界的内置插件 Docker 配置setup-entry 依赖修复加上合成的 bundled-loader 故障隔离。完整的内置更新/渠道矩阵仍然保持为手动/完整套件,因为它会执行多次真实的 npm update 和 doctor 修复流程。
CI 工作流编辑会验证 Node CI 作业图和工作流 lint但不会仅因这些编辑就强制触发 Windows、Android 或 macOS 原生构建;这些平台通道仍然只会在对应平台源码发生变更时运行
Windows Node 检查仅限于 Windows 特定的进程/路径包装器、npm/pnpm/UI 运行器辅助工具、包管理器配置,以及执行该通道的 CI 工作流表面不相关的源码、插件、install-smoke 和仅测试变更仍然留在 Linux Node 通道上,因此不会为已经由常规测试分片覆盖的内容占用一个 16-vCPU 的 Windows worker。
独立的 `install-smoke` 工作流通过自己的 `preflight` 作业复用同一个范围脚本。它会根据更窄的 changed-smoke 信号计算 `run_install_smoke`,因此 Docker/安装 smoke 会在安装、打包、与容器相关的变更、内置扩展生产变更,以及 Docker smoke 作业会触达的 core plugin/channel/Gateway 网关/Plugin SDK 表面发生变更时运行。仅测试和仅文档编辑不会占用 Docker workers。它的 QR 包 smoke 会强制 Docker `pnpm install` 层重新运行,同时保留 BuildKit 的 pnpm store 缓存,因此仍然能覆盖安装路径,而不必在每次运行时重新下载依赖。它的 gateway-network e2e 会复用该作业前面构建好的运行时镜像,因此在不新增一次 Docker 构建的前提下,增加了真实的容器到容器 WebSocket 覆盖。本地 `test:docker:all` 会预构建一个共享的 live-test 镜像和一个共享的 `scripts/e2e/Dockerfile` built-app 镜像,然后以 `OPENCLAW_SKIP_DOCKER_BUILD=1` 并行运行 live/E2E smoke 通道;默认并发数 4 可通过 `OPENCLAW_DOCKER_ALL_PARALLELISM` 调整。本地聚合作业默认会在首次失败后停止调度新的池化通道,并且每个通道都有 120 分钟超时,可通过 `OPENCLAW_DOCKER_ALL_LANE_TIMEOUT_MS` 覆盖。对启动或 provider 敏感的通道会在并行池之后独占运行。可复用的 live/E2E 工作流也采用共享镜像模式:它会在 Docker 矩阵之前构建并推送一个带 SHA 标签的 GHCR Docker E2E 镜像,然后以 `OPENCLAW_SKIP_DOCKER_BUILD=1` 运行矩阵。定时的 live/E2E 工作流每天运行完整的发布路径 Docker 套件。QR 和安装器 Docker 测试保留各自面向安装的 Dockerfile。独立的 `docker-e2e-fast` 作业会在 120 秒命令超时限制下运行有界的内置插件 Docker 配置setup-entry 依赖修复以及合成的 bundled-loader 故障隔离。完整的 bundled update/channel 矩阵仍然是手动/全套件模式,因为它会执行重复的真实 npm update 和 doctor repair 过程。
本地 changed-lane 逻辑位于 `scripts/changed-lanes.mjs`,并由 `scripts/check-changed.mjs` 执行。与宽泛的 CI 平台范围相比这个本地门禁对架构边界要求更严格core 生产代码改动会运行 core 生产 typecheck 加 core 测试core 纯测试改动只运行 core 测试 typecheck/测试,扩展生产代码改动会运行扩展生产 typecheck 加扩展测试,而扩展纯测试改动只运行扩展测试 typecheck/测试。公共 Plugin SDK 或 plugin-contract 改动会扩展到扩展验证,因为扩展依赖这些核心契约。仅有发布元数据的版本号变更会运行定向的版本/配置/根依赖检查。未知的根目录/配置改动会以保守方式触发所有通道。
本地变更通道逻辑位于 `scripts/changed-lanes.mjs`,并由 `scripts/check-changed.mjs` 执行。这个本地门禁比广义的 CI 平台范围更严格地约束架构边界core 生产变更会运行 core 生产 typecheck 加 core 测试core 仅测试变更只会运行 core 测试 typecheck/测试,扩展生产变更会运行扩展生产 typecheck 加扩展测试,而扩展仅测试变更只会运行扩展测试 typecheck/测试。公共 Plugin SDK 或 plugin-contract 变更会扩展为扩展验证,因为扩展依赖这些 core 契约。仅发布元数据版本号变更会运行有针对性的版本/配置/根依赖检查。未知的根目录/配置变更会以安全优先方式退化为所有通道。
在 push 上,`checks` 矩阵会增加仅在 push 时运行的 `compat-node22` 通道。在拉取请求上,该通道会被跳过,矩阵保持聚焦于常规测试/渠道通道。
在 push 上,`checks` 矩阵会增加仅 push 才运行的 `compat-node22` 通道。在拉取请求上,该通道会被跳过,矩阵会专注于常规测试/渠道通道。
最慢的 Node 测试家族会被拆分或平衡,以保证每个作业都足够小,同时又不会过度占用 runners渠道契约会作为三个带权分片运行内置 plugin 测试会在六个扩展 worker 之间平衡,小型 core 单元通道会成对组合auto-reply 作为三个平衡 worker 运行,而不是六个很小的 worker并且 agentic Gateway 网关/plugin 配置会分散到现有的仅源代码 agentic Node 作业中而不是等待已构建产物。宽范围的浏览器、QA、媒体和杂项 plugin 测试使用各自专用的 Vitest 配置,而不是共享的 plugin catch-all。宽范围的 agents 通道使用共享的 Vitest 文件级并行调度器,因为它主要受 import/调度影响,而不是由某个单独的慢测试文件主导。`runtime-config` 与 infra core-runtime 分片一起运行,以避免共享运行时分片拖尾。`check-additional` 会将 package-boundary compile/canary 工作放在一起,并将运行时拓扑架构与 gateway watch 覆盖分开边界守卫分片会在一个作业内并发运行其小型独立守卫。Gateway 网关 watch、渠道测试以及 core support-boundary 分片会在 `build-artifacts` 中于 `dist/``dist-runtime/` 已构建完成后并发运行,在保留其原有检查名称作为轻量校验器作业的同时,避免再增加两个额外的 Blacksmith workers 和第二个产物消费者队列。
Android CI 会同时运行 `testPlayDebugUnitTest``testThirdPartyDebugUnitTest`,然后构建 Play debug APK。第三方 flavor 没有单独的 source set 或 manifest它的单元测试通道仍会使用 SMS/通话日志 BuildConfig 标志编译该 flavor同时避免在每次与 Android 相关的 push 上重复执行一个 debug APK 打包作业。
`extension-fast`限 PR因为 push 运行已经会执行完整的内置 plugin 分片。这样可以在代码评审时为已改动 plugin 提供反馈,而不会在 `main` 上为 `checks-node-extensions`覆盖的内容额外占用一个 Blacksmith worker。
最慢的 Node 测试家族会被拆分或平衡,以便每个作业都保持较小规模,而不会过度占用 runners渠道契约会拆成三个带权重的分片内置插件测试会在六个扩展 workers 之间平衡,小型 core 单元通道会两两配对,自动回复会使用三个平衡 workers 而不是六个很小的 workers而 agentic Gateway 网关/plugin 配置会分布到现有的仅源码 agentic Node 作业中而不是等待构建产物。广义的浏览器、QA、媒体和杂项插件测试使用它们专用的 Vitest 配置,而不是共享的插件兜底配置。扩展分片作业可以并发运行两个插件配置组,但会将每个 Vitest 配置限制为一个 worker这样以导入为主的插件批次就不会过度占用较小的 CI runners。广义的 agents 通道使用共享的 Vitest 文件级并行调度器,因为它受导入/调度开销主导,而不是由某个单独的慢测试文件主导。`runtime-config` 与 infra core-runtime 分片一起运行,以避免共享运行时分片独自承担尾部长耗时。`check-additional` 会将包边界 compile/canary 工作放在一起,并将运行时拓扑架构与 gateway watch 覆盖分开;边界守卫分片会在一个作业内并发运行其小型独立守卫。Gateway 网关 watch、渠道测试和 core support-boundary 分片会在 `dist/``dist-runtime/` 已构建完成后,在 `build-artifacts` 内部并发运行,保留它们原来的检查名称作为轻量验证作业,同时避免额外占用两个 Blacksmith workers 和第二个产物消费者队列。
Android CI 会同时运行 `testPlayDebugUnitTest``testThirdPartyDebugUnitTest`,然后构建 Play debug APK。第三方 flavor 没有单独的源码集或 manifest它的单元测试通道仍然会在启用 SMS/通话记录 BuildConfig 标志的情况下编译该 flavor同时避免在每次与 Android 相关的 push 上重复执行一个 debug APK 打包作业。
`extension-fast`在 PR 上运行,因为 push 运行已经会执行完整的内置插件分片。这样既能为代码评审提供已变更插件的反馈,又不会在 `main` 上为 `checks-node-extensions` 已覆盖的内容额外占用一个 Blacksmith worker。
当同一个 PR 或 `main` 引用上有新的 push 到达时GitHub 可能会将被替代的作业标记为 `cancelled`。除非同一引用的最新运行也失败,否则应将其视为 CI 噪音。聚合分片检查使用 `!cancelled() && always()`,这样它们仍会报告正常的分片失败,但不会在整个工作流已经被替代后继续排队。
CI 并发键带有版本号(`CI-v7-*`因此 GitHub 端旧队列组中的僵尸任务不会无限期阻塞较新的 main 运行。
当同一个 PR 或 `main` 引用上有新的推送到达时GitHub 可能会把已被替代的作业标记为 `cancelled`。除非同一引用的最新一次运行也失败,否则应将其视为 CI 噪声。聚合分片检查使用 `!cancelled() && always()`,因此它们仍会报告正常的分片失败,但不会在整个工作流已经被替代后继续排队。
CI 并发键带有版本号(`CI-v7-*`这样 GitHub 侧旧队列组中的僵尸任务就不会无限期阻塞较新的 main 运行。
## 运行器
| 运行器 | 作业 |
| -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ubuntu-24.04` | `preflight`、快速安全作业及其聚合`security-scm-fast`、`security-dependency-audit`、`security-fast`)、快速 protocol/contract/bundled 检查、分片的渠道契约检查、除 lint 外的 `check` 分片、`check-additional` 分片及聚合、Node 测试聚合验器、文档检查、Python Skills、workflow-sanity、labeler、auto-responseinstall-smoke preflight 也使用 GitHub 托管的 Ubuntu以便 Blacksmith 矩阵能够更早排队 |
| `blacksmith-8vcpu-ubuntu-2404` | `build-artifacts`、build-smoke、Linux Node 测试分片、内置 plugin 测试分片、`android` |
| `blacksmith-16vcpu-ubuntu-2404` | `check-lint`,它对 CPU 仍然足够敏感,以至于 8 vCPU 的成本比节省还高install-smoke Docker 构建也是如此,因为 32-vCPU 的排队时间成本高于其节省的时间 |
| `ubuntu-24.04` | `preflight`、快速安全作业及其聚合(`security-scm-fast`、`security-dependency-audit`、`security-fast`)、快速 protocol/contract/bundled 检查、分片的渠道契约检查、除 lint 外的 `check` 分片、`check-additional` 分片及聚合、Node 测试聚合验器、文档检查、Python Skills、workflow-sanity、labeler、auto-response`install-smoke` 的 preflight 也使用 GitHub 托管的 Ubuntu这样 Blacksmith 矩阵可以更早开始排队 |
| `blacksmith-8vcpu-ubuntu-2404` | `build-artifacts`、build-smoke、Linux Node 测试分片、内置插件测试分片、`android` |
| `blacksmith-16vcpu-ubuntu-2404` | `check-lint`,它对 CPU 的敏感度仍然高到使用 8 vCPU 反而得不偿失;以及 `install-smoke` 的 Docker 构建,在这里 32-vCPU 的排队时间成本高于收益 |
| `blacksmith-16vcpu-windows-2025` | `checks-windows` |
| `blacksmith-6vcpu-macos-latest` | `openclaw/openclaw` 上的 `macos-node`fork 会回退到 `macos-latest` |
| `blacksmith-12vcpu-macos-latest` | `openclaw/openclaw` 上的 `macos-swift`fork 会回退到 `macos-latest` |
@ -92,19 +92,19 @@ CI 并发键带有版本号(`CI-v7-*`),因此 GitHub 端旧队列组中的
## 本地等效命令
```bash
pnpm changed:lanes # 检查 origin/main...HEAD 的本地 changed-lane 分类器
pnpm check:changed # 智能本地门禁:按边界通道运行已变更的 typecheck/lint/tests
pnpm changed:lanes # 检查 origin/main...HEAD 的本地变更通道分类器
pnpm check:changed # 智能本地门禁:按边界通道运行变更相关的 typecheck/lint/测试
pnpm check # 快速本地门禁:生产 tsgo + 分片 lint + 并行快速守卫
pnpm check:test-types
pnpm check:timed # 同门禁,但附带每个阶段的耗时
pnpm check:timed # 同一套门禁,但附带每个阶段的耗时
pnpm build:strict-smoke
pnpm check:architecture
pnpm test:gateway:watch-regression
pnpm test # vitest 测试
pnpm test:channels
pnpm test:contracts:channels
pnpm check:docs # 文档格式化 + lint + 失效链接检查
pnpm check:docs # 文档格式化 + lint + 断链检查
pnpm build # 当 CI 产物/build-smoke 通道相关时,构建 dist
node scripts/ci-run-timings.mjs <run-id> # 汇总总耗时、排队时间和最慢作业
node scripts/ci-run-timings.mjs <run-id> # 汇总总耗时、排队时间和最慢作业
node scripts/ci-run-timings.mjs --recent 10 # 比较最近成功的 main CI 运行
```

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,25 +1,25 @@
---
read_when:
- OpenClaw 无法正常工作,而你需要最快速的修复路径
- 在深入查看详细操作手册之前,你想先走一遍分诊流程
- 你想先走一遍分诊流程,再深入查看详细运行手册
summary: OpenClaw 的按症状优先故障排除中心
title: 常见故障排除
x-i18n:
generated_at: "2026-04-20T06:31:02Z"
generated_at: "2026-04-23T18:24:12Z"
model: gpt-5.4
provider: openai
source_hash: cc5d8c9f804084985c672c5a003ce866e8142ab99fe81abb7a0d38e22aea4b88
source_hash: c6931ea9a8f29de0aa42c0afdf554e223fd2a794e95dce4f4795db99301d2c44
source_path: help/troubleshooting.md
workflow: 15
---
# 故障排除
如果你只有 2 分钟,把这个页面当作分诊入口。
如果你只有 2 分钟,把这个页面当作分诊入口即可
## 最初的六十秒
按顺序运行下面这组精确的排查步骤
按顺序运行以下这一整套命令
```bash
openclaw status
@ -34,11 +34,11 @@ openclaw logs --follow
一行看懂“正常输出”:
- `openclaw status` → 显示已配置的渠道,且没有明显的认证错误。
- `openclaw status --all` → 完整报告存在,并且可以分享。
- `openclaw gateway probe`可以访问预期的 Gateway 网关目标(`Reachable: yes`)。`Capability: ...` 会告诉你探测能够证明的认证级别,而 `Read probe: limited - missing scope: operator.read` 表示诊断能力降级,不是连接失败。
- `openclaw gateway status` → 显示 `Runtime: running`、`Connectivity probe: ok`,以及合理的 `Capability: ...` 行。如果你还需要验证读权限范围的 RPC 证明,请使用 `--require-rpc`
- `openclaw status --all`提供完整报告,并且可以分享给他人查看
- `openclaw gateway probe` → 预期的 Gateway 网关目标可达`Reachable: yes`)。`Capability: ...` 会告诉你探测能够证明的认证级别,而 `Read probe: limited - missing scope: operator.read` 表示诊断能力受限,不代表连接失败。
- `openclaw gateway status` → 显示 `Runtime: running`、`Connectivity probe: ok`,以及合理的 `Capability: ...` 行。如果你还需要证明具备读取作用域的 RPC 访问能力,请使用 `--require-rpc`
- `openclaw doctor` → 没有阻塞性的配置或服务错误。
- `openclaw channels status --probe`当 Gateway 网关可达时,会返回每个账户的实时传输状态,以及诸`works``audit ok` 这样的探测/审计结果;如果 Gateway 网关不可达,该命令会回退为仅配置摘要。
- `openclaw channels status --probe`如果 Gateway 网关可达,会返回每个账号的实时传输状态以及`works``audit ok` 这样的探测/审计结果;如果 Gateway 网关不可达,该命令会回退为仅基于配置摘要。
- `openclaw logs --follow` → 活动持续稳定,没有反复出现的致命错误。
## Anthropic 长上下文 429
@ -47,23 +47,21 @@ openclaw logs --follow
`HTTP 429: rate_limit_error: Extra usage is required for long context requests`
请前往 [/gateway/troubleshooting#anthropic-429-extra-usage-required-for-long-context](/zh-CN/gateway/troubleshooting#anthropic-429-extra-usage-required-for-long-context)。
## 本地 OpenAI 兼容后端直可用,但在 OpenClaw 中失败
## 本地 OpenAI 兼容后端直可用,但在 OpenClaw 中失败
如果你的本地或自托管 `/v1` 后端可以响应小型直接
`/v1/chat/completions` 探测,但在 `openclaw infer model run` 或正常
智能体 回合中失败:
如果你的本地或自托管 `/v1` 后端对小型直接
`/v1/chat/completions` 探测请求能正常响应,但在 `openclaw infer model run` 或正常的智能体对话轮次中失败:
1. 如果错误提到 `messages[].content` 需要字符串,设置
1. 如果错误提到 `messages[].content` 需要字符串,设置
`models.providers.<provider>.models[].compat.requiresStringContent: true`
2. 如果该后端仍然只在 OpenClaw 智能体 回合中失败,设置
`models.providers.<provider>.models[].compat.supportsTools: false` 然后重试。
3. 如果极小的直接调用仍然可用,但更大的 OpenClaw 提示词会让后端崩溃,将剩余问题视为上游模型/服务器限制,并继续查看详细操作手册:
2. 如果该后端仍然只在 OpenClaw 智能体对话轮次中失败,请设置
`models.providers.<provider>.models[].compat.supportsTools: false`然后重试。
3. 如果极小的直接调用仍然可用,但更大的 OpenClaw 提示词会导致后端崩溃,请将剩余问题视为上游模型/服务器限制,并继续阅读详细运行手册:
[/gateway/troubleshooting#local-openai-compatible-backend-passes-direct-probes-but-agent-runs-fail](/zh-CN/gateway/troubleshooting#local-openai-compatible-backend-passes-direct-probes-but-agent-runs-fail)
## 插件安装失败,提示缺少 openclaw extensions
如果安装失败并显示 `package.json missing openclaw.extensions`,说明该插件包
使用了 OpenClaw 已不再接受的旧结构。
如果安装因 `package.json missing openclaw.extensions` 失败,说明该插件包仍在使用 OpenClaw 已不再接受的旧结构。
在插件包中这样修复:
@ -91,10 +89,10 @@ openclaw logs --follow
flowchart TD
A[OpenClaw 无法正常工作] --> B{最先出问题的是什么}
B --> C[没有回复]
B --> D[仪表板或 Control UI 无法连接]
B --> D[Dashboard 或 Control UI 无法连接]
B --> E[Gateway 网关无法启动或服务未运行]
B --> F[渠道已连接但消息不流转]
B --> G[Cron 或心跳没有触发或没有送达]
B --> F[渠道已连接但消息不流转]
B --> G[Cron 或 heartbeat 未触发或未送达]
B --> H[节点已配对,但 camera canvas screen exec 失败]
B --> I[浏览器工具失败]
@ -117,19 +115,19 @@ flowchart TD
openclaw logs --follow
```
正常输出应类似于:
正常输出应类似于:
- `Runtime: running`
- `Connectivity probe: ok`
- `Capability: read-only`、`write-capable` 或 `admin-capable`
- 你的渠道显示传输已连接,并且在支持的情况下,`channels status --probe` 中会显示 `works``audit ok`
- 发送方显示已获批准(或 私信 策略为开放/允许列表)
- 发送者显示为已批准(或者私信策略为开放/允许列表)
常见日志特征:
- `drop guild message (mention required`Discord 中的提及门控阻止了该消息。
- `pairing request` → 发送方未获批准,正在等待 私信 配对批准。
- 渠道日志中的 `blocked` / `allowlist` → 发送、房间或群组被过滤。
- `drop guild message (mention required`在 Discord 中,提及门控阻止了该消息。
- `pairing request` → 发送者尚未获批,正在等待私信配对批准。
- 渠道日志中的 `blocked` / `allowlist` → 发送、房间或群组被过滤。
详细页面:
@ -139,7 +137,7 @@ flowchart TD
</Accordion>
<Accordion title="仪表板或 Control UI 无法连接">
<Accordion title="Dashboard 或 Control UI 无法连接">
```bash
openclaw status
openclaw gateway status
@ -148,9 +146,9 @@ flowchart TD
openclaw channels status --probe
```
正常输出应类似于:
正常输出应类似于:
- `openclaw gateway status` 中显示 `Dashboard: http://...`
- `openclaw gateway status` 中显示 `Dashboard: http://...`
- `Connectivity probe: ok`
- `Capability: read-only`、`write-capable` 或 `admin-capable`
- 日志中没有认证循环
@ -158,23 +156,23 @@ flowchart TD
常见日志特征:
- `device identity required` → HTTP/非安全上下文无法完成设备认证。
- `origin not allowed` → 浏览器 `Origin` 不被该 Control UI Gateway 网关目标允许
- 带有重试提示`canRetryWithDeviceToken=true`)的 `AUTH_TOKEN_MISMATCH` → 可能会自动进行一次可信设备令牌重试。
- `origin not allowed` → 浏览器`Origin` 不在 Control UI 的 Gateway 网关目标允许范围内
- 带有重试提示`AUTH_TOKEN_MISMATCH``canRetryWithDeviceToken=true`)→ 可能会自动执行一次受信任的设备令牌重试。
- 该缓存令牌重试会复用与已配对设备令牌一起存储的缓存作用域集合。显式 `deviceToken` / 显式 `scopes` 调用方则会保留其请求的作用域集合。
- 在异步 Tailscale Serve Control UI 路径中,对于同一个 `{scope, ip}` 的失败尝试会在限制器记录失败之前被串行化,因此第二个并发的错误重试可能已经显示 `retry later`
- 来自 localhost 浏览器来源的 `too many failed authentication attempts (retry later)` → 来自同一 `Origin` 的重复失败会被临时锁定;另一个 localhost 来源会使用单独的桶。
- 在重试之后反复出现 `unauthorized` → 令牌/密码错误、认证模式不匹配,或已配对设备令牌已过期。
- `gateway connect failed:` → UI 指向了错误的 URL/端口,或 Gateway 网关不可达。
- 在异步 Tailscale Serve Control UI 路径上,对于相同 `{scope, ip}` 的失败尝试,会在限制器记录失败之前串行处理,因此第二个并发的错误重试可能已经显示 `retry later`
- 来自 localhost 浏览器来源的 `too many failed authentication attempts (retry later)` → 来自同一 `Origin` 的重复失败会被临时锁定;不同的 localhost 来源使用独立的桶。
- 在那次重试之后反复出现 `unauthorized` → 令牌/密码错误、认证模式不匹配,或已配对设备令牌已过期。
- `gateway connect failed:` → UI 指向了错误的 URL/端口,或 Gateway 网关不可达。
详细页面:
- [/gateway/troubleshooting#dashboard-control-ui-connectivity](/zh-CN/gateway/troubleshooting#dashboard-control-ui-connectivity)
- [/web/control-ui](/web/control-ui)
- [/web/control-ui](/zh-CN/web/control-ui)
- [/gateway/authentication](/zh-CN/gateway/authentication)
</Accordion>
<Accordion title="Gateway 网关无法启动或服务已安装但未运行">
<Accordion title="Gateway 网关无法启动或服务已安装但未运行">
```bash
openclaw status
openclaw gateway status
@ -183,7 +181,7 @@ flowchart TD
openclaw channels status --probe
```
正常输出应类似于:
正常输出应类似于:
- `Service: ... (loaded)`
- `Runtime: running`
@ -192,8 +190,8 @@ flowchart TD
常见日志特征:
- `Gateway start blocked: set gateway.mode=local``existing config is missing gateway.mode` → Gateway 网关模式 remote或者配置文件缺少本地模式标记需要修复。
- `refusing to bind gateway ... without auth` → 在没有有效 Gateway 网关认证路径(令牌/密码,或已配置的 trusted-proxy的情况下拒绝绑定非 loopback 地址。
- `Gateway start blocked: set gateway.mode=local``existing config is missing gateway.mode` → Gateway 网关模式 remote或者配置文件缺少本地模式标记需要修复。
- `refusing to bind gateway ... without auth` → 在没有有效 Gateway 网关认证路径(令牌/密码,或已配置情况下的 trusted-proxy的情况下拒绝绑定非 loopback 地址。
- `another gateway instance is already listening``EADDRINUSE` → 端口已被占用。
详细页面:
@ -204,7 +202,7 @@ flowchart TD
</Accordion>
<Accordion title="渠道已连接但消息不流转">
<Accordion title="渠道已连接但消息不流转">
```bash
openclaw status
openclaw gateway status
@ -213,16 +211,16 @@ flowchart TD
openclaw channels status --probe
```
正常输出应类似于:
正常输出应类似于:
- 渠道传输已连接。
- 配对/允许列表检查通过。
- 在需要时,提及检测到。
- 配对/允许列表检查通过。
- 在需要提及时,已检测到提及
常见日志特征:
- `mention required` → 群组提及门控阻止了处理。
- `pairing` / `pending` → 私信 发送方尚未获批准
- `pairing` / `pending` → 私信发送者尚未获批
- `not_in_channel`、`missing_scope`、`Forbidden`、`401/403` → 渠道权限令牌问题。
详细页面:
@ -232,7 +230,7 @@ flowchart TD
</Accordion>
<Accordion title="Cron 或心跳没有触发或没有送达">
<Accordion title="Cron 或 heartbeat 未触发或未送达">
```bash
openclaw status
openclaw gateway status
@ -242,21 +240,21 @@ flowchart TD
openclaw logs --follow
```
正常输出应类似于:
正常输出应类似于:
- `cron.status` 显示已启用,并有下一次唤醒时间。
- `cron.status` 显示已启用,并有下一次唤醒时间。
- `cron runs` 显示最近的 `ok` 条目。
- 心跳已启用,且不在活跃时段之外。
- heartbeat 已启用,并且不在活跃时间之外。
常见日志特征:
- `cron: scheduler disabled; jobs will not run automatically` → cron 已禁用。
- 带有 `reason=quiet-hours``heartbeat skipped` → 当前不在配置的活跃时段内
- 带有 `reason=empty-heartbeat-file``heartbeat skipped``HEARTBEAT.md` 存在,但只包含空白/仅标题的骨架内容。
- 带有 `reason=no-tasks-due``heartbeat skipped``HEARTBEAT.md` 任务模式已启用,但尚无任务到达间隔时间。
- 带有 `reason=alerts-disabled``heartbeat skipped` → 所有心跳可见性均被禁用(`showOk`、`showAlerts` 和 `useIndicator` 全部关闭)。
- `requests-in-flight` → 主通道繁忙;心跳唤醒被延后。
- `unknown accountId`心跳投递目标账户不存在。
- `heartbeat skipped``reason=quiet-hours` → 当前处于配置的非活跃时段
- `heartbeat skipped``reason=empty-heartbeat-file``HEARTBEAT.md` 存在,但只包含空白/仅标题的脚手架内容。
- `heartbeat skipped``reason=no-tasks-due``HEARTBEAT.md` 任务模式已启用,但当前没有任何任务到达间隔时间。
- `heartbeat skipped``reason=alerts-disabled` → 所有 heartbeat 可见性均已禁用(`showOk`、`showAlerts` 和 `useIndicator` 全部关闭)。
- `requests-in-flight` → 主通道繁忙;heartbeat 唤醒已被延后。
- `unknown accountId`heartbeat 投递目标账号不存在。
详细页面:
@ -264,125 +262,125 @@ flowchart TD
- [/automation/cron-jobs#troubleshooting](/zh-CN/automation/cron-jobs#troubleshooting)
- [/gateway/heartbeat](/zh-CN/gateway/heartbeat)
</Accordion>
</Accordion>
<Accordion title="节点已配对,但工具中的 camera canvas screen exec 失败">
```bash
openclaw status
openclaw gateway status
openclaw nodes status
openclaw nodes describe --node <idOrNameOrIp>
openclaw logs --follow
```
<Accordion title="节点已配对,但工具失败camera canvas screen exec">
```bash
openclaw status
openclaw gateway status
openclaw nodes status
openclaw nodes describe --node <idOrNameOrIp>
openclaw logs --follow
```
正常输出应类似于:
正常输出应类似于:
- 节点显示为已连接,并且已按 `node` 角色完成配对。
- 你正在调用的命令具备相应能力
- 该工具的权限状态已授予。
- 节点列为已连接,并且已针对 `node` 角色完成配对。
- 你调用的命令所需能力存在
- 该工具的权限状态已授予。
常见日志特征:
常见日志特征:
- `NODE_BACKGROUND_UNAVAILABLE` → 将节点应用切到前台。
- `*_PERMISSION_REQUIRED` → 操作系统权限被拒绝或缺失。
- `SYSTEM_RUN_DENIED: approval required` → exec 审批仍在等待中。
- `SYSTEM_RUN_DENIED: allowlist miss` → 命令不在 exec 允许列表中。
- `NODE_BACKGROUND_UNAVAILABLE` → 将节点应用切到前台。
- `*_PERMISSION_REQUIRED` → 操作系统权限被拒绝或缺失。
- `SYSTEM_RUN_DENIED: approval required` → exec 批准正在等待中。
- `SYSTEM_RUN_DENIED: allowlist miss` → 命令不在 exec 允许列表中。
详细页面:
详细页面:
- [/gateway/troubleshooting#node-paired-tool-fails](/zh-CN/gateway/troubleshooting#node-paired-tool-fails)
- [/nodes/troubleshooting](/zh-CN/nodes/troubleshooting)
- [/tools/exec-approvals](/zh-CN/tools/exec-approvals)
- [/gateway/troubleshooting#node-paired-tool-fails](/zh-CN/gateway/troubleshooting#node-paired-tool-fails)
- [/nodes/troubleshooting](/zh-CN/nodes/troubleshooting)
- [/tools/exec-approvals](/zh-CN/tools/exec-approvals)
</Accordion>
</Accordion>
<Accordion title="Exec 突然开始要求批">
```bash
openclaw config get tools.exec.host
openclaw config get tools.exec.security
openclaw config get tools.exec.ask
openclaw gateway restart
```
<Accordion title="Exec 突然开始要求">
```bash
openclaw config get tools.exec.host
openclaw config get tools.exec.security
openclaw config get tools.exec.ask
openclaw gateway restart
```
发生了什么变化:
发生了什么变化:
- 如果 `tools.exec.host` 未设置,默认值是 `auto`
- `host=auto` 在沙箱运行时处于活动状态时会解析为 `sandbox`否则解析为 `gateway`
- `host=auto` 只负责路由;无提示的 “YOLO” 行为来自 gateway/node 上的 `security=full``ask=off`
- 在 `gateway``node` 上,未设置的 `tools.exec.security` 默认 `full`
- 未设置的 `tools.exec.ask` 默认是 `off`
- 结果:如果你看到了审批提示,说明某些主机本地或按会话生效的策略把 exec 收紧到了偏离当前默认值的状态
- 如果 `tools.exec.host` 未设置,默认值是 `auto`
- 当沙箱运行时处于活动状态时,`host=auto` 会解析为 `sandbox`否则解析为 `gateway`
- `host=auto` 只负责路由;无提示的 “YOLO” 行为来自 `gateway`/`node` 上的 `security=full``ask=off`
- 在 `gateway``node` 上,未设置的 `tools.exec.security` 默认值为 `full`
- 未设置的 `tools.exec.ask` 默认值为 `off`
- 结果:如果你现在看到了批准请求,说明某些主机本地或按会话生效的策略,已将 exec 收紧到了当前默认值之外
恢复当前默认的“无需批”行为:
恢复当前默认的“无需批”行为:
```bash
openclaw config set tools.exec.host gateway
openclaw config set tools.exec.security full
openclaw config set tools.exec.ask off
openclaw gateway restart
```
```bash
openclaw config set tools.exec.host gateway
openclaw config set tools.exec.security full
openclaw config set tools.exec.ask off
openclaw gateway restart
```
更安全的替代方案:
更安全的替代方案:
- 如果你只是想要稳定的主机路由,只设置 `tools.exec.host=gateway`
- 如果你想使用主机 exec但仍希望在允许列表未命中时进行审查可使用 `security=allowlist` 搭配 `ask=on-miss`
- 如果你希望 `host=auto` 重新解析为 `sandbox`,请启用沙箱模式。
- 如果你只是想要稳定的主机路由,只设置 `tools.exec.host=gateway`
- 如果你想使用主机 exec但仍希望在未命中允许列表时进行审查请使用 `security=allowlist` 配合 `ask=on-miss`
- 如果你希望 `host=auto` 再次解析回 `sandbox`,请启用沙箱模式。
常见日志特征:
常见日志特征:
- `Approval required.` → 命令正在等待 `/approve ...`
- `SYSTEM_RUN_DENIED: approval required` → 节点主机 exec 审批仍在等待中。
- `exec host=sandbox requires a sandbox runtime for this session`隐式或显式选择了 sandbox,但沙箱模式未开启。
- `Approval required.` → 命令正在等待 `/approve ...`
- `SYSTEM_RUN_DENIED: approval required` → 节点主机 exec 批准正在等待中。
- `exec host=sandbox requires a sandbox runtime for this session`已隐式/显式选择沙箱,但沙箱模式未开启。
详细页面:
详细页面:
- [/tools/exec](/zh-CN/tools/exec)
- [/tools/exec-approvals](/zh-CN/tools/exec-approvals)
- [/gateway/security#what-the-audit-checks-high-level](/zh-CN/gateway/security#what-the-audit-checks-high-level)
- [/tools/exec](/zh-CN/tools/exec)
- [/tools/exec-approvals](/zh-CN/tools/exec-approvals)
- [/gateway/security#what-the-audit-checks-high-level](/zh-CN/gateway/security#what-the-audit-checks-high-level)
</Accordion>
</Accordion>
<Accordion title="浏览器工具失败">
```bash
openclaw status
openclaw gateway status
openclaw browser status
openclaw logs --follow
openclaw doctor
```
<Accordion title="浏览器工具失败">
```bash
openclaw status
openclaw gateway status
openclaw browser status
openclaw logs --follow
openclaw doctor
```
正常输出应类似于:
正常输出应类似于:
- 浏览器状态显示 `running: true`,以及选定的浏览器/配置文件。
- `openclaw`启动,或者 `user` 可以看到本地 Chrome 标签页。
- 浏览器状态显示 `running: true`,以及已选择的浏览器/配置文件。
- `openclaw` 可以启动,或者 `user` 可以看到本地 Chrome 标签页。
常见日志特征:
常见日志特征:
- `unknown command "browser"``unknown command 'browser'` → 设置 `plugins.allow`,但其中不包含 `browser`
- `Failed to start Chrome CDP on port` → 本地浏览器启动失败。
- `browser.executablePath not found` → 配置的二进制路径错误。
- `browser.cdpUrl must be http(s) or ws(s)` → 配置的 CDP URL 使用了不受支持的协议。
- `browser.cdpUrl has invalid port` → 配置的 CDP URL 端口无效或超出范围。
- `No Chrome tabs found for profile="user"` → Chrome MCP 附加配置文件没有打开的本地 Chrome 标签页。
- `Remote CDP for profile "<name>" is not reachable` → 配置的远程 CDP 端点从当前主机无法访问。
- `Browser attachOnly is enabled ... not reachable``Browser attachOnly is enabled and CDP websocket ... is not reachable` → 仅附加配置文件没有可用的实时 CDP 目标。
- attach-only 或远程 CDP 配置文件上存在过期的视口 / 深色模式 / 区域设置 / 离线覆盖状态 → 运行 `openclaw browser stop --browser-profile <name>`,关闭活动控制会话并释放模拟状态,而无需重启 Gateway 网关。
- `unknown command "browser"``unknown command 'browser'`设置 `plugins.allow`,但其中不包含 `browser`
- `Failed to start Chrome CDP on port` → 本地浏览器启动失败。
- `browser.executablePath not found` → 配置的二进制路径错误。
- `browser.cdpUrl must be http(s) or ws(s)` → 配置的 CDP URL 使用了不受支持的协议。
- `browser.cdpUrl has invalid port` → 配置的 CDP URL 端口错误或超出范围。
- `No Chrome tabs found for profile="user"` → Chrome MCP 附加配置文件没有打开的本地 Chrome 标签页。
- `Remote CDP for profile "<name>" is not reachable` → 配置的远程 CDP 端点从当前主机无法访问。
- `Browser attachOnly is enabled ... not reachable``Browser attachOnly is enabled and CDP websocket ... is not reachable` → 仅附加配置文件没有可用的 CDP 目标。
- attach-only 或远程 CDP 配置文件上存在陈旧的视口 / 深色模式 / 区域设置 / 离线覆盖状态 → 运行 `openclaw browser stop --browser-profile <name>`,关闭当前活动控制会话并释放模拟状态,而无需重启 Gateway 网关。
详细页面:
详细页面:
- [/gateway/troubleshooting#browser-tool-fails](/zh-CN/gateway/troubleshooting#browser-tool-fails)
- [/tools/browser#missing-browser-command-or-tool](/zh-CN/tools/browser#missing-browser-command-or-tool)
- [/tools/browser-linux-troubleshooting](/zh-CN/tools/browser-linux-troubleshooting)
- [/tools/browser-wsl2-windows-remote-cdp-troubleshooting](/zh-CN/tools/browser-wsl2-windows-remote-cdp-troubleshooting)
- [/gateway/troubleshooting#browser-tool-fails](/zh-CN/gateway/troubleshooting#browser-tool-fails)
- [/tools/browser#missing-browser-command-or-tool](/zh-CN/tools/browser#missing-browser-command-or-tool)
- [/tools/browser-linux-troubleshooting](/zh-CN/tools/browser-linux-troubleshooting)
- [/tools/browser-wsl2-windows-remote-cdp-troubleshooting](/zh-CN/tools/browser-wsl2-windows-remote-cdp-troubleshooting)
</Accordion>
</Accordion>
</AccordionGroup>
</AccordionGroup>
## 相关内容
- [常见问题](/zh-CN/help/faq) — 常见问题
- [Gateway 网关故障排除](/zh-CN/gateway/troubleshooting) — Gateway 网关专问题
- [Doctor](/zh-CN/gateway/doctor) — 自动健康检查与修复
- [常见问题](/zh-CN/help/faq) — 常见问题解答
- [Gateway 网关故障排除](/zh-CN/gateway/troubleshooting) — Gateway 网关专问题
- [Doctor](/zh-CN/gateway/doctor) — 自动健康检查与修复
- [渠道故障排除](/zh-CN/channels/troubleshooting) — 渠道连接问题
- [自动化故障排除](/zh-CN/automation/cron-jobs#troubleshooting) — cron 和心跳问题
- [自动化故障排除](/zh-CN/automation/cron-jobs#troubleshooting) — cron 和 heartbeat 问题

View File

@ -1,69 +1,71 @@
---
read_when:
- 配置执行批或允许列表
- 在 macOS 应用中实现执行批 UX
- 配置执行批或允许列表
- 在 macOS 应用中实现执行批 UX
- 审查沙箱逃逸提示及其影响
summary: 执行批、允许列表和沙箱逃逸提示
title: 执行批
summary: 执行批、允许列表和沙箱逃逸提示
title: 执行
x-i18n:
generated_at: "2026-04-23T17:53:31Z"
generated_at: "2026-04-23T18:24:13Z"
model: gpt-5.4
provider: openai
source_hash: 942d09665ff9d567361b0c5ee195a5a6b8c893ea1c9412caa33a02acd8e5e5be
source_hash: 1a5aca24c739cd4edfe5389c4897cb6f2efc07141217a70610c247aaa71a5284
source_path: tools/exec-approvals.md
workflow: 15
---
# 执行批
# 执行
执行批准是允许沙箱隔离的智能体在真实主机(`gateway` 或 `node`)上运行命令时的**配套应用 / 节点主机护栏**。它是一个安全联锁:只有当策略 + 允许列表 +(可选的)用户批准全部同意时,命令才会被允许。执行批准叠加在工具策略和 elevated 门控**之上**(除非 elevated 设为 `full`,此时会跳过批准)。
执行审批是用于让沙箱隔离的智能体在真实主机(`gateway` 或 `node`)上运行命令的 **配套应用 / 节点主机护栏**。它是一种安全联锁机制:只有当策略 + 允许列表 +(可选)用户审批全部同意时,命令才会被允许执行。执行审批会**叠加在**工具策略和 elevated 门控之上(除非 elevated 被设置为 `full`,此时会跳过审批)。
<Note>
生效策略取 `tools.exec.*`批准默认值中**更严格**的一方;如果某个批准字段被省略,则使用 `tools.exec` 的值。主机执行还会使用该机器上的本地批状态——如果 `~/.openclaw/exec-approvals.json`主机本地的 `ask: "always"`,即使会话或配置默认值请求 `ask: "on-miss"`,也仍然会持续提示。
生效策略取 `tools.exec.*`审批默认值中**更严格**的那个;如果某个审批字段被省略,则使用 `tools.exec` 的值。主机执行还会使用该机器上的本地批状态——如果 `~/.openclaw/exec-approvals.json` 中主机本地的 `ask: "always"` 已设置,即使会话或配置默认值请求 `ask: "on-miss"`,也仍然会持续提示。
</Note>
## 检查生效策略
- `openclaw approvals get`、`... --gateway`、`... --node <id|name|ip>` — 显示请求的策略、主机策略来源以及生效结果。
- `openclaw exec-policy show` — 本地机器上的合并视图。
- `openclaw exec-policy set|preset` — 一步将本地请求策略与本地主机批文件同步。
- `openclaw approvals get`、`... --gateway`、`... --node <id|name|ip>` — 显示请求的策略、主机策略来源以及最终生效结果。
- `openclaw exec-policy show` 显示本地机器上的合并视图。
- `openclaw exec-policy set|preset` 一步完成:将本地请求策略与本地主机批文件同步。
当本地作用域请求 `host=node` 时,`exec-policy show` 会在运行时将该作用域报告为由节点管理,而不是假装本地批文件是真实来源。
当本地作用域请求 `host=node` 时,`exec-policy show` 会在运行时将该作用域报告为由节点管理,而不是假装本地批文件是真实来源。
如果配套应用 UI **不可用**,任何通常会弹出提示的请求都会由 **ask fallback** 决定结果(默认:拒绝)。
如果配套应用 UI **不可用**,任何原本通常会触发提示的请求都会由 **ask fallback** 处理(默认:拒绝)。
<Tip>
原生聊天批准客户端可以在待处理的批准消息上预置特定渠道的便捷交互。例如Matrix 会预置反应快捷方式(`✅` 允许一次、`❌` 拒绝、`♾️` 始终允许),同时仍在消息中保留 `/approve ...` 命令作为后备方案。
原生聊天审批客户端可以在待处理审批消息上预填特定渠道的便捷交互。例如Matrix 会预填反应快捷方式(`✅`
允许一次、`❌` 拒绝、`♾️` 始终允许),同时仍会在消息中保留 `/approve ...`
命令作为后备方案。
</Tip>
## 适用范围
## 适用位置
执行批会在执行主机本地强制执行:
执行批会在执行主机本地强制执行:
- **gateway host** → Gateway 机器上的 `openclaw` 进程
- **node host** → 节点运行器macOS 配套应用或无头节点主机)
- **Gateway 网关主机** → Gateway 网关机器上的 `openclaw` 进程
- **节点主机** → 节点运行器macOS 配套应用或无头节点主机)
信任模型说明:
- 通过 Gateway 认证的调用方是该 Gateway 网关的受信任操作员。
- 已配对节点会将受信任操作员能力扩展到节点主机。
- 执行批准可降低意外执行风险,但不是按用户划分的认证边界。
- 已批准的节点主机运行会绑定规范执行上下文:规范 cwd、精确 argv、存在时的 env 绑定,以及适用时固定的可执行文件路径。
- 对于 shell 脚本和直接解释器 / 运行时文件调用OpenClaw 还会尝试绑定一个具体的本地文件操作数。如果该绑定文件在批准后、执行前发生变化,则会拒绝本次运行,而不是执行已漂移的内容。
- 这种文件绑定有意设计为尽力而为,而不是对每一种解释器 / 运行时加载路径都建立完整语义模型。如果批准模式无法识别并绑定**恰好一个**具体的本地文件,它会拒绝签发基于批准的运行,而不是假装具备完整覆盖能力
- 通过 Gateway 网关认证的调用方会被视为该 Gateway 网关的受信任操作员。
- 已配对节点会将这种受信任操作员能力扩展到节点主机。
- 执行审批可以降低意外执行风险,但它不是按用户划分的身份验证边界。
- 已批准的节点主机执行会绑定规范化的执行上下文:规范化 cwd、精确 argv、存在时的 env 绑定,以及适用时固定的可执行文件路径。
- 对于 shell 脚本和直接解释器 / 运行时文件调用OpenClaw 还会尝试绑定一个具体的本地文件操作数。如果该绑定文件在批准后、执行前发生变化,则该次执行拒绝,而不是执行已漂移的内容。
- 这种文件绑定有意采用尽力而为的方式,而不是为每一种解释器 / 运行时加载路径提供完整语义模型。如果审批模式无法识别出恰好一个具体的本地文件用于绑定,它会拒绝签发带审批支持的执行,而不是假装自己能完全覆盖
macOS 拆分:
- **节点主机服务** 通过本地 IPC 将 `system.run` 转发给 **macOS 应用**
- **macOS 应用** 负责强制执行批准并在 UI 上下文中执行命令。
- **节点主机服务** 通过本地 IPC 将 `system.run` 转发给 **macOS 应用**
- **macOS 应用** 会在 UI 上下文中执行审批 + 运行命令。
## 设置存储
## 设置存储
批准存储在执行主机本地的一个 JSON 文件中:
审批配置存储在执行主机上的本地 JSON 文件中:
`~/.openclaw/exec-approvals.json`
示例结构
示例模式
```json
{
@ -98,14 +100,14 @@ macOS 拆分:
}
```
## 无需批准的 “YOLO” 模式
## 无审批的 “YOLO” 模式
如果你希望主机执行在没有批准提示的情况下运行,则必须同时打开**两层**策略:
如果你希望主机执行在没有审批提示的情况下运行,你必须同时放开**两层**策略:
- OpenClaw 配置中的请求执行策略(`tools.exec.*`
- `~/.openclaw/exec-approvals.json` 中主机本地的批策略
- `~/.openclaw/exec-approvals.json` 中主机本地的批策略
现在是默认的主机行为,除非你显式收紧它:
现在是默认的主机行为,除非你显式收紧它:
- `tools.exec.security`: 在 `gateway`/`node` 上设为 `full`
- `tools.exec.ask`: `off`
@ -113,15 +115,15 @@ macOS 拆分:
重要区别:
- `tools.exec.host=auto` 决定执行运行在何处:有沙箱时运行在沙箱,否则运行在 gateway
- YOLO 决定主机执行如何被批准`security=full` 加 `ask=off`
- 在 YOLO 模式下OpenClaw 不会在已配置的主机执行策略之上,额外添加单独的启发式命令混淆批或脚本预检拒绝层。
- `auto` 不会让来自沙箱会话的 gateway 路由请求成为一个无代价的覆盖项。每次调用的 `host=node` 请求在 `auto` 下是允许的,而 `host=gateway` 仅在没有活动沙箱运行时的 `auto` 下允许。如果你希望一个稳定的非 auto 默认值,请设置 `tools.exec.host` 或显式使用 `/exec host=...`
- `tools.exec.host=auto` 决定执行在哪里运行:如果有沙箱则在沙箱中运行,否则在 Gateway 网关中运行
- YOLO 决定主机执行如何获批`security=full` 加 `ask=off`
- 在 YOLO 模式下OpenClaw 不会在已配置的主机执行策略之上,额外添加单独的启发式命令混淆批门或脚本预检拒绝层。
- `auto` 不会让 Gateway 网关路由从沙箱隔离会话中变成一个可随意覆盖的通道。单次调用的 `host=node` 请求在 `auto` 下是允许的,而 `host=gateway` 仅在没有活跃沙箱运行时时,才允许从 `auto` 发起。如果你想要一个稳定的非 auto 默认值,请设置 `tools.exec.host`或显式使用 `/exec host=...`
如果你希望更保守的设置,请将任一层收紧回 `allowlist` / `on-miss`
如果你想要更保守的设置,可以把任意一层重新收紧为 `allowlist` / `on-miss`
`deny`
持久化的 gateway host “永不提示” 设置:
持久化的 Gateway 网关主机 “永不提示” 设置:
```bash
openclaw config set tools.exec.host gateway
@ -130,7 +132,7 @@ openclaw config set tools.exec.ask off
openclaw gateway restart
```
然后将主机批文件设置为匹配:
然后将主机批文件设置为匹配
```bash
openclaw approvals set --stdin <<'EOF'
@ -145,7 +147,7 @@ openclaw approvals set --stdin <<'EOF'
EOF
```
当前机器上相同 gateway host 策略的本地快捷方式:
当前机器上同一 Gateway 网关主机策略的本地快捷方式:
```bash
openclaw exec-policy preset yolo
@ -156,11 +158,10 @@ openclaw exec-policy preset yolo
- 本地 `tools.exec.host/security/ask`
- 本地 `~/.openclaw/exec-approvals.json` 默认值
它有意仅限本地使用。如果你需要远程更改 gateway host 或 node host 的批准,
请继续使用 `openclaw approvals set --gateway`
它有意仅在本地生效。如果你需要远程修改 Gateway 网关主机或节点主机审批,请继续使用 `openclaw approvals set --gateway`
`openclaw approvals set --node <id|name|ip>`
对于节点主机,请在该节点上应用相同的批准文件:
对于节点主机,应在该节点上应用相同的审批文件:
```bash
openclaw approvals set --node <id|name|ip> --stdin <<'EOF'
@ -175,45 +176,45 @@ openclaw approvals set --node <id|name|ip> --stdin <<'EOF'
EOF
```
重要的仅本地限制:
重要的仅本地限制:
- `openclaw exec-policy` 不会同步节点批
- `openclaw exec-policy` 不会同步节点
- `openclaw exec-policy set --host node` 会被拒绝
- 节点执行批会在运行时从节点获取,因此面向节点的更新必须使用 `openclaw approvals --node ...`
- 节点执行批会在运行时从节点获取,因此面向节点的更新必须使用 `openclaw approvals --node ...`
仅会话快捷方式:
仅会话快捷方式:
- `/exec security=full ask=off` 只会改当前会话。
- `/elevated full` 是一个紧急破玻璃快捷方式,它也会跳过该会话的执行批准
- `/exec security=full ask=off` 只会改当前会话。
- `/elevated full` 是一个紧急放行快捷方式,也会跳过该会话的执行审批
如果主机批准文件仍比配置更严格,则更严格的主机策略仍然优先生效
如果主机审批文件仍比配置更严格,仍然会以更严格的主机策略为准
## 策略旋钮
## 策略控制项
### 安全性(`exec.security`
- **deny**:阻止所有主机执行请求。
- **allowlist**允许允许列表中的命令。
- **full**:允许所有内容(等同于 elevated
- **allowlist**允许允许列表中的命令。
- **full**:允许一切(等同于 elevated
### 询问(`exec.ask`
- **off**:从不提示。
- **on-miss**:仅当允许列表不匹配时提示。
- **always**对每个命令都提示。
- 当生效的询问模式 `always` 时,`allow-always` 的持久信任不会抑制提示
- **always**每条命令都提示。
- 当生效的询问模式 `always` 时,`allow-always` 的持久信任不会抑制提示
### 询问后备(`askFallback`
如果需要提示但没有可达的 UI后备策略决定结果
如果需要提示但没有可达的 UI则由后备策略决定:
- **deny**:阻止。
- **allowlist**:仅当允许列表匹配时允许。
- **allowlist**:仅当允许列表匹配时允许。
- **full**:允许。
### 内联解释器 eval 加固(`tools.exec.strictInlineEval`
`tools.exec.strictInlineEval=true` 时,OpenClaw 会将内联代码 eval 形式视为“仅可通过批准执行”,即使解释器二进制本身已在允许列表中
`tools.exec.strictInlineEval=true` 时,即使解释器二进制本身已在允许列表中OpenClaw 仍会将内联代码 eval 形式视为只能通过审批执行
示例:
@ -225,14 +226,17 @@ EOF
- `lua -e`
- `osascript -e`
这是对那些无法干净映射到单一稳定文件操作数的解释器加载器所做的纵深防御。在严格模式下:
这是对无法干净映射到单一稳定文件操作数的解释器加载路径的纵深防御。在严格模式下:
- 这些命令仍然需要显式批
- 这些命令仍然需要显式批;
- `allow-always` 不会自动为它们持久化新的允许列表条目。
## 允许列表(按智能体)
## 允许列表(按智能体划分
允许列表是**按智能体**划分的。如果存在多个智能体,请在 macOS 应用中切换你要编辑的智能体。模式是**不区分大小写的 glob 匹配**。模式应解析为**二进制路径**(仅文件名的条目会被忽略)。旧版 `agents.default` 条目会在加载时迁移到 `agents.main`。类似 `echo ok && pwd` 的 shell 链仍要求每个顶层片段都满足允许列表规则。
允许列表是**按智能体**划分的。如果存在多个智能体,请在 macOS 应用中切换你正在编辑的智能体。模式是**不区分大小写的 glob 匹配**。
模式应解析为**二进制路径**(仅文件名的条目会被忽略)。
旧版 `agents.default` 条目会在加载时迁移到 `agents.main`
`echo ok && pwd` 这样的 shell 链仍然要求每个顶层片段都满足允许列表规则。
示例:
@ -242,30 +246,31 @@ EOF
每个允许列表条目会跟踪:
- **id**:用于 UI 标识的稳定 UUID(可选)
- **last used**上次使用时间戳
- **last used command**上次使用的命令
- **last resolved path**上次解析到的路径
- **id**稳定 UUID用于 UI 标识(可选)
- **last used**最后使用时间戳
- **last used command**最后使用的命令
- **last resolved path**最后解析出的路径
## 自动允许 Skills CLI
## 自动允许 Skill CLI
启用 **Auto-allow skill CLIs** 后,已知 Skills 引用的可执行文件会在节点macOS 节点或无头节点主机)被视为已加入允许列表。这会通过 Gateway RPC 使用 `skills.bins` 获取 skill 的二进制列表。如果你希望严格手动管理允许列表,请禁用此项
启用 **Auto-allow skill CLIs** 后,已知 Skills 引用的可执行文件会在节点macOS 节点或无头节点主机)被视为已加入允许列表。这会通过 Gateway 网关 RPC 使用 `skills.bins` 获取 skill 的 bin 列表。如果你想要严格的手动允许列表,请禁用它
重要信任说明:
- 这是一个**隐式的便捷允许列表**,与手动路径允许列表条目分
- 它适用于 Gateway 网关与节点处于同一信任边界的受信任操作员环境。
- 如果你要求严格的显式信任,请保持 `autoAllowSkills: false`,并使用手动路径允许列表条目。
- 这是一个**隐式的便捷允许列表**,与手动路径允许列表条目分
- 它适用于 Gateway 网关与节点处于同一信任边界的受信任操作员环境。
- 如果你要求严格的显式信任,请保持 `autoAllowSkills: false`,并且只使用手动路径允许列表条目。
## Safe bins(仅 stdin
## 安全 bin(仅 stdin
`tools.exec.safeBins` 定义了一小组**仅 stdin** 的二进制文件(例如 `cut`),它们可以在 allowlist 模式下**无需**显式允许列表条目运行。Safe bins 会拒绝位置文件参数和类似路径的 token因此它们只能处理传入流。请将其视为面向流过滤器的狭义快速路径,而不是通用信任列表。
`tools.exec.safeBins` 定义了一小组**仅 stdin** 的二进制文件(例如 `cut`),它们在 allowlist 模式下**无需**显式允许列表条目即可运行。安全 bin 会拒绝位置文件参数和类似路径的标记,因此它们只能处理传入的流。应将此视为流过滤器的狭窄快速路径,而不是通用信任列表。
<Warning>
**不要**将解释器或运行时二进制文件(例如 `python3`、`node`、`ruby`、`bash`、`sh`、`zsh`)添加到 `safeBins`。如果某个命令按设计能够执行代码求值、执行子命令或读取文件,请优先使用显式允许列表条目,并保持批准提示启用。自定义 safe bins 必须在 `tools.exec.safeBinProfiles.<bin>` 中定义显式配置。
**不要**将解释器或运行时二进制文件(例如 `python3`、`node`、
`ruby`、`bash`、`sh`、`zsh`)添加到 `safeBins`。如果某个命令天生就能执行代码、运行子命令或读取文件,请优先使用显式允许列表条目,并保持审批提示开启。自定义安全 bin 必须在 `tools.exec.safeBinProfiles.<bin>` 中定义显式配置。
</Warning>
默认 safe bins
默认安全 bin
[//]: # "SAFE_BIN_DEFAULTS:START"
@ -273,159 +278,122 @@ EOF
[//]: # "SAFE_BIN_DEFAULTS:END"
`grep``sort` 不在默认列表中。如果你选择启用它们,请为其非 stdin 工作流保留显式允许列表条目。对于 safe-bin 模式`grep`,请使用 `-e`/`--regexp` 提供模式;位置模式形式会被拒绝,以防文件操作数被伪装成有歧义的位置参数。
`grep``sort` 不在默认列表中。如果你选择启用它们,请继续为其非 stdin 工作流保留显式允许列表条目。对于处于安全 bin 模式的 `grep`,请使用 `-e`/`--regexp` 提供模式;位置模式形式会被拒绝,以避免将文件操作数伪装成含糊的位置参数。
<AccordionGroup>
<Accordion title="Argv 验证和被拒绝的标志">
验证仅根据 argv 形状做确定性判断(不检查主机文件系统中的文件是否存在),这样可以防止允许 / 拒绝差异泄露文件存在性的预言机行为。默认 safe bins 会拒绝面向文件的选项;长选项采用失败即关闭的验证方式(未知标志和有歧义的缩写都会被拒绝)。
### Argv 验证与被拒绝的标志
各 safe-bin 配置所拒绝的标志:
验证仅根据 argv 形状进行确定性判断(不会检查主机文件系统中路径是否存在),这可以防止因允许 / 拒绝差异而产生文件存在性预言机行为。面向文件的选项会被默认安全 bin 拒绝;长选项采用失败即关闭的验证方式(未知标志和含糊缩写都会被拒绝)。
[//]: # "SAFE_BIN_DENIED_FLAGS:START"
按安全 bin 配置划分的被拒绝标志:
[//]: # "SAFE_BIN_DENIED_FLAGS:START"
- `grep`: `--dereference-recursive`, `--directories`, `--exclude-from`, `--file`, `--recursive`, `-R`, `-d`, `-f`, `-r`
- `jq`: `--argfile`, `--from-file`, `--library-path`, `--rawfile`, `--slurpfile`, `-L`, `-f`
- `sort`: `--compress-program`, `--files0-from`, `--output`, `--random-source`, `--temporary-directory`, `-T`, `-o`
- `wc`: `--files0-from`
[//]: # "SAFE_BIN_DENIED_FLAGS:END"
[//]: # "SAFE_BIN_DENIED_FLAGS:END"
Safe bins 还会强制在执行时将 argv token 视为**字面文本**(不进行 glob 展开,也不进行 `$VARS` 扩展),适用于仅 stdin 的片段,因此像 `*``$HOME/...` 这样的模式不能被用来伪装文件读取。
安全 bin 还会在执行时强制将 argv 标记视为**字面文本**(不会进行 glob 展开,也不会进行 `$VARS` 扩展),适用于仅 stdin 的片段,因此像 `*``$HOME/...` 这样的模式不能被用来伪装文件读取。
</Accordion>
### 受信任的二进制目录
<Accordion title="受信任的二进制目录">
Safe bins 必须从受信任的二进制目录中解析(系统默认值
加上可选的 `tools.exec.safeBinTrustedDirs`)。`PATH` 条目绝不会被自动信任。默认受信任目录有意保持最小化:
`/bin`、`/usr/bin`。如果你的 safe-bin 可执行文件位于
包管理器 / 用户路径中(例如 `/opt/homebrew/bin`
`/usr/local/bin`、`/opt/local/bin`、`/snap/bin`),请将它们显式添加到
`tools.exec.safeBinTrustedDirs`
</Accordion>
安全 bin 必须从受信任的二进制目录解析而来(系统默认目录加上可选的 `tools.exec.safeBinTrustedDirs`)。`PATH` 条目永远不会被自动信任。默认的受信任目录有意保持最小:`/bin`、`/usr/bin`。如果你的安全 bin 可执行文件位于包管理器 / 用户路径中(例如
`/opt/homebrew/bin`、`/usr/local/bin`、`/opt/local/bin`、`/snap/bin`),请将它们显式添加到 `tools.exec.safeBinTrustedDirs`
<Accordion title="Shell 链、包装器和多路复用器">
允许使用 Shell 链(`&&`、`||`、`;`),前提是每个顶层片段
都满足允许列表要求(包括 safe bins 或 skill 自动允许)。
在 allowlist 模式下,重定向仍然不受支持。命令替换
`$()` / 反引号)会在 allowlist 解析期间被拒绝,包括位于
双引号中的情况;如果你需要字面量 `$()` 文本,请使用单引号。
### Shell 链接、包装器与多路复用器
在 macOS 配套应用批准中,包含 shell 控制符
或扩展语法(`&&`、`||`、`;`、`|`、`` ` ``、`$`、`<`、`>`、`(`、
`)`)的原始 shell 文本会被视为 allowlist 未命中,除非 shell 二进制文件本身已在允许列表中。
当每个顶层片段都满足允许列表要求时shell 链接(`&&`、`||`、`;`)是允许的(包括安全 bin 或 skill 自动允许)。在 allowlist 模式下,重定向仍然不受支持。命令替换(`$()` / 反引号)会在 allowlist 解析期间被拒绝,包括双引号内部;如果你需要字面的 `$()` 文本,请使用单引号。
对于 shell 包装器(`bash|sh|zsh ... -c/-lc`),请求作用域的 env
覆盖会被缩减为一个显式的小型允许列表(`TERM`、`LANG`、
`LC_*`、`COLORTERM`、`NO_COLOR`、`FORCE_COLOR`)。
在 macOS 配套应用审批中,包含 shell 控制或展开语法(`&&`、`||`、`;`、`|`、`` ` ``、`$`、`<`、`>`、`(`、`)`)的原始 shell 文本会被视为允许列表未命中,除非 shell 二进制本身已在允许列表中。
对于 allowlist 模式下的 `allow-always` 决策,已知分发包装器
`env`、`nice`、`nohup`、`stdbuf`、`timeout`)会持久化内部可执行文件
路径而不是包装器路径。Shell 多路复用器(`busybox`、`toybox`
对 shell applet`sh`、`ash` 等)也会以同样方式解包。如果某个
包装器或多路复用器无法被安全解包,则不会自动持久化任何允许列表条目。
对于 shell 包装器(`bash|sh|zsh ... -c/-lc`),请求作用域的 env 覆盖会被缩减为一个小型显式允许列表(`TERM`、`LANG`、`LC_*`、`COLORTERM`、`NO_COLOR`、`FORCE_COLOR`)。
如果你将 `python3``node` 之类的解释器加入允许列表,建议启用
`tools.exec.strictInlineEval=true`,这样内联 eval 仍然需要
显式批准。在严格模式下,`allow-always` 仍可持久化无害的
解释器 / 脚本调用,但内联 eval 载体不会被自动持久化。
对于 allowlist 模式下的 `allow-always` 决策,已知的分发包装器(`env`、
`nice`、`nohup`、`stdbuf`、`timeout`会持久化内部可执行文件路径而不是包装器路径。shell 多路复用器(`busybox`、`toybox`)也会对 shell applet`sh`、`ash` 等)以同样方式解包。如果某个包装器或多路复用器无法被安全解包,则不会自动持久化任何允许列表条目。
</Accordion>
</AccordionGroup>
如果你将 `python3``node` 这样的解释器加入允许列表,建议启用
`tools.exec.strictInlineEval=true`,这样内联 eval 仍然需要显式审批。在严格模式下,`allow-always` 仍然可以持久化无害的解释器 / 脚本调用,但内联 eval 载体不会被自动持久化。
### Safe bins 与 allowlist 的对比
### 安全 bin 与允许列表
| Topic | `tools.exec.safeBins` | Allowlist (`exec-approvals.json`) |
| ---------------- | ------------------------------------------------------ | --------------------------------------------------------- |
| 目标 | 自动允许受限的 stdin 过滤器 | 显式信任特定可执行文件 |
| 匹配类型 | 可执行文件名 + safe-bin argv 策略 | 已解析可执行文件路径 glob 模式 |
| 参数范围 | 受 safe-bin 配置和字面量 token 规则限制 | 仅匹配路径;除此之外参数由你自行负责 |
| 典型示例 | `head`、`tail`、`tr`、`wc` | `jq`、`python3`、`node`、`ffmpeg`、自定义 CLI |
| 最佳用途 | 管道中的低风险文本转换 | 任何具有更广泛行为或副作用的工具 |
| 主题 | `tools.exec.safeBins` | 允许列表(`exec-approvals.json` |
| --- | --- | --- |
| 目标 | 自动允许狭窄的 stdin 过滤器 | 显式信任特定可执行文件 |
| 匹配类型 | 可执行文件名 + 安全 bin argv 策略 | 已解析的可执行文件路径 glob 模式 |
| 参数范围 | 受安全 bin 配置和字面标记规则限制 | 仅匹配路径;其他参数由你自行负责 |
| 典型示例 | `head`、`tail`、`tr`、`wc` | `jq`、`python3`、`node`、`ffmpeg`、自定义 CLI |
| 最佳用途 | 管道中的低风险文本转换 | 任何行为更广副作用的工具 |
配置位置:
- `safeBins` 来自配置(`tools.exec.safeBins` 或按智能体划分的 `agents.list[].tools.exec.safeBins`)。
- `safeBinTrustedDirs` 来自配置(`tools.exec.safeBinTrustedDirs` 或按智能体划分的 `agents.list[].tools.exec.safeBinTrustedDirs`)。
- `safeBinProfiles` 来自配置(`tools.exec.safeBinProfiles` 或按智能体划分的 `agents.list[].tools.exec.safeBinProfiles`)。按智能体划分的配置键会覆盖全局配置键。
- allowlist 条目位于主机本地的 `~/.openclaw/exec-approvals.json` 中的 `agents.<id>.allowlist` 下(或通过 Control UI / `openclaw approvals allowlist ...`)。
- 当解释器 / 运行时二进制文件出现在 `safeBins` 中但没有显式配置时,`openclaw security audit` 会以 `tools.exec.safe_bins_interpreter_unprofiled` 发出警告。
- `openclaw doctor --fix` 可以为缺失的自定义 `safeBinProfiles.<bin>` 条目生成 `{}` 骨架(之后请审查并收紧)。解释器 / 运行时二进制文件不会被自动生成骨架
- 允许列表条目存储在主机本地的 `~/.openclaw/exec-approvals.json` 中的 `agents.<id>.allowlist` 下(或通过 Control UI / `openclaw approvals allowlist ...`)。
- 当解释器 / 运行时 bin 出现在 `safeBins` 中但没有显式配置时,`openclaw security audit` 会发出 `tools.exec.safe_bins_interpreter_unprofiled` 警告。
- `openclaw doctor --fix` 可以将缺失的自定义 `safeBinProfiles.<bin>` 条目脚手架生成为 `{}`(之后请审核并收紧)。解释器 / 运行时 bin 不会被自动脚手架生成
自定义配置示例:
__OC_I18N_900005__
如果你显式选择将 `jq` 加入 `safeBins`OpenClaw 在 safe-bin
模式下仍会拒绝 `env` 内建,因此 `jq -n env` 不能在没有显式 allowlist 路径
或批准提示的情况下导出主机进程环境。
如果你显式将 `jq` 加入 `safeBins`OpenClaw 在安全 bin 模式下仍会拒绝 `env` 内建,因此 `jq -n env` 不能在没有显式允许列表路径或审批提示的情况下转储主机进程环境。
## 编辑 Control UI
## 在 Control UI 中编辑
使用 **Control UI → Nodes → Exec approvals** 卡片来编辑默认值、按智能体划分的
覆盖项以及允许列表。选择一个作用域(默认值或某个智能体),调整策略,
添加 / 删除允许列表模式,然后点击 **保存**。UI 会显示每个模式的 **上次使用**
元数据,方便你保持列表整洁。
使用 **Control UI → Nodes → Exec approvals** 卡片来编辑默认值、按智能体划分的覆盖项和允许列表。选择一个作用域Defaults 或某个智能体),调整策略,添加 / 删除允许列表模式,然后点击 **Save**。UI 会按每个模式显示 **last used** 元数据,方便你保持列表整洁。
目标选择器可选择 **Gateway**(本地批准)或某个 **Node**。节点
必须声明 `system.execApprovals.get/set`macOS 应用或无头节点主机)。
如果某个节点尚未声明 exec approvals请直接编辑其本地
目标选择器用于选择 **Gateway**(本地审批)或 **Node**。节点必须声明 `system.execApprovals.get/set`macOS 应用或无头节点主机)。如果某个节点尚未声明执行审批,请直接编辑它本地的
`~/.openclaw/exec-approvals.json`
CLI`openclaw approvals` 支持编辑 gateway 或 node(参见 [Approvals CLI](/cli/approvals))。
CLI`openclaw approvals` 支持编辑 Gateway 网关或节点(参见 [Approvals CLI](/cli/approvals))。
## 批流程
## 批流程
当需要提示时gateway 会向操作员客户端广播 `exec.approval.requested`
Control UI 和 macOS 应用通过 `exec.approval.resolve` 对其进行处理,然后 gateway 将
已批准的请求转发到节点主机。
当需要提示时Gateway 网关会向操作员客户端广播 `exec.approval.requested`。Control UI 和 macOS 应用通过 `exec.approval.resolve` 处理它,然后 Gateway 网关会将已批准的请求转发给节点主机。
对于 `host=node`批准请求会包含一个规范的 `systemRunPlan` 负载。gateway 会在转发已批准的 `system.run`
请求时,将该计划作权威的命令 / cwd / 会话上下文。
对于 `host=node`,审批请求会包含一个规范化的 `systemRunPlan` 负载。Gateway 网关在转发已批准的 `system.run`
请求时,将该计划作权威的命令 / cwd / 会话上下文。
这对异步批延迟很重要:
这对异步批延迟很重要:
- 节点执行路径会预先准备一个规范计划
- 批准记录会存储该计划及其绑定元数据
- 一旦批准,最终转发的 `system.run` 调用会复用已存储的计划
而不是信任调用方之后的编辑
- 如果调用方在创建批准请求后更改了 `command`、`rawCommand`、`cwd`、`agentId` 或
`sessionKey`gateway 会因批准不匹配而拒绝
转发的运行请求
- 节点执行路径会预先准备一个规范化计划
- 审批记录会存储该计划及其绑定元数据
- 一旦审批通过,最终转发的 `system.run` 调用会复用已存储的计划
,而不是信任调用方后续的修改
- 如果调用方在审批请求创建后更改了 `command`、`rawCommand`、`cwd`、`agentId` 或
`sessionKey`Gateway 网关会将转发的执行拒绝为审批不匹配
## 解释器 / 运行时命令
基于批准的解释器 / 运行时执行是有意保守设计的
带审批支持的解释器 / 运行时执行会有意保持保守
- 始终绑定精确的 argv/cwd/env 上下文。
- 直接 shell 脚本和直接运行时文件形式会尽力绑定到一个具体的本地
文件快照。
- 仍然可解析到单个直接本地文件的常见包管理器包装形式(例如
`pnpm exec`、`pnpm node`、`npm exec`、`npx`)会在绑定前
先被解包。
- 如果 OpenClaw 无法为解释器 / 运行时命令识别出**恰好一个**具体本地文件
例如包脚本、eval 形式、运行时特定加载链,或存在歧义的多文件
形式),则会拒绝基于批准的执行,而不是声称它具备并不存在的语义覆盖能力。
- 对于这些工作流,建议优先使用沙箱隔离、单独的主机边界,或显式的受信任
allowlist/full 工作流,由操作员接受更宽泛的运行时语义。
- 直接 shell 脚本和直接运行时文件形式会尽力绑定到一个具体本地文件快照。
- 仍然能解析到单个直接本地文件的常见包管理器包装形式(例如
`pnpm exec`、`pnpm node`、`npm exec`、`npx`)会在绑定前解包。
- 如果 OpenClaw 无法为某个解释器 / 运行时命令识别出恰好一个具体本地文件
例如包脚本、eval 形式、运行时特定加载链或含糊的多文件形式),则会拒绝带审批支持的执行,而不是声称覆盖了它实际上并未覆盖的语义。
- 对于这些工作流,建议优先使用沙箱隔离、单独的主机边界,或显式的受信任允许列表 / full 工作流,由操作员接受更广泛的运行时语义。
当需要批准时,执行工具会立即返回一个批准 id。使用该 id 来
关联后续的系统事件(`Exec finished` / `Exec denied`)。如果在
超时前没有收到决定,该请求会被视为批准超时,并作为拒绝原因显示。
当需要审批时exec 工具会立即返回一个审批 id。请使用该 id 来关联后续系统事件(`Exec finished` / `Exec denied`)。如果在超时前没有收到决策,则该请求会被视为审批超时,并以拒绝原因的形式呈现。
### 后续投递行为
已批准的异步 exec 完成后OpenClaw 会向同一会话发送一个后续 `agent` 轮次。
已批准的异步 exec 完成后OpenClaw 会向同一会话发送一个后续 `agent` 轮次。
- 如果存在有效的外部投递目标(可投递的渠道加目标 `to`),后续投递会使用该渠道。
- 在仅 webchat 或无外部目标的内部会话流中,后续投递会保持仅会话内`deliver: false`)。
- 如果存在有效的外部投递目标(可投递的渠道加目标 `to`),后续投递会使用该渠道。
- 在仅 webchat 或仅内部会话、没有外部目标的流程中,后续投递会保持为仅会话`deliver: false`)。
- 如果调用方显式请求严格的外部投递,但没有可解析的外部渠道,请求会以 `INVALID_REQUEST` 失败。
- 如果启用了 `bestEffortDeliver` 且无法解析出外部渠道,投递会降级为仅会话内,而不是失败。
- 如果启用了 `bestEffortDeliver` 且无法解析任何外部渠道,投递会降级为仅会话,而不是失败。
确认对话框包
确认对话框包
- command + args
- cwd
- 智能体 id
- 已解析可执行文件路径
- 主机 + 策略元数据
- agent id
- 已解析可执行文件路径
- host + 策略元数据
操作:
@ -433,97 +401,85 @@ Control UI 和 macOS 应用通过 `exec.approval.resolve` 对其进行处理,
- **Always allow** → 添加到允许列表 + 运行
- **Deny** → 阻止
## 将批转发到聊天渠道
## 将批转发到聊天渠道
你可以将 exec 批准提示转发到任意聊天渠道(包括渠道插件),并通过
`/approve` 进行批准。这使用常规的出站投递管道。
你可以将执行审批提示转发到任意聊天渠道(包括渠道插件),并使用 `/approve` 进行审批。这使用的是正常的出站投递管道。
配置:
__OC_I18N_900006__
在聊天中回复:
__OC_I18N_900007__
`/approve` 命令同时处理 exec approvals 和 plugin approvals。如果该 ID 与待处理的 exec approval 不匹配,它会自动转而检查 plugin approvals
`/approve` 命令同时处理执行审批和插件审批。如果该 ID 与待处理的执行审批不匹配,它会自动改为检查插件审批
### plugin 批准转发
### 插件审批转发
plugin 批准转发与 exec approvals 使用相同的投递管道,但在 `approvals.plugin` 下拥有自己独立的配置。启用或禁用其中一个不会影响另一个。
插件审批转发与执行审批使用相同的投递管道,但它在 `approvals.plugin`有自己独立的配置。启用或禁用其中一个不会影响另一个。
__OC_I18N_900008__
配置结构与 `approvals.exec` 相同:`enabled`、`mode`、`agentFilter`、
`sessionFilter``targets` 的工作方式完全一致
配置结构与 `approvals.exec` 完全相同:`enabled`、`mode`、`agentFilter`、
`sessionFilter``targets` 的工作方式都一样
支持共享交互式回复的渠道会为 exec 和 plugin approvals 都渲染相同的批准按钮。没有共享交互式 UI 的渠道则会回退为带有 `/approve`
说明的纯文本
支持共享交互式回复的渠道会为执行审批和插件审批渲染相同的审批按钮。不支持共享交互式 UI 的渠道则会回退为纯文本,并附带 `/approve`
说明。
### 任意渠道中的同聊天批
### 任意渠道中的同聊天
当 exec 或 plugin 批准请求源自可投递的聊天界面时,现在默认可以在同一个聊天中使用 `/approve` 进行批准。这适用于 Slack、Matrix 和
Microsoft Teams 等渠道,以及现有的 Web UI 和终端 UI 流程。
当某个执行或插件审批请求来自可投递的聊天界面时,现在默认可以直接在同一个聊天中使用 `/approve` 进行审批。这适用于 Slack、Matrix 和 Microsoft Teams 等渠道,以及现有的 Web UI 与终端 UI 流程。
这条共享文本命令路径使用该对话的常规渠道认证模型。如果发起聊天
本身已经可以发送命令并接收回复,那么批准请求就不再需要
单独的原生投递适配器才能保持待处理状态。
这条共享的文本命令路径使用该会话的正常渠道认证模型。如果发起聊天本来就能发送命令并接收回复,那么审批请求就不再需要单独的原生投递适配器来维持挂起状态。
Discord 和 Telegram 也支持同聊天 `/approve`,但即使禁用了原生批准投递,这些渠道在授权时仍会使用其已解析的批准人列表
Discord 和 Telegram 也支持同聊天 `/approve`,但即使原生审批投递被禁用,这些渠道仍会使用其已解析的 approver 列表进行授权。
对于 Telegram 以及其他直接调用 Gateway 网关的原生批准客户端,
这个后备路径有意限制在“找不到批准”类故障中。真实的
exec approval 拒绝 / 错误不会被静默重试为 plugin approval。
对于 Telegram 和其他直接调用 Gateway 网关的原生审批客户端,这种后备机制有意仅限于 “approval not found” 故障。真正的执行审批拒绝 / 错误不会被静默重试为插件审批。
### 原生批投递
### 原生审批投递
某些渠道还可以作为原生批准客户端。原生客户端会在共享的同聊天 `/approve`
流程之上增加批准人私信、原始聊天扇出,以及渠道特定的交互式批准 UX。
某些渠道还可以充当原生审批客户端。原生客户端会在共享的同聊天 `/approve`
流程之上,增加 approver 私信、来源聊天扇出以及渠道特定的交互式审批 UX。
当可用原生批准卡片 / 按钮时,该原生 UI 是面向
智能体的主要路径。除非工具结果表明聊天批准不可用,或手动批准是唯一剩余路径,否则智能体不应再额外回显重复的纯聊天
`/approve` 命令。
当原生审批卡片 / 按钮可用时,这种原生 UI 是面向智能体的主要路径。除非工具结果表明聊天审批不可用,或手动审批是唯一剩余路径,否则智能体不应再额外回显重复的纯聊天 `/approve` 命令。
通用模型:
- 主机执行策略仍然决定是否需要 exec approval
- `approvals.exec` 控制是否将批提示转发到其他聊天目标
- `channels.<channel>.execApprovals` 控制该渠道是否作为原生批准客户端
- 是否需要执行审批仍由主机执行策略决定
- `approvals.exec` 控制是否将批提示转发到其他聊天目标
- `channels.<channel>.execApprovals` 控制该渠道是否充当原生审批客户端
当以下条件全部满足时,原生批准客户端会自动启用 DM 优先投递:
原生审批客户端会在以下条件全部满足时自动启用私信优先投递:
- 该渠道支持原生批投递
- 可以从显式的 `execApprovals.approvers` 或该
渠道文档说明的后备来源中解析出批准人
- 该渠道支持原生批投递
- approver 可以通过显式 `execApprovals.approvers` 或该
渠道文档中记录的后备来源解析出来
- `channels.<channel>.execApprovals.enabled` 未设置或为 `"auto"`
`enabled: false` 设为显式禁用某个原生批准客户端。将 `enabled: true` 设为在能够解析出批准人时强制启用它。公开的原始聊天投递仍通过
`channels.<channel>.execApprovals.target` 显式控制。
`enabled: false` 设为显式禁用某个原生审批客户端。将 `enabled: true` 设为在 approver 可解析时强制启用。公开来源聊天投递仍通过 `channels.<channel>.execApprovals.target` 显式控制。
常见问题:[为什么聊天批准有两个 exec approval 配置?](/help/faq#why-are-there-two-exec-approval-configs-for-chat-approvals)
常见问题:[为什么聊天审批会有两套执行审批配置?](/help/faq#why-are-there-two-exec-approval-configs-for-chat-approvals)
- Discord`channels.discord.execApprovals.*`
- Slack`channels.slack.execApprovals.*`
- Telegram`channels.telegram.execApprovals.*`
这些原生批客户端会在共享的同聊天 `/approve` 流程和共享批按钮之上,增加私信路由和可选的渠道扇出。
这些原生批客户端会在共享的同聊天 `/approve` 流程和共享批按钮之上,增加私信路由和可选的渠道扇出。
共享行为:
- Slack、Matrix、Microsoft Teams 以及类似的可投递聊天,针对同聊天 `/approve` 使用常规渠道认证模型
- 当原生批准客户端自动启用时,默认的原生投递目标是批准人私信
- 对于 Discord 和 Telegram只有已解析出的批准人可以批准或拒绝
- Discord 批准人可以是显式配置(`execApprovals.approvers`),也可以从 `commands.ownerAllowFrom` 推断
- Telegram 批准人可以是显式配置(`execApprovals.approvers`),也可以从现有 owner 配置推断(`allowFrom`,以及支持时的私信 `defaultTo`
- Slack 批准人可以是显式配置(`execApprovals.approvers`),也可以从 `commands.ownerAllowFrom` 推断
- Slack 原生按钮会保留批准 id 类型,因此 `plugin:` id 可以解析到 plugin approvals
而无需第二层 Slack 本地后备逻辑
- Matrix 原生私信 / 渠道路由和反应快捷方式同时处理 exec 和 plugin approvals
plugin 授权仍然来自 `channels.matrix.dm.allowFrom`
- 请求者不需要是批准人
- 当原始聊天已支持命令和回复时,原始聊天可以直接通过 `/approve` 进行批准
- 原生 Discord 批准按钮会按批准 id 类型路由:`plugin:` id 会
直接进入 plugin approvals其他所有情况都会进入 exec approvals
- 原生 Telegram 批准按钮遵循与 `/approve` 相同的有界 exec 到 plugin 后备逻辑
- 当原生 `target` 启用原始聊天投递时,批准提示会包含命令文本
- 待处理的 exec approvals 默认会在 30 分钟后过期
- 如果没有操作员 UI 或已配置的批准客户端可以接受该请求,提示会回退到 `askFallback`
- Slack、Matrix、Microsoft Teams 以及类似的可投递聊天,都会对同聊天 `/approve` 使用正常的渠道认证模型
- 当原生审批客户端自动启用时,默认的原生投递目标是 approver 私信
- 对于 Discord 和 Telegram只有已解析的 approver 才能批准或拒绝
- Discord approver 可以显式指定(`execApprovals.approvers`),也可以从 `commands.ownerAllowFrom` 推断
- Telegram approver 可以显式指定(`execApprovals.approvers`),也可以从现有 owner 配置推断(`allowFrom`,以及在支持时用于私信的 `defaultTo`
- Slack approver 可以显式指定(`execApprovals.approvers`),也可以从 `commands.ownerAllowFrom` 推断
- Slack 原生按钮会保留审批 id 类型,因此 `plugin:` id 可以解析到插件审批,而无需第二层 Slack 本地后备逻辑
- Matrix 原生私信 / 渠道路由和反应快捷方式同时处理执行审批与插件审批;插件授权仍然来自 `channels.matrix.dm.allowFrom`
- 请求方不需要是 approver
- 当来源聊天本身已支持命令和回复时,来源聊天可以直接通过 `/approve` 进行审批
- 原生 Discord 审批按钮会按审批 id 类型路由:`plugin:` id 直接进入插件审批,其余全部进入执行审批
- 原生 Telegram 审批按钮遵循与 `/approve` 相同的、受限的从执行到插件的后备逻辑
- 当原生 `target` 启用来源聊天投递时,审批提示会包含命令文本
- 待处理的执行审批默认在 30 分钟后过期
- 如果没有任何操作员 UI 或已配置的审批客户端能够接受该请求,则提示会回退到 `askFallback`
Telegram 默认使用批准人私信(`target: "dm"`)。如果你希望批准提示也出现在发起的 Telegram 聊天 / 话题中,可以切换为 `channel``both`。对于 Telegram forum 话题OpenClaw 会在批准提示和批准后的后续消息中保留该话题。
Telegram 默认为 approver 私信(`target: "dm"`)。如果你希望审批提示也出现在来源 Telegram 聊天 / 话题中,可以切换为 `channel``both`。对于 Telegram 论坛话题OpenClaw 会在审批提示和审批后的后续消息中保留该话题。
参见:
@ -536,55 +492,51 @@ __OC_I18N_900009__
- Unix socket 模式为 `0600`token 存储在 `exec-approvals.json` 中。
- 同 UID 对等方检查。
- 质询 / 响应nonce + HMAC token + 请求哈希+ 短 TTL。
- 质询 / 响应nonce + HMAC token + request hash+ 短 TTL。
## 系统事件
Exec 生命周期会作为系统消息呈现:
执行生命周期会以系统消息的形式呈现:
- `Exec running`(仅当命令超过运行提示阈值时)
- `Exec running`(仅当命令超过运行提示阈值时)
- `Exec finished`
- `Exec denied`
这些消息会在节点报事件后发布到智能体的会话中。
Gateway host exec approvals 在命令完成时也会发出相同的生命周期事件(如果运行时间超过阈值,也可在运行中发出)。
批准门控的 exec 会复用批准 id 作为这些消息中的 `runId`,便于关联。
这些消息会在节点报事件后发布到智能体的会话中。
Gateway 网关主机执行审批在命令完成时也会发出相同的生命周期事件(如果运行时间超过阈值,也可选择在运行中发出)。
审批门控的执行会在这些消息中复用审批 id 作为 `runId`,便于关联。
## 批被拒绝时的行为
## 批被拒绝时的行为
当异步 exec approval 被拒绝时OpenClaw 会阻止智能体复用
该会话中此前相同命令任意一次运行的输出。拒绝原因
会附带明确说明“没有可用命令输出”,从而阻止
智能体声称存在新的输出,或使用先前成功运行留下的过期结果
重复被拒绝的命令。
当异步执行审批被拒绝时OpenClaw 会阻止智能体在该会话中复用此前相同命令的任何早期运行输出。拒绝原因会连同明确说明一起传递,指出没有可用的命令输出,从而阻止智能体声称存在新的输出,或使用先前成功运行留下的陈旧结果重复被拒绝的命令。
## 影响
- **full** 权限很强;在可能的情况下优先使用允许列表。
- **ask** 让你保持知情,同时仍能快速批准
- 按智能体划分的允许列表可防止一个智能体的批准泄漏到其他智能体。
- 批准仅适用于来自**已授权发送者**的主机 exec 请求。未授权发送者不能发出 `/exec`
- `/exec security=full` 是面向已授权操作员的会话级便捷方式,并且按设计会跳过批准。若要强制阻止主机 exec请将批准安全性设为 `deny`,或通过工具策略拒绝 `exec` 工具。
- **ask** 能让你保持在决策回路中,同时仍支持快速审批
- 按智能体划分的允许列表可防止某个智能体的审批泄漏到其他智能体。
- 审批仅适用于来自**已授权发送方**的主机执行请求。未授权发送方不能发出 `/exec`
- `/exec security=full` 是面向已授权操作员的会话级便捷方式,并且按设计会跳过审批。要硬性阻止主机执行,请将审批安全性设为 `deny`,或通过工具策略拒绝 `exec` 工具。
## 相关内容
<CardGroup cols={2}>
<Card title="Exec 工具" href="/zh-CN/tools/exec" icon="terminal">
<Card title="Exec tool" href="/zh-CN/tools/exec" icon="terminal">
Shell 命令执行工具。
</Card>
<Card title="Elevated 模式" href="/zh-CN/tools/elevated" icon="shield-exclamation">
同样会跳过批准的紧急破玻璃路径。
<Card title="Elevated mode" href="/zh-CN/tools/elevated" icon="shield-exclamation">
同样会跳过审批的紧急放行路径。
</Card>
<Card title="沙箱隔离" href="/zh-CN/gateway/sandboxing" icon="box">
沙箱模式工作区访问。
<Card title="Sandboxing" href="/zh-CN/gateway/sandboxing" icon="box">
沙箱模式工作区访问。
</Card>
<Card title="安全" href="/zh-CN/gateway/security" icon="lock">
<Card title="Security" href="/zh-CN/gateway/security" icon="lock">
安全模型与加固。
</Card>
<Card title="沙箱隔离 vs 工具策略 vs elevated" href="/zh-CN/gateway/sandbox-vs-tool-policy-vs-elevated" icon="sliders">
<Card title="Sandbox vs tool policy vs elevated" href="/zh-CN/gateway/sandbox-vs-tool-policy-vs-elevated" icon="sliders">
何时应使用各类控制。
</Card>
<Card title="Skills" href="/zh-CN/tools/skills" icon="sparkles">
基于 Skill 的自动允许行为。
由 Skills 支持的自动允许行为。
</Card>
</CardGroup>