chore(i18n): refresh zh-CN translations
This commit is contained in:
parent
d1c4b4dfa4
commit
36593672df
@ -1,25 +1,25 @@
|
||||
---
|
||||
read_when:
|
||||
- 开发 Telegram 功能或 webhook
|
||||
summary: Telegram 机器人支持状态、功能与配置
|
||||
- 处理 Telegram 功能或 Webhook 时
|
||||
summary: Telegram 机器人支持状态、功能和配置
|
||||
title: Telegram
|
||||
x-i18n:
|
||||
generated_at: "2026-04-24T03:37:50Z"
|
||||
generated_at: "2026-04-25T02:35:30Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: fdd6ea0277e074f90306f91d51fd329c6914de85dde0ae09a731713f1bba98d9
|
||||
source_hash: 1554ce51636dece5b44a17a03d3703c621a5f419d27c8f4e5a14fde304bec712
|
||||
source_path: channels/telegram.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
可通过 grammY 用于机器人私信和群组,已达到生产可用级别。长轮询是默认模式;webhook 模式为可选。
|
||||
通过 grammY 为机器人私信和群组提供生产就绪支持。长轮询是默认模式;Webhook 模式为可选。
|
||||
|
||||
<CardGroup cols={3}>
|
||||
<Card title="配对" icon="link" href="/zh-CN/channels/pairing">
|
||||
Telegram 的默认私信策略是配对。
|
||||
</Card>
|
||||
<Card title="渠道故障排除" icon="wrench" href="/zh-CN/channels/troubleshooting">
|
||||
跨渠道诊断与修复操作手册。
|
||||
跨渠道诊断和修复操作手册。
|
||||
</Card>
|
||||
<Card title="Gateway 网关配置" icon="settings" href="/zh-CN/gateway/configuration">
|
||||
完整的渠道配置模式与示例。
|
||||
@ -30,7 +30,7 @@ x-i18n:
|
||||
|
||||
<Steps>
|
||||
<Step title="在 BotFather 中创建机器人令牌">
|
||||
打开 Telegram 并与 **@BotFather** 聊天(确认用户名严格为 `@BotFather`)。
|
||||
打开 Telegram 并与 **@BotFather** 对话(确认账号名严格为 `@BotFather`)。
|
||||
|
||||
运行 `/newbot`,按照提示操作,并保存令牌。
|
||||
|
||||
@ -51,8 +51,8 @@ x-i18n:
|
||||
}
|
||||
```
|
||||
|
||||
环境变量回退:`TELEGRAM_BOT_TOKEN=...`(仅适用于默认账户)。
|
||||
Telegram **不会** 使用 `openclaw channels login telegram`;请在配置 / 环境变量中设置令牌,然后启动 Gateway 网关。
|
||||
环境变量回退:`TELEGRAM_BOT_TOKEN=...`(仅默认账户)。
|
||||
Telegram **不**使用 `openclaw channels login telegram`;请在配置或环境变量中设置令牌,然后启动 Gateway 网关。
|
||||
|
||||
</Step>
|
||||
|
||||
@ -74,34 +74,34 @@ openclaw pairing approve telegram <CODE>
|
||||
</Steps>
|
||||
|
||||
<Note>
|
||||
令牌解析顺序会感知账户。在实际使用中,配置值优先于环境变量回退,而 `TELEGRAM_BOT_TOKEN` 仅适用于默认账户。
|
||||
令牌解析顺序是账户感知的。实际中,配置值优先于环境变量回退,而 `TELEGRAM_BOT_TOKEN` 仅适用于默认账户。
|
||||
</Note>
|
||||
|
||||
## Telegram 侧设置
|
||||
## Telegram 端设置
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="隐私模式与群组可见性">
|
||||
Telegram 机器人默认启用**隐私模式**,这会限制它们能接收到的群组消息。
|
||||
<Accordion title="隐私模式和群组可见性">
|
||||
Telegram 机器人默认启用 **隐私模式**,这会限制它们能接收到的群组消息。
|
||||
|
||||
如果机器人必须看到所有群组消息,可选择以下任一方式:
|
||||
如果机器人必须看到所有群组消息,可以选择以下任一方式:
|
||||
|
||||
- 通过 `/setprivacy` 关闭隐私模式,或
|
||||
- 将机器人设为群组管理员。
|
||||
|
||||
切换隐私模式后,请在每个群组中移除并重新添加机器人,以便 Telegram 应用该变更。
|
||||
切换隐私模式后,请在每个群组中移除并重新添加机器人,以便 Telegram 应用该更改。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="群组权限">
|
||||
管理员状态在 Telegram 群组设置中控制。
|
||||
|
||||
管理员机器人会接收所有群组消息,这对于始终在线的群组行为很有用。
|
||||
管理员机器人会接收所有群组消息,这对始终在线的群组行为很有用。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="BotFather 中有用的开关">
|
||||
|
||||
- `/setjoingroups`:允许 / 禁止加入群组
|
||||
- `/setjoingroups`:允许或拒绝加入群组
|
||||
- `/setprivacy`:控制群组可见性行为
|
||||
|
||||
</Accordion>
|
||||
@ -118,23 +118,23 @@ openclaw pairing approve telegram <CODE>
|
||||
- `open`(要求 `allowFrom` 包含 `"*"`)
|
||||
- `disabled`
|
||||
|
||||
`channels.telegram.allowFrom` 接受数字形式的 Telegram 用户 ID。支持 `telegram:` / `tg:` 前缀,并会被标准化。
|
||||
如果 `dmPolicy: "allowlist"` 但 `allowFrom` 为空,则会阻止所有私信,并在配置校验时被拒绝。
|
||||
设置流程只会请求数字用户 ID。
|
||||
如果你升级后发现配置中包含 `@username` 形式的 allowlist 条目,请运行 `openclaw doctor --fix` 进行解析(尽力而为;需要 Telegram 机器人令牌)。
|
||||
如果你此前依赖配对存储的 allowlist 文件,`openclaw doctor --fix` 也可以在 allowlist 流程中将这些条目恢复到 `channels.telegram.allowFrom`(例如当 `dmPolicy: "allowlist"` 尚未配置显式 ID 时)。
|
||||
`channels.telegram.allowFrom` 接受数字形式的 Telegram 用户 ID。支持并会标准化 `telegram:` / `tg:` 前缀。
|
||||
`dmPolicy: "allowlist"` 且 `allowFrom` 为空时会阻止所有私信,并被配置校验拒绝。
|
||||
设置时仅要求填写数字用户 ID。
|
||||
如果你已升级且配置中包含 `@username` 形式的允许列表条目,请运行 `openclaw doctor --fix` 来解析它们(尽力而为;需要 Telegram 机器人令牌)。
|
||||
如果你之前依赖配对存储的允许列表文件,在允许列表流程中(例如 `dmPolicy: "allowlist"` 尚无显式 ID 时),`openclaw doctor --fix` 可以将这些条目恢复到 `channels.telegram.allowFrom` 中。
|
||||
|
||||
对于单一所有者的机器人,推荐使用 `dmPolicy: "allowlist"` 并显式填写数字 `allowFrom` ID,以便将访问策略稳定保存在配置中(而不是依赖先前的配对批准)。
|
||||
对于单一所有者的机器人,建议优先使用带显式数字 `allowFrom` ID 的 `dmPolicy: "allowlist"`,以便将访问策略稳定保存在配置中(而不是依赖先前的配对批准)。
|
||||
|
||||
常见误解:私信配对获批并不意味着“此发送者在任何地方都已获授权”。
|
||||
配对只授予私信访问权限。群组发送者授权仍然来自显式配置的 allowlist。
|
||||
如果你希望实现“我只授权一次,私信和群组命令都能使用”,请将你的数字 Telegram 用户 ID 放入 `channels.telegram.allowFrom`。
|
||||
常见混淆点:私信配对批准并不表示“这个发送者在所有地方都被授权”。
|
||||
配对仅授予私信访问权限。群组发送者授权仍然来自显式配置的允许列表。
|
||||
如果你希望“我只授权一次,私信和群组命令都能工作”,请将你的数字 Telegram 用户 ID 放入 `channels.telegram.allowFrom`。
|
||||
|
||||
### 查找你的 Telegram 用户 ID
|
||||
|
||||
更安全的方法(无需第三方机器人):
|
||||
|
||||
1. 向你的机器人发送私信。
|
||||
1. 给你的机器人发送私信。
|
||||
2. 运行 `openclaw logs --follow`。
|
||||
3. 读取 `from.id`。
|
||||
|
||||
@ -148,14 +148,14 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
|
||||
</Tab>
|
||||
|
||||
<Tab title="群组策略与 allowlist">
|
||||
有两个控制项会共同生效:
|
||||
<Tab title="群组策略和允许列表">
|
||||
需要同时应用两个控制项:
|
||||
|
||||
1. **允许哪些群组**(`channels.telegram.groups`)
|
||||
- 没有 `groups` 配置:
|
||||
- 当 `groupPolicy: "open"` 时:任何群组都可以通过 group ID 检查
|
||||
- 当 `groupPolicy: "allowlist"`(默认)时:在你添加 `groups` 条目(或 `"*"`)之前,所有群组都会被阻止
|
||||
- 已配置 `groups`:其行为就是 allowlist(显式 ID 或 `"*"`)
|
||||
- 当 `groupPolicy: "open"` 时:任何群组都可以通过群组 ID 检查
|
||||
- 当 `groupPolicy: "allowlist"`(默认)时:在你添加 `groups` 条目(或 `"*"`)之前,群组都会被阻止
|
||||
- 已配置 `groups`:其行为是允许列表(显式 ID 或 `"*"`)
|
||||
|
||||
2. **群组中允许哪些发送者**(`channels.telegram.groupPolicy`)
|
||||
- `open`
|
||||
@ -164,15 +164,15 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
|
||||
`groupAllowFrom` 用于群组发送者过滤。如果未设置,Telegram 会回退到 `allowFrom`。
|
||||
`groupAllowFrom` 条目应为数字形式的 Telegram 用户 ID(`telegram:` / `tg:` 前缀会被标准化)。
|
||||
不要将 Telegram 群组或超级群组 chat ID 放入 `groupAllowFrom`。负数 chat ID 应放在 `channels.telegram.groups` 下。
|
||||
不要将 Telegram 群组或超级群组聊天 ID 放入 `groupAllowFrom`。负数聊天 ID 应放在 `channels.telegram.groups` 下。
|
||||
非数字条目会在发送者授权中被忽略。
|
||||
安全边界(`2026.2.25+`):群组发送者授权**不会**继承私信配对存储中的批准记录。
|
||||
配对仍然仅适用于私信。对于群组,请设置 `groupAllowFrom` 或每群组 / 每话题的 `allowFrom`。
|
||||
安全边界(`2026.2.25+`):群组发送者授权**不会**继承私信配对存储中的批准。
|
||||
配对仍仅适用于私信。对于群组,请设置 `groupAllowFrom` 或按群组/按话题的 `allowFrom`。
|
||||
如果 `groupAllowFrom` 未设置,Telegram 会回退到配置中的 `allowFrom`,而不是配对存储。
|
||||
对于单一所有者机器人,一个实用模式是:将你的用户 ID 设置到 `channels.telegram.allowFrom`,保持 `groupAllowFrom` 未设置,并在 `channels.telegram.groups` 下允许目标群组。
|
||||
运行时说明:如果 `channels.telegram` 完全缺失,运行时默认会采用失败即关闭的 `groupPolicy="allowlist"`,除非显式设置了 `channels.defaults.groupPolicy`。
|
||||
单一所有者机器人的实用模式:将你的用户 ID 设置到 `channels.telegram.allowFrom` 中,保持 `groupAllowFrom` 未设置,并在 `channels.telegram.groups` 下允许目标群组。
|
||||
运行时说明:如果 `channels.telegram` 完全缺失,运行时默认会失败关闭并使用 `groupPolicy="allowlist"`,除非显式设置了 `channels.defaults.groupPolicy`。
|
||||
|
||||
示例:允许某个指定群组中的任意成员:
|
||||
示例:允许某个特定群组中的任意成员:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -189,7 +189,7 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
}
|
||||
```
|
||||
|
||||
示例:只允许某个指定群组中的特定用户:
|
||||
示例:仅允许某个特定群组中的特定用户:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -207,33 +207,33 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
```
|
||||
|
||||
<Warning>
|
||||
常见错误:`groupAllowFrom` 不是 Telegram 群组 allowlist。
|
||||
常见错误:`groupAllowFrom` 不是 Telegram 群组允许列表。
|
||||
|
||||
- 像 `-1001234567890` 这样的负数 Telegram 群组或超级群组 chat ID,应放在 `channels.telegram.groups` 下。
|
||||
- 像 `8734062810` 这样的 Telegram 用户 ID,应放在 `groupAllowFrom` 下,用于限制允许群组内哪些人可以触发机器人。
|
||||
- 只有在你希望允许群组中的任意成员都能与机器人对话时,才使用 `groupAllowFrom: ["*"]`。
|
||||
- 将 `-1001234567890` 这样的负数 Telegram 群组或超级群组聊天 ID 放到 `channels.telegram.groups` 下。
|
||||
- 当你想限制已允许群组中哪些人可以触发机器人时,将 `8734062810` 这样的 Telegram 用户 ID 放到 `groupAllowFrom` 下。
|
||||
- 只有在你希望已允许群组中的任何成员都能与机器人对话时,才使用 `groupAllowFrom: ["*"]`。
|
||||
</Warning>
|
||||
|
||||
</Tab>
|
||||
|
||||
<Tab title="提及行为">
|
||||
默认情况下,群组回复需要被提及。
|
||||
群组回复默认要求提及。
|
||||
|
||||
提及可来自:
|
||||
提及可以来自:
|
||||
|
||||
- 原生 `@botusername` 提及,或
|
||||
- 以下位置中的提及模式:
|
||||
- `agents.list[].groupChat.mentionPatterns`
|
||||
- `messages.groupChat.mentionPatterns`
|
||||
|
||||
会话级命令开关:
|
||||
会话级命令切换:
|
||||
|
||||
- `/activation always`
|
||||
- `/activation mention`
|
||||
|
||||
这些只会更新会话状态。若要持久化,请使用配置。
|
||||
这些仅更新会话状态。要持久保存,请使用配置。
|
||||
|
||||
持久化配置示例:
|
||||
持久配置示例:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -247,7 +247,7 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
}
|
||||
```
|
||||
|
||||
获取群组 chat ID 的方法:
|
||||
获取群组聊天 ID:
|
||||
|
||||
- 将群组消息转发给 `@userinfobot` / `@getidsbot`
|
||||
- 或从 `openclaw logs --follow` 中读取 `chat.id`
|
||||
@ -258,61 +258,61 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
|
||||
## 运行时行为
|
||||
|
||||
- Telegram 由 Gateway 网关进程统一管理。
|
||||
- 路由是确定性的:Telegram 入站消息会回复到 Telegram(模型不会自行选择渠道)。
|
||||
- 入站消息会标准化为共享的渠道信封格式,带有回复元数据和媒体占位符。
|
||||
- Telegram 由 Gateway 网关进程持有。
|
||||
- 路由是确定性的:Telegram 入站回复会返回到 Telegram(模型不会选择渠道)。
|
||||
- 入站消息会标准化为共享的渠道信封格式,并包含回复元数据和媒体占位符。
|
||||
- 群组会话按群组 ID 隔离。论坛话题会追加 `:topic:<threadId>` 以保持话题隔离。
|
||||
- 私信消息可以携带 `message_thread_id`;OpenClaw 会使用感知线程的会话键进行路由,并为回复保留 thread ID。
|
||||
- 长轮询使用 grammY runner,并按每个聊天 / 每个线程进行顺序处理。整体 runner sink 并发数使用 `agents.defaults.maxConcurrent`。
|
||||
- 默认情况下,若 120 秒内没有完成 `getUpdates` 活跃检查,则会触发长轮询 watchdog 重启。只有当你的部署在长时间运行任务期间仍然出现误判的 polling-stall 重启时,才增加 `channels.telegram.pollingStallThresholdMs`。该值的单位为毫秒,允许范围为 `30000` 到 `600000`;支持按账户覆盖。
|
||||
- 私信消息可以携带 `message_thread_id`;OpenClaw 会使用线程感知的会话键对其进行路由,并为回复保留线程 ID。
|
||||
- 长轮询使用带每聊天/每线程顺序控制的 grammY runner。整体 runner sink 并发度使用 `agents.defaults.maxConcurrent`。
|
||||
- 默认情况下,如果在 120 秒内没有完成的 `getUpdates` 存活信号,长轮询看门狗会触发重启。只有在你的部署中仍然出现长时间工作期间的误判轮询停滞重启时,才增加 `channels.telegram.pollingStallThresholdMs`。该值以毫秒为单位,允许范围为 `30000` 到 `600000`;支持按账户覆盖。
|
||||
- Telegram Bot API 不支持已读回执(`sendReadReceipts` 不适用)。
|
||||
|
||||
## 功能参考
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="实时流式预览(消息编辑)">
|
||||
OpenClaw 可以实时流式显示部分回复:
|
||||
OpenClaw 可以实时流式传输部分回复:
|
||||
|
||||
- 私聊:预览消息 + `editMessageText`
|
||||
- 群组 / 话题:预览消息 + `editMessageText`
|
||||
- 群组/话题:预览消息 + `editMessageText`
|
||||
|
||||
要求:
|
||||
|
||||
- `channels.telegram.streaming` 为 `off | partial | block | progress`(默认:`partial`)
|
||||
- `progress` 在 Telegram 上会映射为 `partial`(兼容跨渠道命名)
|
||||
- `streaming.preview.toolProgress` 控制工具 / 进度更新是否复用同一个被编辑的预览消息(默认:`true`)。设为 `false` 可保留独立的工具 / 进度消息。
|
||||
- 在 Telegram 上,`progress` 会映射为 `partial`(与跨渠道命名保持兼容)
|
||||
- `streaming.preview.toolProgress` 控制工具/进度更新是否复用同一个已编辑的预览消息(默认:`false`)。仅当你希望在 Telegram 中显示可见的进度更新时才设为 `true`。
|
||||
- 旧版 `channels.telegram.streamMode` 和布尔型 `streaming` 值会被自动映射
|
||||
|
||||
对于纯文本回复:
|
||||
|
||||
- 私信:OpenClaw 会保留同一个预览消息,并原地执行最终编辑(不会发送第二条消息)
|
||||
- 群组 / 话题:OpenClaw 会保留同一个预览消息,并原地执行最终编辑(不会发送第二条消息)
|
||||
- 私信:OpenClaw 会保留同一个预览消息,并在原位执行最终编辑(不会发送第二条消息)
|
||||
- 群组/话题:OpenClaw 会保留同一个预览消息,并在原位执行最终编辑(不会发送第二条消息)
|
||||
|
||||
对于复杂回复(例如媒体负载),OpenClaw 会回退到常规最终投递,然后清理预览消息。
|
||||
对于复杂回复(例如媒体负载),OpenClaw 会回退到正常的最终投递,然后清理预览消息。
|
||||
|
||||
预览流式传输独立于分块流式传输。当为 Telegram 显式启用分块流式传输时,OpenClaw 会跳过预览流,以避免双重流式传输。
|
||||
预览流式传输与分块流式传输是分开的。当为 Telegram 显式启用分块流式传输时,OpenClaw 会跳过预览流,以避免双重流式传输。
|
||||
|
||||
如果原生草稿传输不可用 / 被拒绝,OpenClaw 会自动回退到 `sendMessage` + `editMessageText`。
|
||||
如果原生草稿传输不可用或被拒绝,OpenClaw 会自动回退到 `sendMessage` + `editMessageText`。
|
||||
|
||||
Telegram 专属推理流:
|
||||
Telegram 专用推理流:
|
||||
|
||||
- `/reasoning stream` 会在生成期间将推理内容发送到实时预览
|
||||
- `/reasoning stream` 会在生成期间将推理发送到实时预览
|
||||
- 最终答案发送时不包含推理文本
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="格式化与 HTML 回退">
|
||||
<Accordion title="格式化和 HTML 回退">
|
||||
出站文本使用 Telegram `parse_mode: "HTML"`。
|
||||
|
||||
- 类 Markdown 文本会被渲染为 Telegram 安全的 HTML。
|
||||
- 类 Markdown 文本会渲染为 Telegram 安全的 HTML。
|
||||
- 原始模型 HTML 会被转义,以减少 Telegram 解析失败。
|
||||
- 如果 Telegram 拒绝已解析的 HTML,OpenClaw 会重试为纯文本。
|
||||
|
||||
链接预览默认启用,可通过 `channels.telegram.linkPreview: false` 禁用。
|
||||
默认启用链接预览,可通过 `channels.telegram.linkPreview: false` 禁用。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="原生命令与自定义命令">
|
||||
<Accordion title="原生命令和自定义命令">
|
||||
Telegram 命令菜单注册会在启动时通过 `setMyCommands` 处理。
|
||||
|
||||
原生命令默认值:
|
||||
@ -336,38 +336,38 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
|
||||
规则:
|
||||
|
||||
- 名称会被标准化(去除前导 `/`,转为小写)
|
||||
- 名称会被标准化(移除前导 `/`,转为小写)
|
||||
- 有效模式:`a-z`、`0-9`、`_`,长度 `1..32`
|
||||
- 自定义命令不能覆盖原生命令
|
||||
- 冲突 / 重复项会被跳过并记录日志
|
||||
- 冲突和重复项会被跳过并记录日志
|
||||
|
||||
说明:
|
||||
|
||||
- 自定义命令仅是菜单项;不会自动实现行为
|
||||
- 即使未显示在 Telegram 菜单中,插件 / Skills 命令在手动输入时仍可工作
|
||||
- 自定义命令仅是菜单项;它们不会自动实现行为
|
||||
- 即使未显示在 Telegram 菜单中,插件 / Skills 命令在手动输入时仍然可以工作
|
||||
|
||||
如果禁用原生命令,内置命令会被移除。自定义 / 插件命令如果已配置,仍可能会注册。
|
||||
如果原生命令被禁用,内置命令会被移除。如果已配置,自定义 / 插件命令仍可注册。
|
||||
|
||||
常见设置失败:
|
||||
|
||||
- `setMyCommands failed` 且报错 `BOT_COMMANDS_TOO_MUCH`,表示即使在裁剪后 Telegram 菜单仍然超出限制;请减少插件 / Skills / 自定义命令数量,或禁用 `channels.telegram.commands.native`。
|
||||
- `setMyCommands failed` 且报错网络 / fetch 错误,通常表示到 `api.telegram.org` 的出站 DNS / HTTPS 被阻止。
|
||||
- 出现 `setMyCommands failed` 且带有 `BOT_COMMANDS_TOO_MUCH`,表示 Telegram 菜单在裁剪后仍然超出限制;请减少插件 / Skills / 自定义命令,或禁用 `channels.telegram.commands.native`。
|
||||
- 出现 `setMyCommands failed` 且带有网络 / fetch 错误,通常表示到 `api.telegram.org` 的出站 DNS / HTTPS 被阻止。
|
||||
|
||||
### 设备配对命令(`device-pair` 插件)
|
||||
|
||||
安装 `device-pair` 插件后:
|
||||
|
||||
1. `/pair` 生成设置代码
|
||||
2. 在 iOS 应用中粘贴该代码
|
||||
2. 将代码粘贴到 iOS 应用中
|
||||
3. `/pair pending` 列出待处理请求(包括角色 / scopes)
|
||||
4. 批准请求:
|
||||
- `/pair approve <requestId>`:显式批准
|
||||
- `/pair approve`:当只有一个待处理请求时使用
|
||||
- `/pair approve latest`:批准最新请求
|
||||
- `/pair approve <requestId>` 用于显式批准
|
||||
- 当只有一个待处理请求时,使用 `/pair approve`
|
||||
- `/pair approve latest` 用于最近的请求
|
||||
|
||||
该设置代码携带一个短期有效的 bootstrap token。内置 bootstrap 交接会将主节点 token 保持为 `scopes: []`;任何已交接的 operator token 都会被限制在 `operator.approvals`、`operator.read`、`operator.talk.secrets` 和 `operator.write`。Bootstrap scope 检查带有角色前缀,因此该 operator allowlist 仅满足 operator 请求;非 operator 角色仍需要其自身角色前缀下的 scopes。
|
||||
设置代码携带一个短期有效的引导令牌。内置引导交接会将主节点令牌保持为 `scopes: []`;任何已交接的操作员令牌都会被限制在 `operator.approvals`、`operator.read`、`operator.talk.secrets` 和 `operator.write`。引导 scope 检查带有角色前缀,因此该操作员允许列表只满足操作员请求;非操作员角色仍需要其自身角色前缀下的 scopes。
|
||||
|
||||
如果设备以变更后的认证详情重试(例如角色 / scopes / 公钥),之前的待处理请求会被新请求取代,而新请求会使用不同的 `requestId`。批准前请重新运行 `/pair pending`。
|
||||
如果设备在认证详情发生变化后重试(例如角色 / scopes / 公钥),先前的待处理请求会被新请求取代,而新请求会使用不同的 `requestId`。批准前请重新运行 `/pair pending`。
|
||||
|
||||
更多详情: [配对](/zh-CN/channels/pairing#pair-via-telegram-recommended-for-ios)。
|
||||
|
||||
@ -439,7 +439,7 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="面向智能体与自动化的 Telegram 消息动作">
|
||||
<Accordion title="用于智能体和自动化的 Telegram 消息动作">
|
||||
Telegram 工具动作包括:
|
||||
|
||||
- `sendMessage`(`to`、`content`、可选的 `mediaUrl`、`replyToMessageId`、`messageThreadId`)
|
||||
@ -448,9 +448,9 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
- `editMessage`(`chatId`、`messageId`、`content`)
|
||||
- `createForumTopic`(`chatId`、`name`、可选的 `iconColor`、`iconCustomEmojiId`)
|
||||
|
||||
渠道消息动作提供了更易用的别名(`send`、`react`、`delete`、`edit`、`sticker`、`sticker-search`、`topic-create`)。
|
||||
渠道消息动作公开了更易用的别名(`send`、`react`、`delete`、`edit`、`sticker`、`sticker-search`、`topic-create`)。
|
||||
|
||||
控制开关:
|
||||
门控控制:
|
||||
|
||||
- `channels.telegram.actions.sendMessage`
|
||||
- `channels.telegram.actions.deleteMessage`
|
||||
@ -458,17 +458,17 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
- `channels.telegram.actions.sticker`(默认:禁用)
|
||||
|
||||
注意:`edit` 和 `topic-create` 当前默认启用,且没有单独的 `channels.telegram.actions.*` 开关。
|
||||
运行时发送使用的是当前生效的配置 / secrets 快照(启动 / 重载时),因此动作路径不会在每次发送时执行临时的 SecretRef 重新解析。
|
||||
运行时发送使用活动的配置 / secrets 快照(启动 / 重载时),因此动作路径不会在每次发送时临时重新解析 SecretRef。
|
||||
|
||||
移除 reaction 的语义:[/tools/reactions](/zh-CN/tools/reactions)
|
||||
移除反应的语义:[/tools/reactions](/zh-CN/tools/reactions)
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="回复线程标签">
|
||||
Telegram 支持在生成输出中使用显式回复线程标签:
|
||||
|
||||
- `[[reply_to_current]]`:回复触发消息
|
||||
- `[[reply_to:<id>]]`:回复指定的 Telegram 消息 ID
|
||||
- `[[reply_to_current]]` 回复触发消息
|
||||
- `[[reply_to:<id>]]` 回复特定的 Telegram 消息 ID
|
||||
|
||||
`channels.telegram.replyToMode` 控制处理方式:
|
||||
|
||||
@ -476,27 +476,27 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
- `first`
|
||||
- `all`
|
||||
|
||||
注意:`off` 会禁用隐式回复线程。显式 `[[reply_to_*]]` 标签仍会被遵循。
|
||||
注意:`off` 会禁用隐式回复线程处理。显式 `[[reply_to_*]]` 标签仍然会被遵循。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="论坛话题与线程行为">
|
||||
<Accordion title="论坛话题和线程行为">
|
||||
论坛超级群组:
|
||||
|
||||
- 话题会话键会追加 `:topic:<threadId>`
|
||||
- 回复与输入状态会发送到对应的话题线程
|
||||
- 回复和输入状态都以该话题线程为目标
|
||||
- 话题配置路径:
|
||||
`channels.telegram.groups.<chatId>.topics.<threadId>`
|
||||
|
||||
常规话题(`threadId=1`)特殊情况:
|
||||
|
||||
- 发送消息时会省略 `message_thread_id`(Telegram 会拒绝 `sendMessage(...thread_id=1)`)
|
||||
- 输入动作仍会包含 `message_thread_id`
|
||||
- 发送消息时省略 `message_thread_id`(Telegram 会拒绝 `sendMessage(...thread_id=1)`)
|
||||
- 输入动作仍然包含 `message_thread_id`
|
||||
|
||||
话题继承:除非被覆盖,话题条目会继承群组设置(`requireMention`、`allowFrom`、`skills`、`systemPrompt`、`enabled`、`groupPolicy`)。
|
||||
`agentId` 是话题专属项,不会从群组默认值继承。
|
||||
`agentId` 仅限话题级,不会从群组默认值继承。
|
||||
|
||||
**按话题分配智能体路由**:每个话题都可以通过在话题配置中设置 `agentId` 路由到不同的智能体。这让每个话题拥有各自隔离的工作区、记忆和会话。示例:
|
||||
**按话题的智能体路由**:每个话题都可以通过在话题配置中设置 `agentId` 路由到不同的智能体。这样每个话题都有自己隔离的工作区、记忆和会话。示例:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -518,21 +518,21 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
|
||||
此后,每个话题都有自己的会话键:`agent:zu:telegram:group:-1001234567890:topic:3`
|
||||
|
||||
**持久化 ACP 话题绑定**:论坛话题可以通过顶层类型化 ACP 绑定来固定 ACP harness 会话(`bindings[]` 中使用 `type: "acp"`,并设置 `match.channel: "telegram"`、`peer.kind: "group"`,以及带话题限定的 id,例如 `-1001234567890:topic:42`)。当前仅适用于群组 / 超级群组中的论坛话题。参见 [ACP Agents](/zh-CN/tools/acp-agents)。
|
||||
**持久 ACP 话题绑定**:论坛话题可以通过顶层类型化 ACP 绑定(`bindings[]` 中设置 `type: "acp"`,并带有 `match.channel: "telegram"`、`peer.kind: "group"` 以及类似 `-1001234567890:topic:42` 的话题限定 ID)固定 ACP harness 会话。目前仅适用于群组 / 超级群组中的论坛话题。参见 [ACP Agents](/zh-CN/tools/acp-agents)。
|
||||
|
||||
**从聊天中生成线程绑定的 ACP**:`/acp spawn <agent> --thread here|auto` 会将当前话题绑定到一个新的 ACP 会话;后续消息会直接路由到该会话。OpenClaw 会在当前话题中固定生成确认消息。要求 `channels.telegram.threadBindings.spawnAcpSessions=true`。
|
||||
**从聊天发起线程绑定的 ACP 生成**:`/acp spawn <agent> --thread here|auto` 会将当前话题绑定到新的 ACP 会话;后续消息会直接路由到该会话。OpenClaw 会将生成确认固定在话题内。需要 `channels.telegram.threadBindings.spawnAcpSessions=true`。
|
||||
|
||||
模板上下文会暴露 `MessageThreadId` 和 `IsForum`。带有 `message_thread_id` 的私信聊天仍保持私信路由,但会使用感知线程的会话键。
|
||||
模板上下文会公开 `MessageThreadId` 和 `IsForum`。带有 `message_thread_id` 的私信聊天会保持私信路由,但使用线程感知的会话键。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="音频、视频与贴纸">
|
||||
<Accordion title="音频、视频和贴纸">
|
||||
### 音频消息
|
||||
|
||||
Telegram 会区分语音便笺和音频文件。
|
||||
|
||||
- 默认:按音频文件行为处理
|
||||
- 在智能体回复中加入标签 `[[audio_as_voice]]` 可强制按语音便笺发送
|
||||
- 在智能体回复中添加标签 `[[audio_as_voice]]` 可强制按语音便笺发送
|
||||
|
||||
消息动作示例:
|
||||
|
||||
@ -562,13 +562,13 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
}
|
||||
```
|
||||
|
||||
视频便笺不支持标题说明;如果提供了消息文本,会单独发送。
|
||||
视频便笺不支持标题说明;如果提供了消息文本,将单独发送。
|
||||
|
||||
### 贴纸
|
||||
|
||||
入站贴纸处理:
|
||||
|
||||
- 静态 WEBP:下载并处理(占位符为 `<media:sticker>`)
|
||||
- 静态 WEBP:下载并处理(占位符 `<media:sticker>`)
|
||||
- 动画 TGS:跳过
|
||||
- 视频 WEBM:跳过
|
||||
|
||||
@ -584,7 +584,7 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
|
||||
- `~/.openclaw/telegram/sticker-cache.json`
|
||||
|
||||
贴纸会在可能的情况下仅描述一次并缓存,以减少重复的视觉调用。
|
||||
贴纸会在可能时仅描述一次并缓存,以减少重复的视觉调用。
|
||||
|
||||
启用贴纸动作:
|
||||
|
||||
@ -611,21 +611,21 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
}
|
||||
```
|
||||
|
||||
搜索缓存贴纸:
|
||||
搜索已缓存的贴纸:
|
||||
|
||||
```json5
|
||||
{
|
||||
action: "sticker-search",
|
||||
channel: "telegram",
|
||||
query: "cat waving",
|
||||
query: "挥手的猫",
|
||||
limit: 5,
|
||||
}
|
||||
```
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Reaction 通知">
|
||||
Telegram reaction 会以 `message_reaction` 更新形式到达(独立于消息负载)。
|
||||
<Accordion title="反应通知">
|
||||
Telegram 反应以 `message_reaction` 更新形式到达(独立于消息负载)。
|
||||
|
||||
启用后,OpenClaw 会将如下系统事件加入队列:
|
||||
|
||||
@ -633,22 +633,22 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
|
||||
配置:
|
||||
|
||||
- `channels.telegram.reactionNotifications`:`off | own | all`(默认:`own`)
|
||||
- `channels.telegram.reactionLevel`:`off | ack | minimal | extensive`(默认:`minimal`)
|
||||
- `channels.telegram.reactionNotifications`: `off | own | all`(默认:`own`)
|
||||
- `channels.telegram.reactionLevel`: `off | ack | minimal | extensive`(默认:`minimal`)
|
||||
|
||||
说明:
|
||||
|
||||
- `own` 表示仅针对用户对机器人发送消息的 reaction(尽力通过已发送消息缓存实现)。
|
||||
- Reaction 事件仍遵循 Telegram 访问控制(`dmPolicy`、`allowFrom`、`groupPolicy`、`groupAllowFrom`);未授权发送者会被丢弃。
|
||||
- Telegram 不会在 reaction 更新中提供线程 ID。
|
||||
- `own` 表示仅处理用户对机器人发送消息的反应(通过已发送消息缓存尽力判断)。
|
||||
- 反应事件仍然遵循 Telegram 访问控制(`dmPolicy`、`allowFrom`、`groupPolicy`、`groupAllowFrom`);未授权发送者会被丢弃。
|
||||
- Telegram 不会在反应更新中提供线程 ID。
|
||||
- 非论坛群组会路由到群聊会话
|
||||
- 论坛群组会路由到群组的常规话题会话(`:topic:1`),而不是精确的原始话题
|
||||
- 论坛群组会路由到群组常规话题会话(`:topic:1`),而不是确切的原始话题
|
||||
|
||||
轮询 / webhook 的 `allowed_updates` 会自动包含 `message_reaction`。
|
||||
用于轮询 / Webhook 的 `allowed_updates` 会自动包含 `message_reaction`。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="确认 Reaction">
|
||||
<Accordion title="确认反应">
|
||||
`ackReaction` 会在 OpenClaw 处理入站消息期间发送一个确认 emoji。
|
||||
|
||||
解析顺序:
|
||||
@ -656,24 +656,24 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
- `channels.telegram.accounts.<accountId>.ackReaction`
|
||||
- `channels.telegram.ackReaction`
|
||||
- `messages.ackReaction`
|
||||
- 智能体 identity emoji 回退(`agents.list[].identity.emoji`,否则为 "👀")
|
||||
- 智能体身份 emoji 回退(`agents.list[].identity.emoji`,否则为 "👀")
|
||||
|
||||
说明:
|
||||
|
||||
- Telegram 需要使用 unicode emoji(例如 "👀")。
|
||||
- 使用 `""` 可为某个渠道或账户禁用该 reaction。
|
||||
- Telegram 需要 unicode emoji(例如 "👀")。
|
||||
- 使用 `""` 可为某个渠道或账户禁用该反应。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="来自 Telegram 事件和命令的配置写入">
|
||||
渠道配置写入默认启用(`configWrites !== false`)。
|
||||
默认启用渠道配置写入(`configWrites !== false`)。
|
||||
|
||||
由 Telegram 触发的写入包括:
|
||||
|
||||
- 群组迁移事件(`migrate_to_chat_id`),用于更新 `channels.telegram.groups`
|
||||
- `/config set` 和 `/config unset`(需要启用命令)
|
||||
|
||||
禁用方式:
|
||||
禁用:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -687,28 +687,28 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="长轮询与 webhook">
|
||||
默认使用长轮询。若要使用 webhook 模式,请设置 `channels.telegram.webhookUrl` 和 `channels.telegram.webhookSecret`;还可选设置 `webhookPath`、`webhookHost`、`webhookPort`(默认分别为 `/telegram-webhook`、`127.0.0.1`、`8787`)。
|
||||
<Accordion title="长轮询与 Webhook">
|
||||
默认为长轮询。要使用 Webhook 模式,请设置 `channels.telegram.webhookUrl` 和 `channels.telegram.webhookSecret`;可选项包括 `webhookPath`、`webhookHost`、`webhookPort`(默认分别为 `/telegram-webhook`、`127.0.0.1`、`8787`)。
|
||||
|
||||
本地监听器会绑定到 `127.0.0.1:8787`。对于公网入口,请在本地端口前放置反向代理,或有意将 `webhookHost` 设置为 `"0.0.0.0"`。
|
||||
本地监听器绑定到 `127.0.0.1:8787`。对于公网入口,可以在本地端口前放置反向代理,或有意设置 `webhookHost: "0.0.0.0"`。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="限制、重试与 CLI 目标">
|
||||
<Accordion title="限制、重试和 CLI 目标">
|
||||
- `channels.telegram.textChunkLimit` 默认值为 4000。
|
||||
- `channels.telegram.chunkMode="newline"` 会优先按段落边界(空行)分割,再按长度分割。
|
||||
- `channels.telegram.mediaMaxMb`(默认 100)限制 Telegram 入站和出站媒体大小。
|
||||
- `channels.telegram.chunkMode="newline"` 会在按长度切分前优先选择段落边界(空行)。
|
||||
- `channels.telegram.mediaMaxMb`(默认 100)限制入站和出站 Telegram 媒体大小。
|
||||
- `channels.telegram.timeoutSeconds` 会覆盖 Telegram API 客户端超时(如果未设置,则使用 grammY 默认值)。
|
||||
- `channels.telegram.pollingStallThresholdMs` 默认为 `120000`;仅在出现 polling-stall 误报重启时,才在 `30000` 到 `600000` 之间调整。
|
||||
- `channels.telegram.pollingStallThresholdMs` 默认为 `120000`;仅在出现轮询停滞误报重启时,才在 `30000` 到 `600000` 之间调整。
|
||||
- 群组上下文历史使用 `channels.telegram.historyLimit` 或 `messages.groupChat.historyLimit`(默认 50);`0` 表示禁用。
|
||||
- reply / quote / forward 补充上下文当前会按接收时原样传递。
|
||||
- Telegram allowlist 主要用于控制谁可以触发智能体,而不是完整的补充上下文脱敏边界。
|
||||
- 回复 / 引用 / 转发的补充上下文当前会按接收时原样传递。
|
||||
- Telegram 允许列表主要用于限制谁可以触发智能体,而不是完整的补充上下文脱敏边界。
|
||||
- 私信历史控制:
|
||||
- `channels.telegram.dmHistoryLimit`
|
||||
- `channels.telegram.dms["<user_id>"].historyLimit`
|
||||
- `channels.telegram.retry` 配置适用于 Telegram 发送辅助器(CLI / 工具 / 动作),用于处理可恢复的出站 API 错误。
|
||||
- `channels.telegram.retry` 配置适用于 Telegram 发送辅助器(CLI / 工具 / 动作)中的可恢复出站 API 错误重试。
|
||||
|
||||
CLI 发送目标可以是数字 chat ID 或用户名:
|
||||
CLI 发送目标可以是数字聊天 ID 或用户名:
|
||||
|
||||
```bash
|
||||
openclaw message send --channel telegram --target 123456789 --message "hi"
|
||||
@ -725,39 +725,39 @@ openclaw message poll --channel telegram --target -1001234567890:topic:42 \
|
||||
--poll-duration-seconds 300 --poll-public
|
||||
```
|
||||
|
||||
Telegram 专属投票标志:
|
||||
Telegram 专用投票标志:
|
||||
|
||||
- `--poll-duration-seconds`(5 - 600)
|
||||
- `--poll-duration-seconds`(5-600)
|
||||
- `--poll-anonymous`
|
||||
- `--poll-public`
|
||||
- 论坛话题使用 `--thread-id`(或使用 `:topic:` 目标)
|
||||
|
||||
Telegram 发送还支持:
|
||||
|
||||
- 当 `channels.telegram.capabilities.inlineButtons` 允许时,使用带有 `buttons` 块的 `--presentation` 来实现内联键盘
|
||||
- `--pin` 或 `--delivery '{"pin":true}'`,用于在机器人有权限固定消息的聊天中请求固定投递
|
||||
- `--force-document`,用于将出站图片和 GIF 作为文档发送,而不是作为压缩照片或动画媒体上传
|
||||
- 当 `channels.telegram.capabilities.inlineButtons` 允许时,使用带有 `buttons` 块的 `--presentation` 来提供内联键盘
|
||||
- 使用 `--pin` 或 `--delivery '{"pin":true}'` 请求固定投递,前提是机器人在该聊天中有固定权限
|
||||
- `--force-document` 将出站图片和 GIF 作为文档发送,而不是压缩照片或动画媒体上传
|
||||
|
||||
动作控制:
|
||||
动作门控:
|
||||
|
||||
- `channels.telegram.actions.sendMessage=false` 会禁用出站 Telegram 消息,包括投票
|
||||
- `channels.telegram.actions.poll=false` 会禁用 Telegram 投票创建,但保留常规发送功能
|
||||
- `channels.telegram.actions.poll=false` 会禁用 Telegram 投票创建,同时保留常规发送功能
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Telegram 中的 exec 批准">
|
||||
Telegram 支持在批准者私信中进行 exec 批准,也可选择在原始聊天或话题中发布提示。批准者必须是数字形式的 Telegram 用户 ID。
|
||||
Telegram 支持在批准者私信中进行 exec 批准,也可以选择在源聊天或话题中发布提示。批准者必须是数字 Telegram 用户 ID。
|
||||
|
||||
配置路径:
|
||||
|
||||
- `channels.telegram.execApprovals.enabled`(当至少有一个批准者可解析时会自动启用)
|
||||
- `channels.telegram.execApprovals.approvers`(回退到来自 `allowFrom` / `defaultTo` 的数字所有者 ID)
|
||||
- `channels.telegram.execApprovals.target`:`dm`(默认)| `channel` | `both`
|
||||
- `channels.telegram.execApprovals.enabled`(当至少有一个批准者可解析时自动启用)
|
||||
- `channels.telegram.execApprovals.approvers`(回退到 `allowFrom` / `defaultTo` 中的数字所有者 ID)
|
||||
- `channels.telegram.execApprovals.target`: `dm`(默认) | `channel` | `both`
|
||||
- `agentFilter`、`sessionFilter`
|
||||
|
||||
渠道投递会在聊天中显示命令文本;仅在受信任的群组 / 话题中启用 `channel` 或 `both`。当提示落在论坛话题中时,OpenClaw 会为批准提示及其后续消息保留该话题。exec 批准默认会在 30 分钟后过期。
|
||||
渠道投递会在聊天中显示命令文本;仅在受信任的群组 / 话题中启用 `channel` 或 `both`。当提示投递到论坛话题中时,OpenClaw 会为批准提示和后续消息保留该话题。exec 批准默认会在 30 分钟后过期。
|
||||
|
||||
内联批准按钮还要求 `channels.telegram.capabilities.inlineButtons` 允许目标表面(`dm`、`group` 或 `all`)。带有 `plugin:` 前缀的批准 ID 会通过插件批准解析;其他 ID 会优先通过 exec 批准解析。
|
||||
内联批准按钮还要求 `channels.telegram.capabilities.inlineButtons` 允许目标界面(`dm`、`group` 或 `all`)。带有 `plugin:` 前缀的批准 ID 会通过插件批准解析;其他 ID 会优先通过 exec 批准解析。
|
||||
|
||||
参见 [Exec approvals](/zh-CN/tools/exec-approvals)。
|
||||
|
||||
@ -766,12 +766,12 @@ openclaw message poll --channel telegram --target -1001234567890:topic:42 \
|
||||
|
||||
## 错误回复控制
|
||||
|
||||
当智能体遇到投递错误或提供商错误时,Telegram 可以回复错误文本,也可以将其静默。两个配置键控制此行为:
|
||||
当智能体遇到投递或提供商错误时,Telegram 可以回复错误文本,也可以抑制该回复。两个配置键控制此行为:
|
||||
|
||||
| Key | 值 | 默认值 | 说明 |
|
||||
| ----------------------------------- | ----------------- | ------- | ---------------------------------------------------------------------------------------------- |
|
||||
| `channels.telegram.errorPolicy` | `reply`, `silent` | `reply` | `reply` 会向聊天发送友好的错误消息。`silent` 会完全抑制错误回复。 |
|
||||
| `channels.telegram.errorCooldownMs` | 数字(毫秒) | `60000` | 同一聊天两次错误回复之间的最短时间。可防止服务中断期间错误刷屏。 |
|
||||
| 键 | 值 | 默认值 | 描述 |
|
||||
| ----------------------------------- | ----------------- | ------- | ----------------------------------------------------------------------------------------------- |
|
||||
| `channels.telegram.errorPolicy` | `reply`, `silent` | `reply` | `reply` 会向聊天发送一条友好的错误消息。`silent` 会完全抑制错误回复。 |
|
||||
| `channels.telegram.errorCooldownMs` | number (ms) | `60000` | 同一聊天两次错误回复之间的最短时间。可防止故障期间的错误刷屏。 |
|
||||
|
||||
支持按账户、按群组和按话题覆盖(继承规则与其他 Telegram 配置键相同)。
|
||||
|
||||
@ -797,10 +797,10 @@ openclaw message poll --channel telegram --target -1001234567890:topic:42 \
|
||||
<Accordion title="机器人不响应未提及的群组消息">
|
||||
|
||||
- 如果 `requireMention=false`,Telegram 隐私模式必须允许完全可见。
|
||||
- BotFather:`/setprivacy` -> Disable
|
||||
- 然后将机器人从群组中移除并重新添加
|
||||
- 当配置预期接收未提及的群组消息时,`openclaw channels status` 会发出警告。
|
||||
- `openclaw channels status --probe` 可检查显式数字群组 ID;通配符 `"*"` 无法执行成员关系探测。
|
||||
- BotFather:`/setprivacy` -> 禁用
|
||||
- 然后移除并重新将机器人添加到群组
|
||||
- 当配置预期处理未提及的群组消息时,`openclaw channels status` 会发出警告。
|
||||
- `openclaw channels status --probe` 可以检查显式数字群组 ID;无法对通配符 `"*"` 进行成员资格探测。
|
||||
- 快速会话测试:`/activation always`。
|
||||
|
||||
</Accordion>
|
||||
@ -808,28 +808,28 @@ openclaw message poll --channel telegram --target -1001234567890:topic:42 \
|
||||
<Accordion title="机器人完全看不到群组消息">
|
||||
|
||||
- 当存在 `channels.telegram.groups` 时,必须列出该群组(或包含 `"*"`)
|
||||
- 验证机器人已加入该群组
|
||||
- 查看日志:使用 `openclaw logs --follow` 检查跳过原因
|
||||
- 验证机器人是否在群组中
|
||||
- 查看日志:`openclaw logs --follow` 以了解跳过原因
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="命令部分可用或完全不可用">
|
||||
|
||||
- 授权你的发送者身份(配对和 / 或数字 `allowFrom`)
|
||||
- 即使群组策略是 `open`,命令授权仍然适用
|
||||
- `setMyCommands failed` 且报错 `BOT_COMMANDS_TOO_MUCH`,表示原生命令菜单条目过多;请减少插件 / Skills / 自定义命令,或禁用原生菜单
|
||||
- `setMyCommands failed` 且报错网络 / fetch 错误,通常表示到 `api.telegram.org` 的 DNS / HTTPS 可达性存在问题
|
||||
- 即使群组策略为 `open`,命令授权仍然适用
|
||||
- 出现 `setMyCommands failed` 且带有 `BOT_COMMANDS_TOO_MUCH`,表示原生命令菜单条目过多;请减少插件 / Skills / 自定义命令,或禁用原生菜单
|
||||
- 出现 `setMyCommands failed` 且带有网络 / fetch 错误,通常表示无法通过 DNS / HTTPS 访问 `api.telegram.org`
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="轮询或网络不稳定">
|
||||
|
||||
- Node 22+ + 自定义 fetch / 代理,如果 AbortSignal 类型不匹配,可能触发立即中止行为。
|
||||
- 某些主机会优先将 `api.telegram.org` 解析为 IPv6;损坏的 IPv6 出站链路可能导致 Telegram API 间歇性失败。
|
||||
- 如果日志包含 `TypeError: fetch failed` 或 `Network request for 'getUpdates' failed!`,OpenClaw 现在会将这些视为可恢复网络错误并重试。
|
||||
- 如果日志包含 `Polling stall detected`,默认情况下,OpenClaw 会在 120 秒内没有完成长轮询活跃检查后重启轮询并重建 Telegram 传输层。
|
||||
- 仅当长时间运行的 `getUpdates` 调用本身健康,但你的主机仍报告 polling-stall 误报重启时,才增加 `channels.telegram.pollingStallThresholdMs`。持续卡住通常表明主机与 `api.telegram.org` 之间存在代理、DNS、IPv6 或 TLS 出站问题。
|
||||
- 在直连出站 / TLS 不稳定的 VPS 主机上,可通过 `channels.telegram.proxy` 转发 Telegram API 调用:
|
||||
- Node 22+ + 自定义 fetch / 代理可能会在 AbortSignal 类型不匹配时触发立即中止行为。
|
||||
- 某些主机会优先将 `api.telegram.org` 解析为 IPv6;损坏的 IPv6 出站连接可能导致间歇性 Telegram API 故障。
|
||||
- 如果日志包含 `TypeError: fetch failed` 或 `Network request for 'getUpdates' failed!`,OpenClaw 现在会将这些作为可恢复网络错误进行重试。
|
||||
- 如果日志包含 `Polling stall detected`,默认情况下,OpenClaw 会在 120 秒内没有完成的长轮询存活信号后重启轮询并重建 Telegram 传输层。
|
||||
- 仅当长时间运行的 `getUpdates` 调用本身健康,但你的主机仍报告轮询停滞误报重启时,才增加 `channels.telegram.pollingStallThresholdMs`。持续的停滞通常表示主机与 `api.telegram.org` 之间存在代理、DNS、IPv6 或 TLS 出站问题。
|
||||
- 在出站连接 / TLS 不稳定的 VPS 主机上,通过 `channels.telegram.proxy` 路由 Telegram API 调用:
|
||||
|
||||
```yaml
|
||||
channels:
|
||||
@ -838,7 +838,7 @@ channels:
|
||||
```
|
||||
|
||||
- Node 22+ 默认使用 `autoSelectFamily=true`(WSL2 除外)和 `dnsResultOrder=ipv4first`。
|
||||
- 如果你的主机是 WSL2,或明确在仅 IPv4 行为下工作更稳定,请强制选择地址族:
|
||||
- 如果你的主机是 WSL2,或明确在仅 IPv4 行为下效果更好,请强制设置地址族选择:
|
||||
|
||||
```yaml
|
||||
channels:
|
||||
@ -847,7 +847,7 @@ channels:
|
||||
autoSelectFamily: false
|
||||
```
|
||||
|
||||
- RFC 2544 基准测试地址范围(`198.18.0.0/15`)默认已允许用于 Telegram 媒体下载。如果受信任的 fake-IP 或透明代理在媒体下载期间将 `api.telegram.org` 重写为其他私有 / 内部 / 特殊用途地址,你可以选择启用 Telegram 专属绕过:
|
||||
- RFC 2544 基准范围响应(`198.18.0.0/15`)默认已被允许用于 Telegram 媒体下载。如果受信任的 fake-IP 或透明代理在媒体下载期间将 `api.telegram.org` 重写到其他私有 / 内部 / 特殊用途地址,你可以选择启用 Telegram 专用绕过:
|
||||
|
||||
```yaml
|
||||
channels:
|
||||
@ -856,13 +856,13 @@ channels:
|
||||
dangerouslyAllowPrivateNetwork: true
|
||||
```
|
||||
|
||||
- 相同的启用项也支持按账户配置,路径为
|
||||
- 同样的选择启用也可按账户配置,路径为
|
||||
`channels.telegram.accounts.<accountId>.network.dangerouslyAllowPrivateNetwork`。
|
||||
- 如果你的代理将 Telegram 媒体主机解析到 `198.18.x.x`,请先保持危险标志关闭。Telegram 媒体默认已经允许 RFC 2544 基准测试范围。
|
||||
- 如果你的代理将 Telegram 媒体主机解析到 `198.18.x.x`,请先保持危险标志关闭。Telegram 媒体默认已允许 RFC 2544 基准范围。
|
||||
|
||||
<Warning>
|
||||
`channels.telegram.network.dangerouslyAllowPrivateNetwork` 会削弱 Telegram
|
||||
媒体 SSRF 保护。只有在受信任、由操作员控制的代理环境中,例如 Clash、Mihomo 或 Surge 的 fake-IP 路由,在其生成 RFC 2544 基准测试范围之外的私有或特殊用途地址时,才应使用它。对于普通公网 Telegram 访问,请保持关闭。
|
||||
媒体 SSRF 保护。仅在受信任且由操作员控制的代理环境中使用,例如 Clash、Mihomo 或 Surge 的 fake-IP 路由,并且它们会在 RFC 2544 基准范围之外合成私有或特殊用途响应。对于正常的公网 Telegram 访问,请保持关闭。
|
||||
</Warning>
|
||||
|
||||
- 环境变量覆盖(临时):
|
||||
@ -879,11 +879,11 @@ dig +short api.telegram.org AAAA
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
更多帮助: [渠道故障排除](/zh-CN/channels/troubleshooting)。
|
||||
更多帮助:[渠道故障排除](/zh-CN/channels/troubleshooting)。
|
||||
|
||||
## 配置参考
|
||||
|
||||
主要参考: [Configuration reference - Telegram](/zh-CN/gateway/config-channels#telegram)。
|
||||
主要参考:[Configuration reference - Telegram](/zh-CN/gateway/config-channels#telegram)。
|
||||
|
||||
<Accordion title="高信号 Telegram 字段">
|
||||
|
||||
@ -895,16 +895,16 @@ dig +short api.telegram.org AAAA
|
||||
- 流式传输:`streaming`(预览)、`streaming.preview.toolProgress`、`blockStreaming`
|
||||
- 格式化 / 投递:`textChunkLimit`、`chunkMode`、`linkPreview`、`responsePrefix`
|
||||
- 媒体 / 网络:`mediaMaxMb`、`timeoutSeconds`、`pollingStallThresholdMs`、`retry`、`network.autoSelectFamily`、`network.dangerouslyAllowPrivateNetwork`、`proxy`
|
||||
- webhook:`webhookUrl`、`webhookSecret`、`webhookPath`、`webhookHost`
|
||||
- 动作 / 能力:`capabilities.inlineButtons`、`actions.sendMessage|editMessage|deleteMessage|reactions|sticker`
|
||||
- reactions:`reactionNotifications`、`reactionLevel`
|
||||
- Webhook:`webhookUrl`、`webhookSecret`、`webhookPath`、`webhookHost`
|
||||
- 动作 / 功能:`capabilities.inlineButtons`、`actions.sendMessage|editMessage|deleteMessage|reactions|sticker`
|
||||
- 反应:`reactionNotifications`、`reactionLevel`
|
||||
- 错误:`errorPolicy`、`errorCooldownMs`
|
||||
- 写入 / 历史:`configWrites`、`historyLimit`、`dmHistoryLimit`、`dms.*.historyLimit`
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Note>
|
||||
多账户优先级:当配置了两个或更多账户 ID 时,请设置 `channels.telegram.defaultAccount`(或包含 `channels.telegram.accounts.default`),以显式指定默认路由。否则,OpenClaw 会回退到第一个标准化账户 ID,并由 `openclaw doctor` 发出警告。命名账户会继承 `channels.telegram.allowFrom` / `groupAllowFrom`,但不会继承 `accounts.default.*` 的值。
|
||||
多账户优先级:当配置了两个或更多账户 ID 时,请设置 `channels.telegram.defaultAccount`(或包含 `channels.telegram.accounts.default`),以明确默认路由。否则,OpenClaw 会回退到第一个标准化账户 ID,并且 `openclaw doctor` 会发出警告。命名账户会继承 `channels.telegram.allowFrom` / `groupAllowFrom`,但不会继承 `accounts.default.*` 的值。
|
||||
</Note>
|
||||
|
||||
## 相关内容
|
||||
@ -913,8 +913,8 @@ dig +short api.telegram.org AAAA
|
||||
<Card title="配对" icon="link" href="/zh-CN/channels/pairing">
|
||||
将 Telegram 用户与 Gateway 网关配对。
|
||||
</Card>
|
||||
<Card title="Groups" icon="users" href="/zh-CN/channels/groups">
|
||||
群组和话题 allowlist 行为。
|
||||
<Card title="群组" icon="users" href="/zh-CN/channels/groups">
|
||||
群组和话题允许列表行为。
|
||||
</Card>
|
||||
<Card title="渠道路由" icon="route" href="/zh-CN/channels/channel-routing">
|
||||
将入站消息路由到智能体。
|
||||
|
||||
@ -1,21 +1,21 @@
|
||||
---
|
||||
read_when:
|
||||
- 你正在使用语音通话插件,并想了解 CLI 入口点
|
||||
- 你想查看 `voicecall call|continue|dtmf|status|tail|expose` 的快速示例
|
||||
summary: '`openclaw voicecall` 的 CLI 参考(语音通话插件命令界面)'
|
||||
title: 语音通话
|
||||
- 你使用语音通话插件,并且想了解 CLI 入口点
|
||||
- 你想查看 `voicecall setup|smoke|call|continue|dtmf|status|tail|expose` 的快速示例
|
||||
summary: '`openclaw voicecall` 的 CLI 参考(语音通话插件命令接口)'
|
||||
title: Voicecall
|
||||
x-i18n:
|
||||
generated_at: "2026-04-24T04:01:49Z"
|
||||
generated_at: "2026-04-25T02:35:33Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: 03773f46d1c9ab407a9734cb2bbe13d2a36bf0da8e6c9c68c18c05e285912c88
|
||||
source_hash: ffed2f9f6edc989066a0b7d1e44752bf30a2356955db2577d350c60070b7b5f0
|
||||
source_path: cli/voicecall.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
# `openclaw voicecall`
|
||||
|
||||
`voicecall` 是一个由插件提供的命令。只有在安装并启用了语音通话插件时,它才会出现。
|
||||
`voicecall` 是一个由插件提供的命令。只有在语音通话插件已安装并启用时,它才会显示。
|
||||
|
||||
主要文档:
|
||||
|
||||
@ -24,6 +24,8 @@ x-i18n:
|
||||
## 常用命令
|
||||
|
||||
```bash
|
||||
openclaw voicecall setup
|
||||
openclaw voicecall smoke
|
||||
openclaw voicecall status --call-id <id>
|
||||
openclaw voicecall call --to "+15555550123" --message "Hello" --mode notify
|
||||
openclaw voicecall continue --call-id <id> --message "Any questions?"
|
||||
@ -31,6 +33,19 @@ openclaw voicecall dtmf --call-id <id> --digits "ww123456#"
|
||||
openclaw voicecall end --call-id <id>
|
||||
```
|
||||
|
||||
默认情况下,`setup` 会输出便于阅读的就绪检查结果。对于脚本,请使用 `--json`:
|
||||
|
||||
```bash
|
||||
openclaw voicecall setup --json
|
||||
```
|
||||
|
||||
`smoke` 会运行相同的就绪检查。除非同时提供 `--to` 和 `--yes`,否则它不会拨打真实电话:
|
||||
|
||||
```bash
|
||||
openclaw voicecall smoke --to "+15555550123" # 试运行
|
||||
openclaw voicecall smoke --to "+15555550123" --yes # 实际 notify 呼叫
|
||||
```
|
||||
|
||||
## 暴露 webhook(Tailscale)
|
||||
|
||||
```bash
|
||||
@ -39,7 +54,7 @@ openclaw voicecall expose --mode funnel
|
||||
openclaw voicecall expose --mode off
|
||||
```
|
||||
|
||||
安全说明:仅将 webhook 端点暴露给你信任的网络。如有可能,优先使用 Tailscale Serve 而不是 Funnel。
|
||||
安全注意事项:仅将 webhook 端点暴露给你信任的网络。尽可能优先使用 Tailscale Serve,而不是 Funnel。
|
||||
|
||||
## 相关内容
|
||||
|
||||
|
||||
@ -1,56 +1,56 @@
|
||||
---
|
||||
read_when:
|
||||
- 你需要一份按提供商逐项说明的模型设置参考文档
|
||||
- 你想要用于模型提供商的示例配置或 CLI 新手引导命令
|
||||
- 你需要一份按提供商分别说明的模型设置参考文档
|
||||
- 你想要模型提供商的示例配置或 CLI 新手引导命令
|
||||
summary: 模型提供商概览,包含示例配置 + CLI 流程
|
||||
title: 模型提供商
|
||||
x-i18n:
|
||||
generated_at: "2026-04-25T01:27:33Z"
|
||||
generated_at: "2026-04-25T02:35:38Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: 9bc820dafddfb56849cc54216cb9392d0f9e2a980ee12e23382348bdb29233c3
|
||||
source_hash: f321baaf1bd451b1f5f70d44dda8d914f8cf10b58e404370576a5a7480191e4d
|
||||
source_path: concepts/model-providers.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
本页介绍的是 **LLM/模型提供商**(不是像 WhatsApp/Telegram 这样的聊天渠道)。
|
||||
关于模型选择规则,请参阅 [/concepts/models](/zh-CN/concepts/models)。
|
||||
关于模型选择规则,请参见 [/concepts/models](/zh-CN/concepts/models)。
|
||||
|
||||
## 快速规则
|
||||
|
||||
- 模型引用使用 `provider/model`(示例:`opencode/claude-opus-4-6`)。
|
||||
- 设置后,`agents.defaults.models` 会作为允许列表生效。
|
||||
- 设置后,`agents.defaults.models` 会作为允许列表。
|
||||
- CLI 辅助命令:`openclaw onboard`、`openclaw models list`、`openclaw models set <provider/model>`。
|
||||
- `models.providers.*.models[].contextWindow` 是原生模型元数据;`contextTokens` 是运行时实际生效的上限。
|
||||
- 回退规则、冷却探测和会话覆盖持久化:参见 [模型故障切换](/zh-CN/concepts/model-failover)。
|
||||
- OpenAI 系列路由按前缀区分:`openai/<model>` 在 PI 中使用直连 OpenAI API 密钥提供商,`openai-codex/<model>` 在 PI 中使用 Codex OAuth,而 `openai/<model>` 加上 `agents.defaults.embeddedHarness.runtime: "codex"` 则使用原生 Codex 应用服务器 harness。参见 [OpenAI](/zh-CN/providers/openai) 和 [Codex harness](/zh-CN/plugins/codex-harness)。
|
||||
- 插件自动启用遵循相同边界:`openai-codex/<model>` 属于 OpenAI 插件,而 Codex 插件由 `embeddedHarness.runtime: "codex"` 或旧版 `codex/<model>` 引用启用。
|
||||
- CLI 运行时也使用同样的拆分:选择规范模型引用,例如 `anthropic/claude-*`、`google/gemini-*` 或 `openai/gpt-*`,然后在需要本地 CLI 后端时,将 `agents.defaults.embeddedHarness.runtime` 设置为 `claude-cli`、`google-gemini-cli` 或 `codex-cli`。旧版 `claude-cli/*`、`google-gemini-cli/*` 和 `codex-cli/*` 引用会迁移回规范提供商引用,并将运行时单独记录。
|
||||
- GPT-5.5 目前可通过订阅/OAuth 路由使用:在 PI 中使用 `openai-codex/gpt-5.5`,或使用带 Codex 应用服务器 harness 的 `openai/gpt-5.5`。当 OpenAI 在公共 API 上启用 GPT-5.5 后,`openai/gpt-5.5` 的直连 API 密钥路由才会受支持;在此之前,`OPENAI_API_KEY` 配置请使用已启用 API 的模型,例如 `openai/gpt-5.4`。
|
||||
- `models.providers.*.models[].contextWindow` 是原生模型元数据;`contextTokens` 是运行时生效的上限。
|
||||
- 回退规则、冷却探测以及会话覆盖持久化:请参见 [模型故障转移](/zh-CN/concepts/model-failover)。
|
||||
- OpenAI 系列路由按前缀区分:`openai/<model>` 在 PI 中使用直接 OpenAI API 密钥提供商,`openai-codex/<model>` 在 PI 中使用 Codex OAuth,而 `openai/<model>` 加上 `agents.defaults.embeddedHarness.runtime: "codex"` 则使用原生 Codex 应用服务器 Codex harness。请参见 [OpenAI](/zh-CN/providers/openai) 和 [Codex harness](/zh-CN/plugins/codex-harness)。
|
||||
- 插件自动启用也遵循同样的边界:`openai-codex/<model>` 属于 OpenAI 插件,而 Codex 插件则由 `embeddedHarness.runtime: "codex"` 或旧版 `codex/<model>` 引用启用。
|
||||
- CLI 运行时也使用同样的拆分:选择规范模型引用,例如 `anthropic/claude-*`、`google/gemini-*` 或 `openai/gpt-*`,然后在你想使用本地 CLI 后端时,将 `agents.defaults.embeddedHarness.runtime` 设为 `claude-cli`、`google-gemini-cli` 或 `codex-cli`。旧版 `claude-cli/*`、`google-gemini-cli/*` 和 `codex-cli/*` 引用会迁移回规范提供商引用,并将运行时单独记录。
|
||||
- GPT-5.5 目前可通过订阅/OAuth 路由使用:在 PI 中使用 `openai-codex/gpt-5.5`,或配合 Codex 应用服务器 Codex harness 使用 `openai/gpt-5.5`。对于 `openai/gpt-5.5`,直接 API 密钥路由会在 OpenAI 为公共 API 启用 GPT-5.5 后支持;在此之前,请在 `OPENAI_API_KEY` 配置中使用已支持 API 的模型,例如 `openai/gpt-5.4`。
|
||||
|
||||
## 插件拥有的提供商行为
|
||||
## 插件自有的提供商行为
|
||||
|
||||
大多数提供商特定逻辑都位于提供商插件中(`registerProvider(...)`),而 OpenClaw 负责保留通用推理循环。插件负责新手引导、模型目录、认证环境变量映射、传输/配置规范化、工具模式清理、故障切换分类、OAuth 刷新、用量报告、思考/推理配置等。
|
||||
大多数提供商特定逻辑都位于提供商插件中(`registerProvider(...)`),而 OpenClaw 保留通用推理循环。插件负责新手引导、模型目录、认证环境变量映射、传输/配置归一化、工具模式清理、故障转移分类、OAuth 刷新、用量报告、thinking/reasoning 配置等。
|
||||
|
||||
提供商 SDK 钩子和内置插件示例的完整列表位于 [提供商插件](/zh-CN/plugins/sdk-provider-plugins)。如果某个提供商需要完全自定义的请求执行器,则属于另一个更深层的扩展接口。
|
||||
Provider SDK 钩子的完整列表以及内置插件示例位于[提供商插件](/zh-CN/plugins/sdk-provider-plugins)。如果某个提供商需要完全自定义的请求执行器,那是另一个更深层的扩展接口。
|
||||
|
||||
<Note>
|
||||
提供商运行时 `capabilities` 是共享的运行器元数据(提供商家族、转录/工具行为差异、传输/缓存提示)。它不同于[公共能力模型](/zh-CN/plugins/architecture#public-capability-model),后者描述的是一个插件注册了什么(文本推理、语音等)。
|
||||
提供商运行时 `capabilities` 是共享的运行器元数据(提供商家族、转录/工具行为差异、传输/缓存提示)。它与[公开能力模型](/zh-CN/plugins/architecture#public-capability-model)不同,后者描述的是插件注册了什么(文本推理、语音等)。
|
||||
</Note>
|
||||
|
||||
## API 密钥轮换
|
||||
|
||||
- 支持为选定提供商进行通用提供商密钥轮换。
|
||||
- 可通过以下方式配置多个密钥:
|
||||
- `OPENCLAW_LIVE_<PROVIDER>_KEY`(单个实时覆盖,最高优先级)
|
||||
- 支持对选定提供商进行通用提供商轮换。
|
||||
- 通过以下方式配置多个密钥:
|
||||
- `OPENCLAW_LIVE_<PROVIDER>_KEY`(单个实时覆盖,优先级最高)
|
||||
- `<PROVIDER>_API_KEYS`(逗号或分号分隔列表)
|
||||
- `<PROVIDER>_API_KEY`(主密钥)
|
||||
- `<PROVIDER>_API_KEY_*`(编号列表,例如 `<PROVIDER>_API_KEY_1`)
|
||||
- 对于 Google 提供商,`GOOGLE_API_KEY` 也会作为回退包含在内。
|
||||
- 密钥选择顺序会保留优先级并去重。
|
||||
- 仅在遇到速率限制响应时,才会使用下一个密钥重试请求(例如 `429`、`rate_limit`、`quota`、`resource exhausted`、`Too many concurrent requests`、`ThrottlingException`、`concurrency limit reached`、`workers_ai ... quota limit exceeded`,或周期性用量限制消息)。
|
||||
- 非速率限制失败会立即失败;不会尝试密钥轮换。
|
||||
- 当所有候选密钥都失败时,将返回最后一次尝试的最终错误。
|
||||
- 对于 Google 提供商,也会将 `GOOGLE_API_KEY` 作为回退项。
|
||||
- 密钥选择顺序会保留优先级并去重值。
|
||||
- 仅当收到限流响应时,才会使用下一个密钥重试请求(例如 `429`、`rate_limit`、`quota`、`resource exhausted`、`Too many concurrent requests`、`ThrottlingException`、`concurrency limit reached`、`workers_ai ... quota limit exceeded` 或周期性用量限制消息)。
|
||||
- 非限流失败会立即失败;不会尝试密钥轮换。
|
||||
- 当所有候选密钥都失败时,会返回最后一次尝试的最终错误。
|
||||
|
||||
## 内置提供商(pi-ai 目录)
|
||||
|
||||
@ -63,17 +63,17 @@ OpenClaw 内置了 pi‑ai 目录。这些提供商**不需要**
|
||||
- 认证:`OPENAI_API_KEY`
|
||||
- 可选轮换:`OPENAI_API_KEYS`、`OPENAI_API_KEY_1`、`OPENAI_API_KEY_2`,以及 `OPENCLAW_LIVE_OPENAI_KEY`(单个覆盖)
|
||||
- 示例模型:`openai/gpt-5.4`、`openai/gpt-5.4-mini`
|
||||
- 一旦 OpenAI 在 API 上开放 GPT-5.5,这里就已为 GPT-5.5 直连 API 支持做好准备
|
||||
- 一旦 OpenAI 在 API 中开放 GPT-5.5,这里就会为 GPT-5.5 直接 API 支持做好准备
|
||||
- CLI:`openclaw onboard --auth-choice openai-api-key`
|
||||
- 默认传输为 `auto`(优先 WebSocket,回退 SSE)
|
||||
- 可按模型通过 `agents.defaults.models["openai/<model>"].params.transport` 覆盖(`"sse"`、`"websocket"` 或 `"auto"`)
|
||||
- 可通过 `agents.defaults.models["openai/<model>"].params.transport` 按模型覆盖(`"sse"`、`"websocket"` 或 `"auto"`)
|
||||
- OpenAI Responses WebSocket 预热默认通过 `params.openaiWsWarmup` 启用(`true`/`false`)
|
||||
- 可通过 `agents.defaults.models["openai/<model>"].params.serviceTier` 启用 OpenAI 优先级处理
|
||||
- `/fast` 和 `params.fastMode` 会将直连 `openai/*` Responses 请求映射为 `api.openai.com` 上的 `service_tier=priority`
|
||||
- 当你希望显式指定层级而不是使用共享 `/fast` 开关时,请使用 `params.serviceTier`
|
||||
- 隐藏的 OpenClaw 归因请求头(`originator`、`version`、`User-Agent`)仅应用于发往 `api.openai.com` 的原生 OpenAI 流量,不适用于通用 OpenAI 兼容代理
|
||||
- 原生 OpenAI 路由还会保留 Responses `store`、提示缓存提示以及 OpenAI 推理兼容负载整形;代理路由则不会
|
||||
- `openai/gpt-5.3-codex-spark` 在 OpenClaw 中被有意屏蔽,因为实际 OpenAI API 请求会拒绝它,而当前 Codex 目录也未公开它
|
||||
- OpenAI 优先级处理可通过 `agents.defaults.models["openai/<model>"].params.serviceTier` 启用
|
||||
- `/fast` 和 `params.fastMode` 会将直接 `openai/*` Responses 请求映射为发往 `api.openai.com` 的 `service_tier=priority`
|
||||
- 当你想使用显式层级而不是共享的 `/fast` 开关时,请使用 `params.serviceTier`
|
||||
- 隐藏的 OpenClaw 归属标头(`originator`、`version`、`User-Agent`)仅适用于发往 `api.openai.com` 的原生 OpenAI 流量,不适用于通用 OpenAI 兼容代理
|
||||
- 原生 OpenAI 路由还会保留 Responses `store`、提示缓存提示以及 OpenAI reasoning 兼容的负载整形;代理路由不会
|
||||
- `openai/gpt-5.3-codex-spark` 在 OpenClaw 中被有意屏蔽,因为实时 OpenAI API 请求会拒绝它,而当前 Codex 目录也未暴露它
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -88,9 +88,9 @@ OpenClaw 内置了 pi‑ai 目录。这些提供商**不需要**
|
||||
- 可选轮换:`ANTHROPIC_API_KEYS`、`ANTHROPIC_API_KEY_1`、`ANTHROPIC_API_KEY_2`,以及 `OPENCLAW_LIVE_ANTHROPIC_KEY`(单个覆盖)
|
||||
- 示例模型:`anthropic/claude-opus-4-6`
|
||||
- CLI:`openclaw onboard --auth-choice apiKey`
|
||||
- 直连公开 Anthropic 请求支持共享 `/fast` 开关和 `params.fastMode`,包括发送到 `api.anthropic.com` 的 API 密钥和 OAuth 认证流量;OpenClaw 会将其映射为 Anthropic `service_tier`(`auto` 与 `standard_only`)
|
||||
- Anthropic 说明:Anthropic 员工告诉我们,OpenClaw 风格的 Claude CLI 用法再次被允许,因此除非 Anthropic 发布新政策,否则 OpenClaw 会将 Claude CLI 复用和 `claude -p` 用法视为此集成的认可方式。
|
||||
- Anthropic setup-token 仍然作为受支持的 OpenClaw token 路径可用,但 OpenClaw 现在在可用时更倾向于 Claude CLI 复用和 `claude -p`。
|
||||
- 直接公共 Anthropic 请求支持共享的 `/fast` 开关和 `params.fastMode`,包括发送到 `api.anthropic.com` 的 API 密钥和 OAuth 认证流量;OpenClaw 会将其映射为 Anthropic `service_tier`(`auto` 或 `standard_only`)
|
||||
- Anthropic 说明:Anthropic 员工告诉我们,OpenClaw 风格的 Claude CLI 用法再次被允许,因此除非 Anthropic 发布新政策,否则 OpenClaw 会将 Claude CLI 复用和 `claude -p` 用法视为此集成的许可方式。
|
||||
- Anthropic setup-token 仍然是 OpenClaw 支持的令牌路径,但 OpenClaw 现在在可用时优先使用 Claude CLI 复用和 `claude -p`。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -103,18 +103,18 @@ OpenClaw 内置了 pi‑ai 目录。这些提供商**不需要**
|
||||
- 提供商:`openai-codex`
|
||||
- 认证:OAuth(ChatGPT)
|
||||
- PI 模型引用:`openai-codex/gpt-5.5`
|
||||
- 原生 Codex 应用服务器 harness 引用:`openai/gpt-5.5`,并设置 `agents.defaults.embeddedHarness.runtime: "codex"`
|
||||
- 原生 Codex 应用服务器 Codex harness 引用:`openai/gpt-5.5`,并设置 `agents.defaults.embeddedHarness.runtime: "codex"`
|
||||
- 旧版模型引用:`codex/gpt-*`
|
||||
- 插件边界:`openai-codex/*` 会加载 OpenAI 插件;原生 Codex 应用服务器插件仅由 Codex harness 运行时或旧版 `codex/*` 引用选中。
|
||||
- 插件边界:`openai-codex/*` 会加载 OpenAI 插件;原生 Codex 应用服务器插件仅由 Codex harness 运行时或旧版 `codex/*` 引用选择。
|
||||
- CLI:`openclaw onboard --auth-choice openai-codex` 或 `openclaw models auth login --provider openai-codex`
|
||||
- 默认传输为 `auto`(优先 WebSocket,回退 SSE)
|
||||
- 可按 PI 模型通过 `agents.defaults.models["openai-codex/<model>"].params.transport` 覆盖(`"sse"`、`"websocket"` 或 `"auto"`)
|
||||
- `params.serviceTier` 也会在原生 Codex Responses 请求(`chatgpt.com/backend-api`)中向前传递
|
||||
- 隐藏的 OpenClaw 归因请求头(`originator`、`version`、`User-Agent`)仅附加在发往 `chatgpt.com/backend-api` 的原生 Codex 流量上,不适用于通用 OpenAI 兼容代理
|
||||
- 与直连 `openai/*` 共享相同的 `/fast` 开关和 `params.fastMode` 配置;OpenClaw 会将其映射为 `service_tier=priority`
|
||||
- `openai-codex/gpt-5.5` 保留原生 `contextWindow = 1000000`,默认运行时 `contextTokens = 272000`;可通过 `models.providers.openai-codex.models[].contextTokens` 覆盖运行时上限
|
||||
- 策略说明:OpenAI Codex OAuth 被明确支持用于 OpenClaw 这样的外部工具/工作流。
|
||||
- 在 OpenAI 于公共 API 上启用 GPT-5.5 之前,当前 GPT-5.5 访问将使用此 OAuth/订阅路由。
|
||||
- 可通过 `agents.defaults.models["openai-codex/<model>"].params.transport` 按 PI 模型覆盖(`"sse"`、`"websocket"` 或 `"auto"`)
|
||||
- `params.serviceTier` 也会转发到原生 Codex Responses 请求(`chatgpt.com/backend-api`)
|
||||
- 隐藏的 OpenClaw 归属标头(`originator`、`version`、`User-Agent`)仅附加到发往 `chatgpt.com/backend-api` 的原生 Codex 流量,不适用于通用 OpenAI 兼容代理
|
||||
- 与直接 `openai/*` 共享同一个 `/fast` 开关和 `params.fastMode` 配置;OpenClaw 会将其映射为 `service_tier=priority`
|
||||
- `openai-codex/gpt-5.5` 保留原生 `contextWindow = 1000000` 和默认运行时 `contextTokens = 272000`;可通过 `models.providers.openai-codex.models[].contextTokens` 覆盖运行时上限
|
||||
- 策略说明:OpenAI Codex OAuth 明确支持像 OpenClaw 这样的外部工具/工作流。
|
||||
- 当前的 GPT-5.5 访问使用此 OAuth/订阅路由,直到 OpenAI 在公共 API 中启用 GPT-5.5。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -136,7 +136,7 @@ OpenClaw 内置了 pi‑ai 目录。这些提供商**不需要**
|
||||
|
||||
### 其他订阅式托管选项
|
||||
|
||||
- [Qwen Cloud](/zh-CN/providers/qwen):Qwen Cloud 提供商接口,以及 Alibaba DashScope 和 Coding Plan 端点映射
|
||||
- [Qwen Cloud](/zh-CN/providers/qwen):Qwen Cloud 提供商接口,以及阿里巴巴 DashScope 和 Coding Plan 端点映射
|
||||
- [MiniMax](/zh-CN/providers/minimax):MiniMax Coding Plan OAuth 或 API 密钥访问
|
||||
- [GLM Models](/zh-CN/providers/glm):Z.AI Coding Plan 或通用 API 端点
|
||||
|
||||
@ -160,16 +160,18 @@ OpenClaw 内置了 pi‑ai 目录。这些提供商**不需要**
|
||||
- 认证:`GEMINI_API_KEY`
|
||||
- 可选轮换:`GEMINI_API_KEYS`、`GEMINI_API_KEY_1`、`GEMINI_API_KEY_2`、`GOOGLE_API_KEY` 回退,以及 `OPENCLAW_LIVE_GEMINI_KEY`(单个覆盖)
|
||||
- 示例模型:`google/gemini-3.1-pro-preview`、`google/gemini-3-flash-preview`
|
||||
- 兼容性:使用 `google/gemini-3.1-flash-preview` 的旧版 OpenClaw 配置会被规范化为 `google/gemini-3-flash-preview`
|
||||
- 兼容性:使用 `google/gemini-3.1-flash-preview` 的旧版 OpenClaw 配置会被归一化为 `google/gemini-3-flash-preview`
|
||||
- CLI:`openclaw onboard --auth-choice gemini-api-key`
|
||||
- 思考:`/think adaptive` 使用 Google 动态思考。Gemini 3/3.1 不包含固定的 `thinkingLevel`;Gemini 2.5 会发送 `thinkingBudget: -1`。
|
||||
- 直连 Gemini 运行还接受 `agents.defaults.models["google/<model>"].params.cachedContent`(或旧版 `cached_content`),以转发提供商原生 `cachedContents/...` 句柄;Gemini 缓存命中会显示为 OpenClaw `cacheRead`
|
||||
- Thinking:`/think adaptive` 使用 Google 动态 thinking。Gemini 3/3.1 不包含固定的 `thinkingLevel`;Gemini 2.5 会发送 `thinkingBudget: -1`。
|
||||
- 直接 Gemini 运行还支持 `agents.defaults.models["google/<model>"].params.cachedContent`
|
||||
(或旧版 `cached_content`),以转发提供商原生的
|
||||
`cachedContents/...` 句柄;Gemini 缓存命中会以 OpenClaw `cacheRead` 的形式显示
|
||||
|
||||
### Google Vertex 和 Gemini CLI
|
||||
|
||||
- 提供商:`google-vertex`、`google-gemini-cli`
|
||||
- 认证:Vertex 使用 gcloud ADC;Gemini CLI 使用其 OAuth 流程
|
||||
- 注意:OpenClaw 中的 Gemini CLI OAuth 是非官方集成。一些用户报告在使用第三方客户端后其 Google 账户受到限制。若你选择继续,请查看 Google 条款并使用非关键账户。
|
||||
- 注意:OpenClaw 中的 Gemini CLI OAuth 是非官方集成。部分用户报告称,在使用第三方客户端后,其 Google 账号受到限制。若你选择继续,请查看 Google 条款并使用非关键账号。
|
||||
- Gemini CLI OAuth 作为内置 `google` 插件的一部分提供。
|
||||
- 先安装 Gemini CLI:
|
||||
- `brew install gemini-cli`
|
||||
@ -177,9 +179,10 @@ OpenClaw 内置了 pi‑ai 目录。这些提供商**不需要**
|
||||
- 启用:`openclaw plugins enable google`
|
||||
- 登录:`openclaw models auth login --provider google-gemini-cli --set-default`
|
||||
- 默认模型:`google-gemini-cli/gemini-3-flash-preview`
|
||||
- 注意:你**不需要**将 client id 或 secret 粘贴到 `openclaw.json` 中。CLI 登录流程会将 token 存储在 Gateway 网关主机上的认证配置文件中。
|
||||
- 注意:你**不需要**把 client id 或 secret 粘贴到 `openclaw.json` 中。CLI 登录流程会将令牌存储在 Gateway 网关主机上的认证配置文件中。
|
||||
- 如果登录后请求失败,请在 Gateway 网关主机上设置 `GOOGLE_CLOUD_PROJECT` 或 `GOOGLE_CLOUD_PROJECT_ID`。
|
||||
- Gemini CLI JSON 回复会从 `response` 解析;用量会回退到 `stats`,其中 `stats.cached` 会被规范化为 OpenClaw `cacheRead`。
|
||||
- Gemini CLI JSON 回复会从 `response` 解析;用量会回退到
|
||||
`stats`,其中 `stats.cached` 会归一化为 OpenClaw `cacheRead`。
|
||||
|
||||
### Z.AI(GLM)
|
||||
|
||||
@ -187,7 +190,7 @@ OpenClaw 内置了 pi‑ai 目录。这些提供商**不需要**
|
||||
- 认证:`ZAI_API_KEY`
|
||||
- 示例模型:`zai/glm-5.1`
|
||||
- CLI:`openclaw onboard --auth-choice zai-api-key`
|
||||
- 别名:`z.ai/*` 和 `z-ai/*` 会规范化为 `zai/*`
|
||||
- 别名:`z.ai/*` 和 `z-ai/*` 会归一化为 `zai/*`
|
||||
- `zai-api-key` 会自动检测匹配的 Z.AI 端点;`zai-coding-global`、`zai-coding-cn`、`zai-global` 和 `zai-cn` 会强制使用特定接口
|
||||
|
||||
### Vercel AI Gateway
|
||||
@ -206,12 +209,12 @@ OpenClaw 内置了 pi‑ai 目录。这些提供商**不需要**
|
||||
- CLI:`openclaw onboard --auth-choice kilocode-api-key`
|
||||
- Base URL:`https://api.kilo.ai/api/gateway/`
|
||||
- 静态回退目录内置了 `kilocode/kilo/auto`;实时
|
||||
`https://api.kilo.ai/api/gateway/models` 发现还可以进一步扩展运行时
|
||||
`https://api.kilo.ai/api/gateway/models` 发现机制可以进一步扩展运行时
|
||||
目录。
|
||||
- `kilocode/kilo/auto` 背后的具体上游路由由 Kilo Gateway 网关负责,
|
||||
- `kilocode/kilo/auto` 背后的精确上游路由由 Kilo Gateway 拥有,
|
||||
并非在 OpenClaw 中硬编码。
|
||||
|
||||
设置详情请参阅 [/providers/kilocode](/zh-CN/providers/kilocode)。
|
||||
设置详情请参见 [/providers/kilocode](/zh-CN/providers/kilocode)。
|
||||
|
||||
### 其他内置提供商插件
|
||||
|
||||
@ -219,13 +222,13 @@ OpenClaw 内置了 pi‑ai 目录。这些提供商**不需要**
|
||||
| ----------------------- | -------------------------------- | ------------------------------------------------------------ | ----------------------------------------------- |
|
||||
| BytePlus(国际版) | `byteplus` / `byteplus-plan` | `BYTEPLUS_API_KEY` | `byteplus-plan/ark-code-latest` |
|
||||
| Cerebras | `cerebras` | `CEREBRAS_API_KEY` | `cerebras/zai-glm-4.7` |
|
||||
| Cloudflare AI Gateway 网关 | `cloudflare-ai-gateway` | `CLOUDFLARE_AI_GATEWAY_API_KEY` | — |
|
||||
| Cloudflare AI Gateway | `cloudflare-ai-gateway` | `CLOUDFLARE_AI_GATEWAY_API_KEY` | — |
|
||||
| DeepSeek | `deepseek` | `DEEPSEEK_API_KEY` | `deepseek/deepseek-v4-flash` |
|
||||
| GitHub Copilot | `github-copilot` | `COPILOT_GITHUB_TOKEN` / `GH_TOKEN` / `GITHUB_TOKEN` | — |
|
||||
| Groq | `groq` | `GROQ_API_KEY` | — |
|
||||
| Hugging Face Inference | `huggingface` | `HUGGINGFACE_HUB_TOKEN` 或 `HF_TOKEN` | `huggingface/deepseek-ai/DeepSeek-R1` |
|
||||
| Kilo Gateway 网关 | `kilocode` | `KILOCODE_API_KEY` | `kilocode/kilo/auto` |
|
||||
| Kimi Coding | `kimi` | `KIMI_API_KEY` 或 `KIMICODE_API_KEY` | `kimi/kimi-code` |
|
||||
| Hugging Face Inference | `huggingface` | `HUGGINGFACE_HUB_TOKEN` or `HF_TOKEN` | `huggingface/deepseek-ai/DeepSeek-R1` |
|
||||
| Kilo Gateway | `kilocode` | `KILOCODE_API_KEY` | `kilocode/kilo/auto` |
|
||||
| Kimi Coding | `kimi` | `KIMI_API_KEY` or `KIMICODE_API_KEY` | `kimi/kimi-code` |
|
||||
| MiniMax | `minimax` / `minimax-portal` | `MINIMAX_API_KEY` / `MINIMAX_OAUTH_TOKEN` | `minimax/MiniMax-M2.7` |
|
||||
| Mistral | `mistral` | `MISTRAL_API_KEY` | `mistral/mistral-large-latest` |
|
||||
| Moonshot | `moonshot` | `MOONSHOT_API_KEY` | `moonshot/kimi-k2.6` |
|
||||
@ -236,39 +239,40 @@ OpenClaw 内置了 pi‑ai 目录。这些提供商**不需要**
|
||||
| StepFun | `stepfun` / `stepfun-plan` | `STEPFUN_API_KEY` | `stepfun/step-3.5-flash` |
|
||||
| Together | `together` | `TOGETHER_API_KEY` | `together/moonshotai/Kimi-K2.5` |
|
||||
| Venice | `venice` | `VENICE_API_KEY` | — |
|
||||
| Vercel AI Gateway 网关 | `vercel-ai-gateway` | `AI_GATEWAY_API_KEY` | `vercel-ai-gateway/anthropic/claude-opus-4.6` |
|
||||
| Vercel AI Gateway | `vercel-ai-gateway` | `AI_GATEWAY_API_KEY` | `vercel-ai-gateway/anthropic/claude-opus-4.6` |
|
||||
| Volcano Engine(Doubao) | `volcengine` / `volcengine-plan` | `VOLCANO_ENGINE_API_KEY` | `volcengine-plan/ark-code-latest` |
|
||||
| xAI | `xai` | `XAI_API_KEY` | `xai/grok-4` |
|
||||
| Xiaomi | `xiaomi` | `XIAOMI_API_KEY` | `xiaomi/mimo-v2-flash` |
|
||||
|
||||
一些值得了解的特性:
|
||||
值得了解的一些特殊行为:
|
||||
|
||||
- **OpenRouter** 仅在已验证的 `openrouter.ai` 路由上应用其应用归因请求头和 Anthropic `cache_control` 标记。作为代理式 OpenAI 兼容路径,它会跳过仅限原生 OpenAI 的整形处理(`serviceTier`、Responses `store`、提示缓存提示、OpenAI 推理兼容性)。基于 Gemini 的引用仅保留代理 Gemini 思考签名清理。
|
||||
- **Kilo Gateway 网关** 中基于 Gemini 的引用遵循相同的代理 Gemini 清理路径;`kilocode/kilo/auto` 和其他不支持代理推理的引用会跳过代理推理注入。
|
||||
- **MiniMax** API 密钥新手引导会写入显式的纯文本 M2.7 聊天模型定义;图像理解仍保留在由插件负责的 `MiniMax-VL-01` 媒体提供商上。
|
||||
- **xAI** 使用 xAI Responses 路径。`/fast` 或 `params.fastMode: true` 会将 `grok-3`、`grok-3-mini`、`grok-4` 和 `grok-4-0709` 重写为它们的 `*-fast` 变体。`tool_stream` 默认开启;可通过 `agents.defaults.models["xai/<model>"].params.tool_stream=false` 禁用。
|
||||
- **Cerebras** GLM 模型使用 `zai-glm-4.7` / `zai-glm-4.6`;OpenAI 兼容 Base URL 是 `https://api.cerebras.ai/v1`。
|
||||
- **OpenRouter** 仅在已验证的 `openrouter.ai` 路由上应用其应用归属标头和 Anthropic `cache_control` 标记。作为代理风格的 OpenAI 兼容路径,它会跳过仅限原生 OpenAI 的负载整形(`serviceTier`、Responses `store`、提示缓存提示、OpenAI reasoning 兼容性)。基于 Gemini 的引用仅保留代理 Gemini 的 thought-signature 清理。
|
||||
- **Kilo Gateway** 中基于 Gemini 的引用遵循相同的代理 Gemini 清理路径;`kilocode/kilo/auto` 以及其他不支持代理 reasoning 的引用会跳过代理 reasoning 注入。
|
||||
- **MiniMax** API 密钥新手引导会写入显式的纯文本 M2.7 聊天模型定义;图像理解仍保留在由插件拥有的 `MiniMax-VL-01` 媒体提供商上。
|
||||
- **xAI** 使用 xAI Responses 路径。`/fast` 或 `params.fastMode: true` 会将 `grok-3`、`grok-3-mini`、`grok-4` 和 `grok-4-0709` 重写为它们对应的 `*-fast` 变体。`tool_stream` 默认开启;可通过 `agents.defaults.models["xai/<model>"].params.tool_stream=false` 禁用。
|
||||
- **Cerebras** GLM 模型使用 `zai-glm-4.7` / `zai-glm-4.6`;OpenAI 兼容 Base URL 为 `https://api.cerebras.ai/v1`。
|
||||
|
||||
## 通过 `models.providers` 配置的提供商(自定义/Base URL)
|
||||
|
||||
使用 `models.providers`(或 `models.json`)来添加**自定义**提供商或
|
||||
OpenAI/Anthropic 兼容代理。
|
||||
|
||||
下方许多内置提供商插件已经发布了默认目录。
|
||||
只有当你想覆盖默认 Base URL、请求头或模型列表时,才需要使用显式
|
||||
`models.providers.<id>` 条目。
|
||||
下面的许多内置提供商插件已经发布了默认目录。
|
||||
只有当你想覆盖默认 Base URL、标头或模型列表时,
|
||||
才需要使用显式的 `models.providers.<id>` 条目。
|
||||
|
||||
### Moonshot AI(Kimi)
|
||||
|
||||
Moonshot 作为内置提供商插件提供。默认情况下请使用内置提供商,
|
||||
仅当你需要覆盖 Base URL 或模型元数据时,才添加显式的 `models.providers.moonshot` 条目:
|
||||
仅当你需要覆盖 Base URL 或模型元数据时,
|
||||
才添加显式的 `models.providers.moonshot` 条目:
|
||||
|
||||
- 提供商:`moonshot`
|
||||
- 认证:`MOONSHOT_API_KEY`
|
||||
- 示例模型:`moonshot/kimi-k2.6`
|
||||
- CLI:`openclaw onboard --auth-choice moonshot-api-key` 或 `openclaw onboard --auth-choice moonshot-api-key-cn`
|
||||
|
||||
Kimi K2 模型 Id:
|
||||
Kimi K2 模型 ID:
|
||||
|
||||
[//]: # "moonshot-kimi-k2-model-refs:start"
|
||||
|
||||
@ -316,13 +320,13 @@ Kimi Coding 使用 Moonshot AI 的 Anthropic 兼容端点:
|
||||
}
|
||||
```
|
||||
|
||||
旧版 `kimi/k2p5` 仍然作为兼容模型 Id 被接受。
|
||||
旧版 `kimi/k2p5` 仍然作为兼容模型 ID 被接受。
|
||||
|
||||
### Volcano Engine(Doubao)
|
||||
|
||||
Volcano Engine(火山引擎)提供对中国区 Doubao 和其他模型的访问。
|
||||
Volcano Engine(火山引擎)在中国提供对 Doubao 及其他模型的访问。
|
||||
|
||||
- 提供商:`volcengine`(编程方案:`volcengine-plan`)
|
||||
- 提供商:`volcengine`(编码接口:`volcengine-plan`)
|
||||
- 认证:`VOLCANO_ENGINE_API_KEY`
|
||||
- 示例模型:`volcengine-plan/ark-code-latest`
|
||||
- CLI:`openclaw onboard --auth-choice volcengine-api-key`
|
||||
@ -335,12 +339,13 @@ Volcano Engine(火山引擎)提供对中国区 Doubao 和其他模型的访
|
||||
}
|
||||
```
|
||||
|
||||
新手引导默认使用编程接口,但通用 `volcengine/*`
|
||||
新手引导默认使用编码接口,但通用 `volcengine/*`
|
||||
目录也会同时注册。
|
||||
|
||||
在新手引导/配置模型选择器中,Volcengine 认证选项会优先显示
|
||||
`volcengine/*` 和 `volcengine-plan/*` 两类条目。如果这些模型尚未加载,
|
||||
OpenClaw 会回退到未过滤的目录,而不是显示一个空的按提供商范围筛选的选择器。
|
||||
OpenClaw 会回退到未过滤的目录,而不是显示一个空的
|
||||
提供商范围选择器。
|
||||
|
||||
可用模型:
|
||||
|
||||
@ -350,7 +355,7 @@ OpenClaw 会回退到未过滤的目录,而不是显示一个空的按提供
|
||||
- `volcengine/glm-4-7-251222`(GLM 4.7)
|
||||
- `volcengine/deepseek-v3-2-251201`(DeepSeek V3.2 128K)
|
||||
|
||||
编程模型(`volcengine-plan`):
|
||||
编码模型(`volcengine-plan`):
|
||||
|
||||
- `volcengine-plan/ark-code-latest`
|
||||
- `volcengine-plan/doubao-seed-code`
|
||||
@ -360,9 +365,9 @@ OpenClaw 会回退到未过滤的目录,而不是显示一个空的按提供
|
||||
|
||||
### BytePlus(国际版)
|
||||
|
||||
BytePlus ARK 为国际用户提供与 Volcano Engine 相同模型的访问能力。
|
||||
BytePlus ARK 为国际用户提供与 Volcano Engine 相同模型的访问。
|
||||
|
||||
- 提供商:`byteplus`(编程方案:`byteplus-plan`)
|
||||
- 提供商:`byteplus`(编码接口:`byteplus-plan`)
|
||||
- 认证:`BYTEPLUS_API_KEY`
|
||||
- 示例模型:`byteplus-plan/ark-code-latest`
|
||||
- CLI:`openclaw onboard --auth-choice byteplus-api-key`
|
||||
@ -375,12 +380,13 @@ BytePlus ARK 为国际用户提供与 Volcano Engine 相同模型的访问能力
|
||||
}
|
||||
```
|
||||
|
||||
新手引导默认使用编程接口,但通用 `byteplus/*`
|
||||
新手引导默认使用编码接口,但通用 `byteplus/*`
|
||||
目录也会同时注册。
|
||||
|
||||
在新手引导/配置模型选择器中,BytePlus 认证选项会优先显示
|
||||
`byteplus/*` 和 `byteplus-plan/*` 两类条目。如果这些模型尚未加载,
|
||||
OpenClaw 会回退到未过滤的目录,而不是显示一个空的按提供商范围筛选的选择器。
|
||||
OpenClaw 会回退到未过滤的目录,而不是显示一个空的
|
||||
提供商范围选择器。
|
||||
|
||||
可用模型:
|
||||
|
||||
@ -388,7 +394,7 @@ OpenClaw 会回退到未过滤的目录,而不是显示一个空的按提供
|
||||
- `byteplus/kimi-k2-5-260127`(Kimi K2.5)
|
||||
- `byteplus/glm-4-7-251222`(GLM 4.7)
|
||||
|
||||
编程模型(`byteplus-plan`):
|
||||
编码模型(`byteplus-plan`):
|
||||
|
||||
- `byteplus-plan/ark-code-latest`
|
||||
- `byteplus-plan/doubao-seed-code`
|
||||
@ -428,25 +434,25 @@ Synthetic 通过 `synthetic` 提供商提供 Anthropic 兼容模型:
|
||||
|
||||
MiniMax 通过 `models.providers` 配置,因为它使用自定义端点:
|
||||
|
||||
- MiniMax OAuth(全球):`--auth-choice minimax-global-oauth`
|
||||
- MiniMax OAuth(中国区):`--auth-choice minimax-cn-oauth`
|
||||
- MiniMax API 密钥(全球):`--auth-choice minimax-global-api`
|
||||
- MiniMax API 密钥(中国区):`--auth-choice minimax-cn-api`
|
||||
- MiniMax OAuth(Global):`--auth-choice minimax-global-oauth`
|
||||
- MiniMax OAuth(CN):`--auth-choice minimax-cn-oauth`
|
||||
- MiniMax API 密钥(Global):`--auth-choice minimax-global-api`
|
||||
- MiniMax API 密钥(CN):`--auth-choice minimax-cn-api`
|
||||
- 认证:`minimax` 使用 `MINIMAX_API_KEY`;`minimax-portal` 使用 `MINIMAX_OAUTH_TOKEN` 或
|
||||
`MINIMAX_API_KEY`
|
||||
|
||||
设置详情、模型选项和配置片段请参阅 [/providers/minimax](/zh-CN/providers/minimax)。
|
||||
设置详情、模型选项和配置片段请参见 [/providers/minimax](/zh-CN/providers/minimax)。
|
||||
|
||||
在 MiniMax 的 Anthropic 兼容流式传输路径上,OpenClaw 默认会禁用思考,
|
||||
除非你显式设置它;而 `/fast on` 会将
|
||||
在 MiniMax 的 Anthropic 兼容流式传输路径上,OpenClaw 默认会禁用 thinking,
|
||||
除非你显式设置它,并且 `/fast on` 会将
|
||||
`MiniMax-M2.7` 重写为 `MiniMax-M2.7-highspeed`。
|
||||
|
||||
插件拥有的能力划分:
|
||||
插件自有的能力拆分:
|
||||
|
||||
- 文本/聊天默认保持在 `minimax/MiniMax-M2.7`
|
||||
- 文本/聊天默认保留在 `minimax/MiniMax-M2.7`
|
||||
- 图像生成使用 `minimax/image-01` 或 `minimax-portal/image-01`
|
||||
- 图像理解在两种 MiniMax 认证路径上都使用由插件负责的 `MiniMax-VL-01`
|
||||
- Web 搜索仍使用提供商 Id `minimax`
|
||||
- 图像理解在两种 MiniMax 认证路径上都使用插件自有的 `MiniMax-VL-01`
|
||||
- Web 搜索保留在提供商 id `minimax`
|
||||
|
||||
### LM Studio
|
||||
|
||||
@ -456,7 +462,7 @@ LM Studio 作为内置提供商插件提供,并使用原生 API:
|
||||
- 认证:`LM_API_TOKEN`
|
||||
- 默认推理 Base URL:`http://localhost:1234/v1`
|
||||
|
||||
然后设置一个模型(替换为 `http://localhost:1234/api/v1/models` 返回的某个 Id):
|
||||
然后设置一个模型(替换为 `http://localhost:1234/api/v1/models` 返回的某个 ID):
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -467,15 +473,15 @@ LM Studio 作为内置提供商插件提供,并使用原生 API:
|
||||
```
|
||||
|
||||
OpenClaw 使用 LM Studio 原生的 `/api/v1/models` 和 `/api/v1/models/load`
|
||||
进行发现 + 自动加载,默认使用 `/v1/chat/completions` 进行推理。
|
||||
设置和故障排除请参阅 [/providers/lmstudio](/zh-CN/providers/lmstudio)。
|
||||
进行发现 + 自动加载,并默认使用 `/v1/chat/completions` 进行推理。
|
||||
设置和故障排除请参见 [/providers/lmstudio](/zh-CN/providers/lmstudio)。
|
||||
|
||||
### Ollama
|
||||
|
||||
Ollama 作为内置提供商插件提供,并使用 Ollama 的原生 API:
|
||||
|
||||
- 提供商:`ollama`
|
||||
- 认证:不需要(本地服务器)
|
||||
- 认证:无需(本地服务器)
|
||||
- 示例模型:`ollama/llama3.3`
|
||||
- 安装:[https://ollama.com/download](https://ollama.com/download)
|
||||
|
||||
@ -492,9 +498,9 @@ ollama pull llama3.3
|
||||
}
|
||||
```
|
||||
|
||||
当你通过 `OLLAMA_API_KEY` 选择启用时,系统会在本地 `http://127.0.0.1:11434`
|
||||
检测 Ollama,内置提供商插件也会将 Ollama 直接添加到
|
||||
`openclaw onboard` 和模型选择器中。有关新手引导、云端/本地模式和自定义配置,请参阅 [/providers/ollama](/zh-CN/providers/ollama)。
|
||||
当你通过 `OLLAMA_API_KEY` 选择启用时,Ollama 会在本地
|
||||
`http://127.0.0.1:11434` 被检测到,并且内置提供商插件会将 Ollama 直接加入
|
||||
`openclaw onboard` 和模型选择器。有关新手引导、云端/本地模式以及自定义配置,请参见 [/providers/ollama](/zh-CN/providers/ollama)。
|
||||
|
||||
### vLLM
|
||||
|
||||
@ -511,7 +517,7 @@ vLLM 作为内置提供商插件提供,用于本地/自托管的 OpenAI 兼容
|
||||
export VLLM_API_KEY="vllm-local"
|
||||
```
|
||||
|
||||
然后设置一个模型(替换为 `/v1/models` 返回的某个 Id):
|
||||
然后设置一个模型(替换为 `/v1/models` 返回的某个 ID):
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -521,7 +527,7 @@ export VLLM_API_KEY="vllm-local"
|
||||
}
|
||||
```
|
||||
|
||||
详情请参阅 [/providers/vllm](/zh-CN/providers/vllm)。
|
||||
详情请参见 [/providers/vllm](/zh-CN/providers/vllm)。
|
||||
|
||||
### SGLang
|
||||
|
||||
@ -539,7 +545,7 @@ OpenAI 兼容服务器:
|
||||
export SGLANG_API_KEY="sglang-local"
|
||||
```
|
||||
|
||||
然后设置一个模型(替换为 `/v1/models` 返回的某个 Id):
|
||||
然后设置一个模型(替换为 `/v1/models` 返回的某个 ID):
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -549,7 +555,7 @@ export SGLANG_API_KEY="sglang-local"
|
||||
}
|
||||
```
|
||||
|
||||
详情请参阅 [/providers/sglang](/zh-CN/providers/sglang)。
|
||||
详情请参见 [/providers/sglang](/zh-CN/providers/sglang)。
|
||||
|
||||
### 本地代理(LM Studio、vLLM、LiteLLM 等)
|
||||
|
||||
@ -595,11 +601,17 @@ export SGLANG_API_KEY="sglang-local"
|
||||
- `cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }`
|
||||
- `contextWindow: 200000`
|
||||
- `maxTokens: 8192`
|
||||
- 建议:设置与你的代理/模型限制相匹配的显式值。
|
||||
- 对于非原生端点上的 `api: "openai-completions"`(任何主机不是 `api.openai.com` 的非空 `baseUrl`),OpenClaw 会强制设定 `compat.supportsDeveloperRole: false`,以避免提供商因不支持 `developer` 角色而返回 400 错误。
|
||||
- 代理式 OpenAI 兼容路由也会跳过仅限原生 OpenAI 的请求整形:没有 `service_tier`、没有 Responses `store`、没有提示缓存提示、没有 OpenAI 推理兼容负载整形,也没有隐藏的 OpenClaw 归因请求头。
|
||||
- 如果 `baseUrl` 为空或省略,OpenClaw 会保留默认 OpenAI 行为(即解析到 `api.openai.com`)。
|
||||
- 为了安全起见,在非原生 `openai-completions` 端点上,即使显式设置了 `compat.supportsDeveloperRole: true`,也仍会被覆盖。
|
||||
- 推荐:设置与你的代理/模型限制相匹配的显式值。
|
||||
- 对于非原生端点上的 `api: "openai-completions"`(任何非空的 `baseUrl` 且其主机不是 `api.openai.com`),OpenClaw 会强制 `compat.supportsDeveloperRole: false`,以避免提供商因不支持 `developer` 角色而返回 400 错误。
|
||||
- 代理风格的 OpenAI 兼容路由也会跳过仅限原生 OpenAI 的请求整形:
|
||||
不使用 `service_tier`,不使用 Responses `store`,不使用 Completions `store`,
|
||||
不使用提示缓存提示,不使用 OpenAI reasoning 兼容负载整形,也不使用隐藏的
|
||||
OpenClaw 归属标头。
|
||||
- 对于需要供应商特定字段的 OpenAI 兼容 Completions 代理,
|
||||
请设置 `agents.defaults.models["provider/model"].params.extra_body`(或
|
||||
`extraBody`),以将额外 JSON 合并到出站请求体中。
|
||||
- 如果 `baseUrl` 为空/省略,OpenClaw 会保留默认 OpenAI 行为(即解析为 `api.openai.com`)。
|
||||
- 出于安全考虑,在非原生 `openai-completions` 端点上,显式设置的 `compat.supportsDeveloperRole: true` 仍会被覆盖。
|
||||
|
||||
## CLI 示例
|
||||
|
||||
@ -609,11 +621,11 @@ openclaw models set opencode/claude-opus-4-6
|
||||
openclaw models list
|
||||
```
|
||||
|
||||
另请参阅:[/gateway/configuration](/zh-CN/gateway/configuration) 获取完整配置示例。
|
||||
另请参见:[/gateway/configuration](/zh-CN/gateway/configuration),了解完整配置示例。
|
||||
|
||||
## 相关内容
|
||||
|
||||
- [模型](/zh-CN/concepts/models) — 模型配置和别名
|
||||
- [模型故障切换](/zh-CN/concepts/model-failover) — 回退链和重试行为
|
||||
- [Models](/zh-CN/concepts/models) — 模型配置和别名
|
||||
- [模型故障转移](/zh-CN/concepts/model-failover) — 回退链和重试行为
|
||||
- [配置参考](/zh-CN/gateway/config-agents#agent-defaults) — 模型配置键
|
||||
- [提供商](/zh-CN/providers) — 按提供商分类的设置指南
|
||||
- [提供商](/zh-CN/providers) — 按提供商划分的设置指南
|
||||
|
||||
@ -1,109 +1,110 @@
|
||||
---
|
||||
read_when:
|
||||
- 解释流式传输或分块处理在渠道中的工作方式
|
||||
- 更改分块流式传输或渠道分块行为
|
||||
- 更改分块流式传输或渠道分块处理行为
|
||||
- 调试重复或过早的分块回复,或渠道预览流式传输
|
||||
summary: 流式传输 + 分块行为(分块回复、渠道预览流式传输、模式映射)
|
||||
summary: 流式传输 + 分块处理行为(分块回复、渠道预览流式传输、模式映射)
|
||||
title: 流式传输和分块处理
|
||||
x-i18n:
|
||||
generated_at: "2026-04-24T22:37:20Z"
|
||||
generated_at: "2026-04-25T02:35:34Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: 544dba171876870ba2608e43bdd9b7a66f446628e18f1c19e72bf491c1d18f6b
|
||||
source_hash: 304583beac6f052573e10a633f835db2527d4e83de19dc4a38207fb8c52ee973
|
||||
source_path: concepts/streaming.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
# 流式传输 + 分块处理
|
||||
|
||||
OpenClaw 有两个独立的流式传输层:
|
||||
OpenClaw 有两个彼此独立的流式传输层:
|
||||
|
||||
- **分块流式传输(渠道):** 在助手写作时,将已完成的 **块** 发出。这些是正常的渠道消息(不是 token 增量)。
|
||||
- **预览流式传输(Telegram/Discord/Slack):** 在生成过程中更新临时的**预览消息**。
|
||||
- **分块流式传输(渠道):** 在助手写出完整的 **块** 时立即发送。这些是普通的渠道消息(不是 token 增量)。
|
||||
- **预览流式传输(Telegram/Discord/Slack):** 在生成过程中更新一条临时的 **预览消息**。
|
||||
|
||||
目前,渠道消息**没有真正的 token 增量流式传输**。预览流式传输是基于消息的(发送 + 编辑/追加)。
|
||||
目前,渠道消息**不支持真正的 token 增量流式传输**。预览流式传输是基于消息的(发送 + 编辑/追加)。
|
||||
|
||||
## 分块流式传输(渠道消息)
|
||||
|
||||
分块流式传输会在助手输出可用时,以较粗粒度的分块发送。
|
||||
分块流式传输会在助手输出可用时,以较粗粒度的块发送内容。
|
||||
|
||||
```
|
||||
模型输出
|
||||
Model output
|
||||
└─ text_delta/events
|
||||
├─ (blockStreamingBreak=text_end)
|
||||
│ └─ chunker 随缓冲区增长发出块
|
||||
│ └─ chunker emits blocks as buffer grows
|
||||
└─ (blockStreamingBreak=message_end)
|
||||
└─ chunker 在 message_end 时刷新
|
||||
└─ 渠道发送(分块回复)
|
||||
└─ chunker flushes at message_end
|
||||
└─ channel send (block replies)
|
||||
```
|
||||
|
||||
图例:
|
||||
|
||||
- `text_delta/events`:模型流事件(对于非流式传输模型,可能较少)。
|
||||
- `chunker`:应用最小/最大边界和断点偏好的 `EmbeddedBlockChunker`。
|
||||
- `channel send`:实际发出的出站消息(分块回复)。
|
||||
- `text_delta/events`:模型流事件(对于非流式模型,这些事件可能很少)。
|
||||
- `chunker`:`EmbeddedBlockChunker`,应用最小/最大边界以及断点偏好。
|
||||
- `channel send`:实际发出的消息(分块回复)。
|
||||
|
||||
**控制项:**
|
||||
|
||||
- `agents.defaults.blockStreamingDefault`:`"on"`/`"off"`(默认关闭)。
|
||||
- 渠道覆盖:`*.blockStreaming`(以及每账号变体),可按渠道强制设为 `"on"`/`"off"`。
|
||||
- 渠道覆盖:`*.blockStreaming`(以及按账号划分的变体),用于在每个渠道上强制设为 `"on"`/`"off"`。
|
||||
- `agents.defaults.blockStreamingBreak`:`"text_end"` 或 `"message_end"`。
|
||||
- `agents.defaults.blockStreamingChunk`:`{ minChars, maxChars, breakPreference? }`。
|
||||
- `agents.defaults.blockStreamingCoalesce`:`{ minChars?, maxChars?, idleMs? }`(在发送前合并已流式传输的块)。
|
||||
- `agents.defaults.blockStreamingCoalesce`:`{ minChars?, maxChars?, idleMs? }`(发送前合并流式块)。
|
||||
- 渠道硬上限:`*.textChunkLimit`(例如 `channels.whatsapp.textChunkLimit`)。
|
||||
- 渠道分块模式:`*.chunkMode`(默认 `length`,`newline` 会先按空行即段落边界拆分,再按长度分块)。
|
||||
- Discord 软上限:`channels.discord.maxLinesPerMessage`(默认 17),会拆分过高的回复以避免 UI 裁剪。
|
||||
- 渠道分块模式:`*.chunkMode`(默认 `length`;`newline` 会先按空行,即段落边界拆分,再按长度分块)。
|
||||
- Discord 软上限:`channels.discord.maxLinesPerMessage`(默认 17),用于拆分过高的回复以避免 UI 裁剪。
|
||||
|
||||
**边界语义:**
|
||||
|
||||
- `text_end`:一旦 chunker 发出块就立即流式传输;在每个 `text_end` 时刷新。
|
||||
- `text_end`:只要 chunker 产生块,就立即流式发送;并在每个 `text_end` 时刷新。
|
||||
- `message_end`:等待助手消息完成后,再刷新缓冲输出。
|
||||
|
||||
如果缓冲文本超过 `maxChars`,`message_end` 仍会使用 chunker,因此它可能在结尾发出多个分块。
|
||||
即使使用 `message_end`,如果缓冲文本超过 `maxChars`,仍然会使用 chunker,因此可能会在末尾发送多个分块。
|
||||
|
||||
## 分块算法(低/高边界)
|
||||
|
||||
分块处理由 `EmbeddedBlockChunker` 实现:
|
||||
|
||||
- **低边界:** 在缓冲区达到 `minChars` 之前不发出(除非被强制发出)。
|
||||
- **高边界:** 优先在 `maxChars` 之前切分;如果必须强制切分,则在 `maxChars` 处切分。
|
||||
- **断点偏好:** `paragraph` → `newline` → `sentence` → `whitespace` → 硬切分。
|
||||
- **代码围栏:** 绝不在围栏内部切分;如果被迫在 `maxChars` 处切分,则会关闭并重新打开围栏,以保持 Markdown 有效。
|
||||
- **低边界:** 在缓冲区达到 `minChars` 之前不发送(除非被强制发送)。
|
||||
- **高边界:** 优先在 `maxChars` 之前拆分;如果必须强制拆分,则在 `maxChars` 处拆分。
|
||||
- **断点偏好:** `paragraph` → `newline` → `sentence` → `whitespace` → 硬拆分。
|
||||
- **代码围栏:** 绝不在围栏内部拆分;如果必须在 `maxChars` 处强制拆分,会先闭合再重新打开围栏,以保持 Markdown 有效。
|
||||
|
||||
`maxChars` 会被限制到渠道的 `textChunkLimit`,因此你不能超过每个渠道的上限。
|
||||
`maxChars` 会被限制到渠道的 `textChunkLimit`,因此不能超过每个渠道的上限。
|
||||
|
||||
## 合并处理(合并已流式传输的块)
|
||||
## 聚合(合并流式块)
|
||||
|
||||
启用分块流式传输时,OpenClaw 可以在发送前**合并连续的分块**。这样可以减少“单行刷屏”,同时仍然提供渐进式输出。
|
||||
启用分块流式传输时,OpenClaw 可以在发送前**合并连续的分块**。
|
||||
这样既能提供渐进式输出,又能减少“单行刷屏”。
|
||||
|
||||
- 合并会等待**空闲间隔**(`idleMs`)后再刷新。
|
||||
- 缓冲区受 `maxChars` 限制,超过时会刷新。
|
||||
- `minChars` 会阻止发送过小的片段,直到积累了足够的文本(最终刷新始终会发送剩余文本)。
|
||||
- 连接符由 `blockStreamingChunk.breakPreference` 派生而来(`paragraph` → `\n\n`,`newline` → `\n`,`sentence` → 空格)。
|
||||
- 可通过 `*.blockStreamingCoalesce` 使用渠道覆盖(包括每账号配置)。
|
||||
- 除非被覆盖,Signal/Slack/Discord 的默认合并 `minChars` 会提高到 1500。
|
||||
- 聚合会等待**空闲间隔**(`idleMs`)后再刷新。
|
||||
- 缓冲区受 `maxChars` 限制,超出时会立即刷新。
|
||||
- `minChars` 可防止过小的片段过早发送,直到累积足够文本(最终刷新总会发送剩余文本)。
|
||||
- 连接符由 `blockStreamingChunk.breakPreference` 决定(`paragraph` → `\n\n`,`newline` → `\n`,`sentence` → 空格)。
|
||||
- 可通过 `*.blockStreamingCoalesce` 进行渠道级覆盖(包括按账号配置)。
|
||||
- 对于 Signal/Slack/Discord,默认的聚合 `minChars` 会提升到 1500,除非已显式覆盖。
|
||||
|
||||
## 分块之间更像人类的节奏
|
||||
## 块之间更像人类的节奏延迟
|
||||
|
||||
启用分块流式传输时,你可以在分块回复之间添加**随机暂停**(首个分块之后)。这会让多气泡回复感觉更自然。
|
||||
启用分块流式传输后,你可以在分块回复之间加入**随机暂停**(第一个块之后)。
|
||||
这样,多气泡回复会显得更自然。
|
||||
|
||||
- 配置:`agents.defaults.humanDelay`(可通过 `agents.list[].humanDelay` 按智能体覆盖)。
|
||||
- 模式:`off`(默认)、`natural`(800–2500 ms)、`custom`(`minMs`/`maxMs`)。
|
||||
- 仅适用于**分块回复**,不适用于最终回复或工具摘要。
|
||||
- 模式:`off`(默认)、`natural`(800–2500ms)、`custom`(`minMs`/`maxMs`)。
|
||||
- 仅作用于**分块回复**,不作用于最终回复或工具摘要。
|
||||
|
||||
## “流式发送分块还是一次性全部发送”
|
||||
## “流式发送分块”还是“一次性发送全部”
|
||||
|
||||
这对应于:
|
||||
|
||||
- **流式发送分块:** `blockStreamingDefault: "on"` + `blockStreamingBreak: "text_end"`(边生成边发出)。非 Telegram 渠道还需要 `*.blockStreaming: true`。
|
||||
- **在末尾一次性流式发送全部内容:** `blockStreamingBreak: "message_end"`(刷新一次;如果内容很长,可能仍会分成多个分块)。
|
||||
- **无分块流式传输:** `blockStreamingDefault: "off"`(仅发送最终回复)。
|
||||
- **流式发送分块:** `blockStreamingDefault: "on"` + `blockStreamingBreak: "text_end"`(边生成边发送)。非 Telegram 渠道还需要设置 `*.blockStreaming: true`。
|
||||
- **在末尾一次性流式发送全部:** `blockStreamingBreak: "message_end"`(只在结束时刷新一次;如果内容很长,可能仍会拆成多个分块)。
|
||||
- **不使用分块流式传输:** `blockStreamingDefault: "off"`(只发送最终回复)。
|
||||
|
||||
**渠道说明:** 只有在显式设置
|
||||
`*.blockStreaming` 为 `true` 时,分块流式传输才会启用。渠道可以在没有分块回复的情况下流式传输实时预览
|
||||
(`channels.<channel>.streaming`)。
|
||||
**渠道说明:** 分块流式传输默认**关闭,除非**
|
||||
显式将 `*.blockStreaming` 设为 `true`。渠道仍然可以通过 `channels.<channel>.streaming` 发送实时预览,而不发送分块回复。
|
||||
|
||||
配置位置提醒:`blockStreaming*` 默认值位于 `agents.defaults` 下,而不是根配置下。
|
||||
配置位置提醒:`blockStreaming*` 默认项位于 `agents.defaults` 下,而不是根配置。
|
||||
|
||||
## 预览流式传输模式
|
||||
|
||||
@ -112,25 +113,25 @@ OpenClaw 有两个独立的流式传输层:
|
||||
模式:
|
||||
|
||||
- `off`:禁用预览流式传输。
|
||||
- `partial`:单个预览,用最新文本替换。
|
||||
- `partial`:单条预览消息,用最新文本替换其内容。
|
||||
- `block`:以分块/追加的方式更新预览。
|
||||
- `progress`:在生成期间显示进度/状态预览,完成时发送最终答案。
|
||||
- `progress`:在生成期间显示进度/状态预览,完成后发送最终答案。
|
||||
|
||||
### 渠道映射
|
||||
|
||||
| 渠道 | `off` | `partial` | `block` | `progress` |
|
||||
| ---------- | ----- | --------- | ------- | ----------------- |
|
||||
| Telegram | ✅ | ✅ | ✅ | 映射为 `partial` |
|
||||
| Discord | ✅ | ✅ | ✅ | 映射为 `partial` |
|
||||
| Slack | ✅ | ✅ | ✅ | ✅ |
|
||||
| Telegram | ✅ | ✅ | ✅ | 映射为 `partial` |
|
||||
| Discord | ✅ | ✅ | ✅ | 映射为 `partial` |
|
||||
| Slack | ✅ | ✅ | ✅ | ✅ |
|
||||
| Mattermost | ✅ | ✅ | ✅ | ✅ |
|
||||
|
||||
仅限 Slack:
|
||||
仅适用于 Slack:
|
||||
|
||||
- 当 `channels.slack.streaming.mode="partial"` 时,`channels.slack.streaming.nativeTransport` 会切换 Slack 原生流式传输 API 调用(默认:`true`)。
|
||||
- Slack 原生流式传输和 Slack 助手线程状态都需要回复线程目标;顶层私信不会显示该类线程式预览。
|
||||
- `channels.slack.streaming.nativeTransport` 在 `channels.slack.streaming.mode="partial"` 时切换是否使用 Slack 原生流式 API 调用(默认:`true`)。
|
||||
- Slack 原生流式传输和 Slack 助手线程状态都需要一个回复线程目标;顶层私信不会显示这种线程式预览。
|
||||
|
||||
旧版键迁移:
|
||||
旧键迁移:
|
||||
|
||||
- Telegram:`streamMode` 和布尔值 `streaming` 会自动迁移为 `streaming` 枚举。
|
||||
- Discord:`streamMode` 和布尔值 `streaming` 会自动迁移为 `streaming` 枚举。
|
||||
@ -140,7 +141,7 @@ OpenClaw 有两个独立的流式传输层:
|
||||
|
||||
Telegram:
|
||||
|
||||
- 在私信和群组/话题中,使用 `sendMessage` + `editMessageText` 更新预览。
|
||||
- 在私信、群组和话题中,使用 `sendMessage` + `editMessageText` 更新预览。
|
||||
- 当 Telegram 分块流式传输被显式启用时,会跳过预览流式传输(以避免双重流式传输)。
|
||||
- `/reasoning stream` 可以将推理内容写入预览。
|
||||
|
||||
@ -149,39 +150,40 @@ Discord:
|
||||
- 使用发送 + 编辑预览消息。
|
||||
- `block` 模式使用草稿分块(`draftChunk`)。
|
||||
- 当 Discord 分块流式传输被显式启用时,会跳过预览流式传输。
|
||||
- 最终媒体、错误和显式回复载荷会取消待处理的预览,而不会刷新新的草稿,然后使用正常投递。
|
||||
- 最终媒体、错误以及显式回复载荷会取消待处理的预览,而不会刷新出新的草稿,然后再使用正常投递。
|
||||
|
||||
Slack:
|
||||
|
||||
- `partial` 在可用时可使用 Slack 原生流式传输(`chat.startStream`/`append`/`stop`)。
|
||||
- `partial` 在可用时可以使用 Slack 原生流式传输(`chat.startStream`/`append`/`stop`)。
|
||||
- `block` 使用追加式草稿预览。
|
||||
- `progress` 使用状态预览文本,然后发送最终答案。
|
||||
- 原生预览流式传输和草稿预览流式传输会在该轮抑制分块回复,因此 Slack 回复只会通过一条投递路径进行流式传输。
|
||||
- 最终媒体/错误载荷和 progress 最终结果不会创建一次性草稿消息;只有可编辑预览的文本/块最终结果才会刷新待处理的草稿文本。
|
||||
- 原生预览流式传输和草稿预览流式传输会在该轮中抑制分块回复,因此 Slack 回复只会通过一种投递路径进行流式传输。
|
||||
- 最终媒体/错误载荷和 `progress` 最终结果不会创建一次性的草稿消息;只有可编辑预览的文本/块最终结果,才会刷新待处理的草稿文本。
|
||||
|
||||
Mattermost:
|
||||
|
||||
- 将思考过程、工具活动和部分回复文本流式写入一个草稿预览帖子中,并在最终答案可以安全发送时原地完成该帖子。
|
||||
- 如果预览帖子已被删除或在最终化时不可用,则回退为发送一个新的最终帖子。
|
||||
- 将思考、工具活动和部分回复文本流式写入同一个草稿预览帖子,并在最终答案可以安全发送时原地完成。
|
||||
- 如果预览帖子已被删除或在最终完成时不可用,则回退为发送一条新的最终帖子。
|
||||
- 最终媒体/错误载荷会在正常投递前取消待处理的预览更新,而不是刷新临时预览帖子。
|
||||
|
||||
Matrix:
|
||||
|
||||
- 当最终文本可以复用预览事件时,草稿预览会原地完成。
|
||||
- 仅媒体、错误和回复目标不匹配的最终结果会在正常投递前取消待处理的预览更新;已经可见的陈旧预览会被撤回。
|
||||
- 仅媒体、错误以及回复目标不匹配的最终结果会在正常投递前取消待处理的预览更新;如果已有可见的陈旧预览,则会将其隐藏。
|
||||
|
||||
### 工具进度预览更新
|
||||
|
||||
预览流式传输还可以包含**工具进度**更新——例如“搜索网页”“读取文件”或“调用工具”之类的简短状态行——在工具运行期间,这些内容会显示在同一个预览消息中,并先于最终回复出现。这样可以让多步骤工具轮次在视觉上保持活跃,而不是在首次思考预览和最终答案之间沉默无响应。
|
||||
预览流式传输还可以包含**工具进度**更新——例如“正在搜索网页”“正在读取文件”或“正在调用工具”之类的简短状态行——在工具运行期间,这些内容会显示在同一条预览消息中,先于最终回复出现。这样可以让多步骤工具轮次在视觉上保持活跃,而不是在首次思考预览与最终答案之间一片沉默。
|
||||
|
||||
支持的界面:
|
||||
|
||||
- **Discord**、**Slack** 和 **Telegram** 会将工具进度流式传输到实时预览编辑中。
|
||||
- **Mattermost** 已经会将工具活动折叠到其单一草稿预览帖子中(见上文)。
|
||||
- 当预览流式传输为 `off`,或当分块流式传输已接管该消息时,会跳过工具进度编辑。
|
||||
- **Discord** 和 **Slack** 默认会将工具进度流式写入实时预览编辑。
|
||||
- **Telegram** 仅在显式启用 `streaming.preview.toolProgress` 时,才会将工具进度流式写入实时预览编辑。
|
||||
- **Mattermost** 已经将工具活动合并进其单一草稿预览帖子中(见上文)。
|
||||
- 工具进度编辑遵循当前启用的预览流式传输模式;当预览流式传输为 `off`,或消息已由分块流式传输接管时,这些更新会被跳过。
|
||||
|
||||
## 相关内容
|
||||
|
||||
- [Messages](/zh-CN/concepts/messages) — 消息生命周期与投递
|
||||
- [Retry](/zh-CN/concepts/retry) — 投递失败时的重试行为
|
||||
- [Channels](/zh-CN/channels) — 各渠道的流式传输支持
|
||||
- [Messages](/zh-CN/concepts/messages) —— 消息生命周期与投递
|
||||
- [Retry](/zh-CN/concepts/retry) —— 投递失败时的重试行为
|
||||
- [Channels](/zh-CN/channels) —— 各渠道的流式传输支持
|
||||
|
||||
@ -6,15 +6,15 @@ read_when:
|
||||
summary: 智能体默认设置、多智能体路由、会话、消息和对话配置
|
||||
title: 配置 — 智能体
|
||||
x-i18n:
|
||||
generated_at: "2026-04-25T01:51:44Z"
|
||||
generated_at: "2026-04-25T02:35:39Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: a0b90bb7a1d46dc2ae68d44de45f0861ec6400bb19ba36d2066d642ecbecc0b3
|
||||
source_hash: 8f787c5553b513c1b2aabe74ff0d0a6c7b2e48d1a14eed030bf60ac24f2dd253
|
||||
source_path: gateway/config-agents.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
位于 `agents.*`、`multiAgent.*`、`session.*`、`messages.*` 和 `talk.*` 下的智能体作用域配置键。关于渠道、工具、Gateway 网关运行时以及其他顶层键,请参阅[配置参考](/zh-CN/gateway/configuration-reference)。
|
||||
位于 `agents.*`、`multiAgent.*`、`session.*`、`messages.*` 和 `talk.*` 下的智能体作用域配置键。关于渠道、工具、Gateway 网关运行时以及其他顶层键,请参阅 [配置参考](/zh-CN/gateway/configuration-reference)。
|
||||
|
||||
## 智能体默认设置
|
||||
|
||||
@ -30,7 +30,7 @@ x-i18n:
|
||||
|
||||
### `agents.defaults.repoRoot`
|
||||
|
||||
可选的仓库根目录,会显示在系统提示中的 Runtime 行里。如果未设置,OpenClaw 会从工作区开始向上遍历并自动检测。
|
||||
可选的仓库根目录,会显示在系统提示中的 Runtime 行里。如果未设置,OpenClaw 会从工作区向上遍历并自动检测。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -55,9 +55,9 @@ x-i18n:
|
||||
}
|
||||
```
|
||||
|
||||
- 省略 `agents.defaults.skills`,则默认不限制 Skills。
|
||||
- 省略 `agents.list[].skills`,则继承默认值。
|
||||
- 将 `agents.list[].skills: []` 设为空 Skills。
|
||||
- 省略 `agents.defaults.skills`,则默认 Skills 不受限制。
|
||||
- 省略 `agents.list[].skills` 以继承默认值。
|
||||
- 设置 `agents.list[].skills: []` 表示不使用任何 Skills。
|
||||
- 非空的 `agents.list[].skills` 列表就是该智能体的最终集合;它不会与默认值合并。
|
||||
|
||||
### `agents.defaults.skipBootstrap`
|
||||
@ -72,9 +72,9 @@ x-i18n:
|
||||
|
||||
### `agents.defaults.contextInjection`
|
||||
|
||||
控制何时将工作区引导文件注入系统提示。默认值:`"always"`。
|
||||
控制何时将工作区引导文件注入到系统提示中。默认值:`"always"`。
|
||||
|
||||
- `"continuation-skip"`:安全的续接轮次(在助手完成一次响应之后)会跳过工作区引导内容的重新注入,从而减小提示大小。心跳运行和压缩后的重试仍会重建上下文。
|
||||
- `"continuation-skip"`:安全的续接轮次(在助手完成响应之后)会跳过重新注入工作区引导内容,从而减小提示大小。Heartbeat 运行和压缩后的重试仍会重建上下文。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -84,7 +84,7 @@ x-i18n:
|
||||
|
||||
### `agents.defaults.bootstrapMaxChars`
|
||||
|
||||
单个工作区引导文件在截断前允许的最大字符数。默认值:`12000`。
|
||||
每个工作区引导文件在截断前允许的最大字符数。默认值:`12000`。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -94,7 +94,7 @@ x-i18n:
|
||||
|
||||
### `agents.defaults.bootstrapTotalMaxChars`
|
||||
|
||||
所有工作区引导文件注入内容的总最大字符数。默认值:`60000`。
|
||||
所有工作区引导文件合计可注入的最大字符数。默认值:`60000`。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -104,7 +104,7 @@ x-i18n:
|
||||
|
||||
### `agents.defaults.bootstrapPromptTruncationWarning`
|
||||
|
||||
控制在引导上下文被截断时,向智能体显示的警告文本。
|
||||
控制当引导上下文被截断时,是否向智能体显示警告文本。
|
||||
默认值:`"once"`。
|
||||
|
||||
- `"off"`:绝不将警告文本注入系统提示。
|
||||
@ -119,20 +119,20 @@ x-i18n:
|
||||
|
||||
### 上下文预算归属映射
|
||||
|
||||
OpenClaw 有多个高容量的提示/上下文预算,并且它们是按子系统有意拆分的,而不是都通过一个通用旋钮来控制。
|
||||
OpenClaw 有多个高容量的提示 / 上下文预算,这些预算会按子系统有意拆分,而不是全部通过一个通用旋钮来控制。
|
||||
|
||||
- `agents.defaults.bootstrapMaxChars` /
|
||||
`agents.defaults.bootstrapTotalMaxChars`:
|
||||
常规工作区引导注入。
|
||||
常规工作区引导内容注入。
|
||||
- `agents.defaults.startupContext.*`:
|
||||
一次性的 `/new` 和 `/reset` 启动前导内容,包括最近的每日
|
||||
`memory/*.md` 文件。
|
||||
- `skills.limits.*`:
|
||||
注入系统提示中的精简 Skills 列表。
|
||||
注入到系统提示中的精简 Skills 列表。
|
||||
- `agents.defaults.contextLimits.*`:
|
||||
有界运行时摘录和由运行时注入的内容块。
|
||||
有界的运行时摘录和由运行时拥有的注入块。
|
||||
- `memory.qmd.limits.*`:
|
||||
已索引的内存搜索片段及注入大小控制。
|
||||
已索引的 memory 搜索片段和注入大小控制。
|
||||
|
||||
仅当某个智能体需要不同预算时,才使用对应的按智能体覆盖项:
|
||||
|
||||
@ -141,7 +141,7 @@ OpenClaw 有多个高容量的提示/上下文预算,并且它们是按子系
|
||||
|
||||
#### `agents.defaults.startupContext`
|
||||
|
||||
控制在纯 `/new` 和 `/reset` 运行时注入的首轮启动前导内容。
|
||||
控制在裸 `/new` 和 `/reset` 运行时注入的首轮启动前导内容。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -162,7 +162,7 @@ OpenClaw 有多个高容量的提示/上下文预算,并且它们是按子系
|
||||
|
||||
#### `agents.defaults.contextLimits`
|
||||
|
||||
为有界运行时上下文面提供共享默认值。
|
||||
有界运行时上下文界面的共享默认值。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -179,14 +179,14 @@ OpenClaw 有多个高容量的提示/上下文预算,并且它们是按子系
|
||||
}
|
||||
```
|
||||
|
||||
- `memoryGetMaxChars`:`memory_get` 摘录在添加截断元数据和续接提示前的默认上限。
|
||||
- `memoryGetMaxChars`:`memory_get` 摘录在添加截断元数据和续接提示之前的默认上限。
|
||||
- `memoryGetDefaultLines`:当省略 `lines` 时,`memory_get` 的默认行窗口。
|
||||
- `toolResultMaxChars`:用于持久化结果和溢出恢复的实时工具结果上限。
|
||||
- `postCompactionMaxChars`:压缩后刷新注入期间使用的 `AGENTS.md` 摘录上限。
|
||||
- `postCompactionMaxChars`:在压缩后刷新注入期间使用的 `AGENTS.md` 摘录上限。
|
||||
|
||||
#### `agents.list[].contextLimits`
|
||||
|
||||
共享 `contextLimits` 控件的按智能体覆盖项。省略的字段会继承 `agents.defaults.contextLimits`。
|
||||
共享 `contextLimits` 旋钮的按智能体覆盖项。省略的字段会继承自 `agents.defaults.contextLimits`。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -212,7 +212,7 @@ OpenClaw 有多个高容量的提示/上下文预算,并且它们是按子系
|
||||
|
||||
#### `skills.limits.maxSkillsPromptChars`
|
||||
|
||||
注入系统提示中的精简 Skills 列表的全局上限。这不会影响按需读取 `SKILL.md` 文件。
|
||||
注入到系统提示中的精简 Skills 列表的全局上限。这不会影响按需读取 `SKILL.md` 文件。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -226,7 +226,7 @@ OpenClaw 有多个高容量的提示/上下文预算,并且它们是按子系
|
||||
|
||||
#### `agents.list[].skillsLimits.maxSkillsPromptChars`
|
||||
|
||||
Skills 提示预算的按智能体覆盖项。
|
||||
按智能体覆盖 Skills 提示预算。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -245,11 +245,11 @@ Skills 提示预算的按智能体覆盖项。
|
||||
|
||||
### `agents.defaults.imageMaxDimensionPx`
|
||||
|
||||
在调用提供商之前,转录/工具图像块中图像最长边的最大像素尺寸。
|
||||
在调用提供商之前,transcript / tool 图像块中图像最长边的最大像素尺寸。
|
||||
默认值:`1200`。
|
||||
|
||||
较低的值通常会减少视觉 token 使用量和请求负载大小,适合以截图为主的运行。
|
||||
较高的值会保留更多视觉细节。
|
||||
较低的值通常会减少视觉 token 使用量和请求负载大小,适合大量截图的运行场景。
|
||||
较高的值则会保留更多视觉细节。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -259,7 +259,7 @@ Skills 提示预算的按智能体覆盖项。
|
||||
|
||||
### `agents.defaults.userTimezone`
|
||||
|
||||
用于系统提示上下文的时区(不影响消息时间戳)。会回退到主机时区。
|
||||
用于系统提示上下文的时区(不影响消息时间戳)。默认回退到主机时区。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -326,50 +326,51 @@ Skills 提示预算的按智能体覆盖项。
|
||||
}
|
||||
```
|
||||
|
||||
- `model`:既可接受字符串(`"provider/model"`),也可接受对象(`{ primary, fallbacks }`)。
|
||||
- `model`:接受字符串(`"provider/model"`)或对象(`{ primary, fallbacks }`)。
|
||||
- 字符串形式只设置主模型。
|
||||
- 对象形式设置主模型以及按顺序排列的故障切换模型。
|
||||
- `imageModel`:既可接受字符串(`"provider/model"`),也可接受对象(`{ primary, fallbacks }`)。
|
||||
- 用作 `image` 工具路径中的视觉模型配置。
|
||||
- 当所选/默认模型无法接受图像输入时,也会用作回退路由。
|
||||
- `imageGenerationModel`:既可接受字符串(`"provider/model"`),也可接受对象(`{ primary, fallbacks }`)。
|
||||
- 用于共享的图像生成能力,以及未来任何生成图像的工具/插件表面。
|
||||
- 对象形式设置主模型以及按顺序排列的故障转移模型。
|
||||
- `imageModel`:接受字符串(`"provider/model"`)或对象(`{ primary, fallbacks }`)。
|
||||
- 作为其视觉模型配置,由 `image` 工具路径使用。
|
||||
- 当所选 / 默认模型无法接受图像输入时,也用作回退路由。
|
||||
- `imageGenerationModel`:接受字符串(`"provider/model"`)或对象(`{ primary, fallbacks }`)。
|
||||
- 由共享图像生成能力以及任何未来用于生成图像的工具 / 插件界面使用。
|
||||
- 典型值:`google/gemini-3.1-flash-image-preview` 用于原生 Gemini 图像生成,`fal/fal-ai/flux/dev` 用于 fal,或 `openai/gpt-image-2` 用于 OpenAI Images。
|
||||
- 如果你直接选择某个提供商/模型,也要配置匹配的提供商凭证,例如 `google/*` 使用 `GEMINI_API_KEY` 或 `GOOGLE_API_KEY`,`openai/gpt-image-2` 使用 `OPENAI_API_KEY` 或 OpenAI Codex OAuth,`fal/*` 使用 `FAL_KEY`。
|
||||
- 如果省略,`image_generate` 仍可以推断出一个有凭证支持的提供商默认值。它会先尝试当前默认提供商,然后按提供商 id 顺序尝试其余已注册的图像生成提供商。
|
||||
- `musicGenerationModel`:既可接受字符串(`"provider/model"`),也可接受对象(`{ primary, fallbacks }`)。
|
||||
- 用于共享的音乐生成能力和内置的 `music_generate` 工具。
|
||||
- 如果你直接选择某个提供商 / 模型,也要配置匹配的提供商凭证(例如,`google/*` 对应 `GEMINI_API_KEY` 或 `GOOGLE_API_KEY`,`openai/gpt-image-2` 对应 `OPENAI_API_KEY` 或 OpenAI Codex OAuth,`fal/*` 对应 `FAL_KEY`)。
|
||||
- 如果省略,`image_generate` 仍可推断一个有凭证支持的提供商默认值。它会先尝试当前默认提供商,然后按提供商 id 顺序尝试其余已注册的图像生成提供商。
|
||||
- `musicGenerationModel`:接受字符串(`"provider/model"`)或对象(`{ primary, fallbacks }`)。
|
||||
- 由共享音乐生成能力和内置 `music_generate` 工具使用。
|
||||
- 典型值:`google/lyria-3-clip-preview`、`google/lyria-3-pro-preview` 或 `minimax/music-2.5+`。
|
||||
- 如果省略,`music_generate` 仍可以推断出一个有凭证支持的提供商默认值。它会先尝试当前默认提供商,然后按提供商 id 顺序尝试其余已注册的音乐生成提供商。
|
||||
- 如果你直接选择某个提供商/模型,也要配置匹配的提供商凭证/API 密钥。
|
||||
- `videoGenerationModel`:既可接受字符串(`"provider/model"`),也可接受对象(`{ primary, fallbacks }`)。
|
||||
- 用于共享的视频生成能力和内置的 `video_generate` 工具。
|
||||
- 如果省略,`music_generate` 仍可推断一个有凭证支持的提供商默认值。它会先尝试当前默认提供商,然后按提供商 id 顺序尝试其余已注册的音乐生成提供商。
|
||||
- 如果你直接选择某个提供商 / 模型,也要配置匹配的提供商凭证 / API key。
|
||||
- `videoGenerationModel`:接受字符串(`"provider/model"`)或对象(`{ primary, fallbacks }`)。
|
||||
- 由共享视频生成能力和内置 `video_generate` 工具使用。
|
||||
- 典型值:`qwen/wan2.6-t2v`、`qwen/wan2.6-i2v`、`qwen/wan2.6-r2v`、`qwen/wan2.6-r2v-flash` 或 `qwen/wan2.7-r2v`。
|
||||
- 如果省略,`video_generate` 仍可以推断出一个有凭证支持的提供商默认值。它会先尝试当前默认提供商,然后按提供商 id 顺序尝试其余已注册的视频生成提供商。
|
||||
- 如果你直接选择某个提供商/模型,也要配置匹配的提供商凭证/API 密钥。
|
||||
- 如果省略,`video_generate` 仍可推断一个有凭证支持的提供商默认值。它会先尝试当前默认提供商,然后按提供商 id 顺序尝试其余已注册的视频生成提供商。
|
||||
- 如果你直接选择某个提供商 / 模型,也要配置匹配的提供商凭证 / API key。
|
||||
- 内置的 Qwen 视频生成提供商最多支持 1 个输出视频、1 张输入图像、4 个输入视频、10 秒时长,以及提供商级别的 `size`、`aspectRatio`、`resolution`、`audio` 和 `watermark` 选项。
|
||||
- `pdfModel`:既可接受字符串(`"provider/model"`),也可接受对象(`{ primary, fallbacks }`)。
|
||||
- 用于 `pdf` 工具的模型路由。
|
||||
- 如果省略,PDF 工具会先回退到 `imageModel`,再回退到解析后的会话/默认模型。
|
||||
- `pdfModel`:接受字符串(`"provider/model"`)或对象(`{ primary, fallbacks }`)。
|
||||
- 由 `pdf` 工具用于模型路由。
|
||||
- 如果省略,PDF 工具会先回退到 `imageModel`,再回退到已解析的会话 / 默认模型。
|
||||
- `pdfMaxBytesMb`:当调用时未传入 `maxBytesMb` 时,`pdf` 工具使用的默认 PDF 大小限制。
|
||||
- `pdfMaxPages`:`pdf` 工具在提取回退模式中考虑的默认最大页数。
|
||||
- `verboseDefault`:智能体的默认详细级别。取值:`"off"`、`"on"`、`"full"`。默认值:`"off"`。
|
||||
- `elevatedDefault`:智能体的默认增强输出级别。取值:`"off"`、`"on"`、`"ask"`、`"full"`。默认值:`"on"`。
|
||||
- `model.primary`:格式为 `provider/model`(例如,`openai/gpt-5.4` 用于 API 密钥访问,或 `openai-codex/gpt-5.5` 用于 Codex OAuth)。如果你省略提供商,OpenClaw 会先尝试别名,然后尝试精确匹配该模型 id 的唯一已配置提供商,最后才回退到已配置的默认提供商(这是已弃用的兼容行为,因此建议优先使用显式的 `provider/model`)。如果该提供商不再暴露已配置的默认模型,OpenClaw 会回退到第一个已配置的提供商/模型,而不是暴露一个已经失效、来自已移除提供商的默认值。
|
||||
- `models`:`/model` 使用的已配置模型目录和允许列表。每个条目都可以包含 `alias`(快捷方式)和 `params`(提供商特定参数,例如 `temperature`、`maxTokens`、`cacheRetention`、`context1m`、`responsesServerCompaction`、`responsesCompactThreshold`)。
|
||||
- 安全编辑方式:使用 `openclaw config set agents.defaults.models '<json>' --strict-json --merge` 添加条目。除非你传入 `--replace`,否则 `config set` 会拒绝会删除现有允许列表条目的替换操作。
|
||||
- 以提供商为作用域的配置/新手引导流程会将所选提供商模型合并到这个映射中,并保留已经配置好的无关提供商。
|
||||
- 对于直接使用的 OpenAI Responses 模型,会自动启用服务端压缩。使用 `params.responsesServerCompaction: false` 可停止注入 `context_management`,或使用 `params.responsesCompactThreshold` 覆盖阈值。参见 [OpenAI 服务端压缩](/zh-CN/providers/openai#server-side-compaction-responses-api)。
|
||||
- `params`:应用到所有模型的全局默认提供商参数。在 `agents.defaults.params` 中设置(例如 `{ cacheRetention: "long" }`)。
|
||||
- `params` 合并优先级(配置):`agents.defaults.params`(全局基础)会被 `agents.defaults.models["provider/model"].params`(按模型)覆盖,然后再由 `agents.list[].params`(匹配的智能体 id)按键覆盖。详见 [提示缓存](/zh-CN/reference/prompt-caching)。
|
||||
- `embeddedHarness`:默认的底层嵌入式智能体运行时策略。省略 `runtime` 时默认使用 OpenClaw Pi。使用 `runtime: "pi"` 可强制使用内置 PI harness,使用 `runtime: "auto"` 可让已注册的插件 harness 认领受支持的模型,或使用已注册的 harness id,例如 `runtime: "codex"`。设置 `fallback: "none"` 可禁用自动回退到 PI。像 `codex` 这样的显式插件运行时默认采用失败即关闭,除非你在同一覆盖作用域中设置 `fallback: "pi"`。请将模型引用保持为规范形式 `provider/model`;Codex、Claude CLI、Gemini CLI 以及其他执行后端应通过运行时配置来选择,而不是使用旧式运行时提供商前缀。参见 [Agent Runtimes](/zh-CN/concepts/agent-runtimes),了解它与提供商/模型选择有何不同。
|
||||
- 会修改这些字段的配置写入器(例如 `/models set`、`/models set-image` 以及回退模型的添加/移除命令)会保存为规范对象形式,并尽可能保留现有回退列表。
|
||||
- `maxConcurrent`:跨会话的最大并行智能体运行数(每个会话本身仍然串行)。默认值:4。
|
||||
- `model.primary`:格式为 `provider/model`(例如,`openai/gpt-5.4` 用于 API key 访问,或 `openai-codex/gpt-5.5` 用于 Codex OAuth)。如果你省略提供商,OpenClaw 会先尝试别名,然后尝试与该精确模型 id 唯一匹配的已配置提供商,最后才回退到已配置的默认提供商(这是已弃用的兼容行为,因此更推荐显式使用 `provider/model`)。如果该提供商不再公开已配置的默认模型,OpenClaw 会回退到第一个已配置的提供商 / 模型,而不是暴露一个已过期、已移除提供商的默认值。
|
||||
- `models`:为 `/model` 配置的模型目录和允许列表。每个条目都可以包含 `alias`(快捷方式)和 `params`(提供商特定参数,例如 `temperature`、`maxTokens`、`cacheRetention`、`context1m`、`responsesServerCompaction`、`responsesCompactThreshold`、`extra_body` / `extraBody`)。
|
||||
- 安全编辑:使用 `openclaw config set agents.defaults.models '<json>' --strict-json --merge` 添加条目。`config set` 会拒绝删除现有允许列表条目的替换操作,除非你传入 `--replace`。
|
||||
- 提供商作用域的配置 / 新手引导流程会将所选提供商模型合并到此映射中,并保留已配置的其他无关提供商。
|
||||
- 对于直接的 OpenAI Responses 模型,默认会自动启用服务端压缩。使用 `params.responsesServerCompaction: false` 可停止注入 `context_management`,或使用 `params.responsesCompactThreshold` 覆盖阈值。参见 [OpenAI 服务端压缩](/zh-CN/providers/openai#server-side-compaction-responses-api)。
|
||||
- `params`:应用于所有模型的全局默认提供商参数。在 `agents.defaults.params` 处设置(例如 `{ cacheRetention: "long" }`)。
|
||||
- `params` 合并优先级(配置):`agents.defaults.params`(全局基础)会被 `agents.defaults.models["provider/model"].params`(按模型)覆盖,然后 `agents.list[].params`(匹配智能体 id)会按键继续覆盖。详情参见 [Prompt Caching](/zh-CN/reference/prompt-caching)。
|
||||
- `params.extra_body` / `params.extraBody`:高级透传 JSON,会合并到 `api: "openai-completions"` 的请求体中,供兼容 OpenAI 的代理使用。如果它与自动生成的请求键冲突,以额外请求体为准;非原生 completions 路由之后仍会去除 OpenAI 专用的 `store`。
|
||||
- `embeddedHarness`:默认的底层嵌入式智能体运行时策略。省略 `runtime` 时默认使用 OpenClaw Pi。使用 `runtime: "pi"` 强制使用内置的 PI harness,使用 `runtime: "auto"` 让已注册的插件 harness 认领受支持的模型,或使用已注册的 harness id,例如 `runtime: "codex"`。设置 `fallback: "none"` 可禁用自动回退到 PI。像 `codex` 这样的显式插件运行时默认是封闭失败的,除非你在同一覆盖作用域中设置 `fallback: "pi"`。模型引用请保持为标准格式 `provider/model`;应通过运行时配置而不是旧式运行时提供商前缀来选择 Codex、Claude CLI、Gemini CLI 和其他执行后端。关于它与提供商 / 模型选择的区别,参见 [Agent Runtimes](/zh-CN/concepts/agent-runtimes)。
|
||||
- 会修改这些字段的配置写入器(例如 `/models set`、`/models set-image` 以及回退项添加 / 删除命令)会保存为标准对象形式,并在可能时保留现有回退列表。
|
||||
- `maxConcurrent`:跨会话并行运行的最大智能体数量(每个会话本身仍是串行的)。默认值:4。
|
||||
|
||||
### `agents.defaults.embeddedHarness`
|
||||
|
||||
`embeddedHarness` 控制哪个底层执行器运行嵌入式智能体轮次。
|
||||
大多数部署应保留默认的 OpenClaw Pi 运行时。
|
||||
`embeddedHarness` 控制由哪个底层执行器来运行嵌入式智能体轮次。
|
||||
大多数部署应保持默认的 OpenClaw Pi 运行时。
|
||||
当受信任的插件提供原生 harness 时使用它,例如内置的
|
||||
Codex 应用服务器 harness。关于其思维模型,请参见
|
||||
[Agent Runtimes](/zh-CN/concepts/agent-runtimes)。
|
||||
@ -388,14 +389,14 @@ Codex 应用服务器 harness。关于其思维模型,请参见
|
||||
}
|
||||
```
|
||||
|
||||
- `runtime`:`"auto"`、`"pi"` 或已注册的插件 harness id。内置的 Codex 插件会注册 `codex`。
|
||||
- `fallback`:`"pi"` 或 `"none"`。在 `runtime: "auto"` 中,省略 `fallback` 时默认值为 `"pi"`,这样旧配置在没有插件 harness 认领运行时仍可继续使用 PI。在显式插件运行时模式下,例如 `runtime: "codex"`,省略 `fallback` 时默认值为 `"none"`,这样缺少 harness 时会失败,而不是静默改用 PI。运行时覆盖项不会从更宽范围继承 `fallback`;当你有意需要这种兼容性回退时,请在显式运行时旁边同时设置 `fallback: "pi"`。所选插件 harness 的失败总是会直接暴露出来。
|
||||
- 环境变量覆盖:`OPENCLAW_AGENT_RUNTIME=<id|auto|pi>` 会覆盖 `runtime`;`OPENCLAW_AGENT_HARNESS_FALLBACK=pi|none` 会为该进程覆盖 `fallback`。
|
||||
- 对于仅使用 Codex 的部署,设置 `model: "openai/gpt-5.5"` 和 `embeddedHarness.runtime: "codex"`。你也可以显式设置 `embeddedHarness.fallback: "none"` 以提高可读性;对于显式插件运行时,这就是默认值。
|
||||
- 第一次嵌入式运行之后,harness 选择会按会话 id 固定。配置/环境变量变更只影响新的或已重置的会话,不影响现有转录。具有转录历史但没有记录固定值的旧会话会被视为固定到 PI。`/status` 会在 `Fast` 旁显示非 PI 的 harness id,例如 `codex`。
|
||||
- 这只控制嵌入式聊天 harness。媒体生成、视觉、PDF、音乐、视频和 TTS 仍使用各自的提供商/模型设置。
|
||||
- `runtime`:`"auto"`、`"pi"`,或已注册的插件 harness id。内置的 Codex 插件注册的 id 为 `codex`。
|
||||
- `fallback`:`"pi"` 或 `"none"`。在 `runtime: "auto"` 中,省略 `fallback` 时默认值为 `"pi"`,这样旧配置在没有插件 harness 认领运行时仍可继续使用 PI。在显式插件运行时模式下,例如 `runtime: "codex"`,省略 `fallback` 时默认值为 `"none"`,这样缺失 harness 时会直接失败,而不是静默使用 PI。运行时覆盖不会从更宽作用域继承 `fallback`;如果你确实希望在显式运行时旁边保留这种兼容性回退,请同时设置 `fallback: "pi"`。所选插件 harness 的失败总是会直接暴露出来。
|
||||
- 环境变量覆盖:`OPENCLAW_AGENT_RUNTIME=<id|auto|pi>` 会覆盖 `runtime`;`OPENCLAW_AGENT_HARNESS_FALLBACK=pi|none` 会覆盖该进程的 `fallback`。
|
||||
- 对于仅使用 Codex 的部署,设置 `model: "openai/gpt-5.5"` 和 `embeddedHarness.runtime: "codex"`。你也可以显式设置 `embeddedHarness.fallback: "none"` 以增强可读性;对于显式插件运行时,这本就是默认值。
|
||||
- 在第一次嵌入式运行之后,harness 选择会按会话 id 固定。配置 / 环境变量变更只会影响新会话或已重置的会话,不影响已有 transcript。带有 transcript 历史但未记录固定值的旧会话会被视为固定到 PI。`/status` 会在 `Fast` 旁显示非 PI 的 harness id,例如 `codex`。
|
||||
- 这只控制嵌入式聊天 harness。媒体生成、视觉、PDF、音乐、视频和 TTS 仍使用各自的提供商 / 模型设置。
|
||||
|
||||
**内置别名简写**(仅当模型位于 `agents.defaults.models` 中时适用):
|
||||
**内置别名简写**(仅当模型存在于 `agents.defaults.models` 中时适用):
|
||||
|
||||
| 别名 | 模型 |
|
||||
| ------------------- | -------------------------------------------------- |
|
||||
@ -408,15 +409,15 @@ Codex 应用服务器 harness。关于其思维模型,请参见
|
||||
| `gemini-flash` | `google/gemini-3-flash-preview` |
|
||||
| `gemini-flash-lite` | `google/gemini-3.1-flash-lite-preview` |
|
||||
|
||||
你配置的别名始终优先于默认值。
|
||||
你自己配置的别名始终优先于默认值。
|
||||
|
||||
Z.AI 的 GLM-4.x 模型会自动启用思考模式,除非你设置 `--thinking off`,或自行定义 `agents.defaults.models["zai/<model>"].params.thinking`。
|
||||
Z.AI 模型默认启用 `tool_stream` 以进行工具调用流式传输。将 `agents.defaults.models["zai/<model>"].params.tool_stream` 设为 `false` 可禁用它。
|
||||
Anthropic Claude 4.6 模型在未显式设置思考级别时,默认使用 `adaptive` 思考。
|
||||
Z.AI GLM-4.x 模型会自动启用思考模式,除非你设置 `--thinking off`,或自行定义 `agents.defaults.models["zai/<model>"].params.thinking`。
|
||||
Z.AI 模型默认启用 `tool_stream` 用于工具调用流式传输。将 `agents.defaults.models["zai/<model>"].params.tool_stream` 设置为 `false` 可禁用它。
|
||||
Anthropic Claude 4.6 模型在未设置显式思考级别时,默认使用 `adaptive` 思考。
|
||||
|
||||
### `agents.defaults.cliBackends`
|
||||
|
||||
用于纯文本回退运行(无工具调用)的可选 CLI 后端。当 API 提供商失败时,可作为备份。
|
||||
用于纯文本回退运行(无工具调用)的可选 CLI 后端。当 API 提供商失败时,这可作为备份。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -444,13 +445,13 @@ Anthropic Claude 4.6 模型在未显式设置思考级别时,默认使用 `ada
|
||||
}
|
||||
```
|
||||
|
||||
- CLI 后端以文本为主;工具始终被禁用。
|
||||
- CLI 后端以文本优先;工具始终被禁用。
|
||||
- 设置了 `sessionArg` 时支持会话。
|
||||
- 当 `imageArg` 接受文件路径时,支持图像直通。
|
||||
- 当 `imageArg` 接受文件路径时,支持图像透传。
|
||||
|
||||
### `agents.defaults.systemPromptOverride`
|
||||
|
||||
用一个固定字符串替换整个由 OpenClaw 组装的系统提示。可在默认级别(`agents.defaults.systemPromptOverride`)设置,也可按智能体设置(`agents.list[].systemPromptOverride`)。按智能体的值优先;空值或仅空白字符的值会被忽略。适用于受控的提示实验。
|
||||
用固定字符串替换整个由 OpenClaw 组装的系统提示。可在默认级别(`agents.defaults.systemPromptOverride`)或按智能体(`agents.list[].systemPromptOverride`)设置。按智能体的值优先级更高;空值或仅空白字符的值会被忽略。适用于受控的提示实验。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -464,7 +465,7 @@ Anthropic Claude 4.6 模型在未显式设置思考级别时,默认使用 `ada
|
||||
|
||||
### `agents.defaults.promptOverlays`
|
||||
|
||||
按模型家族应用、与提供商无关的提示覆盖层。GPT-5 系列模型 id 会在不同提供商之间接收共享行为契约;`personality` 仅控制友好的交互风格层。
|
||||
按模型家族应用的、与提供商无关的提示覆盖层。GPT-5 系列模型 id 会跨提供商接收共享的行为契约;`personality` 只控制友好型交互风格这一层。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -481,12 +482,12 @@ Anthropic Claude 4.6 模型在未显式设置思考级别时,默认使用 `ada
|
||||
```
|
||||
|
||||
- `"friendly"`(默认)和 `"on"` 会启用友好交互风格层。
|
||||
- `"off"` 仅禁用友好层;带标签的 GPT-5 行为契约仍保持启用。
|
||||
- 旧版 `plugins.entries.openai.config.personality` 在这个共享设置未配置时仍会被读取。
|
||||
- `"off"` 只会禁用友好层;带标签的 GPT-5 行为契约仍然启用。
|
||||
- 当这个共享设置未设置时,仍会读取旧版 `plugins.entries.openai.config.personality`。
|
||||
|
||||
### `agents.defaults.heartbeat`
|
||||
|
||||
周期性心跳运行。
|
||||
周期性 Heartbeat 运行。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -496,13 +497,13 @@ Anthropic Claude 4.6 模型在未显式设置思考级别时,默认使用 `ada
|
||||
every: "30m", // 0m 表示禁用
|
||||
model: "openai/gpt-5.4-mini",
|
||||
includeReasoning: false,
|
||||
includeSystemPromptSection: true, // 默认值:true;false 会从系统提示中省略 Heartbeat 部分
|
||||
lightContext: false, // 默认值:false;true 只保留工作区引导文件中的 HEARTBEAT.md
|
||||
isolatedSession: false, // 默认值:false;true 会让每次心跳在一个全新的会话中运行(无会话历史)
|
||||
includeSystemPromptSection: true, // 默认:true;false 会从系统提示中省略 Heartbeat 部分
|
||||
lightContext: false, // 默认:false;true 仅保留工作区引导文件中的 HEARTBEAT.md
|
||||
isolatedSession: false, // 默认:false;true 会在全新会话中运行每次 heartbeat(无对话历史)
|
||||
session: "main",
|
||||
to: "+15555550123",
|
||||
directPolicy: "allow", // allow(默认) | block
|
||||
target: "none", // 默认值:none | 可选值:last | whatsapp | telegram | discord | ...
|
||||
directPolicy: "allow", // allow(默认)| block
|
||||
target: "none", // 默认:none | 可选值:last | whatsapp | telegram | discord | ...
|
||||
prompt: "Read HEARTBEAT.md if it exists...",
|
||||
ackMaxChars: 300,
|
||||
suppressToolErrorWarnings: false,
|
||||
@ -513,15 +514,15 @@ Anthropic Claude 4.6 模型在未显式设置思考级别时,默认使用 `ada
|
||||
}
|
||||
```
|
||||
|
||||
- `every`:时长字符串(ms/s/m/h)。默认值:`30m`(API 密钥认证)或 `1h`(OAuth 认证)。设置为 `0m` 可禁用。
|
||||
- `includeSystemPromptSection`:为 false 时,会从系统提示中省略 Heartbeat 部分,并跳过将 `HEARTBEAT.md` 注入引导上下文。默认值:`true`。
|
||||
- `suppressToolErrorWarnings`:为 true 时,会在心跳运行期间抑制工具错误警告负载。
|
||||
- `timeoutSeconds`:心跳智能体轮次在被中止前允许的最长秒数。留空则使用 `agents.defaults.timeoutSeconds`。
|
||||
- `directPolicy`:直接/私信投递策略。`allow`(默认)允许投递到直接目标。`block` 会阻止投递到直接目标,并发出 `reason=dm-blocked`。
|
||||
- `lightContext`:为 true 时,心跳运行使用轻量引导上下文,并且只保留工作区引导文件中的 `HEARTBEAT.md`。
|
||||
- `isolatedSession`:为 true 时,每次心跳都会在一个没有先前会话历史的新会话中运行。与 cron `sessionTarget: "isolated"` 使用相同的隔离模式。可将每次心跳的 token 成本从约 100K 降低到约 2-5K token。
|
||||
- 按智能体设置:使用 `agents.list[].heartbeat`。当任何智能体定义了 `heartbeat` 时,**只有这些智能体**会运行心跳。
|
||||
- 心跳会运行完整的智能体轮次——间隔越短,消耗的 token 越多。
|
||||
- `every`:时长字符串(ms/s/m/h)。默认值:`30m`(API key 认证)或 `1h`(OAuth 认证)。设置为 `0m` 可禁用。
|
||||
- `includeSystemPromptSection`:为 false 时,会从系统提示中省略 Heartbeat 部分,并跳过将 `HEARTBEAT.md` 注入到引导上下文中。默认值:`true`。
|
||||
- `suppressToolErrorWarnings`:为 true 时,在 heartbeat 运行期间抑制工具错误警告负载。
|
||||
- `timeoutSeconds`:heartbeat 智能体轮次在被中止前允许的最长秒数。留空则使用 `agents.defaults.timeoutSeconds`。
|
||||
- `directPolicy`:直发 / 私信投递策略。`allow`(默认)允许向直接目标投递。`block` 会抑制向直接目标投递,并发出 `reason=dm-blocked`。
|
||||
- `lightContext`:为 true 时,heartbeat 运行会使用轻量级引导上下文,并且只保留工作区引导文件中的 `HEARTBEAT.md`。
|
||||
- `isolatedSession`:为 true 时,每次 heartbeat 都会在无任何先前对话历史的全新会话中运行。与 cron 的 `sessionTarget: "isolated"` 使用相同的隔离模式。可将每次 heartbeat 的 token 成本从约 100K 降低到约 2-5K。
|
||||
- 按智能体设置:使用 `agents.list[].heartbeat`。当任一智能体定义了 `heartbeat` 时,**只有这些智能体** 会运行 heartbeat。
|
||||
- Heartbeat 会运行完整的智能体轮次——间隔越短,消耗的 token 越多。
|
||||
|
||||
### `agents.defaults.compaction`
|
||||
|
||||
@ -531,14 +532,14 @@ Anthropic Claude 4.6 模型在未显式设置思考级别时,默认使用 `ada
|
||||
defaults: {
|
||||
compaction: {
|
||||
mode: "safeguard", // default | safeguard
|
||||
provider: "my-provider", // 已注册压缩提供商插件的 id(可选)
|
||||
provider: "my-provider", // 已注册 compaction 提供商插件的 id(可选)
|
||||
timeoutSeconds: 900,
|
||||
reserveTokensFloor: 24000,
|
||||
identifierPolicy: "strict", // strict | off | custom
|
||||
identifierInstructions: "Preserve deployment IDs, ticket IDs, and host:port pairs exactly.", // 当 identifierPolicy=custom 时使用
|
||||
postCompactionSections: ["Session Startup", "Red Lines"], // [] 表示禁用重新注入
|
||||
model: "openrouter/anthropic/claude-sonnet-4-6", // 可选,仅用于压缩的模型覆盖
|
||||
notifyUser: true, // 在压缩开始和完成时向用户发送简短通知(默认值:false)
|
||||
model: "openrouter/anthropic/claude-sonnet-4-6", // 可选,仅用于 compaction 的模型覆盖
|
||||
notifyUser: true, // 在 compaction 开始和完成时发送简短通知(默认:false)
|
||||
memoryFlush: {
|
||||
enabled: true,
|
||||
softThresholdTokens: 6000,
|
||||
@ -551,19 +552,19 @@ Anthropic Claude 4.6 模型在未显式设置思考级别时,默认使用 `ada
|
||||
}
|
||||
```
|
||||
|
||||
- `mode`:`default` 或 `safeguard`(针对长历史的分块摘要)。参见[压缩](/zh-CN/concepts/compaction)。
|
||||
- `provider`:已注册压缩提供商插件的 id。设置后,会调用该提供商的 `summarize()`,而不是使用内置 LLM 摘要。失败时会回退到内置方式。设置提供商会强制使用 `mode: "safeguard"`。参见[压缩](/zh-CN/concepts/compaction)。
|
||||
- `timeoutSeconds`:OpenClaw 中止单次压缩操作前允许的最长秒数。默认值:`900`。
|
||||
- `identifierPolicy`:`strict`(默认)、`off` 或 `custom`。`strict` 会在压缩摘要时预先添加内置的不透明标识符保留指引。
|
||||
- `identifierInstructions`:当 `identifierPolicy=custom` 时使用的可选自定义标识符保留说明文本。
|
||||
- `postCompactionSections`:压缩后重新注入的可选 `AGENTS.md` H2/H3 章节名。默认值为 `["Session Startup", "Red Lines"]`;设为 `[]` 可禁用重新注入。未设置时,或显式设置为该默认组合时,也接受旧版 `Every Session`/`Safety` 标题作为兼容回退。
|
||||
- `model`:可选的 `provider/model-id` 覆盖项,仅用于压缩摘要。当主会话应继续使用一个模型,而压缩摘要应使用另一个模型时可使用此项;未设置时,压缩会使用会话的主模型。
|
||||
- `notifyUser`:为 `true` 时,在压缩开始和完成时向用户发送简短通知(例如“Compacting context...” 和 “Compaction complete”)。默认关闭,以保持压缩静默。
|
||||
- `memoryFlush`:在自动压缩前执行静默智能体轮次,以存储持久记忆。当工作区为只读时会跳过。
|
||||
- `mode`:`default` 或 `safeguard`(针对长历史的分块摘要)。参见 [Compaction](/zh-CN/concepts/compaction)。
|
||||
- `provider`:已注册 compaction 提供商插件的 id。设置后,会调用该提供商的 `summarize()`,而不是使用内置 LLM 摘要。失败时会回退到内置实现。设置提供商会强制使用 `mode: "safeguard"`。参见 [Compaction](/zh-CN/concepts/compaction)。
|
||||
- `timeoutSeconds`:OpenClaw 中止单次 compaction 操作前允许的最长秒数。默认值:`900`。
|
||||
- `identifierPolicy`:`strict`(默认)、`off` 或 `custom`。`strict` 会在 compaction 摘要期间预置内置的不透明标识符保留指引。
|
||||
- `identifierInstructions`:当 `identifierPolicy=custom` 时使用的可选自定义标识符保留文本。
|
||||
- `postCompactionSections`:compaction 后可重新注入的 `AGENTS.md` H2/H3 章节名称。默认值为 `["Session Startup", "Red Lines"]`;设置为 `[]` 可禁用重新注入。若未设置或显式设为该默认对,则旧版 `Every Session` / `Safety` 标题也会作为兼容性回退被接受。
|
||||
- `model`:仅用于 compaction 摘要的可选 `provider/model-id` 覆盖。当主会话应保持一个模型,而 compaction 摘要应使用另一个模型时使用;未设置时,compaction 使用会话的主模型。
|
||||
- `notifyUser`:为 `true` 时,会在 compaction 开始和完成时向用户发送简短通知(例如 “Compacting context...” 和 “Compaction complete”)。默认禁用,以保持 compaction 静默。
|
||||
- `memoryFlush`:在自动 compaction 前进行静默的智能体轮次,以存储持久 memory。工作区为只读时会跳过。
|
||||
|
||||
### `agents.defaults.contextPruning`
|
||||
|
||||
在将内容发送给 LLM 之前,从内存上下文中修剪**旧的工具结果**。**不会**修改磁盘上的会话历史。
|
||||
在将上下文发送给 LLM 之前,从内存上下文中裁剪**旧工具结果**。**不会**修改磁盘上的会话历史。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -587,23 +588,23 @@ Anthropic Claude 4.6 模型在未显式设置思考级别时,默认使用 `ada
|
||||
|
||||
<Accordion title="`cache-ttl` 模式行为">
|
||||
|
||||
- `mode: "cache-ttl"` 会启用修剪流程。
|
||||
- `ttl` 控制多久之后才能再次运行修剪(从上次缓存触达后开始计算)。
|
||||
- 修剪会先对过大的工具结果进行软修剪,如果仍有需要,再对更旧的工具结果执行硬清除。
|
||||
- `mode: "cache-ttl"` 会启用裁剪流程。
|
||||
- `ttl` 控制多久之后才能再次运行裁剪(从上次缓存触达后开始计算)。
|
||||
- 裁剪会先对过大的工具结果进行软裁剪,如仍有需要,再对更旧的工具结果进行硬清除。
|
||||
|
||||
**软修剪**会保留开头和结尾,并在中间插入 `...`。
|
||||
**软裁剪**会保留开头和结尾,并在中间插入 `...`。
|
||||
|
||||
**硬清除**会用占位符替换整个工具结果。
|
||||
|
||||
说明:
|
||||
|
||||
- 图像块永远不会被修剪/清除。
|
||||
- 比例是基于字符的近似值,而不是精确 token 计数。
|
||||
- 如果助手消息少于 `keepLastAssistants` 条,则会跳过修剪。
|
||||
- 图像块永远不会被裁剪 / 清除。
|
||||
- 比例按字符计算(近似),不是精确 token 数。
|
||||
- 如果助手消息少于 `keepLastAssistants` 条,则跳过裁剪。
|
||||
|
||||
</Accordion>
|
||||
|
||||
行为细节参见[会话修剪](/zh-CN/concepts/session-pruning)。
|
||||
行为详情参见 [会话裁剪](/zh-CN/concepts/session-pruning)。
|
||||
|
||||
### 分块流式传输
|
||||
|
||||
@ -622,10 +623,10 @@ Anthropic Claude 4.6 模型在未显式设置思考级别时,默认使用 `ada
|
||||
```
|
||||
|
||||
- 非 Telegram 渠道需要显式设置 `*.blockStreaming: true` 才能启用分块回复。
|
||||
- 渠道覆盖项:`channels.<channel>.blockStreamingCoalesce`(以及按账号的变体)。Signal/Slack/Discord/Google Chat 默认 `minChars: 1500`。
|
||||
- `humanDelay`:分块回复之间的随机停顿。`natural` = 800–2500 毫秒。按智能体覆盖:`agents.list[].humanDelay`。
|
||||
- 渠道覆盖:`channels.<channel>.blockStreamingCoalesce`(以及按账号的变体)。Signal / Slack / Discord / Google Chat 默认 `minChars: 1500`。
|
||||
- `humanDelay`:分块回复之间的随机停顿。`natural` = 800–2500ms。按智能体覆盖:`agents.list[].humanDelay`。
|
||||
|
||||
行为和分块细节参见[流式传输](/zh-CN/concepts/streaming)。
|
||||
行为和分块详情参见 [流式传输](/zh-CN/concepts/streaming)。
|
||||
|
||||
### 输入中指示器
|
||||
|
||||
@ -640,16 +641,16 @@ Anthropic Claude 4.6 模型在未显式设置思考级别时,默认使用 `ada
|
||||
}
|
||||
```
|
||||
|
||||
- 默认值:直接聊天/提及时使用 `instant`,未提及的群聊使用 `message`。
|
||||
- 默认值:对于直接聊天 / 提及使用 `instant`,对于未被提及的群聊使用 `message`。
|
||||
- 按会话覆盖:`session.typingMode`、`session.typingIntervalSeconds`。
|
||||
|
||||
参见[输入中指示器](/zh-CN/concepts/typing-indicators)。
|
||||
参见 [输入中指示器](/zh-CN/concepts/typing-indicators)。
|
||||
|
||||
<a id="agentsdefaultssandbox"></a>
|
||||
|
||||
### `agents.defaults.sandbox`
|
||||
|
||||
嵌入式智能体的可选沙箱隔离。完整指南参见[沙箱隔离](/zh-CN/gateway/sandboxing)。
|
||||
嵌入式智能体的可选沙箱隔离。完整指南参见 [沙箱隔离](/zh-CN/gateway/sandboxing)。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -695,7 +696,7 @@ Anthropic Claude 4.6 模型在未显式设置思考级别时,默认使用 `ada
|
||||
identityFile: "~/.ssh/id_ed25519",
|
||||
certificateFile: "~/.ssh/id_ed25519-cert.pub",
|
||||
knownHostsFile: "~/.ssh/known_hosts",
|
||||
// 也支持 SecretRef / 内联内容:
|
||||
// 也支持 SecretRefs / 内联内容:
|
||||
// identityData: { source: "env", provider: "default", id: "SSH_IDENTITY" },
|
||||
// certificateData: { source: "env", provider: "default", id: "SSH_CERTIFICATE" },
|
||||
// knownHostsData: { source: "env", provider: "default", id: "SSH_KNOWN_HOSTS" },
|
||||
@ -749,39 +750,39 @@ Anthropic Claude 4.6 模型在未显式设置思考级别时,默认使用 `ada
|
||||
**后端:**
|
||||
|
||||
- `docker`:本地 Docker 运行时(默认)
|
||||
- `ssh`:通用 SSH 远程运行时
|
||||
- `ssh`:通用 SSH 支持的远程运行时
|
||||
- `openshell`:OpenShell 运行时
|
||||
|
||||
当选择 `backend: "openshell"` 时,运行时专属设置会移动到
|
||||
当选择 `backend: "openshell"` 时,运行时特定设置会移到
|
||||
`plugins.entries.openshell.config`。
|
||||
|
||||
**SSH 后端配置:**
|
||||
|
||||
- `target`:采用 `user@host[:port]` 形式的 SSH 目标
|
||||
- `command`:SSH 客户端命令(默认值:`ssh`)
|
||||
- `workspaceRoot`:供各作用域工作区使用的远程绝对根路径
|
||||
- `target`:格式为 `user@host[:port]` 的 SSH 目标
|
||||
- `command`:SSH 客户端命令(默认:`ssh`)
|
||||
- `workspaceRoot`:用于按作用域工作区的远程绝对根目录
|
||||
- `identityFile` / `certificateFile` / `knownHostsFile`:传递给 OpenSSH 的现有本地文件
|
||||
- `identityData` / `certificateData` / `knownHostsData`:内联内容或 SecretRef,OpenClaw 会在运行时将其实体化为临时文件
|
||||
- `strictHostKeyChecking` / `updateHostKeys`:OpenSSH 主机密钥策略开关
|
||||
- `identityData` / `certificateData` / `knownHostsData`:内联内容或 SecretRefs,OpenClaw 会在运行时将其物化为临时文件
|
||||
- `strictHostKeyChecking` / `updateHostKeys`:OpenSSH 主机密钥策略控制项
|
||||
|
||||
**SSH 认证优先级:**
|
||||
|
||||
- `identityData` 优先于 `identityFile`
|
||||
- `certificateData` 优先于 `certificateFile`
|
||||
- `knownHostsData` 优先于 `knownHostsFile`
|
||||
- 基于 SecretRef 的 `*Data` 值会在沙箱会话开始前,从活动的 secrets 运行时快照中解析
|
||||
- `identityData` 的优先级高于 `identityFile`
|
||||
- `certificateData` 的优先级高于 `certificateFile`
|
||||
- `knownHostsData` 的优先级高于 `knownHostsFile`
|
||||
- 由 SecretRef 支持的 `*Data` 值会在沙箱会话开始前,从当前激活的 secrets 运行时快照中解析
|
||||
|
||||
**SSH 后端行为:**
|
||||
|
||||
- 在创建或重建后,会先对远程工作区执行一次初始化填充
|
||||
- 然后保持远程 SSH 工作区为规范副本
|
||||
- 在创建或重建后,只对远程工作区执行一次初始化填充
|
||||
- 之后保持远程 SSH 工作区为标准状态
|
||||
- 通过 SSH 路由 `exec`、文件工具和媒体路径
|
||||
- 不会自动将远程更改同步回主机
|
||||
- 不支持沙箱浏览器容器
|
||||
|
||||
**工作区访问:**
|
||||
|
||||
- `none`:在 `~/.openclaw/sandboxes` 下为每个作用域创建沙箱工作区
|
||||
- `none`:按作用域创建位于 `~/.openclaw/sandboxes` 下的沙箱工作区
|
||||
- `ro`:沙箱工作区位于 `/workspace`,智能体工作区以只读方式挂载到 `/agent`
|
||||
- `rw`:智能体工作区以读写方式挂载到 `/workspace`
|
||||
|
||||
@ -804,10 +805,10 @@ Anthropic Claude 4.6 模型在未显式设置思考级别时,默认使用 `ada
|
||||
from: "openclaw",
|
||||
remoteWorkspaceDir: "/sandbox",
|
||||
remoteAgentWorkspaceDir: "/agent",
|
||||
gateway: "lab", // optional
|
||||
gatewayEndpoint: "https://lab.example", // optional
|
||||
policy: "strict", // optional OpenShell policy id
|
||||
providers: ["openai"], // optional
|
||||
gateway: "lab", // 可选
|
||||
gatewayEndpoint: "https://lab.example", // 可选
|
||||
policy: "strict", // 可选 OpenShell 策略 id
|
||||
providers: ["openai"], // 可选
|
||||
autoProviders: true,
|
||||
timeoutSeconds: 120,
|
||||
},
|
||||
@ -819,30 +820,30 @@ Anthropic Claude 4.6 模型在未显式设置思考级别时,默认使用 `ada
|
||||
|
||||
**OpenShell 模式:**
|
||||
|
||||
- `mirror`:在执行前将本地内容初始化到远程,执行后再同步回本地;本地工作区保持为规范副本
|
||||
- `remote`:在创建沙箱时仅向远程初始化一次,此后保持远程工作区为规范副本
|
||||
- `mirror`:在执行前将本地内容填充到远程,执行后再同步回本地;本地工作区保持为标准状态
|
||||
- `remote`:在创建沙箱时仅对远程执行一次初始化填充,之后保持远程工作区为标准状态
|
||||
|
||||
在 `remote` 模式下,在 OpenClaw 之外于主机本地所做的编辑,在初始化步骤之后不会自动同步到沙箱中。
|
||||
传输方式是通过 SSH 连接到 OpenShell 沙箱,但插件负责沙箱生命周期以及可选的镜像同步。
|
||||
在 `remote` 模式下,于 OpenClaw 外部在主机本地进行的编辑,在初始化填充步骤之后不会自动同步到沙箱中。
|
||||
传输层使用 SSH 连接到 OpenShell 沙箱,但插件负责沙箱生命周期以及可选的镜像同步。
|
||||
|
||||
**`setupCommand`** 会在容器创建后运行一次(通过 `sh -lc`)。它需要网络出口、可写根文件系统以及 root 用户。
|
||||
**`setupCommand`** 会在容器创建后运行一次(通过 `sh -lc`)。需要网络出口、可写根文件系统和 root 用户。
|
||||
|
||||
**容器默认使用 `network: "none"`** —— 如果智能体需要出站访问,请设置为 `"bridge"`(或自定义桥接网络)。
|
||||
`"host"` 会被阻止。默认也会阻止 `"container:<id>"`,除非你显式设置
|
||||
**容器默认使用 `network: "none"`** ——如果智能体需要出站访问,请设置为 `"bridge"`(或自定义 bridge 网络)。
|
||||
默认会阻止使用 `"host"`。默认也会阻止使用 `"container:<id>"`,除非你显式设置
|
||||
`sandbox.docker.dangerouslyAllowContainerNamespaceJoin: true`(破窗开关)。
|
||||
|
||||
**入站附件** 会被暂存到活动工作区中的 `media/inbound/*`。
|
||||
**入站附件** 会被暂存到当前活动工作区中的 `media/inbound/*`。
|
||||
|
||||
**`docker.binds`** 会挂载额外的主机目录;全局和按智能体的挂载会合并。
|
||||
**`docker.binds`** 会挂载额外的主机目录;全局和按智能体的 binds 会合并。
|
||||
|
||||
**沙箱浏览器**(`sandbox.browser.enabled`):在容器中运行 Chromium + CDP。noVNC URL 会注入到系统提示中。不需要在 `openclaw.json` 中启用 `browser.enabled`。
|
||||
noVNC 观察者访问默认使用 VNC 认证,OpenClaw 会发出短时有效的 token URL(而不是在共享 URL 中暴露密码)。
|
||||
**沙箱隔离浏览器**(`sandbox.browser.enabled`):在容器中运行 Chromium + CDP。noVNC URL 会注入到系统提示中。不需要在 `openclaw.json` 中启用 `browser.enabled`。
|
||||
默认情况下,noVNC 观察者访问使用 VNC 认证,OpenClaw 会发出带短时效 token 的 URL(而不是在共享 URL 中暴露密码)。
|
||||
|
||||
- `allowHostControl: false`(默认)会阻止沙箱会话将主机浏览器作为目标。
|
||||
- `network` 默认是 `openclaw-sandbox-browser`(专用桥接网络)。只有在你明确需要全局桥接连通性时,才设置为 `bridge`。
|
||||
- `cdpSourceRange` 可选择将容器边缘的 CDP 入站限制为某个 CIDR 范围(例如 `172.21.0.1/32`)。
|
||||
- `sandbox.browser.binds` 仅将额外的主机目录挂载到沙箱浏览器容器中。设置后(包括 `[]`),它会替换浏览器容器的 `docker.binds`。
|
||||
- 启动默认值定义在 `scripts/sandbox-browser-entrypoint.sh` 中,并针对容器主机进行了调优:
|
||||
- `allowHostControl: false`(默认)会阻止沙箱隔离会话以主机浏览器为目标。
|
||||
- `network` 默认值为 `openclaw-sandbox-browser`(专用 bridge 网络)。仅在你明确需要全局 bridge 连通性时才设置为 `bridge`。
|
||||
- `cdpSourceRange` 可选择将容器边缘的 CDP 入站限制到某个 CIDR 范围(例如 `172.21.0.1/32`)。
|
||||
- `sandbox.browser.binds` 只会将额外的主机目录挂载到沙箱浏览器容器中。设置后(包括 `[]`),它会替换浏览器容器的 `docker.binds`。
|
||||
- 启动默认值定义在 `scripts/sandbox-browser-entrypoint.sh` 中,并针对容器主机做了调优:
|
||||
- `--remote-debugging-address=127.0.0.1`
|
||||
- `--remote-debugging-port=<derived from OPENCLAW_BROWSER_CDP_PORT>`
|
||||
- `--user-data-dir=${HOME}/.chrome`
|
||||
@ -861,26 +862,26 @@ noVNC 观察者访问默认使用 VNC 认证,OpenClaw 会发出短时有效的
|
||||
- `--metrics-recording-only`
|
||||
- `--disable-extensions`(默认启用)
|
||||
- `--disable-3d-apis`、`--disable-software-rasterizer` 和 `--disable-gpu`
|
||||
默认启用;如果 WebGL/3D 使用场景需要它们,可通过
|
||||
`OPENCLAW_BROWSER_DISABLE_GRAPHICS_FLAGS=0` 禁用这些标志。
|
||||
- `OPENCLAW_BROWSER_DISABLE_EXTENSIONS=0` 会重新启用扩展,如果你的工作流
|
||||
依赖于它们。
|
||||
默认启用;如果 WebGL / 3D 使用场景需要,可通过
|
||||
`OPENCLAW_BROWSER_DISABLE_GRAPHICS_FLAGS=0` 禁用它们。
|
||||
- 如果你的工作流依赖扩展,可通过
|
||||
`OPENCLAW_BROWSER_DISABLE_EXTENSIONS=0` 重新启用扩展。
|
||||
- `--renderer-process-limit=2` 可通过
|
||||
`OPENCLAW_BROWSER_RENDERER_PROCESS_LIMIT=<N>` 修改;设置为 `0` 将使用 Chromium 的
|
||||
`OPENCLAW_BROWSER_RENDERER_PROCESS_LIMIT=<N>` 修改;设置为 `0` 可使用 Chromium 的
|
||||
默认进程限制。
|
||||
- 以及当启用 `noSandbox` 时的 `--no-sandbox` 和 `--disable-setuid-sandbox`。
|
||||
- 这些默认值是容器镜像基线;如果要更改容器默认值,请使用带自定义
|
||||
入口点的自定义浏览器镜像。
|
||||
- 当启用 `noSandbox` 时,还会附加 `--no-sandbox` 和 `--disable-setuid-sandbox`。
|
||||
- 这些默认值是容器镜像的基线;如果要更改容器默认值,请使用带自定义
|
||||
entrypoint 的自定义浏览器镜像。
|
||||
|
||||
</Accordion>
|
||||
|
||||
浏览器沙箱隔离和 `sandbox.docker.binds` 仅适用于 Docker。
|
||||
浏览器沙箱隔离和 `sandbox.docker.binds` 仅支持 Docker。
|
||||
|
||||
构建镜像:
|
||||
|
||||
```bash
|
||||
scripts/sandbox-setup.sh # 主沙箱镜像
|
||||
scripts/sandbox-browser-setup.sh # 可选浏览器镜像
|
||||
scripts/sandbox-browser-setup.sh # 可选的浏览器镜像
|
||||
```
|
||||
|
||||
### `agents.list`(按智能体覆盖)
|
||||
@ -895,13 +896,13 @@ scripts/sandbox-browser-setup.sh # 可选浏览器镜像
|
||||
name: "Main Agent",
|
||||
workspace: "~/.openclaw/workspace",
|
||||
agentDir: "~/.openclaw/agents/main/agent",
|
||||
model: "anthropic/claude-opus-4-6", // or { primary, fallbacks }
|
||||
thinkingDefault: "high", // per-agent thinking level override
|
||||
reasoningDefault: "on", // per-agent reasoning visibility override
|
||||
fastModeDefault: false, // per-agent fast mode override
|
||||
model: "anthropic/claude-opus-4-6", // 或 { primary, fallbacks }
|
||||
thinkingDefault: "high", // 按智能体覆盖思考级别
|
||||
reasoningDefault: "on", // 按智能体覆盖推理可见性
|
||||
fastModeDefault: false, // 按智能体覆盖快速模式
|
||||
embeddedHarness: { runtime: "auto", fallback: "pi" },
|
||||
params: { cacheRetention: "none" }, // overrides matching defaults.models params by key
|
||||
skills: ["docs-search"], // replaces agents.defaults.skills when set
|
||||
params: { cacheRetention: "none" }, // 按键覆盖匹配的 defaults.models params
|
||||
skills: ["docs-search"], // 设置后会替换 agents.defaults.skills
|
||||
identity: {
|
||||
name: "Samantha",
|
||||
theme: "helpful sloth",
|
||||
@ -933,26 +934,26 @@ scripts/sandbox-browser-setup.sh # 可选浏览器镜像
|
||||
```
|
||||
|
||||
- `id`:稳定的智能体 id(必填)。
|
||||
- `default`:当设置了多个时,以第一个为准(会记录警告)。如果都未设置,则列表中的第一个条目为默认值。
|
||||
- `model`:字符串形式仅覆盖 `primary`;对象形式 `{ primary, fallbacks }` 会同时覆盖两者(`[]` 会禁用全局故障切换)。只覆盖 `primary` 的 cron 作业仍会继承默认故障切换,除非你设置 `fallbacks: []`。
|
||||
- `params`:按智能体的流参数,会合并覆盖到 `agents.defaults.models` 中选定模型条目之上。可用于为特定智能体覆盖 `cacheRetention`、`temperature` 或 `maxTokens`,而无需复制整个模型目录。
|
||||
- `skills`:可选的按智能体 Skills 允许列表。如果省略,则在已设置时该智能体会继承 `agents.defaults.skills`;显式列表会替换默认值而不是合并,`[]` 表示无 Skills。
|
||||
- `thinkingDefault`:可选的按智能体默认思考级别(`off | minimal | low | medium | high | xhigh | adaptive | max`)。当未设置按消息或按会话覆盖时,会覆盖该智能体的 `agents.defaults.thinkingDefault`。所选提供商/模型配置决定哪些值有效;对于 Google Gemini,`adaptive` 会保留由提供商控制的动态思考(Gemini 3/3.1 上省略 `thinkingLevel`,Gemini 2.5 上使用 `thinkingBudget: -1`)。
|
||||
- `reasoningDefault`:可选的按智能体默认推理可见性(`on | off | stream`)。当未设置按消息或按会话的推理覆盖时生效。
|
||||
- `fastModeDefault`:可选的按智能体快速模式默认值(`true | false`)。当未设置按消息或按会话的快速模式覆盖时生效。
|
||||
- `default`:如果设置了多个,以第一个为准(会记录警告)。如果一个都没设置,则列表中的第一个条目为默认值。
|
||||
- `model`:字符串形式仅覆盖 `primary`;对象形式 `{ primary, fallbacks }` 同时覆盖两者(`[]` 会禁用全局回退)。仅覆盖 `primary` 的 cron 任务仍会继承默认回退,除非你设置 `fallbacks: []`。
|
||||
- `params`:按智能体的流参数,会合并到 `agents.defaults.models` 中所选模型条目之上。用于按智能体覆盖 `cacheRetention`、`temperature` 或 `maxTokens` 等参数,而无需复制整个模型目录。
|
||||
- `skills`:可选的按智能体 Skills 允许列表。如果省略,当 `agents.defaults.skills` 已设置时,智能体会继承它;显式列表会替换默认值而不是合并,`[]` 表示无 Skills。
|
||||
- `thinkingDefault`:可选的按智能体默认思考级别(`off | minimal | low | medium | high | xhigh | adaptive | max`)。当未设置按消息或按会话覆盖时,它会覆盖该智能体的 `agents.defaults.thinkingDefault`。所选提供商 / 模型配置决定哪些值有效;对于 Google Gemini,`adaptive` 会保留由提供商控制的动态思考(在 Gemini 3 / 3.1 上省略 `thinkingLevel`,在 Gemini 2.5 上设置 `thinkingBudget: -1`)。
|
||||
- `reasoningDefault`:可选的按智能体默认推理可见性(`on | off | stream`)。当未设置按消息或按会话推理覆盖时生效。
|
||||
- `fastModeDefault`:可选的按智能体快速模式默认值(`true | false`)。当未设置按消息或按会话快速模式覆盖时生效。
|
||||
- `embeddedHarness`:可选的按智能体底层 harness 策略覆盖。使用 `{ runtime: "codex" }` 可让某个智能体仅使用 Codex,而其他智能体在 `auto` 模式下继续保留默认的 PI 回退。
|
||||
- `runtime`:可选的按智能体运行时描述符。当智能体应默认使用 ACP harness 会话时,使用 `type: "acp"` 并设置 `runtime.acp` 默认值(`agent`、`backend`、`mode`、`cwd`)。
|
||||
- `identity.avatar`:工作区相对路径、`http(s)` URL 或 `data:` URI。
|
||||
- `identity` 会派生默认值:`ackReaction` 来自 `emoji`,`mentionPatterns` 来自 `name`/`emoji`。
|
||||
- `subagents.allowAgents`:用于 `sessions_spawn` 的智能体 id 允许列表(`["*"]` = 任意;默认:仅同一智能体)。
|
||||
- 沙箱继承保护:如果请求方会话处于沙箱中,`sessions_spawn` 会拒绝会导致目标在非沙箱中运行的请求。
|
||||
- `runtime`:可选的按智能体运行时描述符。当智能体应默认使用 ACP harness 会话时,使用 `type: "acp"` 和 `runtime.acp` 默认值(`agent`、`backend`、`mode`、`cwd`)。
|
||||
- `identity.avatar`:工作区相对路径、`http(s)` URL,或 `data:` URI。
|
||||
- `identity` 会派生默认值:`ackReaction` 来自 `emoji`,`mentionPatterns` 来自 `name` / `emoji`。
|
||||
- `subagents.allowAgents`:`sessions_spawn` 的智能体 id 允许列表(`["*"]` = 任意;默认:仅相同智能体)。
|
||||
- 沙箱继承保护:如果请求方会话处于沙箱隔离中,`sessions_spawn` 会拒绝那些会以非沙箱方式运行的目标。
|
||||
- `subagents.requireAgentId`:为 true 时,会阻止省略 `agentId` 的 `sessions_spawn` 调用(强制显式选择配置;默认:false)。
|
||||
|
||||
---
|
||||
|
||||
## 多智能体路由
|
||||
|
||||
在一个 Gateway 网关中运行多个彼此隔离的智能体。参见[多智能体](/zh-CN/concepts/multi-agent)。
|
||||
在一个 Gateway 网关中运行多个相互隔离的智能体。参见 [多智能体](/zh-CN/concepts/multi-agent)。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -971,25 +972,25 @@ scripts/sandbox-browser-setup.sh # 可选浏览器镜像
|
||||
|
||||
### 绑定匹配字段
|
||||
|
||||
- `type`(可选):普通路由使用 `route`(缺失时默认是 route),持久 ACP 会话绑定使用 `acp`
|
||||
- `type`(可选):正常路由使用 `route`(缺失时默认就是 `route`),持久 ACP 对话绑定使用 `acp`。
|
||||
- `match.channel`(必填)
|
||||
- `match.accountId`(可选;`*` = 任意账号;省略 = 默认账号)
|
||||
- `match.peer`(可选;`{ kind: direct|group|channel, id }`)
|
||||
- `match.guildId` / `match.teamId`(可选;特定于渠道)
|
||||
- `match.guildId` / `match.teamId`(可选;渠道特定)
|
||||
- `acp`(可选;仅用于 `type: "acp"`):`{ mode, label, cwd, backend }`
|
||||
|
||||
**确定性匹配顺序:**
|
||||
**确定性的匹配顺序:**
|
||||
|
||||
1. `match.peer`
|
||||
2. `match.guildId`
|
||||
3. `match.teamId`
|
||||
4. `match.accountId`(精确匹配,无 peer/guild/team)
|
||||
4. `match.accountId`(精确匹配,无 peer / guild / team)
|
||||
5. `match.accountId: "*"`(整个渠道范围)
|
||||
6. 默认智能体
|
||||
|
||||
在每一层内,第一个匹配的 `bindings` 条目获胜。
|
||||
在每一层内,第一个匹配的 `bindings` 条目胜出。
|
||||
|
||||
对于 `type: "acp"` 条目,OpenClaw 会按精确会话标识(`match.channel` + 账号 + `match.peer.id`)解析,不使用上面的 route 绑定层级顺序。
|
||||
对于 `type: "acp"` 条目,OpenClaw 会按精确对话标识(`match.channel` + 账号 + `match.peer.id`)解析,不使用上面的 route 绑定层级顺序。
|
||||
|
||||
### 按智能体的访问配置
|
||||
|
||||
@ -1040,7 +1041,7 @@ scripts/sandbox-browser-setup.sh # 可选浏览器镜像
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="无文件系统访问(仅消息传递)">
|
||||
<Accordion title="无文件系统访问(仅消息)">
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -1086,7 +1087,7 @@ scripts/sandbox-browser-setup.sh # 可选浏览器镜像
|
||||
|
||||
</Accordion>
|
||||
|
||||
有关优先级细节,请参阅[多智能体沙箱隔离与工具](/zh-CN/tools/multi-agent-sandbox-tools)。
|
||||
有关优先级详情,请参阅 [多智能体沙箱隔离与工具](/zh-CN/tools/multi-agent-sandbox-tools)。
|
||||
|
||||
---
|
||||
|
||||
@ -1112,20 +1113,20 @@ scripts/sandbox-browser-setup.sh # 可选浏览器镜像
|
||||
},
|
||||
resetTriggers: ["/new", "/reset"],
|
||||
store: "~/.openclaw/agents/{agentId}/sessions/sessions.json",
|
||||
parentForkMaxTokens: 100000, // 父线程 token 数超过此值时跳过父线程分叉(0 表示禁用)
|
||||
parentForkMaxTokens: 100000, // 超过此 token 数时跳过父线程 fork(0 表示禁用)
|
||||
maintenance: {
|
||||
mode: "warn", // warn | enforce
|
||||
pruneAfter: "30d",
|
||||
maxEntries: 500,
|
||||
rotateBytes: "10mb",
|
||||
resetArchiveRetention: "30d", // duration or false
|
||||
maxDiskBytes: "500mb", // optional hard budget
|
||||
highWaterBytes: "400mb", // optional cleanup target
|
||||
resetArchiveRetention: "30d", // 时长或 false
|
||||
maxDiskBytes: "500mb", // 可选硬预算
|
||||
highWaterBytes: "400mb", // 可选清理目标
|
||||
},
|
||||
threadBindings: {
|
||||
enabled: true,
|
||||
idleHours: 24, // 默认按不活动时间自动取消聚焦的小时数(`0` 表示禁用)
|
||||
maxAgeHours: 0, // 默认硬性最长存续小时数(`0` 表示禁用)
|
||||
idleHours: 24, // 默认按小时计算的不活动自动失焦时间(`0` 表示禁用)
|
||||
maxAgeHours: 0, // 默认按小时计算的硬性最大时长(`0` 表示禁用)
|
||||
},
|
||||
mainKey: "main", // 旧版字段(运行时始终使用 "main")
|
||||
agentToAgent: { maxPingPongTurns: 5 },
|
||||
@ -1139,35 +1140,35 @@ scripts/sandbox-browser-setup.sh # 可选浏览器镜像
|
||||
|
||||
<Accordion title="会话字段详情">
|
||||
|
||||
- **`scope`**:群聊上下文中的基础会话分组策略。
|
||||
- `per-sender`(默认):在某个渠道上下文中,每个发送者都有独立会话。
|
||||
- `global`:某个渠道上下文中的所有参与者共享同一个会话(仅在确实需要共享上下文时使用)。
|
||||
- **`scope`**:群聊上下文的基础会话分组策略。
|
||||
- `per-sender`(默认):在一个渠道上下文中,每个发送者都有独立的会话。
|
||||
- `global`:一个渠道上下文中的所有参与者共享同一个会话(仅在确实需要共享上下文时使用)。
|
||||
- **`dmScope`**:私信的分组方式。
|
||||
- `main`:所有私信共享主会话。
|
||||
- `per-peer`:按发送者 id 跨渠道隔离。
|
||||
- `per-peer`:跨渠道按发送者 id 隔离。
|
||||
- `per-channel-peer`:按渠道 + 发送者隔离(推荐用于多用户收件箱)。
|
||||
- `per-account-channel-peer`:按账号 + 渠道 + 发送者隔离(推荐用于多账号)。
|
||||
- **`identityLinks`**:将规范 id 映射到带提供商前缀的 peer,用于跨渠道共享会话。
|
||||
- **`reset`**:主重置策略。`daily` 会在本地时间 `atHour` 重置;`idle` 会在空闲 `idleMinutes` 后重置。如果两者都已配置,则先到期者生效。
|
||||
- **`resetByType`**:按类型的覆盖项(`direct`、`group`、`thread`)。旧版 `dm` 仍接受,作为 `direct` 的别名。
|
||||
- **`parentForkMaxTokens`**:创建分叉线程会话时,父会话允许的最大 `totalTokens`(默认 `100000`)。
|
||||
- 如果父会话的 `totalTokens` 高于此值,OpenClaw 会启动一个全新的线程会话,而不是继承父转录历史。
|
||||
- 设置为 `0` 可禁用此保护,并始终允许父会话分叉。
|
||||
- **`mainKey`**:旧版字段。运行时始终对主私聊桶使用 `"main"`。
|
||||
- **`agentToAgent.maxPingPongTurns`**:智能体之间来回对话时允许的最大回复轮数(整数,范围:`0`–`5`)。`0` 表示禁用来回链式对话。
|
||||
- **`sendPolicy`**:按 `channel`、`chatType`(`direct|group|channel`,旧版 `dm` 仍可作为别名)、`keyPrefix` 或 `rawKeyPrefix` 匹配。第一个 deny 规则优先。
|
||||
- **`identityLinks`**:将标准 id 映射到带提供商前缀的 peer,以支持跨渠道共享会话。
|
||||
- **`reset`**:主重置策略。`daily` 会在本地时间 `atHour` 重置;`idle` 会在 `idleMinutes` 后重置。如果两者都配置,谁先到期就以谁为准。
|
||||
- **`resetByType`**:按类型覆盖(`direct`、`group`、`thread`)。旧版 `dm` 仍可作为 `direct` 的别名。
|
||||
- **`parentForkMaxTokens`**:创建 fork 线程会话时,父会话允许的最大 `totalTokens`(默认 `100000`)。
|
||||
- 如果父会话的 `totalTokens` 高于此值,OpenClaw 会启动一个全新的线程会话,而不是继承父 transcript 历史。
|
||||
- 设置为 `0` 可禁用此保护,并始终允许父级 fork。
|
||||
- **`mainKey`**:旧版字段。运行时始终对主私聊分桶使用 `"main"`。
|
||||
- **`agentToAgent.maxPingPongTurns`**:智能体之间进行智能体到智能体交互时,允许的最大往返回复轮次(整数,范围:`0`–`5`)。`0` 会禁用 ping-pong 链式交互。
|
||||
- **`sendPolicy`**:可按 `channel`、`chatType`(`direct|group|channel`,旧版 `dm` 为别名)、`keyPrefix` 或 `rawKeyPrefix` 匹配。第一个 deny 优先生效。
|
||||
- **`maintenance`**:会话存储清理 + 保留控制。
|
||||
- `mode`:`warn` 仅发出警告;`enforce` 执行清理。
|
||||
- `pruneAfter`:陈旧条目的保留截止时间(默认 `30d`)。
|
||||
- `maxEntries`:`sessions.json` 中的最大条目数(默认 `500`)。
|
||||
- `mode`:`warn` 仅发出警告;`enforce` 会实际执行清理。
|
||||
- `pruneAfter`:过期条目的年龄截止值(默认 `30d`)。
|
||||
- `maxEntries`:`sessions.json` 中允许的最大条目数(默认 `500`)。
|
||||
- `rotateBytes`:当 `sessions.json` 超过该大小时进行轮转(默认 `10mb`)。
|
||||
- `resetArchiveRetention`:`*.reset.<timestamp>` 转录归档的保留时长。默认跟随 `pruneAfter`;设为 `false` 可禁用。
|
||||
- `maxDiskBytes`:可选的会话目录磁盘硬预算。在 `warn` 模式下会记录警告;在 `enforce` 模式下会优先删除最旧的产物/会话。
|
||||
- `resetArchiveRetention`:`*.reset.<timestamp>` transcript 归档的保留时长。默认与 `pruneAfter` 一致;设置为 `false` 可禁用。
|
||||
- `maxDiskBytes`:可选的 sessions 目录磁盘预算。在 `warn` 模式下仅记录警告;在 `enforce` 模式下会优先删除最旧的工件 / 会话。
|
||||
- `highWaterBytes`:预算清理后的可选目标值。默认是 `maxDiskBytes` 的 `80%`。
|
||||
- **`threadBindings`**:线程绑定会话功能的全局默认值。
|
||||
- `enabled`:主默认开关(提供商可覆盖;Discord 使用 `channels.discord.threadBindings.enabled`)
|
||||
- `idleHours`:默认按不活动时间自动取消聚焦的小时数(`0` 表示禁用;提供商可覆盖)
|
||||
- `maxAgeHours`:默认硬性最长存续小时数(`0` 表示禁用;提供商可覆盖)
|
||||
- `idleHours`:默认按小时计算的不活动自动失焦时间(`0` 表示禁用;提供商可覆盖)
|
||||
- `maxAgeHours`:默认按小时计算的硬性最大时长(`0` 表示禁用;提供商可覆盖)
|
||||
|
||||
</Accordion>
|
||||
|
||||
@ -1205,36 +1206,36 @@ scripts/sandbox-browser-setup.sh # 可选浏览器镜像
|
||||
|
||||
### 响应前缀
|
||||
|
||||
按渠道/账号覆盖:`channels.<channel>.responsePrefix`、`channels.<channel>.accounts.<id>.responsePrefix`。
|
||||
按渠道 / 账号覆盖:`channels.<channel>.responsePrefix`、`channels.<channel>.accounts.<id>.responsePrefix`。
|
||||
|
||||
解析顺序(越具体越优先):账号 → 渠道 → 全局。`""` 会禁用并停止继续回退。`"auto"` 会派生为 `[{identity.name}]`。
|
||||
解析顺序(最具体者优先):账号 → 渠道 → 全局。`""` 会禁用并停止级联。`"auto"` 会派生为 `[{identity.name}]`。
|
||||
|
||||
**模板变量:**
|
||||
|
||||
| 变量 | 说明 | 示例 |
|
||||
| ----------------- | -------------- | --------------------------- |
|
||||
| `{model}` | 短模型名 | `claude-opus-4-6` |
|
||||
| `{modelFull}` | 完整模型标识符 | `anthropic/claude-opus-4-6` |
|
||||
| `{provider}` | 提供商名称 | `anthropic` |
|
||||
| `{thinkingLevel}` | 当前思考级别 | `high`、`low`、`off` |
|
||||
| `{identity.name}` | 智能体身份名称 | (与 `"auto"` 相同) |
|
||||
| 变量 | 说明 | 示例 |
|
||||
| ----------------- | ---------------- | --------------------------- |
|
||||
| `{model}` | 短模型名 | `claude-opus-4-6` |
|
||||
| `{modelFull}` | 完整模型标识符 | `anthropic/claude-opus-4-6` |
|
||||
| `{provider}` | 提供商名称 | `anthropic` |
|
||||
| `{thinkingLevel}` | 当前思考级别 | `high`、`low`、`off` |
|
||||
| `{identity.name}` | 智能体身份名称 | (与 `"auto"` 相同) |
|
||||
|
||||
变量不区分大小写。`{think}` 是 `{thinkingLevel}` 的别名。
|
||||
|
||||
### 确认反应
|
||||
|
||||
- 默认使用活动智能体的 `identity.emoji`,否则为 `"👀"`。设置为 `""` 可禁用。
|
||||
- 默认使用当前智能体的 `identity.emoji`,否则为 `"👀"`。设置为 `""` 可禁用。
|
||||
- 按渠道覆盖:`channels.<channel>.ackReaction`、`channels.<channel>.accounts.<id>.ackReaction`。
|
||||
- 解析顺序:账号 → 渠道 → `messages.ackReaction` → identity 回退值。
|
||||
- 解析顺序:账号 → 渠道 → `messages.ackReaction` → identity 回退。
|
||||
- 作用域:`group-mentions`(默认)、`group-all`、`direct`、`all`。
|
||||
- `removeAckAfterReply`:在 Slack、Discord 和 Telegram 上,回复后移除确认反应。
|
||||
- `messages.statusReactions.enabled`:在 Slack、Discord 和 Telegram 上启用生命周期状态反应。
|
||||
在 Slack 和 Discord 上,未设置时如果确认反应处于激活状态,则状态反应保持启用。
|
||||
在 Telegram 上,需显式设为 `true` 才会启用生命周期状态反应。
|
||||
在 Slack 和 Discord 上,未设置时,如果确认反应处于启用状态,则状态反应保持启用。
|
||||
在 Telegram 上,需显式将其设置为 `true` 才会启用生命周期状态反应。
|
||||
|
||||
### 入站防抖
|
||||
### 入站去抖
|
||||
|
||||
将同一发送者的快速连续纯文本消息批处理为单个智能体轮次。媒体/附件会立即触发发送。控制命令会绕过防抖。
|
||||
将来自同一发送者的快速纯文本消息批处理为一次智能体轮次。媒体 / 附件会立即刷新。控制命令会绕过去抖。
|
||||
|
||||
### TTS(文本转语音)
|
||||
|
||||
@ -1250,45 +1251,47 @@ scripts/sandbox-browser-setup.sh # 可选浏览器镜像
|
||||
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,
|
||||
providers: {
|
||||
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",
|
||||
baseUrl: "https://api.openai.com/v1",
|
||||
model: "gpt-4o-mini-tts",
|
||||
voice: "alloy",
|
||||
},
|
||||
},
|
||||
openai: {
|
||||
apiKey: "openai_api_key",
|
||||
baseUrl: "https://api.openai.com/v1",
|
||||
model: "gpt-4o-mini-tts",
|
||||
voice: "alloy",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
- `auto` 控制默认自动 TTS 模式:`off`、`always`、`inbound` 或 `tagged`。`/tts on|off` 可以覆盖本地偏好设置,`/tts status` 会显示实际生效状态。
|
||||
- `summaryModel` 会覆盖自动摘要所使用的 `agents.defaults.model.primary`。
|
||||
- `modelOverrides` 默认启用;`modelOverrides.allowProvider` 默认是 `false`(需主动启用)。
|
||||
- API 密钥会回退到 `ELEVENLABS_API_KEY`/`XI_API_KEY` 和 `OPENAI_API_KEY`。
|
||||
- `openai.baseUrl` 会覆盖 OpenAI TTS 端点。解析顺序是配置,然后是 `OPENAI_TTS_BASE_URL`,最后是 `https://api.openai.com/v1`。
|
||||
- 当 `openai.baseUrl` 指向非 OpenAI 端点时,OpenClaw 会将其视为兼容 OpenAI 的 TTS 服务器,并放宽对模型/语音的校验。
|
||||
- `auto` 控制默认的自动 TTS 模式:`off`、`always`、`inbound` 或 `tagged`。`/tts on|off` 可覆盖本地偏好,`/tts status` 会显示生效状态。
|
||||
- `summaryModel` 会覆盖用于自动摘要的 `agents.defaults.model.primary`。
|
||||
- `modelOverrides` 默认启用;`modelOverrides.allowProvider` 默认为 `false`(需显式启用)。
|
||||
- API key 会回退到 `ELEVENLABS_API_KEY` / `XI_API_KEY` 和 `OPENAI_API_KEY`。
|
||||
- `providers.openai.baseUrl` 会覆盖 OpenAI TTS 端点。解析顺序为配置,然后是 `OPENAI_TTS_BASE_URL`,最后是 `https://api.openai.com/v1`。
|
||||
- 当 `providers.openai.baseUrl` 指向非 OpenAI 端点时,OpenClaw 会将其视为兼容 OpenAI 的 TTS 服务器,并放宽模型 / 声音校验。
|
||||
|
||||
---
|
||||
|
||||
## 对话
|
||||
|
||||
对话模式的默认设置(macOS/iOS/Android)。
|
||||
对话模式默认设置(macOS / iOS / Android)。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -1312,18 +1315,18 @@ scripts/sandbox-browser-setup.sh # 可选浏览器镜像
|
||||
}
|
||||
```
|
||||
|
||||
- `talk.provider` 在配置了多个对话提供商时,必须匹配 `talk.providers` 中的某个键。
|
||||
- 旧版扁平 Talk 键(`talk.voiceId`、`talk.voiceAliases`、`talk.modelId`、`talk.outputFormat`、`talk.apiKey`)仅用于兼容,并会自动迁移到 `talk.providers.<provider>`。
|
||||
- 语音 id 会回退到 `ELEVENLABS_VOICE_ID` 或 `SAG_VOICE_ID`。
|
||||
- 当配置了多个对话提供商时,`talk.provider` 必须匹配 `talk.providers` 中的某个键。
|
||||
- 旧版扁平 Talk 键(`talk.voiceId`、`talk.voiceAliases`、`talk.modelId`、`talk.outputFormat`、`talk.apiKey`)仅为兼容而保留,并会自动迁移到 `talk.providers.<provider>`。
|
||||
- Voice ID 会回退到 `ELEVENLABS_VOICE_ID` 或 `SAG_VOICE_ID`。
|
||||
- `providers.*.apiKey` 接受明文字符串或 SecretRef 对象。
|
||||
- 只有在未配置对话 API 密钥时,才会应用 `ELEVENLABS_API_KEY` 回退。
|
||||
- `providers.*.voiceAliases` 允许对话指令使用友好名称。
|
||||
- `silenceTimeoutMs` 控制对话模式在用户停止说话后等待多久才发送转录。未设置时,将保持平台默认停顿窗口(`macOS 和 Android 为 700 ms,iOS 为 900 ms`)。
|
||||
- 只有在未配置 Talk API key 时,才会应用 `ELEVENLABS_API_KEY` 回退。
|
||||
- `providers.*.voiceAliases` 让对话指令可以使用易读名称。
|
||||
- `silenceTimeoutMs` 控制在用户静音后,对话模式等待多久才发送 transcript。未设置时会保留平台默认停顿窗口(`macOS 和 Android 为 700 ms,iOS 为 900 ms`)。
|
||||
|
||||
---
|
||||
|
||||
## 相关内容
|
||||
|
||||
- [配置参考](/zh-CN/gateway/configuration-reference) —— 所有其他配置键
|
||||
- [配置](/zh-CN/gateway/configuration) —— 常见任务和快速设置
|
||||
- [配置参考](/zh-CN/gateway/configuration-reference) — 所有其他配置键
|
||||
- [配置](/zh-CN/gateway/configuration) — 常见任务和快速设置
|
||||
- [配置示例](/zh-CN/gateway/configuration-examples)
|
||||
|
||||
@ -2,32 +2,32 @@
|
||||
read_when:
|
||||
- 你需要精确到字段级别的配置语义或默认值
|
||||
- 你正在验证渠道、模型、Gateway 网关或工具配置块
|
||||
summary: 核心 OpenClaw 键名、默认值及专用子系统参考链接的 Gateway 网关配置参考
|
||||
summary: Gateway 网关配置参考,涵盖 OpenClaw 核心键名、默认值以及指向各专用子系统参考文档的链接
|
||||
title: 配置参考
|
||||
x-i18n:
|
||||
generated_at: "2026-04-25T00:40:41Z"
|
||||
generated_at: "2026-04-25T02:35:32Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: 1405f1a1de10197ab38ca8ef18832b83636c49a3b82d136450c4d2bf27d457e0
|
||||
source_hash: 5c844b2af8d431d6bc090f128b6a2415254f284196f2c6612ed35bd5502f26bb
|
||||
source_path: gateway/configuration-reference.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
`~/.openclaw/openclaw.json` 的核心配置参考。若需面向任务的概览,请参见 [配置](/zh-CN/gateway/configuration)。
|
||||
`~/.openclaw/openclaw.json` 的核心配置参考。若想查看面向任务的概览,请参见 [配置](/zh-CN/gateway/configuration)。
|
||||
|
||||
本页介绍 OpenClaw 的主要配置界面,并在某个子系统拥有更深入的独立参考时提供链接。它**不会**尝试在单个页面中内联每个渠道/插件拥有的命令目录,或每个深层 memory/QMD 调节项。
|
||||
本页介绍 OpenClaw 的主要配置面,并在某个子系统拥有自己更深入的参考文档时提供跳转链接。它**不会**尝试在单页中内联每个渠道/插件自有的命令目录,也不会内联所有深入的 memory/QMD 旋钮。
|
||||
|
||||
代码中的真实依据:
|
||||
代码真相:
|
||||
|
||||
- `openclaw config schema` 会打印用于验证和 Control UI 的实时 JSON Schema,并在可用时合并内置/插件/渠道元数据
|
||||
- `config.schema.lookup` 会返回一个按路径限定的 schema 节点,供钻取式工具使用
|
||||
- `pnpm config:docs:check` / `pnpm config:docs:gen` 会根据当前 schema 界面验证配置文档基线哈希
|
||||
- `config.schema.lookup` 会返回一个按路径范围限定的 schema 节点,用于深入查看工具
|
||||
- `pnpm config:docs:check` / `pnpm config:docs:gen` 会根据当前 schema 面验证配置文档基线哈希
|
||||
|
||||
专用深度参考:
|
||||
专用深入参考:
|
||||
|
||||
- [内存配置参考](/zh-CN/reference/memory-config),适用于 `agents.defaults.memorySearch.*`、`memory.qmd.*`、`memory.citations`,以及位于 `plugins.entries.memory-core.config.dreaming` 下的 Dreaming 配置
|
||||
- [Slash Commands](/zh-CN/tools/slash-commands),适用于当前内置 + 内置打包的命令目录
|
||||
- 各自所属的渠道/插件页面,适用于渠道特定的命令界面
|
||||
- [斜杠命令](/zh-CN/tools/slash-commands),适用于当前内建 + 内置的命令目录
|
||||
- 对应渠道/插件页面,适用于特定渠道的命令面
|
||||
|
||||
配置格式为 **JSON5**(允许注释和尾随逗号)。所有字段都是可选的——省略时,OpenClaw 会使用安全的默认值。
|
||||
|
||||
@ -35,27 +35,27 @@ x-i18n:
|
||||
|
||||
## 渠道
|
||||
|
||||
每个渠道的配置键已移至独立页面——请参见
|
||||
每个渠道的配置键已移至专用页面——请参见
|
||||
[配置 — 渠道](/zh-CN/gateway/config-channels),了解 `channels.*`,
|
||||
包括 Slack、Discord、Telegram、WhatsApp、Matrix、iMessage 和其他
|
||||
内置渠道(认证、访问控制、多账号、提及门控)。
|
||||
包括 Slack、Discord、Telegram、WhatsApp、Matrix、iMessage 以及其他
|
||||
内置渠道(凭证、访问控制、多账号、提及门控)。
|
||||
|
||||
## 智能体默认值、多智能体、会话和消息
|
||||
|
||||
已移至独立页面——请参见
|
||||
[配置 — 智能体](/zh-CN/gateway/config-agents),了解:
|
||||
已移至专用页面——请参见
|
||||
[配置 — 智能体](/zh-CN/gateway/config-agents),内容包括:
|
||||
|
||||
- `agents.defaults.*`(工作区、模型、思考、心跳、内存、媒体、Skills、沙箱)
|
||||
- `multiAgent.*`(多智能体路由和绑定)
|
||||
- `session.*`(会话生命周期、压缩、修剪)
|
||||
- `messages.*`(消息投递、TTS、Markdown 渲染)
|
||||
- `session.*`(会话生命周期、压缩、清理)
|
||||
- `messages.*`(消息传递、TTS、Markdown 渲染)
|
||||
- `talk.*`(Talk 模式)
|
||||
- `talk.silenceTimeoutMs`:未设置时,Talk 会在发送转录内容前保持平台默认的暂停窗口(`macOS 和 Android 为 700 ms,iOS 为 900 ms`)
|
||||
- `talk.silenceTimeoutMs`:未设置时,Talk 会在发送转录文本前保持平台默认的静默等待窗口(`macOS 和 Android 为 700 ms,iOS 为 900 ms`)
|
||||
|
||||
## 工具和自定义提供商
|
||||
|
||||
工具策略、实验性开关、由提供商支持的工具配置,以及自定义
|
||||
提供商 / 基础 URL 设置已移至独立页面——请参见
|
||||
提供商 / base-URL 设置已移至专用页面——请参见
|
||||
[配置 — 工具和自定义提供商](/zh-CN/gateway/config-tools)。
|
||||
|
||||
## Skills
|
||||
@ -83,11 +83,11 @@ x-i18n:
|
||||
}
|
||||
```
|
||||
|
||||
- `allowBundled`:仅对内置 Skills 生效的可选允许列表(托管 / 工作区 Skills 不受影响)。
|
||||
- `allowBundled`:仅针对内置 Skills 的可选允许列表(托管/工作区 Skills 不受影响)。
|
||||
- `load.extraDirs`:额外的共享 Skills 根目录(优先级最低)。
|
||||
- `install.preferBrew`:当为 true 且 `brew` 可用时,优先使用 Homebrew 安装器,然后再回退到其他安装器类型。
|
||||
- `install.nodeManager`:用于 `metadata.openclaw.install` 规范的 node 安装器偏好(`npm` | `pnpm` | `yarn` | `bun`)。
|
||||
- `entries.<skillKey>.enabled: false`:即使某个 Skill 已内置 / 已安装,也会禁用它。
|
||||
- `install.preferBrew`:为 true 时,若 `brew` 可用,则优先使用 Homebrew 安装器,之后才回退到其他安装器类型。
|
||||
- `install.nodeManager`:`metadata.openclaw.install` 规范的 Node 安装器偏好(`npm` | `pnpm` | `yarn` | `bun`)。
|
||||
- `entries.<skillKey>.enabled: false`:即使某个 Skill 已内置/已安装,也会将其禁用。
|
||||
- `entries.<skillKey>.apiKey`:为声明了主环境变量的 Skills 提供的便捷字段(明文字符串或 SecretRef 对象)。
|
||||
|
||||
---
|
||||
@ -117,42 +117,42 @@ x-i18n:
|
||||
```
|
||||
|
||||
- 从 `~/.openclaw/extensions`、`<workspace>/.openclaw/extensions` 以及 `plugins.load.paths` 加载。
|
||||
- 发现机制接受原生 OpenClaw 插件,以及兼容的 Codex 打包和 Claude 打包,包括无 manifest 的 Claude 默认布局打包。
|
||||
- **配置更改需要重启 Gateway 网关。**
|
||||
- `allow`:可选允许列表(仅加载列出的插件)。`deny` 优先生效。
|
||||
- `plugins.entries.<id>.apiKey`:插件级 API key 便捷字段(当插件支持时)。
|
||||
- 设备发现接受原生 OpenClaw 插件,以及兼容的 Codex bundle 和 Claude bundle,包括无 manifest 的 Claude 默认布局 bundle。
|
||||
- **配置变更需要重启 Gateway 网关。**
|
||||
- `allow`:可选允许列表(仅加载列出的插件)。`deny` 优先。
|
||||
- `plugins.entries.<id>.apiKey`:插件级 API key 便捷字段(插件支持时可用)。
|
||||
- `plugins.entries.<id>.env`:插件作用域的环境变量映射。
|
||||
- `plugins.entries.<id>.hooks.allowPromptInjection`:当为 `false` 时,核心会阻止 `before_prompt_build`,并忽略旧版 `before_agent_start` 中会修改提示词的字段,同时保留旧版 `modelOverride` 和 `providerOverride`。适用于原生插件钩子和受支持的打包提供的钩子目录。
|
||||
- `plugins.entries.<id>.hooks.allowConversationAccess`:当为 `true` 时,受信任的非内置插件可以从类型化钩子中读取原始对话内容,例如 `llm_input`、`llm_output` 和 `agent_end`。
|
||||
- `plugins.entries.<id>.subagent.allowModelOverride`:显式信任该插件,使其可为后台子智能体运行请求按次执行的 `provider` 和 `model` 覆盖。
|
||||
- `plugins.entries.<id>.subagent.allowedModels`:受信任子智能体覆盖的可选规范 `provider/model` 目标允许列表。仅当你有意允许任意模型时才使用 `"*"`。
|
||||
- `plugins.entries.<id>.config`:插件定义的配置对象(在可用时由原生 OpenClaw 插件 schema 验证)。
|
||||
- 渠道插件的账号 / 运行时设置位于 `channels.<id>` 下,应由所属插件 manifest 的 `channelConfigs` 元数据描述,而不是由中央 OpenClaw 选项注册表描述。
|
||||
- `plugins.entries.firecrawl.config.webFetch`:Firecrawl web-fetch 提供商设置。
|
||||
- `apiKey`:Firecrawl API key(接受 SecretRef)。会回退到 `plugins.entries.firecrawl.config.webSearch.apiKey`、旧版 `tools.web.fetch.firecrawl.apiKey`,或 `FIRECRAWL_API_KEY` 环境变量。
|
||||
- `plugins.entries.<id>.hooks.allowPromptInjection`:为 `false` 时,核心会阻止 `before_prompt_build`,并忽略旧版 `before_agent_start` 中会变更提示词的字段,同时保留旧版 `modelOverride` 和 `providerOverride`。适用于原生插件钩子,以及受支持的 bundle 提供的钩子目录。
|
||||
- `plugins.entries.<id>.hooks.allowConversationAccess`:为 `true` 时,受信任的非内置插件可以从类型化钩子中读取原始对话内容,例如 `llm_input`、`llm_output` 和 `agent_end`。
|
||||
- `plugins.entries.<id>.subagent.allowModelOverride`:显式信任该插件可为后台子智能体运行请求按次覆盖 `provider` 和 `model`。
|
||||
- `plugins.entries.<id>.subagent.allowedModels`:受信任子智能体覆盖可用的规范 `provider/model` 目标可选允许列表。仅当你有意允许任意模型时才使用 `"*"`。
|
||||
- `plugins.entries.<id>.config`:插件定义的配置对象(若可用,则由原生 OpenClaw 插件 schema 验证)。
|
||||
- 渠道插件的账号/运行时设置位于 `channels.<id>` 下,应由所属插件 manifest 的 `channelConfigs` 元数据描述,而不是由集中式 OpenClaw 选项注册表描述。
|
||||
- `plugins.entries.firecrawl.config.webFetch`:Firecrawl 网页抓取提供商设置。
|
||||
- `apiKey`:Firecrawl API key(接受 SecretRef)。会回退到 `plugins.entries.firecrawl.config.webSearch.apiKey`、旧版 `tools.web.fetch.firecrawl.apiKey` 或 `FIRECRAWL_API_KEY` 环境变量。
|
||||
- `baseUrl`:Firecrawl API 基础 URL(默认:`https://api.firecrawl.dev`)。
|
||||
- `onlyMainContent`:仅提取页面主体内容(默认:`true`)。
|
||||
- `maxAgeMs`:缓存的最大保留时间(毫秒)(默认:`172800000` / 2 天)。
|
||||
- `timeoutSeconds`:抓取请求超时(秒)(默认:`60`)。
|
||||
- `plugins.entries.xai.config.xSearch`:xAI X Search(Grok web 搜索)设置。
|
||||
- `onlyMainContent`:仅提取页面主内容(默认:`true`)。
|
||||
- `maxAgeMs`:最大缓存时长(毫秒)(默认:`172800000` / 2 天)。
|
||||
- `timeoutSeconds`:抓取请求超时秒数(默认:`60`)。
|
||||
- `plugins.entries.xai.config.xSearch`:xAI X Search(Grok 网页搜索)设置。
|
||||
- `enabled`:启用 X Search 提供商。
|
||||
- `model`:用于搜索的 Grok 模型(例如 `"grok-4-1-fast"`)。
|
||||
- `plugins.entries.memory-core.config.dreaming`:内存 Dreaming 设置。关于阶段和阈值,请参见 [Dreaming](/zh-CN/concepts/dreaming)。
|
||||
- `model`:搜索使用的 Grok 模型(例如 `"grok-4-1-fast"`)。
|
||||
- `plugins.entries.memory-core.config.dreaming`:内存 Dreaming 设置。有关阶段和阈值,请参见 [Dreaming](/zh-CN/concepts/dreaming)。
|
||||
- `enabled`:Dreaming 总开关(默认 `false`)。
|
||||
- `frequency`:每次完整 Dreaming 扫描的 cron 频率(默认 `"0 3 * * *"`)。
|
||||
- 阶段策略和阈值属于实现细节(不是面向用户的配置键)。
|
||||
- 完整的内存配置见 [内存配置参考](/zh-CN/reference/memory-config):
|
||||
- 完整内存配置位于 [内存配置参考](/zh-CN/reference/memory-config):
|
||||
- `agents.defaults.memorySearch.*`
|
||||
- `memory.backend`
|
||||
- `memory.citations`
|
||||
- `memory.qmd.*`
|
||||
- `plugins.entries.memory-core.config.dreaming`
|
||||
- 已启用的 Claude 打包插件也可以通过 `settings.json` 提供内嵌的 Pi 默认值;OpenClaw 会将这些作为净化后的智能体设置应用,而不是作为原始 OpenClaw 配置补丁应用。
|
||||
- `plugins.slots.memory`:选择活动的内存插件 id,或使用 `"none"` 禁用内存插件。
|
||||
- `plugins.slots.contextEngine`:选择活动的上下文引擎插件 id;默认值为 `"legacy"`,除非你安装并选择了其他引擎。
|
||||
- 已启用的 Claude bundle 插件也可从 `settings.json` 提供嵌入式 Pi 默认值;OpenClaw 会将其作为已净化的智能体设置应用,而不是作为原始 OpenClaw 配置补丁应用。
|
||||
- `plugins.slots.memory`:选择活动内存插件 id,或设为 `"none"` 以禁用内存插件。
|
||||
- `plugins.slots.contextEngine`:选择活动上下文引擎插件 id;默认值为 `"legacy"`,除非你安装并选择了其他引擎。
|
||||
- `plugins.installs`:由 CLI 管理的安装元数据,供 `openclaw plugins update` 使用。
|
||||
- 包括 `source`、`spec`、`sourcePath`、`installPath`、`version`、`resolvedName`、`resolvedVersion`、`resolvedSpec`、`integrity`、`shasum`、`resolvedAt`、`installedAt`。
|
||||
- 将 `plugins.installs.*` 视为受管理状态;优先使用 CLI 命令,而不是手动编辑。
|
||||
- 将 `plugins.installs.*` 视为托管状态;优先使用 CLI 命令,而不是手动编辑。
|
||||
|
||||
请参见 [插件](/zh-CN/tools/plugin)。
|
||||
|
||||
@ -172,6 +172,12 @@ x-i18n:
|
||||
// hostnameAllowlist: ["*.example.com", "example.com"],
|
||||
// allowedHostnames: ["localhost"],
|
||||
},
|
||||
tabCleanup: {
|
||||
enabled: true,
|
||||
idleMinutes: 120,
|
||||
maxTabsPerSession: 8,
|
||||
sweepMinutes: 5,
|
||||
},
|
||||
profiles: {
|
||||
openclaw: { cdpPort: 18800, color: "#FF4500" },
|
||||
work: { cdpPort: 18801, color: "#0066CC" },
|
||||
@ -194,27 +200,26 @@ x-i18n:
|
||||
}
|
||||
```
|
||||
|
||||
- `evaluateEnabled: false`:禁用 `act:evaluate` 和 `wait --fn`。
|
||||
- `ssrfPolicy.dangerouslyAllowPrivateNetwork`:未设置时为禁用状态,因此默认情况下浏览器导航保持严格。
|
||||
- 仅当你明确相信私有网络中的浏览器导航时,才设置 `ssrfPolicy.dangerouslyAllowPrivateNetwork: true`。
|
||||
- 在严格模式下,远程 CDP 配置文件端点(`profiles.*.cdpUrl`)在可达性 / 发现检查期间也会受到相同的私有网络阻止。
|
||||
- `ssrfPolicy.allowPrivateNetwork` 仍然作为旧版别名受支持。
|
||||
- 在严格模式下,使用 `ssrfPolicy.hostnameAllowlist` 和 `ssrfPolicy.allowedHostnames` 来添加显式例外。
|
||||
- 远程配置文件为仅连接模式(禁用 start / stop / reset)。
|
||||
- `evaluateEnabled: false` 会禁用 `act:evaluate` 和 `wait --fn`。
|
||||
- `tabCleanup` 会在空闲超时后回收已跟踪的主智能体标签页,或在某个会话超过上限时回收。将 `idleMinutes: 0` 或 `maxTabsPerSession: 0` 设为 0,可禁用这些单独的清理模式。
|
||||
- `ssrfPolicy.dangerouslyAllowPrivateNetwork` 在未设置时为禁用状态,因此浏览器导航默认保持严格。
|
||||
- 仅当你明确信任私有网络浏览器导航时,才设置 `ssrfPolicy.dangerouslyAllowPrivateNetwork: true`。
|
||||
- 在严格模式下,远程 CDP 配置项端点(`profiles.*.cdpUrl`)在可达性/设备发现检查期间也会受到相同的私有网络阻止。
|
||||
- `ssrfPolicy.allowPrivateNetwork` 仍作为旧版别名受支持。
|
||||
- 在严格模式下,使用 `ssrfPolicy.hostnameAllowlist` 和 `ssrfPolicy.allowedHostnames` 来配置显式例外。
|
||||
- 远程配置项为仅附加模式(禁用启动/停止/重置)。
|
||||
- `profiles.*.cdpUrl` 接受 `http://`、`https://`、`ws://` 和 `wss://`。
|
||||
当你希望 OpenClaw 发现 `/json/version` 时,使用 HTTP(S);
|
||||
当你的提供商直接提供 DevTools WebSocket URL 时,使用 WS(S)。
|
||||
- `existing-session` 配置文件使用 Chrome MCP 而不是 CDP,并且可以在所选主机上或通过已连接的浏览器节点进行连接。
|
||||
- `existing-session` 配置文件可以设置 `userDataDir`,以定位特定的基于 Chromium 的浏览器配置文件,例如 Brave 或 Edge。
|
||||
- `existing-session` 配置文件仍受当前 Chrome MCP 路由限制:
|
||||
使用快照 / ref 驱动的操作,而不是 CSS 选择器定位;单文件上传
|
||||
钩子;不支持对话框超时覆盖;不支持 `wait --load networkidle`;以及不支持
|
||||
`responsebody`、PDF 导出、下载拦截或批量操作。
|
||||
- 本地托管的 `openclaw` 配置文件会自动分配 `cdpPort` 和 `cdpUrl`;仅在远程 CDP 场景下显式设置 `cdpUrl`。
|
||||
- 自动检测顺序:如果默认浏览器是基于 Chromium 的则优先使用默认浏览器 → Chrome → Brave → Edge → Chromium → Chrome Canary。
|
||||
- 控制服务:仅 local loopback(端口由 `gateway.port` 推导,默认 `18791`)。
|
||||
- `extraArgs`:向本地 Chromium 启动追加额外启动标志(例如
|
||||
`--disable-gpu`、窗口大小设置或调试标志)。
|
||||
当你希望 OpenClaw 发现 `/json/version` 时,请使用 HTTP(S);
|
||||
当提供商直接给出 DevTools WebSocket URL 时,请使用 WS(S)。
|
||||
- `existing-session` 配置项使用 Chrome MCP 而非 CDP,并且可以附加到所选主机上,或通过已连接的浏览器节点附加。
|
||||
- `existing-session` 配置项可设置 `userDataDir`,以定位特定的 Chromium 系浏览器配置,例如 Brave 或 Edge。
|
||||
- `existing-session` 配置项保留当前 Chrome MCP 路由限制:使用 snapshot/ref 驱动的操作而非 CSS 选择器定位、单文件上传钩子、不支持对话框超时覆盖、不支持 `wait --load networkidle`,并且不支持 `responsebody`、PDF 导出、下载拦截或批量操作。
|
||||
- 本地托管的 `openclaw` 配置项会自动分配 `cdpPort` 和 `cdpUrl`;仅在远程 CDP 场景下才显式设置 `cdpUrl`。
|
||||
- 自动检测顺序:默认浏览器若为 Chromium 系 → Chrome → Brave → Edge → Chromium → Chrome Canary。
|
||||
- `browser.executablePath` 接受 `~` 作为你的操作系统主目录。
|
||||
- 控制服务:仅限 loopback(端口由 `gateway.port` 派生,默认 `18791`)。
|
||||
- `extraArgs` 会向本地 Chromium 启动追加额外启动标志(例如
|
||||
`--disable-gpu`、窗口尺寸设置或调试标志)。
|
||||
|
||||
---
|
||||
|
||||
@ -232,8 +237,8 @@ x-i18n:
|
||||
}
|
||||
```
|
||||
|
||||
- `seamColor`:原生应用 UI 外壳的强调色(Talk 模式气泡着色等)。
|
||||
- `assistant`:Control UI 身份覆盖。会回退到当前活动的智能体身份。
|
||||
- `seamColor`:原生应用 UI 外观的强调色(Talk 模式气泡着色等)。
|
||||
- `assistant`:Control UI 身份覆盖。会回退到当前活动智能体身份。
|
||||
|
||||
---
|
||||
|
||||
@ -280,12 +285,12 @@ x-i18n:
|
||||
// password: "your-password",
|
||||
},
|
||||
trustedProxies: ["10.0.0.1"],
|
||||
// Optional. Default false.
|
||||
// 可选。默认值为 false。
|
||||
allowRealIpFallback: false,
|
||||
tools: {
|
||||
// Additional /tools/invoke HTTP denies
|
||||
// 对 /tools/invoke HTTP 的额外拒绝列表
|
||||
deny: ["browser"],
|
||||
// Remove tools from the default HTTP deny list
|
||||
// 从默认 HTTP 拒绝列表中移除工具
|
||||
allow: ["gateway"],
|
||||
},
|
||||
push: {
|
||||
@ -302,49 +307,44 @@ x-i18n:
|
||||
|
||||
<Accordion title="Gateway 网关字段详情">
|
||||
|
||||
- `mode`:`local`(运行 gateway)或 `remote`(连接到远程 gateway)。只有在 `local` 模式下,Gateway 网关才允许启动。
|
||||
- `mode`:`local`(运行 Gateway 网关)或 `remote`(连接到远程 Gateway 网关)。除非为 `local`,否则 Gateway 网关会拒绝启动。
|
||||
- `port`:用于 WS + HTTP 的单一复用端口。优先级:`--port` > `OPENCLAW_GATEWAY_PORT` > `gateway.port` > `18789`。
|
||||
- `bind`:`auto`、`loopback`(默认)、`lan`(`0.0.0.0`)、`tailnet`(仅 Tailscale IP)或 `custom`。
|
||||
- **旧版 bind 别名**:请在 `gateway.bind` 中使用 bind 模式值(`auto`、`loopback`、`lan`、`tailnet`、`custom`),不要使用主机别名(`0.0.0.0`、`127.0.0.1`、`localhost`、`::`、`::1`)。
|
||||
- **Docker 注意事项**:默认的 `loopback` bind 会在容器内监听 `127.0.0.1`。使用 Docker bridge 网络(`-p 18789:18789`)时,流量会到达 `eth0`,因此 Gateway 网关不可达。请使用 `--network host`,或设置 `bind: "lan"`(或 `bind: "custom"` 并配合 `customBindHost: "0.0.0.0"`)以监听所有网络接口。
|
||||
- **认证**:默认必需。非 loopback bind 需要 Gateway 网关认证。实际中,这意味着共享 token / password,或使用 `gateway.auth.mode: "trusted-proxy"` 的具备身份感知能力的反向代理。新手引导向导默认会生成一个 token。
|
||||
- 如果同时配置了 `gateway.auth.token` 和 `gateway.auth.password`(包括 SecretRef),请显式将 `gateway.auth.mode` 设为 `token` 或 `password`。如果两者都已配置但未设置 mode,启动以及服务安装 / 修复流程都会失败。
|
||||
- `gateway.auth.mode: "none"`:显式无认证模式。仅用于受信任的本地 local loopback 设置;新手引导提示不会提供这个选项。
|
||||
- `gateway.auth.mode: "trusted-proxy"`:将认证委托给具备身份感知能力的反向代理,并信任来自 `gateway.trustedProxies` 的身份头(参见 [Trusted Proxy Auth](/zh-CN/gateway/trusted-proxy-auth))。此模式要求**非 loopback** 的代理来源;同机 loopback 反向代理不满足 trusted-proxy 认证条件。
|
||||
- `gateway.auth.allowTailscale`:当为 `true` 时,Tailscale Serve 身份头可以满足 Control UI / WebSocket 认证(通过 `tailscale whois` 验证)。HTTP API 端点**不会**使用该 Tailscale 头认证;它们仍遵循 Gateway 网关正常的 HTTP 认证模式。这个无 token 流程假设 gateway 主机是可信的。当 `tailscale.mode = "serve"` 时,默认值为 `true`。
|
||||
- `gateway.auth.rateLimit`:可选的认证失败限流器。按客户端 IP 和认证作用域生效(共享密钥和设备 token 分别独立跟踪)。被阻止的尝试会返回 `429` + `Retry-After`。
|
||||
- 在异步 Tailscale Serve Control UI 路径中,同一 `{scope, clientIp}` 的失败尝试会在写入失败记录前被串行化。因此,同一客户端并发的错误尝试,可能会在第二个请求时触发限流,而不是都以普通不匹配方式竞争通过。
|
||||
- `gateway.auth.rateLimit.exemptLoopback` 默认值为 `true`;如果你有意也要对 localhost 流量进行限流(例如测试环境或严格代理部署),请设为 `false`。
|
||||
- 来自浏览器源的 WS 认证尝试总会启用限流,且关闭 loopback 豁免(作为针对基于浏览器的 localhost 暴力破解的纵深防御)。
|
||||
- **Docker 注意事项**:默认的 `loopback` bind 会在容器内监听 `127.0.0.1`。使用 Docker bridge 网络(`-p 18789:18789`)时,流量会到达 `eth0`,因此 Gateway 网关不可访问。请使用 `--network host`,或设置 `bind: "lan"`(或 `bind: "custom"` 并配合 `customBindHost: "0.0.0.0"`)以在所有接口上监听。
|
||||
- **凭证**:默认要求开启。非 loopback bind 要求 Gateway 网关凭证。实际中,这意味着共享 token/password,或者使用配置了 `gateway.auth.mode: "trusted-proxy"` 的身份感知反向代理。新手引导向导默认会生成一个 token。
|
||||
- 如果同时配置了 `gateway.auth.token` 和 `gateway.auth.password`(包括 SecretRef),请将 `gateway.auth.mode` 明确设置为 `token` 或 `password`。若两者都已配置但未设置 mode,启动以及服务安装/修复流程都会失败。
|
||||
- `gateway.auth.mode: "none"`:显式无凭证模式。仅用于受信任的本地 local loopback 设置;新手引导提示中不会提供此选项。
|
||||
- `gateway.auth.mode: "trusted-proxy"`:将凭证委托给身份感知反向代理,并信任来自 `gateway.trustedProxies` 的身份头(参见 [受信任代理凭证](/zh-CN/gateway/trusted-proxy-auth))。该模式要求**非 loopback** 代理来源;同机 loopback 反向代理不满足 trusted-proxy 凭证要求。
|
||||
- `gateway.auth.allowTailscale`:为 `true` 时,Tailscale Serve 身份头可满足 Control UI/WebSocket 凭证要求(通过 `tailscale whois` 验证)。HTTP API 端点**不会**使用该 Tailscale 头部凭证;它们仍遵循 Gateway 网关正常的 HTTP 凭证模式。此无 token 流程假定 Gateway 网关主机受信任。当 `tailscale.mode = "serve"` 时默认值为 `true`。
|
||||
- `gateway.auth.rateLimit`:可选的凭证失败限流器。按客户端 IP 和凭证范围生效(共享密钥和设备 token 分别独立跟踪)。被阻止的尝试会返回 `429` + `Retry-After`。
|
||||
- 在异步 Tailscale Serve Control UI 路径上,同一 `{scope, clientIp}` 的失败尝试会在写入失败记录前被串行化。因此,来自同一客户端的并发错误尝试,可能会在第二个请求时触发限流,而不是两者都作为普通不匹配竞态通过。
|
||||
- `gateway.auth.rateLimit.exemptLoopback` 默认值为 `true`;如果你明确希望 localhost 流量也受到限流(例如测试环境或严格代理部署),请将其设为 `false`。
|
||||
- 来自浏览器源的 WS 凭证尝试始终会启用限流,并关闭 loopback 豁免(作为针对基于浏览器的 localhost 暴力破解的纵深防御)。
|
||||
- 在 loopback 上,这些来自浏览器源的锁定会按规范化后的 `Origin`
|
||||
值隔离,因此来自某一个 localhost origin 的重复失败不会自动
|
||||
值彼此隔离,因此某个 localhost origin 的重复失败不会自动
|
||||
锁定另一个 origin。
|
||||
- `tailscale.mode`:`serve`(仅 tailnet,loopback bind)或 `funnel`(公开,需要认证)。
|
||||
- `controlUi.allowedOrigins`:用于 Gateway 网关 WebSocket 连接的显式浏览器源允许列表。当预期浏览器客户端来自非 loopback 源时,这是必需的。
|
||||
- `controlUi.dangerouslyAllowHostHeaderOriginFallback`:危险模式,为有意依赖 Host 头源策略的部署启用 Host 头源回退。
|
||||
- `tailscale.mode`:`serve`(仅 tailnet,loopback bind)或 `funnel`(公开访问,要求凭证)。
|
||||
- `controlUi.allowedOrigins`:用于 Gateway 网关 WebSocket 连接的显式浏览器源允许列表。当预期浏览器客户端来自非 loopback origin 时为必填。
|
||||
- `controlUi.dangerouslyAllowHostHeaderOriginFallback`:危险模式,为有意依赖 Host 头 origin 策略的部署启用 Host 头 origin 回退。
|
||||
- `remote.transport`:`ssh`(默认)或 `direct`(ws/wss)。对于 `direct`,`remote.url` 必须是 `ws://` 或 `wss://`。
|
||||
- `OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1`:客户端进程环境中的紧急放行
|
||||
覆盖项,允许对受信任私有网络 IP 使用明文 `ws://`;
|
||||
默认情况下,明文连接仍仅限 local loopback。没有对应的 `openclaw.json`
|
||||
配置项,并且浏览器私有网络配置(例如
|
||||
`browser.ssrfPolicy.dangerouslyAllowPrivateNetwork`)不会影响 Gateway
|
||||
网关 WebSocket 客户端。
|
||||
- `gateway.remote.token` / `.password`:远程客户端凭据字段。它们本身不会配置 Gateway 网关认证。
|
||||
- `gateway.push.apns.relay.baseUrl`:外部 APNs 中继的基础 HTTPS URL,官方 / TestFlight iOS 构建在将基于中继的注册发布到 Gateway 网关之后会使用它。该 URL 必须与编译进 iOS 构建中的中继 URL 一致。
|
||||
- `gateway.push.apns.relay.timeoutMs`:Gateway 网关到中继的发送超时时间,单位为毫秒。默认值为 `10000`。
|
||||
- 基于中继的注册会委托给特定的 Gateway 网关身份。配对的 iOS 应用会获取 `gateway.identity.get`,在中继注册中包含该身份,并将一个按注册范围限定的发送授权转发给 Gateway 网关。另一个 Gateway 网关无法复用该已存储的注册。
|
||||
- `OPENCLAW_APNS_RELAY_BASE_URL` / `OPENCLAW_APNS_RELAY_TIMEOUT_MS`:对上述中继配置的临时环境变量覆盖。
|
||||
- `OPENCLAW_APNS_RELAY_ALLOW_HTTP=true`:仅用于开发的逃生口,用于 loopback HTTP 中继 URL。生产中继 URL 应保持为 HTTPS。
|
||||
- `gateway.channelHealthCheckMinutes`:渠道健康监控间隔,单位为分钟。设为 `0` 可全局禁用健康监控重启。默认值:`5`。
|
||||
- `gateway.channelStaleEventThresholdMinutes`:陈旧套接字阈值,单位为分钟。应保持其大于或等于 `gateway.channelHealthCheckMinutes`。默认值:`30`。
|
||||
- `gateway.channelMaxRestartsPerHour`:每个渠道 / 账号在滚动一小时内允许的最大健康监控重启次数。默认值:`10`。
|
||||
- `channels.<provider>.healthMonitor.enabled`:每个渠道的健康监控重启退出开关,同时保留全局监控启用状态。
|
||||
- `channels.<provider>.accounts.<accountId>.healthMonitor.enabled`:多账号渠道的每个账号覆盖项。设置后,其优先级高于渠道级覆盖项。
|
||||
- 仅当 `gateway.auth.*` 未设置时,本地 gateway 调用路径才可将 `gateway.remote.*` 用作回退。
|
||||
- 如果通过 SecretRef 显式配置了 `gateway.auth.token` / `gateway.auth.password` 但未解析成功,解析将以关闭方式失败(不会由远程回退掩盖)。
|
||||
- `trustedProxies`:终止 TLS 或注入转发客户端头的反向代理 IP。只列出你控制的代理。对于同机代理 / 本地检测设置(例如 Tailscale Serve 或本地反向代理),loopback 条目仍然有效,但它们**不会**让 loopback 请求具备 `gateway.auth.mode: "trusted-proxy"` 的资格。
|
||||
- `allowRealIpFallback`:当为 `true` 时,如果缺少 `X-Forwarded-For`,Gateway 网关接受 `X-Real-IP`。默认值为 `false`,以实现失败即关闭行为。
|
||||
- `gateway.tools.deny`:为 HTTP `POST /tools/invoke` 额外阻止的工具名(扩展默认拒绝列表)。
|
||||
- `OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1`:客户端进程环境变量中的紧急放行覆盖项,允许对受信任私有网络 IP 使用明文 `ws://`;默认仍仅允许对 loopback 使用明文。没有对应的 `openclaw.json` 配置项,并且浏览器私有网络配置,例如 `browser.ssrfPolicy.dangerouslyAllowPrivateNetwork`,不会影响 Gateway 网关 WebSocket 客户端。
|
||||
- `gateway.remote.token` / `.password`:远程客户端凭证字段。它们本身不会配置 Gateway 网关凭证。
|
||||
- `gateway.push.apns.relay.baseUrl`:官方/TestFlight iOS 构建在向 Gateway 网关发布基于 relay 的注册后,供其使用的外部 APNs relay 基础 HTTPS URL。此 URL 必须与编译进 iOS 构建中的 relay URL 一致。
|
||||
- `gateway.push.apns.relay.timeoutMs`:Gateway 网关到 relay 的发送超时时间,单位毫秒。默认值为 `10000`。
|
||||
- 基于 relay 的注册会委托给某个特定的 Gateway 网关身份。配对的 iOS 应用会获取 `gateway.identity.get`,在 relay 注册中包含该身份,并向 Gateway 网关转发一个作用于该注册的发送授权。另一个 Gateway 网关无法复用该已存储的注册。
|
||||
- `OPENCLAW_APNS_RELAY_BASE_URL` / `OPENCLAW_APNS_RELAY_TIMEOUT_MS`:上述 relay 配置的临时环境变量覆盖项。
|
||||
- `OPENCLAW_APNS_RELAY_ALLOW_HTTP=true`:仅开发环境使用的逃生舱设置,用于 loopback HTTP relay URL。生产环境 relay URL 应保持为 HTTPS。
|
||||
- `gateway.channelHealthCheckMinutes`:渠道健康监控间隔,单位分钟。设为 `0` 可全局禁用健康监控重启。默认值:`5`。
|
||||
- `gateway.channelStaleEventThresholdMinutes`:陈旧 socket 阈值,单位分钟。应保持其大于或等于 `gateway.channelHealthCheckMinutes`。默认值:`30`。
|
||||
- `gateway.channelMaxRestartsPerHour`:滚动一小时内每个渠道/账号允许的最大健康监控重启次数。默认值:`10`。
|
||||
- `channels.<provider>.healthMonitor.enabled`:逐渠道退出健康监控重启,同时保持全局监控启用。
|
||||
- `channels.<provider>.accounts.<accountId>.healthMonitor.enabled`:多账号渠道的逐账号覆盖。设置后,其优先级高于渠道级覆盖。
|
||||
- 仅当 `gateway.auth.*` 未设置时,本地 Gateway 网关调用路径才可将 `gateway.remote.*` 用作回退。
|
||||
- 如果通过 SecretRef 显式配置了 `gateway.auth.token` / `gateway.auth.password` 但无法解析,解析会以关闭方式失败(不会被远程回退掩盖)。
|
||||
- `trustedProxies`:终止 TLS 或注入转发客户端头的反向代理 IP。只列出你控制的代理。loopback 条目对于同机代理/本地检测设置(例如 Tailscale Serve 或本地反向代理)仍然有效,但它们**不会**让 loopback 请求符合 `gateway.auth.mode: "trusted-proxy"` 的资格。
|
||||
- `allowRealIpFallback`:为 `true` 时,如果缺少 `X-Forwarded-For`,Gateway 网关接受 `X-Real-IP`。默认值为 `false`,以保持失败关闭行为。
|
||||
- `gateway.tools.deny`:对 HTTP `POST /tools/invoke` 额外阻止的工具名(扩展默认拒绝列表)。
|
||||
- `gateway.tools.allow`:从默认 HTTP 拒绝列表中移除工具名。
|
||||
|
||||
</Accordion>
|
||||
@ -357,14 +357,14 @@ x-i18n:
|
||||
- `gateway.http.endpoints.responses.maxUrlParts`
|
||||
- `gateway.http.endpoints.responses.files.urlAllowlist`
|
||||
- `gateway.http.endpoints.responses.images.urlAllowlist`
|
||||
空允许列表会被视为未设置;如需禁用 URL 获取,请使用 `gateway.http.endpoints.responses.files.allowUrl=false`
|
||||
和 / 或 `gateway.http.endpoints.responses.images.allowUrl=false`。
|
||||
空允许列表会被视为未设置;使用 `gateway.http.endpoints.responses.files.allowUrl=false`
|
||||
和/或 `gateway.http.endpoints.responses.images.allowUrl=false` 可禁用 URL 抓取。
|
||||
- 可选的响应加固头:
|
||||
- `gateway.http.securityHeaders.strictTransportSecurity`(仅对你控制的 HTTPS 源设置;参见 [Trusted Proxy Auth](/zh-CN/gateway/trusted-proxy-auth#tls-termination-and-hsts))
|
||||
- `gateway.http.securityHeaders.strictTransportSecurity`(仅对你控制的 HTTPS origin 设置;参见 [受信任代理凭证](/zh-CN/gateway/trusted-proxy-auth#tls-termination-and-hsts))
|
||||
|
||||
### 多实例隔离
|
||||
|
||||
在同一主机上运行多个 Gateway 网关时,请使用唯一端口和状态目录:
|
||||
在同一主机上运行多个 Gateway 网关时,请使用不同的端口和状态目录:
|
||||
|
||||
```bash
|
||||
OPENCLAW_CONFIG_PATH=~/.openclaw/a.json \
|
||||
@ -372,7 +372,7 @@ OPENCLAW_STATE_DIR=~/.openclaw-a \
|
||||
openclaw gateway --port 19001
|
||||
```
|
||||
|
||||
便捷标志:`--dev`(使用 `~/.openclaw-dev` + 端口 `19001`),`--profile <name>`(使用 `~/.openclaw-<name>`)。
|
||||
便捷标志:`--dev`(使用 `~/.openclaw-dev` + 端口 `19001`)、`--profile <name>`(使用 `~/.openclaw-<name>`)。
|
||||
|
||||
参见 [多个 Gateway 网关](/zh-CN/gateway/multiple-gateways)。
|
||||
|
||||
@ -393,10 +393,10 @@ openclaw gateway --port 19001
|
||||
```
|
||||
|
||||
- `enabled`:在 Gateway 网关监听器处启用 TLS 终止(HTTPS/WSS)(默认:`false`)。
|
||||
- `autoGenerate`:在未配置显式文件时自动生成本地自签名证书 / 密钥对;仅用于本地 / 开发。
|
||||
- `autoGenerate`:未配置显式文件时,自动生成本地自签名证书/密钥对;仅用于本地/开发环境。
|
||||
- `certPath`:TLS 证书文件的文件系统路径。
|
||||
- `keyPath`:TLS 私钥文件的文件系统路径;请限制其权限。
|
||||
- `caPath`:可选的 CA bundle 路径,用于客户端验证或自定义信任链。
|
||||
- `keyPath`:TLS 私钥文件的文件系统路径;应限制权限。
|
||||
- `caPath`:用于客户端验证或自定义信任链的可选 CA bundle 路径。
|
||||
|
||||
### `gateway.reload`
|
||||
|
||||
@ -412,13 +412,13 @@ openclaw gateway --port 19001
|
||||
}
|
||||
```
|
||||
|
||||
- `mode`:控制如何在运行时应用配置编辑。
|
||||
- `"off"`:忽略实时编辑;更改需要显式重启。
|
||||
- `"restart"`:配置变更时总是重启 Gateway 网关进程。
|
||||
- `mode`:控制运行时如何应用配置编辑。
|
||||
- `"off"`:忽略实时编辑;变更需要显式重启。
|
||||
- `"restart"`:配置变更时始终重启 Gateway 网关进程。
|
||||
- `"hot"`:在不重启的情况下于进程内应用变更。
|
||||
- `"hybrid"`(默认):先尝试热重载;如果需要则回退到重启。
|
||||
- `debounceMs`:应用配置更改前的防抖窗口,单位为毫秒(非负整数)。
|
||||
- `deferralTimeoutMs`:在强制重启前等待进行中操作完成的最长时间,单位为毫秒(默认:`300000` = 5 分钟)。
|
||||
- `"hybrid"`(默认):先尝试热重载;如有需要则回退为重启。
|
||||
- `debounceMs`:应用配置变更前的防抖窗口,单位毫秒(非负整数)。
|
||||
- `deferralTimeoutMs`:在强制重启前等待进行中操作完成的最长时间,单位毫秒(默认:`300000` = 5 分钟)。
|
||||
|
||||
---
|
||||
|
||||
@ -455,47 +455,47 @@ openclaw gateway --port 19001
|
||||
}
|
||||
```
|
||||
|
||||
认证:`Authorization: Bearer <token>` 或 `x-openclaw-token: <token>`。
|
||||
凭证:`Authorization: Bearer <token>` 或 `x-openclaw-token: <token>`。
|
||||
不接受查询字符串中的 hook token。
|
||||
|
||||
验证和安全说明:
|
||||
|
||||
- `hooks.enabled=true` 需要一个非空的 `hooks.token`。
|
||||
- `hooks.enabled=true` 要求 `hooks.token` 为非空。
|
||||
- `hooks.token` 必须与 `gateway.auth.token` **不同**;复用 Gateway 网关 token 会被拒绝。
|
||||
- `hooks.path` 不能为 `/`;请使用专用子路径,例如 `/hooks`。
|
||||
- 如果 `hooks.allowRequestSessionKey=true`,请限制 `hooks.allowedSessionKeyPrefixes`(例如 `["hook:"]`)。
|
||||
- 如果某个映射或预设使用模板化的 `sessionKey`,请设置 `hooks.allowedSessionKeyPrefixes` 和 `hooks.allowRequestSessionKey=true`。静态映射键不需要这个显式启用。
|
||||
- 如果 `hooks.allowRequestSessionKey=true`,请约束 `hooks.allowedSessionKeyPrefixes`(例如 `["hook:"]`)。
|
||||
- 如果某个 mapping 或 preset 使用模板化的 `sessionKey`,请设置 `hooks.allowedSessionKeyPrefixes` 和 `hooks.allowRequestSessionKey=true`。静态 mapping 键不需要该显式启用。
|
||||
|
||||
**端点:**
|
||||
|
||||
- `POST /hooks/wake` → `{ text, mode?: "now"|"next-heartbeat" }`
|
||||
- `POST /hooks/agent` → `{ message, name?, agentId?, sessionKey?, wakeMode?, deliver?, channel?, to?, model?, thinking?, timeoutSeconds? }`
|
||||
- 只有当 `hooks.allowRequestSessionKey=true`(默认:`false`)时,才接受请求负载中的 `sessionKey`。
|
||||
- 仅当 `hooks.allowRequestSessionKey=true`(默认:`false`)时,才接受请求载荷中的 `sessionKey`。
|
||||
- `POST /hooks/<name>` → 通过 `hooks.mappings` 解析
|
||||
- 模板渲染后的映射 `sessionKey` 值会被视为外部提供,因此也需要 `hooks.allowRequestSessionKey=true`。
|
||||
- 模板渲染后的 mapping `sessionKey` 值会被视为外部提供,因此同样要求 `hooks.allowRequestSessionKey=true`。
|
||||
|
||||
<Accordion title="映射详情">
|
||||
|
||||
- `match.path` 匹配 `/hooks` 之后的子路径(例如 `/hooks/gmail` → `gmail`)。
|
||||
- `match.source` 匹配通用路径中的某个负载字段。
|
||||
- 像 `{{messages[0].subject}}` 这样的模板会从负载中读取。
|
||||
- `transform` 可以指向一个返回 hook action 的 JS/TS 模块。
|
||||
- `transform.module` 必须是相对路径,并且必须保持在 `hooks.transformsDir` 内(绝对路径和路径穿越会被拒绝)。
|
||||
- `match.source` 匹配通用路径的载荷字段。
|
||||
- 像 `{{messages[0].subject}}` 这样的模板会从载荷中读取。
|
||||
- `transform` 可指向一个返回 hook 操作的 JS/TS 模块。
|
||||
- `transform.module` 必须是相对路径,并保持在 `hooks.transformsDir` 内(绝对路径和路径穿越会被拒绝)。
|
||||
- `agentId` 会路由到特定智能体;未知 ID 会回退到默认值。
|
||||
- `allowedAgentIds`:限制显式路由(`*` 或省略 = 允许全部,`[]` = 全部拒绝)。
|
||||
- `defaultSessionKey`:可选的固定 session 键,用于没有显式 `sessionKey` 的 hook 智能体运行。
|
||||
- `allowRequestSessionKey`:允许 `/hooks/agent` 调用方和模板驱动的映射 session 键设置 `sessionKey`(默认:`false`)。
|
||||
- `allowedSessionKeyPrefixes`:显式 `sessionKey` 值(请求 + 映射)的可选前缀允许列表,例如 `["hook:"]`。当任意映射或预设使用模板化 `sessionKey` 时,它就变为必需。
|
||||
- `defaultSessionKey`:hook 智能体运行时的可选固定会话键,用于未显式提供 `sessionKey` 的情况。
|
||||
- `allowRequestSessionKey`:允许 `/hooks/agent` 调用方以及模板驱动的 mapping 会话键设置 `sessionKey`(默认:`false`)。
|
||||
- `allowedSessionKeyPrefixes`:显式 `sessionKey` 值(请求 + mapping)的可选前缀允许列表,例如 `["hook:"]`。当任意 mapping 或 preset 使用模板化 `sessionKey` 时,它会成为必填项。
|
||||
- `deliver: true` 会将最终回复发送到某个渠道;`channel` 默认为 `last`。
|
||||
- `model` 会覆盖此次 hook 运行使用的 LLM(如果设置了模型目录,则必须被允许)。
|
||||
- `model`:覆盖本次 hook 运行的 LLM(如果设置了模型目录,则必须被允许)。
|
||||
|
||||
</Accordion>
|
||||
|
||||
### Gmail 集成
|
||||
|
||||
- 内置 Gmail 预设使用 `sessionKey: "hook:gmail:{{messages[0].id}}"`。
|
||||
- 如果你保留这种按消息路由方式,请设置 `hooks.allowRequestSessionKey: true`,并限制 `hooks.allowedSessionKeyPrefixes` 以匹配 Gmail 命名空间,例如 `["hook:", "hook:gmail:"]`。
|
||||
- 如果你需要 `hooks.allowRequestSessionKey: false`,请使用静态 `sessionKey` 覆盖该预设,而不是使用默认的模板化值。
|
||||
- 内建 Gmail preset 使用 `sessionKey: "hook:gmail:{{messages[0].id}}"`。
|
||||
- 如果你保留这种按消息路由的方式,请设置 `hooks.allowRequestSessionKey: true`,并约束 `hooks.allowedSessionKeyPrefixes` 以匹配 Gmail 命名空间,例如 `["hook:", "hook:gmail:"]`。
|
||||
- 如果你需要 `hooks.allowRequestSessionKey: false`,请使用静态 `sessionKey` 覆盖该 preset,而不是使用默认的模板化值。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -518,12 +518,12 @@ openclaw gateway --port 19001
|
||||
}
|
||||
```
|
||||
|
||||
- 配置后,Gateway 网关会在启动时自动启动 `gog gmail watch serve`。设置 `OPENCLAW_SKIP_GMAIL_WATCHER=1` 可禁用。
|
||||
- 不要在 Gateway 网关旁边单独运行一个 `gog gmail watch serve`。
|
||||
- 配置完成后,Gateway 网关会在启动时自动启动 `gog gmail watch serve`。设置 `OPENCLAW_SKIP_GMAIL_WATCHER=1` 可禁用。
|
||||
- 不要在 Gateway 网关旁边单独运行另一个 `gog gmail watch serve`。
|
||||
|
||||
---
|
||||
|
||||
## Canvas 主机
|
||||
## Canvas host
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -538,14 +538,14 @@ openclaw gateway --port 19001
|
||||
- 通过 Gateway 网关端口下的 HTTP 提供可由智能体编辑的 HTML/CSS/JS 和 A2UI:
|
||||
- `http://<gateway-host>:<gateway.port>/__openclaw__/canvas/`
|
||||
- `http://<gateway-host>:<gateway.port>/__openclaw__/a2ui/`
|
||||
- 仅本地:请保持 `gateway.bind: "loopback"`(默认)。
|
||||
- 非 loopback bind:canvas 路由和其他 Gateway 网关 HTTP 界面一样,需要 Gateway 网关认证(token / password / trusted-proxy)。
|
||||
- 节点 WebView 通常不会发送认证头;在节点完成配对并连接后,Gateway 网关会为 canvas / A2UI 访问公布节点作用域的 capability URL。
|
||||
- Capability URL 绑定到当前活动的节点 WS 会话,并且会很快过期。不使用基于 IP 的回退。
|
||||
- 会将 live-reload 客户端注入到所提供的 HTML 中。
|
||||
- 仅本地:保持 `gateway.bind: "loopback"`(默认)。
|
||||
- 非 loopback bind:canvas 路由与其他 Gateway 网关 HTTP 面一样,要求 Gateway 网关凭证(token/password/trusted-proxy)。
|
||||
- Node WebView 通常不会发送凭证头;节点配对并连接后,Gateway 网关会为 canvas/A2UI 访问通告节点作用域的能力 URL。
|
||||
- 能力 URL 绑定到当前活动节点的 WS 会话,并会很快过期。不使用基于 IP 的回退。
|
||||
- 向已提供的 HTML 中注入 live-reload 客户端。
|
||||
- 为空时会自动创建起始 `index.html`。
|
||||
- 同时也会在 `/__openclaw__/a2ui/` 提供 A2UI。
|
||||
- 更改需要重启 Gateway 网关。
|
||||
- 还会在 `/__openclaw__/a2ui/` 提供 A2UI。
|
||||
- 变更需要重启 Gateway 网关。
|
||||
- 对于大型目录或出现 `EMFILE` 错误时,请禁用 live reload。
|
||||
|
||||
---
|
||||
@ -564,9 +564,9 @@ openclaw gateway --port 19001
|
||||
}
|
||||
```
|
||||
|
||||
- `minimal`(默认):从 TXT 记录中省略 `cliPath` + `sshPort`。
|
||||
- `minimal`(默认):在 TXT 记录中省略 `cliPath` + `sshPort`。
|
||||
- `full`:包含 `cliPath` + `sshPort`。
|
||||
- 主机名默认为 `openclaw`。可通过 `OPENCLAW_MDNS_HOSTNAME` 覆盖。
|
||||
- 主机名默认为 `openclaw`。可用 `OPENCLAW_MDNS_HOSTNAME` 覆盖。
|
||||
|
||||
### 广域(DNS-SD)
|
||||
|
||||
@ -578,7 +578,7 @@ openclaw gateway --port 19001
|
||||
}
|
||||
```
|
||||
|
||||
会在 `~/.openclaw/dns/` 下写入一个单播 DNS-SD 区域。若要进行跨网络 设备发现,请搭配 DNS 服务器(推荐 CoreDNS)+ Tailscale split DNS。
|
||||
会在 `~/.openclaw/dns/` 下写入单播 DNS-SD 区域。要实现跨网络设备发现,请搭配 DNS 服务器(推荐 CoreDNS)+ Tailscale split DNS。
|
||||
|
||||
设置:`openclaw dns setup --apply`。
|
||||
|
||||
@ -603,14 +603,14 @@ openclaw gateway --port 19001
|
||||
}
|
||||
```
|
||||
|
||||
- 只有当进程环境中缺少该键时,才会应用内联环境变量。
|
||||
- `.env` 文件:当前工作目录下的 `.env` + `~/.openclaw/.env`(两者都不会覆盖现有变量)。
|
||||
- `shellEnv`:从你的登录 shell 配置文件中导入缺失的预期键名。
|
||||
- 仅当进程环境中缺少该键时,才会应用内联环境变量。
|
||||
- `.env` 文件:当前工作目录的 `.env` + `~/.openclaw/.env`(两者都不会覆盖现有变量)。
|
||||
- `shellEnv`:从你的登录 shell 配置中导入缺失的预期键名。
|
||||
- 完整优先级请参见 [环境](/zh-CN/help/environment)。
|
||||
|
||||
### 环境变量替换
|
||||
|
||||
可在任意配置字符串中使用 `${VAR_NAME}` 引用环境变量:
|
||||
可在任意配置字符串中用 `${VAR_NAME}` 引用环境变量:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -621,19 +621,19 @@ openclaw gateway --port 19001
|
||||
```
|
||||
|
||||
- 仅匹配大写名称:`[A-Z_][A-Z0-9_]*`。
|
||||
- 缺失 / 为空的变量会在加载配置时抛出错误。
|
||||
- 缺失/为空的变量会在加载配置时抛出错误。
|
||||
- 使用 `$${VAR}` 可转义为字面量 `${VAR}`。
|
||||
- 与 `$include` 一起可用。
|
||||
- 对 `$include` 同样有效。
|
||||
|
||||
---
|
||||
|
||||
## Secrets
|
||||
## 密钥
|
||||
|
||||
Secret ref 是增量功能:明文值仍然可用。
|
||||
Secret ref 为增量特性:明文值仍然可用。
|
||||
|
||||
### `SecretRef`
|
||||
|
||||
使用以下对象结构之一:
|
||||
使用如下对象形态之一:
|
||||
|
||||
```json5
|
||||
{ source: "env" | "file" | "exec", provider: "default", id: "..." }
|
||||
@ -645,15 +645,15 @@ Secret ref 是增量功能:明文值仍然可用。
|
||||
- `source: "env"` 的 id 模式:`^[A-Z][A-Z0-9_]{0,127}$`
|
||||
- `source: "file"` 的 id:绝对 JSON 指针(例如 `"/providers/openai/apiKey"`)
|
||||
- `source: "exec"` 的 id 模式:`^[A-Za-z0-9][A-Za-z0-9._:/-]{0,255}$`
|
||||
- `source: "exec"` 的 id 不得包含 `.` 或 `..` 这样的斜杠分隔路径段(例如 `a/../b` 会被拒绝)
|
||||
- `source: "exec"` 的 id 不能包含 `.` 或 `..` 这类以斜杠分隔的路径段(例如 `a/../b` 会被拒绝)
|
||||
|
||||
### 支持的凭据界面
|
||||
### 支持的凭证面
|
||||
|
||||
- 规范矩阵:[SecretRef 凭据界面](/zh-CN/reference/secretref-credential-surface)
|
||||
- `secrets apply` 以受支持的 `openclaw.json` 凭据路径为目标。
|
||||
- `auth-profiles.json` ref 也包含在运行时解析和审计覆盖范围内。
|
||||
- 规范矩阵:[SecretRef 凭证面](/zh-CN/reference/secretref-credential-surface)
|
||||
- `secrets apply` 作用于受支持的 `openclaw.json` 凭证路径。
|
||||
- `auth-profiles.json` ref 已纳入运行时解析和审计覆盖范围。
|
||||
|
||||
### Secret 提供商配置
|
||||
### 密钥提供商配置
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -684,17 +684,17 @@ Secret ref 是增量功能:明文值仍然可用。
|
||||
说明:
|
||||
|
||||
- `file` 提供商支持 `mode: "json"` 和 `mode: "singleValue"`(在 singleValue 模式下,`id` 必须为 `"value"`)。
|
||||
- 当无法验证 Windows ACL 时,file 和 exec 提供商路径会以关闭方式失败。仅对无法验证但你信任的路径设置 `allowInsecurePath: true`。
|
||||
- `exec` 提供商要求使用绝对 `command` 路径,并通过 stdin / stdout 使用协议负载。
|
||||
- 默认情况下,符号链接命令路径会被拒绝。设置 `allowSymlinkCommand: true` 可允许符号链接路径,同时验证解析后的目标路径。
|
||||
- 如果配置了 `trustedDirs`,受信任目录检查会应用到解析后的目标路径。
|
||||
- 默认情况下,`exec` 子进程环境是最小化的;请通过 `passEnv` 显式传递所需变量。
|
||||
- Secret ref 会在激活时解析为内存中的快照,之后请求路径只读取该快照。
|
||||
- 激活期间会应用活动界面过滤:已启用界面上的未解析 ref 会导致启动 / 重载失败,而非活动界面则会被跳过并附带诊断信息。
|
||||
- 当 Windows ACL 验证不可用时,file 和 exec 提供商路径会以失败关闭方式处理。仅对无法验证但受信任的路径设置 `allowInsecurePath: true`。
|
||||
- `exec` 提供商要求 `command` 为绝对路径,并通过 stdin/stdout 使用协议载荷。
|
||||
- 默认情况下,符号链接命令路径会被拒绝。设置 `allowSymlinkCommand: true` 可允许符号链接路径,同时仍验证解析后的目标路径。
|
||||
- 如果配置了 `trustedDirs`,受信任目录检查会作用于解析后的目标路径。
|
||||
- `exec` 子进程环境默认最小化;请使用 `passEnv` 显式传入所需变量。
|
||||
- Secret ref 会在激活时解析为内存快照,随后请求路径只读取该快照。
|
||||
- 激活期间会应用活动面过滤:启用面上无法解析的 ref 会导致启动/重载失败,而非活动面会被跳过并附带诊断信息。
|
||||
|
||||
---
|
||||
|
||||
## 认证存储
|
||||
## 凭证存储
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -713,11 +713,11 @@ Secret ref 是增量功能:明文值仍然可用。
|
||||
```
|
||||
|
||||
- 每个智能体的配置文件存储在 `<agentDir>/auth-profiles.json`。
|
||||
- `auth-profiles.json` 支持值级 ref(静态凭据模式下,`api_key` 使用 `keyRef`,`token` 使用 `tokenRef`)。
|
||||
- OAuth 模式配置文件(`auth.profiles.<id>.mode = "oauth"`)不支持由 SecretRef 驱动的 auth-profile 凭据。
|
||||
- 静态运行时凭据来自内存中已解析的快照;发现旧版静态 `auth.json` 条目时会进行清理。
|
||||
- 从 `~/.openclaw/credentials/oauth.json` 导入旧版 OAuth。
|
||||
- 请参见 [OAuth](/zh-CN/concepts/oauth)。
|
||||
- `auth-profiles.json` 支持静态凭证模式的值级 ref(`api_key` 使用 `keyRef`,`token` 使用 `tokenRef`)。
|
||||
- OAuth 模式配置文件(`auth.profiles.<id>.mode = "oauth"`)不支持基于 SecretRef 的 auth-profile 凭证。
|
||||
- 静态运行时凭证来自内存中的已解析快照;发现旧版静态 `auth.json` 条目时会被清理。
|
||||
- 旧版 OAuth 从 `~/.openclaw/credentials/oauth.json` 导入。
|
||||
- 参见 [OAuth](/zh-CN/concepts/oauth)。
|
||||
- Secrets 运行时行为以及 `audit/configure/apply` 工具:参见 [Secrets 管理](/zh-CN/gateway/secrets)。
|
||||
|
||||
### `auth.cooldowns`
|
||||
@ -740,20 +740,15 @@ Secret ref 是增量功能:明文值仍然可用。
|
||||
}
|
||||
```
|
||||
|
||||
- `billingBackoffHours`:当某个配置文件因真实的
|
||||
计费 / 额度不足错误而失败时,使用的基础退避时长(小时)(默认:`5`)。即使在 `401` / `403` 响应中,明确的计费文本
|
||||
仍可能归入这里,但提供商特定的文本
|
||||
匹配器仍仅限于拥有它们的提供商(例如 OpenRouter 的
|
||||
`Key limit exceeded`)。可重试的 HTTP `402` 使用窗口或
|
||||
组织 / 工作区消费上限消息则仍归入 `rate_limit` 路径。
|
||||
- `billingBackoffHoursByProvider`:按提供商覆盖计费退避小时数的可选配置。
|
||||
- `billingMaxHours`:计费退避指数增长的上限小时数(默认:`24`)。
|
||||
- `authPermanentBackoffMinutes`:高置信度 `auth_permanent` 失败的基础退避时长(分钟)(默认:`10`)。
|
||||
- `authPermanentMaxMinutes`:`auth_permanent` 退避增长的上限分钟数(默认:`60`)。
|
||||
- `failureWindowHours`:用于退避计数器的滚动时间窗口(小时)(默认:`24`)。
|
||||
- `overloadedProfileRotations`:在切换到模型回退前,同一提供商因过载错误而允许的最大 auth-profile 轮换次数(默认:`1`)。像 `ModelNotReadyException` 这样的提供商繁忙形态会归入这里。
|
||||
- `overloadedBackoffMs`:在重试过载的提供商 / 配置文件轮换前的固定延迟,单位为毫秒(默认:`0`)。
|
||||
- `rateLimitedProfileRotations`:在切换到模型回退前,同一提供商因速率限制错误而允许的最大 auth-profile 轮换次数(默认:`1`)。该速率限制桶包括具有提供商特征的文本,例如 `Too many concurrent requests`、`ThrottlingException`、`concurrency limit reached`、`workers_ai ... quota limit exceeded` 和 `resource exhausted`。
|
||||
- `billingBackoffHours`:当某个配置文件因真正的计费/余额不足错误而失败时使用的基础退避时间,单位小时(默认:`5`)。即使在 `401`/`403` 响应上,明确的计费文本仍可能归入这里,但提供商特定的文本匹配器会继续限定在拥有它们的提供商范围内(例如 OpenRouter 的 `Key limit exceeded`)。可重试的 HTTP `402` 使用窗口或组织/工作区支出限制消息,则仍归入 `rate_limit` 路径。
|
||||
- `billingBackoffHoursByProvider`:按提供商分别覆盖计费退避小时数的可选设置。
|
||||
- `billingMaxHours`:计费退避指数增长的上限,单位小时(默认:`24`)。
|
||||
- `authPermanentBackoffMinutes`:高置信度 `auth_permanent` 失败的基础退避时间,单位分钟(默认:`10`)。
|
||||
- `authPermanentMaxMinutes`:`auth_permanent` 退避增长的上限,单位分钟(默认:`60`)。
|
||||
- `failureWindowHours`:用于退避计数器的滚动时间窗口,单位小时(默认:`24`)。
|
||||
- `overloadedProfileRotations`:对于 overloaded 错误,在切换到模型回退之前,同一提供商 auth-profile 允许轮换的最大次数(默认:`1`)。像 `ModelNotReadyException` 这样的提供商繁忙形态归入这里。
|
||||
- `overloadedBackoffMs`:在重试 overloaded 提供商/配置文件轮换前的固定延迟,单位毫秒(默认:`0`)。
|
||||
- `rateLimitedProfileRotations`:对于速率限制错误,在切换到模型回退之前,同一提供商 auth-profile 允许轮换的最大次数(默认:`1`)。该速率限制桶包括提供商特定文本,例如 `Too many concurrent requests`、`ThrottlingException`、`concurrency limit reached`、`workers_ai ... quota limit exceeded` 和 `resource exhausted`。
|
||||
|
||||
---
|
||||
|
||||
@ -775,7 +770,7 @@ Secret ref 是增量功能:明文值仍然可用。
|
||||
- 默认日志文件:`/tmp/openclaw/openclaw-YYYY-MM-DD.log`。
|
||||
- 设置 `logging.file` 可使用固定路径。
|
||||
- 使用 `--verbose` 时,`consoleLevel` 会提升为 `debug`。
|
||||
- `maxFileBytes`:在抑制写入前允许的最大日志文件大小(字节)(正整数;默认:`524288000` = 500 MB)。生产部署请使用外部日志轮转。
|
||||
- `maxFileBytes`:在抑制写入前,日志文件允许的最大字节数(正整数;默认:`524288000` = 500 MB)。生产环境部署请使用外部日志轮转。
|
||||
|
||||
---
|
||||
|
||||
@ -820,21 +815,21 @@ Secret ref 是增量功能:明文值仍然可用。
|
||||
}
|
||||
```
|
||||
|
||||
- `enabled`:仪表输出的总开关(默认:`true`)。
|
||||
- `flags`:用于启用定向日志输出的标志字符串数组(支持如 `"telegram.*"` 或 `"*"` 这样的通配符)。
|
||||
- `stuckSessionWarnMs`:当某个会话仍处于 processing 状态时,发出卡住会话警告的年龄阈值,单位为毫秒。
|
||||
- `otel.enabled`:启用 OpenTelemetry 导出管道(默认:`false`)。
|
||||
- `otel.endpoint`:用于 OTel 导出的 collector URL。
|
||||
- `enabled`:检测输出总开关(默认:`true`)。
|
||||
- `flags`:用于启用定向日志输出的标志字符串数组(支持通配符,如 `"telegram.*"` 或 `"*"`)。
|
||||
- `stuckSessionWarnMs`:当会话仍处于处理中状态时,发出卡住会话警告的年龄阈值,单位毫秒。
|
||||
- `otel.enabled`:启用 OpenTelemetry 导出管线(默认:`false`)。
|
||||
- `otel.endpoint`:OTel 导出的采集器 URL。
|
||||
- `otel.protocol`:`"http/protobuf"`(默认)或 `"grpc"`。
|
||||
- `otel.headers`:随 OTel 导出请求发送的额外 HTTP / gRPC 元数据头。
|
||||
- `otel.serviceName`:资源属性使用的服务名称。
|
||||
- `otel.traces` / `otel.metrics` / `otel.logs`:启用 trace、metrics 或 logs 导出。
|
||||
- `otel.headers`:随 OTel 导出请求发送的额外 HTTP/gRPC 元数据头。
|
||||
- `otel.serviceName`:资源属性的服务名称。
|
||||
- `otel.traces` / `otel.metrics` / `otel.logs`:启用 trace、metrics 或 log 导出。
|
||||
- `otel.sampleRate`:trace 采样率 `0`–`1`。
|
||||
- `otel.flushIntervalMs`:定期刷新 telemetry 的时间间隔,单位为毫秒。
|
||||
- `otel.captureContent`:用于 OTEL span 属性的原始内容捕获显式启用项。默认关闭。布尔值 `true` 会捕获非系统消息 / 工具内容;对象形式则允许你显式启用 `inputMessages`、`outputMessages`、`toolInputs`、`toolOutputs` 和 `systemPrompt`。
|
||||
- `cacheTrace.enabled`:为嵌入式运行记录缓存追踪快照(默认:`false`)。
|
||||
- `cacheTrace.filePath`:缓存追踪 JSONL 的输出路径(默认:`$OPENCLAW_STATE_DIR/logs/cache-trace.jsonl`)。
|
||||
- `cacheTrace.includeMessages` / `includePrompt` / `includeSystem`:控制缓存追踪输出中包含的内容(默认均为 `true`)。
|
||||
- `otel.flushIntervalMs`:周期性遥测刷新间隔,单位毫秒。
|
||||
- `otel.captureContent`:用于 OTel span 属性的原始内容捕获显式启用项。默认关闭。布尔值 `true` 会捕获非 system 的消息/工具内容;对象形式则允许你显式启用 `inputMessages`、`outputMessages`、`toolInputs`、`toolOutputs` 和 `systemPrompt`。
|
||||
- `cacheTrace.enabled`:记录嵌入式运行的缓存跟踪快照(默认:`false`)。
|
||||
- `cacheTrace.filePath`:缓存跟踪 JSONL 的输出路径(默认:`$OPENCLAW_STATE_DIR/logs/cache-trace.jsonl`)。
|
||||
- `cacheTrace.includeMessages` / `includePrompt` / `includeSystem`:控制缓存跟踪输出中包含的内容(默认都为 `true`)。
|
||||
|
||||
---
|
||||
|
||||
@ -856,12 +851,12 @@ Secret ref 是增量功能:明文值仍然可用。
|
||||
}
|
||||
```
|
||||
|
||||
- `channel`:用于 npm / git 安装的发布渠道——`"stable"`、`"beta"` 或 `"dev"`。
|
||||
- `channel`:用于 npm/git 安装的发布渠道——`"stable"`、`"beta"` 或 `"dev"`。
|
||||
- `checkOnStart`:Gateway 网关启动时检查 npm 更新(默认:`true`)。
|
||||
- `auto.enabled`:为包安装启用后台自动更新(默认:`false`)。
|
||||
- `auto.stableDelayHours`:稳定渠道自动应用前的最小延迟小时数(默认:`6`;最大:`168`)。
|
||||
- `auto.stableJitterHours`:稳定渠道额外的发布扩散窗口小时数(默认:`12`;最大:`168`)。
|
||||
- `auto.betaCheckIntervalHours`:beta 渠道检查运行的频率(小时)(默认:`1`;最大:`24`)。
|
||||
- `auto.stableDelayHours`:stable 渠道自动应用前的最小时延,单位小时(默认:`6`;最大:`168`)。
|
||||
- `auto.stableJitterHours`:stable 渠道额外的发布扩散窗口,单位小时(默认:`12`;最大:`168`)。
|
||||
- `auto.betaCheckIntervalHours`:beta 渠道检查的运行频率,单位小时(默认:`1`;最大:`24`)。
|
||||
|
||||
---
|
||||
|
||||
@ -895,21 +890,21 @@ Secret ref 是增量功能:明文值仍然可用。
|
||||
```
|
||||
|
||||
- `enabled`:全局 ACP 功能开关(默认:`false`)。
|
||||
- `dispatch.enabled`:ACP 会话轮次分发的独立开关(默认:`true`)。设为 `false` 可在保留 ACP 命令可用的同时阻止执行。
|
||||
- `dispatch.enabled`:ACP 会话轮次分发的独立开关(默认:`true`)。设为 `false` 可在阻止执行的同时保留 ACP 命令可用。
|
||||
- `backend`:默认 ACP 运行时后端 id(必须匹配已注册的 ACP 运行时插件)。
|
||||
- `defaultAgent`:当生成过程未指定显式目标时,使用的 ACP 后备目标智能体 id。
|
||||
- `allowedAgents`:允许用于 ACP 运行时会话的智能体 id 允许列表;空值表示没有额外限制。
|
||||
- `maxConcurrentSessions`:同时活跃的 ACP 会话最大数量。
|
||||
- `stream.coalesceIdleMs`:流式文本的空闲合并刷新窗口,单位为毫秒。
|
||||
- `stream.maxChunkChars`:在拆分流式分块投影前允许的最大块大小。
|
||||
- `stream.repeatSuppression`:每轮抑制重复的状态 / 工具行(默认:`true`)。
|
||||
- `stream.deliveryMode`:`"live"` 增量流式传输;`"final_only"` 则缓冲到轮次终止事件再输出。
|
||||
- `stream.hiddenBoundarySeparator`:隐藏工具事件之后、可见文本之前的分隔符(默认:`"paragraph"`)。
|
||||
- `stream.maxOutputChars`:每个 ACP 轮次投影的最大助手输出字符数。
|
||||
- `stream.maxSessionUpdateChars`:投影的 ACP 状态 / 更新行的最大字符数。
|
||||
- `stream.tagVisibility`:tag 名称到布尔可见性覆盖的记录,用于流式事件。
|
||||
- `runtime.ttlMinutes`:ACP 会话工作进程在符合清理条件前的空闲 TTL,单位为分钟。
|
||||
- `runtime.installCommand`:在引导 ACP 运行时环境时运行的可选安装命令。
|
||||
- `defaultAgent`:当 spawn 未指定显式目标时的 ACP 回退目标智能体 id。
|
||||
- `allowedAgents`:允许用于 ACP 运行时会话的智能体 id 允许列表;为空表示不施加额外限制。
|
||||
- `maxConcurrentSessions`:同时处于活动状态的 ACP 会话最大数量。
|
||||
- `stream.coalesceIdleMs`:流式文本的空闲合并刷新窗口,单位毫秒。
|
||||
- `stream.maxChunkChars`:流式分块投影在拆分前的最大块大小。
|
||||
- `stream.repeatSuppression`:每轮抑制重复的状态/工具行(默认:`true`)。
|
||||
- `stream.deliveryMode`:`"live"` 为增量流式传输;`"final_only"` 会缓冲到轮次终止事件后再输出。
|
||||
- `stream.hiddenBoundarySeparator`:隐藏工具事件后、可见文本前的分隔符(默认:`"paragraph"`)。
|
||||
- `stream.maxOutputChars`:每个 ACP 轮次投影的智能体输出最大字符数。
|
||||
- `stream.maxSessionUpdateChars`:投影的 ACP 状态/更新行最大字符数。
|
||||
- `stream.tagVisibility`:tag 名称到布尔可见性覆盖值的记录,用于流式事件。
|
||||
- `runtime.ttlMinutes`:ACP 会话工作进程在符合清理条件前的空闲 TTL,单位分钟。
|
||||
- `runtime.installCommand`:引导 ACP 运行时环境时要运行的可选安装命令。
|
||||
|
||||
---
|
||||
|
||||
@ -926,9 +921,9 @@ Secret ref 是增量功能:明文值仍然可用。
|
||||
```
|
||||
|
||||
- `cli.banner.taglineMode` 控制横幅标语样式:
|
||||
- `"random"`(默认):轮换的有趣 / 季节性标语。
|
||||
- `"random"`(默认):轮换的有趣/季节性标语。
|
||||
- `"default"`:固定的中性标语(`All your chats, one OpenClaw.`)。
|
||||
- `"off"`:不显示标语文本(仍显示横幅标题 / 版本)。
|
||||
- `"off"`:不显示标语文本(仍显示横幅标题/版本)。
|
||||
- 若要隐藏整个横幅(而不仅仅是标语),请设置环境变量 `OPENCLAW_HIDE_BANNER=1`。
|
||||
|
||||
---
|
||||
@ -953,13 +948,13 @@ Secret ref 是增量功能:明文值仍然可用。
|
||||
|
||||
## 身份
|
||||
|
||||
请参见 [智能体默认值](/zh-CN/gateway/config-agents#agent-defaults) 下的 `agents.list` 身份字段。
|
||||
请参见 [智能体默认值](/zh-CN/gateway/config-agents#agent-defaults) 下 `agents.list` 的身份字段。
|
||||
|
||||
---
|
||||
|
||||
## Bridge protocol(旧版节点,历史参考)(旧版,已移除)
|
||||
|
||||
当前构建已不再包含 TCP bridge。节点通过 Gateway 网关 WebSocket 连接。`bridge.*` 键已不再属于配置 schema 的一部分(在移除前验证会失败;`openclaw doctor --fix` 可以清除未知键)。
|
||||
当前构建已不再包含 TCP bridge。节点通过 Gateway 网关 WebSocket 连接。`bridge.*` 键已不再属于配置 schema 的一部分(移除前验证会失败;`openclaw doctor --fix` 可以剥离未知键)。
|
||||
|
||||
<Accordion title="旧版 bridge 配置(历史参考)">
|
||||
|
||||
@ -999,11 +994,11 @@ Secret ref 是增量功能:明文值仍然可用。
|
||||
}
|
||||
```
|
||||
|
||||
- `sessionRetention`:在从 `sessions.json` 中清理前,已完成的隔离 cron 运行会话保留多久。也控制已归档的已删除 cron 转录内容的清理。默认:`24h`;设为 `false` 可禁用。
|
||||
- `runLog.maxBytes`:每个运行日志文件(`cron/runs/<jobId>.jsonl`)在触发清理前的最大大小。默认:`2_000_000` 字节。
|
||||
- `runLog.keepLines`:触发运行日志清理时保留的最新行数。默认:`2000`。
|
||||
- `webhookToken`:用于 cron webhook POST 投递(`delivery.mode = "webhook"`)的 bearer token;如果省略,则不会发送认证头。
|
||||
- `webhook`:已弃用的旧版后备 webhook URL(http / https),仅用于仍带有 `notify: true` 的已存储任务。
|
||||
- `sessionRetention`:在从 `sessions.json` 清理前,保留已完成隔离 cron 运行会话的时长。也控制已归档的已删除 cron 转录的清理。默认:`24h`;设为 `false` 可禁用。
|
||||
- `runLog.maxBytes`:每个运行日志文件(`cron/runs/<jobId>.jsonl`)在触发裁剪前的最大大小。默认:`2_000_000` 字节。
|
||||
- `runLog.keepLines`:触发运行日志裁剪时保留的最新行数。默认:`2000`。
|
||||
- `webhookToken`:用于 cron webhook POST 投递(`delivery.mode = "webhook"`)的 bearer token;若省略,则不发送凭证头。
|
||||
- `webhook`:已弃用的旧版回退 webhook URL(http/https),仅用于仍保留 `notify: true` 的已存储任务。
|
||||
|
||||
### `cron.retry`
|
||||
|
||||
@ -1020,10 +1015,10 @@ Secret ref 是增量功能:明文值仍然可用。
|
||||
```
|
||||
|
||||
- `maxAttempts`:一次性任务在瞬时错误下的最大重试次数(默认:`3`;范围:`0`–`10`)。
|
||||
- `backoffMs`:每次重试尝试的退避延迟数组,单位为毫秒(默认:`[30000, 60000, 300000]`;1–10 个条目)。
|
||||
- `retryOn`:触发重试的错误类型——`"rate_limit"`、`"overloaded"`、`"network"`、`"timeout"`、`"server_error"`。省略时会重试所有瞬时类型。
|
||||
- `backoffMs`:每次重试尝试对应的退避延迟数组,单位毫秒(默认:`[30000, 60000, 300000]`;1–10 项)。
|
||||
- `retryOn`:触发重试的错误类型——`"rate_limit"`、`"overloaded"`、`"network"`、`"timeout"`、`"server_error"`。省略则会重试所有瞬时错误类型。
|
||||
|
||||
仅适用于一次性 cron 任务。周期性任务使用单独的失败处理方式。
|
||||
仅适用于一次性 cron 任务。周期性任务使用独立的失败处理逻辑。
|
||||
|
||||
### `cron.failureAlert`
|
||||
|
||||
@ -1041,10 +1036,10 @@ Secret ref 是增量功能:明文值仍然可用。
|
||||
}
|
||||
```
|
||||
|
||||
- `enabled`:启用 cron 任务失败告警(默认:`false`)。
|
||||
- `after`:在触发告警前允许的连续失败次数(正整数,最小值:`1`)。
|
||||
- `cooldownMs`:同一任务重复告警之间的最小毫秒间隔(非负整数)。
|
||||
- `mode`:投递模式——`"announce"` 通过渠道消息发送;`"webhook"` 向配置的 webhook 发起 POST。
|
||||
- `enabled`:为 cron 任务启用失败告警(默认:`false`)。
|
||||
- `after`:连续失败多少次后触发告警(正整数,最小值:`1`)。
|
||||
- `cooldownMs`:同一任务重复告警之间的最短间隔,单位毫秒(非负整数)。
|
||||
- `mode`:投递模式——`"announce"` 通过渠道消息发送;`"webhook"` 则 POST 到已配置的 webhook。
|
||||
- `accountId`:用于限定告警投递范围的可选账号或渠道 id。
|
||||
|
||||
### `cron.failureDestination`
|
||||
@ -1064,14 +1059,14 @@ Secret ref 是增量功能:明文值仍然可用。
|
||||
|
||||
- 所有任务共用的 cron 失败通知默认目标。
|
||||
- `mode`:`"announce"` 或 `"webhook"`;当存在足够的目标数据时,默认值为 `"announce"`。
|
||||
- `channel`:用于 announce 投递的渠道覆盖。`"last"` 会复用最近一次已知的投递渠道。
|
||||
- `to`:显式的 announce 目标或 webhook URL。在 webhook 模式下为必填。
|
||||
- `accountId`:可选的投递账号覆盖。
|
||||
- 每个任务的 `delivery.failureDestination` 会覆盖这个全局默认值。
|
||||
- 当全局和每个任务的失败目标都未设置时,那些本来通过 `announce` 投递的任务会在失败时回退到其主 announce 目标。
|
||||
- `channel`:announce 投递的渠道覆盖值。`"last"` 会复用最后一次已知投递渠道。
|
||||
- `to`:显式的 announce 目标或 webhook URL。webhook 模式下为必填。
|
||||
- `accountId`:投递时使用的可选账号覆盖值。
|
||||
- 每个任务的 `delivery.failureDestination` 会覆盖该全局默认值。
|
||||
- 当既未设置全局失败目标,也未设置按任务失败目标时,那些已通过 `announce` 投递的任务会在失败时回退到其主 announce 目标。
|
||||
- `delivery.failureDestination` 仅支持 `sessionTarget="isolated"` 的任务,除非该任务的主 `delivery.mode` 为 `"webhook"`。
|
||||
|
||||
请参见 [Cron 任务](/zh-CN/automation/cron-jobs)。隔离的 cron 执行会作为[后台任务](/zh-CN/automation/tasks)进行跟踪。
|
||||
参见 [Cron 任务](/zh-CN/automation/cron-jobs)。隔离的 cron 执行会作为 [后台任务](/zh-CN/automation/tasks) 进行跟踪。
|
||||
|
||||
---
|
||||
|
||||
@ -1079,34 +1074,34 @@ Secret ref 是增量功能:明文值仍然可用。
|
||||
|
||||
在 `tools.media.models[].args` 中展开的模板占位符:
|
||||
|
||||
| 变量 | 说明 |
|
||||
| Variable | 说明 |
|
||||
| ------------------ | ------------------------------------------------- |
|
||||
| `{{Body}}` | 完整的入站消息正文 |
|
||||
| `{{RawBody}}` | 原始正文(不含历史记录 / 发送者包装) |
|
||||
| `{{BodyStripped}}` | 去除了群组提及的正文 |
|
||||
| `{{From}}` | 发送者标识符 |
|
||||
| `{{To}}` | 目标标识符 |
|
||||
| `{{MessageSid}}` | 渠道消息 id |
|
||||
| `{{SessionId}}` | 当前 session UUID |
|
||||
| `{{IsNewSession}}` | 新建 session 时为 `"true"` |
|
||||
| `{{MediaUrl}}` | 入站媒体伪 URL |
|
||||
| `{{MediaPath}}` | 本地媒体路径 |
|
||||
| `{{MediaType}}` | 媒体类型(image/audio/document/…) |
|
||||
| `{{Transcript}}` | 音频转录 |
|
||||
| `{{Prompt}}` | 为 CLI 条目解析后的媒体提示词 |
|
||||
| `{{MaxChars}}` | 为 CLI 条目解析后的最大输出字符数 |
|
||||
| `{{ChatType}}` | `"direct"` 或 `"group"` |
|
||||
| `{{Body}}` | 完整的入站消息正文 |
|
||||
| `{{RawBody}}` | 原始正文(无历史记录/发送者包装) |
|
||||
| `{{BodyStripped}}` | 移除了群组提及的正文 |
|
||||
| `{{From}}` | 发送者标识符 |
|
||||
| `{{To}}` | 目标标识符 |
|
||||
| `{{MessageSid}}` | 渠道消息 id |
|
||||
| `{{SessionId}}` | 当前会话 UUID |
|
||||
| `{{IsNewSession}}` | 新建会话时为 `"true"` |
|
||||
| `{{MediaUrl}}` | 入站媒体伪 URL |
|
||||
| `{{MediaPath}}` | 本地媒体路径 |
|
||||
| `{{MediaType}}` | 媒体类型(image/audio/document/…) |
|
||||
| `{{Transcript}}` | 音频转录文本 |
|
||||
| `{{Prompt}}` | CLI 条目的已解析媒体提示词 |
|
||||
| `{{MaxChars}}` | CLI 条目的已解析最大输出字符数 |
|
||||
| `{{ChatType}}` | `"direct"` 或 `"group"` |
|
||||
| `{{GroupSubject}}` | 群组主题(尽力而为) |
|
||||
| `{{GroupMembers}}` | 群组成员预览(尽力而为) |
|
||||
| `{{SenderName}}` | 发送者显示名称(尽力而为) |
|
||||
| `{{SenderE164}}` | 发送者电话号码(尽力而为) |
|
||||
| `{{Provider}}` | 提供商提示(whatsapp、telegram、discord 等) |
|
||||
| `{{SenderName}}` | 发送者显示名称(尽力而为) |
|
||||
| `{{SenderE164}}` | 发送者电话号码(尽力而为) |
|
||||
| `{{Provider}}` | 提供商提示(whatsapp、telegram、discord 等) |
|
||||
|
||||
---
|
||||
|
||||
## 配置 include(`$include`)
|
||||
|
||||
将配置拆分为多个文件:
|
||||
将配置拆分到多个文件中:
|
||||
|
||||
```json5
|
||||
// ~/.openclaw/openclaw.json
|
||||
@ -1122,19 +1117,19 @@ Secret ref 是增量功能:明文值仍然可用。
|
||||
**合并行为:**
|
||||
|
||||
- 单个文件:替换所在的包含对象。
|
||||
- 文件数组:按顺序深度合并(后者覆盖前者)。
|
||||
- 同级键:在 include 之后合并(覆盖 include 的值)。
|
||||
- 嵌套 include:最多 10 层深。
|
||||
- 路径:相对于包含它的文件解析,但必须保持在顶层配置目录(`openclaw.json` 的 `dirname`)内。仅当绝对路径 / `../` 形式最终仍解析到该边界内时才允许。
|
||||
- 当 OpenClaw 自有写入仅更改由单文件 include 支持的某一个顶层 section 时,写入会透传到该 include 文件。例如,`plugins install` 会把 `plugins: { $include: "./plugins.json5" }` 的更新写入 `plugins.json5`,并保持 `openclaw.json` 不变。
|
||||
- 根 include、include 数组,以及带有同级覆盖的 include 对 OpenClaw 自有写入来说是只读的;这些写入会以关闭方式失败,而不是将配置展平。
|
||||
- 错误:对缺失文件、解析错误和循环 include 提供清晰的错误消息。
|
||||
- 文件数组:按顺序进行深度合并(后者覆盖前者)。
|
||||
- 同级键:在 includes 之后合并(覆盖 include 的值)。
|
||||
- 嵌套 include:最多支持 10 层深度。
|
||||
- 路径:相对于包含它的文件解析,但必须保持在顶层配置目录(`openclaw.json` 的 `dirname`)内。仅当绝对路径/`../` 最终仍解析到该边界内时才允许。
|
||||
- 仅变更某个由单文件 include 支持的顶层 section 的 OpenClaw 自有写入,会直写到该 include 文件。例如,`plugins install` 会将 `plugins: { $include: "./plugins.json5" }` 更新到 `plugins.json5` 中,并保持 `openclaw.json` 不变。
|
||||
- 根级 include、include 数组以及带有同级覆盖的 include,对 OpenClaw 自有写入均为只读;这些写入会以失败关闭方式终止,而不是将配置拍平。
|
||||
- 错误:会为缺失文件、解析错误和循环 include 提供清晰消息。
|
||||
|
||||
---
|
||||
|
||||
_相关内容:[配置](/zh-CN/gateway/configuration) · [配置示例](/zh-CN/gateway/configuration-examples) · [Doctor](/zh-CN/gateway/doctor)_
|
||||
_相关:[配置](/zh-CN/gateway/configuration) · [配置示例](/zh-CN/gateway/configuration-examples) · [Doctor](/zh-CN/gateway/doctor)_
|
||||
|
||||
## 相关内容
|
||||
## 相关
|
||||
|
||||
- [配置](/zh-CN/gateway/configuration)
|
||||
- [配置示例](/zh-CN/gateway/configuration-examples)
|
||||
|
||||
@ -1,29 +1,29 @@
|
||||
---
|
||||
read_when:
|
||||
- 构建或调试原生 OpenClaw 插件
|
||||
- 理解插件能力模型或所有权边界
|
||||
- 处理插件加载流程或注册表
|
||||
- 理解插件能力模型或归属边界
|
||||
- 处理插件加载管线或注册表
|
||||
- 实现提供商运行时钩子或渠道插件
|
||||
sidebarTitle: Internals
|
||||
summary: 插件内部机制:能力模型、所有权、契约、加载流程和运行时辅助工具
|
||||
summary: 插件内部机制:能力模型、归属、契约、加载管线和运行时辅助工具
|
||||
title: 插件内部机制
|
||||
x-i18n:
|
||||
generated_at: "2026-04-24T06:33:30Z"
|
||||
generated_at: "2026-04-25T02:35:33Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: d05891966669e599b1aa0165f20f913bfa82c22436356177436fba5d1be31e7b
|
||||
source_hash: d1fd7d9192c8c06aceeb6e8054a740bba27c94770e17eabf064627adda884e77
|
||||
source_path: plugins/architecture.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
这是 OpenClaw 插件系统的**深度架构参考**。如需实用指南,请先从下面的聚焦页面之一开始。
|
||||
这是 OpenClaw 插件系统的**深度架构参考**。如需实用指南,请先从下面这些聚焦页面之一开始。
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="安装和使用插件" icon="plug" href="/zh-CN/tools/plugin">
|
||||
面向终端用户的指南,介绍如何添加、启用和故障排除插件。
|
||||
</Card>
|
||||
<Card title="构建插件" icon="rocket" href="/zh-CN/plugins/building-plugins">
|
||||
首个插件教程,包含最小可工作的清单。
|
||||
首个插件教程,使用最小可工作的清单文件。
|
||||
</Card>
|
||||
<Card title="渠道插件" icon="comments" href="/zh-CN/plugins/sdk-channel-plugins">
|
||||
构建一个消息渠道插件。
|
||||
@ -36,11 +36,11 @@ x-i18n:
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## 公共能力模型
|
||||
## 公开能力模型
|
||||
|
||||
能力是 OpenClaw 内部公开的**原生插件**模型。每个原生 OpenClaw 插件都会针对一个或多个能力类型进行注册:
|
||||
能力是 OpenClaw 内部公开的**原生插件**模型。每个原生 OpenClaw 插件都会针对一种或多种能力类型进行注册:
|
||||
|
||||
| 能力 | 注册方式 | 示例插件 |
|
||||
| 能力 | 注册方法 | 示例插件 |
|
||||
| ---------------------- | ------------------------------------------------ | ------------------------------------ |
|
||||
| 文本推理 | `api.registerProvider(...)` | `openai`, `anthropic` |
|
||||
| CLI 推理后端 | `api.registerCliBackend(...)` | `openai`, `anthropic` |
|
||||
@ -51,47 +51,47 @@ x-i18n:
|
||||
| 图像生成 | `api.registerImageGenerationProvider(...)` | `openai`, `google`, `fal`, `minimax` |
|
||||
| 音乐生成 | `api.registerMusicGenerationProvider(...)` | `google`, `minimax` |
|
||||
| 视频生成 | `api.registerVideoGenerationProvider(...)` | `qwen` |
|
||||
| 网页抓取 | `api.registerWebFetchProvider(...)` | `firecrawl` |
|
||||
| 网页搜索 | `api.registerWebSearchProvider(...)` | `google` |
|
||||
| 渠道 / 消息传递 | `api.registerChannel(...)` | `msteams`, `matrix` |
|
||||
| Web 抓取 | `api.registerWebFetchProvider(...)` | `firecrawl` |
|
||||
| Web 搜索 | `api.registerWebSearchProvider(...)` | `google` |
|
||||
| 渠道 / 消息 | `api.registerChannel(...)` | `msteams`, `matrix` |
|
||||
| Gateway 网关发现 | `api.registerGatewayDiscoveryService(...)` | `bonjour` |
|
||||
|
||||
如果某个插件注册了零个能力,但提供了钩子、工具、发现服务或后台服务,那么它就是一个**仅 legacy 钩子**插件。该模式目前仍然得到完整支持。
|
||||
如果某个插件注册了零个能力,但提供了钩子、工具、发现服务或后台服务,则它属于**仅 legacy hook** 插件。该模式目前仍被完全支持。
|
||||
|
||||
### 外部兼容性立场
|
||||
|
||||
能力模型已经在核心中落地,并被当前的内置 / 原生插件使用,但外部插件兼容性仍需要比“它已导出,因此它已冻结”更严格的标准。
|
||||
能力模型已经在核心中落地,并且当前已被内置 / 原生插件使用,但外部插件兼容性仍需要比“它已导出,因此它已冻结”更严格的标准。
|
||||
|
||||
| 插件情况 | 指引 |
|
||||
| ------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
|
||||
| 现有外部插件 | 保持基于钩子的集成继续工作;这是兼容性基线。 |
|
||||
| 新的内置 / 原生插件 | 优先使用显式能力注册,而不是面向特定厂商的直连方式,或新的仅钩子设计。 |
|
||||
| 采用能力注册的外部插件 | 允许,但除非文档明确标记为稳定,否则应将特定能力的辅助接口视为仍在演进中。 |
|
||||
| 现有外部插件 | 保持基于钩子的集成继续可用;这是兼容性的基线。 |
|
||||
| 新的内置 / 原生插件 | 优先选择显式能力注册,而不是面向特定厂商的深入访问或新的纯钩子设计。 |
|
||||
| 采用能力注册的外部插件 | 允许,但除非文档明确标记为稳定,否则应将特定于能力的辅助接口视为仍在演进中。 |
|
||||
|
||||
能力注册是预期的发展方向。在过渡期间,legacy 钩子仍然是对外部插件最安全、最不容易破坏的路径。导出的辅助子路径并不完全等价——相比偶然暴露的辅助导出,应优先使用范围更窄、文档化的契约。
|
||||
能力注册是预期的发展方向。在过渡期间,对于外部插件来说,legacy hook 仍然是最安全、最不易破坏的路径。已导出的辅助子路径并不完全等同 —— 应优先选择范围明确、已文档化的契约,而不是偶然暴露出来的辅助导出。
|
||||
|
||||
### 插件形态
|
||||
|
||||
OpenClaw 会根据每个已加载插件的实际注册行为(而不仅仅是静态元数据)将其归类为某种形态:
|
||||
OpenClaw 会根据每个已加载插件的实际注册行为(而不只是静态元数据)将其分类为一种形态:
|
||||
|
||||
- **plain-capability**:恰好注册一种能力类型(例如仅提供商插件 `mistral`)。
|
||||
- **hybrid-capability**:注册多种能力类型(例如 `openai` 拥有文本推理、语音、媒体理解和图像生成)。
|
||||
- **hook-only**:仅注册钩子(类型化或自定义),不注册能力、工具、命令或服务。
|
||||
- **non-capability**:注册工具、命令、服务或路由,但不注册任何能力。
|
||||
- **hybrid-capability**:注册多种能力类型(例如 `openai` 同时拥有文本推理、语音、媒体理解和图像生成)。
|
||||
- **hook-only**:只注册钩子(类型化或自定义),不注册能力、工具、命令或服务。
|
||||
- **non-capability**:注册工具、命令、服务或路由,但不注册能力。
|
||||
|
||||
使用 `openclaw plugins inspect <id>` 查看插件的形态和能力细分。详见 [CLI 参考](/zh-CN/cli/plugins#inspect)。
|
||||
使用 `openclaw plugins inspect <id>` 可查看插件的形态和能力拆分。详情请参见 [CLI 参考](/zh-CN/cli/plugins#inspect)。
|
||||
|
||||
### Legacy 钩子
|
||||
### Legacy hooks
|
||||
|
||||
`before_agent_start` 钩子仍然作为仅钩子插件的兼容路径而受到支持。现实中的 legacy 插件仍然依赖它。
|
||||
`before_agent_start` 钩子仍然作为仅 hook 插件的兼容路径而受到支持。现实中的 legacy 插件仍然依赖它。
|
||||
|
||||
方向如下:
|
||||
|
||||
- 保持其可用
|
||||
- 在文档中将其标记为 legacy
|
||||
- 将其文档标注为 legacy
|
||||
- 对于模型 / 提供商覆盖工作,优先使用 `before_model_resolve`
|
||||
- 对于提示词变更工作,优先使用 `before_prompt_build`
|
||||
- 只有在真实使用量下降,并且夹具覆盖证明迁移安全后,才移除它
|
||||
- 仅在真实使用量下降且夹具覆盖证明迁移安全后再移除
|
||||
|
||||
### 兼容性信号
|
||||
|
||||
@ -99,70 +99,71 @@ OpenClaw 会根据每个已加载插件的实际注册行为(而不仅仅是
|
||||
|
||||
| 信号 | 含义 |
|
||||
| -------------------------- | ------------------------------------------------------------ |
|
||||
| **config valid** | 配置解析正常,插件可解析 |
|
||||
| **compatibility advisory** | 插件使用了受支持但较旧的模式(例如 `hook-only`) |
|
||||
| **legacy warning** | 插件使用了已弃用的 `before_agent_start` |
|
||||
| **config valid** | 配置解析正常,且插件可被解析 |
|
||||
| **compatibility advisory** | 插件使用受支持但较旧的模式(例如 `hook-only`) |
|
||||
| **legacy warning** | 插件使用 `before_agent_start`,该接口已弃用 |
|
||||
| **hard error** | 配置无效或插件加载失败 |
|
||||
|
||||
目前,`hook-only` 和 `before_agent_start` 都不会导致你的插件损坏:`hook-only` 只是提示,而 `before_agent_start` 只会触发警告。这些信号也会出现在 `openclaw status --all` 和 `openclaw plugins doctor` 中。
|
||||
当前,`hook-only` 和 `before_agent_start` 都不会让你的插件损坏:`hook-only` 只是提示性信息,而 `before_agent_start` 只会触发警告。这些信号也会出现在 `openclaw status --all` 和 `openclaw plugins doctor` 中。
|
||||
|
||||
## 架构概览
|
||||
|
||||
OpenClaw 的插件系统有四层:
|
||||
|
||||
1. **清单 + 设备发现**
|
||||
OpenClaw 会从已配置路径、工作区根目录、全局插件根目录以及内置插件中查找候选插件。设备发现会优先读取原生 `openclaw.plugin.json` 清单以及受支持的 bundle 清单。
|
||||
1. **清单文件 + 设备发现**
|
||||
OpenClaw 会从已配置路径、工作区根目录、全局插件根目录和内置插件中查找候选插件。设备发现会先读取原生 `openclaw.plugin.json` 清单文件以及受支持的 bundle 清单文件。
|
||||
2. **启用 + 验证**
|
||||
核心会决定某个已发现插件是启用、禁用、阻止,还是被选中用于某个独占槽位(例如 memory)。
|
||||
核心决定某个已发现的插件是启用、禁用、阻止,还是被选入诸如 memory 之类的独占插槽。
|
||||
3. **运行时加载**
|
||||
原生 OpenClaw 插件会通过 jiti 在进程内加载,并将能力注册到中央注册表中。兼容的 bundle 会被规范化为注册表记录,而无需导入运行时代码。
|
||||
4. **接口消费**
|
||||
OpenClaw 的其余部分会读取注册表,以暴露工具、渠道、提供商设置、钩子、HTTP 路由、CLI 命令和服务。
|
||||
原生 OpenClaw 插件通过 jiti 在进程内加载,并将能力注册到中央注册表中。兼容的 bundle 会在不导入运行时代码的情况下被规范化为注册表记录。
|
||||
4. **表面消费**
|
||||
OpenClaw 的其余部分会读取注册表,以公开工具、渠道、提供商设置、钩子、HTTP 路由、CLI 命令和服务。
|
||||
|
||||
对于插件 CLI,根命令发现会拆分为两个阶段:
|
||||
对于插件 CLI 而言,根命令发现会拆分为两个阶段:
|
||||
|
||||
- 解析时元数据来自 `registerCli(..., { descriptors: [...] })`
|
||||
- 真正的插件 CLI 模块可以保持惰性,并在首次调用时注册
|
||||
- 真正的插件 CLI 模块可以保持惰性,并在首次调用时再注册
|
||||
|
||||
这样既能让插件拥有的 CLI 代码保留在插件内部,又能让 OpenClaw 在解析前预留根命令名称。
|
||||
这样既能让插件自有的 CLI 代码保留在插件内部,又能让 OpenClaw 在解析前预留根命令名称。
|
||||
|
||||
重要的设计边界是:
|
||||
|
||||
- 设备发现 + 配置验证应当依赖**清单 / schema 元数据**完成,而无需执行插件代码
|
||||
- 原生运行时行为来自插件模块的 `register(api)` 路径
|
||||
- 清单文件 / 配置验证应当基于**清单文件 / schema 元数据**完成,而无需执行插件代码
|
||||
- 原生能力发现可以加载受信任的插件入口代码,以构建一个非激活的注册表快照
|
||||
- 原生运行时行为来自插件模块的 `register(api)` 路径,其中 `api.registrationMode === "full"`
|
||||
|
||||
这种拆分使 OpenClaw 能够在完整运行时尚未激活前,就验证配置、解释缺失 / 已禁用插件,并构建 UI / schema 提示。
|
||||
这种拆分使 OpenClaw 能够在完整运行时激活之前,先验证配置、解释缺失 / 被禁用的插件,并构建 UI / schema 提示。
|
||||
|
||||
### 激活规划
|
||||
|
||||
激活规划属于控制平面的一部分。调用方可以在加载更广泛的运行时注册表之前,先询问哪些插件与某个具体命令、提供商、渠道、路由、智能体 harness 或能力相关。
|
||||
激活规划是控制平面的一部分。调用方可以在加载更广泛的运行时注册表之前,先询问哪些插件与某个具体命令、提供商、渠道、路由、Agent harness 或能力相关。
|
||||
|
||||
规划器会保持当前清单行为的兼容性:
|
||||
规划器会保持当前清单文件行为的兼容性:
|
||||
|
||||
- `activation.*` 字段是显式的规划器提示
|
||||
- `providers`、`channels`、`commandAliases`、`setup.providers`、`contracts.tools` 和钩子仍然是清单所有权回退来源
|
||||
- `providers`、`channels`、`commandAliases`、`setup.providers`、`contracts.tools` 和 hooks 仍然是清单文件归属的回退来源
|
||||
- 仅 id 的规划器 API 仍然对现有调用方可用
|
||||
- 规划 API 会报告原因标签,以便诊断区分显式提示和所有权回退
|
||||
- 规划 API 会报告原因标签,以便诊断区分显式提示与归属回退
|
||||
|
||||
不要把 `activation` 视为生命周期钩子,也不要把它视为 `register(...)` 的替代品。它只是用于缩小加载范围的元数据。当现有所有权字段已经足以描述关系时,应优先使用它们;只有在需要额外规划器提示时,才使用 `activation`。
|
||||
不要把 `activation` 视为生命周期钩子,也不要把它当作 `register(...)` 的替代品。它是用于缩小加载范围的元数据。当归属字段已经能描述关系时,应优先使用归属字段;只有在需要额外规划提示时才使用 `activation`。
|
||||
|
||||
### 渠道插件和共享 message 工具
|
||||
### 渠道插件与共享 message 工具
|
||||
|
||||
对于常规聊天操作,渠道插件不需要单独注册发送 / 编辑 / 响应工具。OpenClaw 在核心中保留了一个共享的 `message` 工具,而渠道插件负责其背后的渠道特定发现与执行。
|
||||
|
||||
当前边界如下:
|
||||
|
||||
- 核心拥有共享 `message` 工具宿主、提示词接线、会话 / 线程簿记和执行分派
|
||||
- 渠道插件拥有作用域动作发现、能力发现以及任何渠道特定的 schema 片段
|
||||
- 核心拥有共享 `message` 工具宿主、提示词接线、会话 / 线程记账以及执行分发
|
||||
- 渠道插件拥有作用域化的动作发现、能力发现以及任何渠道特定的 schema 片段
|
||||
- 渠道插件拥有提供商特定的会话对话语法,例如对话 id 如何编码线程 id,或如何从父对话继承
|
||||
- 渠道插件通过其动作适配器执行最终动作
|
||||
|
||||
对于渠道插件,SDK 接口是 `ChannelMessageActionAdapter.describeMessageTool(...)`。这个统一的发现调用允许插件将其可见动作、能力和 schema 扩展一起返回,从而避免这些部分彼此漂移。
|
||||
对于渠道插件,SDK 接口是 `ChannelMessageActionAdapter.describeMessageTool(...)`。这个统一的发现调用允许插件将可见动作、能力以及 schema 贡献一起返回,从而避免这些部分彼此漂移。
|
||||
|
||||
当某个渠道特定的消息工具参数携带媒体来源,例如本地路径或远程媒体 URL 时,插件还应从 `describeMessageTool(...)` 返回 `mediaSourceParams`。核心会使用这份显式列表来应用沙箱路径规范化和出站媒体访问提示,而不是硬编码插件拥有的参数名。
|
||||
这里应优先使用按动作划分的映射,而不是一个按渠道统一的扁平列表,这样仅用于 profile 的媒体参数就不会在 `send` 之类的不相关动作上被规范化。
|
||||
当某个渠道特定的消息工具参数携带媒体源(例如本地路径或远程媒体 URL)时,插件还应从 `describeMessageTool(...)` 返回 `mediaSourceParams`。核心会使用这份显式列表来应用沙箱路径规范化和出站媒体访问提示,而无需硬编码插件自有参数名。
|
||||
这里应优先使用按动作划分的映射,而不是整个渠道共用的扁平列表,这样仅配置文件相关的媒体参数就不会在 `send` 等无关动作上被规范化。
|
||||
|
||||
核心会将运行时作用域传入这个发现步骤。重要字段包括:
|
||||
核心会将运行时作用域传入这一步发现过程。重要字段包括:
|
||||
|
||||
- `accountId`
|
||||
- `currentChannelId`
|
||||
@ -173,80 +174,80 @@ OpenClaw 的插件系统有四层:
|
||||
- `agentId`
|
||||
- 受信任的入站 `requesterSenderId`
|
||||
|
||||
这对于上下文敏感型插件很重要。渠道可以根据活动账户、当前房间 / 线程 / 消息,或受信任的请求者身份,隐藏或暴露消息动作,而无需在核心 `message` 工具中硬编码渠道特定分支。
|
||||
这对于上下文敏感的插件很重要。渠道可以根据当前账户、当前房间 / 线程 / 消息,或受信任的请求者身份,隐藏或暴露消息动作,而无需在核心 `message` 工具中硬编码渠道特定分支。
|
||||
|
||||
这也是为什么嵌入式 runner 路由变更仍然属于插件工作:runner 负责将当前聊天 / 会话身份转发到插件发现边界,以便共享 `message` 工具在当前轮次暴露正确的渠道拥有接口。
|
||||
这也是为什么嵌入式 runner 路由变更仍然属于插件工作:runner 负责将当前聊天 / 会话身份转发到插件发现边界中,从而让共享 `message` 工具在当前轮次中暴露正确的、由渠道拥有的表面。
|
||||
|
||||
对于渠道拥有的执行辅助工具,内置插件应将执行运行时保留在它们自己的扩展模块中。核心不再在 `src/agents/tools` 下拥有 Discord、Slack、Telegram 或 WhatsApp 的消息动作运行时。我们不会发布单独的 `plugin-sdk/*-action-runtime` 子路径,内置插件应直接从各自扩展拥有的模块中导入本地运行时代码。
|
||||
对于渠道自有的执行辅助工具,内置插件应将执行运行时保留在其各自的扩展模块内部。核心不再拥有位于 `src/agents/tools` 下的 Discord、Slack、Telegram 或 WhatsApp 消息动作运行时。我们不会发布独立的 `plugin-sdk/*-action-runtime` 子路径,内置插件应直接从其扩展自有模块导入本地运行时代码。
|
||||
|
||||
同样的边界也适用于一般性的提供商命名 SDK 接缝:核心不应导入面向 Slack、Discord、Signal、WhatsApp 或类似扩展的渠道特定便捷 barrel。如果核心需要某种行为,要么消费该内置插件自己的 `api.ts` / `runtime-api.ts` barrel,要么将该需求提升为共享 SDK 中范围更窄的通用能力。
|
||||
同样的边界也适用于一般意义上按提供商命名的 SDK 接缝:核心不应导入面向 Slack、Discord、Signal、WhatsApp 或类似扩展的渠道特定便捷 barrel。如果核心需要某种行为,要么消费内置插件自己的 `api.ts` / `runtime-api.ts` barrel,要么将这项需求提升为共享 SDK 中范围明确的通用能力。
|
||||
|
||||
对于投票,具体有两条执行路径:
|
||||
|
||||
- `outbound.sendPoll` 是适用于符合通用投票模型的渠道的共享基线
|
||||
- `actions.handleAction("poll")` 是用于渠道特定投票语义或额外投票参数的首选路径
|
||||
- `actions.handleAction("poll")` 是处理渠道特定投票语义或额外投票参数的首选路径
|
||||
|
||||
现在,核心会在插件投票分发拒绝该动作之后,才回退到共享投票解析,因此由插件拥有的投票处理器可以接受渠道特定的投票字段,而不会先被通用投票解析器拦住。
|
||||
现在,核心会在插件投票分发拒绝该动作之后,才延迟执行共享投票解析,因此由插件拥有的投票处理器可以接受渠道特定的投票字段,而不会先被通用投票解析器拦住。
|
||||
|
||||
完整启动顺序请参见 [插件架构内部机制](/zh-CN/plugins/architecture-internals)。
|
||||
|
||||
## 能力所有权模型
|
||||
## 能力归属模型
|
||||
|
||||
OpenClaw 将原生插件视为**公司**或**功能**的所有权边界,而不是一堆彼此无关的集成的集合。
|
||||
OpenClaw 将原生插件视为某个**公司**或某个**功能**的归属边界,而不是一堆互不相关集成的杂物袋。
|
||||
|
||||
这意味着:
|
||||
|
||||
- 一个公司插件通常应拥有该公司的所有面向 OpenClaw 的接口
|
||||
- 一个功能插件通常应拥有它引入的完整功能接口
|
||||
- 公司插件通常应拥有该公司面向 OpenClaw 的所有表面
|
||||
- 功能插件通常应拥有它所引入的完整功能表面
|
||||
- 渠道应消费共享的核心能力,而不是临时重新实现提供商行为
|
||||
|
||||
<Accordion title="内置插件中的所有权模式示例">
|
||||
- **供应商多能力**:`openai` 拥有文本推理、语音、实时语音、媒体理解和图像生成。`google` 拥有文本推理以及媒体理解、图像生成和网页搜索。`qwen` 拥有文本推理以及媒体理解和视频生成。
|
||||
- **供应商单能力**:`elevenlabs` 和 `microsoft` 拥有语音;`firecrawl` 拥有网页抓取;`minimax` / `mistral` / `moonshot` / `zai` 拥有媒体理解后端。
|
||||
- **功能插件**:`voice-call` 拥有通话传输、工具、CLI、路由和 Twilio 媒体流桥接,但它消费共享的语音、实时转录和实时语音能力,而不是直接导入供应商插件。
|
||||
<Accordion title="内置插件中的归属模式示例">
|
||||
- **厂商多能力**:`openai` 拥有文本推理、语音、实时语音、媒体理解和图像生成。`google` 拥有文本推理,以及媒体理解、图像生成和 Web 搜索。`qwen` 拥有文本推理,以及媒体理解和视频生成。
|
||||
- **厂商单能力**:`elevenlabs` 和 `microsoft` 拥有语音;`firecrawl` 拥有 Web 抓取;`minimax` / `mistral` / `moonshot` / `zai` 拥有媒体理解后端。
|
||||
- **功能插件**:`voice-call` 拥有通话传输、工具、CLI、路由和 Twilio 媒体流桥接,但它消费共享的语音、实时转录和实时语音能力,而不是直接导入厂商插件。
|
||||
</Accordion>
|
||||
|
||||
预期的最终状态是:
|
||||
|
||||
- 即使 OpenAI 横跨文本模型、语音、图像和未来的视频,也应存在于一个插件中
|
||||
- 其他供应商也可以对自己的接口范围采用相同方式
|
||||
- 渠道不关心哪个供应商插件拥有该提供商;它们只消费核心暴露的共享能力契约
|
||||
- OpenAI 位于一个插件中,即使它横跨文本模型、语音、图像以及未来的视频
|
||||
- 其他厂商也可以对自己的表面区域采用同样方式
|
||||
- 渠道不关心哪个厂商插件拥有提供商;它们消费的是由核心暴露的共享能力契约
|
||||
|
||||
这是关键区别:
|
||||
|
||||
- **plugin** = 所有权边界
|
||||
- **capability** = 可由多个插件实现或消费的核心契约
|
||||
- **plugin** = 归属边界
|
||||
- **capability** = 多个插件都可实现或消费的核心契约
|
||||
|
||||
因此,如果 OpenClaw 添加了一个新领域,例如视频,第一个问题不应该是“哪个提供商应该硬编码视频处理?”第一个问题应该是“核心的视频能力契约是什么?”一旦该契约存在,供应商插件就可以针对它进行注册,而渠道 / 功能插件也可以消费它。
|
||||
因此,如果 OpenClaw 新增一个诸如视频这样的领域,第一个问题不应是“哪个提供商应该硬编码视频处理?”第一个问题应是“核心的视频能力契约是什么?”一旦这个契约存在,厂商插件就可以针对它进行注册,而渠道 / 功能插件也可以消费它。
|
||||
|
||||
如果该能力尚不存在,通常正确的做法是:
|
||||
|
||||
1. 在核心中定义缺失的能力
|
||||
2. 通过插件 API / 运行时以类型化方式将其暴露出来
|
||||
3. 让渠道 / 功能对接该能力
|
||||
4. 让供应商插件注册实现
|
||||
3. 让渠道 / 功能围绕该能力进行接线
|
||||
4. 让厂商插件注册实现
|
||||
|
||||
这样既能保持所有权明确,又能避免核心行为依赖于某个单一供应商或某条一次性的插件特定代码路径。
|
||||
这样既能保持归属明确,也能避免核心行为依赖某个单一厂商或某条一次性的插件特定代码路径。
|
||||
|
||||
### 能力分层
|
||||
|
||||
在决定代码归属位置时,可使用以下心智模型:
|
||||
在判断代码应放在哪里时,请使用以下心智模型:
|
||||
|
||||
- **核心能力层**:共享编排、策略、回退、配置合并规则、交付语义和类型化契约
|
||||
- **供应商插件层**:供应商特定 API、认证、模型目录、语音合成、图像生成、未来的视频后端、用量端点
|
||||
- **渠道 / 功能插件层**:Slack / Discord / voice-call / 等集成,它们消费核心能力并将其呈现在某个界面上
|
||||
- **厂商插件层**:厂商特定 API、认证、模型目录、语音合成、图像生成、未来的视频后端、用量端点
|
||||
- **渠道 / 功能插件层**:Slack / Discord / voice-call / 等集成,它们消费核心能力并将其呈现在某个表面上
|
||||
|
||||
例如,TTS 遵循以下结构:
|
||||
例如,TTS 遵循这种形态:
|
||||
|
||||
- 核心拥有回复时 TTS 策略、回退顺序、偏好设置和渠道交付
|
||||
- 核心拥有回复时 TTS 策略、回退顺序、偏好和渠道交付
|
||||
- `openai`、`elevenlabs` 和 `microsoft` 拥有合成实现
|
||||
- `voice-call` 消费电话 TTS 运行时辅助工具
|
||||
|
||||
未来能力也应优先采用同样的模式。
|
||||
对于未来的能力,也应优先采用相同模式。
|
||||
|
||||
### 多能力公司插件示例
|
||||
|
||||
从外部看,一个公司插件应当具有一致性。如果 OpenClaw 具有用于模型、语音、实时转录、实时语音、媒体理解、图像生成、视频生成、网页抓取和网页搜索的共享契约,那么某个供应商可以在一个地方拥有其全部接口:
|
||||
一个公司插件从外部看应该是连贯的。如果 OpenClaw 对模型、语音、实时转录、实时语音、媒体理解、图像生成、视频生成、Web 抓取和 Web 搜索都有共享契约,那么某个厂商可以在一个地方拥有其所有表面:
|
||||
|
||||
```ts
|
||||
import type { OpenClawPluginDefinition } from "openclaw/plugin-sdk/plugin-entry";
|
||||
@ -300,116 +301,109 @@ const plugin: OpenClawPluginDefinition = {
|
||||
export default plugin;
|
||||
```
|
||||
|
||||
重要的不是确切的辅助函数名称,而是这种结构:
|
||||
重要的不是确切的辅助工具名称,而是这种形态:
|
||||
|
||||
- 一个插件拥有该供应商接口
|
||||
- 一个插件拥有厂商表面
|
||||
- 核心仍然拥有能力契约
|
||||
- 渠道和功能插件消费 `api.runtime.*` 辅助工具,而不是供应商代码
|
||||
- 契约测试可以断言该插件注册了它声称拥有的能力
|
||||
- 渠道和功能插件消费 `api.runtime.*` 辅助工具,而不是厂商代码
|
||||
- 契约测试可以断言该插件确实注册了它声称拥有的能力
|
||||
|
||||
### 能力示例:视频理解
|
||||
|
||||
OpenClaw 已经将图像 / 音频 / 视频理解视为一种共享能力。相同的所有权模型也适用于这里:
|
||||
OpenClaw 已经将图像 / 音频 / 视频理解视为一种共享能力。同样的归属模型也适用于这里:
|
||||
|
||||
1. 核心定义媒体理解契约
|
||||
2. 供应商插件根据适用情况注册 `describeImage`、`transcribeAudio` 和 `describeVideo`
|
||||
3. 渠道和功能插件消费共享的核心行为,而不是直接对接供应商代码
|
||||
2. 厂商插件按需注册 `describeImage`、`transcribeAudio` 和 `describeVideo`
|
||||
3. 渠道和功能插件消费共享的核心行为,而不是直接接到厂商代码上
|
||||
|
||||
这样可以避免把某个提供商的视频假设固化到核心中。插件拥有供应商接口;核心拥有能力契约和回退行为。
|
||||
这样可以避免把某个提供商对视频的假设烘焙进核心。插件拥有厂商表面;核心拥有能力契约和回退行为。
|
||||
|
||||
视频生成已经采用了同样的顺序:核心拥有类型化能力契约和运行时辅助工具,而供应商插件通过 `api.registerVideoGenerationProvider(...)` 针对它注册实现。
|
||||
视频生成已经采用了同样的顺序:核心拥有类型化的能力契约和运行时辅助工具,而厂商插件则针对它注册 `api.registerVideoGenerationProvider(...)` 实现。
|
||||
|
||||
需要一个具体的发布检查清单吗?请参见
|
||||
[能力扩展手册](/zh-CN/plugins/architecture)。
|
||||
需要具体的上线检查清单?请参见 [能力扩展手册](/zh-CN/plugins/architecture)。
|
||||
|
||||
## 契约与强制执行
|
||||
|
||||
插件 API 接口被有意设计为类型化,并集中在
|
||||
`OpenClawPluginApi` 中。这个契约定义了受支持的注册点,以及插件可依赖的运行时辅助工具。
|
||||
插件 API 表面有意通过 `OpenClawPluginApi` 进行类型化并集中管理。该契约定义了受支持的注册点,以及插件可以依赖的运行时辅助工具。
|
||||
|
||||
这很重要,因为:
|
||||
|
||||
- 插件作者可以获得一个稳定的内部标准
|
||||
- 核心可以拒绝重复所有权,例如两个插件注册同一个 provider id
|
||||
- 启动过程可以为格式错误的注册暴露可操作的诊断信息
|
||||
- 契约测试可以强制执行内置插件的所有权,并防止无声漂移
|
||||
- 核心可以拒绝重复归属,例如两个插件注册同一个 provider id
|
||||
- 启动阶段可以为格式错误的注册提供可执行的诊断信息
|
||||
- 契约测试可以强制约束内置插件的归属并防止静默漂移
|
||||
|
||||
这里有两层强制执行:
|
||||
|
||||
1. **运行时注册强制执行**
|
||||
插件注册表会在插件加载时验证注册内容。例如:重复的 provider id、重复的语音提供商 id,以及格式错误的注册,都会产生插件诊断,而不是导致未定义行为。
|
||||
2. **契约测试**
|
||||
内置插件会在测试运行期间被记录到契约注册表中,因此 OpenClaw 可以显式断言所有权。如今,这已被用于模型提供商、语音提供商、网页搜索提供商以及内置注册所有权。
|
||||
在测试运行期间,内置插件会被捕获到契约注册表中,以便 OpenClaw 可以显式断言归属。目前这用于模型提供商、语音提供商、Web 搜索提供商以及内置注册归属。
|
||||
|
||||
实际效果是,OpenClaw 可以预先知道哪个插件拥有哪个接口。这使得核心和渠道可以无缝组合,因为所有权是声明式、类型化且可测试的,而不是隐式的。
|
||||
实际效果是,OpenClaw 可以预先知道哪个插件拥有哪个表面。这让核心和渠道能够无缝组合,因为归属是被声明、被类型化并且可测试的,而不是隐式的。
|
||||
|
||||
### 什么内容应属于契约
|
||||
### 什么应该属于契约
|
||||
|
||||
好的插件契约应当是:
|
||||
良好的插件契约应当是:
|
||||
|
||||
- 类型化的
|
||||
- 小而精的
|
||||
- 能力特定的
|
||||
- 由核心拥有的
|
||||
- 特定于能力的
|
||||
- 由核心拥有
|
||||
- 可被多个插件复用
|
||||
- 可被渠道 / 功能消费,而无需了解供应商细节
|
||||
- 可被渠道 / 功能消费,而无需厂商知识
|
||||
|
||||
不好的插件契约包括:
|
||||
不良的插件契约则是:
|
||||
|
||||
- 隐藏在核心中的供应商特定策略
|
||||
- 隐藏在核心中的厂商特定策略
|
||||
- 绕过注册表的一次性插件逃生口
|
||||
- 直接深入供应商实现的渠道代码
|
||||
- 不属于 `OpenClawPluginApi` 或
|
||||
`api.runtime` 的临时运行时对象
|
||||
- 直接深入某个厂商实现的渠道代码
|
||||
- 不属于 `OpenClawPluginApi` 或 `api.runtime` 的临时运行时对象
|
||||
|
||||
如果有疑问,请提升抽象层级:先定义能力,再让插件接入它。
|
||||
如果拿不准,请提升抽象层级:先定义能力,再让插件接入它。
|
||||
|
||||
## 执行模型
|
||||
|
||||
原生 OpenClaw 插件会与 Gateway 网关**在同一进程内**运行。它们不是沙箱隔离的。已加载的原生插件与核心代码具有相同的进程级信任边界。
|
||||
原生 OpenClaw 插件与 Gateway 网关**在同一进程内**运行。它们没有经过沙箱隔离。一个已加载的原生插件与核心代码处于同样的进程级信任边界内。
|
||||
|
||||
这意味着:
|
||||
其含义是:
|
||||
|
||||
- 原生插件可以注册工具、网络处理器、钩子和服务
|
||||
- 原生插件中的 bug 可能导致 Gateway 网关崩溃或不稳定
|
||||
- 原生插件中的 bug 可能导致 gateway 崩溃或不稳定
|
||||
- 恶意原生插件等同于在 OpenClaw 进程内执行任意代码
|
||||
|
||||
兼容的 bundle 默认更安全,因为 OpenClaw 目前将其视为元数据 / 内容包。在当前版本中,这主要意味着内置 Skills。
|
||||
兼容 bundle 默认更安全,因为 OpenClaw 当前将它们视为元数据 / 内容包。在当前版本中,这主要意味着内置 Skills。
|
||||
|
||||
对于非内置插件,请使用 allowlist 和显式的安装 / 加载路径。应将工作区插件视为开发阶段代码,而不是生产默认值。
|
||||
对于非内置插件,请使用 allowlist 和显式的安装 / 加载路径。应将工作区插件视为开发期代码,而不是生产默认值。
|
||||
|
||||
对于内置工作区包名,应让插件 id 默认锚定在 npm 名称中:默认使用 `@openclaw/<id>`,或者在包有意暴露更窄插件角色时,使用经批准的类型化后缀,例如
|
||||
`-provider`、`-plugin`、`-speech`、`-sandbox` 或 `-media-understanding`。
|
||||
对于内置工作区包名,请让插件 id 锚定在 npm 名称中:默认使用 `@openclaw/<id>`,或者在包有意暴露更窄的插件角色时,使用经批准的类型化后缀,例如 `-provider`、`-plugin`、`-speech`、`-sandbox` 或 `-media-understanding`。
|
||||
|
||||
重要的信任说明:
|
||||
重要信任说明:
|
||||
|
||||
- `plugins.allow` 信任的是**插件 id**,而不是来源出处。
|
||||
- 与内置插件具有相同 id 的工作区插件,在被启用 / 加入 allowlist 时,会有意覆盖内置副本。
|
||||
- 这对于本地开发、补丁测试和热修复来说是正常且有用的。
|
||||
- 内置插件的信任是根据源快照来解析的——即加载时磁盘上的清单和代码——而不是根据安装元数据。损坏或被替换的安装记录不能在实际源码声明范围之外,悄悄扩大内置插件的信任接口。
|
||||
- 与内置插件具有相同 id 的工作区插件,在该工作区插件被启用 / 加入 allowlist 时,会有意遮蔽内置副本。
|
||||
- 这很正常,也很有用,适用于本地开发、补丁测试和热修复。
|
||||
- 内置插件信任是根据源码快照解析的 —— 即加载时磁盘上的清单文件和代码 —— 而不是基于安装元数据。损坏或被替换的安装记录不能在实际源码声明之外,悄悄扩大某个内置插件的信任表面。
|
||||
|
||||
## 导出边界
|
||||
|
||||
OpenClaw 导出的是能力,而不是实现便利性。
|
||||
OpenClaw 导出的是能力,而不是实现层面的便捷工具。
|
||||
|
||||
应保持能力注册公开。应精简非契约辅助导出:
|
||||
请保持能力注册为公开接口,并收缩那些不属于契约的辅助导出:
|
||||
|
||||
- 内置插件特定的辅助子路径
|
||||
- 无意作为公共 API 的运行时管线子路径
|
||||
- 供应商特定的便捷辅助工具
|
||||
- 属于实现细节的设置 / 新手引导辅助工具
|
||||
- 不打算作为公开 API 的运行时接线子路径
|
||||
- 厂商特定的便捷辅助工具
|
||||
- 属于实现细节的 setup / onboarding 辅助工具
|
||||
|
||||
出于兼容性和内置插件维护需求,一些内置插件辅助子路径仍然保留在生成的 SDK 导出映射中。当前示例包括
|
||||
`plugin-sdk/feishu`、`plugin-sdk/feishu-setup`、`plugin-sdk/zalo`、
|
||||
`plugin-sdk/zalo-setup` 以及若干 `plugin-sdk/matrix*` 接缝。应将它们视为保留的实现细节导出,而不是推荐给新的第三方插件使用的 SDK 模式。
|
||||
某些内置插件辅助子路径仍然保留在生成的 SDK 导出映射中,以兼容现有用法并便于维护内置插件。当前示例包括 `plugin-sdk/feishu`、`plugin-sdk/feishu-setup`、`plugin-sdk/zalo`、`plugin-sdk/zalo-setup` 以及若干 `plugin-sdk/matrix*` 接缝。应将这些视为保留的实现细节导出,而不是新第三方插件推荐采用的 SDK 模式。
|
||||
|
||||
## 内部机制与参考
|
||||
|
||||
有关加载流程、注册表模型、提供商运行时钩子、Gateway 网关 HTTP 路由、消息工具 schema、渠道目标解析、提供商目录、上下文引擎插件,以及新增能力的指南,请参见
|
||||
[插件架构内部机制](/zh-CN/plugins/architecture-internals)。
|
||||
有关加载管线、注册表模型、提供商运行时钩子、Gateway 网关 HTTP 路由、message 工具 schema、渠道目标解析、提供商目录、上下文引擎插件,以及新增能力的指南,请参见 [插件架构内部机制](/zh-CN/plugins/architecture-internals)。
|
||||
|
||||
## 相关内容
|
||||
|
||||
- [构建插件](/zh-CN/plugins/building-plugins)
|
||||
- [插件 SDK 设置](/zh-CN/plugins/sdk-setup)
|
||||
- [插件清单](/zh-CN/plugins/manifest)
|
||||
- [插件清单文件](/zh-CN/plugins/manifest)
|
||||
|
||||
@ -1,41 +1,42 @@
|
||||
---
|
||||
read_when:
|
||||
- 你希望一个 OpenClaw 智能体加入一个 Google Meet 通话
|
||||
- 你希望一个 OpenClaw 智能体创建一个新的 Google Meet 通话
|
||||
- 你想让一个 OpenClaw 智能体加入一个 Google Meet 通话
|
||||
- 你想让一个 OpenClaw 智能体创建一个新的 Google Meet 通话
|
||||
- 你正在将 Chrome、Chrome 节点或 Twilio 配置为 Google Meet 传输方式
|
||||
summary: Google Meet 插件:通过 Chrome 或 Twilio 加入显式的 Meet URL,并使用默认的实时语音设置
|
||||
summary: Google Meet 插件:通过 Chrome 或 Twilio 加入明确指定的 Meet URL,并使用实时语音默认设置
|
||||
title: Google Meet 插件
|
||||
x-i18n:
|
||||
generated_at: "2026-04-25T01:27:31Z"
|
||||
generated_at: "2026-04-25T02:35:36Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: 61ba617e92bc1e5791844adb2c77455577af55970143b39b38f1cc5bd1038a3a
|
||||
source_hash: 5e8655573953d39792f705dffa692345b88edaa38275468601b304e042e17cdd
|
||||
source_path: plugins/google-meet.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
OpenClaw 的 Google Meet 参会支持 —— 该插件在设计上是显式的:
|
||||
OpenClaw 的 Google Meet 参与支持——该插件在设计上是显式的:
|
||||
|
||||
- 它只会加入显式的 `https://meet.google.com/...` URL。
|
||||
- 它只会加入一个明确指定的 `https://meet.google.com/...` URL。
|
||||
- 它可以通过 Google Meet API 创建一个新的 Meet 空间,然后加入返回的 URL。
|
||||
- `realtime` 语音是默认模式。
|
||||
- 当需要更深入的推理或工具时,实时语音可以回调到完整的 OpenClaw 智能体。
|
||||
- 智能体通过 `mode` 选择加入行为:使用 `realtime` 进行实时收听/回话,或使用 `transcribe` 在不启用实时语音桥接的情况下加入/控制浏览器。
|
||||
- 认证起点可以是个人 Google OAuth,或一个已经登录的 Chrome 配置文件。
|
||||
- 认证从个人 Google OAuth 或已登录的 Chrome 配置文件开始。
|
||||
- 不会自动播报同意声明。
|
||||
- 默认的 Chrome 音频后端是 `BlackHole 2ch`。
|
||||
- Chrome 可以在本地运行,也可以在已配对的节点主机上运行。
|
||||
- Twilio 接受拨入号码,以及可选的 PIN 或 DTMF 序列。
|
||||
- CLI 命令是 `googlemeet`;`meet` 保留给更广泛的智能体电话会议工作流使用。
|
||||
- CLI 命令是 `googlemeet`;`meet` 保留用于更广义的智能体电话会议工作流。
|
||||
|
||||
## 快速开始
|
||||
|
||||
安装本地音频依赖并配置一个后端实时语音提供商。默认使用 OpenAI;Google Gemini Live 也可与 `realtime.provider: "google"` 搭配使用:
|
||||
安装本地音频依赖并配置一个后端实时语音提供商。OpenAI 是默认选项;Google Gemini Live 也可用,配合
|
||||
`realtime.provider: "google"`:
|
||||
|
||||
```bash
|
||||
brew install blackhole-2ch sox
|
||||
export OPENAI_API_KEY=sk-...
|
||||
# 或者
|
||||
# or
|
||||
export GEMINI_API_KEY=...
|
||||
```
|
||||
|
||||
@ -73,7 +74,9 @@ command -v rec play
|
||||
openclaw googlemeet setup
|
||||
```
|
||||
|
||||
设置输出旨在便于智能体读取。它会报告 Chrome 配置文件、音频桥接、节点固定、延迟实时介绍,以及在配置了 Twilio 委派时,`voice-call` 插件和 Twilio 凭证是否已就绪。将任何 `ok: false` 检查都视为阻塞项,在要求智能体加入之前先解决。对脚本或机器可读输出,请使用 `openclaw googlemeet setup --json`。
|
||||
设置输出旨在让智能体可读。它会报告 Chrome 配置文件、音频桥接、节点固定、延迟的实时介绍,以及在配置了 Twilio 委托时,`voice-call` 插件和 Twilio 凭证是否就绪。
|
||||
在要求智能体加入之前,将任何 `ok: false` 的检查都视为阻塞项。
|
||||
对于脚本或机器可读输出,请使用 `openclaw googlemeet setup --json`。
|
||||
|
||||
加入会议:
|
||||
|
||||
@ -98,7 +101,7 @@ openclaw googlemeet join https://meet.google.com/abc-defg-hij
|
||||
openclaw googlemeet create --transport chrome-node --mode realtime
|
||||
```
|
||||
|
||||
只创建 URL 而不加入:
|
||||
仅创建 URL 而不加入:
|
||||
|
||||
```bash
|
||||
openclaw googlemeet create --no-join
|
||||
@ -106,12 +109,17 @@ openclaw googlemeet create --no-join
|
||||
|
||||
`googlemeet create` 有两条路径:
|
||||
|
||||
- API 创建:当配置了 Google Meet OAuth 凭证时使用。这是最确定性的路径,不依赖浏览器 UI 状态。
|
||||
- 浏览器回退:当缺少 OAuth 凭证时使用。OpenClaw 会使用固定的 Chrome 节点,打开 `https://meet.google.com/new`,等待 Google 重定向到真实的会议代码 URL,然后返回该 URL。这条路径要求节点上的 OpenClaw Chrome 配置文件已经登录 Google。浏览器自动化会处理 Meet 自身的首次运行麦克风提示;该提示不会被视为 Google 登录失败。
|
||||
- API 创建:当配置了 Google Meet OAuth 凭证时使用。这是最确定的路径,不依赖浏览器 UI 状态。
|
||||
- 浏览器回退:当缺少 OAuth 凭证时使用。OpenClaw 会使用固定的 Chrome 节点,打开 `https://meet.google.com/new`,等待 Google 重定向到真实的会议代码 URL,然后返回该 URL。此路径要求节点上的 OpenClaw Chrome 配置文件已经登录 Google。
|
||||
浏览器自动化会处理 Meet 自己的首次运行麦克风提示;该提示不会被视为 Google 登录失败。
|
||||
加入和创建流程也会在打开新标签页之前尝试复用现有的 Meet 标签页。匹配会忽略像 `authuser` 这样的无害 URL 查询字符串,因此智能体重试时应聚焦已经打开的会议,而不是创建第二个 Chrome 标签页。
|
||||
|
||||
命令/工具输出包含一个 `source` 字段(`api` 或 `browser`),这样智能体就可以说明使用了哪条路径。`create` 默认会加入新会议,并返回 `joined: true` 以及加入会话。若只想生成 URL,请在 CLI 上使用 `create --no-join`,或向工具传入 `"join": false`。
|
||||
命令/工具输出包含一个 `source` 字段(`api` 或 `browser`),这样智能体就可以说明使用了哪条路径。
|
||||
`create` 默认会加入新会议,并返回 `joined: true` 以及加入会话。若仅想生成 URL,请在 CLI 中使用
|
||||
`create --no-join`,或向工具传递 `"join": false`。
|
||||
|
||||
或者告诉智能体:“创建一个 Google Meet,用实时语音加入,并把链接发给我。” 智能体应调用 `google_meet`,并使用 `action: "create"`,然后分享返回的 `meetingUri`。
|
||||
或者告诉智能体:“创建一个 Google Meet,用实时语音加入,然后把链接发给我。”
|
||||
智能体应使用 `action: "create"` 调用 `google_meet`,然后分享返回的 `meetingUri`。
|
||||
|
||||
```json
|
||||
{
|
||||
@ -121,19 +129,26 @@ openclaw googlemeet create --no-join
|
||||
}
|
||||
```
|
||||
|
||||
如果只想观察/控制浏览器加入,请设置 `"mode": "transcribe"`。这不会启动双工实时模型桥接,因此它不会在会议中回话。
|
||||
对于仅观察/浏览器控制的加入,将 `"mode": "transcribe"`。
|
||||
这不会启动双工实时模型桥接,因此它不会在会议中进行回话。
|
||||
|
||||
Chrome 会以已登录的 Chrome 配置文件身份加入。在 Meet 中,选择 `BlackHole 2ch` 作为 OpenClaw 使用的麦克风/扬声器路径。若要获得干净的双工音频,请使用独立的虚拟设备或类似 Loopback 的音频图;单个 BlackHole 设备足以完成首次冒烟测试,但可能会产生回声。
|
||||
在实时会话期间,`google_meet` 状态包含浏览器和音频桥接的健康信息,例如 `inCall`、`manualActionRequired`、`providerConnected`、
|
||||
`realtimeReady`、`audioInputActive`、`audioOutputActive`、最近的输入/输出时间戳、字节计数以及桥接关闭状态。
|
||||
如果出现安全的 Meet 页面提示,浏览器自动化会在可能时处理它。登录、主持人准入以及浏览器/操作系统权限提示会作为手动操作报告,并附带原因和消息,供智能体转达。
|
||||
|
||||
Chrome 会以已登录的 Chrome 配置文件身份加入。在 Meet 中,选择 `BlackHole 2ch` 作为 OpenClaw 使用的麦克风/扬声器路径。
|
||||
为了获得干净的双工音频,请使用独立的虚拟设备或类似 Loopback 的音频图;单个 BlackHole 设备足以完成第一次冒烟测试,但可能会产生回声。
|
||||
|
||||
### 本地 Gateway 网关 + Parallels Chrome
|
||||
|
||||
你**不**需要在 macOS VM 里运行完整的 OpenClaw Gateway 网关或配置模型 API 密钥,才能让 VM 承担 Chrome。你可以在本地运行 Gateway 网关和智能体,然后在 VM 中运行一个节点主机。只需在 VM 中启用一次内置插件,这样节点就会声明 Chrome 命令:
|
||||
你**不**需要在 macOS VM 中运行完整的 OpenClaw Gateway 网关或配置模型 API 密钥,只是为了让 VM 承载 Chrome。
|
||||
在本地运行 Gateway 网关和智能体,然后在 VM 中运行一个节点主机。在 VM 中启用一次内置插件,这样节点就会通告 Chrome 命令:
|
||||
|
||||
各组件运行位置:
|
||||
各部分的运行位置:
|
||||
|
||||
- Gateway 网关主机:OpenClaw Gateway 网关、智能体工作区、模型/API 密钥、实时提供商,以及 Google Meet 插件配置。
|
||||
- Parallels macOS VM:OpenClaw CLI/节点主机、Google Chrome、SoX、BlackHole 2ch,以及一个已登录 Google 的 Chrome 配置文件。
|
||||
- VM 中不需要:Gateway 网关服务、智能体配置、OpenAI/GPT 密钥或模型提供商设置。
|
||||
- VM 中不需要:Gateway 网关服务、智能体配置、OpenAI/GPT 密钥,或模型提供商设置。
|
||||
|
||||
安装 VM 依赖:
|
||||
|
||||
@ -147,14 +162,14 @@ brew install blackhole-2ch sox
|
||||
sudo reboot
|
||||
```
|
||||
|
||||
重启后,验证 VM 能看到该音频设备以及 SoX 命令:
|
||||
重启后,验证 VM 能看到音频设备和 SoX 命令:
|
||||
|
||||
```bash
|
||||
system_profiler SPAudioDataType | grep -i BlackHole
|
||||
command -v rec play
|
||||
```
|
||||
|
||||
在 VM 中安装或更新 OpenClaw,然后在其中启用内置插件:
|
||||
在 VM 中安装或更新 OpenClaw,然后在那里启用内置插件:
|
||||
|
||||
```bash
|
||||
openclaw plugins enable google-meet
|
||||
@ -166,14 +181,14 @@ openclaw plugins enable google-meet
|
||||
openclaw node run --host <gateway-host> --port 18789 --display-name parallels-macos
|
||||
```
|
||||
|
||||
如果 `<gateway-host>` 是局域网 IP,且你没有使用 TLS,那么除非你为该受信任私有网络显式启用明文 WebSocket,否则节点会拒绝连接:
|
||||
如果 `<gateway-host>` 是 LAN IP 且你未使用 TLS,除非你为该受信任私有网络显式启用,否则节点会拒绝该明文 WebSocket:
|
||||
|
||||
```bash
|
||||
OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1 \
|
||||
openclaw node run --host <gateway-lan-ip> --port 18789 --display-name parallels-macos
|
||||
```
|
||||
|
||||
将节点安装为 LaunchAgent 时,也使用相同的环境变量:
|
||||
将节点安装为 LaunchAgent 时,也要使用同一个环境变量:
|
||||
|
||||
```bash
|
||||
OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1 \
|
||||
@ -181,7 +196,8 @@ OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1 \
|
||||
openclaw node restart
|
||||
```
|
||||
|
||||
`OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1` 是进程环境,而不是 `openclaw.json` 设置。`openclaw node install` 会在安装命令中检测到它存在时,将其存储到 LaunchAgent 环境中。
|
||||
`OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1` 是进程环境,不是
|
||||
`openclaw.json` 设置项。`openclaw node install` 会在安装命令中检测到它时,将其存储到 LaunchAgent 环境中。
|
||||
|
||||
从 Gateway 网关主机批准该节点:
|
||||
|
||||
@ -190,7 +206,8 @@ openclaw devices list
|
||||
openclaw devices approve <requestId>
|
||||
```
|
||||
|
||||
确认 Gateway 网关能看到该节点,并且它同时声明了 `googlemeet.chrome` 和浏览器能力/`browser.proxy`:
|
||||
确认 Gateway 网关看到了该节点,并且它同时通告了 `googlemeet.chrome`
|
||||
和浏览器能力/`browser.proxy`:
|
||||
|
||||
```bash
|
||||
openclaw nodes status
|
||||
@ -226,61 +243,82 @@ openclaw nodes status
|
||||
}
|
||||
```
|
||||
|
||||
现在可以像平常一样从 Gateway 网关主机加入:
|
||||
现在可从 Gateway 网关主机正常加入:
|
||||
|
||||
```bash
|
||||
openclaw googlemeet join https://meet.google.com/abc-defg-hij
|
||||
```
|
||||
|
||||
或者要求智能体使用 `google_meet` 工具,并设置 `transport: "chrome-node"`。
|
||||
或者让智能体使用 `google_meet` 工具,并设置 `transport: "chrome-node"`。
|
||||
|
||||
如果你想执行一个单命令冒烟测试,用来创建或复用会话、说出一段已知短语并打印会话健康状态:
|
||||
如果你想执行一个单命令冒烟测试,用于创建或复用一个会话、说出一段已知短语并打印会话健康状态:
|
||||
|
||||
```bash
|
||||
openclaw googlemeet test-speech https://meet.google.com/abc-defg-hij
|
||||
```
|
||||
|
||||
在加入过程中,OpenClaw 浏览器自动化会填写访客名称、点击加入/请求加入,并在出现该提示时接受 Meet 首次运行时的“使用麦克风”选项。在仅浏览器创建会议期间,如果 Meet 没有暴露使用麦克风按钮,它也可以绕过相同的提示继续而不使用麦克风。如果浏览器配置文件未登录、Meet 正在等待主持人批准、Chrome 需要麦克风/摄像头权限,或者 Meet 卡在某个自动化无法解决的提示上,那么 join/test-speech 结果会报告 `manualActionRequired: true`,并附带 `manualActionReason` 和 `manualActionMessage`。智能体应停止重试加入,报告这条精确消息以及当前的 `browserUrl`/`browserTitle`,并且只在手动浏览器操作完成后再重试。
|
||||
在加入过程中,OpenClaw 浏览器自动化会填写访客名称,点击“加入/请求加入”,并在出现该提示时接受 Meet 首次运行的“使用麦克风”选项。
|
||||
在仅通过浏览器创建会议时,如果 Meet 没有提供使用麦克风按钮,它也可以在不使用麦克风的情况下继续通过同一提示。
|
||||
如果浏览器配置文件未登录、Meet 正在等待主持人准入、Chrome 需要麦克风/摄像头权限,或者 Meet 卡在自动化无法解决的提示上,加入/`test-speech` 结果会报告
|
||||
`manualActionRequired: true`,并附带 `manualActionReason` 和
|
||||
`manualActionMessage`。智能体应停止重试加入,报告该确切消息以及当前的
|
||||
`browserUrl`/`browserTitle`,并且只在手动浏览器操作完成后重试。
|
||||
|
||||
如果省略了 `chromeNode.node`,只有在恰好有一个已连接节点同时声明了 `googlemeet.chrome` 和浏览器控制时,OpenClaw 才会自动选择它。如果连接了多个具备该能力的节点,请将 `chromeNode.node` 设置为节点 id、显示名称或远程 IP。
|
||||
如果省略了 `chromeNode.node`,只有在恰好有一个已连接节点同时通告 `googlemeet.chrome` 和浏览器控制能力时,OpenClaw 才会自动选择。
|
||||
如果连接了多个具备能力的节点,请将 `chromeNode.node` 设置为节点 id、显示名称或远程 IP。
|
||||
|
||||
常见故障检查:
|
||||
|
||||
- `No connected Google Meet-capable node`:在 VM 中启动 `openclaw node run`,批准配对,并确保已在 VM 中运行 `openclaw plugins enable google-meet` 和 `openclaw plugins enable browser`。还要确认 Gateway 网关主机允许这两个节点命令,即设置 `gateway.nodes.allowCommands: ["googlemeet.chrome", "browser.proxy"]`。
|
||||
- `BlackHole 2ch audio device not found on the node`:在 VM 中安装 `blackhole-2ch` 并重启 VM。
|
||||
- Chrome 打开但无法加入:在 VM 中登录浏览器配置文件,或保持设置 `chrome.guestName` 以进行访客加入。访客自动加入使用 OpenClaw 通过节点浏览器代理执行的浏览器自动化;请确保节点浏览器配置指向你想使用的配置文件,例如 `browser.defaultProfile: "user"` 或某个已存在会话的命名配置文件。
|
||||
- 重复的 Meet 标签页:保持启用 `chrome.reuseExistingTab: true`。在打开新标签页之前,OpenClaw 会先为相同的 Meet URL 激活一个现有标签页,并且浏览器会议创建会在打开新的标签页之前复用一个进行中的 `https://meet.google.com/new` 或 Google 账号提示标签页。
|
||||
- 没有音频:在 Meet 中,将麦克风/扬声器通过 OpenClaw 使用的虚拟音频设备路径进行路由;使用独立的虚拟设备或类似 Loopback 的路由方式可获得更干净的双工音频。
|
||||
- `No connected Google Meet-capable node`:在 VM 中启动 `openclaw node run`,
|
||||
批准配对,并确保在 VM 中运行了 `openclaw plugins enable google-meet` 和
|
||||
`openclaw plugins enable browser`。还要确认
|
||||
Gateway 网关主机通过
|
||||
`gateway.nodes.allowCommands: ["googlemeet.chrome", "browser.proxy"]` 允许这两个节点命令。
|
||||
- `BlackHole 2ch audio device not found on the node`:在 VM 中安装 `blackhole-2ch`
|
||||
并重启 VM。
|
||||
- Chrome 打开了但无法加入:在 VM 内的浏览器配置文件中登录,或者保持设置 `chrome.guestName` 以进行访客加入。访客自动加入使用的是 OpenClaw
|
||||
通过节点浏览器代理执行的浏览器自动化;请确保节点浏览器配置指向你想使用的配置文件,例如
|
||||
`browser.defaultProfile: "user"` 或一个命名的现有会话配置文件。
|
||||
- 重复的 Meet 标签页:保持启用 `chrome.reuseExistingTab: true`。OpenClaw
|
||||
会在打开新标签页之前激活同一 Meet URL 的现有标签页,而浏览器会议创建会在打开另一个标签页之前复用一个进行中的 `https://meet.google.com/new`
|
||||
或 Google 账号提示标签页。
|
||||
- 无音频:在 Meet 中,将麦克风/扬声器路由到 OpenClaw 使用的虚拟音频设备路径;使用独立的虚拟设备或类似 Loopback 的路由方式,以获得干净的双工音频。
|
||||
|
||||
## 安装说明
|
||||
|
||||
Chrome 实时默认设置会使用两个外部工具:
|
||||
Chrome 实时默认配置使用两个外部工具:
|
||||
|
||||
- `sox`:命令行音频工具。该插件使用它的 `rec` 和 `play` 命令来实现默认的 8 kHz G.711 mu-law 音频桥接。
|
||||
- `blackhole-2ch`:macOS 虚拟音频驱动。它会创建 `BlackHole 2ch` 音频设备,供 Chrome/Meet 路由使用。
|
||||
- `sox`:命令行音频工具。插件使用它的 `rec` 和 `play`
|
||||
命令作为默认 8 kHz G.711 mu-law 音频桥接。
|
||||
- `blackhole-2ch`:macOS 虚拟音频驱动。它会创建 `BlackHole 2ch`
|
||||
音频设备,供 Chrome/Meet 路由使用。
|
||||
|
||||
OpenClaw 不会内置或重新分发其中任何一个包。文档要求用户通过 Homebrew 将它们作为主机依赖安装。SoX 的许可证是 `LGPL-2.0-only AND GPL-2.0-only`;BlackHole 是 GPL-3.0。如果你要构建一个将 BlackHole 与 OpenClaw 一起打包的安装程序或一体机,请查阅 BlackHole 上游的许可条款,或从 Existential Audio 获取单独的许可证。
|
||||
OpenClaw 不捆绑也不重新分发这两个软件包。文档要求用户通过 Homebrew
|
||||
将它们作为主机依赖进行安装。SoX 的许可为
|
||||
`LGPL-2.0-only AND GPL-2.0-only`;BlackHole 为 GPL-3.0。如果你构建了一个将 BlackHole 与 OpenClaw 一起捆绑的安装程序或设备,请查看 BlackHole 上游许可条款,或从 Existential Audio 获取单独许可。
|
||||
|
||||
## 传输方式
|
||||
|
||||
### Chrome
|
||||
|
||||
Chrome 传输会在 Google Chrome 中打开 Meet URL,并以已登录的 Chrome 配置文件身份加入。在 macOS 上,插件会在启动前检查 `BlackHole 2ch`。如果进行了配置,它还会在打开 Chrome 之前运行音频桥接健康检查命令和启动命令。当 Chrome/音频运行在 Gateway 网关主机上时使用 `chrome`;当 Chrome/音频运行在已配对节点(例如 Parallels macOS VM)上时使用 `chrome-node`。
|
||||
Chrome 传输会在 Google Chrome 中打开 Meet URL,并以已登录的 Chrome 配置文件身份加入。在 macOS 上,插件会在启动前检查是否存在 `BlackHole 2ch`。
|
||||
如果已配置,它还会在打开 Chrome 之前运行一个音频桥健康检查命令和启动命令。当 Chrome/音频运行在 Gateway 网关主机上时使用 `chrome`;
|
||||
当 Chrome/音频 运行在已配对节点上(例如 Parallels macOS VM)时使用 `chrome-node`。
|
||||
|
||||
```bash
|
||||
openclaw googlemeet join https://meet.google.com/abc-defg-hij --transport chrome
|
||||
openclaw googlemeet join https://meet.google.com/abc-defg-hij --transport chrome-node
|
||||
```
|
||||
|
||||
将 Chrome 的麦克风和扬声器音频通过本地 OpenClaw 音频桥接进行路由。如果未安装 `BlackHole 2ch`,加入会以设置错误失败,而不是在没有音频路径的情况下静默加入。
|
||||
将 Chrome 的麦克风和扬声器音频通过本地 OpenClaw 音频桥接进行路由。如果未安装 `BlackHole 2ch`,加入会因设置错误而失败,而不是在没有音频路径的情况下静默加入。
|
||||
|
||||
### Twilio
|
||||
|
||||
Twilio 传输是一个严格的拨号计划,会委派给 Voice Call 插件。它不会从 Meet 页面解析电话号码。
|
||||
Twilio 传输是一种严格的拨号计划,并委托给 Voice Call 插件执行。它不会从 Meet 页面解析电话号码。
|
||||
|
||||
当无法使用 Chrome 参会,或者你希望使用电话拨入作为回退方案时,请使用此方式。Google Meet 必须为该会议提供电话拨入号码和 PIN;OpenClaw 不会从 Meet 页面中发现这些信息。
|
||||
当无法使用 Chrome 参与,或者你想要电话拨入作为回退方案时,请使用此方式。Google Meet 必须为会议提供电话拨入号码和 PIN;OpenClaw 不会从 Meet 页面中发现这些信息。
|
||||
|
||||
在 Gateway 网关主机上启用 Voice Call 插件,而不是在 Chrome 节点上启用:
|
||||
在 Gateway 网关主机上启用 Voice Call 插件,而不是在 Chrome 节点上:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -291,7 +329,7 @@ Twilio 传输是一个严格的拨号计划,会委派给 Voice Call 插件。
|
||||
enabled: true,
|
||||
config: {
|
||||
defaultTransport: "chrome-node",
|
||||
// 或者如果应将 Twilio 设为默认值,则设置为 "twilio"
|
||||
// or set "twilio" if Twilio should be the default
|
||||
},
|
||||
},
|
||||
"voice-call": {
|
||||
@ -305,7 +343,7 @@ Twilio 传输是一个严格的拨号计划,会委派给 Voice Call 插件。
|
||||
}
|
||||
```
|
||||
|
||||
通过环境或配置提供 Twilio 凭证。使用环境变量可以让密钥不进入 `openclaw.json`:
|
||||
通过环境变量或配置提供 Twilio 凭证。环境变量可以让密钥不出现在 `openclaw.json` 中:
|
||||
|
||||
```bash
|
||||
export TWILIO_ACCOUNT_SID=AC...
|
||||
@ -313,9 +351,9 @@ export TWILIO_AUTH_TOKEN=...
|
||||
export TWILIO_FROM_NUMBER=+15550001234
|
||||
```
|
||||
|
||||
启用 `voice-call` 后,重启或重新加载 Gateway 网关;在 Gateway 网关进程重新加载之前,插件配置更改不会出现在已运行的 Gateway 网关进程中。
|
||||
启用 `voice-call` 后,重启或重新加载 Gateway 网关;插件配置变更在 Gateway 网关进程重新加载之前,不会出现在已运行的进程中。
|
||||
|
||||
然后验证:
|
||||
然后进行验证:
|
||||
|
||||
```bash
|
||||
openclaw config validate
|
||||
@ -323,7 +361,8 @@ openclaw plugins list | grep -E 'google-meet|voice-call'
|
||||
openclaw googlemeet setup
|
||||
```
|
||||
|
||||
当 Twilio 委派已正确接线时,`googlemeet setup` 会包含成功的 `twilio-voice-call-plugin` 和 `twilio-voice-call-credentials` 检查。
|
||||
当 Twilio 委托配置完成后,`googlemeet setup` 会包含成功的
|
||||
`twilio-voice-call-plugin` 和 `twilio-voice-call-credentials` 检查。
|
||||
|
||||
```bash
|
||||
openclaw googlemeet join https://meet.google.com/abc-defg-hij \
|
||||
@ -343,21 +382,23 @@ openclaw googlemeet join https://meet.google.com/abc-defg-hij \
|
||||
|
||||
## OAuth 和预检
|
||||
|
||||
OAuth 对创建 Meet 链接来说是可选的,因为 `googlemeet create` 可以回退到浏览器自动化。当你希望使用官方 API 创建、空间解析或 Meet Media API 预检时,请配置 OAuth。
|
||||
对于创建 Meet 链接,OAuth 是可选的,因为 `googlemeet create` 可以回退到浏览器自动化。当你需要官方 API 创建、空间解析或 Meet Media API 预检时,请配置 OAuth。
|
||||
|
||||
Google Meet API 访问优先使用个人 OAuth 客户端。配置 `oauth.clientId`,并可选配置 `oauth.clientSecret`,然后运行:
|
||||
Google Meet API 访问优先使用个人 OAuth 客户端。配置
|
||||
`oauth.clientId`,并可选配置 `oauth.clientSecret`,然后运行:
|
||||
|
||||
```bash
|
||||
openclaw googlemeet auth login --json
|
||||
```
|
||||
|
||||
该命令会打印一个包含刷新令牌的 `oauth` 配置块。它使用 PKCE、位于 `http://localhost:8085/oauth2callback` 的 localhost 回调,以及通过 `--manual` 进行的手动复制/粘贴流程。
|
||||
该命令会打印一个包含刷新令牌的 `oauth` 配置块。它使用 PKCE、
|
||||
位于 `http://localhost:8085/oauth2callback` 的 localhost 回调,以及通过 `--manual` 进行的手动复制/粘贴流程。
|
||||
|
||||
OAuth 同意范围包括 Meet 空间创建、Meet 空间读取访问,以及 Meet 会议媒体读取访问。如果你在支持会议创建功能出现之前就已完成认证,请重新运行 `openclaw googlemeet auth login --json`,以便刷新令牌具备 `meetings.space.created` scope。
|
||||
OAuth 同意范围包括 Meet 空间创建、Meet 空间读取权限,以及 Meet 会议媒体读取权限。如果你是在支持会议创建之前完成认证的,请重新运行 `openclaw googlemeet auth login --json`,这样刷新令牌才会具有 `meetings.space.created` scope。
|
||||
|
||||
浏览器回退不需要 OAuth 凭证。在该模式下,Google 认证来自所选节点上已登录的 Chrome 配置文件,而不是 OpenClaw 配置。
|
||||
浏览器回退不需要 OAuth 凭证。在该模式下,Google 认证来自所选节点上已登录的 Chrome 配置文件,而不是来自 OpenClaw 配置。
|
||||
|
||||
接受以下环境变量作为回退值:
|
||||
以下环境变量可作为回退值使用:
|
||||
|
||||
- `OPENCLAW_GOOGLE_MEET_CLIENT_ID` 或 `GOOGLE_MEET_CLIENT_ID`
|
||||
- `OPENCLAW_GOOGLE_MEET_CLIENT_SECRET` 或 `GOOGLE_MEET_CLIENT_SECRET`
|
||||
@ -374,7 +415,7 @@ OAuth 同意范围包括 Meet 空间创建、Meet 空间读取访问,以及 Me
|
||||
openclaw googlemeet resolve-space --meeting https://meet.google.com/abc-defg-hij
|
||||
```
|
||||
|
||||
在进行媒体相关工作前运行预检:
|
||||
在进行媒体工作之前运行预检:
|
||||
|
||||
```bash
|
||||
openclaw googlemeet preflight --meeting https://meet.google.com/abc-defg-hij
|
||||
@ -386,9 +427,9 @@ openclaw googlemeet preflight --meeting https://meet.google.com/abc-defg-hij
|
||||
openclaw googlemeet create
|
||||
```
|
||||
|
||||
该命令会打印新的 `meeting uri`、source 和加入会话。有 OAuth 凭证时,它会使用官方 Google Meet API。没有 OAuth 凭证时,它会回退为使用固定 Chrome 节点中已登录的浏览器配置文件。智能体可以使用 `google_meet` 工具并设置 `action: "create"`,以一步完成创建并加入。如果只需创建 URL,请传入 `"join": false`。
|
||||
该命令会打印新的 `meeting uri`、来源以及加入会话。配置了 OAuth 凭证时,它会使用官方 Google Meet API。没有 OAuth 凭证时,它会使用固定的 Chrome 节点上已登录的浏览器配置文件作为回退。智能体可以使用带有 `action: "create"` 的 `google_meet` 工具一步完成创建和加入。若仅创建 URL,请传入 `"join": false`。
|
||||
|
||||
来自浏览器回退的 JSON 输出示例:
|
||||
浏览器回退的 JSON 输出示例:
|
||||
|
||||
```json
|
||||
{
|
||||
@ -408,7 +449,7 @@ openclaw googlemeet create
|
||||
}
|
||||
```
|
||||
|
||||
来自 API 创建的 JSON 输出示例:
|
||||
API 创建的 JSON 输出示例:
|
||||
|
||||
```json
|
||||
{
|
||||
@ -429,18 +470,19 @@ openclaw googlemeet create
|
||||
}
|
||||
```
|
||||
|
||||
创建 Meet 默认会加入会议。Chrome 或 chrome-node 传输仍然需要一个已登录 Google 的 Chrome 配置文件,才能通过浏览器加入。如果该配置文件已退出登录,OpenClaw 会报告 `manualActionRequired: true` 或浏览器回退错误,并要求操作员在重试之前完成 Google 登录。
|
||||
创建 Meet 默认会加入会议。Chrome 或 Chrome-node 传输仍然需要一个已登录 Google 的 Chrome 配置文件,才能通过浏览器加入。如果该配置文件已登出,OpenClaw 会报告 `manualActionRequired: true` 或浏览器回退错误,并要求操作员先完成 Google 登录再重试。
|
||||
|
||||
仅在确认你的 Cloud 项目、OAuth principal 和会议参与者已加入 Google Workspace Developer Preview Program for Meet media APIs 之后,才设置 `preview.enrollmentAcknowledged: true`。
|
||||
仅在确认你的 Cloud 项目、OAuth 主体以及会议参与者都已加入适用于 Meet 媒体 API 的 Google Workspace Developer Preview Program 后,才设置 `preview.enrollmentAcknowledged: true`。
|
||||
|
||||
## 配置
|
||||
|
||||
常见的 Chrome 实时路径只需要启用插件、BlackHole、SoX,以及一个后端实时语音提供商密钥。默认使用 OpenAI;设置 `realtime.provider: "google"` 可使用 Google Gemini Live:
|
||||
常见的 Chrome 实时路径只需要启用插件、BlackHole、SoX,以及一个后端实时语音提供商密钥。OpenAI 是默认选项;设置
|
||||
`realtime.provider: "google"` 可使用 Google Gemini Live:
|
||||
|
||||
```bash
|
||||
brew install blackhole-2ch sox
|
||||
export OPENAI_API_KEY=sk-...
|
||||
# 或者
|
||||
# or
|
||||
export GEMINI_API_KEY=...
|
||||
```
|
||||
|
||||
@ -465,16 +507,19 @@ export GEMINI_API_KEY=...
|
||||
- `defaultMode: "realtime"`
|
||||
- `chromeNode.node`:`chrome-node` 的可选节点 id/名称/IP
|
||||
- `chrome.audioBackend: "blackhole-2ch"`
|
||||
- `chrome.guestName: "OpenClaw Agent"`:在已退出登录的 Meet 访客界面上使用的名称
|
||||
- `chrome.autoJoin: true`:通过 OpenClaw 浏览器自动化在 `chrome-node` 上尽力完成访客名填写和点击立即加入
|
||||
- `chrome.guestName: "OpenClaw Agent"`:在已登出的 Meet 访客界面中使用的名称
|
||||
- `chrome.autoJoin: true`:通过 OpenClaw 浏览器自动化在 `chrome-node` 上尽力填写访客名称并点击立即加入
|
||||
- `chrome.reuseExistingTab: true`:激活现有 Meet 标签页,而不是打开重复标签页
|
||||
- `chrome.waitForInCallMs: 20000`:在触发实时介绍之前,等待 Meet 标签页报告已在通话中
|
||||
- `chrome.audioInputCommand`:将 8 kHz G.711 mu-law 音频写入 stdout 的 SoX `rec` 命令
|
||||
- `chrome.audioOutputCommand`:从 stdin 读取 8 kHz G.711 mu-law 音频的 SoX `play` 命令
|
||||
- `chrome.waitForInCallMs: 20000`:在触发实时介绍前,等待 Meet 标签页报告已在通话中
|
||||
- `chrome.audioInputCommand`:SoX `rec` 命令,将 8 kHz G.711 mu-law
|
||||
音频写入 stdout
|
||||
- `chrome.audioOutputCommand`:SoX `play` 命令,从 stdin 读取 8 kHz G.711 mu-law
|
||||
音频
|
||||
- `realtime.provider: "openai"`
|
||||
- `realtime.toolPolicy: "safe-read-only"`
|
||||
- `realtime.instructions`:简短的口头回复,较深入的回答使用 `openclaw_agent_consult`
|
||||
- `realtime.introMessage`:实时桥接连接时的简短口头就绪检查;将其设为 `""` 可静默加入
|
||||
- `realtime.instructions`:简短的口头回复,必要时使用
|
||||
`openclaw_agent_consult` 获取更深入答案
|
||||
- `realtime.introMessage`:当实时桥接连接时的简短口头就绪检查;将其设置为 `""` 可静默加入
|
||||
|
||||
可选覆盖项:
|
||||
|
||||
@ -494,7 +539,7 @@ export GEMINI_API_KEY=...
|
||||
realtime: {
|
||||
provider: "google",
|
||||
toolPolicy: "owner",
|
||||
introMessage: "准确说出:我到了。",
|
||||
introMessage: "Say exactly: I'm here.",
|
||||
providers: {
|
||||
google: {
|
||||
model: "gemini-2.5-flash-native-audio-preview-12-2025",
|
||||
@ -520,7 +565,7 @@ export GEMINI_API_KEY=...
|
||||
}
|
||||
```
|
||||
|
||||
`voiceCall.enabled` 默认值为 `true`;使用 Twilio 传输时,它会将实际的 PSTN 呼叫和 DTMF 委派给 Voice Call 插件。如果未启用 `voice-call`,Google Meet 仍然可以验证并记录拨号计划,但无法发起 Twilio 呼叫。
|
||||
`voiceCall.enabled` 默认为 `true`;使用 Twilio 传输时,它会将实际 PSTN 呼叫和 DTMF 委托给 Voice Call 插件。如果未启用 `voice-call`,Google Meet 仍可验证并记录拨号计划,但无法发起 Twilio 呼叫。
|
||||
|
||||
## 工具
|
||||
|
||||
@ -535,52 +580,55 @@ export GEMINI_API_KEY=...
|
||||
}
|
||||
```
|
||||
|
||||
当 Chrome 运行在 Gateway 网关主机上时,使用 `transport: "chrome"`。当 Chrome 运行在已配对节点(例如 Parallels VM)上时,使用 `transport: "chrome-node"`。在这两种情况下,实时模型和 `openclaw_agent_consult` 都运行在 Gateway 网关主机上,因此模型凭证保留在那里。
|
||||
当 Chrome 运行在 Gateway 网关主机上时,使用 `transport: "chrome"`。当 Chrome 运行在已配对节点上,例如 Parallels VM 时,使用
|
||||
`transport: "chrome-node"`。在这两种情况下,实时模型和 `openclaw_agent_consult` 都运行在 Gateway 网关主机上,因此模型凭证保留在那里。
|
||||
|
||||
使用 `action: "status"` 可列出活动会话或检查某个会话 ID。使用 `action: "speak"` 并提供 `sessionId` 和 `message`,可让实时智能体立即发声。使用 `action: "test_speech"` 可创建或复用会话、触发一段已知短语,并在 Chrome 主机可报告时返回 `inCall` 健康状态。使用 `action: "leave"` 将会话标记为已结束。
|
||||
使用 `action: "status"` 列出活动会话或检查某个会话 ID。使用带有 `sessionId` 和 `message` 的 `action: "speak"` 让实时智能体立即发言。使用 `action: "test_speech"` 创建或复用会话、触发一个已知短语,并在 Chrome 主机可报告时返回 `inCall` 健康状态。使用 `action: "leave"` 将会话标记为结束。
|
||||
|
||||
`status` 在可用时包含 Chrome 健康状态:
|
||||
可用时,`status` 包含 Chrome 健康状态:
|
||||
|
||||
- `inCall`:Chrome 看起来已进入 Meet 通话
|
||||
- `micMuted`:尽力检测的 Meet 麦克风状态
|
||||
- `manualActionRequired` / `manualActionReason` / `manualActionMessage`:浏览器配置文件需要手动登录、Meet 主持人批准、权限授予或浏览器控制修复,语音功能才能工作
|
||||
- `micMuted`:尽力判断的 Meet 麦克风状态
|
||||
- `manualActionRequired` / `manualActionReason` / `manualActionMessage`:浏览器配置文件需要手动登录、Meet 主持人准入、权限授予,或浏览器控制修复,语音功能才能工作
|
||||
- `providerConnected` / `realtimeReady`:实时语音桥接状态
|
||||
- `lastInputAt` / `lastOutputAt`:最近一次从桥接接收到或发送到桥接的音频时间
|
||||
- `lastInputAt` / `lastOutputAt`:最近一次从桥接收到或发送到桥接的音频时间
|
||||
|
||||
```json
|
||||
{
|
||||
"action": "speak",
|
||||
"sessionId": "meet_...",
|
||||
"message": "准确说出:我在这里,正在听。"
|
||||
"message": "Say exactly: I'm here and listening."
|
||||
}
|
||||
```
|
||||
|
||||
## 实时智能体咨询
|
||||
## Realtime 智能体咨询
|
||||
|
||||
Chrome 实时模式针对实时语音回路进行了优化。实时语音提供商会听取会议音频,并通过配置的音频桥接进行发声。当实时模型需要更深入的推理、当前信息或常规 OpenClaw 工具时,它可以调用 `openclaw_agent_consult`。
|
||||
Chrome 实时模式针对实时语音循环进行了优化。实时语音提供商会听取会议音频,并通过已配置的音频桥接进行发言。当实时模型需要更深入的推理、当前信息或常规 OpenClaw 工具时,它可以调用 `openclaw_agent_consult`。
|
||||
|
||||
该咨询工具会在后台运行常规 OpenClaw 智能体,并结合最近的会议转录上下文,向实时语音会话返回简洁的口头回答。然后语音模型可以将该回答再说回会议中。它与 Voice Call 共用同一个实时咨询工具。
|
||||
咨询工具会在后台运行常规的 OpenClaw 智能体,并结合最近的会议转录上下文,向实时语音会话返回简洁的口头答案。随后语音模型可以将该答案说回会议中。它与 Voice Call 共用同一个实时咨询工具。
|
||||
|
||||
`realtime.toolPolicy` 控制咨询运行方式:
|
||||
|
||||
- `safe-read-only`:暴露咨询工具,并将常规智能体限制为使用 `read`、`web_search`、`web_fetch`、`x_search`、`memory_search` 和 `memory_get`。
|
||||
- `owner`:暴露咨询工具,并允许常规智能体使用正常的智能体工具策略。
|
||||
- `safe-read-only`:暴露咨询工具,并将常规智能体限制为
|
||||
`read`、`web_search`、`web_fetch`、`x_search`、`memory_search` 和
|
||||
`memory_get`。
|
||||
- `owner`:暴露咨询工具,并允许常规智能体使用普通智能体工具策略。
|
||||
- `none`:不向实时语音模型暴露咨询工具。
|
||||
|
||||
咨询会话键按每个 Meet 会话进行作用域隔离,因此在同一场会议期间,后续咨询调用可以复用先前的咨询上下文。
|
||||
咨询会话键按每个 Meet 会话划分范围,因此在同一会议期间,后续咨询调用可以复用先前的咨询上下文。
|
||||
|
||||
若要在 Chrome 完全加入通话后强制执行一次口头就绪检查:
|
||||
|
||||
```bash
|
||||
openclaw googlemeet speak meet_... "准确说出:我在这里,正在听。"
|
||||
openclaw googlemeet speak meet_... "Say exactly: I'm here and listening."
|
||||
```
|
||||
|
||||
完整的加入并发声冒烟测试:
|
||||
完整的加入并发言冒烟测试:
|
||||
|
||||
```bash
|
||||
openclaw googlemeet test-speech https://meet.google.com/abc-defg-hij \
|
||||
--transport chrome-node \
|
||||
--message "准确说出:我在这里,正在听。"
|
||||
--message "Say exactly: I'm here and listening."
|
||||
```
|
||||
|
||||
## 实时测试检查清单
|
||||
@ -592,18 +640,18 @@ openclaw googlemeet setup
|
||||
openclaw nodes status
|
||||
openclaw googlemeet test-speech https://meet.google.com/abc-defg-hij \
|
||||
--transport chrome-node \
|
||||
--message "准确说出:Google Meet 语音测试完成。"
|
||||
--message "Say exactly: Google Meet speech test complete."
|
||||
```
|
||||
|
||||
预期的 chrome-node 状态:
|
||||
预期的 Chrome-node 状态:
|
||||
|
||||
- `googlemeet setup` 全部为绿色。
|
||||
- 当 chrome-node 是默认传输方式或固定了节点时,`googlemeet setup` 会包含 `chrome-node-connected`。
|
||||
- 当 Chrome-node 是默认传输方式或某个节点已被固定时,`googlemeet setup` 会包含 `chrome-node-connected`。
|
||||
- `nodes status` 显示所选节点已连接。
|
||||
- 所选节点同时声明了 `googlemeet.chrome` 和 `browser.proxy`。
|
||||
- Meet 标签页已加入通话,且 `test-speech` 返回包含 `inCall: true` 的 Chrome 健康状态。
|
||||
- 所选节点同时通告 `googlemeet.chrome` 和 `browser.proxy`。
|
||||
- Meet 标签页加入通话,且 `test-speech` 返回包含 `inCall: true` 的 Chrome 健康状态。
|
||||
|
||||
对于远程 Chrome 主机,例如 Parallels macOS VM,在更新 Gateway 网关或 VM 后,这是最短且安全的检查方式:
|
||||
对于远程 Chrome 主机,例如 Parallels macOS VM,在更新 Gateway 网关或 VM 之后,这是最简短且安全的检查方式:
|
||||
|
||||
```bash
|
||||
openclaw googlemeet setup
|
||||
@ -614,9 +662,9 @@ openclaw nodes invoke \
|
||||
--params '{"action":"setup"}'
|
||||
```
|
||||
|
||||
这可以证明 Gateway 网关插件已加载、VM 节点使用当前令牌保持连接,并且在智能体打开真实会议标签页之前,Meet 音频桥接已可用。
|
||||
这可以证明 Gateway 网关插件已加载、VM 节点已使用当前令牌连接,并且 Meet 音频桥接在智能体打开真实会议标签页之前可用。
|
||||
|
||||
对于 Twilio 冒烟测试,请使用一个会公开电话拨入详情的会议:
|
||||
对于 Twilio 冒烟测试,请使用一个会暴露电话拨入详情的会议:
|
||||
|
||||
```bash
|
||||
openclaw googlemeet setup
|
||||
@ -628,23 +676,25 @@ openclaw googlemeet join https://meet.google.com/abc-defg-hij \
|
||||
|
||||
预期的 Twilio 状态:
|
||||
|
||||
- `googlemeet setup` 包含绿色的 `twilio-voice-call-plugin` 和 `twilio-voice-call-credentials` 检查。
|
||||
- `googlemeet setup` 包含绿色的 `twilio-voice-call-plugin` 和
|
||||
`twilio-voice-call-credentials` 检查。
|
||||
- Gateway 网关重新加载后,CLI 中可用 `voicecall`。
|
||||
- 返回的会话具有 `transport: "twilio"` 和一个 `twilio.voiceCallId`。
|
||||
- `googlemeet leave <sessionId>` 会挂断被委派的语音通话。
|
||||
- 返回的会话包含 `transport: "twilio"` 和 `twilio.voiceCallId`。
|
||||
- `googlemeet leave <sessionId>` 会挂断委托的语音通话。
|
||||
|
||||
## 故障排除
|
||||
|
||||
### 智能体看不到 Google Meet 工具
|
||||
|
||||
确认该插件已在 Gateway 网关配置中启用,并重新加载 Gateway 网关:
|
||||
确认插件已在 Gateway 网关配置中启用,并重新加载 Gateway 网关:
|
||||
|
||||
```bash
|
||||
openclaw plugins list | grep google-meet
|
||||
openclaw googlemeet setup
|
||||
```
|
||||
|
||||
如果你刚编辑了 `plugins.entries.google-meet`,请重启或重新加载 Gateway 网关。正在运行的智能体只能看到由当前 Gateway 网关进程注册的插件工具。
|
||||
如果你刚刚编辑了 `plugins.entries.google-meet`,请重启或重新加载 Gateway 网关。
|
||||
运行中的智能体只能看到由当前 Gateway 网关进程注册的插件工具。
|
||||
|
||||
### 没有已连接的 Google Meet 可用节点
|
||||
|
||||
@ -665,7 +715,8 @@ openclaw devices approve <requestId>
|
||||
openclaw nodes status
|
||||
```
|
||||
|
||||
该节点必须处于已连接状态,并列出 `googlemeet.chrome` 和 `browser.proxy`。Gateway 网关配置还必须允许这些节点命令:
|
||||
该节点必须已连接,并列出 `googlemeet.chrome` 以及 `browser.proxy`。
|
||||
Gateway 网关配置必须允许这些节点命令:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -677,7 +728,8 @@ openclaw nodes status
|
||||
}
|
||||
```
|
||||
|
||||
如果 `googlemeet setup` 的 `chrome-node-connected` 检查失败,或者 Gateway 网关日志报告 `gateway token mismatch`,请使用当前的 Gateway 网关令牌重新安装或重启节点。对于一个局域网 Gateway 网关,这通常意味着:
|
||||
如果 `googlemeet setup` 的 `chrome-node-connected` 检查失败,或者 Gateway 网关日志报告
|
||||
`gateway token mismatch`,请使用当前 Gateway 网关令牌重新安装或重启节点。对于 LAN Gateway 网关,这通常意味着:
|
||||
|
||||
```bash
|
||||
OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1 \
|
||||
@ -688,36 +740,45 @@ OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1 \
|
||||
--force
|
||||
```
|
||||
|
||||
然后重新加载节点服务,并再次运行:
|
||||
然后重新加载节点服务,并重新运行:
|
||||
|
||||
```bash
|
||||
openclaw googlemeet setup
|
||||
openclaw nodes status --connected
|
||||
```
|
||||
|
||||
### 浏览器已打开,但智能体无法加入
|
||||
### 浏览器打开了,但智能体无法加入
|
||||
|
||||
运行 `googlemeet test-speech` 并检查返回的 Chrome 健康状态。如果它报告 `manualActionRequired: true`,请向操作员显示 `manualActionMessage`,并在浏览器操作完成前停止重试。
|
||||
运行 `googlemeet test-speech` 并检查返回的 Chrome 健康状态。如果它报告
|
||||
`manualActionRequired: true`,请将 `manualActionMessage` 展示给操作员,并在浏览器操作完成之前停止重试。
|
||||
|
||||
常见的手动操作:
|
||||
|
||||
- 登录 Chrome 配置文件。
|
||||
- 使用 Meet 主持人账号批准访客加入。
|
||||
- 当 Chrome 的原生权限提示出现时,授予 Chrome 麦克风/摄像头权限。
|
||||
- 从 Meet 主持人账号允许访客加入。
|
||||
- 当 Chrome 原生权限提示出现时,授予 Chrome 麦克风/摄像头权限。
|
||||
- 关闭或修复卡住的 Meet 权限对话框。
|
||||
|
||||
不要仅仅因为 Meet 显示 “Do you want people to hear you in the meeting?” 就报告“未登录”。这是 Meet 的音频选择过渡页面;OpenClaw 会在可用时通过浏览器自动化点击 **Use microphone**,并继续等待真实的会议状态。对于仅创建的浏览器回退,OpenClaw 可能会点击 **Continue without microphone**,因为创建 URL 不需要实时音频路径。
|
||||
不要仅因为 Meet 显示“Do you want people to hear you in the meeting?” 就报告“未登录”。
|
||||
那是 Meet 的音频选择过场页;OpenClaw 会在可用时通过浏览器自动化点击 **Use microphone**,并继续等待真实的会议状态。
|
||||
对于仅创建的浏览器回退,OpenClaw 可能会点击 **Continue without microphone**,因为创建 URL 不需要实时音频路径。
|
||||
|
||||
### 会议创建失败
|
||||
|
||||
当配置了 OAuth 凭证时,`googlemeet create` 会先使用 Google Meet API 的 `spaces.create` 端点。没有 OAuth 凭证时,它会回退到固定的 Chrome 节点浏览器。请确认:
|
||||
当配置了 OAuth 凭证时,`googlemeet create` 会首先使用 Google Meet API 的 `spaces.create` 端点。
|
||||
如果没有 OAuth 凭证,它会回退到固定的 Chrome 节点浏览器。请确认:
|
||||
|
||||
- 对于 API 创建:已配置 `oauth.clientId` 和 `oauth.refreshToken`,或者存在匹配的 `OPENCLAW_GOOGLE_MEET_*` 环境变量。
|
||||
- 对于 API 创建:刷新令牌是在添加创建支持之后生成的。较旧的令牌可能缺少 `meetings.space.created` scope;请重新运行 `openclaw googlemeet auth login --json` 并更新插件配置。
|
||||
- 对于浏览器回退:`defaultTransport: "chrome-node"` 且 `chromeNode.node` 指向一个已连接的节点,并且该节点具有 `browser.proxy` 和 `googlemeet.chrome`。
|
||||
- 对于 API 创建:已配置 `oauth.clientId` 和 `oauth.refreshToken`,
|
||||
或存在匹配的 `OPENCLAW_GOOGLE_MEET_*` 环境变量。
|
||||
- 对于 API 创建:刷新令牌是在添加创建支持之后签发的。较旧的令牌可能缺少 `meetings.space.created` scope;请重新运行
|
||||
`openclaw googlemeet auth login --json` 并更新插件配置。
|
||||
- 对于浏览器回退:`defaultTransport: "chrome-node"` 和
|
||||
`chromeNode.node` 指向一个已连接且具有 `browser.proxy` 和
|
||||
`googlemeet.chrome` 的节点。
|
||||
- 对于浏览器回退:该节点上的 OpenClaw Chrome 配置文件已登录 Google,并且可以打开 `https://meet.google.com/new`。
|
||||
- 对于浏览器回退:重试会复用已有的 `https://meet.google.com/new` 或 Google 账号提示标签页,而不是打开新标签页。如果智能体超时,请重试工具调用,而不是手动再打开一个 Meet 标签页。
|
||||
- 对于浏览器回退:如果 Meet 显示 “Do you want people to hear you in the meeting?”,请保持该标签页打开。OpenClaw 应通过浏览器自动化点击 **Use microphone**,或者在仅创建回退时点击 **Continue without microphone**,然后继续等待生成的 Meet URL。如果它做不到,错误应提及 `meet-audio-choice-required`,而不是 `google-login-required`。
|
||||
- 对于浏览器回退:重试会复用现有的 `https://meet.google.com/new`
|
||||
或 Google 账号提示标签页,而不是打开新标签页。如果智能体超时,请重试工具调用,而不是手动再打开一个 Meet 标签页。
|
||||
- 对于浏览器回退:如果 Meet 显示“Do you want people to hear you in the meeting?”,请保持该标签页打开。OpenClaw 应通过浏览器自动化点击 **Use microphone**,或者在仅创建回退时点击 **Continue without microphone**,并继续等待生成的 Meet URL。如果无法做到,错误应提及 `meet-audio-choice-required`,而不是 `google-login-required`。
|
||||
|
||||
### 智能体已加入但不说话
|
||||
|
||||
@ -725,23 +786,40 @@ openclaw nodes status --connected
|
||||
|
||||
```bash
|
||||
openclaw googlemeet setup
|
||||
openclaw googlemeet status
|
||||
openclaw googlemeet doctor
|
||||
```
|
||||
|
||||
使用 `mode: "realtime"` 实现收听/回话。`mode: "transcribe"` 按设计不会启动双工实时语音桥接。
|
||||
使用 `mode: "realtime"` 进行收听/回话。`mode: "transcribe"` 按设计不会启动双工实时语音桥接。
|
||||
|
||||
另外还要验证:
|
||||
还要验证:
|
||||
|
||||
- Gateway 网关主机上有可用的实时提供商密钥,例如 `OPENAI_API_KEY` 或 `GEMINI_API_KEY`。
|
||||
- Chrome 主机上可见 `BlackHole 2ch`。
|
||||
- Chrome 主机上存在 `rec` 和 `play`。
|
||||
- Meet 的麦克风和扬声器已通过 OpenClaw 使用的虚拟音频路径进行路由。
|
||||
- Gateway 网关主机上有可用的实时提供商密钥,例如
|
||||
`OPENAI_API_KEY` 或 `GEMINI_API_KEY`。
|
||||
- 在 Chrome 主机上可以看到 `BlackHole 2ch`。
|
||||
- 在 Chrome 主机上存在 `rec` 和 `play`。
|
||||
- Meet 的麦克风和扬声器已路由到 OpenClaw 使用的虚拟音频路径。
|
||||
|
||||
`googlemeet doctor [session-id]` 会打印会话、节点、in-call 状态、
|
||||
手动操作原因、实时提供商连接、`realtimeReady`、音频输入/输出活动、最近音频时间戳、字节计数以及浏览器 URL。
|
||||
当你需要原始 JSON 时,请使用 `googlemeet status [session-id]`。
|
||||
|
||||
如果智能体超时了,而你能看到一个已打开的 Meet 标签页,请检查该标签页,而不要再打开另一个:
|
||||
|
||||
```bash
|
||||
openclaw googlemeet recover-tab
|
||||
openclaw googlemeet recover-tab https://meet.google.com/abc-defg-hij
|
||||
```
|
||||
|
||||
对应的工具操作是 `recover_current_tab`。它会在已配置的 Chrome 节点上聚焦并检查现有 Meet 标签页。
|
||||
它不会打开新标签页,也不会创建新会话;它会报告当前阻塞项,例如登录、准入、权限或音频选择状态。
|
||||
|
||||
### Twilio 设置检查失败
|
||||
|
||||
当 `voice-call` 不被允许或未启用时,`twilio-voice-call-plugin` 会失败。将其添加到 `plugins.allow`,启用 `plugins.entries.voice-call`,并重新加载 Gateway 网关。
|
||||
当 `voice-call` 未被允许或未启用时,`twilio-voice-call-plugin` 会失败。
|
||||
请将其添加到 `plugins.allow`,启用 `plugins.entries.voice-call`,并重新加载 Gateway 网关。
|
||||
|
||||
当 Twilio 后端缺少 account SID、auth token 或 caller number 时,`twilio-voice-call-credentials` 会失败。在 Gateway 网关主机上设置这些值:
|
||||
当 Twilio 后端缺少 account SID、auth token 或主叫号码时,`twilio-voice-call-credentials` 会失败。
|
||||
请在 Gateway 网关主机上设置这些值:
|
||||
|
||||
```bash
|
||||
export TWILIO_ACCOUNT_SID=AC...
|
||||
@ -753,11 +831,25 @@ export TWILIO_FROM_NUMBER=+15550001234
|
||||
|
||||
```bash
|
||||
openclaw googlemeet setup
|
||||
openclaw voicecall setup
|
||||
openclaw voicecall smoke
|
||||
```
|
||||
|
||||
### Twilio 通话已开始但始终未进入会议
|
||||
默认情况下,`voicecall smoke` 仅进行就绪性检查。若要对特定号码进行 dry-run:
|
||||
|
||||
确认 Meet 事件公开了电话拨入详情。传入准确的拨入号码和 PIN,或者自定义 DTMF 序列:
|
||||
```bash
|
||||
openclaw voicecall smoke --to "+15555550123"
|
||||
```
|
||||
|
||||
只有在你明确想发起真实外呼通知电话时,才添加 `--yes`:
|
||||
|
||||
```bash
|
||||
openclaw voicecall smoke --to "+15555550123" --yes
|
||||
```
|
||||
|
||||
### Twilio 通话开始了,但始终未进入会议
|
||||
|
||||
确认 Meet 事件暴露了电话拨入详情。传入精确的拨入号码和 PIN,或自定义 DTMF 序列:
|
||||
|
||||
```bash
|
||||
openclaw googlemeet join https://meet.google.com/abc-defg-hij \
|
||||
@ -766,20 +858,23 @@ openclaw googlemeet join https://meet.google.com/abc-defg-hij \
|
||||
--dtmf-sequence ww123456#
|
||||
```
|
||||
|
||||
如果提供商在输入 PIN 前需要暂停,请在 `--dtmf-sequence` 中使用前导 `w` 或逗号。
|
||||
如果提供商需要在输入 PIN 之前暂停,请在 `--dtmf-sequence` 中使用前导 `w` 或逗号。
|
||||
|
||||
## 说明
|
||||
|
||||
Google Meet 的官方媒体 API 偏向接收,因此向 Meet 通话中发声仍然需要一个参会者路径。这个插件会明确保留这一边界:Chrome 负责浏览器参会和本地音频路由;Twilio 负责电话拨入参会。
|
||||
Google Meet 官方媒体 API 偏向接收,因此要在 Meet 通话中发言,仍然需要一条参与者路径。该插件将这一边界明确化:
|
||||
Chrome 负责浏览器参与和本地音频路由;Twilio 负责电话拨入参与。
|
||||
|
||||
Chrome 实时模式需要以下其中之一:
|
||||
Chrome 实时模式需要以下两者之一:
|
||||
|
||||
- `chrome.audioInputCommand` 加 `chrome.audioOutputCommand`:OpenClaw 自主管理实时模型桥接,并在这些命令与所选实时语音提供商之间传输 8 kHz G.711 mu-law 音频。
|
||||
- `chrome.audioBridgeCommand`:一个外部桥接命令拥有整个本地音频路径,并且必须在启动或验证其守护进程后退出。
|
||||
- `chrome.audioInputCommand` 加 `chrome.audioOutputCommand`:OpenClaw 负责实时模型桥接,并在这些命令与所选实时语音提供商之间传输 8 kHz G.711 mu-law 音频。
|
||||
- `chrome.audioBridgeCommand`:外部桥接命令负责整个本地音频路径,并且必须在启动或验证其守护进程后退出。
|
||||
|
||||
为了获得干净的双工音频,请将 Meet 输出和 Meet 麦克风通过独立的虚拟设备或类似 Loopback 的虚拟设备图进行路由。单个共享的 BlackHole 设备可能会将其他参与者的声音回送到通话中。
|
||||
为了获得干净的双工音频,请将 Meet 输出和 Meet 麦克风路由到独立的虚拟设备,或使用类似 Loopback 的虚拟设备图。
|
||||
单个共享的 BlackHole 设备可能会把其他参与者的声音回送到通话中。
|
||||
|
||||
`googlemeet speak` 会触发 Chrome 会话的活动实时音频桥接。`googlemeet leave` 会停止该桥接。对于通过 Voice Call 插件委派的 Twilio 会话,`leave` 还会挂断底层语音通话。
|
||||
`googlemeet speak` 会触发 Chrome 会话的活动实时音频桥接。
|
||||
`googlemeet leave` 会停止该桥接。对于通过 Voice Call 插件委托的 Twilio 会话,`leave` 还会挂断底层语音通话。
|
||||
|
||||
## 相关内容
|
||||
|
||||
|
||||
@ -2,20 +2,20 @@
|
||||
read_when:
|
||||
- 你正在构建一个新的消息渠道插件
|
||||
- 你想将 OpenClaw 连接到一个消息平台
|
||||
- 你需要了解 `ChannelPlugin` 适配器接口
|
||||
- 你需要理解 ChannelPlugin 适配器接口
|
||||
sidebarTitle: Channel Plugins
|
||||
summary: 为 OpenClaw 构建消息渠道插件的分步指南
|
||||
title: 构建渠道插件
|
||||
x-i18n:
|
||||
generated_at: "2026-04-25T01:59:27Z"
|
||||
generated_at: "2026-04-25T02:35:45Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: ac64ec8cc8963eaa5aff862e9b318951a156f10c2f6963cd7fce24780fb028ac
|
||||
source_hash: 0a466decff828bdce1d9d3e85127867b88f43c6eca25aa97306f8bd0df39f3a9
|
||||
source_path: plugins/sdk-channel-plugins.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
本指南将带你逐步构建一个渠道插件,把 OpenClaw 连接到某个消息平台。完成后,你将拥有一个可用的渠道,支持私信安全策略、配对、回复线程,以及出站消息发送。
|
||||
本指南将逐步带你构建一个渠道插件,把 OpenClaw 连接到某个消息平台。完成后,你将拥有一个可用的渠道,支持私信安全、配对、回复线程以及出站消息。
|
||||
|
||||
<Info>
|
||||
如果你之前还没有构建过任何 OpenClaw 插件,请先阅读
|
||||
@ -24,72 +24,68 @@ x-i18n:
|
||||
|
||||
## 渠道插件的工作方式
|
||||
|
||||
渠道插件不需要自带 send/edit/react 工具。OpenClaw 在核心中保留了一个共享的 `message` 工具。你的插件负责:
|
||||
渠道插件不需要自带发送/编辑/反应工具。OpenClaw 在核心中保留了一个共享的 `message` 工具。你的插件负责:
|
||||
|
||||
- **配置** —— 账户解析和设置向导
|
||||
- **安全** —— 私信策略和允许列表
|
||||
- **配对** —— 私信批准流程
|
||||
- **会话语法** —— 提供商特定的会话 id 如何映射到基础聊天、线程 id 和父级回退
|
||||
- **出站** —— 向平台发送文本、媒体和投票
|
||||
- **线程处理** —— 回复如何在线程中组织
|
||||
- **心跳输入状态** —— 用于心跳投递目标的可选 typing/busy 信号
|
||||
- **配置** — 账号解析和设置向导
|
||||
- **安全** — 私信策略和允许列表
|
||||
- **配对** — 私信批准流程
|
||||
- **会话语法** — 提供商特定的会话 id 如何映射到基础聊天、线程 id 和父级回退
|
||||
- **出站** — 向平台发送文本、媒体和投票
|
||||
- **线程处理** — 回复如何串成线程
|
||||
- **心跳输入状态** — 针对心跳投递目标的可选“正在输入”/忙碌信号
|
||||
|
||||
核心负责共享的消息工具、提示词接线、外层会话键形状、通用的 `:thread:` 记录,以及分发。
|
||||
核心负责共享消息工具、提示词接线、外层会话键形状、通用 `:thread:` 记录以及分发。
|
||||
|
||||
如果你的渠道支持在入站回复之外显示 typing 指示器,请在渠道插件上暴露
|
||||
`heartbeat.sendTyping(...)`。核心会在心跳模型运行开始前,使用已解析的心跳投递目标调用它,并使用共享的 typing 保活/清理生命周期。如果平台需要显式停止信号,请再添加 `heartbeat.clearTyping(...)`。
|
||||
如果你的渠道支持在入站回复之外显示输入指示器,请在渠道插件上暴露 `heartbeat.sendTyping(...)`。核心会在心跳模型运行开始前,使用已解析的心跳投递目标调用它,并使用共享的输入状态保活/清理生命周期。如果平台需要显式停止信号,请再添加 `heartbeat.clearTyping(...)`。
|
||||
|
||||
如果你的渠道为消息工具添加了携带媒体来源的参数,请通过
|
||||
`describeMessageTool(...).mediaSourceParams` 暴露这些参数名。核心会使用这个显式列表来进行沙箱路径规范化和出站媒体访问策略处理,因此插件不需要在共享核心中为提供商特定的头像、附件或封面图参数添加特殊分支。
|
||||
优先返回按 action 键控的映射,例如
|
||||
`{ "set-profile": ["avatarUrl", "avatarPath"] }`,这样无关的 action 就不会继承其他 action 的媒体参数。对于有意在所有暴露 action 之间共享的参数,扁平数组仍然可用。
|
||||
如果你的渠道会为消息工具添加携带媒体来源的参数,请通过 `describeMessageTool(...).mediaSourceParams` 暴露这些参数名。核心会使用这个显式列表进行沙箱路径规范化和出站媒体访问策略控制,这样插件就不需要为提供商特定的头像、附件或封面图参数添加共享核心特例。
|
||||
更推荐返回一个按 action 分组的映射,例如
|
||||
`{ "set-profile": ["avatarUrl", "avatarPath"] }`,
|
||||
这样无关 action 就不会继承其他 action 的媒体参数。对于有意在所有暴露 action 中共享的参数,扁平数组仍然可用。
|
||||
|
||||
如果你的平台在会话 id 中存储了额外作用域,请把这部分解析保留在插件中,使用
|
||||
`messaging.resolveSessionConversation(...)`。这是将 `rawId` 映射为基础会话 id、可选线程 id、显式 `baseConversationId` 以及任意 `parentConversationCandidates` 的规范钩子。
|
||||
当你返回 `parentConversationCandidates` 时,请保持从最窄父级到最宽/基础会话的顺序。
|
||||
如果你的平台会在会话 id 中存储额外作用域,请把这部分解析逻辑保留在插件中,并使用 `messaging.resolveSessionConversation(...)`。这是把 `rawId` 映射到基础会话 id、可选线程 id、显式 `baseConversationId` 以及任何 `parentConversationCandidates` 的规范钩子。
|
||||
当你返回 `parentConversationCandidates` 时,请保持顺序从最窄的父级到最宽泛/基础会话。
|
||||
|
||||
如果某些内置插件需要在渠道注册表启动之前完成相同的解析,它们也可以暴露一个顶层 `session-key-api.ts` 文件,并导出匹配的
|
||||
`resolveSessionConversation(...)`。只有在运行时插件注册表尚不可用时,核心才会使用这个可安全引导的接口。
|
||||
需要在渠道注册表启动前就进行相同解析的内置插件,也可以暴露一个顶层 `session-key-api.ts` 文件,并导出匹配的 `resolveSessionConversation(...)`。只有在运行时插件注册表尚不可用时,核心才会使用这个可安全引导的接口。
|
||||
|
||||
当某个插件只需要在通用/raw id 之上提供父级回退时,
|
||||
`messaging.resolveParentConversationCandidates(...)` 仍可作为旧版兼容回退继续使用。如果两个钩子都存在,核心会优先使用
|
||||
`resolveSessionConversation(...).parentConversationCandidates`,只有当规范钩子省略它们时,才会回退到 `resolveParentConversationCandidates(...)`。
|
||||
当插件只需要在通用/原始 id 之上提供父级回退时,`messaging.resolveParentConversationCandidates(...)` 仍可作为旧版兼容回退使用。如果两个钩子都存在,核心会优先使用
|
||||
`resolveSessionConversation(...).parentConversationCandidates`,只有在规范钩子省略它们时,才会回退到 `resolveParentConversationCandidates(...)`。
|
||||
|
||||
## 批准与渠道能力
|
||||
|
||||
大多数渠道插件不需要编写批准专用代码。
|
||||
大多数渠道插件不需要编写特定于批准的代码。
|
||||
|
||||
- 核心负责同聊天内的 `/approve`、共享的批准按钮负载,以及通用回退投递。
|
||||
- 当渠道需要批准专用行为时,优先在渠道插件上提供一个 `approvalCapability` 对象。
|
||||
- `ChannelPlugin.approvals` 已移除。请把批准投递/原生渲染/凭证相关信息放到 `approvalCapability` 中。
|
||||
- `plugin.auth` 仅用于 login/logout;核心不再从该对象读取批准认证钩子。
|
||||
- 核心负责同一聊天中的 `/approve`、共享批准按钮负载以及通用回退投递。
|
||||
- 当渠道需要特定于批准的行为时,优先在渠道插件上使用一个 `approvalCapability` 对象。
|
||||
- `ChannelPlugin.approvals` 已移除。请把批准投递/原生渲染/认证相关信息放到 `approvalCapability` 中。
|
||||
- `plugin.auth` 仅用于登录/登出;核心不再从该对象读取批准认证钩子。
|
||||
- `approvalCapability.authorizeActorAction` 和 `approvalCapability.getActionAvailabilityState` 是规范的批准认证接口。
|
||||
- 对于同聊天批准认证可用性,请使用 `approvalCapability.getActionAvailabilityState`。
|
||||
- 如果你的渠道暴露原生 exec 批准,请在发起界面/原生客户端状态与同聊天批准认证不同时,使用 `approvalCapability.getExecInitiatingSurfaceState`。核心会使用这个 exec 专用钩子来区分 `enabled` 和 `disabled`,判断发起渠道是否支持原生 exec 批准,并在原生客户端回退指引中包含该渠道。`createApproverRestrictedNativeApprovalCapability(...)` 为常见场景填充了这部分。
|
||||
- 对于渠道特定的负载生命周期行为,例如隐藏重复的本地批准提示或在投递前发送 typing 指示器,请使用 `outbound.shouldSuppressLocalPayloadPrompt` 或 `outbound.beforeDeliverPayload`。
|
||||
- 仅在需要原生批准路由或抑制回退时使用 `approvalCapability.delivery`。
|
||||
- 使用 `approvalCapability.nativeRuntime` 表达由渠道拥有的原生批准信息。在高频渠道入口点保持其懒加载,使用 `createLazyChannelApprovalNativeRuntimeAdapter(...)`,它可以按需导入你的运行时模块,同时仍允许核心组装批准生命周期。
|
||||
- 只有当渠道确实需要自定义批准负载而不是使用共享渲染器时,才使用 `approvalCapability.render`。
|
||||
- 当渠道希望在禁用路径回复中说明启用原生 exec 批准所需的精确配置项时,请使用 `approvalCapability.describeExecApprovalSetup`。该钩子会接收 `{ channel, channelLabel, accountId }`;具名账户渠道应渲染带账户作用域的路径,例如 `channels.<channel>.accounts.<id>.execApprovals.*`,而不是顶层默认值。
|
||||
- 如果某个渠道可以从现有配置中推断出稳定的、类似 owner 的私信身份,请使用 `openclaw/plugin-sdk/approval-runtime` 中的 `createResolvedApproverActionAuthAdapter` 来限制同聊天 `/approve`,而无需在核心中添加批准专用逻辑。
|
||||
- 如果某个渠道需要原生批准投递,请让渠道代码专注于目标规范化以及传输/展示事实。使用 `openclaw/plugin-sdk/approval-runtime` 中的 `createChannelExecApprovalProfile`、`createChannelNativeOriginTargetResolver`、`createChannelApproverDmTargetResolver` 和 `createApproverRestrictedNativeApprovalCapability`。把渠道特定事实放在 `approvalCapability.nativeRuntime` 后面,理想情况下通过 `createChannelApprovalNativeRuntimeAdapter(...)` 或 `createLazyChannelApprovalNativeRuntimeAdapter(...)`,这样核心就可以组装处理器,并负责请求过滤、路由、去重、过期、Gateway 网关订阅,以及“已路由到其他位置”的通知。`nativeRuntime` 被拆分为几个更小的接口:
|
||||
- `availability` —— 账户是否已配置,以及请求是否应被处理
|
||||
- `presentation` —— 将共享批准视图模型映射为待处理/已解决/已过期的原生负载或最终 action
|
||||
- `transport` —— 准备目标并发送/更新/删除原生批准消息
|
||||
- `interactions` —— 原生按钮或 reaction 的可选 bind/unbind/clear-action 钩子
|
||||
- `observe` —— 可选的投递诊断钩子
|
||||
- 如果渠道需要运行时拥有的对象,例如客户端、令牌、Bolt 应用或 webhook 接收器,请通过 `openclaw/plugin-sdk/channel-runtime-context` 注册它们。通用的运行时上下文注册表让核心可以从渠道启动状态中引导由能力驱动的处理器,而无需添加批准专用的包装胶水代码。
|
||||
- 只有在能力驱动接口仍不足以表达需求时,才考虑更底层的 `createChannelApprovalHandler` 或 `createChannelNativeApprovalRuntime`。
|
||||
- 原生批准渠道必须通过这些辅助工具同时传递 `accountId` 和 `approvalKind`。`accountId` 使多账户批准策略能限定在正确的机器人账户范围内,而 `approvalKind` 使渠道能够区分 exec 与插件批准行为,而无需在核心中写死分支。
|
||||
- 核心现在也负责批准重路由通知。渠道插件不应再从 `createChannelNativeApprovalRuntime` 发送自己的“批准已发往私信/另一渠道”后续消息;应改为通过共享批准能力辅助工具暴露准确的 origin + approver 私信路由,让核心在向发起聊天回发通知之前,先聚合实际投递结果。
|
||||
- 在端到端流程中保留已投递批准 id 的种类。原生客户端不应根据渠道本地状态去猜测或重写 exec 与插件批准路由。
|
||||
- 不同的批准种类可以有意暴露不同的原生界面。
|
||||
当前内置示例:
|
||||
- 对于同一聊天中的批准认证可用性,请使用 `approvalCapability.getActionAvailabilityState`。
|
||||
- 如果你的渠道暴露原生 exec 批准,请在发起界面/原生客户端状态与同聊批准认证不同的情况下,使用 `approvalCapability.getExecInitiatingSurfaceState`。核心会使用这个 exec 专用钩子来区分 `enabled` 与 `disabled`,判断发起渠道是否支持原生 exec 批准,并在原生客户端回退指引中包含该渠道。`createApproverRestrictedNativeApprovalCapability(...)` 为常见场景填充了这一能力。
|
||||
- 对于渠道特定的负载生命周期行为,例如隐藏重复的本地批准提示或在投递前发送输入指示器,请使用 `outbound.shouldSuppressLocalPayloadPrompt` 或 `outbound.beforeDeliverPayload`。
|
||||
- 仅在原生批准路由或回退抑制时使用 `approvalCapability.delivery`。
|
||||
- 对于渠道自有的原生批准信息,请使用 `approvalCapability.nativeRuntime`。在高频渠道入口点上,请通过 `createLazyChannelApprovalNativeRuntimeAdapter(...)` 保持其惰性,这样它可以按需导入你的运行时模块,同时仍允许核心组装批准生命周期。
|
||||
- 只有当渠道确实需要自定义批准负载而不是共享渲染器时,才使用 `approvalCapability.render`。
|
||||
- 当渠道希望禁用路径回复解释启用原生 exec 批准所需的确切配置项时,请使用 `approvalCapability.describeExecApprovalSetup`。该钩子会接收 `{ channel, channelLabel, accountId }`;对于具名账号渠道,应渲染账号范围路径,例如 `channels.<channel>.accounts.<id>.execApprovals.*`,而不是顶层默认值。
|
||||
- 如果某个渠道能够从现有配置中推断出稳定的、类似所有者的私信身份,请使用 `openclaw/plugin-sdk/approval-runtime` 中的 `createResolvedApproverActionAuthAdapter` 来限制同一聊天中的 `/approve`,而无需添加特定于批准的核心逻辑。
|
||||
- 如果某个渠道需要原生批准投递,请让渠道代码专注于目标规范化以及传输/展示信息。请使用 `openclaw/plugin-sdk/approval-runtime` 中的 `createChannelExecApprovalProfile`、`createChannelNativeOriginTargetResolver`、`createChannelApproverDmTargetResolver` 和 `createApproverRestrictedNativeApprovalCapability`。把渠道特定信息放在 `approvalCapability.nativeRuntime` 后面,理想情况下通过 `createChannelApprovalNativeRuntimeAdapter(...)` 或 `createLazyChannelApprovalNativeRuntimeAdapter(...)`,这样核心就能组装处理器,并接管请求过滤、路由、去重、过期、Gateway 网关订阅以及“已路由到别处”通知。`nativeRuntime` 被拆分为几个更小的接口:
|
||||
- `availability` — 账号是否已配置,以及某个请求是否应被处理
|
||||
- `presentation` — 将共享批准视图模型映射为待处理/已解决/已过期的原生负载或最终操作
|
||||
- `transport` — 准备目标以及发送/更新/删除原生批准消息
|
||||
- `interactions` — 针对原生按钮或反应的可选绑定/解绑/清除动作钩子
|
||||
- `observe` — 可选的投递诊断钩子
|
||||
- 如果渠道需要运行时自有对象,例如客户端、令牌、Bolt 应用或 webhook 接收器,请通过 `openclaw/plugin-sdk/channel-runtime-context` 注册它们。通用运行时上下文注册表让核心能够基于渠道启动状态引导能力驱动的处理器,而无需添加特定于批准的包装胶水代码。
|
||||
- 只有当能力驱动接口还不够表达需求时,才使用更底层的 `createChannelApprovalHandler` 或 `createChannelNativeApprovalRuntime`。
|
||||
- 原生批准渠道必须通过这些辅助工具同时传递 `accountId` 和 `approvalKind`。`accountId` 可确保多账号批准策略限定在正确的机器人账号内,而 `approvalKind` 则让渠道能够在不依赖核心硬编码分支的情况下处理 exec 与插件批准行为。
|
||||
- 现在核心也负责批准重路由通知。渠道插件不应再从 `createChannelNativeApprovalRuntime` 发送自己的“批准已发往私信/其他渠道”后续消息;相反,请通过共享批准能力辅助工具暴露准确的来源 + 批准人私信路由,让核心在向发起聊天回发通知前,统一汇总实际投递结果。
|
||||
- 在端到端流程中保留已投递批准 id 的类型。原生客户端不应根据渠道本地状态猜测或改写 exec 与插件批准路由。
|
||||
- 不同的批准类型可以有意暴露不同的原生界面。
|
||||
当前内置示例包括:
|
||||
- Slack 对 exec 和插件 id 都保留原生批准路由能力。
|
||||
- Matrix 对 exec 和插件批准保持相同的原生私信/渠道路由和 reaction UX,同时仍允许认证随批准种类不同而变化。
|
||||
- `createApproverRestrictedNativeApprovalAdapter` 仍然作为兼容包装器存在,但新代码应优先使用 capability builder,并在插件上暴露 `approvalCapability`。
|
||||
- Matrix 对 exec 和插件批准保持相同的原生私信/渠道路由和反应 UX,同时仍允许批准类型之间的认证不同。
|
||||
- `createApproverRestrictedNativeApprovalAdapter` 仍然作为兼容包装器存在,但新代码应优先使用能力构建器,并在插件上暴露 `approvalCapability`。
|
||||
|
||||
对于高频渠道入口点,如果你只需要该系列中的某一部分,请优先使用更窄的运行时子路径:
|
||||
对于高频渠道入口点,当你只需要该系列中的某一部分时,请优先使用更窄的运行时子路径:
|
||||
|
||||
- `openclaw/plugin-sdk/approval-auth-runtime`
|
||||
- `openclaw/plugin-sdk/approval-client-runtime`
|
||||
@ -101,76 +97,78 @@ x-i18n:
|
||||
- `openclaw/plugin-sdk/approval-reply-runtime`
|
||||
- `openclaw/plugin-sdk/channel-runtime-context`
|
||||
|
||||
同样地,当你不需要更宽泛的总括接口时,请优先使用
|
||||
`openclaw/plugin-sdk/setup-runtime`、
|
||||
同样地,当你不需要更宽泛的总接口时,请优先使用 `openclaw/plugin-sdk/setup-runtime`、
|
||||
`openclaw/plugin-sdk/setup-adapter-runtime`、
|
||||
`openclaw/plugin-sdk/reply-runtime`、
|
||||
`openclaw/plugin-sdk/reply-dispatch-runtime`、
|
||||
`openclaw/plugin-sdk/reply-reference` 和
|
||||
`openclaw/plugin-sdk/reply-chunking`。
|
||||
|
||||
对于设置,具体来说:
|
||||
对于设置,特别说明如下:
|
||||
|
||||
- `openclaw/plugin-sdk/setup-runtime` 涵盖运行时安全的设置辅助工具:
|
||||
导入安全的设置补丁适配器(`createPatchedAccountSetupAdapter`、
|
||||
- `openclaw/plugin-sdk/setup-runtime` 覆盖运行时安全的设置辅助工具:
|
||||
可安全导入的设置补丁适配器(`createPatchedAccountSetupAdapter`、
|
||||
`createEnvPatchedAccountSetupAdapter`、
|
||||
`createSetupInputPresenceValidator`)、查找说明输出、
|
||||
`promptResolvedAllowFrom`、`splitSetupEntries`,以及委托式
|
||||
setup-proxy builder
|
||||
- `openclaw/plugin-sdk/setup-adapter-runtime` 是
|
||||
`createEnvPatchedAccountSetupAdapter` 的窄范围、环境变量感知适配器接口
|
||||
- `openclaw/plugin-sdk/channel-setup` 涵盖可选安装设置 builder,以及少量设置安全原语:
|
||||
`createOptionalChannelSetupSurface`、`createOptionalChannelSetupAdapter`、
|
||||
设置代理构建器
|
||||
- `openclaw/plugin-sdk/setup-adapter-runtime` 是针对 `createEnvPatchedAccountSetupAdapter` 的窄接口、环境感知适配器接口
|
||||
- `openclaw/plugin-sdk/channel-setup` 覆盖可选安装设置构建器以及一些设置安全原语:
|
||||
`createOptionalChannelSetupSurface`、`createOptionalChannelSetupAdapter`,
|
||||
|
||||
如果你的渠道支持基于环境变量的设置或认证,并且通用启动/配置流程需要在运行时加载前就知道这些环境变量名,请在插件清单中使用 `channelEnvVars` 进行声明。保留渠道运行时 `envVars` 或本地常量,仅用于面向运维者的文案。
|
||||
如果你的渠道支持由环境变量驱动的设置或认证,并且通用启动/配置流程需要在运行时加载前知道这些环境变量名,请在插件清单中使用 `channelEnvVars` 进行声明。把渠道运行时 `envVars` 或本地常量仅用于面向操作员的文案。
|
||||
|
||||
如果你的渠道可能会在插件运行时启动之前出现在 `status`、`channels list`、`channels status` 或 SecretRef 扫描中,请在 `package.json` 中添加 `openclaw.setupEntry`。该入口点应能在只读命令路径中安全导入,并返回这些摘要所需的渠道元数据、设置安全配置适配器、状态适配器,以及渠道 secret target 元数据。不要从设置入口启动客户端、监听器或传输运行时。
|
||||
如果你的渠道可能会在插件运行时启动前出现在 `status`、`channels list`、`channels status` 或 SecretRef 扫描中,请在 `package.json` 中添加 `openclaw.setupEntry`。该入口点应能在只读命令路径中安全导入,并返回这些摘要所需的渠道元数据、设置安全配置适配器、状态适配器以及渠道密钥目标元数据。不要从设置入口启动客户端、监听器或传输运行时。
|
||||
|
||||
也请保持主渠道入口导入路径足够窄。设备发现过程可能会评估入口点和渠道插件模块,以注册能力,而不会激活该渠道。像 `channel-plugin-api.ts` 这样的文件应导出渠道插件对象,而不要导入设置向导、传输客户端、套接字监听器、子进程启动器或服务启动模块。把这些运行时部分放到通过 `registerFull(...)`、运行时 setter 或惰性能力适配器加载的模块中。
|
||||
|
||||
`createOptionalChannelSetupWizard`、`DEFAULT_ACCOUNT_ID`、
|
||||
`createTopLevelChannelDmPolicy`、`setSetupChannelEnabled` 和
|
||||
`splitSetupEntries`
|
||||
|
||||
- 仅当你还需要更重型的共享设置/配置辅助工具时,才使用更宽泛的
|
||||
`openclaw/plugin-sdk/setup` 接口,例如
|
||||
- 只有在你还需要更重的共享设置/配置辅助工具时,才使用更宽泛的 `openclaw/plugin-sdk/setup` 接口,例如
|
||||
`moveSingleAccountChannelSectionToDefaultAccount(...)`
|
||||
|
||||
如果你的渠道只是想在设置界面中提示“请先安装此插件”,请优先使用 `createOptionalChannelSetupSurface(...)`。生成的适配器/向导会在配置写入和最终确认时默认拒绝,并在校验、最终确认和文档链接文案中复用同一条“需要先安装”的消息。
|
||||
如果你的渠道只想在设置界面中提示“请先安装此插件”,优先使用 `createOptionalChannelSetupSurface(...)`。生成的适配器/向导会在配置写入和最终完成时默认关闭失败路径,并在校验、完成以及文档链接文案中复用同一条“需要安装”的消息。
|
||||
|
||||
对于其他高频渠道路径,也请优先使用窄接口辅助工具,而不是更宽泛的旧版接口:
|
||||
对于其他高频渠道路径,也应优先使用窄接口辅助工具,而不是更宽泛的旧接口:
|
||||
|
||||
- `openclaw/plugin-sdk/account-core`、
|
||||
`openclaw/plugin-sdk/account-id`、
|
||||
`openclaw/plugin-sdk/account-resolution` 和
|
||||
`openclaw/plugin-sdk/account-helpers`,用于多账户配置和默认账户回退
|
||||
`openclaw/plugin-sdk/account-helpers`,用于多账号配置和
|
||||
默认账号回退
|
||||
- `openclaw/plugin-sdk/inbound-envelope` 和
|
||||
`openclaw/plugin-sdk/inbound-reply-dispatch`,用于入站路由/信封以及
|
||||
record-and-dispatch 接线
|
||||
记录并分发接线
|
||||
- `openclaw/plugin-sdk/messaging-targets`,用于目标解析/匹配
|
||||
- `openclaw/plugin-sdk/outbound-media` 和
|
||||
`openclaw/plugin-sdk/outbound-runtime`,用于媒体加载以及出站
|
||||
identity/send 委托和负载规划
|
||||
身份/发送委托和负载规划
|
||||
- 来自 `openclaw/plugin-sdk/channel-core` 的 `buildThreadAwareOutboundSessionRoute(...)`,
|
||||
当某个出站路由需要保留显式的 `replyToId`/`threadId`,或在基础会话键仍然匹配后恢复当前 `:thread:` 会话时使用。
|
||||
当平台具有原生线程投递语义时,提供商插件可以覆盖优先级、后缀行为和线程 id 规范化。
|
||||
当某个出站路由需要保留显式的
|
||||
`replyToId`/`threadId`,或者在基础会话键仍然匹配后恢复当前
|
||||
`:thread:` 会话时使用。若提供商插件所在平台具有原生线程投递语义,
|
||||
它们可以覆盖优先级、后缀行为和线程 id 规范化。
|
||||
- `openclaw/plugin-sdk/thread-bindings-runtime`,用于线程绑定生命周期
|
||||
和适配器注册
|
||||
- `openclaw/plugin-sdk/agent-media-payload`,仅在仍需要旧版 agent/media
|
||||
- `openclaw/plugin-sdk/agent-media-payload`,仅当仍需要旧版智能体/媒体
|
||||
负载字段布局时使用
|
||||
- `openclaw/plugin-sdk/telegram-command-config`,用于 Telegram 自定义命令
|
||||
规范化、重复/冲突校验,以及稳定回退的命令
|
||||
规范化、重复/冲突校验,以及回退稳定的命令
|
||||
配置契约
|
||||
|
||||
仅认证型渠道通常可以止步于默认路径:核心处理批准,插件只需暴露出站/认证能力。像 Matrix、Slack、Telegram 以及自定义聊天传输这类原生批准渠道,应使用共享的原生辅助工具,而不是自行实现批准生命周期。
|
||||
仅认证型渠道通常只需走默认路径:核心负责批准,插件只需暴露出站/认证能力。像 Matrix、Slack、Telegram 以及自定义聊天传输这类原生批准渠道,应使用共享的原生辅助工具,而不是自行实现批准生命周期。
|
||||
|
||||
## 入站提及策略
|
||||
|
||||
请将入站提及处理拆分为两层:
|
||||
|
||||
- 由插件拥有的证据收集
|
||||
- 插件自有的证据收集
|
||||
- 共享的策略评估
|
||||
|
||||
使用 `openclaw/plugin-sdk/channel-mention-gating` 做提及策略决策。
|
||||
仅当你需要更宽泛的入站辅助 barrel 时,才使用 `openclaw/plugin-sdk/channel-inbound`。
|
||||
提及策略决策请使用 `openclaw/plugin-sdk/channel-mention-gating`。
|
||||
只有在你需要更宽泛的入站辅助工具 barrel 时,才使用 `openclaw/plugin-sdk/channel-inbound`。
|
||||
|
||||
适合放在插件本地逻辑中的内容:
|
||||
|
||||
@ -180,7 +178,7 @@ x-i18n:
|
||||
- 服务/系统消息排除
|
||||
- 证明机器人参与所需的平台原生缓存
|
||||
|
||||
适合放在共享辅助工具中的内容:
|
||||
适合使用共享辅助工具的内容:
|
||||
|
||||
- `requireMention`
|
||||
- 显式提及结果
|
||||
@ -191,7 +189,7 @@ x-i18n:
|
||||
推荐流程:
|
||||
|
||||
1. 计算本地提及事实。
|
||||
2. 将这些事实传给 `resolveInboundMentionDecision({ facts, policy })`。
|
||||
2. 将这些事实传入 `resolveInboundMentionDecision({ facts, policy })`。
|
||||
3. 在你的入站门控中使用 `decision.effectiveWasMentioned`、`decision.shouldBypassMention` 和 `decision.shouldSkip`。
|
||||
|
||||
```typescript
|
||||
@ -231,7 +229,7 @@ const decision = resolveInboundMentionDecision({
|
||||
if (decision.shouldSkip) return;
|
||||
```
|
||||
|
||||
`api.runtime.channel.mentions` 为已依赖运行时注入的内置渠道插件暴露了同一组共享提及辅助工具:
|
||||
`api.runtime.channel.mentions` 为已经依赖运行时注入的内置渠道插件暴露了同一套共享提及辅助工具:
|
||||
|
||||
- `buildMentionRegexes`
|
||||
- `matchesMentionPatterns`
|
||||
@ -245,7 +243,8 @@ if (decision.shouldSkip) return;
|
||||
运行时辅助工具。
|
||||
|
||||
较旧的 `resolveMentionGating*` 辅助工具仍保留在
|
||||
`openclaw/plugin-sdk/channel-inbound` 中,但仅作为兼容性导出。新代码应使用 `resolveInboundMentionDecision({ facts, policy })`。
|
||||
`openclaw/plugin-sdk/channel-inbound` 中,但仅作为兼容性导出。新代码应使用
|
||||
`resolveInboundMentionDecision({ facts, policy })`。
|
||||
|
||||
## 演练
|
||||
|
||||
@ -253,8 +252,8 @@ if (decision.shouldSkip) return;
|
||||
<a id="step-1-package-and-manifest"></a>
|
||||
<Step title="包和清单">
|
||||
创建标准插件文件。`package.json` 中的 `channel` 字段
|
||||
会将其标记为一个渠道插件。关于完整的包元数据接口,
|
||||
请参阅 [插件设置和配置](/zh-CN/plugins/sdk-setup#openclaw-channel):
|
||||
用于声明这是一个渠道插件。完整的包元数据接口
|
||||
参见 [插件设置和配置](/zh-CN/plugins/sdk-setup#openclaw-channel):
|
||||
|
||||
<CodeGroup>
|
||||
```json package.json
|
||||
@ -301,7 +300,7 @@ if (decision.shouldSkip) return;
|
||||
},
|
||||
"uiHints": {
|
||||
"token": {
|
||||
"label": "机器人令牌",
|
||||
"label": "Bot token",
|
||||
"sensitive": true
|
||||
}
|
||||
}
|
||||
@ -311,16 +310,16 @@ if (decision.shouldSkip) return;
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
`configSchema` 用于校验 `plugins.entries.acme-chat.config`。请将它用于
|
||||
由插件拥有、但不属于渠道账户配置的设置。`channelConfigs`
|
||||
用于校验 `channels.acme-chat`,并且是在插件运行时加载之前,
|
||||
供配置 schema、设置和 UI 界面使用的冷路径数据源。
|
||||
`configSchema` 用于校验 `plugins.entries.acme-chat.config`。它适用于
|
||||
不属于渠道账号配置、但由插件自行拥有的设置。`channelConfigs`
|
||||
用于校验 `channels.acme-chat`,并且是在插件运行时加载前,供配置
|
||||
schema、设置和 UI 界面使用的冷路径数据源。
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="构建渠道插件对象">
|
||||
`ChannelPlugin` 接口有许多可选的适配器接口。先从
|
||||
最小集开始——`id` 和 `setup`——然后按需添加适配器。
|
||||
`ChannelPlugin` 接口包含许多可选适配器接口。开始时先使用
|
||||
最小集合 —— `id` 和 `setup` —— 然后按需添加适配器。
|
||||
|
||||
创建 `src/channel.ts`:
|
||||
|
||||
@ -415,27 +414,26 @@ if (decision.shouldSkip) return;
|
||||
});
|
||||
```
|
||||
|
||||
<Accordion title="`createChatChannelPlugin` 为你完成了什么">
|
||||
<Accordion title="createChatChannelPlugin 会为你做什么">
|
||||
你无需手动实现底层适配器接口,而是传入声明式选项,
|
||||
由 builder 负责组合它们:
|
||||
然后由构建器完成组合:
|
||||
|
||||
| 选项 | 接线内容 |
|
||||
| 选项 | 它接线的内容 |
|
||||
| --- | --- |
|
||||
| `security.dm` | 从配置字段解析带作用域的私信安全策略 |
|
||||
| `security.dm` | 基于配置字段的作用域化私信安全解析器 |
|
||||
| `pairing.text` | 基于文本和验证码交换的私信配对流程 |
|
||||
| `threading` | reply-to 模式解析器(固定、账户作用域或自定义) |
|
||||
| `threading` | reply-to 模式解析器(固定、账号作用域或自定义) |
|
||||
| `outbound.attachedResults` | 返回结果元数据(消息 ID)的发送函数 |
|
||||
|
||||
如果你需要完全控制,也可以直接传入原始适配器对象,
|
||||
而不是这些声明式选项。
|
||||
如果你需要完全控制,也可以直接传入原始适配器对象,而不是这些声明式选项。
|
||||
|
||||
原始出站适配器可以定义 `chunker(text, limit, ctx)` 函数。
|
||||
可选的 `ctx.formatting` 携带投递时的格式化决策,
|
||||
例如 `maxLinesPerMessage`;请在发送前应用它,
|
||||
这样回复线程和分块边界就能由共享的出站投递统一解析一次。
|
||||
发送上下文还包括 `replyToIdSource`(`implicit` 或 `explicit`),
|
||||
当某个原生回复目标已被解析时,负载辅助工具就可以保留显式回复标签,
|
||||
而不会消耗隐式的单次回复槽位。
|
||||
可选的 `ctx.formatting` 携带投递时格式化决策,
|
||||
例如 `maxLinesPerMessage`;请在发送前应用它,以便回复线程和
|
||||
分块边界只由共享出站投递解析一次。
|
||||
发送上下文还包含 `replyToIdSource`(`implicit` 或 `explicit`),
|
||||
当原生回复目标已解析时会提供该值,这样负载辅助工具就能保留显式
|
||||
回复标签,而不会消耗隐式的单次回复槽位。
|
||||
</Accordion>
|
||||
|
||||
</Step>
|
||||
@ -476,21 +474,20 @@ if (decision.shouldSkip) return;
|
||||
});
|
||||
```
|
||||
|
||||
将由渠道拥有的 CLI 描述符放在 `registerCliMetadata(...)` 中,这样 OpenClaw
|
||||
就能在不激活完整渠道运行时的情况下,在根帮助中显示它们,
|
||||
同时普通的完整加载仍会拾取同一组描述符以进行真实的命令注册。
|
||||
请把 `registerFull(...)` 保留给仅限运行时的工作。
|
||||
将渠道自有的 CLI 描述符放在 `registerCliMetadata(...)` 中,这样 OpenClaw
|
||||
就能在不激活完整渠道运行时的情况下,在根帮助中显示它们;而正常的完整加载
|
||||
仍会使用同一组描述符进行真实命令注册。将 `registerFull(...)` 保留给仅运行时的工作。
|
||||
如果 `registerFull(...)` 注册 Gateway 网关 RPC 方法,请使用
|
||||
插件专用前缀。核心管理命名空间(`config.*`、
|
||||
`exec.approvals.*`、`wizard.*`、`update.*`)仍然保留,并始终
|
||||
解析为 `operator.admin`。
|
||||
`defineChannelPluginEntry` 会自动处理注册模式拆分。有关
|
||||
所有选项,请参阅 [入口点](/zh-CN/plugins/sdk-entrypoints#definechannelpluginentry)。
|
||||
插件专属前缀。核心管理命名空间(`config.*`、
|
||||
`exec.approvals.*`、`wizard.*`、`update.*`)始终保留,并且总是
|
||||
解析到 `operator.admin`。
|
||||
`defineChannelPluginEntry` 会自动处理注册模式拆分。所有
|
||||
选项请参见 [入口点](/zh-CN/plugins/sdk-entrypoints#definechannelpluginentry)。
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="添加设置入口">
|
||||
创建 `setup-entry.ts`,用于新手引导期间的轻量加载:
|
||||
为新手引导期间的轻量加载创建 `setup-entry.ts`:
|
||||
|
||||
```typescript setup-entry.ts
|
||||
import { defineSetupPluginEntry } from "openclaw/plugin-sdk/channel-core";
|
||||
@ -499,20 +496,20 @@ if (decision.shouldSkip) return;
|
||||
export default defineSetupPluginEntry(acmeChatPlugin);
|
||||
```
|
||||
|
||||
当渠道被禁用或尚未配置时,OpenClaw 会加载它,而不是完整入口。
|
||||
当渠道被禁用或尚未配置时,OpenClaw 会加载这个入口,而不是完整入口。
|
||||
这样可以避免在设置流程中拉入较重的运行时代码。
|
||||
详情请参阅 [设置和配置](/zh-CN/plugins/sdk-setup#setup-entry)。
|
||||
详情请参见 [设置和配置](/zh-CN/plugins/sdk-setup#setup-entry)。
|
||||
|
||||
对于将设置安全导出拆分到 sidecar
|
||||
模块中的内置工作区渠道,如果它们还需要一个显式的设置期运行时 setter,
|
||||
可以使用 `openclaw/plugin-sdk/channel-entry-contract` 中的
|
||||
将设置安全导出拆分到侧车模块中的内置工作区渠道,
|
||||
如果还需要显式的设置期运行时 setter,可以使用
|
||||
`openclaw/plugin-sdk/channel-entry-contract` 中的
|
||||
`defineBundledChannelSetupEntry(...)`。
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="处理入站消息">
|
||||
你的插件需要从平台接收消息,并将其转发给
|
||||
OpenClaw。典型模式是使用 webhook 来验证请求,并通过你渠道的入站处理器进行分发:
|
||||
你的插件需要接收来自平台的消息并将其转发给
|
||||
OpenClaw。典型模式是使用一个 webhook,对请求进行验证,并通过你的渠道入站处理器进行分发:
|
||||
|
||||
```typescript
|
||||
registerFull(api) {
|
||||
@ -536,16 +533,16 @@ if (decision.shouldSkip) return;
|
||||
```
|
||||
|
||||
<Note>
|
||||
入站消息处理是渠道特定的。每个渠道插件都拥有
|
||||
自己的入站流水线。请查看内置渠道插件
|
||||
(例如 Microsoft Teams 或 Google Chat 插件包)以获取真实模式。
|
||||
入站消息处理是渠道特定的。每个渠道插件都负责
|
||||
自己的入站处理管线。可以参考内置渠道插件
|
||||
(例如 Microsoft Teams 或 Google Chat 插件包)了解真实模式。
|
||||
</Note>
|
||||
|
||||
</Step>
|
||||
|
||||
<a id="step-6-test"></a>
|
||||
<Step title="测试">
|
||||
在 `src/channel.test.ts` 中编写同目录测试:
|
||||
编写同目录测试文件 `src/channel.test.ts`:
|
||||
|
||||
```typescript src/channel.test.ts
|
||||
import { describe, it, expect } from "vitest";
|
||||
@ -583,7 +580,7 @@ if (decision.shouldSkip) return;
|
||||
pnpm test -- <bundled-plugin-root>/acme-chat/
|
||||
```
|
||||
|
||||
关于共享测试辅助工具,请参阅 [测试](/zh-CN/plugins/sdk-testing)。
|
||||
共享测试辅助工具请参见 [测试](/zh-CN/plugins/sdk-testing)。
|
||||
|
||||
</Step>
|
||||
</Steps>
|
||||
@ -592,24 +589,24 @@ if (decision.shouldSkip) return;
|
||||
|
||||
```
|
||||
<bundled-plugin-root>/acme-chat/
|
||||
├── package.json # openclaw.channel 元数据
|
||||
├── openclaw.plugin.json # 带配置 schema 的清单
|
||||
├── package.json # openclaw.channel metadata
|
||||
├── openclaw.plugin.json # Manifest with config schema
|
||||
├── index.ts # defineChannelPluginEntry
|
||||
├── setup-entry.ts # defineSetupPluginEntry
|
||||
├── api.ts # 公共导出(可选)
|
||||
├── runtime-api.ts # 内部运行时导出(可选)
|
||||
├── api.ts # Public exports (optional)
|
||||
├── runtime-api.ts # Internal runtime exports (optional)
|
||||
└── src/
|
||||
├── channel.ts # 通过 createChatChannelPlugin 构建的 ChannelPlugin
|
||||
├── channel.test.ts # 测试
|
||||
├── client.ts # 平台 API 客户端
|
||||
└── runtime.ts # 运行时存储(如有需要)
|
||||
├── channel.ts # ChannelPlugin via createChatChannelPlugin
|
||||
├── channel.test.ts # Tests
|
||||
├── client.ts # Platform API client
|
||||
└── runtime.ts # Runtime store (if needed)
|
||||
```
|
||||
|
||||
## 高级主题
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="线程处理选项" icon="git-branch" href="/zh-CN/plugins/sdk-entrypoints#registration-mode">
|
||||
固定、账户作用域或自定义回复模式
|
||||
固定、账号作用域或自定义回复模式
|
||||
</Card>
|
||||
<Card title="消息工具集成" icon="puzzle" href="/zh-CN/plugins/architecture#channel-plugins-and-the-shared-message-tool">
|
||||
describeMessageTool 和 action 发现
|
||||
@ -618,23 +615,23 @@ if (decision.shouldSkip) return;
|
||||
inferTargetChatType、looksLikeId、resolveTarget
|
||||
</Card>
|
||||
<Card title="运行时辅助工具" icon="settings" href="/zh-CN/plugins/sdk-runtime">
|
||||
通过 api.runtime 使用 TTS、STT、媒体、subagent
|
||||
通过 api.runtime 使用 TTS、STT、媒体、子智能体
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
<Note>
|
||||
一些内置辅助接口仍然保留,用于内置插件维护和兼容性。
|
||||
它们并不是新渠道插件的推荐模式;
|
||||
除非你是在直接维护该内置插件家族,否则请优先使用通用 SDK
|
||||
接口中的 channel/setup/reply/runtime 子路径。
|
||||
一些内置辅助工具接口仍然存在,用于内置插件维护和
|
||||
兼容性。对于新的渠道插件,它们并不是推荐模式;
|
||||
除非你是在直接维护该内置插件系列,否则应优先使用通用 SDK
|
||||
接口中的渠道/设置/回复/运行时子路径。
|
||||
</Note>
|
||||
|
||||
## 后续步骤
|
||||
|
||||
- [提供商插件](/zh-CN/plugins/sdk-provider-plugins) —— 如果你的插件还提供模型
|
||||
- [SDK 概览](/zh-CN/plugins/sdk-overview) —— 完整的子路径导入参考
|
||||
- [插件 SDK 测试](/zh-CN/plugins/sdk-testing) —— 测试工具和契约测试
|
||||
- [插件清单](/zh-CN/plugins/manifest) —— 完整清单 schema
|
||||
- [提供商插件](/zh-CN/plugins/sdk-provider-plugins) — 如果你的插件也提供 Models
|
||||
- [SDK 概览](/zh-CN/plugins/sdk-overview) — 完整子路径导入参考
|
||||
- [插件 SDK 测试](/zh-CN/plugins/sdk-testing) — 测试工具和契约测试
|
||||
- [插件清单](/zh-CN/plugins/manifest) — 完整清单 schema
|
||||
|
||||
## 相关内容
|
||||
|
||||
|
||||
@ -1,25 +1,23 @@
|
||||
---
|
||||
read_when:
|
||||
- 你需要 `definePluginEntry` 或 `defineChannelPluginEntry` 的精确类型签名
|
||||
- 你想了解注册模式(full、setup、CLI 元数据)
|
||||
- 你正在查找入口点选项
|
||||
- 你想了解注册模式(完整、设置、CLI 元数据)
|
||||
- 你在查找入口点选项
|
||||
sidebarTitle: Entry Points
|
||||
summary: '`definePluginEntry`、`defineChannelPluginEntry` 和 `defineSetupPluginEntry` 参考'
|
||||
summary: '`definePluginEntry`、`defineChannelPluginEntry` 和 `defineSetupPluginEntry` 的参考说明'
|
||||
title: 插件入口点
|
||||
x-i18n:
|
||||
generated_at: "2026-04-23T20:57:37Z"
|
||||
generated_at: "2026-04-25T02:36:15Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: 517559e16416cbf9d152a0ca2e09f57de92ff65277fec768cbaf38d9de62e051
|
||||
source_hash: 8253cf0ac43ca11b42c0032027bba6e926c961b54901caaa63da70bd5ff5aab5
|
||||
source_path: plugins/sdk-entrypoints.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
每个插件都会导出一个默认入口对象。SDK 提供了三个辅助函数来
|
||||
创建它们。
|
||||
每个插件都会导出一个默认入口对象。SDK 提供了三个辅助函数来创建它们。
|
||||
|
||||
对于已安装的插件,`package.json` 应在可用时将运行时加载指向已构建的
|
||||
JavaScript:
|
||||
对于已安装的插件,`package.json` 应在可用时将运行时加载指向已构建的 JavaScript:
|
||||
|
||||
```json
|
||||
{
|
||||
@ -32,25 +30,19 @@ JavaScript:
|
||||
}
|
||||
```
|
||||
|
||||
`extensions` 和 `setupEntry` 仍然是工作区和 git
|
||||
检出开发时有效的源码入口。`runtimeExtensions` 和 `runtimeSetupEntry` 在 OpenClaw 加载已安装包时优先使用,并让 npm 包能够避免运行时 TypeScript 编译。如果已安装包只声明了 TypeScript
|
||||
源码入口,OpenClaw 会在存在匹配的构建产物 `dist/*.js` 对等文件时优先使用它,然后再回退到 TypeScript 源码。
|
||||
`extensions` 和 `setupEntry` 仍然是工作区和 git 检出开发时有效的源码入口。`runtimeExtensions` 和 `runtimeSetupEntry` 会在 OpenClaw 加载已安装包时优先使用,并让 npm 包避免在运行时编译 TypeScript。如果某个已安装包只声明了 TypeScript 源码入口,OpenClaw 会在存在对应项时使用匹配的已构建 `dist/*.js` 对应文件,然后再回退到 TypeScript 源码。
|
||||
|
||||
所有入口路径都必须保持在插件包目录内部。运行时入口
|
||||
和推断出的已构建 JavaScript 对等文件,并不会让一个逃逸包目录的 `extensions` 或
|
||||
`setupEntry` 源路径变得有效。
|
||||
所有入口路径都必须保留在插件包目录内。运行时入口和推断出的已构建 JavaScript 对应文件,不会让逃逸出 `extensions` 或 `setupEntry` 源码路径的配置变为有效。
|
||||
|
||||
<Tip>
|
||||
**在找操作演练吗?** 请参阅[渠道插件](/zh-CN/plugins/sdk-channel-plugins)
|
||||
或[提供商插件](/zh-CN/plugins/sdk-provider-plugins)以获取逐步指南。
|
||||
**在找分步演练?** 参见 [渠道插件](/zh-CN/plugins/sdk-channel-plugins) 或 [提供商插件](/zh-CN/plugins/sdk-provider-plugins) 获取分步指南。
|
||||
</Tip>
|
||||
|
||||
## `definePluginEntry`
|
||||
|
||||
**导入:** `openclaw/plugin-sdk/plugin-entry`
|
||||
|
||||
用于提供商插件、工具插件、hook 插件,以及任何**不是**
|
||||
消息渠道的插件。
|
||||
用于提供商插件、工具插件、钩子插件,以及任何**不是**消息渠道的插件。
|
||||
|
||||
```typescript
|
||||
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
|
||||
@ -72,25 +64,23 @@ export default definePluginEntry({
|
||||
|
||||
| 字段 | 类型 | 必填 | 默认值 |
|
||||
| -------------- | ---------------------------------------------------------------- | -------- | ------------------- |
|
||||
| `id` | `string` | 是 | — |
|
||||
| `name` | `string` | 是 | — |
|
||||
| `description` | `string` | 是 | — |
|
||||
| `kind` | `string` | 否 | — |
|
||||
| `configSchema` | `OpenClawPluginConfigSchema \| () => OpenClawPluginConfigSchema` | 否 | 空对象 schema |
|
||||
| `register` | `(api: OpenClawPluginApi) => void` | 是 | — |
|
||||
| `id` | `string` | 是 | — |
|
||||
| `name` | `string` | 是 | — |
|
||||
| `description` | `string` | 是 | — |
|
||||
| `kind` | `string` | 否 | — |
|
||||
| `configSchema` | `OpenClawPluginConfigSchema \| () => OpenClawPluginConfigSchema` | 否 | 空对象 schema |
|
||||
| `register` | `(api: OpenClawPluginApi) => void` | 是 | — |
|
||||
|
||||
- `id` 必须与你的 `openclaw.plugin.json` manifest 匹配。
|
||||
- `id` 必须与你的 `openclaw.plugin.json` 清单一致。
|
||||
- `kind` 用于互斥槽位:`"memory"` 或 `"context-engine"`。
|
||||
- `configSchema` 可以是函数,以实现惰性求值。
|
||||
- OpenClaw 会在首次访问时解析并记忆该 schema,因此代价较高的 schema
|
||||
构建器只会运行一次。
|
||||
- `configSchema` 可以是一个用于延迟求值的函数。
|
||||
- OpenClaw 会在首次访问时解析并记忆该 schema,因此代价较高的 schema 构建器只会运行一次。
|
||||
|
||||
## `defineChannelPluginEntry`
|
||||
|
||||
**导入:** `openclaw/plugin-sdk/channel-core`
|
||||
|
||||
它是在 `definePluginEntry` 之上增加渠道特定连接的封装。会自动调用
|
||||
`api.registerChannel({ plugin })`,暴露一个可选的根帮助 CLI 元数据接口,并根据注册模式控制 `registerFull` 的执行。
|
||||
这是带有渠道专用接线逻辑的 `definePluginEntry` 封装。它会自动调用 `api.registerChannel({ plugin })`,提供一个可选的根帮助 CLI 元数据扩展点,并根据注册模式控制 `registerFull` 的执行。
|
||||
|
||||
```typescript
|
||||
import { defineChannelPluginEntry } from "openclaw/plugin-sdk/channel-core";
|
||||
@ -112,40 +102,29 @@ export default defineChannelPluginEntry({
|
||||
|
||||
| 字段 | 类型 | 必填 | 默认值 |
|
||||
| --------------------- | ---------------------------------------------------------------- | -------- | ------------------- |
|
||||
| `id` | `string` | 是 | — |
|
||||
| `name` | `string` | 是 | — |
|
||||
| `description` | `string` | 是 | — |
|
||||
| `plugin` | `ChannelPlugin` | 是 | — |
|
||||
| `configSchema` | `OpenClawPluginConfigSchema \| () => OpenClawPluginConfigSchema` | 否 | 空对象 schema |
|
||||
| `setRuntime` | `(runtime: PluginRuntime) => void` | 否 | — |
|
||||
| `registerCliMetadata` | `(api: OpenClawPluginApi) => void` | 否 | — |
|
||||
| `registerFull` | `(api: OpenClawPluginApi) => void` | 否 | — |
|
||||
| `id` | `string` | 是 | — |
|
||||
| `name` | `string` | 是 | — |
|
||||
| `description` | `string` | 是 | — |
|
||||
| `plugin` | `ChannelPlugin` | 是 | — |
|
||||
| `configSchema` | `OpenClawPluginConfigSchema \| () => OpenClawPluginConfigSchema` | 否 | 空对象 schema |
|
||||
| `setRuntime` | `(runtime: PluginRuntime) => void` | 否 | — |
|
||||
| `registerCliMetadata` | `(api: OpenClawPluginApi) => void` | 否 | — |
|
||||
| `registerFull` | `(api: OpenClawPluginApi) => void` | 否 | — |
|
||||
|
||||
- `setRuntime` 会在注册期间调用,以便你存储运行时引用
|
||||
(通常通过 `createPluginRuntimeStore`)。在 CLI 元数据
|
||||
捕获期间会跳过它。
|
||||
- `registerCliMetadata` 会在 `api.registrationMode === "cli-metadata"`
|
||||
和 `api.registrationMode === "full"` 两种情况下运行。
|
||||
请将它作为渠道自有 CLI 描述符的规范位置,这样根帮助
|
||||
就能保持非激活式,同时普通 CLI 命令注册仍与完整插件加载兼容。
|
||||
- `registerFull` 仅在 `api.registrationMode === "full"` 时运行。在 setup-only 加载期间会跳过。
|
||||
- 与 `definePluginEntry` 一样,`configSchema` 可以是惰性工厂,OpenClaw
|
||||
会在首次访问时记忆解析结果。
|
||||
- 对于插件自有的根 CLI 命令,当你希望命令保持惰性加载而又不从
|
||||
根 CLI 解析树中消失时,请优先使用 `api.registerCli(..., { descriptors: [...] })`。
|
||||
对于渠道插件,请优先从 `registerCliMetadata(...)` 中注册这些描述符,
|
||||
并让 `registerFull(...)` 只专注于运行时专属工作。
|
||||
- 如果 `registerFull(...)` 同时注册 Gateway 网关 RPC 方法,请将它们保留在
|
||||
插件专用前缀下。保留的核心管理命名空间(`config.*`、
|
||||
`exec.approvals.*`、`wizard.*`、`update.*`)始终会被强制为
|
||||
`operator.admin`。
|
||||
- `setRuntime` 会在注册期间调用,这样你就可以保存运行时引用(通常通过 `createPluginRuntimeStore`)。在捕获 CLI 元数据期间会跳过它。
|
||||
- `registerCliMetadata` 会在 `api.registrationMode === "cli-metadata"`、`api.registrationMode === "discovery"` 和 `api.registrationMode === "full"` 时运行。
|
||||
将它作为渠道自有 CLI 描述符的规范位置,这样根帮助就不会激活插件,设备发现快照会包含静态命令元数据,而正常 CLI 命令注册也能与完整插件加载保持兼容。
|
||||
- 设备发现注册是非激活式的,而不是完全不导入。OpenClaw 可能会对受信任的插件入口和渠道插件模块求值,以构建快照,因此要保持顶层导入无副作用,并把套接字、客户端、worker 和服务放在仅 `"full"` 的路径后面。
|
||||
- `registerFull` 仅会在 `api.registrationMode === "full"` 时运行。在仅设置加载期间会跳过它。
|
||||
- 与 `definePluginEntry` 一样,`configSchema` 可以是延迟工厂,且 OpenClaw 会在首次访问时记忆已解析的 schema。
|
||||
- 对于插件自有的根 CLI 命令,如果你希望命令保持延迟加载,同时又不从根 CLI 解析树中消失,优先使用 `api.registerCli(..., { descriptors: [...] })`。对于渠道插件,优先在 `registerCliMetadata(...)` 中注册这些描述符,并让 `registerFull(...)` 专注于仅运行时工作。
|
||||
- 如果 `registerFull(...)` 还会注册 Gateway 网关 RPC 方法,请将它们保留在插件专属前缀下。保留的核心管理命名空间(`config.*`、`exec.approvals.*`、`wizard.*`、`update.*`)始终会被强制为 `operator.admin`。
|
||||
|
||||
## `defineSetupPluginEntry`
|
||||
|
||||
**导入:** `openclaw/plugin-sdk/channel-core`
|
||||
|
||||
用于轻量级的 `setup-entry.ts` 文件。它仅返回 `{ plugin }`,不包含
|
||||
运行时或 CLI 连接逻辑。
|
||||
用于轻量级的 `setup-entry.ts` 文件。它只返回 `{ plugin }`,不包含运行时或 CLI 接线逻辑。
|
||||
|
||||
```typescript
|
||||
import { defineSetupPluginEntry } from "openclaw/plugin-sdk/channel-core";
|
||||
@ -153,24 +132,17 @@ import { defineSetupPluginEntry } from "openclaw/plugin-sdk/channel-core";
|
||||
export default defineSetupPluginEntry(myChannelPlugin);
|
||||
```
|
||||
|
||||
当某个渠道被禁用、未配置,或启用了延迟加载时,OpenClaw 会加载这个入口而不是完整入口。请参阅
|
||||
[设置与配置](/zh-CN/plugins/sdk-setup#setup-entry) 了解其适用场景。
|
||||
当某个渠道被禁用、未配置,或启用了延迟加载时,OpenClaw 会加载它而不是完整入口。有关何时会出现这种情况,请参见 [设置和配置](/zh-CN/plugins/sdk-setup#setup-entry)。
|
||||
|
||||
在实践中,请将 `defineSetupPluginEntry(...)` 与以下狭义设置辅助工具家族搭配使用:
|
||||
在实际使用中,建议将 `defineSetupPluginEntry(...)` 与以下窄范围的设置辅助函数族搭配使用:
|
||||
|
||||
- `openclaw/plugin-sdk/setup-runtime`:用于运行时安全的设置辅助工具,例如
|
||||
可安全导入的设置补丁适配器、查找说明输出、
|
||||
`promptResolvedAllowFrom`、`splitSetupEntries` 和委托设置代理
|
||||
- `openclaw/plugin-sdk/setup-runtime`:用于运行时安全的设置辅助函数,例如导入安全的设置补丁适配器、查找说明输出、`promptResolvedAllowFrom`、`splitSetupEntries` 和委托式设置代理
|
||||
- `openclaw/plugin-sdk/channel-setup`:用于可选安装的设置界面
|
||||
- `openclaw/plugin-sdk/setup-tools`:用于设置 / 安装 CLI / 归档 / 文档辅助工具
|
||||
- `openclaw/plugin-sdk/setup-tools`:用于设置/安装 CLI、归档和文档辅助函数
|
||||
|
||||
请将重量级 SDK、CLI 注册器和长生命周期运行时服务保留在完整
|
||||
入口中。
|
||||
请将重量级 SDK、CLI 注册以及长生命周期运行时服务保留在完整入口中。
|
||||
|
||||
拆分设置与运行时界面的内置工作区渠道,可以改用
|
||||
`openclaw/plugin-sdk/channel-entry-contract` 中的
|
||||
`defineBundledChannelSetupEntry(...)`。该契约允许设置入口保留设置安全的 plugin / secrets 导出,同时仍暴露一个
|
||||
运行时 setter:
|
||||
拆分了设置面和运行时面的内置工作区渠道,可以改用来自 `openclaw/plugin-sdk/channel-entry-contract` 的 `defineBundledChannelSetupEntry(...)`。这个契约允许设置入口在暴露运行时 setter 的同时,仍然保留设置安全的插件/密钥导出:
|
||||
|
||||
```typescript
|
||||
import { defineBundledChannelSetupEntry } from "openclaw/plugin-sdk/channel-entry-contract";
|
||||
@ -188,26 +160,29 @@ export default defineBundledChannelSetupEntry({
|
||||
});
|
||||
```
|
||||
|
||||
仅当设置流程在完整渠道入口加载之前,确实需要一个轻量级运行时
|
||||
setter 时,才使用该内置契约。
|
||||
只有当设置流程确实需要在完整渠道入口加载之前,先使用一个轻量级运行时 setter 时,才使用这个内置契约。
|
||||
|
||||
## 注册模式
|
||||
|
||||
`api.registrationMode` 会告诉你的插件它是如何被加载的:
|
||||
|
||||
| 模式 | 何时使用 | 应注册什么 |
|
||||
| ----------------- | --------------------------------- | ----------------------------------------------------------------------------------------- |
|
||||
| `"full"` | 正常 Gateway 网关启动 | 全部内容 |
|
||||
| `"setup-only"` | 已禁用 / 未配置的渠道 | 仅渠道注册 |
|
||||
| `"setup-runtime"` | 设置流程中可用运行时 | 渠道注册,以及完整入口加载前所需的轻量级运行时 |
|
||||
| `"cli-metadata"` | 根帮助 / CLI 元数据捕获 | 仅 CLI 描述符 |
|
||||
| 模式 | 何时 | 应注册的内容 |
|
||||
| ----------------- | --------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
|
||||
| `"full"` | 正常 Gateway 网关启动 | 全部内容 |
|
||||
| `"discovery"` | 只读能力发现 | 渠道注册加静态 CLI 描述符;入口代码可能会加载,但要跳过套接字、worker、客户端和服务 |
|
||||
| `"setup-only"` | 渠道被禁用/未配置 | 仅渠道注册 |
|
||||
| `"setup-runtime"` | 设置流程且运行时可用 | 渠道注册,以及在完整入口加载前所需的轻量级运行时 |
|
||||
| `"cli-metadata"` | 根帮助 / CLI 元数据捕获 | 仅 CLI 描述符 |
|
||||
|
||||
`defineChannelPluginEntry` 会自动处理这种拆分。如果你为渠道直接使用
|
||||
`definePluginEntry`,则需要自己检查模式:
|
||||
`defineChannelPluginEntry` 会自动处理这个拆分。如果你对某个渠道直接使用 `definePluginEntry`,请自行检查模式:
|
||||
|
||||
```typescript
|
||||
register(api) {
|
||||
if (api.registrationMode === "cli-metadata" || api.registrationMode === "full") {
|
||||
if (
|
||||
api.registrationMode === "cli-metadata" ||
|
||||
api.registrationMode === "discovery" ||
|
||||
api.registrationMode === "full"
|
||||
) {
|
||||
api.registerCli(/* ... */);
|
||||
if (api.registrationMode === "cli-metadata") return;
|
||||
}
|
||||
@ -215,40 +190,39 @@ register(api) {
|
||||
api.registerChannel({ plugin: myPlugin });
|
||||
if (api.registrationMode !== "full") return;
|
||||
|
||||
// 仅运行时的重量级注册
|
||||
// Heavy runtime-only registrations
|
||||
api.registerService(/* ... */);
|
||||
}
|
||||
```
|
||||
|
||||
请将 `"setup-runtime"` 视为这样一个窗口:设置专用启动界面必须
|
||||
存在,但又不能重新进入完整内置渠道运行时。适合放在这里的有:
|
||||
渠道注册、设置安全的 HTTP 路由、设置安全的 Gateway 网关方法,以及
|
||||
委托设置辅助工具。重量级后台服务、CLI 注册器和
|
||||
提供商 / 客户端 SDK 启动仍然属于 `"full"`。
|
||||
设备发现模式会构建一个非激活式注册表快照。它仍然可能会对插件入口和渠道插件对象求值,以便 OpenClaw 注册渠道能力和静态 CLI 描述符。应将设备发现中的模块求值视为受信任但轻量:顶层不要包含网络客户端、子进程、监听器、数据库连接、后台 worker、凭证读取或其他实时运行时副作用。
|
||||
|
||||
对于 CLI 注册器,特别要注意:
|
||||
将 `"setup-runtime"` 视为这样一个窗口:仅设置阶段所需的启动面必须存在,但不能重新进入完整的内置渠道运行时。适合放在这里的内容包括渠道注册、设置安全的 HTTP 路由、设置安全的 Gateway 网关方法以及委托式设置辅助函数。重量级后台服务、CLI 注册器以及提供商/客户端 SDK 引导仍然应放在 `"full"` 中。
|
||||
|
||||
- 当注册器拥有一个或多个根命令,并且你希望 OpenClaw 在首次调用时惰性加载真实 CLI 模块时,请使用 `descriptors`
|
||||
- 请确保这些描述符覆盖该注册器暴露的每一个顶层命令根
|
||||
- 仅当你需要急切兼容路径时,才单独使用 `commands`
|
||||
具体到 CLI 注册器:
|
||||
|
||||
- 当注册器拥有一个或多个根命令,并且你希望 OpenClaw 在首次调用时再延迟加载真实 CLI 模块时,请使用 `descriptors`
|
||||
- 确保这些描述符覆盖注册器暴露的每个顶层命令根
|
||||
- 将描述符命令名称限制为字母、数字、连字符和下划线,并且必须以字母或数字开头;OpenClaw 会拒绝不符合该形状的描述符名称,并在渲染帮助前移除描述中的终端控制序列
|
||||
- 仅当需要急切兼容路径时,才单独使用 `commands`
|
||||
|
||||
## 插件形态
|
||||
|
||||
OpenClaw 会根据加载后插件的注册行为对其进行分类:
|
||||
OpenClaw 会根据已加载插件的注册行为对其进行分类:
|
||||
|
||||
| 形态 | 说明 |
|
||||
| --------------------- | -------------------------------------------------- |
|
||||
| **plain-capability** | 一种能力类型(例如仅提供商) |
|
||||
| **plain-capability** | 单一能力类型(例如仅提供商) |
|
||||
| **hybrid-capability** | 多种能力类型(例如提供商 + 语音) |
|
||||
| **hook-only** | 仅 hooks,没有能力 |
|
||||
| **non-capability** | 有工具 / 命令 / 服务,但没有能力 |
|
||||
| **hook-only** | 仅有钩子,没有能力 |
|
||||
| **non-capability** | 有工具/命令/服务,但没有能力 |
|
||||
|
||||
使用 `openclaw plugins inspect <id>` 可查看插件的形态。
|
||||
使用 `openclaw plugins inspect <id>` 查看插件的形态。
|
||||
|
||||
## 相关内容
|
||||
|
||||
- [SDK 概览](/zh-CN/plugins/sdk-overview) —— 注册 API 和子路径参考
|
||||
- [运行时辅助工具](/zh-CN/plugins/sdk-runtime) —— `api.runtime` 和 `createPluginRuntimeStore`
|
||||
- [设置与配置](/zh-CN/plugins/sdk-setup) —— manifest、setup entry、延迟加载
|
||||
- [运行时辅助函数](/zh-CN/plugins/sdk-runtime) —— `api.runtime` 和 `createPluginRuntimeStore`
|
||||
- [设置和配置](/zh-CN/plugins/sdk-setup) —— 清单、设置入口、延迟加载
|
||||
- [渠道插件](/zh-CN/plugins/sdk-channel-plugins) —— 构建 `ChannelPlugin` 对象
|
||||
- [提供商插件](/zh-CN/plugins/sdk-provider-plugins) —— 提供商注册与 hooks
|
||||
- [提供商插件](/zh-CN/plugins/sdk-provider-plugins) —— 提供商注册和钩子
|
||||
|
||||
@ -1,30 +1,30 @@
|
||||
---
|
||||
read_when:
|
||||
- 你想从 OpenClaw 发起一个呼出语音通话
|
||||
- 你想从 OpenClaw 发起一通外呼语音电话
|
||||
- 你正在配置或开发 voice-call 插件
|
||||
summary: Voice Call 插件:通过 Twilio/Telnyx/Plivo 进行呼出 + 呼入通话(插件安装 + 配置 + CLI)
|
||||
summary: Voice Call 插件:通过 Twilio / Telnyx / Plivo 进行外呼和来电(插件安装 + 配置 + CLI)
|
||||
title: Voice call 插件
|
||||
x-i18n:
|
||||
generated_at: "2026-04-24T22:14:45Z"
|
||||
generated_at: "2026-04-25T02:36:42Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: 1b033d9c46fa1af60c3ae2d22f8bad909ee179ef01926efca5b62b9f8a30375f
|
||||
source_hash: 2a498c1b34e8aa19a2a966560c95bf4593bbf844a6163831e933f33199ad848d
|
||||
source_path: plugins/voice-call.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
# Voice Call(插件)
|
||||
|
||||
通过插件为 OpenClaw 提供语音通话。支持呼出通知,以及带有呼入策略的多轮对话。
|
||||
通过插件为 OpenClaw 提供语音通话。支持外呼通知,以及带来电策略的多轮对话。
|
||||
|
||||
当前提供商:
|
||||
|
||||
- `twilio`(Programmable Voice + Media Streams)
|
||||
- `telnyx`(Call Control v2)
|
||||
- `plivo`(Voice API + XML transfer + GetInput speech)
|
||||
- `mock`(开发用/无网络)
|
||||
- `mock`(开发 / 无网络)
|
||||
|
||||
快速理解模型:
|
||||
快速心智模型:
|
||||
|
||||
- 安装插件
|
||||
- 重启 Gateway 网关
|
||||
@ -33,9 +33,9 @@ x-i18n:
|
||||
|
||||
## 运行位置(本地 vs 远程)
|
||||
|
||||
Voice Call 插件**运行在 Gateway 网关进程内部**。
|
||||
Voice Call 插件**运行在 Gateway 网关进程内**。
|
||||
|
||||
如果你使用远程 Gateway 网关,请在**运行 Gateway 网关的机器上**安装/配置该插件,然后重启 Gateway 网关以加载它。
|
||||
如果你使用远程 Gateway 网关,请在**运行 Gateway 网关的机器**上安装 / 配置该插件,然后重启 Gateway 网关以加载它。
|
||||
|
||||
## 安装
|
||||
|
||||
@ -47,7 +47,7 @@ openclaw plugins install @openclaw/voice-call
|
||||
|
||||
之后重启 Gateway 网关。
|
||||
|
||||
### 选项 B:从本地文件夹安装(开发用,不复制)
|
||||
### 选项 B:从本地文件夹安装(开发,无需复制)
|
||||
|
||||
```bash
|
||||
PLUGIN_SRC=./path/to/local/voice-call-plugin
|
||||
@ -69,7 +69,7 @@ cd "$PLUGIN_SRC" && pnpm install
|
||||
enabled: true,
|
||||
config: {
|
||||
provider: "twilio", // 或 "telnyx" | "plivo" | "mock"
|
||||
fromNumber: "+15550001234", // 或者对 Twilio 使用 TWILIO_FROM_NUMBER
|
||||
fromNumber: "+15550001234", // 或者 Twilio 的 TWILIO_FROM_NUMBER
|
||||
toNumber: "+15550005678",
|
||||
|
||||
twilio: {
|
||||
@ -96,13 +96,13 @@ cd "$PLUGIN_SRC" && pnpm install
|
||||
path: "/voice/webhook",
|
||||
},
|
||||
|
||||
// Webhook 安全性(建议用于隧道/代理)
|
||||
// Webhook 安全性(推荐用于 tunnel / proxy)
|
||||
webhookSecurity: {
|
||||
allowedHosts: ["voice.example.com"],
|
||||
trustedProxyIPs: ["100.64.0.1"],
|
||||
},
|
||||
|
||||
// 对外暴露(任选其一)
|
||||
// 公网暴露(任选其一)
|
||||
// publicUrl: "https://example.ngrok.app/voice/webhook",
|
||||
// tunnel: { provider: "ngrok" },
|
||||
// tailscale: { mode: "funnel", path: "/voice/webhook" }
|
||||
@ -113,11 +113,11 @@ cd "$PLUGIN_SRC" && pnpm install
|
||||
|
||||
streaming: {
|
||||
enabled: true,
|
||||
provider: "openai", // 可选;未设置时使用第一个已注册的实时转写提供商
|
||||
provider: "openai", // 可选;未设置时使用第一个已注册的实时转录提供商
|
||||
streamPath: "/voice/stream",
|
||||
providers: {
|
||||
openai: {
|
||||
apiKey: "sk-...", // 如果设置了 OPENAI_API_KEY,则可选
|
||||
apiKey: "sk-...", // 如果已设置 OPENAI_API_KEY,则可选
|
||||
model: "gpt-4o-transcribe",
|
||||
silenceDurationMs: 800,
|
||||
vadThreshold: 0.5,
|
||||
@ -147,29 +147,50 @@ cd "$PLUGIN_SRC" && pnpm install
|
||||
}
|
||||
```
|
||||
|
||||
说明:
|
||||
在使用真实提供商测试之前,先检查设置:
|
||||
|
||||
- Twilio/Telnyx 需要一个**可被公网访问**的 webhook URL。
|
||||
- Plivo 需要一个**可被公网访问**的 webhook URL。
|
||||
- `mock` 是一个本地开发提供商(不进行网络调用)。
|
||||
- 如果旧配置仍在使用 `provider: "log"`、`twilio.from` 或旧版 `streaming.*` OpenAI 键,请运行 `openclaw doctor --fix` 进行重写。
|
||||
- Telnyx 需要 `telnyx.publicKey`(或 `TELNYX_PUBLIC_KEY`),除非 `skipSignatureVerification` 为 true。
|
||||
```bash
|
||||
openclaw voicecall setup
|
||||
```
|
||||
|
||||
默认输出在聊天日志和终端会话中都易于阅读。它会检查插件是否已启用、提供商和凭证是否存在、webhook 暴露是否已配置,以及是否只启用了一个音频模式。脚本请使用 `openclaw voicecall setup --json`。
|
||||
|
||||
要进行一次无意外的 smoke test,请运行:
|
||||
|
||||
```bash
|
||||
openclaw voicecall smoke
|
||||
openclaw voicecall smoke --to "+15555550123"
|
||||
```
|
||||
|
||||
第二条命令仍然是 dry run。添加 `--yes` 可发起一通简短的外呼通知电话:
|
||||
|
||||
```bash
|
||||
openclaw voicecall smoke --to "+15555550123" --yes
|
||||
```
|
||||
|
||||
注意:
|
||||
|
||||
- Twilio / Telnyx 要求使用**公网可访问**的 webhook URL。
|
||||
- Plivo 要求使用**公网可访问**的 webhook URL。
|
||||
- `mock` 是本地开发提供商(无网络调用)。
|
||||
- 如果旧配置仍使用 `provider: "log"`、`twilio.from` 或旧版 `streaming.*` OpenAI 键,请运行 `openclaw doctor --fix` 进行重写。
|
||||
- 除非 `skipSignatureVerification` 为 true,否则 Telnyx 需要 `telnyx.publicKey`(或 `TELNYX_PUBLIC_KEY`)。
|
||||
- `skipSignatureVerification` 仅用于本地测试。
|
||||
- 如果你使用 ngrok 免费层,请将 `publicUrl` 设置为准确的 ngrok URL;签名校验始终会被强制执行。
|
||||
- `tunnel.allowNgrokFreeTierLoopbackBypass: true` 仅在 `tunnel.provider="ngrok"` 且 `serve.bind` 为 loopback(ngrok 本地代理)时,允许带有无效签名的 Twilio webhook。仅用于本地开发。
|
||||
- Ngrok 免费层 URL 可能会变化,或增加中间页行为;如果 `publicUrl` 漂移,Twilio 签名校验将失败。生产环境中,优先使用稳定域名或 Tailscale funnel。
|
||||
- 如果你使用 ngrok 免费套餐,请将 `publicUrl` 设置为确切的 ngrok URL;签名验证始终强制执行。
|
||||
- `tunnel.allowNgrokFreeTierLoopbackBypass: true` 仅会在 `tunnel.provider="ngrok"` 且 `serve.bind` 为 loopback(ngrok 本地代理)时,允许带有无效签名的 Twilio webhook。仅用于本地开发。
|
||||
- Ngrok 免费套餐 URL 可能会变化,或增加中间页行为;如果 `publicUrl` 漂移,Twilio 签名将验证失败。在生产环境中,优先使用稳定域名或 Tailscale funnel。
|
||||
- `realtime.enabled` 会启动完整的语音到语音对话;不要与 `streaming.enabled` 同时启用。
|
||||
- 流式传输安全默认值:
|
||||
- `streaming.preStartTimeoutMs` 会关闭那些从未发送有效 `start` 帧的 socket。
|
||||
- `streaming.maxPendingConnections` 限制未认证启动前 socket 的总数。
|
||||
- `streaming.maxPendingConnectionsPerIp` 限制每个源 IP 的未认证启动前 socket 数量。
|
||||
- `streaming.maxConnections` 限制已打开媒体流 socket 的总数(待启动 + 活跃)。
|
||||
- 运行时回退目前仍会接受这些旧版 voice-call 键,但重写路径是 `openclaw doctor --fix`,兼容垫片只是临时方案。
|
||||
- `streaming.maxPendingConnections` 限制未经认证的 pre-start socket 总数。
|
||||
- `streaming.maxPendingConnectionsPerIp` 限制每个源 IP 的未经认证 pre-start socket 数量。
|
||||
- `streaming.maxConnections` 限制已打开的媒体流 socket 总数(待启动 + 活跃)。
|
||||
- 运行时回退目前仍接受这些旧的 voice-call 键,但重写路径是 `openclaw doctor --fix`,兼容垫片只是临时性的。
|
||||
|
||||
## 实时语音对话
|
||||
|
||||
`realtime` 为实时通话音频选择一个全双工实时语音提供商。
|
||||
它与 `streaming` 分开,后者仅将音频转发给实时转写提供商。
|
||||
`realtime` 用于为实时通话音频选择一个全双工实时语音提供商。
|
||||
它与 `streaming` 分开,后者只会将音频转发给实时转录提供商。
|
||||
|
||||
当前运行时行为:
|
||||
|
||||
@ -177,20 +198,20 @@ cd "$PLUGIN_SRC" && pnpm install
|
||||
- `realtime.enabled` 不能与 `streaming.enabled` 同时使用。
|
||||
- `realtime.provider` 是可选的。未设置时,Voice Call 会使用第一个已注册的实时语音提供商。
|
||||
- 内置的实时语音提供商包括 Google Gemini Live(`google`)和 OpenAI(`openai`),由它们各自的提供商插件注册。
|
||||
- 提供商拥有的原始配置位于 `realtime.providers.<providerId>` 下。
|
||||
- 默认情况下,Voice Call 会暴露共享的 `openclaw_agent_consult` 实时工具。当来电者请求更深入的推理、当前信息或普通 OpenClaw 工具时,实时模型可以调用它。
|
||||
- 提供商自有的原始配置位于 `realtime.providers.<providerId>` 下。
|
||||
- Voice Call 默认暴露共享的 `openclaw_agent_consult` 实时工具。当来电者请求更深层的推理、当前信息或普通 OpenClaw 工具时,实时模型可以调用它。
|
||||
- `realtime.toolPolicy` 控制 consult 运行:
|
||||
- `safe-read-only`:暴露 consult 工具,并将常规智能体限制为使用 `read`、`web_search`、`web_fetch`、`x_search`、`memory_search` 和 `memory_get`。
|
||||
- `owner`:暴露 consult 工具,并允许常规智能体使用普通智能体工具策略。
|
||||
- `safe-read-only`:暴露 consult 工具,并将普通智能体限制为使用 `read`、`web_search`、`web_fetch`、`x_search`、`memory_search` 和 `memory_get`
|
||||
- `owner`:暴露 consult 工具,并允许普通智能体使用常规智能体工具策略
|
||||
- `none`:不暴露 consult 工具。自定义 `realtime.tools` 仍会传递给实时提供商。
|
||||
- Consult 会话键在可用时会复用现有语音会话,否则回退到主叫/被叫电话号码,以便后续 consult 调用在通话期间保持上下文。
|
||||
- 如果 `realtime.provider` 指向未注册的提供商,或者根本没有注册任何实时语音提供商,Voice Call 会记录一条警告,并跳过实时媒体,而不是让整个插件失败。
|
||||
- Consult 会话键会在可用时复用现有语音会话,否则回退到来电方 / 被叫方电话号码,以便后续 consult 调用在通话期间保持上下文。
|
||||
- 如果 `realtime.provider` 指向一个未注册的提供商,或者根本没有注册任何实时语音提供商,Voice Call 会记录警告,并跳过实时媒体,而不会让整个插件失败。
|
||||
|
||||
Google Gemini Live 实时默认值:
|
||||
|
||||
- API 密钥:`realtime.providers.google.apiKey`、`GEMINI_API_KEY` 或 `GOOGLE_GENERATIVE_AI_API_KEY`
|
||||
- 模型:`gemini-2.5-flash-native-audio-preview-12-2025`
|
||||
- 声音:`Kore`
|
||||
- API key:`realtime.providers.google.apiKey`、`GEMINI_API_KEY` 或 `GOOGLE_GENERATIVE_AI_API_KEY`
|
||||
- model:`gemini-2.5-flash-native-audio-preview-12-2025`
|
||||
- voice:`Kore`
|
||||
|
||||
示例:
|
||||
|
||||
@ -206,7 +227,7 @@ Google Gemini Live 实时默认值:
|
||||
realtime: {
|
||||
enabled: true,
|
||||
provider: "google",
|
||||
instructions: "简短说话。在使用更深层工具之前先调用 openclaw_agent_consult。",
|
||||
instructions: "Speak briefly. Call openclaw_agent_consult before using deeper tools.",
|
||||
toolPolicy: "safe-read-only",
|
||||
providers: {
|
||||
google: {
|
||||
@ -247,30 +268,30 @@ Google Gemini Live 实时默认值:
|
||||
}
|
||||
```
|
||||
|
||||
有关提供商特定的实时语音选项,请参阅 [Google provider](/zh-CN/providers/google) 和 [OpenAI provider](/zh-CN/providers/openai)。
|
||||
有关提供商特定的实时语音选项,请参见 [Google 提供商](/zh-CN/providers/google) 和 [OpenAI 提供商](/zh-CN/providers/openai)。
|
||||
|
||||
## 流式转写
|
||||
## 流式转录
|
||||
|
||||
`streaming` 为实时通话音频选择一个实时转写提供商。
|
||||
`streaming` 用于为实时通话音频选择一个实时转录提供商。
|
||||
|
||||
当前运行时行为:
|
||||
|
||||
- `streaming.provider` 是可选的。未设置时,Voice Call 会使用第一个已注册的实时转写提供商。
|
||||
- 内置的实时转写提供商包括 Deepgram(`deepgram`)、ElevenLabs(`elevenlabs`)、Mistral(`mistral`)、OpenAI(`openai`)和 xAI(`xai`),由它们各自的提供商插件注册。
|
||||
- 提供商拥有的原始配置位于 `streaming.providers.<providerId>` 下。
|
||||
- 如果 `streaming.provider` 指向未注册的提供商,或者根本没有注册任何实时转写提供商,Voice Call 会记录一条警告,并跳过媒体流传输,而不是让整个插件失败。
|
||||
- `streaming.provider` 是可选的。未设置时,Voice Call 会使用第一个已注册的实时转录提供商。
|
||||
- 内置的实时转录提供商包括 Deepgram(`deepgram`)、ElevenLabs(`elevenlabs`)、Mistral(`mistral`)、OpenAI(`openai`)和 xAI(`xai`),由它们各自的提供商插件注册。
|
||||
- 提供商自有的原始配置位于 `streaming.providers.<providerId>` 下。
|
||||
- 如果 `streaming.provider` 指向一个未注册的提供商,或者根本没有注册任何实时转录提供商,Voice Call 会记录警告,并跳过媒体流,而不会让整个插件失败。
|
||||
|
||||
OpenAI 流式转写默认值:
|
||||
OpenAI 流式转录默认值:
|
||||
|
||||
- API 密钥:`streaming.providers.openai.apiKey` 或 `OPENAI_API_KEY`
|
||||
- 模型:`gpt-4o-transcribe`
|
||||
- API key:`streaming.providers.openai.apiKey` 或 `OPENAI_API_KEY`
|
||||
- model:`gpt-4o-transcribe`
|
||||
- `silenceDurationMs`:`800`
|
||||
- `vadThreshold`:`0.5`
|
||||
|
||||
xAI 流式转写默认值:
|
||||
xAI 流式转录默认值:
|
||||
|
||||
- API 密钥:`streaming.providers.xai.apiKey` 或 `XAI_API_KEY`
|
||||
- 端点:`wss://api.x.ai/v1/stt`
|
||||
- API key:`streaming.providers.xai.apiKey` 或 `XAI_API_KEY`
|
||||
- endpoint:`wss://api.x.ai/v1/stt`
|
||||
- `encoding`:`mulaw`
|
||||
- `sampleRate`:`8000`
|
||||
- `endpointingMs`:`800`
|
||||
@ -290,7 +311,7 @@ xAI 流式转写默认值:
|
||||
streamPath: "/voice/stream",
|
||||
providers: {
|
||||
openai: {
|
||||
apiKey: "sk-...", // 如果设置了 OPENAI_API_KEY,则可选
|
||||
apiKey: "sk-...", // 如果已设置 OPENAI_API_KEY,则可选
|
||||
model: "gpt-4o-transcribe",
|
||||
silenceDurationMs: 800,
|
||||
vadThreshold: 0.5,
|
||||
@ -318,7 +339,7 @@ xAI 流式转写默认值:
|
||||
streamPath: "/voice/stream",
|
||||
providers: {
|
||||
xai: {
|
||||
apiKey: "${XAI_API_KEY}", // 如果设置了 XAI_API_KEY,则可选
|
||||
apiKey: "${XAI_API_KEY}", // 如果已设置 XAI_API_KEY,则可选
|
||||
endpointingMs: 800,
|
||||
language: "en",
|
||||
},
|
||||
@ -331,7 +352,7 @@ xAI 流式转写默认值:
|
||||
}
|
||||
```
|
||||
|
||||
旧版键仍会由 `openclaw doctor --fix` 自动迁移:
|
||||
旧键仍可通过 `openclaw doctor --fix` 自动迁移:
|
||||
|
||||
- `streaming.sttProvider` → `streaming.provider`
|
||||
- `streaming.openaiApiKey` → `streaming.providers.openai.apiKey`
|
||||
@ -341,14 +362,14 @@ xAI 流式转写默认值:
|
||||
|
||||
## 过期通话清理器
|
||||
|
||||
使用 `staleCallReaperSeconds` 结束那些从未收到终止 webhook 的通话
|
||||
(例如,永远没有完成的通知模式通话)。默认值为 `0`
|
||||
使用 `staleCallReaperSeconds` 可结束那些从未收到终止 webhook 的通话
|
||||
(例如永远未完成的通知模式通话)。默认值为 `0`
|
||||
(禁用)。
|
||||
|
||||
推荐范围:
|
||||
|
||||
- **生产环境:** 对于通知风格流程,使用 `120`–`300` 秒。
|
||||
- 保持该值**高于 `maxDurationSeconds`**,以便正常通话能够完成。一个不错的起始值是 `maxDurationSeconds + 30–60` 秒。
|
||||
- **生产环境:** 对于通知型流程,使用 `120`–`300` 秒。
|
||||
- 请将该值保持为**高于 `maxDurationSeconds`**,以便正常通话能够结束。一个不错的起点是 `maxDurationSeconds + 30–60` 秒。
|
||||
|
||||
示例:
|
||||
|
||||
@ -369,21 +390,21 @@ xAI 流式转写默认值:
|
||||
|
||||
## Webhook 安全性
|
||||
|
||||
当 Gateway 网关前面有代理或隧道时,插件会重建用于签名校验的公网 URL。这些选项用于控制信任哪些转发头。
|
||||
当 Gateway 网关前面有 proxy 或 tunnel 时,插件会重建公网 URL 以进行签名验证。这些选项用于控制信任哪些转发头。
|
||||
|
||||
`webhookSecurity.allowedHosts` 对来自转发头的主机进行允许列表控制。
|
||||
`webhookSecurity.allowedHosts` 会将转发头中的主机加入 allowlist。
|
||||
|
||||
`webhookSecurity.trustForwardingHeaders` 在没有允许列表的情况下信任转发头。
|
||||
`webhookSecurity.trustForwardingHeaders` 会在没有 allowlist 的情况下信任转发头。
|
||||
|
||||
`webhookSecurity.trustedProxyIPs` 仅在请求的远程 IP 与列表匹配时,才信任转发头。
|
||||
只有当请求的远端 IP 与列表匹配时,`webhookSecurity.trustedProxyIPs` 才会信任转发头。
|
||||
|
||||
Twilio 和 Plivo 已启用 webhook 重放保护。被重放的有效 webhook 请求会被确认接收,但会跳过副作用处理。
|
||||
Twilio 和 Plivo 启用了 webhook 重放保护。被重放的有效 webhook 请求会被确认,但会跳过副作用处理。
|
||||
|
||||
Twilio 对话轮次会在 `<Gather>` 回调中包含每轮专属 token,因此过期/重放的语音回调无法满足较新的待处理转写轮次。
|
||||
Twilio 对话轮次在 `<Gather>` 回调中包含每轮唯一的 token,因此过期 / 重放的语音回调无法满足较新的待处理转录轮次。
|
||||
|
||||
当提供商要求的签名头缺失时,未认证的 webhook 请求会在读取 body 之前被拒绝。
|
||||
当缺少提供商要求的签名头时,未经认证的 webhook 请求会在读取请求体之前被拒绝。
|
||||
|
||||
voice-call webhook 在签名校验前使用共享的预认证 body 配置文件(64 KB / 5 秒),并带有按 IP 限制的进行中请求上限。
|
||||
voice-call webhook 在签名验证前使用共享的预认证请求体配置(64 KB / 5 秒),并带有按 IP 限制的进行中请求上限。
|
||||
|
||||
使用稳定公网主机的示例:
|
||||
|
||||
@ -406,7 +427,7 @@ voice-call webhook 在签名校验前使用共享的预认证 body 配置文件
|
||||
|
||||
## 通话的 TTS
|
||||
|
||||
Voice Call 对通话中的流式语音使用核心 `messages.tts` 配置。你可以在插件配置下使用**相同结构**覆盖它——它会与 `messages.tts` 进行深度合并。
|
||||
Voice Call 在通话中使用核心 `messages.tts` 配置来进行流式语音播放。你可以在插件配置下用**相同的结构**覆盖它 —— 它会与 `messages.tts` 进行深度合并。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -422,12 +443,12 @@ Voice Call 对通话中的流式语音使用核心 `messages.tts` 配置。你
|
||||
}
|
||||
```
|
||||
|
||||
说明:
|
||||
注意:
|
||||
|
||||
- 插件配置中的旧版 `tts.<provider>` 键(`openai`、`elevenlabs`、`microsoft`、`edge`)会在加载时自动迁移到 `tts.providers.<provider>`。提交到配置文件时,优先使用 `providers` 结构。
|
||||
- **Microsoft speech 会被语音通话忽略**(电话音频需要 PCM;当前的 Microsoft 传输不提供电话用 PCM 输出)。
|
||||
- 当启用 Twilio 媒体流时,会使用核心 TTS;否则通话会回退到提供商原生语音。
|
||||
- 如果 Twilio 媒体流已经处于活动状态,Voice Call 不会回退到 TwiML `<Say>`。如果该状态下电话 TTS 不可用,播放请求会失败,而不是混用两条播放路径。
|
||||
- 插件配置中的旧版 `tts.<provider>` 键(`openai`、`elevenlabs`、`microsoft`、`edge`)会在加载时自动迁移到 `tts.providers.<provider>`。提交到配置中的内容应优先使用 `providers` 结构。
|
||||
- **Microsoft 语音会被语音通话忽略**(电话音频需要 PCM;当前 Microsoft 传输不暴露电话 PCM 输出)。
|
||||
- 启用 Twilio 媒体流时会使用核心 TTS;否则通话会回退到提供商原生语音。
|
||||
- 如果某个 Twilio 媒体流已经处于活动状态,Voice Call 不会回退到 TwiML `<Say>`。如果该状态下电话 TTS 不可用,则播放请求会失败,而不是混用两条播放路径。
|
||||
- 当电话 TTS 回退到次级提供商时,Voice Call 会记录一条带有提供商链(`from`、`to`、`attempts`)的警告,便于调试。
|
||||
|
||||
### 更多示例
|
||||
@ -447,7 +468,7 @@ Voice Call 对通话中的流式语音使用核心 `messages.tts` 配置。你
|
||||
}
|
||||
```
|
||||
|
||||
仅为通话覆盖为 ElevenLabs(其他地方保留核心默认值):
|
||||
仅为通话覆盖到 ElevenLabs(其他地方保留核心默认值):
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -495,61 +516,61 @@ Voice Call 对通话中的流式语音使用核心 `messages.tts` 配置。你
|
||||
}
|
||||
```
|
||||
|
||||
## 呼入通话
|
||||
## 来电
|
||||
|
||||
呼入策略默认为 `disabled`。要启用呼入通话,请设置:
|
||||
来电策略默认是 `disabled`。要启用来电,请设置:
|
||||
|
||||
```json5
|
||||
{
|
||||
inboundPolicy: "allowlist",
|
||||
allowFrom: ["+15550001234"],
|
||||
inboundGreeting: "你好!我能帮你什么?",
|
||||
inboundGreeting: "Hello! How can I help?",
|
||||
}
|
||||
```
|
||||
|
||||
`inboundPolicy: "allowlist"` 是一种低保障级别的来电显示筛选。插件会规范化提供商给出的 `From` 值,并将其与 `allowFrom` 进行比较。Webhook 校验可以验证提供商投递和负载完整性,但不能证明 PSTN/VoIP 来电号码的实际归属。请将 `allowFrom` 视为来电显示过滤,而不是强身份认证。
|
||||
`inboundPolicy: "allowlist"` 是一种低保障的来电号码筛选。插件会规范化提供商提供的 `From` 值,并将其与 `allowFrom` 进行比较。webhook 验证可以认证提供商投递和负载完整性,但不能证明 PSTN / VoIP 来电号码的归属权。应将 `allowFrom` 视为来电显示过滤,而不是强来电身份认证。
|
||||
|
||||
自动响应使用智能体系统。可通过以下参数调优:
|
||||
自动响应使用智能体系统。可通过以下项进行调优:
|
||||
|
||||
- `responseModel`
|
||||
- `responseSystemPrompt`
|
||||
- `responseTimeoutMs`
|
||||
|
||||
### 语音输出契约
|
||||
### 口语输出契约
|
||||
|
||||
对于自动响应,Voice Call 会在系统提示词后附加一个严格的语音输出契约:
|
||||
对于自动响应,Voice Call 会在系统提示词后附加一个严格的口语输出契约:
|
||||
|
||||
- `{"spoken":"..."}`
|
||||
|
||||
随后 Voice Call 会以防御性方式提取语音文本:
|
||||
随后,Voice Call 会以防御性方式提取语音文本:
|
||||
|
||||
- 忽略被标记为推理/错误内容的负载。
|
||||
- 忽略被标记为推理 / 错误内容的负载。
|
||||
- 解析直接 JSON、带围栏的 JSON 或内联 `"spoken"` 键。
|
||||
- 回退到纯文本,并移除可能属于规划/元信息引导段落的内容。
|
||||
- 回退为纯文本,并移除可能是规划 / 元信息引导段落的内容。
|
||||
|
||||
这样可以让语音播放聚焦于面向来电者的文本,并避免把规划文本泄露到音频中。
|
||||
这样可让语音播放专注于面向来电者的文本,并避免将规划文本泄露到音频中。
|
||||
|
||||
### 对话启动行为
|
||||
|
||||
对于呼出的 `conversation` 通话,首条消息处理与实时播放状态绑定:
|
||||
对于外呼 `conversation` 通话,首条消息处理与实时播放状态绑定:
|
||||
|
||||
- 仅当初始问候正在主动播报时,才会抑制打断队列清空和自动响应。
|
||||
- 如果初始播放失败,通话会返回 `listening`,初始消息会保留在队列中以便重试。
|
||||
- Twilio 流式传输的初始播放会在流连接建立时立即开始,不会额外延迟。
|
||||
- 实时语音对话使用实时流自身的开场轮次。Voice Call 不会为该初始消息发送旧版 `<Say>` TwiML 更新,因此呼出的 `<Connect><Stream>` 会话会保持附着。
|
||||
- 仅当初始问候正在主动播报时,才会抑制打断清队和自动响应。
|
||||
- 如果初始播放失败,通话会返回 `listening`,初始消息会保留在队列中以供重试。
|
||||
- 对于 Twilio 流式传输,初始播放会在流连接建立后立即开始,无额外延迟。
|
||||
- 实时语音对话使用实时流自身的开场轮次。Voice Call 不会为该初始消息再发送旧版 `<Say>` TwiML 更新,因此外呼 `<Connect><Stream>` 会话会保持附着。
|
||||
|
||||
### Twilio 流断开宽限期
|
||||
|
||||
当 Twilio 媒体流断开时,Voice Call 会等待 `2000ms`,然后才自动结束通话:
|
||||
|
||||
- 如果流在此窗口期间重新连接,则会取消自动结束。
|
||||
- 如果宽限期过后仍未重新注册任何流,则会结束通话,以防止活跃通话卡住。
|
||||
- 如果流在此窗口内重新连接,则会取消自动结束。
|
||||
- 如果在宽限期后仍未重新注册任何流,则会结束该通话,以防止通话卡在活动状态。
|
||||
|
||||
## CLI
|
||||
|
||||
```bash
|
||||
openclaw voicecall call --to "+15555550123" --message "Hello from OpenClaw"
|
||||
openclaw voicecall start --to "+15555550123" # `call` 的别名
|
||||
openclaw voicecall start --to "+15555550123" # call 的别名
|
||||
openclaw voicecall continue --call-id <id> --message "Any questions?"
|
||||
openclaw voicecall speak --call-id <id> --message "One moment"
|
||||
openclaw voicecall dtmf --call-id <id> --digits "ww123456#"
|
||||
@ -560,13 +581,14 @@ openclaw voicecall latency # 从日志汇总轮次延迟
|
||||
openclaw voicecall expose --mode funnel
|
||||
```
|
||||
|
||||
`latency` 会从默认的 voice-call 存储路径读取 `calls.jsonl`。使用 `--file <path>` 指向其他日志文件,并使用 `--last <n>` 将分析限制为最后 N 条记录(默认 200)。输出包含轮次延迟和监听等待时间的 p50/p90/p99。
|
||||
`latency` 会从默认的 voice-call 存储路径读取 `calls.jsonl`。使用
|
||||
`--file <path>` 可指向其他日志,使用 `--last <n>` 可将分析限制为最后 N 条记录(默认 200)。输出包括轮次延迟和监听等待时间的 p50 / p90 / p99。
|
||||
|
||||
## 智能体工具
|
||||
|
||||
工具名称:`voice_call`
|
||||
|
||||
操作:
|
||||
动作:
|
||||
|
||||
- `initiate_call`(message、to?、mode?)
|
||||
- `continue_call`(callId、message)
|
||||
@ -575,7 +597,7 @@ openclaw voicecall expose --mode funnel
|
||||
- `end_call`(callId)
|
||||
- `get_status`(callId)
|
||||
|
||||
此仓库附带对应的 skill 文档,位于 `skills/voice-call/SKILL.md`。
|
||||
此仓库在 `skills/voice-call/SKILL.md` 中附带了一份对应的 skill 文档。
|
||||
|
||||
## Gateway 网关 RPC
|
||||
|
||||
@ -588,6 +610,6 @@ openclaw voicecall expose --mode funnel
|
||||
|
||||
## 相关内容
|
||||
|
||||
- [Text-to-speech](/zh-CN/tools/tts)
|
||||
- [Talk mode](/zh-CN/nodes/talk)
|
||||
- [Voice wake](/zh-CN/nodes/voicewake)
|
||||
- [文本转语音](/zh-CN/tools/tts)
|
||||
- [通话模式](/zh-CN/nodes/talk)
|
||||
- [语音唤醒](/zh-CN/nodes/voicewake)
|
||||
|
||||
@ -6,74 +6,73 @@ read_when:
|
||||
summary: 在 OpenClaw 中通过 API 密钥或 Codex 订阅使用 OpenAI
|
||||
title: OpenAI
|
||||
x-i18n:
|
||||
generated_at: "2026-04-25T00:43:55Z"
|
||||
generated_at: "2026-04-25T02:37:07Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: 281ea7705763053b7038159035867b54e7255dc01136c54bfb7c68b5cc34cab1
|
||||
source_hash: 095452c94074c628352a4c33a41c4c2a708e36124bd1aaf172927c60e167f6a7
|
||||
source_path: providers/openai.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
OpenAI 提供 GPT 模型的开发者 API。OpenClaw 支持三种 OpenAI 系列路由。模型前缀决定所使用的路由:
|
||||
OpenAI 为 GPT 模型提供开发者 API。OpenClaw 支持三种 OpenAI 系列接入路径。模型前缀决定所走的路径:
|
||||
|
||||
- **API 密钥** — 通过直接 OpenAI Platform 访问,按使用量计费(`openai/*` 模型)
|
||||
- **通过 PI 使用 Codex 订阅** — 使用 ChatGPT/Codex 登录并通过订阅访问(`openai-codex/*` 模型)
|
||||
- **Codex app-server harness** — 原生 Codex app-server 执行(`openai/*` 模型,加上 `agents.defaults.embeddedHarness.runtime: "codex"`)
|
||||
- **API 密钥** —— 通过 OpenAI Platform 直接访问,并按使用量计费(`openai/*` 模型)
|
||||
- **通过 PI 的 Codex 订阅** —— 使用 ChatGPT/Codex 登录并通过订阅访问(`openai-codex/*` 模型)
|
||||
- **Codex app-server harness** —— 原生 Codex app-server 执行(`openai/*` 模型,并配合 `agents.defaults.embeddedHarness.runtime: "codex"`)
|
||||
|
||||
OpenAI 明确支持在像 OpenClaw 这样的外部工具和工作流中使用订阅 OAuth。
|
||||
OpenAI 明确支持在 OpenClaw 这类外部工具和工作流中使用订阅 OAuth。
|
||||
|
||||
## 快速选择
|
||||
|
||||
| 目标 | 使用方式 | 说明 |
|
||||
| --------------------------------------------- | -------------------------------------------------------- | ---------------------------------------------------------------------------- |
|
||||
| 直接 API 密钥计费 | `openai/gpt-5.4` | 设置 `OPENAI_API_KEY` 或运行 OpenAI API 密钥新手引导。 |
|
||||
| 使用 ChatGPT/Codex 订阅认证的 GPT-5.5 | `openai-codex/gpt-5.5` | Codex OAuth 的默认 PI 路由。对于订阅配置,这是最佳首选。 |
|
||||
| 使用原生 Codex app-server 行为的 GPT-5.5 | `openai/gpt-5.5` 加 `embeddedHarness.runtime: "codex"` | 使用 Codex app-server harness,而不是公共 OpenAI API 路由。 |
|
||||
| 直接使用 API 密钥计费 | `openai/gpt-5.4` | 设置 `OPENAI_API_KEY`,或运行 OpenAI API 密钥新手引导。 |
|
||||
| 使用 ChatGPT/Codex 订阅认证的 GPT-5.5 | `openai-codex/gpt-5.5` | Codex OAuth 的默认 PI 路径。是订阅场景下的首选。 |
|
||||
| 使用原生 Codex app-server 行为的 GPT-5.5 | `openai/gpt-5.5` 加 `embeddedHarness.runtime: "codex"` | 使用 Codex app-server harness,而不是公共 OpenAI API 路径。 |
|
||||
| 图像生成或编辑 | `openai/gpt-image-2` | 可搭配 `OPENAI_API_KEY` 或 OpenAI Codex OAuth 使用。 |
|
||||
|
||||
<Note>
|
||||
GPT-5.5 目前在 OpenClaw 中通过订阅/OAuth 路由提供:
|
||||
使用 PI 运行器的 `openai-codex/gpt-5.5`,或配合
|
||||
Codex app-server harness 的 `openai/gpt-5.5`。`openai/gpt-5.5` 的
|
||||
直连 API 密钥访问会在 OpenAI 为公共 API 启用 GPT-5.5 后受支持;
|
||||
在此之前,`OPENAI_API_KEY` 配置请使用已启用 API 的模型,例如 `openai/gpt-5.4`。
|
||||
GPT-5.5 当前在 OpenClaw 中可通过订阅/OAuth 路径使用:
|
||||
使用 PI 运行器时为 `openai-codex/gpt-5.5`,使用
|
||||
Codex app-server harness 时为 `openai/gpt-5.5`。对于 `openai/gpt-5.5` 的直接 API 密钥访问,
|
||||
要等 OpenAI 在公共 API 上开放 GPT-5.5 后才支持;在此之前,
|
||||
对于 `OPENAI_API_KEY` 配置,请使用已启用 API 的模型,例如 `openai/gpt-5.4`。
|
||||
</Note>
|
||||
|
||||
<Note>
|
||||
启用 OpenAI 插件,或选择 `openai-codex/*` 模型,并不会
|
||||
启用内置的 Codex app-server 插件。OpenClaw 仅会在你显式选择
|
||||
原生 Codex harness,即设置
|
||||
`embeddedHarness.runtime: "codex"` 或使用旧版 `codex/*` 模型引用时,
|
||||
才启用该插件。
|
||||
启用内置的 Codex app-server 插件。只有当你显式选择原生 Codex harness,
|
||||
即设置 `embeddedHarness.runtime: "codex"`,或使用旧版 `codex/*` 模型引用时,
|
||||
OpenClaw 才会启用该插件。
|
||||
</Note>
|
||||
|
||||
## OpenClaw 功能覆盖范围
|
||||
|
||||
| OpenAI 能力 | OpenClaw 接口 | 状态 |
|
||||
| OpenAI 能力 | OpenClaw 表面 | 状态 |
|
||||
| ------------------------- | ---------------------------------------------------------- | ------------------------------------------------------ |
|
||||
| 聊天 / Responses | `openai/<model>` 模型提供商 | 是 |
|
||||
| Codex 订阅模型 | 使用 `openai-codex` OAuth 的 `openai-codex/<model>` | 是 |
|
||||
| Codex app-server harness | 使用 `embeddedHarness.runtime: codex` 的 `openai/<model>` | 是 |
|
||||
| 服务端 Web 搜索 | 原生 OpenAI Responses 工具 | 是,启用 Web 搜索且未固定提供商时 |
|
||||
| 图像 | `image_generate` | 是 |
|
||||
| 视频 | `video_generate` | 是 |
|
||||
| 文本转语音 | `messages.tts.provider: "openai"` / `tts` | 是 |
|
||||
| 批量语音转文本 | `tools.media.audio` / 媒体理解 | 是 |
|
||||
| 流式语音转文本 | Voice Call `streaming.provider: "openai"` | 是 |
|
||||
| 实时语音 | Voice Call `realtime.provider: "openai"` / Control UI Talk | 是 |
|
||||
| Embeddings | memory embedding provider | 是 |
|
||||
| 聊天 / Responses | `openai/<model>` 模型提供商 | 支持 |
|
||||
| Codex 订阅模型 | `openai-codex/<model>` 配合 `openai-codex` OAuth | 支持 |
|
||||
| Codex app-server harness | `openai/<model>` 配合 `embeddedHarness.runtime: codex` | 支持 |
|
||||
| 服务端网页搜索 | 原生 OpenAI Responses 工具 | 支持,在启用网页搜索且未固定 provider 时 |
|
||||
| 图像 | `image_generate` | 支持 |
|
||||
| 视频 | `video_generate` | 支持 |
|
||||
| 文本转语音 | `messages.tts.provider: "openai"` / `tts` | 支持 |
|
||||
| 批量语音转文本 | `tools.media.audio` / 媒体理解 | 支持 |
|
||||
| 流式语音转文本 | Voice Call `streaming.provider: "openai"` | 支持 |
|
||||
| 实时语音 | Voice Call `realtime.provider: "openai"` / Control UI Talk | 支持 |
|
||||
| Embeddings | 记忆 embedding 提供商 | 支持 |
|
||||
|
||||
## 入门指南
|
||||
|
||||
选择你偏好的认证方式,并按照设置步骤操作。
|
||||
选择你偏好的认证方式,并按照设置步骤进行。
|
||||
|
||||
<Tabs>
|
||||
<Tab title="API 密钥(OpenAI Platform)">
|
||||
**最适合:** 直接 API 访问和按使用量计费。
|
||||
**最适合:** 直接 API 访问和按量计费。
|
||||
|
||||
<Steps>
|
||||
<Step title="获取你的 API 密钥">
|
||||
在 [OpenAI Platform 控制台](https://platform.openai.com/api-keys) 中创建或复制一个 API 密钥。
|
||||
在 [OpenAI Platform dashboard](https://platform.openai.com/api-keys) 创建或复制一个 API 密钥。
|
||||
</Step>
|
||||
<Step title="运行新手引导">
|
||||
```bash
|
||||
@ -93,17 +92,17 @@ Codex app-server harness 的 `openai/gpt-5.5`。`openai/gpt-5.5` 的
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
### 路由概览
|
||||
### 路径摘要
|
||||
|
||||
| 模型引用 | 路由 | 认证 |
|
||||
| 模型引用 | 路径 | 认证 |
|
||||
|-----------|-------|------|
|
||||
| `openai/gpt-5.4` | 直连 OpenAI Platform API | `OPENAI_API_KEY` |
|
||||
| `openai/gpt-5.4-mini` | 直连 OpenAI Platform API | `OPENAI_API_KEY` |
|
||||
| `openai/gpt-5.5` | OpenAI 在 API 中启用 GPT-5.5 后的未来直连 API 路由 | `OPENAI_API_KEY` |
|
||||
| `openai/gpt-5.4` | 直接 OpenAI Platform API | `OPENAI_API_KEY` |
|
||||
| `openai/gpt-5.4-mini` | 直接 OpenAI Platform API | `OPENAI_API_KEY` |
|
||||
| `openai/gpt-5.5` | 一旦 OpenAI 在 API 上开放 GPT-5.5 后的未来直接 API 路径 | `OPENAI_API_KEY` |
|
||||
|
||||
<Note>
|
||||
除非你显式强制使用 Codex app-server harness,否则 `openai/*`
|
||||
走的是直连 OpenAI API 密钥路由。GPT-5.5 目前本身仅支持订阅/OAuth;
|
||||
`openai/*` 默认是直接 OpenAI API 密钥路径,除非你显式强制使用
|
||||
Codex app-server harness。GPT-5.5 当前本身仅支持订阅/OAuth;
|
||||
对于通过默认 PI 运行器使用 Codex OAuth,请使用 `openai-codex/*`。
|
||||
</Note>
|
||||
|
||||
@ -117,13 +116,13 @@ Codex app-server harness 的 `openai/gpt-5.5`。`openai/gpt-5.5` 的
|
||||
```
|
||||
|
||||
<Warning>
|
||||
OpenClaw **不会**暴露 `openai/gpt-5.3-codex-spark`。实时 OpenAI API 请求会拒绝该模型,而当前 Codex 目录也未公开它。
|
||||
OpenClaw **不**暴露 `openai/gpt-5.3-codex-spark`。实时 OpenAI API 请求会拒绝该模型,当前 Codex 目录也没有暴露它。
|
||||
</Warning>
|
||||
|
||||
</Tab>
|
||||
|
||||
<Tab title="Codex 订阅">
|
||||
**最适合:** 使用你的 ChatGPT/Codex 订阅,而不是单独的 API 密钥。Codex 云端需要 ChatGPT 登录。
|
||||
**最适合:** 使用你的 ChatGPT/Codex 订阅,而不是单独的 API 密钥。Codex cloud 需要 ChatGPT 登录。
|
||||
|
||||
<Steps>
|
||||
<Step title="运行 Codex OAuth">
|
||||
@ -137,7 +136,7 @@ Codex app-server harness 的 `openai/gpt-5.5`。`openai/gpt-5.5` 的
|
||||
openclaw models auth login --provider openai-codex
|
||||
```
|
||||
|
||||
对于无头环境或不便使用回调的配置,可添加 `--device-code`,通过 ChatGPT device-code 流程登录,而不是使用 localhost 浏览器回调:
|
||||
对于无头环境或不适合回调主机的场景,可添加 `--device-code`,通过 ChatGPT device-code 流程登录,而不是使用 localhost 浏览器回调:
|
||||
|
||||
```bash
|
||||
openclaw models auth login --provider openai-codex --device-code
|
||||
@ -155,16 +154,16 @@ Codex app-server harness 的 `openai/gpt-5.5`。`openai/gpt-5.5` 的
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
### 路由概览
|
||||
### 路径摘要
|
||||
|
||||
| 模型引用 | 路由 | 认证 |
|
||||
| 模型引用 | 路径 | 认证 |
|
||||
|-----------|-------|------|
|
||||
| `openai-codex/gpt-5.5` | 通过 PI 使用 ChatGPT/Codex OAuth | Codex 登录 |
|
||||
| `openai-codex/gpt-5.5` | 通过 PI 的 ChatGPT/Codex OAuth | Codex 登录 |
|
||||
| `openai/gpt-5.5` + `embeddedHarness.runtime: "codex"` | Codex app-server harness | Codex app-server 认证 |
|
||||
|
||||
<Note>
|
||||
对于认证/配置文件命令,请继续使用 `openai-codex` 提供商 id。
|
||||
`openai-codex/*` 模型前缀也是 Codex OAuth 的显式 PI 路由。
|
||||
对于认证/配置文件命令,请继续使用 `openai-codex` provider id。
|
||||
`openai-codex/*` 模型前缀也是 Codex OAuth 明确对应的 PI 路径。
|
||||
它不会选择或自动启用内置的 Codex app-server harness。
|
||||
</Note>
|
||||
|
||||
@ -177,27 +176,27 @@ Codex app-server harness 的 `openai/gpt-5.5`。`openai/gpt-5.5` 的
|
||||
```
|
||||
|
||||
<Note>
|
||||
新手引导不再从 `~/.codex` 导入 OAuth 材料。请通过浏览器 OAuth(默认)或上面的 device-code 流程登录——OpenClaw 会在自己的智能体认证存储中管理所得凭证。
|
||||
新手引导不再从 `~/.codex` 导入 OAuth 材料。请使用浏览器 OAuth(默认)或上面的 device-code 流程登录 —— OpenClaw 会在它自己的智能体认证存储中管理生成的凭证。
|
||||
</Note>
|
||||
|
||||
### 状态指示器
|
||||
|
||||
聊天中的 `/status` 会显示当前会话正在使用哪个模型运行时。
|
||||
默认 PI harness 显示为 `Runtime: OpenClaw Pi Default`。当选择
|
||||
聊天中的 `/status` 会显示当前会话正在使用的模型运行时。
|
||||
默认 PI harness 会显示为 `Runtime: OpenClaw Pi Default`。当选择
|
||||
内置 Codex app-server harness 时,`/status` 会显示
|
||||
`Runtime: OpenAI Codex`。现有会话会保留其已记录的 harness id,因此如果你在更改 `embeddedHarness` 后希望 `/status` 反映新的 PI/Codex 选择,请使用
|
||||
`/new` 或 `/reset`。
|
||||
`Runtime: OpenAI Codex`。现有会话会保留其记录的 harness id,因此如果你更改了 `embeddedHarness` 后希望 `/status`
|
||||
反映新的 PI/Codex 选择,请使用 `/new` 或 `/reset`。
|
||||
|
||||
### 上下文窗口上限
|
||||
|
||||
OpenClaw 将模型元数据和运行时上下文上限视为两个独立值。
|
||||
OpenClaw 将模型元数据和运行时上下文上限视为两个不同的值。
|
||||
|
||||
对于通过 Codex OAuth 使用的 `openai-codex/gpt-5.5`:
|
||||
|
||||
- 原生 `contextWindow`:`1000000`
|
||||
- 默认运行时 `contextTokens` 上限:`272000`
|
||||
|
||||
较小的默认上限在实践中具有更好的延迟和质量表现。可通过 `contextTokens` 覆盖:
|
||||
实践中,较小的默认上限通常具有更好的延迟和质量表现。你可以通过 `contextTokens` 覆盖它:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -212,15 +211,14 @@ Codex app-server harness 的 `openai/gpt-5.5`。`openai/gpt-5.5` 的
|
||||
```
|
||||
|
||||
<Note>
|
||||
使用 `contextWindow` 声明原生模型元数据。使用 `contextTokens` 限制运行时上下文预算。
|
||||
使用 `contextWindow` 声明模型的原生元数据。使用 `contextTokens` 限制运行时上下文预算。
|
||||
</Note>
|
||||
|
||||
### 目录恢复
|
||||
|
||||
OpenClaw 会在上游 Codex 目录元数据存在时使用其中的 `gpt-5.5`
|
||||
元数据。如果实时 Codex 发现结果在
|
||||
账号已认证的情况下遗漏了 `openai-codex/gpt-5.5` 这一行,
|
||||
OpenClaw 会合成这一 OAuth 模型条目,这样 cron、子智能体以及已配置默认模型的运行就不会因
|
||||
当上游 Codex 目录元数据存在时,OpenClaw 会使用其 `gpt-5.5` 数据。
|
||||
如果在账号已认证的情况下,实时 Codex 发现遗漏了 `openai-codex/gpt-5.5` 这一行,
|
||||
OpenClaw 会合成这条 OAuth 模型记录,这样 cron、子智能体以及已配置默认模型的运行就不会因
|
||||
`Unknown model` 而失败。
|
||||
|
||||
</Tab>
|
||||
@ -228,19 +226,19 @@ Codex app-server harness 的 `openai/gpt-5.5`。`openai/gpt-5.5` 的
|
||||
|
||||
## 图像生成
|
||||
|
||||
内置的 `openai` 插件通过 `image_generate` 工具注册图像生成。
|
||||
它同时支持基于 OpenAI API 密钥的图像生成,以及通过同一个
|
||||
`openai/gpt-image-2` 模型引用进行的 Codex OAuth 图像生成。
|
||||
内置的 `openai` 插件通过 `image_generate` 工具注册图像生成功能。
|
||||
它同时支持使用 OpenAI API 密钥进行图像生成,以及通过 Codex OAuth
|
||||
使用同一个 `openai/gpt-image-2` 模型引用进行图像生成。
|
||||
|
||||
| 能力 | OpenAI API 密钥 | Codex OAuth |
|
||||
| ------------------------- | ---------------------------------- | ------------------------------------ |
|
||||
| 模型引用 | `openai/gpt-image-2` | `openai/gpt-image-2` |
|
||||
| 认证 | `OPENAI_API_KEY` | OpenAI Codex OAuth 登录 |
|
||||
| 传输 | OpenAI Images API | Codex Responses 后端 |
|
||||
| 每次请求最大图像数 | 4 | 4 |
|
||||
| 编辑模式 | 启用(最多 5 张参考图像) | 启用(最多 5 张参考图像) |
|
||||
| 每次请求的最大图片数 | 4 | 4 |
|
||||
| 编辑模式 | 支持(最多 5 张参考图) | 支持(最多 5 张参考图) |
|
||||
| 尺寸覆盖 | 支持,包括 2K/4K 尺寸 | 支持,包括 2K/4K 尺寸 |
|
||||
| 宽高比 / 分辨率 | 不会透传到 OpenAI Images API | 在安全时映射到受支持的尺寸 |
|
||||
| 宽高比 / 分辨率 | 不会转发给 OpenAI Images API | 在安全时映射到受支持的尺寸 |
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -253,47 +251,45 @@ Codex app-server harness 的 `openai/gpt-5.5`。`openai/gpt-5.5` 的
|
||||
```
|
||||
|
||||
<Note>
|
||||
有关共享工具参数、提供商选择和故障切换行为,请参阅 [图像生成](/zh-CN/tools/image-generation)。
|
||||
有关共享工具参数、提供商选择和故障转移行为,请参见 [图像生成](/zh-CN/tools/image-generation)。
|
||||
</Note>
|
||||
|
||||
`gpt-image-2` 是 OpenAI 文生图和图像
|
||||
编辑的默认模型。`gpt-image-1` 仍然可以作为显式模型覆盖使用,但新的
|
||||
OpenAI 图像工作流应使用 `openai/gpt-image-2`。
|
||||
`gpt-image-2` 是 OpenAI 文生图和图像编辑的默认模型。
|
||||
`gpt-image-1` 仍可作为显式模型覆盖使用,但新的 OpenAI 图像工作流
|
||||
应使用 `openai/gpt-image-2`。
|
||||
|
||||
对于 Codex OAuth 安装,请继续使用相同的 `openai/gpt-image-2` 引用。当已配置
|
||||
`openai-codex` OAuth 配置文件时,OpenClaw 会解析该已存储的 OAuth
|
||||
访问令牌,并通过 Codex Responses 后端发送图像请求。它
|
||||
不会先尝试 `OPENAI_API_KEY`,也不会在该请求中静默回退到 API 密钥。
|
||||
如果你想使用直连 OpenAI Images API
|
||||
路由,请显式配置 `models.providers.openai`,并提供 API 密钥、
|
||||
自定义 base URL 或 Azure 端点。
|
||||
如果该自定义图像端点位于受信任的局域网/私有地址上,还要设置
|
||||
`browser.ssrfPolicy.dangerouslyAllowPrivateNetwork: true`;如果没有这个显式选项,OpenClaw 会继续阻止
|
||||
私有/内部 OpenAI 兼容图像端点。
|
||||
对于使用 Codex OAuth 的安装,继续使用同一个 `openai/gpt-image-2` 引用即可。当配置了
|
||||
`openai-codex` OAuth 配置文件时,OpenClaw 会解析该已保存的 OAuth
|
||||
访问令牌,并通过 Codex Responses 后端发送图像请求。它不会先尝试 `OPENAI_API_KEY`,也不会为该请求静默回退到 API 密钥。
|
||||
当你想改用直接 OpenAI Images API 路径时,请显式配置
|
||||
`models.providers.openai`,并提供 API 密钥、自定义 base URL 或 Azure 端点。
|
||||
如果该自定义图像端点位于受信任的 LAN/私有地址上,还需要设置
|
||||
`browser.ssrfPolicy.dangerouslyAllowPrivateNetwork: true`;若没有此显式启用项,
|
||||
OpenClaw 会继续阻止私有/内部的 OpenAI 兼容图像端点。
|
||||
|
||||
生成:
|
||||
|
||||
```
|
||||
/tool image_generate model=openai/gpt-image-2 prompt="A polished launch poster for OpenClaw on macOS" size=3840x2160 count=1
|
||||
/tool image_generate model=openai/gpt-image-2 prompt="为 OpenClaw 在 macOS 上制作一张精美的发布海报" size=3840x2160 count=1
|
||||
```
|
||||
|
||||
编辑:
|
||||
|
||||
```
|
||||
/tool image_generate model=openai/gpt-image-2 prompt="Preserve the object shape, change the material to translucent glass" image=/path/to/reference.png size=1024x1536
|
||||
/tool image_generate model=openai/gpt-image-2 prompt="保留物体形状,将材质改为半透明玻璃" image=/path/to/reference.png size=1024x1536
|
||||
```
|
||||
|
||||
## 视频生成
|
||||
|
||||
内置的 `openai` 插件通过 `video_generate` 工具注册视频生成。
|
||||
内置的 `openai` 插件通过 `video_generate` 工具注册视频生成功能。
|
||||
|
||||
| 能力 | 值 |
|
||||
| ---------------- | --------------------------------------------------------------------------------- |
|
||||
| 默认模型 | `openai/sora-2` |
|
||||
| 模式 | 文生视频、图生视频、单视频编辑 |
|
||||
| 参考输入 | 1 张图像或 1 个视频 |
|
||||
| 模式 | 文本生成视频、图像生成视频、单视频编辑 |
|
||||
| 参考输入 | 1 张图片或 1 个视频 |
|
||||
| 尺寸覆盖 | 支持 |
|
||||
| 其他覆盖 | `aspectRatio`、`resolution`、`audio`、`watermark` 会被忽略,并给出工具警告 |
|
||||
| 其他覆盖项 | `aspectRatio`、`resolution`、`audio`、`watermark` 会被忽略,并给出工具警告 |
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -306,20 +302,20 @@ OpenAI 图像工作流应使用 `openai/gpt-image-2`。
|
||||
```
|
||||
|
||||
<Note>
|
||||
有关共享工具参数、提供商选择和故障切换行为,请参阅 [视频生成](/zh-CN/tools/video-generation)。
|
||||
有关共享工具参数、提供商选择和故障转移行为,请参见 [视频生成](/zh-CN/tools/video-generation)。
|
||||
</Note>
|
||||
|
||||
## GPT-5 提示词贡献
|
||||
## GPT-5 提示词叠加
|
||||
|
||||
OpenClaw 会为跨提供商的 GPT-5 系列运行添加共享的 GPT-5 提示词贡献。它按模型 id 生效,因此 `openai-codex/gpt-5.5`、`openai/gpt-5.4`、`openrouter/openai/gpt-5.5`、`opencode/gpt-5.5` 以及其他兼容的 GPT-5 引用都会收到同样的覆盖层。较旧的 GPT-4.x 模型不会收到。
|
||||
OpenClaw 会为跨提供商的 GPT-5 系列运行添加一个共享的 GPT-5 提示词叠加层。它按模型 id 生效,因此 `openai-codex/gpt-5.5`、`openai/gpt-5.4`、`openrouter/openai/gpt-5.5`、`opencode/gpt-5.5` 以及其他兼容的 GPT-5 引用都会收到同样的叠加层。较旧的 GPT-4.x 模型不会应用它。
|
||||
|
||||
内置的原生 Codex harness 通过 Codex app-server 开发者指令使用相同的 GPT-5 行为和心跳覆盖层,因此即使 Codex 接管了其余 harness 提示词,被强制通过 `embeddedHarness.runtime: "codex"` 运行的 `openai/gpt-5.x` 会话仍会保留相同的后续执行与主动心跳指引。
|
||||
内置的原生 Codex harness 通过 Codex app-server 开发者指令使用相同的 GPT-5 行为和心跳叠加层,因此,即使 Codex 接管了其余的 harness 提示词,被强制通过 `embeddedHarness.runtime: "codex"` 运行的 `openai/gpt-5.x` 会话,仍会保留相同的后续执行和主动心跳指引。
|
||||
|
||||
GPT-5 提示词贡献增加了一个带标签的行为契约,用于约束 persona 持续性、执行安全、工具纪律、输出形态、完成检查和验证。渠道特定的回复和静默消息行为仍保留在共享的 OpenClaw 系统提示词和出站传递策略中。GPT-5 指引始终会为匹配的模型启用。友好交互风格层是独立且可配置的。
|
||||
GPT-5 叠加层会为角色持续性、执行安全、工具纪律、输出形态、完成检查和验证添加一个带标签的行为契约。渠道特定的回复与静默消息行为仍保留在共享的 OpenClaw 系统提示词和出站投递策略中。对于匹配的模型,GPT-5 指引始终启用。友好的交互风格层是独立的,并且可配置。
|
||||
|
||||
| 值 | 效果 |
|
||||
| ---------------------- | ------------------------------------------- |
|
||||
| `"friendly"`(默认) | 启用友好交互风格层 |
|
||||
| `"friendly"`(默认) | 启用友好的交互风格层 |
|
||||
| `"on"` | `"friendly"` 的别名 |
|
||||
| `"off"` | 仅禁用友好风格层 |
|
||||
|
||||
@ -345,30 +341,30 @@ GPT-5 提示词贡献增加了一个带标签的行为契约,用于约束 pers
|
||||
</Tabs>
|
||||
|
||||
<Tip>
|
||||
运行时值不区分大小写,因此 `"Off"` 和 `"off"` 都会禁用友好风格层。
|
||||
这些值在运行时不区分大小写,因此 `"Off"` 和 `"off"` 都会禁用友好风格层。
|
||||
</Tip>
|
||||
|
||||
<Note>
|
||||
当共享设置 `agents.defaults.promptOverlays.gpt5.personality` 未设置时,旧版 `plugins.entries.openai.config.personality` 仍会作为兼容回退项被读取。
|
||||
当未设置共享的 `agents.defaults.promptOverlays.gpt5.personality` 时,旧版 `plugins.entries.openai.config.personality` 仍会作为兼容性回退项被读取。
|
||||
</Note>
|
||||
|
||||
## 语音与语音处理
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="语音合成(TTS)">
|
||||
内置的 `openai` 插件为 `messages.tts` 接口注册了语音合成。
|
||||
内置的 `openai` 插件会为 `messages.tts` 表面注册语音合成功能。
|
||||
|
||||
| 设置 | 配置路径 | 默认值 |
|
||||
|---------|------------|---------|
|
||||
| 模型 | `messages.tts.providers.openai.model` | `gpt-4o-mini-tts` |
|
||||
| 声音 | `messages.tts.providers.openai.voice` | `coral` |
|
||||
| 语速 | `messages.tts.providers.openai.speed` | (未设置) |
|
||||
| 语音 | `messages.tts.providers.openai.voice` | `coral` |
|
||||
| 速度 | `messages.tts.providers.openai.speed` | (未设置) |
|
||||
| 指令 | `messages.tts.providers.openai.instructions` | (未设置,仅 `gpt-4o-mini-tts`) |
|
||||
| 格式 | `messages.tts.providers.openai.responseFormat` | 语音便笺用 `opus`,文件用 `mp3` |
|
||||
| 格式 | `messages.tts.providers.openai.responseFormat` | 语音便签为 `opus`,文件为 `mp3` |
|
||||
| API 密钥 | `messages.tts.providers.openai.apiKey` | 回退到 `OPENAI_API_KEY` |
|
||||
| Base URL | `messages.tts.providers.openai.baseUrl` | `https://api.openai.com/v1` |
|
||||
|
||||
可用模型:`gpt-4o-mini-tts`、`tts-1`、`tts-1-hd`。可用声音:`alloy`、`ash`、`ballad`、`cedar`、`coral`、`echo`、`fable`、`juniper`、`marin`、`onyx`、`nova`、`sage`、`shimmer`、`verse`。
|
||||
可用模型:`gpt-4o-mini-tts`、`tts-1`、`tts-1-hd`。可用语音:`alloy`、`ash`、`ballad`、`cedar`、`coral`、`echo`、`fable`、`juniper`、`marin`、`onyx`、`nova`、`sage`、`shimmer`、`verse`。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -383,23 +379,23 @@ GPT-5 提示词贡献增加了一个带标签的行为契约,用于约束 pers
|
||||
```
|
||||
|
||||
<Note>
|
||||
设置 `OPENAI_TTS_BASE_URL` 可在不影响聊天 API 端点的情况下覆盖 TTS Base URL。
|
||||
设置 `OPENAI_TTS_BASE_URL` 可以覆盖 TTS 的 base URL,而不会影响聊天 API 端点。
|
||||
</Note>
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="语音转文本">
|
||||
内置的 `openai` 插件通过
|
||||
OpenClaw 的媒体理解转录接口注册批量语音转文本。
|
||||
内置的 `openai` 插件会通过
|
||||
OpenClaw 的媒体理解转写表面注册批量语音转文本。
|
||||
|
||||
- 默认模型:`gpt-4o-transcribe`
|
||||
- 端点:OpenAI REST `/v1/audio/transcriptions`
|
||||
- 输入路径:multipart 音频文件上传
|
||||
- 在 OpenClaw 中,凡是入站音频转录使用
|
||||
`tools.media.audio` 的地方都受支持,包括 Discord 语音频道片段和渠道
|
||||
- 只要入站音频转写使用
|
||||
`tools.media.audio`,OpenClaw 都支持,包括 Discord 语音频道片段和渠道
|
||||
音频附件
|
||||
|
||||
要强制对入站音频转录使用 OpenAI:
|
||||
若要强制对入站音频转写使用 OpenAI:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -419,12 +415,13 @@ GPT-5 提示词贡献增加了一个带标签的行为契约,用于约束 pers
|
||||
}
|
||||
```
|
||||
|
||||
当共享音频媒体配置或逐次调用转录请求提供了语言和提示词提示时,它们都会转发给 OpenAI。
|
||||
当由共享音频媒体配置或单次调用的转写请求提供时,
|
||||
语言和提示词提示会被转发给 OpenAI。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="实时转录">
|
||||
内置的 `openai` 插件为 Voice Call 插件注册了实时转录。
|
||||
<Accordion title="实时转写">
|
||||
内置的 `openai` 插件会为 Voice Call 插件注册实时转写功能。
|
||||
|
||||
| 设置 | 配置路径 | 默认值 |
|
||||
|---------|------------|---------|
|
||||
@ -436,18 +433,18 @@ GPT-5 提示词贡献增加了一个带标签的行为契约,用于约束 pers
|
||||
| API 密钥 | `...openai.apiKey` | 回退到 `OPENAI_API_KEY` |
|
||||
|
||||
<Note>
|
||||
使用到 `wss://api.openai.com/v1/realtime` 的 WebSocket 连接,并采用 G.711 u-law(`g711_ulaw` / `audio/pcmu`)音频。这个流式提供商用于 Voice Call 的实时转录路径;Discord 语音目前仍是录制短片段,然后改用批量 `tools.media.audio` 转录路径。
|
||||
通过 WebSocket 连接到 `wss://api.openai.com/v1/realtime`,使用 G.711 u-law(`g711_ulaw` / `audio/pcmu`)音频。这个流式 provider 用于 Voice Call 的实时转写路径;Discord 语音目前仍会录制短片段,并改用批量 `tools.media.audio` 转写路径。
|
||||
</Note>
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="实时语音">
|
||||
内置的 `openai` 插件为 Voice Call 插件注册了实时语音。
|
||||
内置的 `openai` 插件会为 Voice Call 插件注册实时语音功能。
|
||||
|
||||
| 设置 | 配置路径 | 默认值 |
|
||||
|---------|------------|---------|
|
||||
| 模型 | `plugins.entries.voice-call.config.realtime.providers.openai.model` | `gpt-realtime-1.5` |
|
||||
| 声音 | `...openai.voice` | `alloy` |
|
||||
| 语音 | `...openai.voice` | `alloy` |
|
||||
| 温度 | `...openai.temperature` | `0.8` |
|
||||
| VAD 阈值 | `...openai.vadThreshold` | `0.5` |
|
||||
| 静音时长 | `...openai.silenceDurationMs` | `500` |
|
||||
@ -462,26 +459,23 @@ GPT-5 提示词贡献增加了一个带标签的行为契约,用于约束 pers
|
||||
|
||||
## Azure OpenAI 端点
|
||||
|
||||
内置的 `openai` 提供商可以通过覆盖 base URL,将图像
|
||||
生成请求定向到 Azure OpenAI 资源。在图像生成路径上,OpenClaw
|
||||
会识别 `models.providers.openai.baseUrl` 上的 Azure 主机名,并自动切换到
|
||||
Azure 的请求格式。
|
||||
内置的 `openai` provider 可以通过覆盖 base URL,将图像生成请求发送到 Azure OpenAI 资源。在图像生成路径上,OpenClaw 会检测 `models.providers.openai.baseUrl` 中的 Azure 主机名,并自动切换到 Azure 的请求格式。
|
||||
|
||||
<Note>
|
||||
实时语音使用单独的配置路径
|
||||
(`plugins.entries.voice-call.config.realtime.providers.openai.azureEndpoint`),不会受 `models.providers.openai.baseUrl` 影响。请参阅 [语音与语音处理](#voice-and-speech) 下 **实时语音** 折叠面板中的 Azure
|
||||
设置。
|
||||
(`plugins.entries.voice-call.config.realtime.providers.openai.azureEndpoint`),不会受到 `models.providers.openai.baseUrl` 的影响。请参见 [语音与语音处理](#voice-and-speech) 下 **实时语音**
|
||||
折叠项中的 Azure 设置。
|
||||
</Note>
|
||||
|
||||
在以下情况下使用 Azure OpenAI:
|
||||
以下情况适合使用 Azure OpenAI:
|
||||
|
||||
- 你已经拥有 Azure OpenAI 订阅、配额或企业协议
|
||||
- 你需要 Azure 提供的区域数据驻留或合规控制
|
||||
- 你希望把流量保留在现有 Azure 租户内
|
||||
- 你希望将流量保留在现有 Azure 租户内
|
||||
|
||||
### 配置
|
||||
|
||||
要通过内置 `openai` 提供商使用 Azure 图像生成,请将
|
||||
若要通过内置 `openai` provider 使用 Azure 图像生成,请将
|
||||
`models.providers.openai.baseUrl` 指向你的 Azure 资源,并将 `apiKey` 设置为
|
||||
Azure OpenAI 密钥(而不是 OpenAI Platform 密钥):
|
||||
|
||||
@ -498,99 +492,89 @@ Azure OpenAI 密钥(而不是 OpenAI Platform 密钥):
|
||||
}
|
||||
```
|
||||
|
||||
OpenClaw 会为 Azure 图像生成
|
||||
路由识别以下 Azure 主机后缀:
|
||||
对于 Azure 图像生成路径,OpenClaw 会将以下 Azure 主机后缀识别为 Azure 路由:
|
||||
|
||||
- `*.openai.azure.com`
|
||||
- `*.services.ai.azure.com`
|
||||
- `*.cognitiveservices.azure.com`
|
||||
|
||||
对于发往已识别 Azure 主机的图像生成请求,OpenClaw 会:
|
||||
对于发送到已识别 Azure 主机的图像生成请求,OpenClaw 会:
|
||||
|
||||
- 发送 `api-key` 请求头,而不是 `Authorization: Bearer`
|
||||
- 使用按部署划分的路径(`/openai/deployments/{deployment}/...`)
|
||||
- 使用基于部署的路径(`/openai/deployments/{deployment}/...`)
|
||||
- 为每个请求追加 `?api-version=...`
|
||||
|
||||
其他 base URL(公共 OpenAI、OpenAI 兼容代理)则保留标准
|
||||
其他 base URL(公共 OpenAI、OpenAI 兼容代理)则继续使用标准的
|
||||
OpenAI 图像请求格式。
|
||||
|
||||
<Note>
|
||||
`openai` 提供商图像生成路径的 Azure 路由需要
|
||||
`openai` provider 图像生成路径的 Azure 路由要求
|
||||
OpenClaw 2026.4.22 或更高版本。更早版本会将任何自定义
|
||||
`openai.baseUrl` 视为公共 OpenAI 端点,从而在 Azure
|
||||
图像部署上失败。
|
||||
`openai.baseUrl` 都视为公共 OpenAI 端点,从而导致 Azure
|
||||
图像部署失败。
|
||||
</Note>
|
||||
|
||||
### API 版本
|
||||
|
||||
设置 `AZURE_OPENAI_API_VERSION` 可为 Azure 图像生成路径固定特定的 Azure 预览版或 GA 版本:
|
||||
设置 `AZURE_OPENAI_API_VERSION` 可以为 Azure 图像生成路径固定特定的 Azure 预览版或 GA 版本:
|
||||
|
||||
```bash
|
||||
export AZURE_OPENAI_API_VERSION="2024-12-01-preview"
|
||||
```
|
||||
|
||||
如果该变量未设置,默认值为 `2024-12-01-preview`。
|
||||
当该变量未设置时,默认值为 `2024-12-01-preview`。
|
||||
|
||||
### 模型名称就是部署名称
|
||||
|
||||
Azure OpenAI 将模型绑定到部署。对于通过内置 `openai` 提供商
|
||||
路由的 Azure 图像生成请求,OpenClaw 中的 `model` 字段
|
||||
必须是你在 Azure 门户中配置的**Azure 部署名称**,而不是
|
||||
公共 OpenAI 模型 id。
|
||||
Azure OpenAI 将模型绑定到部署。对于通过内置 `openai` provider 路由的 Azure 图像生成请求,OpenClaw 中的 `model` 字段必须是你在 Azure 门户中配置的 **Azure 部署名称**,而不是公共 OpenAI 模型 id。
|
||||
|
||||
如果你创建了一个名为 `gpt-image-2-prod` 的部署,用来提供 `gpt-image-2`:
|
||||
如果你创建了一个名为 `gpt-image-2-prod` 的部署来提供 `gpt-image-2`:
|
||||
|
||||
```
|
||||
/tool image_generate model=openai/gpt-image-2-prod prompt="A clean poster" size=1024x1024 count=1
|
||||
/tool image_generate model=openai/gpt-image-2-prod prompt="一张简洁的海报" size=1024x1024 count=1
|
||||
```
|
||||
|
||||
同样的部署名称规则也适用于通过
|
||||
内置 `openai` 提供商路由的图像生成调用。
|
||||
同样的部署名称规则也适用于通过内置 `openai` provider 路由的图像生成调用。
|
||||
|
||||
### 区域可用性
|
||||
|
||||
Azure 图像生成目前仅在部分区域可用
|
||||
Azure 图像生成目前仅在部分区域提供
|
||||
(例如 `eastus2`、`swedencentral`、`polandcentral`、`westus3`、
|
||||
`uaenorth`)。在创建
|
||||
部署之前,请检查 Microsoft 当前的区域列表,并确认你所在区域提供特定模型。
|
||||
`uaenorth`)。在创建部署前,请先查看 Microsoft 当前的区域列表,并确认你所在区域提供该具体模型。
|
||||
|
||||
### 参数差异
|
||||
|
||||
Azure OpenAI 和公共 OpenAI 并不总是接受相同的图像参数。
|
||||
Azure 可能会拒绝公共 OpenAI 允许的选项(例如某些
|
||||
`gpt-image-2` 的 `background` 值),或者仅在特定模型
|
||||
版本上提供这些选项。这些差异来自 Azure 和底层模型,而不是
|
||||
OpenClaw。如果 Azure 请求因校验错误而失败,请在
|
||||
Azure 门户中检查你的特定部署和 API 版本所支持的参数
|
||||
集合。
|
||||
Azure 可能会拒绝公共 OpenAI 允许的某些选项(例如在 `gpt-image-2` 上某些
|
||||
`background` 值),或者只在特定模型版本中提供它们。这些差异来自 Azure 及底层模型,而不是 OpenClaw。如果 Azure 请求因验证错误失败,请在
|
||||
Azure 门户中检查你的具体部署和 API 版本所支持的参数集。
|
||||
|
||||
<Note>
|
||||
Azure OpenAI 使用原生传输和兼容行为,但不会收到
|
||||
OpenClaw 的隐藏归因请求头——请参阅 [高级配置](#advanced-configuration) 下 **原生与 OpenAI 兼容
|
||||
路由** 折叠面板。
|
||||
Azure OpenAI 使用原生传输和兼容行为,但不会接收
|
||||
OpenClaw 的隐藏归因请求头 —— 请参见 [高级配置](#advanced-configuration) 下 **原生与 OpenAI 兼容
|
||||
路径** 折叠项。
|
||||
|
||||
对于 Azure 上的聊天或 Responses 流量(超出图像生成范围),请使用
|
||||
新手引导流程或专用的 Azure 提供商配置——仅设置 `openai.baseUrl`
|
||||
并不会自动套用 Azure API/认证格式。另有一个独立的
|
||||
`azure-openai-responses/*` 提供商;请参阅下面的
|
||||
服务端压缩折叠面板。
|
||||
对于 Azure 上的聊天或 Responses 流量(图像生成之外),请使用
|
||||
新手引导流程或专用的 Azure provider 配置 —— 单独设置 `openai.baseUrl` 并不会启用 Azure 的 API/认证格式。另有独立的
|
||||
`azure-openai-responses/*` provider;请参见下面的
|
||||
服务端压缩折叠项。
|
||||
</Note>
|
||||
|
||||
## 高级配置
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="传输(WebSocket 与 SSE)">
|
||||
对于 `openai/*` 和 `openai-codex/*`,OpenClaw 默认使用优先 WebSocket、SSE 回退(`"auto"`)的方式。
|
||||
对于 `openai/*` 和 `openai-codex/*`,OpenClaw 默认都采用 WebSocket 优先,并在失败时回退到 SSE(`"auto"`)。
|
||||
|
||||
在 `"auto"` 模式下,OpenClaw 会:
|
||||
- 在回退到 SSE 之前,先重试一次早期 WebSocket 失败
|
||||
- 失败后,将 WebSocket 标记为降级约 60 秒,并在冷却期间使用 SSE
|
||||
- 为重试和重连附加稳定的会话和回合标识请求头
|
||||
- 在不同传输变体之间规范化用量计数器(`input_tokens` / `prompt_tokens`)
|
||||
- 在回退到 SSE 前,对一次早期 WebSocket 失败进行重试
|
||||
- 在发生失败后,将 WebSocket 标记为降级约 60 秒,并在冷却期间使用 SSE
|
||||
- 为重试和重连附加稳定的会话和轮次身份请求头
|
||||
- 在不同传输变体之间统一使用量计数器(`input_tokens` / `prompt_tokens`)
|
||||
|
||||
| 值 | 行为 |
|
||||
|-------|----------|
|
||||
| `"auto"`(默认) | 优先 WebSocket,回退到 SSE |
|
||||
| `"auto"`(默认) | WebSocket 优先,失败回退到 SSE |
|
||||
| `"sse"` | 强制仅使用 SSE |
|
||||
| `"websocket"` | 强制仅使用 WebSocket |
|
||||
|
||||
@ -618,7 +602,7 @@ OpenClaw 的隐藏归因请求头——请参阅 [高级配置](#advanced-config
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="WebSocket 预热">
|
||||
对于 `openai/*` 和 `openai-codex/*`,OpenClaw 默认启用 WebSocket 预热,以降低首回合延迟。
|
||||
对于 `openai/*` 和 `openai-codex/*`,OpenClaw 默认启用 WebSocket 预热,以降低首轮延迟。
|
||||
|
||||
```json5
|
||||
// 禁用预热
|
||||
@ -638,12 +622,12 @@ OpenClaw 的隐藏归因请求头——请参阅 [高级配置](#advanced-config
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="快速模式">
|
||||
OpenClaw 为 `openai/*` 和 `openai-codex/*` 暴露了共享的快速模式开关:
|
||||
OpenClaw 为 `openai/*` 和 `openai-codex/*` 提供了一个共享的快速模式开关:
|
||||
|
||||
- **聊天/UI:** `/fast status|on|off`
|
||||
- **配置:** `agents.defaults.models["<provider>/<model>"].params.fastMode`
|
||||
|
||||
启用后,OpenClaw 会将快速模式映射为 OpenAI 优先级处理(`service_tier = "priority"`)。现有 `service_tier` 值会被保留,快速模式不会重写 `reasoning` 或 `text.verbosity`。
|
||||
启用后,OpenClaw 会将快速模式映射为 OpenAI 优先处理(`service_tier = "priority"`)。现有的 `service_tier` 值会被保留,且快速模式不会改写 `reasoning` 或 `text.verbosity`。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -658,13 +642,13 @@ OpenClaw 的隐藏归因请求头——请参阅 [高级配置](#advanced-config
|
||||
```
|
||||
|
||||
<Note>
|
||||
会话覆盖优先于配置。在 Sessions UI 中清除会话覆盖后,会话将回到已配置的默认值。
|
||||
会话级覆盖的优先级高于配置。在 Sessions UI 中清除会话覆盖后,会话会恢复为已配置的默认值。
|
||||
</Note>
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="优先级处理(service_tier)">
|
||||
OpenAI API 通过 `service_tier` 暴露优先级处理。你可以在 OpenClaw 中按模型设置它:
|
||||
<Accordion title="优先处理(service_tier)">
|
||||
OpenAI 的 API 通过 `service_tier` 暴露优先处理能力。你可以在 OpenClaw 中按模型设置它:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -681,23 +665,23 @@ OpenClaw 的隐藏归因请求头——请参阅 [高级配置](#advanced-config
|
||||
支持的值:`auto`、`default`、`flex`、`priority`。
|
||||
|
||||
<Warning>
|
||||
`serviceTier` 仅会转发到原生 OpenAI 端点(`api.openai.com`)和原生 Codex 端点(`chatgpt.com/backend-api`)。如果你通过代理路由任一提供商,OpenClaw 会保持 `service_tier` 不变。
|
||||
`serviceTier` 仅会转发到原生 OpenAI 端点(`api.openai.com`)和原生 Codex 端点(`chatgpt.com/backend-api`)。如果你通过代理路由任一 provider,OpenClaw 会保持 `service_tier` 原样不动。
|
||||
</Warning>
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="服务端压缩(Responses API)">
|
||||
对于直连 OpenAI Responses 模型(`api.openai.com` 上的 `openai/*`),OpenAI 插件的 Pi-harness 流包装器会自动启用服务端压缩:
|
||||
对于直接 OpenAI Responses 模型(`api.openai.com` 上的 `openai/*`),OpenAI 插件的 Pi-harness 流包装器会自动启用服务端压缩:
|
||||
|
||||
- 强制 `store: true`(除非模型 compat 设置 `supportsStore: false`)
|
||||
- 强制设置 `store: true`(除非模型兼容性配置将 `supportsStore: false`)
|
||||
- 注入 `context_management: [{ type: "compaction", compact_threshold: ... }]`
|
||||
- 默认 `compact_threshold`:`contextWindow` 的 70%(如果不可用则为 `80000`)
|
||||
|
||||
这适用于内置 Pi harness 路径,也适用于嵌入式运行所使用的 OpenAI 提供商钩子。原生 Codex app-server harness 通过 Codex 管理自己的上下文,并通过 `agents.defaults.embeddedHarness.runtime` 单独配置。
|
||||
这适用于内置 Pi harness 路径,也适用于嵌入式运行所用的 OpenAI provider 钩子。原生 Codex app-server harness 通过 Codex 自行管理上下文,并通过 `agents.defaults.embeddedHarness.runtime` 单独配置。
|
||||
|
||||
<Tabs>
|
||||
<Tab title="显式启用">
|
||||
对于 Azure OpenAI Responses 之类的兼容端点,这很有用:
|
||||
这对于 Azure OpenAI Responses 之类的兼容端点很有用:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -749,12 +733,12 @@ OpenClaw 的隐藏归因请求头——请参阅 [高级配置](#advanced-config
|
||||
</Tabs>
|
||||
|
||||
<Note>
|
||||
`responsesServerCompaction` 仅控制 `context_management` 注入。直连 OpenAI Responses 模型仍会强制 `store: true`,除非 compat 设置了 `supportsStore: false`。
|
||||
`responsesServerCompaction` 仅控制 `context_management` 注入。直接 OpenAI Responses 模型仍会强制设置 `store: true`,除非兼容性配置将 `supportsStore: false`。
|
||||
</Note>
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="严格智能体式 GPT 模式">
|
||||
<Accordion title="严格智能体 GPT 模式">
|
||||
对于 `openai/*` 上的 GPT-5 系列运行,OpenClaw 可以使用更严格的嵌入式执行契约:
|
||||
|
||||
```json5
|
||||
@ -768,32 +752,34 @@ OpenClaw 的隐藏归因请求头——请参阅 [高级配置](#advanced-config
|
||||
```
|
||||
|
||||
使用 `strict-agentic` 时,OpenClaw 会:
|
||||
- 当工具 action 可用时,不再将“仅规划”的回合视为成功进展
|
||||
- 使用立即执行导向重试该回合
|
||||
- 对于实质性工作,自动启用 `update_plan`
|
||||
- 如果模型持续规划而不执行,则显式显示阻塞状态
|
||||
- 在有工具操作可用时,不再把“仅规划”的轮次视为成功进展
|
||||
- 使用“立即行动”的引导重试该轮
|
||||
- 对于较大工作自动启用 `update_plan`
|
||||
- 如果模型持续规划而不执行,则显式呈现阻塞状态
|
||||
|
||||
<Note>
|
||||
仅作用于 OpenAI 和 Codex 的 GPT-5 系列运行。其他提供商和较旧模型系列仍保持默认行为。
|
||||
仅作用于 OpenAI 和 Codex 的 GPT-5 系列运行。其他 provider 和较旧模型系列保持默认行为。
|
||||
</Note>
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="原生与 OpenAI 兼容路由">
|
||||
OpenClaw 会将直连 OpenAI、Codex 和 Azure OpenAI 端点,与通用 OpenAI 兼容 `/v1` 代理区别对待:
|
||||
<Accordion title="原生路径与 OpenAI 兼容路径">
|
||||
OpenClaw 对直接 OpenAI、Codex 和 Azure OpenAI 端点,与通用 OpenAI 兼容 `/v1` 代理采取不同处理方式:
|
||||
|
||||
**原生路由**(`openai/*`、Azure OpenAI):
|
||||
**原生路径**(`openai/*`、Azure OpenAI):
|
||||
- 仅对支持 OpenAI `none` effort 的模型保留 `reasoning: { effort: "none" }`
|
||||
- 对于拒绝 `reasoning.effort: "none"` 的模型或代理,省略禁用的推理设置
|
||||
- 默认将工具 schema 设为严格模式
|
||||
- 对于会拒绝 `reasoning.effort: "none"` 的模型或代理,省略禁用推理配置
|
||||
- 默认对工具 schema 使用严格模式
|
||||
- 仅在已验证的原生主机上附加隐藏归因请求头
|
||||
- 保留 OpenAI 专有的请求整形(`service_tier`、`store`、推理兼容性、提示缓存提示)
|
||||
- 保留 OpenAI 专用的请求整形(`service_tier`、`store`、reasoning 兼容性、提示词缓存提示)
|
||||
|
||||
**代理/兼容路由:**
|
||||
**代理/兼容路径:**
|
||||
- 使用更宽松的兼容行为
|
||||
- 不会强制严格工具 schema 或原生专用请求头
|
||||
- 从非原生 `openai-completions` 载荷中剥离 Completions `store`
|
||||
- 接受高级 `params.extra_body`/`params.extraBody` 透传 JSON,用于 OpenAI 兼容的 Completions 代理
|
||||
- 不强制严格工具 schema 或仅原生可用的请求头
|
||||
|
||||
Azure OpenAI 使用原生传输和兼容行为,但不会收到隐藏归因请求头。
|
||||
Azure OpenAI 使用原生传输和兼容行为,但不会接收隐藏的归因请求头。
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
@ -802,15 +788,15 @@ OpenClaw 的隐藏归因请求头——请参阅 [高级配置](#advanced-config
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="模型选择" href="/zh-CN/concepts/model-providers" icon="layers">
|
||||
选择提供商、模型引用和故障切换行为。
|
||||
选择 provider、模型引用和故障转移行为。
|
||||
</Card>
|
||||
<Card title="图像生成" href="/zh-CN/tools/image-generation" icon="image">
|
||||
共享图像工具参数和提供商选择。
|
||||
共享图像工具参数和 provider 选择。
|
||||
</Card>
|
||||
<Card title="视频生成" href="/zh-CN/tools/video-generation" icon="video">
|
||||
共享视频工具参数和提供商选择。
|
||||
共享视频工具参数和 provider 选择。
|
||||
</Card>
|
||||
<Card title="OAuth 和认证" href="/zh-CN/gateway/authentication" icon="key">
|
||||
认证详情和凭证复用规则。
|
||||
认证细节和凭证复用规则。
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
@ -2,32 +2,32 @@
|
||||
read_when:
|
||||
- 你正在调试与转录结构相关的提供商请求拒绝问题
|
||||
- 你正在更改转录清理或工具调用修复逻辑
|
||||
- 你正在调查跨提供商的工具调用 ID 不匹配问题
|
||||
summary: 参考:提供商特定的转录清理和修复规则
|
||||
- 你正在调查跨提供商的工具调用 id 不匹配问题
|
||||
summary: 参考:提供商特定的转录清理与修复规则
|
||||
title: 转录清理规范
|
||||
x-i18n:
|
||||
generated_at: "2026-04-24T21:20:34Z"
|
||||
generated_at: "2026-04-25T02:37:12Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: eb9b8ea55b34810609d65433fa3be1558dd7c59bf4b33e66dfab3fdbd5a211ef
|
||||
source_hash: 2b4ce42332ec62a75bb1ad60574c462ef81297471add4588cf9286543e1ce104
|
||||
source_path: reference/transcript-hygiene.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
本文档描述了在一次运行前(构建模型上下文时)应用于转录的**提供商特定修复**。这些是用于满足严格提供商要求的**内存中**调整。这些清理步骤**不会**重写磁盘上存储的 JSONL 转录;不过,单独的会话文件修复流程可能会在加载会话前通过丢弃无效行来重写格式错误的 JSONL 文件。发生修复时,原始文件会与会话文件一起备份。
|
||||
本文档说明在运行前(构建模型上下文时)对转录应用的**提供商特定修复**。这些是用于满足严格提供商要求的**内存中**调整。这些清理步骤**不会**重写磁盘上存储的 JSONL 转录;不过,单独的会话文件修复流程可能会在加载会话前通过丢弃无效行来重写格式错误的 JSONL 文件。发生修复时,原始文件会在会话文件旁边备份。
|
||||
|
||||
范围包括:
|
||||
|
||||
- 仅运行时的提示词上下文,不进入用户可见的转录轮次
|
||||
- 工具调用 ID 清理
|
||||
- 仅运行时的提示上下文,不进入用户可见的转录轮次
|
||||
- 工具调用 id 清理
|
||||
- 工具调用输入验证
|
||||
- 工具结果配对修复
|
||||
- 轮次验证 / 排序
|
||||
- 思考签名清理
|
||||
- 图像载荷清理
|
||||
- 用户输入来源标记(用于跨会话路由的提示词)
|
||||
- thought signature 清理
|
||||
- 图像负载清理
|
||||
- 用户输入来源标记(用于跨会话路由的提示)
|
||||
|
||||
如果你需要了解转录存储细节,请参阅:
|
||||
如果你需要了解转录存储细节,请参见:
|
||||
|
||||
- [/reference/session-management-compaction](/zh-CN/reference/session-management-compaction)
|
||||
|
||||
@ -35,9 +35,9 @@ x-i18n:
|
||||
|
||||
## 全局规则:运行时上下文不是用户转录
|
||||
|
||||
运行时 / 系统上下文可以被添加到某一轮的模型提示词中,但它不是终端用户撰写的内容。OpenClaw 会为 Gateway 网关回复、排队的后续操作、ACP、CLI 以及嵌入式 Pi 运行保留一个独立的面向转录的提示词正文。存储的可见用户轮次使用该转录正文,而不是经过运行时增强的提示词。
|
||||
运行时/系统上下文可以添加到某一轮的模型提示中,但它不是最终用户编写的内容。OpenClaw 会为 Gateway 网关回复、排队后续步骤、ACP、CLI 以及嵌入式 Pi 运行保留一个独立的、面向转录的提示正文。存储的可见用户轮次会使用该转录正文,而不是经过运行时增强的提示。
|
||||
|
||||
对于已经持久化了运行时包装内容的旧版会话,Gateway 网关历史记录界面会在将消息返回给 WebChat、TUI、REST 或 SSE 客户端之前应用显示投影。
|
||||
对于已经持久化了运行时包装器的旧会话,Gateway 网关历史记录界面会在将消息返回给 WebChat、TUI、REST 或 SSE 客户端之前应用显示投影。
|
||||
|
||||
---
|
||||
|
||||
@ -46,7 +46,7 @@ x-i18n:
|
||||
所有转录清理都集中在嵌入式运行器中:
|
||||
|
||||
- 策略选择:`src/agents/transcript-policy.ts`
|
||||
- 清理 / 修复应用:`src/agents/pi-embedded-runner/replay-history.ts` 中的 `sanitizeSessionHistory`
|
||||
- 清理/修复应用:`src/agents/pi-embedded-runner/replay-history.ts` 中的 `sanitizeSessionHistory`
|
||||
|
||||
该策略使用 `provider`、`modelApi` 和 `modelId` 来决定应用哪些规则。
|
||||
|
||||
@ -59,9 +59,11 @@ x-i18n:
|
||||
|
||||
## 全局规则:图像清理
|
||||
|
||||
图像载荷始终会被清理,以防止因大小限制导致提供商侧拒绝请求(对过大的 base64 图像进行缩放 / 重新压缩)。
|
||||
图像负载始终会被清理,以防止因大小限制而导致提供商侧拒绝
|
||||
(对过大的 base64 图像进行缩放/重新压缩)。
|
||||
|
||||
这也有助于控制支持视觉能力的模型因图像导致的 token 压力。较低的最大尺寸通常会减少 token 使用量;较高的尺寸则会保留更多细节。
|
||||
这也有助于控制支持视觉的模型中由图像驱动的 token 压力。
|
||||
较低的最大尺寸通常会减少 token 使用量;较高的尺寸则能保留更多细节。
|
||||
|
||||
实现:
|
||||
|
||||
@ -73,7 +75,9 @@ x-i18n:
|
||||
|
||||
## 全局规则:格式错误的工具调用
|
||||
|
||||
缺少 `input` 和 `arguments` 的助手工具调用块会在构建模型上下文之前被丢弃。这样可以防止提供商因部分已持久化的工具调用而拒绝请求(例如,在速率限制失败之后)。
|
||||
缺少 `input` 和 `arguments` 的 assistant 工具调用块会在构建模型上下文前被丢弃。
|
||||
|
||||
这可以防止提供商因部分持久化的工具调用而拒绝请求(例如在速率限制失败之后)。
|
||||
|
||||
实现:
|
||||
|
||||
@ -84,14 +88,16 @@ x-i18n:
|
||||
|
||||
## 全局规则:跨会话输入来源
|
||||
|
||||
当一个智能体通过 `sessions_send` 将提示词发送到另一个会话时(包括智能体到智能体的回复 / 通知步骤),OpenClaw 会在创建的用户轮次中持久化以下字段:
|
||||
当一个智能体通过 `sessions_send` 将提示发送到另一个会话时(包括
|
||||
智能体到智能体的回复/公告步骤),OpenClaw 会将创建的用户轮次持久化并附带:
|
||||
|
||||
- `message.provenance.kind = "inter_session"`
|
||||
|
||||
此元数据会在追加到转录时写入,不会更改角色
|
||||
(为保证提供商兼容性,仍保持 `role: "user"`)。转录读取器可以利用这一点,避免将路由的内部提示词视为终端用户撰写的指令。
|
||||
此元数据会在追加到转录时写入,并且不会改变角色
|
||||
(出于提供商兼容性,仍保持 `role: "user"`)。转录读取器可以使用它来避免将内部路由提示视为最终用户编写的指令。
|
||||
|
||||
在重建上下文期间,OpenClaw 还会在内存中为这些用户轮次添加一个简短的 `[Inter-session message]` 标记作为前缀,以便模型能够将它们与外部终端用户指令区分开来。
|
||||
在重建上下文期间,OpenClaw 还会在内存中为这些用户轮次前置一个简短的 `[Inter-session message]`
|
||||
标记,以便模型将其与外部最终用户指令区分开来。
|
||||
|
||||
---
|
||||
|
||||
@ -100,35 +106,35 @@ x-i18n:
|
||||
**OpenAI / OpenAI Codex**
|
||||
|
||||
- 仅进行图像清理。
|
||||
- 对于 OpenAI Responses / Codex 转录,丢弃孤立的推理签名(后面没有内容块的独立推理项)。
|
||||
- 不进行工具调用 ID 清理。
|
||||
- 对于 OpenAI Responses/Codex 转录,丢弃孤立的 reasoning signature(即后面没有内容块的独立 reasoning 项),并在模型路由切换后丢弃可重放的 OpenAI reasoning。
|
||||
- 不进行工具调用 id 清理。
|
||||
- 不进行工具结果配对修复。
|
||||
- 不进行轮次验证或重排序。
|
||||
- 不进行轮次验证或重排。
|
||||
- 不生成合成工具结果。
|
||||
- 不剥离思考签名。
|
||||
- 不移除 thought signature。
|
||||
|
||||
**Google(Generative AI / Gemini CLI / Antigravity)**
|
||||
|
||||
- 工具调用 ID 清理:严格字母数字。
|
||||
- 工具调用 id 清理:严格字母数字格式。
|
||||
- 工具结果配对修复和合成工具结果。
|
||||
- 轮次验证(Gemini 风格的轮次交替)。
|
||||
- Google 轮次顺序修复(如果历史记录以助手开头,则预置一个极小的用户引导消息)。
|
||||
- Antigravity Claude:规范化思考签名;丢弃未签名的思考块。
|
||||
- Google 轮次排序修复(如果历史记录以 assistant 开始,则前置一个极小的用户 bootstrap)。
|
||||
- Antigravity Claude:归一化 thinking signature;丢弃未签名的 thinking 块。
|
||||
|
||||
**Anthropic / Minimax(Anthropic 兼容)**
|
||||
|
||||
- 工具结果配对修复和合成工具结果。
|
||||
- 轮次验证(合并连续的用户轮次以满足严格交替要求)。
|
||||
- 轮次验证(合并连续的 user 轮次,以满足严格交替要求)。
|
||||
|
||||
**Mistral(包括基于模型 ID 的检测)**
|
||||
**Mistral(包括基于模型 id 的检测)**
|
||||
|
||||
- 工具调用 ID 清理:strict9(长度为 9 的字母数字)。
|
||||
- 工具调用 id 清理:strict9(长度为 9 的字母数字)。
|
||||
|
||||
**OpenRouter Gemini**
|
||||
|
||||
- 思考签名清理:剥离非 base64 的 `thought_signature` 值(保留 base64)。
|
||||
- thought signature 清理:移除非 base64 的 `thought_signature` 值(保留 base64)。
|
||||
|
||||
**其他所有情况**
|
||||
**其他所有提供商**
|
||||
|
||||
- 仅进行图像清理。
|
||||
|
||||
@ -138,19 +144,19 @@ x-i18n:
|
||||
|
||||
在 2026.1.22 版本之前,OpenClaw 应用了多层转录清理:
|
||||
|
||||
- 一个 **transcript-sanitize extension** 会在每次构建上下文时运行,并且可以:
|
||||
- 修复工具使用 / 结果配对。
|
||||
- 清理工具调用 ID(包括保留 `_` / `-` 的非严格模式)。
|
||||
- 运行器也会执行提供商特定清理,这造成了重复工作。
|
||||
- 提供商策略之外还会发生其他变更,包括:
|
||||
- 在持久化之前从助手文本中剥离 `<final>` 标签。
|
||||
- 丢弃空的助手错误轮次。
|
||||
- 在工具调用之后裁剪助手内容。
|
||||
- 每次构建上下文时都会运行一个 **transcript-sanitize 扩展**,它可以:
|
||||
- 修复工具使用/结果配对。
|
||||
- 清理工具调用 id(包括一种会保留 `_`/`-` 的非严格模式)。
|
||||
- 运行器还会执行提供商特定清理,造成重复处理。
|
||||
- 在提供商策略之外还会发生额外变更,包括:
|
||||
- 在持久化前从 assistant 文本中移除 `<final>` 标签。
|
||||
- 丢弃空的 assistant 错误轮次。
|
||||
- 在工具调用后裁剪 assistant 内容。
|
||||
|
||||
这种复杂性导致了跨提供商回归问题(特别是 `openai-responses`
|
||||
`call_id|fc_id` 配对)。2026.1.22 的清理工作移除了该扩展,将逻辑集中到运行器中,并让 OpenAI 除图像清理之外保持**不触碰**。
|
||||
这种复杂性导致了跨提供商回归(尤其是 `openai-responses`
|
||||
`call_id|fc_id` 配对问题)。2026.1.22 的清理工作移除了该扩展,将逻辑集中到运行器中,并让 OpenAI 除图像清理外保持**不做处理**。
|
||||
|
||||
## 相关内容
|
||||
|
||||
- [会话管理](/zh-CN/concepts/session)
|
||||
- [会话修剪](/zh-CN/concepts/session-pruning)
|
||||
- [会话裁剪](/zh-CN/concepts/session-pruning)
|
||||
|
||||
@ -1,40 +1,41 @@
|
||||
---
|
||||
read_when:
|
||||
- 添加由智能体控制的浏览器自动化
|
||||
- 调试 openclaw 为什么会干扰你自己的 Chrome
|
||||
- 在 macOS 应用中实现浏览器设置 + 生命周期管理
|
||||
summary: 集成式浏览器控制服务 + 操作命令
|
||||
- 排查为什么 openclaw 正在干扰你自己的 Chrome
|
||||
- 在 macOS 应用中实现浏览器设置和生命周期
|
||||
summary: 集成浏览器控制服务 + 操作命令
|
||||
title: 浏览器(由 OpenClaw 管理)
|
||||
x-i18n:
|
||||
generated_at: "2026-04-25T00:55:00Z"
|
||||
generated_at: "2026-04-25T02:37:15Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: 6a7fca9d290891b6d009e62929cdc87e58e5fd6e32aad3719b37099f2051fbd0
|
||||
source_hash: 32d614f519ebe83421426abd86cae23857f5d9afb7500583658961c10eeb69c7
|
||||
source_path: tools/browser.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
OpenClaw 可以运行一个**专用的 Chrome/Brave/Edge/Chromium 配置文件**,由智能体控制。
|
||||
它与你的个人浏览器隔离,并通过 Gateway 网关 内部的一个小型本地控制服务进行管理
|
||||
(仅 loopback)。
|
||||
OpenClaw 可以运行一个**专用的 Chrome/Brave/Edge/Chromium 配置文件**,由智能体控制。
|
||||
它与你的个人浏览器隔离,并通过 Gateway 网关内部一个小型本地
|
||||
控制服务进行管理(仅限 loopback)。
|
||||
|
||||
面向初学者的理解:
|
||||
面向初学者的理解方式:
|
||||
|
||||
- 可以把它看作一个**独立的、仅供智能体使用的浏览器**。
|
||||
- `openclaw` 配置文件**不会**触碰你的个人浏览器配置文件。
|
||||
- 智能体可以在一条安全通道中**打开标签页、读取页面、点击和输入**。
|
||||
- 内置的 `user` 配置文件会通过 Chrome MCP 连接到你真实的已登录 Chrome 会话。
|
||||
- 内置的 `user` 配置文件会通过 Chrome MCP 附加到你真实的、已登录的 Chrome 会话。
|
||||
|
||||
## 你将获得什么
|
||||
|
||||
- 一个名为 **openclaw** 的独立浏览器配置文件(默认使用橙色强调色)。
|
||||
- 可预测的标签页控制(列出/打开/聚焦/关闭)。
|
||||
- 智能体操作(点击/输入/拖拽/选择)、快照、截图、PDF。
|
||||
- 一个内置的 `browser-automation` Skills,在启用浏览器插件时,它会教智能体如何使用 snapshot、stable-tab、stale-ref 和 manual-blocker 恢复循环。
|
||||
- 可选的多配置文件支持(`openclaw`、`work`、`remote` 等)。
|
||||
- 智能体操作(点击/输入/拖动/选择)、快照、截图、PDF。
|
||||
- 一个内置的 `browser-automation` Skill,会在浏览器
|
||||
插件启用时,指导智能体使用快照、稳定标签页、过期引用和手动阻塞恢复循环。
|
||||
- 可选的多配置文件支持(`openclaw`、`work`、`remote`,等等)。
|
||||
|
||||
这个浏览器**不是**你的日常主力浏览器。
|
||||
它是一个安全、隔离的界面,用于智能体自动化和验证。
|
||||
这个浏览器**不是**你的日常主力浏览器。它是一个安全、隔离的界面,
|
||||
用于智能体自动化和验证。
|
||||
|
||||
## 快速开始
|
||||
|
||||
@ -46,14 +47,14 @@ openclaw browser --browser-profile openclaw open https://example.com
|
||||
openclaw browser --browser-profile openclaw snapshot
|
||||
```
|
||||
|
||||
如果你看到“浏览器已禁用”,请在配置中启用它(见下文),然后重启
|
||||
如果你看到“Browser disabled”,请在配置中启用它(见下文),然后重启
|
||||
Gateway 网关。
|
||||
|
||||
如果 `openclaw browser` 命令完全不存在,或者智能体提示浏览器工具不可用,请跳转到[缺少浏览器命令或工具](/zh-CN/tools/browser#missing-browser-command-or-tool)。
|
||||
如果 `openclaw browser` 完全不存在,或者智能体提示浏览器工具不可用,请跳转到[浏览器命令或工具缺失](/zh-CN/tools/browser#missing-browser-command-or-tool)。
|
||||
|
||||
## 插件控制
|
||||
|
||||
默认的 `browser` 工具是一个内置插件。你可以禁用它,以便用另一个注册相同 `browser` 工具名的插件来替换它:
|
||||
默认的 `browser` 工具是一个内置插件。若要用另一个注册相同 `browser` 工具名的插件替换它,请先禁用它:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -67,23 +68,28 @@ Gateway 网关。
|
||||
}
|
||||
```
|
||||
|
||||
默认设置需要同时启用 `plugins.entries.browser.enabled` **以及** `browser.enabled=true`。如果只禁用插件,会将 `openclaw browser` CLI、`browser.request` Gateway 网关方法、智能体工具和控制服务作为一个整体一并移除;你的 `browser.*` 配置会保持不变,以供替代插件使用。
|
||||
默认情况下需要同时满足 `plugins.entries.browser.enabled` **和** `browser.enabled=true`。只禁用插件会一次性移除 `openclaw browser` CLI、`browser.request` Gateway 网关方法、智能体工具和控制服务;你的 `browser.*` 配置将保持不变,以便替代插件使用。
|
||||
|
||||
浏览器配置变更需要重启 Gateway 网关,这样插件才能重新注册其服务。
|
||||
|
||||
## 智能体指引
|
||||
|
||||
浏览器插件附带两层智能体指引:
|
||||
浏览器插件提供两层智能体指引:
|
||||
|
||||
- `browser` 工具描述中包含始终启用的精简契约:选择正确的配置文件、在同一标签页中保持 ref 有效、使用 `tabId`/标签名定位标签页,以及在执行多步骤任务时加载浏览器 Skills。
|
||||
- 内置的 `browser-automation` Skills 包含更完整的操作循环:先检查状态/标签页、为任务标签页打标签、操作前先做快照、UI 变化后重新快照、遇到 stale ref 时恢复一次,并将登录/2FA/captcha 或摄像头/麦克风阻塞报告为需要手动处理的操作,而不是猜测。
|
||||
- `browser` 工具描述携带紧凑的常驻契约:选择
|
||||
正确的配置文件、在同一标签页中保持引用、使用 `tabId`/标签进行标签页
|
||||
定位,并在进行多步骤工作时加载浏览器 Skill。
|
||||
- 内置的 `browser-automation` Skill 携带更完整的操作循环:
|
||||
先检查状态/标签页、为任务标签页打标签、操作前先做快照、
|
||||
UI 变化后重新快照、过期引用恢复一次,并将登录/2FA/captcha 或
|
||||
摄像头/麦克风阻塞报告为手动操作,而不是猜测处理。
|
||||
|
||||
当插件启用时,插件内置的 Skills 会列在智能体可用 Skills 中。
|
||||
完整的 Skills 指令会按需加载,因此日常轮次不会承担全部 token 成本。
|
||||
当插件启用时,插件内置的 Skills 会列在智能体可用 Skills 中。
|
||||
完整的 Skill 指令按需加载,因此日常轮次不会承担全部 token 成本。
|
||||
|
||||
## 缺少浏览器命令或工具
|
||||
## 浏览器命令或工具缺失
|
||||
|
||||
如果升级后 `openclaw browser` 变为未知命令、`browser.request` 不存在,或者智能体报告浏览器工具不可用,通常原因是 `plugins.allow` 列表中遗漏了 `browser`。请将其添加进去:
|
||||
如果升级后 `openclaw browser` 未知、`browser.request` 缺失,或者智能体报告浏览器工具不可用,通常原因是 `plugins.allow` 列表中遗漏了 `browser`。请添加它:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -93,18 +99,20 @@ Gateway 网关。
|
||||
}
|
||||
```
|
||||
|
||||
`browser.enabled=true`、`plugins.entries.browser.enabled=true` 和 `tools.alsoAllow: ["browser"]` 都不能替代 allowlist 成员资格——allowlist 控制插件是否加载,而工具策略只会在加载之后运行。完全移除 `plugins.allow` 也会恢复默认行为。
|
||||
`browser.enabled=true`、`plugins.entries.browser.enabled=true` 和 `tools.alsoAllow: ["browser"]` 都不能替代允许列表成员资格 —— 允许列表控制插件加载,而工具策略只会在加载后运行。完全删除 `plugins.allow` 也会恢复默认行为。
|
||||
|
||||
## 配置文件:`openclaw` 与 `user`
|
||||
|
||||
- `openclaw`:受管理的隔离浏览器(不需要扩展)。
|
||||
- `user`:内置的 Chrome MCP 附加配置文件,用于连接你**真实的已登录 Chrome** 会话。
|
||||
- `openclaw`:受管理、隔离的浏览器(无需扩展)。
|
||||
- `user`:内置的 Chrome MCP 附加配置文件,用于你**真实已登录的 Chrome**
|
||||
会话。
|
||||
|
||||
对于智能体浏览器工具调用:
|
||||
|
||||
- 默认:使用隔离的 `openclaw` 浏览器。
|
||||
- 当现有登录会话很重要,并且用户就在电脑前可以点击/批准任何附加提示时,优先使用 `profile="user"`。
|
||||
- 当你希望使用特定浏览器模式时,`profile` 是显式覆盖项。
|
||||
- 当现有登录会话很重要,并且用户
|
||||
正在电脑前可以点击/批准任何附加提示时,优先使用 `profile="user"`。
|
||||
- 当你想要特定浏览器模式时,`profile` 是显式覆盖项。
|
||||
|
||||
如果你希望默认使用受管理模式,请设置 `browser.defaultProfile: "openclaw"`。
|
||||
|
||||
@ -125,6 +133,12 @@ Gateway 网关。
|
||||
// cdpUrl: "http://127.0.0.1:18792", // legacy single-profile override
|
||||
remoteCdpTimeoutMs: 1500, // remote CDP HTTP timeout (ms)
|
||||
remoteCdpHandshakeTimeoutMs: 3000, // remote CDP WebSocket handshake timeout (ms)
|
||||
tabCleanup: {
|
||||
enabled: true, // default: true
|
||||
idleMinutes: 120, // set 0 to disable idle cleanup
|
||||
maxTabsPerSession: 8, // set 0 to disable the per-session cap
|
||||
sweepMinutes: 5,
|
||||
},
|
||||
defaultProfile: "openclaw",
|
||||
color: "#FF4500",
|
||||
headless: false,
|
||||
@ -155,30 +169,31 @@ Gateway 网关。
|
||||
|
||||
<Accordion title="端口与可达性">
|
||||
|
||||
- 控制服务会绑定到 loopback,端口由 `gateway.port` 推导而来(默认 `18791` = gateway + 2)。覆盖 `gateway.port` 或 `OPENCLAW_GATEWAY_PORT` 会让同一组派生端口一并变化。
|
||||
- 本地 `openclaw` 配置文件会自动分配 `cdpPort`/`cdpUrl`;只有远程 CDP 才需要设置这些值。未设置时,`cdpUrl` 默认指向受管理的本地 CDP 端口。
|
||||
- 控制服务绑定到 loopback,端口从 `gateway.port` 派生而来(默认 `18791` = gateway + 2)。覆盖 `gateway.port` 或 `OPENCLAW_GATEWAY_PORT` 会同步移动同一组派生端口。
|
||||
- 本地 `openclaw` 配置文件会自动分配 `cdpPort`/`cdpUrl`;仅在远程 CDP 场景下才需要设置它们。未设置时,`cdpUrl` 默认指向受管理的本地 CDP 端口。
|
||||
- `remoteCdpTimeoutMs` 适用于远程(非 loopback)CDP HTTP 可达性检查;`remoteCdpHandshakeTimeoutMs` 适用于远程 CDP WebSocket 握手。
|
||||
- `tabCleanup` 是针对由主智能体浏览器会话打开标签页的尽力清理机制。子智能体、cron 和 ACP 生命周期清理仍会在会话结束时关闭其显式跟踪的标签页;主会话会保留活动标签页以供复用,然后在后台关闭空闲或超出数量的已跟踪标签页。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="SSRF 策略">
|
||||
|
||||
- 浏览器导航和打开标签页会在导航前执行 SSRF 防护,并在最终 `http(s)` URL 上尽力再次检查。
|
||||
- 浏览器导航和打开标签页会在导航前进行 SSRF 防护,并在导航完成后尽力对最终 `http(s)` URL 再次检查。
|
||||
- 在严格 SSRF 模式下,远程 CDP 端点发现和 `/json/version` 探测(`cdpUrl`)也会被检查。
|
||||
- `browser.ssrfPolicy.dangerouslyAllowPrivateNetwork` 默认关闭;仅当你明确可信任私有网络浏览器访问时才启用。
|
||||
- 默认关闭 `browser.ssrfPolicy.dangerouslyAllowPrivateNetwork`;仅当你明确可信任私有网络浏览器访问时才启用。
|
||||
- `browser.ssrfPolicy.allowPrivateNetwork` 仍作为旧版别名受支持。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="配置文件行为">
|
||||
|
||||
- `attachOnly: true` 表示绝不启动本地浏览器;只在浏览器已经运行时附加。
|
||||
- `headless` 可以全局设置,也可以为每个本地受管理配置文件单独设置。每个配置文件的值会覆盖 `browser.headless`,因此一个本地启动的配置文件可以保持无头模式,而另一个仍然可见。
|
||||
- `color`(顶层和每个配置文件级别)会为浏览器 UI 着色,这样你可以看出当前激活的是哪个配置文件。
|
||||
- 默认配置文件是 `openclaw`(受管理的独立浏览器)。使用 `defaultProfile: "user"` 可切换为已登录的用户浏览器。
|
||||
- 自动检测顺序:系统默认浏览器(如果基于 Chromium);否则依次为 Chrome → Brave → Edge → Chromium → Chrome Canary。
|
||||
- `attachOnly: true` 表示永不启动本地浏览器;仅在浏览器已运行时附加。
|
||||
- `headless` 可在全局或每个本地受管理配置文件级别设置。每个配置文件的值会覆盖 `browser.headless`,因此某个本地启动的配置文件可以保持无头,而另一个仍保持可见。
|
||||
- `color`(顶层和每个配置文件)会为浏览器 UI 着色,便于你看出当前活动的是哪个配置文件。
|
||||
- 默认配置文件是 `openclaw`(受管理的独立模式)。使用 `defaultProfile: "user"` 可选择启用已登录的用户浏览器。
|
||||
- 自动检测顺序:系统默认浏览器(若为 Chromium 系);否则依次为 Chrome → Brave → Edge → Chromium → Chrome Canary。
|
||||
- `driver: "existing-session"` 使用 Chrome DevTools MCP,而不是原始 CDP。不要为该驱动设置 `cdpUrl`。
|
||||
- 当某个 existing-session 配置文件需要附加到非默认的 Chromium 用户配置文件(Brave、Edge 等)时,请设置 `browser.profiles.<name>.userDataDir`。
|
||||
- 如果某个 existing-session 配置文件需要附加到非默认的 Chromium 用户配置文件(Brave、Edge 等),请设置 `browser.profiles.<name>.userDataDir`。
|
||||
|
||||
</Accordion>
|
||||
|
||||
@ -186,14 +201,15 @@ Gateway 网关。
|
||||
|
||||
## 使用 Brave(或其他基于 Chromium 的浏览器)
|
||||
|
||||
如果你的**系统默认**浏览器是基于 Chromium 的(Chrome/Brave/Edge 等),
|
||||
OpenClaw 会自动使用它。设置 `browser.executablePath` 可以覆盖自动检测:
|
||||
如果你的**系统默认**浏览器是基于 Chromium 的(Chrome/Brave/Edge 等),
|
||||
OpenClaw 会自动使用它。设置 `browser.executablePath` 可覆盖
|
||||
自动检测。`~` 会展开为你的操作系统主目录:
|
||||
|
||||
```bash
|
||||
openclaw config set browser.executablePath "/usr/bin/google-chrome"
|
||||
```
|
||||
|
||||
或者在配置中按平台设置:
|
||||
或者按平台在配置中设置:
|
||||
|
||||
<Tabs>
|
||||
<Tab title="macOS">
|
||||
@ -227,46 +243,51 @@ openclaw config set browser.executablePath "/usr/bin/google-chrome"
|
||||
|
||||
## 本地控制与远程控制
|
||||
|
||||
- **本地控制(默认):** Gateway 网关 启动 loopback 控制服务,并且可以启动本地浏览器。
|
||||
- **远程控制(节点主机):** 在拥有浏览器的机器上运行节点主机;Gateway 网关 会将浏览器操作代理到该节点主机。
|
||||
- **远程 CDP:** 设置 `browser.profiles.<name>.cdpUrl`(或 `browser.cdpUrl`)以附加到远程的基于 Chromium 的浏览器。在这种情况下,OpenClaw 不会启动本地浏览器。
|
||||
- `headless` 只影响 OpenClaw 启动的本地受管理配置文件。它不会重启或更改 existing-session 或远程 CDP 浏览器。
|
||||
- **本地控制(默认):** Gateway 网关启动 loopback 控制服务,并可启动本地浏览器。
|
||||
- **远程控制(节点主机):** 在拥有浏览器的机器上运行节点主机;Gateway 网关会将浏览器操作代理到该主机。
|
||||
- **远程 CDP:** 设置 `browser.profiles.<name>.cdpUrl`(或 `browser.cdpUrl`)以
|
||||
附加到远程的 Chromium 系浏览器。在这种情况下,OpenClaw 不会启动本地浏览器。
|
||||
- `headless` 仅影响由 OpenClaw 启动的本地受管理配置文件。它不会重启或改变 existing-session 或远程 CDP 浏览器。
|
||||
|
||||
不同配置文件模式下的停止行为不同:
|
||||
不同配置文件模式下,停止行为也不同:
|
||||
|
||||
- 本地受管理配置文件:`openclaw browser stop` 会停止
|
||||
OpenClaw 启动的浏览器进程
|
||||
- 仅附加和远程 CDP 配置文件:`openclaw browser stop` 会关闭当前活动的
|
||||
控制会话,并释放 Playwright/CDP 仿真覆盖(视口、配色方案、区域设置、时区、离线模式及类似状态),即使 OpenClaw 并未启动任何浏览器进程
|
||||
- 本地受管理配置文件:`openclaw browser stop` 会停止
|
||||
由 OpenClaw 启动的浏览器进程
|
||||
- attach-only 和远程 CDP 配置文件:`openclaw browser stop` 会关闭当前活动的
|
||||
控制会话,并释放 Playwright/CDP 模拟覆盖(视口、
|
||||
色彩方案、区域设置、时区、离线模式及类似状态),即使
|
||||
并没有由 OpenClaw 启动任何浏览器进程
|
||||
|
||||
远程 CDP URL 可以包含认证信息:
|
||||
|
||||
- 查询参数 token(例如 `https://provider.example?token=<token>`)
|
||||
- HTTP Basic 认证(例如 `https://user:pass@provider.example`)
|
||||
|
||||
OpenClaw 在调用 `/json/*` 端点以及连接到 CDP WebSocket 时都会保留认证信息。
|
||||
对于 token,优先使用环境变量或密钥管理器,而不是将它们提交到配置文件中。
|
||||
OpenClaw 在调用 `/json/*` 端点以及连接
|
||||
CDP WebSocket 时都会保留这些认证信息。对于 token,优先使用
|
||||
环境变量或密钥管理器,而不是将其提交到配置文件中。
|
||||
|
||||
## 节点浏览器代理(默认零配置)
|
||||
|
||||
如果你在拥有浏览器的机器上运行了**节点主机**,OpenClaw 可以
|
||||
自动将浏览器工具调用路由到该节点,而无需额外的浏览器配置。
|
||||
这是远程 Gateway 网关 的默认路径。
|
||||
如果你在拥有浏览器的机器上运行了一个**节点主机**,OpenClaw 可以
|
||||
自动将浏览器工具调用路由到该节点,而无需任何额外的浏览器配置。
|
||||
这是远程 Gateway 网关的默认路径。
|
||||
|
||||
说明:
|
||||
|
||||
- 节点主机会通过一个**代理命令**暴露其本地浏览器控制服务器。
|
||||
- 配置文件来自节点自己的 `browser.profiles` 配置(与本地相同)。
|
||||
- `nodeHost.browserProxy.allowProfiles` 是可选的。将其留空即可保留旧版/默认行为:所有已配置的配置文件都可通过代理访问,包括配置文件创建/删除路由。
|
||||
- 如果你设置了 `nodeHost.browserProxy.allowProfiles`,OpenClaw 会将其视为最小权限边界:只有 allowlist 中的配置文件可以作为目标,且持久化配置文件创建/删除路由会在代理界面上被阻止。
|
||||
- 如果你不想启用它,可以禁用:
|
||||
- `nodeHost.browserProxy.allowProfiles` 是可选的。若保持为空,则沿用旧版/默认行为:所有已配置配置文件都可通过代理访问,包括配置文件创建/删除路由。
|
||||
- 如果你设置了 `nodeHost.browserProxy.allowProfiles`,OpenClaw 会将其视为最小权限边界:只有允许列表中的配置文件可以作为目标,持久配置文件创建/删除路由也会在代理接口上被阻止。
|
||||
- 如果你不想启用它,可将其关闭:
|
||||
- 在节点上:`nodeHost.browserProxy.enabled=false`
|
||||
- 在网关上:`gateway.nodes.browser.mode="off"`
|
||||
- 在 Gateway 网关上:`gateway.nodes.browser.mode="off"`
|
||||
|
||||
## Browserless(托管远程 CDP)
|
||||
|
||||
[Browserless](https://browserless.io) 是一个托管的 Chromium 服务,通过 HTTPS 和 WebSocket 暴露
|
||||
CDP 连接 URL。OpenClaw 可以使用这两种形式,但对于远程浏览器配置文件来说,最简单的选项是使用 Browserless 连接文档中的直接 WebSocket URL。
|
||||
[Browserless](https://browserless.io) 是一个托管的 Chromium 服务,通过 HTTPS 和 WebSocket 暴露
|
||||
CDP 连接 URL。OpenClaw 可以使用任一形式,但对于远程浏览器配置文件,
|
||||
最简单的选项是使用 Browserless 连接文档中的直接 WebSocket URL。
|
||||
|
||||
示例:
|
||||
|
||||
@ -290,26 +311,37 @@ CDP 连接 URL。OpenClaw 可以使用这两种形式,但对于远程浏览器
|
||||
说明:
|
||||
|
||||
- 将 `<BROWSERLESS_API_KEY>` 替换为你真实的 Browserless token。
|
||||
- 选择与你的 Browserless 账户匹配的区域端点(参见其文档)。
|
||||
- 如果 Browserless 提供给你的是 HTTPS 基础 URL,你可以将其转换为
|
||||
`wss://` 以进行直接 CDP 连接,或者保留 HTTPS URL,让 OpenClaw
|
||||
- 选择与你的 Browserless 账号匹配的区域端点(参见其文档)。
|
||||
- 如果 Browserless 提供的是 HTTPS 基础 URL,你既可以将它转换为
|
||||
`wss://` 以建立直接 CDP 连接,也可以保留 HTTPS URL,让 OpenClaw
|
||||
自动发现 `/json/version`。
|
||||
|
||||
## 直接 WebSocket CDP 提供商
|
||||
|
||||
某些托管浏览器服务暴露的是**直接 WebSocket** 端点,而不是标准的基于 HTTP 的 CDP 发现机制(`/json/version`)。OpenClaw 接受三种 CDP URL 形式,并会自动选择正确的连接策略:
|
||||
一些托管浏览器服务暴露的是**直接 WebSocket** 端点,而不是
|
||||
标准的基于 HTTP 的 CDP 发现(`/json/version`)。OpenClaw 接受三种
|
||||
CDP URL 形式,并会自动选择正确的连接策略:
|
||||
|
||||
- **HTTP(S) 发现** — `http://host[:port]` 或 `https://host[:port]`。
|
||||
OpenClaw 会调用 `/json/version` 来发现 WebSocket 调试器 URL,然后进行连接。不提供 WebSocket 回退。
|
||||
- **直接 WebSocket 端点** — `ws://host[:port]/devtools/<kind>/<id>` 或
|
||||
`wss://...`,路径为 `/devtools/browser|page|worker|shared_worker|service_worker/<id>`。
|
||||
OpenClaw 会通过 WebSocket 握手直接连接,并完全跳过 `/json/version`。
|
||||
- **裸 WebSocket 根路径** — `ws://host[:port]` 或 `wss://host[:port]`,且不带
|
||||
`/devtools/...` 路径(例如 [Browserless](https://browserless.io)、[Browserbase](https://www.browserbase.com))。OpenClaw 会先尝试通过 HTTP 进行 `/json/version` 发现(将协议规范化为 `http`/`https`);如果发现结果返回 `webSocketDebuggerUrl`,则使用它,否则 OpenClaw 会回退为在裸根路径上直接进行 WebSocket 握手。这样一来,即使一个裸 `ws://` 指向本地 Chrome 也仍可连接,因为 Chrome 只接受来自 `/json/version` 返回的特定目标路径上的 WebSocket 升级。
|
||||
- **HTTP(S) 发现** — `http://host[:port]` 或 `https://host[:port]`。
|
||||
OpenClaw 会调用 `/json/version` 来发现 WebSocket 调试 URL,然后
|
||||
进行连接。不会回退到 WebSocket。
|
||||
- **直接 WebSocket 端点** — `ws://host[:port]/devtools/<kind>/<id>` 或
|
||||
`wss://...`,路径为 `/devtools/browser|page|worker|shared_worker|service_worker/<id>`。
|
||||
OpenClaw 会通过 WebSocket 握手直接连接,并完全跳过
|
||||
`/json/version`。
|
||||
- **裸 WebSocket 根路径** — `ws://host[:port]` 或 `wss://host[:port]`,且没有
|
||||
`/devtools/...` 路径(例如 [Browserless](https://browserless.io)、
|
||||
[Browserbase](https://www.browserbase.com))。OpenClaw 会先尝试 HTTP
|
||||
`/json/version` 发现(将协议规范化为 `http`/`https`);
|
||||
如果发现结果返回了 `webSocketDebuggerUrl`,就使用它,否则 OpenClaw
|
||||
会回退为在裸根路径上直接进行 WebSocket 握手。这样一来,即使裸 `ws://`
|
||||
指向的是本地 Chrome 也能连接,因为 Chrome 仅接受来自
|
||||
`/json/version` 返回的特定目标路径上的 WebSocket 升级。
|
||||
|
||||
### Browserbase
|
||||
|
||||
[Browserbase](https://www.browserbase.com) 是一个云平台,用于运行无头浏览器,内置 CAPTCHA 求解、隐身模式和住宅代理。
|
||||
[Browserbase](https://www.browserbase.com) 是一个云平台,用于运行
|
||||
无头浏览器,内置 CAPTCHA 求解、隐身模式和住宅代理。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -330,70 +362,80 @@ CDP 连接 URL。OpenClaw 可以使用这两种形式,但对于远程浏览器
|
||||
|
||||
说明:
|
||||
|
||||
- [注册](https://www.browserbase.com/sign-up),然后从 [Overview 仪表盘](https://www.browserbase.com/overview) 复制你的 **API Key**。
|
||||
- [注册](https://www.browserbase.com/sign-up),并从 [Overview dashboard](https://www.browserbase.com/overview) 复制你的**API Key**。
|
||||
- 将 `<BROWSERBASE_API_KEY>` 替换为你真实的 Browserbase API key。
|
||||
- Browserbase 会在 WebSocket 连接时自动创建浏览器会话,因此不需要手动创建会话步骤。
|
||||
- 免费套餐每月允许一个并发会话和一个浏览器小时。付费套餐限制请参见[定价](https://www.browserbase.com/pricing)。
|
||||
- 完整的 API 参考、SDK 指南和集成示例请参见 [Browserbase 文档](https://docs.browserbase.com)。
|
||||
- Browserbase 会在 WebSocket 连接时自动创建浏览器会话,因此
|
||||
无需手动创建会话。
|
||||
- 免费套餐每月允许一个并发会话和一个浏览器小时。
|
||||
付费套餐限制请参见 [pricing](https://www.browserbase.com/pricing)。
|
||||
- 完整 API
|
||||
参考、SDK 指南和集成示例请参见 [Browserbase docs](https://docs.browserbase.com)。
|
||||
|
||||
## 安全性
|
||||
## 安全
|
||||
|
||||
关键要点:
|
||||
关键概念:
|
||||
|
||||
- 浏览器控制仅限 loopback;访问通过 Gateway 网关 的身份验证或节点配对进行。
|
||||
- 独立的 loopback 浏览器 HTTP API **仅使用共享密钥认证**:
|
||||
gateway token bearer 认证、`x-openclaw-password`,或使用已配置 Gateway 网关密码的 HTTP Basic 认证。
|
||||
- Tailscale Serve 身份标头和 `gateway.auth.mode: "trusted-proxy"`
|
||||
**不能**为这个独立的 loopback 浏览器 API 提供认证。
|
||||
- 如果启用了浏览器控制且未配置共享密钥认证,OpenClaw 会在启动时
|
||||
自动生成 `gateway.auth.token` 并将其持久化到配置中。
|
||||
- 当 `gateway.auth.mode` 已经是 `password`、`none` 或 `trusted-proxy` 时,OpenClaw **不会**自动生成该 token。
|
||||
- 请将 Gateway 网关 和任何节点主机保持在私有网络中(Tailscale);避免公开暴露。
|
||||
- 将远程 CDP URL/token 视为机密;优先使用环境变量或密钥管理器。
|
||||
- 浏览器控制仅限 loopback;访问通过 Gateway 网关的认证或节点配对进行。
|
||||
- 独立的 loopback 浏览器 HTTP API **仅使用共享密钥认证**:
|
||||
Gateway 网关 token bearer 认证、`x-openclaw-password`,或使用
|
||||
已配置 Gateway 网关密码的 HTTP Basic 认证。
|
||||
- Tailscale Serve 身份头和 `gateway.auth.mode: "trusted-proxy"`
|
||||
**不会**为这个独立的 loopback 浏览器 API 提供认证。
|
||||
- 如果启用了浏览器控制且未配置共享密钥认证,OpenClaw
|
||||
会在启动时自动生成 `gateway.auth.token` 并将其持久化到配置中。
|
||||
- 当 `gateway.auth.mode` 已经是
|
||||
`password`、`none` 或 `trusted-proxy` 时,OpenClaw **不会**自动生成该 token。
|
||||
- 请将 Gateway 网关和所有节点主机保留在私有网络中(Tailscale);避免公开暴露。
|
||||
- 将远程 CDP URL/token 视为密钥;优先使用环境变量或密钥管理器。
|
||||
|
||||
远程 CDP 提示:
|
||||
|
||||
- 尽可能优先使用加密端点(HTTPS 或 WSS)和短期 token。
|
||||
- 尽可能优先使用加密端点(HTTPS 或 WSS)以及短期 token。
|
||||
- 避免将长期 token 直接嵌入配置文件。
|
||||
|
||||
## 配置文件(多浏览器)
|
||||
|
||||
OpenClaw 支持多个命名配置文件(路由配置)。配置文件可以是:
|
||||
|
||||
- **由 openclaw 管理**:一个专用的、基于 Chromium 的浏览器实例,拥有自己的用户数据目录 + CDP 端口
|
||||
- **远程**:显式的 CDP URL(浏览器运行在其他位置)
|
||||
- **现有会话**:通过 Chrome DevTools MCP 自动连接你现有的 Chrome 配置文件
|
||||
- **由 OpenClaw 管理**:一个独立的 Chromium 系浏览器实例,拥有自己的用户数据目录 + CDP 端口
|
||||
- **远程**:显式的 CDP URL(在其他地方运行的 Chromium 系浏览器)
|
||||
- **现有会话**:通过 Chrome DevTools MCP 自动连接到你现有的 Chrome 配置文件
|
||||
|
||||
默认值:
|
||||
默认行为:
|
||||
|
||||
- 如果缺少,`openclaw` 配置文件会自动创建。
|
||||
- `user` 配置文件是内置的,用于 Chrome MCP 的 existing-session 附加。
|
||||
- 除 `user` 之外,existing-session 配置文件需要显式启用;可通过 `--driver existing-session` 创建。
|
||||
- 本地 CDP 端口默认从 **18800–18899** 分配。
|
||||
- 删除配置文件时,其本地数据目录会被移到废纸篓。
|
||||
- 若缺失,`openclaw` 配置文件会自动创建。
|
||||
- `user` 配置文件是内置的,用于 Chrome MCP 现有会话附加。
|
||||
- 除 `user` 外,existing-session 配置文件需要主动启用;可使用 `--driver existing-session` 创建。
|
||||
- 默认情况下,本地 CDP 端口从 **18800–18899** 范围分配。
|
||||
- 删除某个配置文件时,其本地数据目录会被移到废纸篓。
|
||||
|
||||
所有控制端点都接受 `?profile=<name>`;CLI 使用 `--browser-profile`。
|
||||
|
||||
## 通过 Chrome DevTools MCP 使用 existing-session
|
||||
## 通过 Chrome DevTools MCP 使用现有会话
|
||||
|
||||
OpenClaw 还可以通过官方的 Chrome DevTools MCP 服务器附加到一个正在运行的、基于 Chromium 的浏览器配置文件。这样会复用该浏览器配置文件中已经打开的标签页和登录状态。
|
||||
OpenClaw 也可以通过
|
||||
官方 Chrome DevTools MCP 服务器附加到正在运行的 Chromium 系浏览器配置文件。
|
||||
这样可以复用该浏览器配置文件中
|
||||
已经打开的标签页和登录状态。
|
||||
|
||||
官方背景与设置参考:
|
||||
官方背景说明和设置参考:
|
||||
|
||||
- [Chrome for Developers:在你的浏览器会话中使用 Chrome DevTools MCP](https://developer.chrome.com/blog/chrome-devtools-mcp-debug-your-browser-session)
|
||||
- [Chrome for Developers: Use Chrome DevTools MCP with your browser session](https://developer.chrome.com/blog/chrome-devtools-mcp-debug-your-browser-session)
|
||||
- [Chrome DevTools MCP README](https://github.com/ChromeDevTools/chrome-devtools-mcp)
|
||||
|
||||
内置配置文件:
|
||||
|
||||
- `user`
|
||||
|
||||
可选:如果你希望使用不同的名称、颜色或浏览器数据目录,可以创建你自己的自定义 existing-session 配置文件。
|
||||
可选:如果你希望使用不同的名称、颜色或浏览器数据目录,
|
||||
可以创建自己的自定义 existing-session 配置文件。
|
||||
|
||||
默认行为:
|
||||
|
||||
- 内置的 `user` 配置文件使用 Chrome MCP 自动连接,目标是默认的本地 Google Chrome 配置文件。
|
||||
- 内置的 `user` 配置文件使用 Chrome MCP 自动连接,其目标是
|
||||
默认本地 Google Chrome 配置文件。
|
||||
|
||||
对于 Brave、Edge、Chromium 或非默认的 Chrome 配置文件,请使用 `userDataDir`:
|
||||
对于 Brave、Edge、Chromium 或非默认 Chrome 配置文件,请使用 `userDataDir`:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -410,13 +452,13 @@ OpenClaw 还可以通过官方的 Chrome DevTools MCP 服务器附加到一个
|
||||
}
|
||||
```
|
||||
|
||||
然后在对应的浏览器中:
|
||||
然后在对应浏览器中执行以下操作:
|
||||
|
||||
1. 打开该浏览器用于远程调试的 inspect 页面。
|
||||
1. 打开该浏览器的远程调试检查页面。
|
||||
2. 启用远程调试。
|
||||
3. 保持浏览器运行,并在 OpenClaw 附加时批准连接提示。
|
||||
|
||||
常见的 inspect 页面:
|
||||
常见检查页面:
|
||||
|
||||
- Chrome:`chrome://inspect/#remote-debugging`
|
||||
- Brave:`brave://inspect/#remote-debugging`
|
||||
@ -436,50 +478,60 @@ openclaw browser --browser-profile user snapshot --format ai
|
||||
- `status` 显示 `driver: existing-session`
|
||||
- `status` 显示 `transport: chrome-mcp`
|
||||
- `status` 显示 `running: true`
|
||||
- `tabs` 会列出你已经打开的浏览器标签页
|
||||
- `snapshot` 会返回所选实时标签页中的 ref
|
||||
- `tabs` 会列出你已打开的浏览器标签页
|
||||
- `snapshot` 会从当前选中的实时标签页返回 refs
|
||||
|
||||
如果附加不起作用,请检查:
|
||||
如果附加失败,请检查以下内容:
|
||||
|
||||
- 目标的 Chromium 浏览器版本为 `144+`
|
||||
- 已在该浏览器的 inspect 页面中启用远程调试
|
||||
- 浏览器显示了附加同意提示,且你已接受
|
||||
- `openclaw doctor` 会迁移旧的基于扩展的浏览器配置,并检查默认自动连接配置文件所需的 Chrome 是否已在本地安装,但它无法替你启用浏览器端的远程调试
|
||||
- 目标 Chromium 系浏览器的版本为 `144+`
|
||||
- 已在该浏览器的检查页面中启用远程调试
|
||||
- 浏览器已显示附加授权提示,并且你已接受
|
||||
- `openclaw doctor` 会迁移旧的基于扩展的浏览器配置,并检查
|
||||
对于默认自动连接配置文件,本地是否安装了 Chrome,但它不能
|
||||
代替你在浏览器端启用远程调试
|
||||
|
||||
智能体使用方式:
|
||||
|
||||
- 当你需要用户已登录的浏览器状态时,使用 `profile="user"`。
|
||||
- 如果你使用自定义 existing-session 配置文件,请传入该显式配置文件名称。
|
||||
- 只有当用户就在电脑前可以批准附加提示时,才选择这种模式。
|
||||
- Gateway 网关 或节点主机可以启动 `npx chrome-devtools-mcp@latest --autoConnect`
|
||||
- 当你需要用户已登录浏览器状态时,使用 `profile="user"`。
|
||||
- 如果你使用自定义 existing-session 配置文件,请传入明确的配置文件名称。
|
||||
- 只有在用户正在电脑前并能批准附加
|
||||
提示时,才选择此模式。
|
||||
- Gateway 网关或节点主机可以启动 `npx chrome-devtools-mcp@latest --autoConnect`
|
||||
|
||||
说明:
|
||||
|
||||
- 与隔离的 `openclaw` 配置文件相比,这条路径风险更高,因为它可以在你已登录的浏览器会话中执行操作。
|
||||
- 与隔离的 `openclaw` 配置文件相比,这条路径风险更高,因为它可以
|
||||
在你已登录的浏览器会话中执行操作。
|
||||
- 对于这个驱动,OpenClaw 不会启动浏览器;它只会附加。
|
||||
- OpenClaw 在这里使用官方的 Chrome DevTools MCP `--autoConnect` 流程。如果设置了 `userDataDir`,它会被透传以定位该用户数据目录。
|
||||
- existing-session 可以附加到选定的主机上,也可以通过已连接的浏览器节点附加。如果 Chrome 位于其他地方且没有连接浏览器节点,请改用远程 CDP 或节点主机。
|
||||
- OpenClaw 在这里使用官方的 Chrome DevTools MCP `--autoConnect` 流程。如果
|
||||
设置了 `userDataDir`,它会一并传递,以定位该用户数据目录。
|
||||
- existing-session 可以附加到所选主机上,也可以通过已连接的
|
||||
浏览器节点附加。如果 Chrome 在其他地方运行且没有连接浏览器节点,请改用
|
||||
远程 CDP 或节点主机。
|
||||
|
||||
<Accordion title="existing-session 功能限制">
|
||||
|
||||
与受管理的 `openclaw` 配置文件相比,existing-session 驱动的限制更多:
|
||||
|
||||
- **截图** — 支持页面截图和 `--ref` 元素截图;不支持 CSS `--element` 选择器。`--full-page` 不能与 `--ref` 或 `--element` 组合使用。页面截图或基于 ref 的元素截图不要求 Playwright。
|
||||
- **操作** — `click`、`type`、`hover`、`scrollIntoView`、`drag` 和 `select` 需要 snapshot ref(不支持 CSS 选择器)。`click` 仅支持鼠标左键。`type` 不支持 `slowly=true`;请使用 `fill` 或 `press`。`press` 不支持 `delayMs`。`type`、`hover`、`scrollIntoView`、`drag`、`select`、`fill` 和 `evaluate` 不支持按调用单独设置超时。`select` 接受单个值。
|
||||
- **等待 / 上传 / 对话框** — `wait --url` 支持精确、子串和 glob 模式;不支持 `wait --load networkidle`。上传钩子需要 `ref` 或 `inputRef`,一次一个文件,不支持 CSS `element`。对话框钩子不支持超时覆盖。
|
||||
- **仅受管理模式支持的功能** — 批量操作、PDF 导出、下载拦截和 `responsebody` 仍然需要受管理浏览器路径。
|
||||
- **截图** —— 支持页面截图和 `--ref` 元素截图;不支持 CSS `--element` 选择器。`--full-page` 不能与 `--ref` 或 `--element` 组合使用。页面截图或基于 ref 的元素截图不需要 Playwright。
|
||||
- **操作** —— `click`、`type`、`hover`、`scrollIntoView`、`drag` 和 `select` 需要快照 refs(不支持 CSS 选择器)。`click` 仅支持左键。`type` 不支持 `slowly=true`;请使用 `fill` 或 `press`。`press` 不支持 `delayMs`。`type`、`hover`、`scrollIntoView`、`drag`、`select`、`fill` 和 `evaluate` 不支持按调用单独设置超时。`select` 只接受单个值。
|
||||
- **等待 / 上传 / 对话框** —— `wait --url` 支持精确匹配、子串匹配和 glob 模式;不支持 `wait --load networkidle`。上传钩子要求提供 `ref` 或 `inputRef`,一次一个文件,不支持 CSS `element`。对话框钩子不支持超时覆盖。
|
||||
- **仅受管理模式支持的功能** —— 批量操作、PDF 导出、下载拦截和 `responsebody` 仍然需要受管理浏览器路径。
|
||||
|
||||
</Accordion>
|
||||
|
||||
## 隔离保证
|
||||
|
||||
- **专用用户数据目录**:绝不会触碰你的个人浏览器配置文件。
|
||||
- **专用端口**:避开 `9222`,防止与开发工作流发生冲突。
|
||||
- **可预测的标签页控制**:`tabs` 会先返回 `suggestedTargetId`,然后是稳定的 `tabId` 句柄(例如 `t1`)、可选标签,以及原始 `targetId`。智能体应优先复用 `suggestedTargetId`;原始 id 仍保留用于调试和兼容性。
|
||||
- **专用端口**:避免使用 `9222`,防止与开发工作流冲突。
|
||||
- **可预测的标签页控制**:`tabs` 会先返回 `suggestedTargetId`,然后是
|
||||
稳定的 `tabId` 句柄,例如 `t1`、可选标签以及原始 `targetId`。
|
||||
智能体应优先复用 `suggestedTargetId`;原始 id 仍保留用于
|
||||
调试和兼容性。
|
||||
|
||||
## 浏览器选择
|
||||
|
||||
在本地启动时,OpenClaw 会选择第一个可用的浏览器:
|
||||
在本地启动时,OpenClaw 会选择第一个可用项:
|
||||
|
||||
1. Chrome
|
||||
2. Brave
|
||||
@ -487,7 +539,7 @@ openclaw browser --browser-profile user snapshot --format ai
|
||||
4. Chromium
|
||||
5. Chrome Canary
|
||||
|
||||
你可以通过 `browser.executablePath` 覆盖该选择。
|
||||
你可以通过 `browser.executablePath` 覆盖它。
|
||||
|
||||
平台说明:
|
||||
|
||||
@ -497,32 +549,35 @@ openclaw browser --browser-profile user snapshot --format ai
|
||||
|
||||
## 控制 API(可选)
|
||||
|
||||
对于脚本编写和调试,Gateway 网关 会暴露一个小型的**仅限 loopback 的 HTTP 控制 API**,以及与之匹配的 `openclaw browser` CLI(快照、ref、wait 增强功能、JSON 输出、调试工作流)。完整参考请参见[浏览器控制 API](/zh-CN/tools/browser-control)。
|
||||
为了方便脚本和调试,Gateway 网关暴露了一个小型的**仅限 loopback 的 HTTP
|
||||
控制 API**,以及与之匹配的 `openclaw browser` CLI(快照、refs、wait
|
||||
增强能力、JSON 输出、调试工作流)。完整参考请参见
|
||||
[浏览器控制 API](/zh-CN/tools/browser-control)。
|
||||
|
||||
## 故障排除
|
||||
|
||||
有关 Linux 特定问题(尤其是 snap Chromium),请参见
|
||||
Linux 特定问题(尤其是 snap Chromium)请参见
|
||||
[浏览器故障排除](/zh-CN/tools/browser-linux-troubleshooting)。
|
||||
|
||||
有关 WSL2 Gateway 网关 + Windows Chrome 分离主机配置,请参见
|
||||
对于 WSL2 Gateway 网关 + Windows Chrome 分离主机场景,请参见
|
||||
[WSL2 + Windows + 远程 Chrome CDP 故障排除](/zh-CN/tools/browser-wsl2-windows-remote-cdp-troubleshooting)。
|
||||
|
||||
### CDP 启动失败与导航 SSRF 阻止
|
||||
### CDP 启动失败 vs 导航 SSRF 拦截
|
||||
|
||||
这两类失败是不同的,分别指向不同的代码路径。
|
||||
这是两类不同的失败,它们指向不同的代码路径。
|
||||
|
||||
- **CDP 启动或就绪失败** 表示 OpenClaw 无法确认浏览器控制平面处于健康状态。
|
||||
- **导航 SSRF 阻止** 表示浏览器控制平面是健康的,但页面导航目标被策略拒绝。
|
||||
- **导航 SSRF 拦截** 表示浏览器控制平面是健康的,但页面导航目标被策略拒绝。
|
||||
|
||||
常见示例:
|
||||
|
||||
- CDP 启动或就绪失败:
|
||||
- `Chrome CDP websocket for profile "openclaw" is not reachable after start`
|
||||
- `Remote CDP for profile "<name>" is not reachable at <cdpUrl>`
|
||||
- 导航 SSRF 阻止:
|
||||
- 当 `start` 和 `tabs` 仍然可用时,`open`、`navigate`、snapshot 或打开标签页流程因浏览器/网络策略错误而失败
|
||||
- 导航 SSRF 拦截:
|
||||
- 当 `start` 和 `tabs` 仍然可用时,`open`、`navigate`、快照或打开标签页流程因浏览器/网络策略错误而失败
|
||||
|
||||
使用下面这个最小序列来区分两者:
|
||||
使用下面这组最小命令来区分两者:
|
||||
|
||||
```bash
|
||||
openclaw browser --browser-profile openclaw start
|
||||
@ -530,48 +585,48 @@ openclaw browser --browser-profile openclaw tabs
|
||||
openclaw browser --browser-profile openclaw open https://example.com
|
||||
```
|
||||
|
||||
如何解读结果:
|
||||
结果解读方式:
|
||||
|
||||
- 如果 `start` 失败并显示 `not reachable after start`,先排查 CDP 就绪性问题。
|
||||
- 如果 `start` 成功但 `tabs` 失败,则控制平面仍然不健康。应将其视为 CDP 可达性问题,而不是页面导航问题。
|
||||
- 如果 `start` 和 `tabs` 成功,但 `open` 或 `navigate` 失败,则浏览器控制平面已启动,失败原因在导航策略或目标页面。
|
||||
- 如果 `start` 失败并显示 `not reachable after start`,请先排查 CDP 就绪状态。
|
||||
- 如果 `start` 成功但 `tabs` 失败,说明控制平面仍然不健康。应将其视为 CDP 可达性问题,而不是页面导航问题。
|
||||
- 如果 `start` 和 `tabs` 成功,但 `open` 或 `navigate` 失败,则说明浏览器控制平面已启动,失败原因在于导航策略或目标页面。
|
||||
- 如果 `start`、`tabs` 和 `open` 全部成功,则基础的受管理浏览器控制路径是健康的。
|
||||
|
||||
重要行为细节:
|
||||
|
||||
- 即使你没有配置 `browser.ssrfPolicy`,浏览器配置默认也会使用一个失败即关闭的 SSRF 策略对象。
|
||||
- 对于本地 loopback 的 `openclaw` 受管理配置文件,CDP 健康检查会有意跳过浏览器 SSRF 可达性强制校验,以允许 OpenClaw 自身的本地控制平面正常工作。
|
||||
- 导航保护是独立的。`start` 或 `tabs` 成功,并不意味着之后的 `open` 或 `navigate` 目标一定被允许。
|
||||
- 即使你没有配置 `browser.ssrfPolicy`,浏览器配置默认也会使用一个默认拒绝的 SSRF 策略对象。
|
||||
- 对于本地 loopback 的 `openclaw` 受管理配置文件,CDP 健康检查会有意跳过对 OpenClaw 自身本地控制平面的浏览器 SSRF 可达性强制检查。
|
||||
- 导航保护是分开的。`start` 或 `tabs` 成功,并不意味着后续的 `open` 或 `navigate` 目标一定被允许。
|
||||
|
||||
安全建议:
|
||||
|
||||
- **不要**默认放宽浏览器 SSRF 策略。
|
||||
- 与广泛开放私有网络访问相比,优先使用更窄范围的主机例外,例如 `hostnameAllowlist` 或 `allowedHostnames`。
|
||||
- 仅在明确受信任、确实需要并且已经过审查的私有网络浏览器访问环境中,才使用 `dangerouslyAllowPrivateNetwork: true`。
|
||||
- 相比宽泛地开放私有网络访问,更推荐使用精确的主机例外,例如 `hostnameAllowlist` 或 `allowedHostnames`。
|
||||
- 仅在明确可信、且确实需要并已审查私有网络浏览器访问的环境中,才使用 `dangerouslyAllowPrivateNetwork: true`。
|
||||
|
||||
## 智能体工具 + 控制原理
|
||||
## 智能体工具 + 控制如何工作
|
||||
|
||||
智能体会获得**一个工具**用于浏览器自动化:
|
||||
|
||||
- `browser` — doctor/status/start/stop/tabs/open/focus/close/snapshot/screenshot/navigate/act
|
||||
|
||||
其映射方式如下:
|
||||
其映射关系如下:
|
||||
|
||||
- `browser snapshot` 返回稳定的 UI 树(AI 或 ARIA)。
|
||||
- `browser act` 使用 snapshot 中的 `ref` ID 来执行点击/输入/拖拽/选择。
|
||||
- `browser screenshot` 捕获像素截图(整页、元素或已标记的 ref)。
|
||||
- `browser doctor` 检查 Gateway 网关、插件、配置文件、浏览器和标签页就绪状态。
|
||||
- `browser act` 使用快照中的 `ref` ID 执行点击/输入/拖动/选择。
|
||||
- `browser screenshot` 捕获像素截图(整页、元素或带标签的 refs)。
|
||||
- `browser doctor` 检查 Gateway 网关、插件、配置文件、浏览器和标签页的就绪状态。
|
||||
- `browser` 接受:
|
||||
- `profile`,用于选择命名浏览器配置文件(openclaw、chrome 或远程 CDP)。
|
||||
- `target`(`sandbox` | `host` | `node`),用于选择浏览器所在位置。
|
||||
- 在沙箱隔离会话中,`target: "host"` 需要 `agents.defaults.sandbox.browser.allowHostControl=true`。
|
||||
- 如果省略 `target`:沙箱隔离会话默认使用 `sandbox`,非沙箱会话默认使用 `host`。
|
||||
- 如果已连接支持浏览器的节点,工具可能会自动路由到该节点,除非你固定指定 `target="host"` 或 `target="node"`。
|
||||
- 在沙箱会话中,`target: "host"` 需要 `agents.defaults.sandbox.browser.allowHostControl=true`。
|
||||
- 如果省略 `target`:沙箱会话默认使用 `sandbox`,非沙箱会话默认使用 `host`。
|
||||
- 如果已连接具备浏览器能力的节点,除非你固定指定 `target="host"` 或 `target="node"`,否则该工具可能会自动路由到该节点。
|
||||
|
||||
这样可以让智能体行为保持可预测,并避免脆弱的选择器。
|
||||
|
||||
## 相关内容
|
||||
|
||||
- [工具概览](/zh-CN/tools) — 所有可用的智能体工具
|
||||
- [沙箱隔离](/zh-CN/gateway/sandboxing) — 沙箱隔离环境中的浏览器控制
|
||||
- [安全性](/zh-CN/gateway/security) — 浏览器控制的风险与加固
|
||||
- [沙箱隔离](/zh-CN/gateway/sandboxing) — 沙箱环境中的浏览器控制
|
||||
- [安全](/zh-CN/gateway/security) — 浏览器控制的风险与加固
|
||||
|
||||
@ -1,26 +1,26 @@
|
||||
---
|
||||
read_when:
|
||||
- 安装或配置插件
|
||||
- 了解插件发现和加载规则
|
||||
- 使用与 Codex/Claude 兼容的插件包
|
||||
- 安装或配置插件时
|
||||
- 了解插件发现和加载规则时
|
||||
- 处理与 Codex / Claude 兼容的插件包时
|
||||
sidebarTitle: Install and Configure
|
||||
summary: 安装、配置和管理 OpenClaw 插件
|
||||
title: 插件
|
||||
x-i18n:
|
||||
generated_at: "2026-04-24T23:09:48Z"
|
||||
generated_at: "2026-04-25T02:37:24Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: 7d962119bcb2bf94da08fcd48d4da8be76618104ea3c37ce60e2fcf397b05c98
|
||||
source_hash: 4e41595020c5f1702e3288eb07c88482cb820b78b33ea27154af788e8da80fa1
|
||||
source_path: tools/plugin.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
插件通过新增能力来扩展 OpenClaw:渠道、模型提供商、智能体 harness、工具、Skills、语音、实时转写、实时语音、媒体理解、图像生成、视频生成、网页抓取、网页搜索等。有些插件是**核心**插件(随 OpenClaw 一起发布),另一些则是**外部**插件(由社区在 npm 上发布)。
|
||||
插件可为 OpenClaw 扩展新能力:渠道、模型提供商、Agent harnesses、工具、Skills、语音、实时转录、实时语音、媒体理解、图像生成、视频生成、网页抓取、网页搜索等。有些插件是 **core**(随 OpenClaw 一起发布),另一些是 **external**(由社区发布到 npm)。
|
||||
|
||||
## 快速开始
|
||||
|
||||
<Steps>
|
||||
<Step title="查看已加载的内容">
|
||||
<Step title="查看已加载内容">
|
||||
```bash
|
||||
openclaw plugins list
|
||||
```
|
||||
@ -28,10 +28,10 @@ x-i18n:
|
||||
|
||||
<Step title="安装插件">
|
||||
```bash
|
||||
# 从 npm
|
||||
# From npm
|
||||
openclaw plugins install @openclaw/voice-call
|
||||
|
||||
# 从本地目录或归档文件
|
||||
# From a local directory or archive
|
||||
openclaw plugins install ./my-plugin
|
||||
openclaw plugins install ./my-plugin.tgz
|
||||
```
|
||||
@ -43,12 +43,12 @@ x-i18n:
|
||||
openclaw gateway restart
|
||||
```
|
||||
|
||||
然后在你的配置文件中,通过 `plugins.entries.\<id\>.config` 进行配置。
|
||||
然后在你的配置文件中的 `plugins.entries.\<id\>.config` 下进行配置。
|
||||
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
如果你更喜欢使用聊天原生控制方式,请启用 `commands.plugins: true` 并使用:
|
||||
如果你更喜欢聊天原生控制,请启用 `commands.plugins: true` 并使用:
|
||||
|
||||
```text
|
||||
/plugin install clawhub:@openclaw/voice-call
|
||||
@ -56,11 +56,21 @@ x-i18n:
|
||||
/plugin enable voice-call
|
||||
```
|
||||
|
||||
安装路径使用与 CLI 相同的解析器:本地路径/归档、显式 `clawhub:<pkg>`,或裸包规范(优先 ClawHub,然后回退到 npm)。
|
||||
安装路径使用与 CLI 相同的解析器:本地路径 / 归档、显式 `clawhub:<pkg>`,或裸包规范(优先 ClawHub,然后回退到 npm)。
|
||||
|
||||
如果配置无效,安装通常会以失败关闭的方式结束,并提示你运行 `openclaw doctor --fix`。唯一的恢复例外是一个有限的内置插件重装路径,适用于选择启用 `openclaw.install.allowInvalidConfigRecovery` 的插件。
|
||||
如果配置无效,安装通常会以失败关闭方式结束,并引导你使用
|
||||
`openclaw doctor --fix`。唯一的恢复例外是一个较窄的内置插件重装路径,
|
||||
适用于选择启用
|
||||
`openclaw.install.allowInvalidConfigRecovery`
|
||||
的插件。
|
||||
|
||||
打包后的 OpenClaw 安装不会急切地安装每个内置插件的运行时依赖树。当一个由 OpenClaw 拥有的内置插件通过插件配置、旧版渠道配置或默认启用的清单处于激活状态时,启动修复只会在导入该插件之前修复该插件声明的运行时依赖。显式禁用仍然优先:`plugins.entries.<id>.enabled: false`、`plugins.deny`、`plugins.enabled: false` 和 `channels.<id>.enabled: false` 会阻止为该插件/渠道自动修复内置运行时依赖。外部插件和自定义加载路径仍然必须通过 `openclaw plugins install` 安装。
|
||||
打包后的 OpenClaw 安装不会急切安装每个内置插件的完整运行时依赖树。
|
||||
当某个内置且由 OpenClaw 拥有的插件通过插件配置、旧版渠道配置或默认启用的清单处于活动状态时,启动修复只会在导入该插件之前修复该插件声明的运行时依赖。显式禁用仍然优先:`plugins.entries.<id>.enabled: false`、
|
||||
`plugins.deny`、`plugins.enabled: false` 和 `channels.<id>.enabled: false`
|
||||
都会阻止该插件 / 渠道的内置运行时依赖自动修复。
|
||||
外部插件和自定义加载路径仍必须通过
|
||||
`openclaw plugins install`
|
||||
进行安装。
|
||||
|
||||
## 插件类型
|
||||
|
||||
@ -68,12 +78,13 @@ OpenClaw 可识别两种插件格式:
|
||||
|
||||
| 格式 | 工作方式 | 示例 |
|
||||
| ---------- | ------------------------------------------------------------------ | ------------------------------------------------------ |
|
||||
| **原生** | `openclaw.plugin.json` + 运行时模块;在进程内执行 | 官方插件、社区 npm 包 |
|
||||
| **Bundle** | 与 Codex/Claude/Cursor 兼容的布局;映射到 OpenClaw 功能 | `.codex-plugin/`、`.claude-plugin/`、`.cursor-plugin/` |
|
||||
| **Native** | `openclaw.plugin.json` + 运行时模块;在进程内执行 | 官方插件、社区 npm 包 |
|
||||
| **Bundle** | 与 Codex / Claude / Cursor 兼容的布局;映射到 OpenClaw 功能 | `.codex-plugin/`、`.claude-plugin/`、`.cursor-plugin/` |
|
||||
|
||||
两者都会显示在 `openclaw plugins list` 中。有关 bundle 的详细信息,请参阅 [Plugin Bundles](/zh-CN/plugins/bundles)。
|
||||
这两种都会显示在 `openclaw plugins list` 下。有关 bundle 的详细信息,请参见 [插件包](/zh-CN/plugins/bundles)。
|
||||
|
||||
如果你要编写原生插件,请从 [构建插件](/zh-CN/plugins/building-plugins) 和 [插件 SDK 概览](/zh-CN/plugins/sdk-overview) 开始。
|
||||
如果你正在编写原生插件,请从 [构建插件](/zh-CN/plugins/building-plugins)
|
||||
和 [插件 SDK 概览](/zh-CN/plugins/sdk-overview) 开始。
|
||||
|
||||
## 官方插件
|
||||
|
||||
@ -88,33 +99,33 @@ OpenClaw 可识别两种插件格式:
|
||||
| Zalo | `@openclaw/zalo` | [Zalo](/zh-CN/channels/zalo) |
|
||||
| Zalo Personal | `@openclaw/zalouser` | [Zalo Personal](/zh-CN/plugins/zalouser) |
|
||||
|
||||
### 核心(随 OpenClaw 一起发布)
|
||||
### Core(随 OpenClaw 一起发布)
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="模型提供商(默认启用)">
|
||||
`anthropic`, `byteplus`, `cloudflare-ai-gateway`, `github-copilot`, `google`,
|
||||
`huggingface`, `kilocode`, `kimi-coding`, `minimax`, `mistral`, `qwen`,
|
||||
`moonshot`, `nvidia`, `openai`, `opencode`, `opencode-go`, `openrouter`,
|
||||
`qianfan`, `synthetic`, `together`, `venice`,
|
||||
`vercel-ai-gateway`, `volcengine`, `xiaomi`, `zai`
|
||||
`anthropic`、`byteplus`、`cloudflare-ai-gateway`、`github-copilot`、`google`、
|
||||
`huggingface`、`kilocode`、`kimi-coding`、`minimax`、`mistral`、`qwen`、
|
||||
`moonshot`、`nvidia`、`openai`、`opencode`、`opencode-go`、`openrouter`、
|
||||
`qianfan`、`synthetic`、`together`、`venice`、
|
||||
`vercel-ai-gateway`、`volcengine`、`xiaomi`、`zai`
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="记忆插件">
|
||||
- `memory-core` — 内置的记忆搜索(默认通过 `plugins.slots.memory` 使用)
|
||||
- `memory-lancedb` — 按需安装的长期记忆,支持自动召回/捕获(设置 `plugins.slots.memory = "memory-lancedb"`)
|
||||
<Accordion title="Memory 插件">
|
||||
- `memory-core` — 内置内存搜索(默认通过 `plugins.slots.memory`)
|
||||
- `memory-lancedb` — 按需安装的长期记忆,带自动召回 / 捕获(设置 `plugins.slots.memory = "memory-lancedb"`)
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="语音提供商(默认启用)">
|
||||
`elevenlabs`, `microsoft`
|
||||
`elevenlabs`、`microsoft`
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="其他">
|
||||
- `browser` — 用于浏览器工具、`openclaw browser` CLI、`browser.request` Gateway 网关方法、浏览器运行时以及默认浏览器控制服务的内置浏览器插件(默认启用;在替换它之前请先禁用)
|
||||
- `browser` — 用于浏览器工具、`openclaw browser` CLI、`browser.request` Gateway 网关方法、浏览器运行时以及默认浏览器控制服务的内置浏览器插件(默认启用;替换前请先禁用)
|
||||
- `copilot-proxy` — VS Code Copilot Proxy 桥接(默认禁用)
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
在寻找第三方插件?请参阅 [Community Plugins](/zh-CN/plugins/community)。
|
||||
在找第三方插件?请参见 [社区插件](/zh-CN/plugins/community)。
|
||||
|
||||
## 配置
|
||||
|
||||
@ -132,26 +143,32 @@ OpenClaw 可识别两种插件格式:
|
||||
}
|
||||
```
|
||||
|
||||
| 字段 | 说明 |
|
||||
| 字段 | 描述 |
|
||||
| ---------------- | --------------------------------------------------------- |
|
||||
| `enabled` | 总开关(默认:`true`) |
|
||||
| `allow` | 插件允许列表(可选) |
|
||||
| `deny` | 插件拒绝列表(可选;拒绝优先) |
|
||||
| `load.paths` | 额外的插件文件/目录 |
|
||||
| `slots` | 独占插槽选择器(例如 `memory`、`contextEngine`) |
|
||||
| `entries.\<id\>` | 按插件分别设置的开关 + 配置 |
|
||||
| `load.paths` | 额外的插件文件 / 目录 |
|
||||
| `slots` | 独占槽位选择器(例如 `memory`、`contextEngine`) |
|
||||
| `entries.\<id\>` | 按插件的开关 + 配置 |
|
||||
|
||||
配置更改**需要重启 Gateway 网关**。如果 Gateway 网关正在以启用配置监听和进程内重启的方式运行(默认的 `openclaw gateway` 路径),通常会在配置写入完成后不久自动执行重启。对于原生插件运行时代码或生命周期钩子,没有受支持的热重载路径;在你期望更新后的 `register(api)` 代码、`api.on(...)` 钩子、工具、服务或提供商/运行时钩子生效之前,请重启正在服务实时渠道的 Gateway 网关进程。
|
||||
配置更改**需要重启 Gateway 网关**。如果 Gateway 网关以启用配置监视和进程内重启的方式运行(默认的 `openclaw gateway` 路径),那么在配置写入落地后,通常会在片刻后自动执行该重启。
|
||||
原生插件运行时代码或生命周期钩子没有受支持的热重载路径;在期望更新后的 `register(api)` 代码、`api.on(...)` 钩子、工具、服务或提供商 / 运行时钩子生效之前,请重启正在服务实时渠道的 Gateway 网关进程。
|
||||
|
||||
`openclaw plugins list` 是本地 CLI/配置快照。那里显示为 `loaded` 的插件,表示从该次 CLI 调用所看到的配置/文件中,该插件可被发现且可被加载。这并不能证明一个已在运行的远程 Gateway 网关子进程已经重启并使用了相同的插件代码。在 VPS/容器部署中,如果有包装进程,请将重启发送到实际的 `openclaw gateway run` 进程,或对正在运行的 Gateway 网关使用 `openclaw gateway restart`。
|
||||
`openclaw plugins list` 是本地 CLI / 配置快照。那里显示为 `loaded`
|
||||
的插件表示该插件可从该次 CLI 调用所看到的配置 / 文件中被发现并加载。
|
||||
这并不能证明一个已经运行的远程 Gateway 网关子进程已经重启到相同的插件代码。
|
||||
在使用包装进程的 VPS / 容器部署中,请将重启发送到实际的
|
||||
`openclaw gateway run`
|
||||
进程,或对正在运行的 Gateway 网关使用 `openclaw gateway restart`。
|
||||
|
||||
<Accordion title="插件状态:已禁用 vs 缺失 vs 无效">
|
||||
- **已禁用**:插件存在,但启用规则将其关闭。配置会被保留。
|
||||
- **缺失**:配置引用了某个插件 id,但在发现过程中未找到它。
|
||||
- **无效**:插件存在,但其配置与声明的 schema 不匹配。
|
||||
<Accordion title="插件状态:disabled、missing、invalid">
|
||||
- **Disabled**:插件存在,但启用规则将其关闭。配置会被保留。
|
||||
- **Missing**:配置引用了某个插件 ID,但发现过程未找到该插件。
|
||||
- **Invalid**:插件存在,但其配置与声明的 schema 不匹配。
|
||||
</Accordion>
|
||||
|
||||
## 发现顺序和优先级
|
||||
## 发现与优先级
|
||||
|
||||
OpenClaw 按以下顺序扫描插件(先匹配者优先):
|
||||
|
||||
@ -169,79 +186,90 @@ OpenClaw 按以下顺序扫描插件(先匹配者优先):
|
||||
</Step>
|
||||
|
||||
<Step title="内置插件">
|
||||
随 OpenClaw 一起发布。其中许多默认启用(模型提供商、语音)。
|
||||
其他插件则需要显式启用。
|
||||
随 OpenClaw 一起发布。许多默认启用(模型提供商、语音)。
|
||||
其他则需要显式启用。
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
### 启用规则
|
||||
|
||||
- `plugins.enabled: false` 会禁用所有插件
|
||||
- `plugins.deny` 总是优先于 allow
|
||||
- `plugins.deny` 始终优先于 allow
|
||||
- `plugins.entries.\<id\>.enabled: false` 会禁用该插件
|
||||
- 来自工作区的插件**默认禁用**(必须显式启用)
|
||||
- 工作区来源的插件**默认禁用**(必须显式启用)
|
||||
- 内置插件遵循内建的默认启用集合,除非被覆盖
|
||||
- 独占插槽可以强制启用该插槽中被选中的插件
|
||||
- 某些内置的可选启用插件会在配置命名了某个插件拥有的表面时自动启用,例如提供商模型引用、渠道配置或 harness 运行时
|
||||
- OpenAI 家族的 Codex 路由保持独立的插件边界:
|
||||
`openai-codex/*` 属于 OpenAI 插件,而内置 Codex app-server 插件则通过 `embeddedHarness.runtime: "codex"` 或旧版 `codex/*` 模型引用来选择
|
||||
- 独占槽位可强制启用为该槽位选定的插件
|
||||
- 某些内置的按需启用插件会在配置命名某个插件拥有的表面时自动启用,
|
||||
例如提供商模型引用、渠道配置或 harness 运行时
|
||||
- OpenAI 系列 Codex 路由保持独立的插件边界:
|
||||
`openai-codex/*` 属于 OpenAI 插件,而内置的 Codex
|
||||
app-server 插件由 `embeddedHarness.runtime: "codex"` 或旧版
|
||||
`codex/*` 模型引用选定
|
||||
|
||||
## 运行时钩子故障排除
|
||||
|
||||
如果某个插件出现在 `plugins list` 中,但 `register(api)` 副作用或钩子没有在实时聊天流量中运行,请先检查以下内容:
|
||||
如果某个插件出现在 `plugins list` 中,但 `register(api)` 副作用或钩子
|
||||
未在实时聊天流量中运行,请先检查以下内容:
|
||||
|
||||
- 运行 `openclaw gateway status --deep --require-rpc`,确认活动的 Gateway 网关 URL、配置文件、配置路径和进程就是你正在编辑的那些。
|
||||
- 在插件安装/配置/代码更改后重启实时 Gateway 网关。在包装容器中,PID 1 可能只是一个 supervisor;请重启或向子 `openclaw gateway run` 进程发送信号。
|
||||
- 使用 `openclaw plugins inspect <id> --json` 确认钩子注册和诊断信息。非内置的会话钩子,如 `llm_input`、`llm_output` 和 `agent_end`,需要设置 `plugins.entries.<id>.hooks.allowConversationAccess=true`。
|
||||
- 对于模型切换,优先使用 `before_model_resolve`。它会在智能体轮次进行模型解析之前运行;`llm_output` 只会在某次模型尝试生成 assistant 输出之后运行。
|
||||
- 若要证明会话实际使用的模型,请使用 `openclaw sessions` 或 Gateway 网关的会话/状态表面;调试提供商负载时,请使用 `--raw-stream --raw-stream-path <path>` 启动 Gateway 网关。
|
||||
- 运行 `openclaw gateway status --deep --require-rpc` 并确认活动的
|
||||
Gateway 网关 URL、配置文件、配置路径和进程正是你在编辑的那些。
|
||||
- 在插件安装 / 配置 / 代码更改后重启实时 Gateway 网关。在包装容器中,
|
||||
PID 1 可能只是一个监督进程;请重启或向子进程
|
||||
`openclaw gateway run`
|
||||
发送信号。
|
||||
- 使用 `openclaw plugins inspect <id> --json` 确认钩子注册和
|
||||
诊断信息。像 `llm_input`、
|
||||
`llm_output` 和 `agent_end` 这样的非内置会话钩子需要
|
||||
`plugins.entries.<id>.hooks.allowConversationAccess=true`。
|
||||
- 对于模型切换,优先使用 `before_model_resolve`。它会在智能体轮次的模型解析前运行;`llm_output` 只会在模型尝试产生助手输出后运行。
|
||||
- 如需证明有效的会话模型,请使用 `openclaw sessions` 或 Gateway 网关会话 / 状态表面;在调试提供商负载时,请使用 `--raw-stream --raw-stream-path <path>` 启动 Gateway 网关。
|
||||
|
||||
## 插件插槽(独占类别)
|
||||
## 插件槽位(独占类别)
|
||||
|
||||
某些类别是独占的(同一时间只能激活一个):
|
||||
某些类别是独占的(同一时间只能有一个处于活动状态):
|
||||
|
||||
```json5
|
||||
{
|
||||
plugins: {
|
||||
slots: {
|
||||
memory: "memory-core", // 或 "none" 以禁用
|
||||
contextEngine: "legacy", // 或某个插件 id
|
||||
memory: "memory-core", // or "none" to disable
|
||||
contextEngine: "legacy", // or a plugin id
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
| 插槽 | 控制内容 | 默认值 |
|
||||
| 槽位 | 控制内容 | 默认值 |
|
||||
| --------------- | --------------------- | ------------------- |
|
||||
| `memory` | 当前激活的记忆插件 | `memory-core` |
|
||||
| `contextEngine` | 当前激活的上下文引擎 | `legacy`(内建) |
|
||||
| `memory` | 活动 Memory 插件 | `memory-core` |
|
||||
| `contextEngine` | 活动上下文引擎 | `legacy`(内建) |
|
||||
|
||||
## CLI 参考
|
||||
|
||||
```bash
|
||||
openclaw plugins list # 精简清单
|
||||
openclaw plugins list --enabled # 仅显示已加载的插件
|
||||
openclaw plugins list --verbose # 每个插件的详细信息行
|
||||
openclaw plugins list # 紧凑清单
|
||||
openclaw plugins list --enabled # 仅已加载插件
|
||||
openclaw plugins list --verbose # 每个插件的详细行
|
||||
openclaw plugins list --json # 机器可读清单
|
||||
openclaw plugins inspect <id> # 深度详情
|
||||
openclaw plugins inspect <id> --json # 机器可读
|
||||
openclaw plugins inspect --all # 全量范围表格
|
||||
openclaw plugins inspect --all # 全局表格
|
||||
openclaw plugins info <id> # inspect 别名
|
||||
openclaw plugins doctor # 诊断
|
||||
|
||||
openclaw plugins install <package> # 安装(优先 ClawHub,然后回退到 npm)
|
||||
openclaw plugins install <package> # 安装(优先 ClawHub,然后 npm)
|
||||
openclaw plugins install clawhub:<pkg> # 仅从 ClawHub 安装
|
||||
openclaw plugins install <spec> --force # 覆盖现有安装
|
||||
openclaw plugins install <path> # 从本地路径安装
|
||||
openclaw plugins install -l <path> # 链接(不复制),用于开发
|
||||
openclaw plugins install <plugin> --marketplace <source>
|
||||
openclaw plugins install <plugin> --marketplace https://github.com/<owner>/<repo>
|
||||
openclaw plugins install <spec> --pin # 记录精确解析后的 npm spec
|
||||
openclaw plugins install <spec> --pin # 记录精确解析的 npm spec
|
||||
openclaw plugins install <spec> --dangerously-force-unsafe-install
|
||||
openclaw plugins update <id-or-npm-spec> # 更新单个插件
|
||||
openclaw plugins update <id-or-npm-spec> --dangerously-force-unsafe-install
|
||||
openclaw plugins update --all # 更新全部
|
||||
openclaw plugins uninstall <id> # 删除配置/安装记录
|
||||
openclaw plugins uninstall <id> # 移除配置 / 安装记录
|
||||
openclaw plugins uninstall <id> --keep-files
|
||||
openclaw plugins marketplace list <source>
|
||||
openclaw plugins marketplace list <source> --json
|
||||
@ -250,31 +278,31 @@ openclaw plugins enable <id>
|
||||
openclaw plugins disable <id>
|
||||
```
|
||||
|
||||
内置插件随 OpenClaw 一起发布。许多插件默认启用(例如内置模型提供商、内置语音提供商,以及内置浏览器插件)。其他内置插件仍然需要运行 `openclaw plugins enable <id>`。
|
||||
内置插件随 OpenClaw 一起发布。许多默认启用(例如内置模型提供商、内置语音提供商以及内置浏览器插件)。其他内置插件仍需要运行 `openclaw plugins enable <id>`。
|
||||
|
||||
`--force` 会就地覆盖现有已安装的插件或 hook 包。对于已跟踪 npm 插件的常规升级,请使用 `openclaw plugins update <id-or-npm-spec>`。它不支持与 `--link` 一起使用,因为后者会复用源路径,而不是复制到受管理的安装目标中。
|
||||
`--force` 会原地覆盖已安装的插件或 hook pack。对于已跟踪 npm 插件的常规升级,请使用 `openclaw plugins update <id-or-npm-spec>`。它不支持与 `--link` 一起使用,因为后者会复用源路径,而不是复制到受管理的安装目标。
|
||||
|
||||
当 `plugins.allow` 已设置时,`openclaw plugins install` 会先把已安装插件的 id 添加到该允许列表中,然后再启用它,因此插件在重启后可以立即被加载。
|
||||
当已设置 `plugins.allow` 时,`openclaw plugins install` 会在启用插件前,将已安装插件的 id 添加到该允许列表中,因此插件在重启后可立即加载。
|
||||
|
||||
`openclaw plugins update <id-or-npm-spec>` 适用于已跟踪的安装。传入带有 dist-tag 或精确版本的 npm 包 spec 时,会将包名解析回已跟踪的插件记录,并记录新的 spec 以供后续更新使用。传入不带版本的包名时,会将一个精确固定版本的安装恢复到注册表的默认发布线。如果已安装的 npm 插件已经与解析出的版本和记录的工件标识一致,OpenClaw 会跳过更新,不会下载、重新安装或重写配置。
|
||||
`openclaw plugins update <id-or-npm-spec>` 适用于已跟踪的安装。传入带 dist-tag 或精确版本的 npm 包规范时,会将包名解析回已跟踪的插件记录,并为将来的更新记录新的 spec。传入不带版本的包名时,会将精确固定的安装移回注册表的默认发布线。如果已安装的 npm 插件已经与解析后的版本和记录的产物标识一致,OpenClaw 会跳过更新,不会下载、重新安装或重写配置。
|
||||
|
||||
`--pin` 仅适用于 npm。它不支持与 `--marketplace` 一起使用,因为 marketplace 安装会持久化 marketplace 源元数据,而不是 npm spec。
|
||||
`--pin` 仅适用于 npm。它不支持与 `--marketplace` 一起使用,因为 marketplace 安装会持久化 marketplace 来源元数据,而不是 npm spec。
|
||||
|
||||
`--dangerously-force-unsafe-install` 是一个紧急破玻璃式覆盖选项,用于处理内置危险代码扫描器的误报。它允许插件安装和插件更新在遇到内置 `critical` 发现后继续执行,但仍不会绕过插件 `before_install` 策略阻止或扫描失败阻止。
|
||||
`--dangerously-force-unsafe-install` 是用于内置危险代码扫描器误报的紧急覆盖开关。它允许插件安装和插件更新在遇到内置 `critical` 发现后继续进行,但仍不会绕过插件 `before_install` 策略阻止或扫描失败阻止。
|
||||
|
||||
这个 CLI 标志只适用于插件安装/更新流程。由 Gateway 网关支持的 Skills 依赖安装则改用对应的 `dangerouslyForceUnsafeInstall` 请求覆盖,而 `openclaw skills install` 仍然是独立的 ClawHub Skills 下载/安装流程。
|
||||
这个 CLI 标志仅适用于插件安装 / 更新流程。由 Gateway 网关支持的 Skills 依赖安装则使用对应的 `dangerouslyForceUnsafeInstall` 请求覆盖,而 `openclaw skills install` 仍是独立的 ClawHub Skills 下载 / 安装流程。
|
||||
|
||||
兼容的 bundle 会参与同样的插件 list/inspect/enable/disable 流程。当前运行时支持包括 bundle Skills、Claude command-skills、Claude `settings.json` 默认值、Claude `.lsp.json` 和 manifest 声明的 `lspServers` 默认值、Cursor command-skills,以及兼容的 Codex hook 目录。
|
||||
兼容的 bundle 会参与相同的插件 list / inspect / enable / disable 流程。当前运行时支持包括 bundle Skills、Claude command-skills、Claude `settings.json` 默认值、Claude `.lsp.json` 和清单声明的 `lspServers` 默认值、Cursor command-skills,以及兼容的 Codex hook 目录。
|
||||
|
||||
`openclaw plugins inspect <id>` 还会报告检测到的 bundle 能力,以及由 bundle 支持或不支持的 MCP 和 LSP 服务器条目。
|
||||
`openclaw plugins inspect <id>` 还会报告检测到的 bundle 能力,以及由 bundle 支持的或不支持的 MCP 和 LSP server 条目。
|
||||
|
||||
Marketplace 源可以是 `~/.claude/plugins/known_marketplaces.json` 中的 Claude 已知 marketplace 名称、本地 marketplace 根目录或 `marketplace.json` 路径、类似 `owner/repo` 的 GitHub 简写、GitHub 仓库 URL,或 git URL。对于远程 marketplace,插件条目必须保持在克隆的 marketplace 仓库内,并且只能使用相对路径源。
|
||||
Marketplace 来源可以是 `~/.claude/plugins/known_marketplaces.json` 中的 Claude 已知 marketplace 名称、本地 marketplace 根目录或 `marketplace.json` 路径、类似 `owner/repo` 的 GitHub 简写、GitHub 仓库 URL,或 git URL。对于远程 marketplace,插件条目必须保持在克隆后的 marketplace 仓库内,并且只能使用相对路径来源。
|
||||
|
||||
有关完整详情,请参阅 [`openclaw plugins` CLI 参考](/zh-CN/cli/plugins)。
|
||||
完整信息请参见 [`openclaw plugins` CLI 参考](/zh-CN/cli/plugins)。
|
||||
|
||||
## 插件 API 概览
|
||||
|
||||
原生插件会导出一个入口对象,该对象暴露 `register(api)`。旧版插件仍可能使用 `activate(api)` 作为旧版别名,但新插件应使用 `register`。
|
||||
原生插件会导出一个入口对象,并公开 `register(api)`。较旧的插件仍可能使用 `activate(api)` 作为旧版别名,但新插件应使用 `register`。
|
||||
|
||||
```typescript
|
||||
export default definePluginEntry({
|
||||
@ -294,19 +322,19 @@ export default definePluginEntry({
|
||||
});
|
||||
```
|
||||
|
||||
OpenClaw 会加载该入口对象,并在插件激活期间调用 `register(api)`。加载器仍会为旧版插件回退到 `activate(api)`,但内置插件和新的外部插件应将 `register` 视为公开契约。
|
||||
OpenClaw 会加载该入口对象,并在插件激活期间调用 `register(api)`。加载器仍会为旧插件回退到 `activate(api)`,但内置插件和新的外部插件应将 `register` 视为公开契约。
|
||||
|
||||
`api.registrationMode` 会告诉插件其入口正在因何种原因被加载:
|
||||
`api.registrationMode` 会告诉插件其入口为何被加载:
|
||||
|
||||
| 模式 | 含义 |
|
||||
| --------------- | ------------------------------------------------------------------------------------------------------ |
|
||||
| `full` | 运行时激活。注册工具、钩子、服务、命令、路由和其他实时副作用。 |
|
||||
| `discovery` | 只读能力发现。注册提供商和元数据,但跳过高成本的实时副作用。 |
|
||||
| `setup-only` | 通过轻量设置入口加载渠道设置元数据。 |
|
||||
| `setup-runtime` | 加载渠道设置,同时也需要运行时入口。 |
|
||||
| --------------- | -------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `full` | 运行时激活。注册工具、钩子、服务、命令、路由以及其他实时副作用。 |
|
||||
| `discovery` | 只读能力发现。注册提供商和元数据;受信任的插件入口代码可能会被加载,但要跳过实时副作用。 |
|
||||
| `setup-only` | 通过轻量级设置入口加载渠道设置元数据。 |
|
||||
| `setup-runtime` | 需要运行时入口的渠道设置加载。 |
|
||||
| `cli-metadata` | 仅收集 CLI 命令元数据。 |
|
||||
|
||||
如果插件入口会打开 socket、数据库、后台 worker 或长生命周期客户端,应使用 `api.registrationMode === "full"` 来保护这些副作用。发现加载会与激活加载分开缓存,并且不会替换正在运行的 Gateway 网关注册表。
|
||||
会打开套接字、数据库、后台工作进程或长生命周期客户端的插件入口,应使用 `api.registrationMode === "full"` 来保护这些副作用。发现加载与激活加载会分别缓存,且不会替换正在运行的 Gateway 网关注册表。发现是非激活式的,而不是免导入的:OpenClaw 可能会求值受信任的插件入口或渠道插件模块以构建快照。请保持模块顶层轻量且无副作用,并将网络客户端、子进程、监听器、凭证读取和服务启动移到完整运行时路径后面。
|
||||
|
||||
常见注册方法:
|
||||
|
||||
@ -318,8 +346,8 @@ OpenClaw 会加载该入口对象,并在插件激活期间调用 `register(api
|
||||
| `registerHook` / `on(...)` | 生命周期钩子 |
|
||||
| `registerSpeechProvider` | 文本转语音 / STT |
|
||||
| `registerRealtimeTranscriptionProvider` | 流式 STT |
|
||||
| `registerRealtimeVoiceProvider` | 双工实时语音 |
|
||||
| `registerMediaUnderstandingProvider` | 图像/音频分析 |
|
||||
| `registerRealtimeVoiceProvider` | 双向实时语音 |
|
||||
| `registerMediaUnderstandingProvider` | 图像 / 音频分析 |
|
||||
| `registerImageGenerationProvider` | 图像生成 |
|
||||
| `registerMusicGenerationProvider` | 音乐生成 |
|
||||
| `registerVideoGenerationProvider` | 视频生成 |
|
||||
@ -332,22 +360,22 @@ OpenClaw 会加载该入口对象,并在插件激活期间调用 `register(api
|
||||
|
||||
类型化生命周期钩子的钩子保护行为:
|
||||
|
||||
- `before_tool_call`:`{ block: true }` 是终止性的;更低优先级的处理器会被跳过。
|
||||
- `before_tool_call`:`{ block: false }` 不执行任何操作,也不会清除之前的阻止。
|
||||
- `before_install`:`{ block: true }` 是终止性的;更低优先级的处理器会被跳过。
|
||||
- `before_install`:`{ block: false }` 不执行任何操作,也不会清除之前的阻止。
|
||||
- `message_sending`:`{ cancel: true }` 是终止性的;更低优先级的处理器会被跳过。
|
||||
- `message_sending`:`{ cancel: false }` 不执行任何操作,也不会清除之前的取消。
|
||||
- `before_tool_call`:`{ block: true }` 为终止性结果;较低优先级处理器会被跳过。
|
||||
- `before_tool_call`:`{ block: false }` 为无操作,不会清除更早的阻止。
|
||||
- `before_install`:`{ block: true }` 为终止性结果;较低优先级处理器会被跳过。
|
||||
- `before_install`:`{ block: false }` 为无操作,不会清除更早的阻止。
|
||||
- `message_sending`:`{ cancel: true }` 为终止性结果;较低优先级处理器会被跳过。
|
||||
- `message_sending`:`{ cancel: false }` 为无操作,不会清除更早的取消。
|
||||
|
||||
原生 Codex app-server 会将桥接的 Codex 原生工具事件回传到这个钩子表面。插件可以通过 `before_tool_call` 阻止原生 Codex 工具,通过 `after_tool_call` 观察结果,并参与 Codex `PermissionRequest` 批准。该桥接目前尚不会重写 Codex 原生工具参数。
|
||||
原生 Codex app-server 会将桥接的 Codex 原生工具事件回传到这个钩子表面。插件可以通过 `before_tool_call` 阻止原生 Codex 工具,通过 `after_tool_call` 观察结果,并参与 Codex 的 `PermissionRequest` 批准。该桥接目前尚不会重写 Codex 原生工具参数。
|
||||
|
||||
有关完整的类型化钩子行为,请参阅 [SDK 概览](/zh-CN/plugins/sdk-overview#hook-decision-semantics)。
|
||||
有关完整的类型化钩子行为,请参见 [SDK 概览](/zh-CN/plugins/sdk-overview#hook-decision-semantics)。
|
||||
|
||||
## 相关内容
|
||||
## 相关
|
||||
|
||||
- [构建插件](/zh-CN/plugins/building-plugins) — 创建你自己的插件
|
||||
- [Plugin Bundles](/zh-CN/plugins/bundles) — Codex/Claude/Cursor bundle 兼容性
|
||||
- [Plugin Manifest](/zh-CN/plugins/manifest) — manifest schema
|
||||
- [插件包](/zh-CN/plugins/bundles) — 与 Codex / Claude / Cursor 的插件包兼容性
|
||||
- [插件清单](/zh-CN/plugins/manifest) — 清单 schema
|
||||
- [注册工具](/zh-CN/plugins/building-plugins#registering-agent-tools) — 在插件中添加智能体工具
|
||||
- [Plugin Internals](/zh-CN/plugins/architecture) — 能力模型和加载流水线
|
||||
- [Community Plugins](/zh-CN/plugins/community) — 第三方列表
|
||||
- [插件内部机制](/zh-CN/plugins/architecture) — 能力模型和加载流水线
|
||||
- [社区插件](/zh-CN/plugins/community) — 第三方列表
|
||||
|
||||
@ -1,55 +1,56 @@
|
||||
---
|
||||
read_when:
|
||||
- 添加或修改 Skills
|
||||
- 更改 Skills 的门控或加载规则
|
||||
summary: Skills:托管模式与工作区模式、门控规则,以及配置/环境变量接线
|
||||
- 更改 Skills 门控或加载规则
|
||||
summary: Skills:托管型与工作区型、门控规则,以及配置/环境变量接线
|
||||
title: Skills
|
||||
x-i18n:
|
||||
generated_at: "2026-04-24T23:30:18Z"
|
||||
generated_at: "2026-04-25T02:37:37Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: 346058f4d85cd66f7b05f6ddd7ee3b8959f05da8645c62ce5531a955eedf7a83
|
||||
source_hash: 44f946d91588c878754340aaf55e0e3b9096bba12aea36fb90c445cd41e4f892
|
||||
source_path: tools/skills.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
OpenClaw 使用与 **[AgentSkills](https://agentskills.io)** 兼容的 skill 文件夹来教会智能体如何使用工具。每个 skill 都是一个目录,包含带有 YAML frontmatter 和说明的 `SKILL.md`。OpenClaw 会加载**内置 skills**以及可选的本地覆盖项,并在加载时根据环境、配置和二进制文件是否存在来进行筛选。
|
||||
OpenClaw 使用与 **[AgentSkills](https://agentskills.io)** 兼容的 Skills 文件夹来教智能体如何使用工具。每个 Skill 都是一个目录,包含带有 YAML frontmatter 和说明的 `SKILL.md`。OpenClaw 会加载**内置 Skills**以及可选的本地覆盖,并在加载时根据环境、配置和二进制文件是否存在进行过滤。
|
||||
|
||||
## 位置与优先级
|
||||
|
||||
OpenClaw 会从以下来源加载 skills:
|
||||
OpenClaw 会从以下来源加载 Skills:
|
||||
|
||||
1. **额外 skill 文件夹**:通过 `skills.load.extraDirs` 配置
|
||||
2. **内置 skills**:随安装包一起提供(`npm` 包或 OpenClaw.app)
|
||||
3. **托管/本地 skills**:`~/.openclaw/skills`
|
||||
4. **个人 agent skills**:`~/.agents/skills`
|
||||
5. **项目 agent skills**:`<workspace>/.agents/skills`
|
||||
6. **工作区 skills**:`<workspace>/skills`
|
||||
1. **额外 Skills 文件夹**:通过 `skills.load.extraDirs` 配置
|
||||
2. **内置 Skills**:随安装一起提供(npm 包或 OpenClaw.app)
|
||||
3. **托管/本地 Skills**:`~/.openclaw/skills`
|
||||
4. **个人 agent Skills**:`~/.agents/skills`
|
||||
5. **项目 agent Skills**:`<workspace>/.agents/skills`
|
||||
6. **工作区 Skills**:`<workspace>/skills`
|
||||
|
||||
如果 skill 名称冲突,优先级如下:
|
||||
如果 Skill 名称冲突,优先级为:
|
||||
|
||||
`<workspace>/skills`(最高)→ `<workspace>/.agents/skills` → `~/.agents/skills` → `~/.openclaw/skills` → 内置 skills → `skills.load.extraDirs`(最低)
|
||||
`<workspace>/skills`(最高)→ `<workspace>/.agents/skills` → `~/.agents/skills` → `~/.openclaw/skills` → 内置 Skills → `skills.load.extraDirs`(最低)
|
||||
|
||||
## 按 agent 区分的 skills 与共享 skills
|
||||
## 每个智能体专属 Skills 与共享 Skills
|
||||
|
||||
在**多智能体**设置中,每个智能体都有自己的工作区。这意味着:
|
||||
|
||||
- **按 agent 区分的 skills** 仅存在于该 agent 的 `<workspace>/skills` 中。
|
||||
- **项目 agent skills** 位于 `<workspace>/.agents/skills`,会在普通工作区 `skills/` 文件夹之前应用到该工作区。
|
||||
- **个人 agent skills** 位于 `~/.agents/skills`,会应用到该机器上的所有工作区。
|
||||
- **共享 skills** 位于 `~/.openclaw/skills`(托管/本地),并且同一台机器上的**所有智能体**都可见。
|
||||
- 如果你想让多个智能体共用同一套 skills,也可以通过 `skills.load.extraDirs` 添加**共享文件夹**(最低优先级)。
|
||||
- **每个智能体专属 Skills** 位于该智能体自己的 `<workspace>/skills` 中。
|
||||
- **项目 agent Skills** 位于 `<workspace>/.agents/skills` 中,并会在普通工作区 `skills/` 文件夹之前应用于该工作区。
|
||||
- **个人 agent Skills** 位于 `~/.agents/skills` 中,并应用于该机器上的所有工作区。
|
||||
- **共享 Skills** 位于 `~/.openclaw/skills`(托管/本地)中,并对同一台机器上的**所有智能体**可见。
|
||||
- 如果你想为多个智能体使用同一个通用 Skills 包,也可以通过 `skills.load.extraDirs` 添加**共享文件夹**(最低优先级)。
|
||||
|
||||
如果同一个 skill 名称出现在多个位置,则仍按通常的优先级处理:工作区优先,其次是项目 agent skills、个人 agent skills、托管/本地 skills、内置 skills,最后是额外目录。
|
||||
如果同一个 Skill 名称在多个位置存在,则仍适用通常的优先级规则:工作区优先,然后是项目 agent Skills,再然后是个人 agent Skills,然后是托管/本地 Skills,再然后是内置 Skills,最后是额外目录。
|
||||
|
||||
## 每个 agent 的 skill 允许列表
|
||||
## 智能体 Skill 允许列表
|
||||
|
||||
Skill 的**位置**和 skill 的**可见性**是两套独立控制。
|
||||
Skill 的**位置**和 Skill 的**可见性**是两个独立的控制项。
|
||||
|
||||
- 位置/优先级决定同名 skill 中哪一份会胜出。
|
||||
- Agent 允许列表决定某个 agent 实际上可以使用哪些可见 skills。
|
||||
- 位置/优先级决定同名 Skill 中哪一个副本胜出。
|
||||
- 智能体允许列表决定某个智能体实际可以使用哪些可见 Skills。
|
||||
|
||||
对共享基线使用 `agents.defaults.skills`,然后通过 `agents.list[].skills` 为每个 agent 覆盖:
|
||||
使用 `agents.defaults.skills` 作为共享基线,然后通过
|
||||
`agents.list[].skills` 为每个智能体覆盖:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -60,7 +61,7 @@ Skill 的**位置**和 skill 的**可见性**是两套独立控制。
|
||||
list: [
|
||||
{ id: "writer" }, // 继承 github、weather
|
||||
{ id: "docs", skills: ["docs-search"] }, // 替换默认值
|
||||
{ id: "locked-down", skills: [] }, // 无 skills
|
||||
{ id: "locked-down", skills: [] }, // 无 Skills
|
||||
],
|
||||
},
|
||||
}
|
||||
@ -68,58 +69,60 @@ Skill 的**位置**和 skill 的**可见性**是两套独立控制。
|
||||
|
||||
规则:
|
||||
|
||||
- 省略 `agents.defaults.skills` 表示默认不限制 skills。
|
||||
- 省略 `agents.list[].skills` 表示继承 `agents.defaults.skills`。
|
||||
- 将 `agents.list[].skills: []` 设为空表示不使用任何 skills。
|
||||
- 非空的 `agents.list[].skills` 列表就是该 agent 的最终集合;它不会与默认值合并。
|
||||
- 默认情况下,如果希望 Skills 不受限制,请省略 `agents.defaults.skills`。
|
||||
- 省略 `agents.list[].skills` 以继承 `agents.defaults.skills`。
|
||||
- 将 `agents.list[].skills: []` 设为空表示不使用任何 Skills。
|
||||
- 非空的 `agents.list[].skills` 列表就是该智能体的最终集合;它不会与默认值合并。
|
||||
|
||||
OpenClaw 会将生效后的 agent skill 集合应用到提示词构建、skill 斜杠命令发现、沙箱同步以及 skill 快照中。
|
||||
OpenClaw 会在提示构建、Skill 斜杠命令发现、沙箱同步以及 Skill 快照中应用智能体的生效 Skill 集合。
|
||||
|
||||
## 插件 + skills
|
||||
## 插件 + Skills
|
||||
|
||||
插件可以通过在 `openclaw.plugin.json` 中列出 `skills` 目录来附带自己的 skills(路径相对于插件根目录)。插件启用时,插件 skills 就会加载。对于那些过长而不适合放在工具描述中、但又应在插件安装后始终可用的工具专用操作指南,这是正确的放置位置;例如,浏览器插件附带了一个 `browser-automation` skill,用于多步骤浏览器控制。目前,这些目录会并入与 `skills.load.extraDirs` 相同的低优先级路径,因此同名的内置、托管、agent 或工作区 skill 都会覆盖它们。
|
||||
你可以通过插件配置项上的 `metadata.openclaw.requires.config` 对它们进行门控。有关发现/配置,请参见 [Plugins](/zh-CN/tools/plugin);有关这些 skills 所教授的工具表面,请参见 [Tools](/zh-CN/tools)。
|
||||
插件可以通过在 `openclaw.plugin.json` 中列出 `skills` 目录(相对于插件根目录的路径)来附带自己的 Skills。插件启用时,这些插件 Skills 会被加载。对于那些太长而不适合放进工具描述、但只要插件安装好就应该可用的工具专用操作指南,这是正确的放置位置;例如,浏览器插件附带了一个 `browser-automation` Skill,用于多步骤浏览器控制。当前,这些目录会被合并到与 `skills.load.extraDirs` 相同的低优先级路径中,因此同名的内置、托管、agent 或工作区 Skill 会覆盖它们。
|
||||
你可以通过插件配置项上的 `metadata.openclaw.requires.config` 对其进行门控。关于发现/配置,请参见 [插件](/zh-CN/tools/plugin);关于这些 Skills 所教授的工具接口,请参见 [工具](/zh-CN/tools)。
|
||||
|
||||
## Skill Workshop
|
||||
|
||||
可选且实验性的 Skill Workshop 插件可以根据 agent 工作过程中观察到的可复用流程,创建或更新工作区 skills。它默认禁用,必须通过 `plugins.entries.skill-workshop` 显式启用。
|
||||
可选的实验性 Skill Workshop 插件可以根据智能体工作期间观察到的可复用流程来创建或更新工作区 Skills。它默认禁用,必须通过
|
||||
`plugins.entries.skill-workshop` 显式启用。
|
||||
|
||||
Skill Workshop 只会写入 `<workspace>/skills`,会扫描生成内容,支持“待批准”或“自动安全写入”,会隔离不安全提案,并在成功写入后刷新 skill 快照,以便新 skills 无需重启 Gateway 网关即可变为可用。
|
||||
Skill Workshop 只会写入 `<workspace>/skills`,会扫描生成的内容,支持待审批或自动安全写入,会隔离不安全的提案,并在成功写入后刷新 Skill 快照,从而使新 Skills 无需重启 Gateway 网关即可变为可用。
|
||||
|
||||
当你希望把诸如“下次请验证 GIF 归属”这样的修正,或诸如媒体 QA 检查清单这样的宝贵工作流,沉淀为持久的过程性说明时,就可以使用它。建议从“待批准”开始;只有在受信任的工作区中,并且审查过其提案后,才使用自动写入。完整指南:
|
||||
[Skill Workshop Plugin](/zh-CN/plugins/skill-workshop)。
|
||||
当你希望将诸如“下次请验证 GIF 署名”之类的修正,或媒体 QA 检查清单之类来之不易的工作流,沉淀为持久的程序性说明时,就可以使用它。建议先从待审批模式开始;只有在受信任的工作区中并且审查过其提案后,才使用自动写入。完整指南:
|
||||
[Skill Workshop 插件](/zh-CN/plugins/skill-workshop)。
|
||||
|
||||
## ClawHub(安装 + 同步)
|
||||
|
||||
ClawHub 是 OpenClaw 的公共 skills 注册表。可在
|
||||
ClawHub 是 OpenClaw 的公共 Skills 注册表。可在
|
||||
[https://clawhub.ai](https://clawhub.ai) 浏览。使用原生 `openclaw skills`
|
||||
命令来发现/安装/更新 skills;如果你需要发布/同步工作流,则使用独立的 `clawhub` CLI。
|
||||
命令来发现/安装/更新 Skills;如果你需要发布/同步工作流,则使用单独的 `clawhub` CLI。
|
||||
完整指南:[ClawHub](/zh-CN/tools/clawhub)。
|
||||
|
||||
常见流程:
|
||||
|
||||
- 将一个 skill 安装到你的工作区:
|
||||
- 将一个 Skill 安装到你的工作区:
|
||||
- `openclaw skills install <skill-slug>`
|
||||
- 更新所有已安装 skills:
|
||||
- 更新所有已安装 Skills:
|
||||
- `openclaw skills update --all`
|
||||
- 同步(扫描 + 发布更新):
|
||||
- `clawhub sync --all`
|
||||
|
||||
原生 `openclaw skills install` 会安装到当前工作区的 `skills/`
|
||||
目录中。独立的 `clawhub` CLI 也会安装到当前工作目录下的 `./skills` 中(或者回退到已配置的 OpenClaw 工作区)。
|
||||
OpenClaw 会在下一次会话中将其识别为 `<workspace>/skills`。
|
||||
目录中。单独的 `clawhub` CLI 也会安装到你当前工作目录下的 `./skills` 中(或者回退到已配置的 OpenClaw 工作区)。
|
||||
OpenClaw 会在下一次会话中将其作为 `<workspace>/skills` 加载。
|
||||
|
||||
## 安全说明
|
||||
|
||||
- 将第三方 skills 视为**不受信任的代码**。启用前请先阅读。
|
||||
- 对于不受信任的输入和高风险工具,优先使用沙箱隔离运行。参见 [沙箱隔离](/zh-CN/gateway/sandboxing)。
|
||||
- 工作区和额外目录中的 skill 发现,只接受其解析后的 realpath 仍位于配置根目录内的 skill 根目录和 `SKILL.md` 文件。
|
||||
- 由 Gateway 网关支持的 skill 依赖安装(`skills.install`、新手引导以及 Skills 设置 UI)在执行安装器元数据之前,会先运行内置的危险代码扫描器。默认情况下,`critical` 级别发现会阻止执行,除非调用方显式设置危险覆盖;可疑发现仍然只会发出警告。
|
||||
- `openclaw skills install <slug>` 不同:它会将一个 ClawHub skill 文件夹下载到工作区中,不会使用上述安装器元数据路径。
|
||||
- `skills.entries.*.env` 和 `skills.entries.*.apiKey` 会将密钥注入该 agent 轮次的**宿主机**进程中(而不是沙箱)。请让密钥远离提示词和日志。
|
||||
- 更广泛的威胁模型和检查清单,请参见 [Security](/zh-CN/gateway/security)。
|
||||
- 将第三方 Skills 视为**不受信任的代码**。启用前请先阅读。
|
||||
- 对于不受信任的输入和高风险工具,优先使用沙箱隔离运行。请参见[沙箱隔离](/zh-CN/gateway/sandboxing)。
|
||||
- 工作区和额外目录中的 Skill 发现只接受那些其解析后 realpath 仍位于已配置根目录内的 Skill 根目录和 `SKILL.md` 文件。
|
||||
- 由 Gateway 网关支持的 Skill 依赖安装(`skills.install`、新手引导以及 Skills 设置 UI)在执行安装器元数据前会运行内置危险代码扫描器。默认情况下,`critical` 级发现会阻止执行,除非调用方显式设置危险覆盖;可疑发现仍然只会发出警告。
|
||||
- `openclaw skills install <slug>` 是不同的:它会把一个 ClawHub Skill 文件夹下载到工作区中,不使用上述安装器元数据路径。
|
||||
- `skills.entries.*.env` 和 `skills.entries.*.apiKey` 会将密钥注入到该智能体轮次的**宿主机**进程中
|
||||
(而不是沙箱)。请避免将密钥写入提示和日志。
|
||||
- 如需更广泛的威胁模型和检查清单,请参见[安全](/zh-CN/gateway/security)。
|
||||
|
||||
## 格式(兼容 AgentSkills + Pi)
|
||||
## 格式(AgentSkills + Pi 兼容)
|
||||
|
||||
`SKILL.md` 至少必须包含:
|
||||
|
||||
@ -132,24 +135,24 @@ description: Generate or edit images via a provider-backed image workflow
|
||||
|
||||
说明:
|
||||
|
||||
- 我们遵循 AgentSkills 规范的布局和意图。
|
||||
- 嵌入式 agent 使用的解析器仅支持**单行** frontmatter 键。
|
||||
- 我们遵循 AgentSkills 规范中的布局/意图。
|
||||
- 嵌入式智能体使用的解析器仅支持**单行** frontmatter 键。
|
||||
- `metadata` 应为**单行 JSON 对象**。
|
||||
- 在说明中使用 `{baseDir}` 来引用 skill 文件夹路径。
|
||||
- 可选的 frontmatter 键:
|
||||
- `homepage` — 在 macOS Skills UI 中显示为“Website”的 URL(也可通过 `metadata.openclaw.homepage` 提供)。
|
||||
- `user-invocable` — `true|false`(默认:`true`)。为 `true` 时,该 skill 会作为用户斜杠命令暴露。
|
||||
- `disable-model-invocation` — `true|false`(默认:`false`)。为 `true` 时,该 skill 会从模型提示词中排除(但仍可通过用户调用使用)。
|
||||
- `command-dispatch` — `tool`(可选)。设为 `tool` 时,该斜杠命令会绕过模型并直接分发给某个工具。
|
||||
- `command-tool` — 当设置了 `command-dispatch: tool` 时要调用的工具名称。
|
||||
- `command-arg-mode` — `raw`(默认)。对于工具分发,会将原始参数字符串原样转发给工具(核心层不做解析)。
|
||||
- 在说明中使用 `{baseDir}` 来引用 Skill 文件夹路径。
|
||||
- 可选 frontmatter 键:
|
||||
- `homepage` — URL,在 macOS Skills UI 中显示为“Website”(也支持通过 `metadata.openclaw.homepage` 设置)。
|
||||
- `user-invocable` — `true|false`(默认:`true`)。为 `true` 时,该 Skill 会作为用户斜杠命令公开。
|
||||
- `disable-model-invocation` — `true|false`(默认:`false`)。为 `true` 时,该 Skill 会从模型提示中排除(但仍可通过用户调用使用)。
|
||||
- `command-dispatch` — `tool`(可选)。设为 `tool` 时,斜杠命令会绕过模型并直接分发给工具。
|
||||
- `command-tool` — 当设置了 `command-dispatch: tool` 时,要调用的工具名称。
|
||||
- `command-arg-mode` — `raw`(默认)。对于工具分发,会将原始参数字符串转发给工具(不做核心解析)。
|
||||
|
||||
工具会使用以下参数调用:
|
||||
工具会以以下参数调用:
|
||||
`{ command: "<raw args>", commandName: "<slash command>", skillName: "<skill name>" }`。
|
||||
|
||||
## 门控(加载时过滤器)
|
||||
## 门控(加载时过滤)
|
||||
|
||||
OpenClaw 使用 `metadata`(单行 JSON)在**加载时筛选 skills**:
|
||||
OpenClaw 会在加载时使用 `metadata`(单行 JSON)对 Skills 进行**过滤**:
|
||||
|
||||
```markdown
|
||||
---
|
||||
@ -168,25 +171,30 @@ metadata:
|
||||
|
||||
`metadata.openclaw` 下的字段:
|
||||
|
||||
- `always: true` — 始终包含该 skill(跳过其他门控)。
|
||||
- `emoji` — macOS Skills UI 使用的可选 emoji。
|
||||
- `homepage` — 在 macOS Skills UI 中显示为“Website”的可选 URL。
|
||||
- `os` — 可选的平台列表(`darwin`、`linux`、`win32`)。设置后,该 skill 仅在这些操作系统上符合条件。
|
||||
- `always: true` — 始终包含该 Skill(跳过其他门控)。
|
||||
- `emoji` — 可选 emoji,供 macOS Skills UI 使用。
|
||||
- `homepage` — 可选 URL,在 macOS Skills UI 中显示为“Website”。
|
||||
- `os` — 可选平台列表(`darwin`、`linux`、`win32`)。如果设置,则该 Skill 仅在这些操作系统上可用。
|
||||
- `requires.bins` — 列表;其中每一项都必须存在于 `PATH` 中。
|
||||
- `requires.anyBins` — 列表;其中至少一项必须存在于 `PATH` 中。
|
||||
- `requires.env` — 列表;环境变量必须存在,**或者**在配置中提供。
|
||||
- `requires.config` — 必须为真值的 `openclaw.json` 路径列表。
|
||||
- `requires.config` — 列表;必须是值为 truthy 的 `openclaw.json` 路径。
|
||||
- `primaryEnv` — 与 `skills.entries.<name>.apiKey` 关联的环境变量名。
|
||||
- `install` — 可选的安装器规范数组,供 macOS Skills UI 使用(brew/node/go/uv/download)。
|
||||
- `install` — 可选安装器规范数组,供 macOS Skills UI 使用(brew/node/go/uv/download)。
|
||||
|
||||
如果 `metadata.openclaw` 缺失,仍接受旧版 `metadata.clawdbot`
|
||||
块,因此旧的已安装 Skills 仍可保留其依赖门控和安装器提示。新的和更新过的 Skills 应使用
|
||||
`metadata.openclaw`。
|
||||
|
||||
关于沙箱隔离的说明:
|
||||
|
||||
- `requires.bins` 会在 skill 加载时于**宿主机**上检查。
|
||||
- 如果某个 agent 处于沙箱隔离中,那么该二进制文件也必须**存在于容器内部**。
|
||||
请通过 `agents.defaults.sandbox.docker.setupCommand`(或自定义镜像)进行安装。
|
||||
- `requires.bins` 会在 Skill 加载时于**宿主机**上检查。
|
||||
- 如果某个智能体处于沙箱隔离状态,该二进制文件也必须**存在于容器内部**。
|
||||
请通过 `agents.defaults.sandbox.docker.setupCommand`(或自定义镜像)安装它。
|
||||
`setupCommand` 会在容器创建后运行一次。
|
||||
软件包安装还要求沙箱中具备网络出口、可写根文件系统以及 root 用户。
|
||||
例如,`summarize` skill(`skills/summarize/SKILL.md`)若要在沙箱容器中运行,就需要容器内存在 `summarize` CLI。
|
||||
安装软件包还需要沙箱中具备网络出口、可写的根文件系统以及 root 用户权限。
|
||||
示例:`summarize` Skill(`skills/summarize/SKILL.md`)需要在沙箱容器内存在 `summarize` CLI
|
||||
才能运行。
|
||||
|
||||
安装器示例:
|
||||
|
||||
@ -217,23 +225,23 @@ metadata:
|
||||
|
||||
说明:
|
||||
|
||||
- 如果列出了多个安装器,Gateway 网关会选择**一个**首选选项(有 `brew` 时优先 `brew`,否则为 `node`)。
|
||||
- 如果所有安装器都是 `download`,OpenClaw 会列出每个条目,以便你查看可用工件。
|
||||
- 安装器规范可包含 `os: ["darwin"|"linux"|"win32"]`,用于按平台筛选选项。
|
||||
- Node 安装会遵循 `openclaw.json` 中的 `skills.install.nodeManager`(默认:`npm`;可选:`npm/pnpm/yarn/bun`)。
|
||||
这只影响**skill 安装**;Gateway 网关运行时仍应使用 Node
|
||||
- 如果列出了多个安装器,Gateway 网关会选择**一个**首选选项(有 brew 时优先 brew,否则选择 node)。
|
||||
- 如果所有安装器都是 `download`,OpenClaw 会列出每一项,以便你查看可用的构件。
|
||||
- 安装器规范可包含 `os: ["darwin"|"linux"|"win32"]`,以按平台过滤选项。
|
||||
- Node 安装会遵循 `openclaw.json` 中的 `skills.install.nodeManager`(默认:npm;可选值:npm/pnpm/yarn/bun)。
|
||||
这只影响 **Skill 安装**;Gateway 网关运行时仍应使用 Node
|
||||
(不建议对 WhatsApp/Telegram 使用 Bun)。
|
||||
- 由 Gateway 网关支持的安装器选择是基于偏好,而不只是 node:
|
||||
当安装规范混合多种类型时,如果启用了 `skills.install.preferBrew` 且存在 `brew`,OpenClaw 会优先 Homebrew,然后是 `uv`,再然后是已配置的 node 管理器,最后才是 `go` 或 `download` 等其他回退项。
|
||||
- 如果每个安装规范都是 `download`,OpenClaw 会展示所有下载选项,而不是收敛为一个首选安装器。
|
||||
- Go 安装:如果缺少 `go` 且存在 `brew`,Gateway 网关会先通过 Homebrew 安装 Go,并在可能时将 `GOBIN` 设为 Homebrew 的 `bin`。
|
||||
- 由 Gateway 网关支持的安装器选择是基于偏好的,而不是仅限 node:
|
||||
当安装规范混合多种类型时,如果启用了 `skills.install.preferBrew` 且存在 `brew`,OpenClaw 会优先选择 Homebrew,然后是 `uv`,再然后是已配置的 node 管理器,之后才是 `go` 或 `download` 等其他回退选项。
|
||||
- 如果每个安装规范都是 `download`,OpenClaw 会显示所有下载选项,而不是折叠为一个首选安装器。
|
||||
- Go 安装:如果缺少 `go` 且存在 `brew`,Gateway 网关会先通过 Homebrew 安装 Go,并在可能时将 `GOBIN` 设置为 Homebrew 的 `bin`。
|
||||
- Download 安装:`url`(必填)、`archive`(`tar.gz` | `tar.bz2` | `zip`)、`extract`(默认:检测到归档文件时自动开启)、`stripComponents`、`targetDir`(默认:`~/.openclaw/tools/<skillKey>`)。
|
||||
|
||||
如果不存在 `metadata.openclaw`,则该 skill 始终符合条件(除非在配置中被禁用,或者作为内置 skill 被 `skills.allowBundled` 阻止)。
|
||||
如果不存在 `metadata.openclaw`,则该 Skill 始终符合条件(除非它在配置中被禁用,或对于内置 Skills 被 `skills.allowBundled` 阻止)。
|
||||
|
||||
## 配置覆盖(`~/.openclaw/openclaw.json`)
|
||||
|
||||
内置/托管 skills 可以切换启用状态,并可提供环境变量值:
|
||||
可以对内置/托管 Skills 进行开关控制,并为其提供环境变量值:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -257,61 +265,67 @@ metadata:
|
||||
}
|
||||
```
|
||||
|
||||
注意:如果 skill 名称包含连字符,请给键名加引号(JSON5 允许带引号的键)。
|
||||
注意:如果 Skill 名称包含连字符,请给该键加引号(JSON5 允许带引号的键)。
|
||||
|
||||
如果你想在 OpenClaw 本身内部使用原生的图片生成/编辑,请使用核心
|
||||
`image_generate` 工具并配置 `agents.defaults.imageGenerationModel`,而不是使用内置 skill。这里的 skill 示例适用于自定义或第三方工作流。
|
||||
如果你想在 OpenClaw 本身内部使用标准图像生成/编辑,请使用核心
|
||||
`image_generate` 工具并配合 `agents.defaults.imageGenerationModel`,而不是使用
|
||||
内置 Skill。这里的 Skill 示例适用于自定义或第三方工作流。
|
||||
|
||||
对于原生图像分析,请使用 `image` 工具并配置 `agents.defaults.imageModel`。
|
||||
对于原生图片生成/编辑,请使用 `image_generate` 并配置
|
||||
`agents.defaults.imageGenerationModel`。如果你选择 `openai/*`、`google/*`、
|
||||
`fal/*` 或其他提供商专用图像模型,还需要添加该提供商对应的认证/API
|
||||
对于原生图像分析,请将 `image` 工具与 `agents.defaults.imageModel` 搭配使用。
|
||||
对于原生图像生成/编辑,请将 `image_generate` 与
|
||||
`agents.defaults.imageGenerationModel` 搭配使用。如果你选择 `openai/*`、`google/*`、
|
||||
`fal/*` 或其他提供商特定的图像模型,还需要添加该提供商的认证/API
|
||||
密钥。
|
||||
|
||||
默认情况下,配置键与**skill 名称**匹配。如果某个 skill 定义了
|
||||
默认情况下,配置键与 **Skill 名称** 匹配。如果某个 Skill 定义了
|
||||
`metadata.openclaw.skillKey`,请在 `skills.entries` 下使用该键。
|
||||
|
||||
规则:
|
||||
|
||||
- `enabled: false` 会禁用该 skill,即使它是内置/已安装的。
|
||||
- `enabled: false` 会禁用该 Skill,即使它是内置/已安装的。
|
||||
- `env`:**仅当**该变量尚未在进程中设置时才会注入。
|
||||
- `apiKey`:为声明了 `metadata.openclaw.primaryEnv` 的 skills 提供的便捷写法。
|
||||
- `apiKey`:为声明了 `metadata.openclaw.primaryEnv` 的 Skills 提供的便捷方式。
|
||||
支持明文字符串或 SecretRef 对象(`{ source, provider, id }`)。
|
||||
- `config`:用于自定义每个 skill 字段的可选对象;自定义键必须放在这里。
|
||||
- `allowBundled`:仅针对**内置** skills 的可选允许列表。如果设置,则只有列表中的内置 skills 符合条件(不影响托管/工作区 skills)。
|
||||
- `config`:可选对象,用于存放每个 Skill 的自定义字段;自定义键必须放在这里。
|
||||
- `allowBundled`:仅针对**内置** Skills 的可选允许列表。设置后,只有
|
||||
列表中的内置 Skills 才符合条件(托管/工作区 Skills 不受影响)。
|
||||
|
||||
## 环境变量注入(每次 agent 运行)
|
||||
## 环境注入(每次智能体运行)
|
||||
|
||||
当一次 agent 运行开始时,OpenClaw 会:
|
||||
当智能体开始运行时,OpenClaw 会:
|
||||
|
||||
1. 读取 skill 元数据。
|
||||
2. 将任何 `skills.entries.<key>.env` 或 `skills.entries.<key>.apiKey` 应用到
|
||||
1. 读取 Skill 元数据。
|
||||
2. 将所有 `skills.entries.<key>.env` 或 `skills.entries.<key>.apiKey` 应用到
|
||||
`process.env`。
|
||||
3. 使用**符合条件**的 skills 构建系统提示词。
|
||||
3. 使用**符合条件的** Skills 构建系统提示。
|
||||
4. 在运行结束后恢复原始环境。
|
||||
|
||||
这是**限定在 agent 运行范围内**的,不是全局 shell 环境。
|
||||
这是**限定在智能体运行范围内**的,不是全局 shell 环境。
|
||||
|
||||
对于内置的 `claude-cli` 后端,OpenClaw 还会将同一份符合条件的快照实体化为临时 Claude Code 插件,并通过 `--plugin-dir` 传入。这样 Claude Code 就可以使用其原生的 skill 解析器,同时 OpenClaw 仍然掌控优先级、每个 agent 的允许列表、门控以及
|
||||
`skills.entries.*` 环境变量/API 密钥注入。其他 CLI 后端仅使用提示词目录。
|
||||
对于内置的 `claude-cli` 后端,OpenClaw 还会将同一个
|
||||
符合条件的快照物化为一个临时 Claude Code 插件,并通过
|
||||
`--plugin-dir` 传入。这样 Claude Code 就可以使用它的原生 Skill 解析器,而 OpenClaw 仍负责优先级、每个智能体的允许列表、门控,以及
|
||||
`skills.entries.*` 环境变量/API 密钥注入。其他 CLI 后端仅使用提示目录。
|
||||
|
||||
## 会话快照(性能)
|
||||
|
||||
OpenClaw 会在会话开始时对符合条件的 skills 进行快照,并在同一会话的后续轮次中复用该列表。对 skills 或配置的更改会在下一个新会话中生效。
|
||||
OpenClaw 会在会话开始时对符合条件的 Skills 进行快照,并在同一会话的后续轮次中复用该列表。对 Skills 或配置的更改会在下一次新会话中生效。
|
||||
|
||||
当启用 skills 监视器时,或者出现新的符合条件的远程节点时,skills 也可以在会话中途刷新(见下文)。你可以把这理解为一种**热重载**:刷新后的列表会在下一次 agent 轮次中生效。
|
||||
当启用 Skills 监视器时,或者出现新的符合条件的远程节点时,Skills 也可以在会话中途刷新(见下文)。你可以将其视为一种**热重载**:刷新的列表会在下一次智能体轮次中被采用。
|
||||
|
||||
如果该会话的有效 agent skill 允许列表发生变化,OpenClaw 会刷新快照,以便可见 skills 与当前 agent 保持一致。
|
||||
如果该会话的生效智能体 Skill 允许列表发生变化,OpenClaw
|
||||
会刷新快照,以便可见 Skills 始终与当前智能体保持一致。
|
||||
|
||||
## 远程 macOS 节点(Linux Gateway 网关)
|
||||
|
||||
如果 Gateway 网关运行在 Linux 上,但连接了一个**允许 `system.run` 的 macOS 节点**(Exec approvals 安全设置不是 `deny`),当所需二进制文件存在于该节点上时,OpenClaw 可以将仅限 macOS 的 skills 视为符合条件。智能体应通过 `exec` 工具并设置 `host=node` 来执行这些 skills。
|
||||
如果 Gateway 网关运行在 Linux 上,但连接了一个**允许 `system.run` 的 macOS 节点**
|
||||
(Exec 审批安全性未设置为 `deny`),那么当该节点上存在所需二进制文件时,OpenClaw 可以将仅限 macOS 的 Skills 视为符合条件。智能体应通过带有 `host=node` 的 `exec` 工具来执行这些 Skills。
|
||||
|
||||
这依赖于节点报告其命令支持情况,以及通过 `system.run` 进行的二进制探测。如果该 macOS 节点之后离线,这些 skills 仍会保持可见;但在节点重新连接之前,调用可能会失败。
|
||||
这依赖于节点报告其命令支持能力,以及通过 `system.run` 进行二进制探测。如果 macOS 节点之后离线,这些 Skills 仍会保持可见;在节点重新连接之前,调用可能会失败。
|
||||
|
||||
## Skills 监视器(自动刷新)
|
||||
|
||||
默认情况下,OpenClaw 会监视 skill 文件夹,并在 `SKILL.md` 文件发生变化时更新 skills 快照。可在 `skills.load` 下进行配置:
|
||||
默认情况下,OpenClaw 会监视 Skill 文件夹,并在 `SKILL.md` 文件发生变化时更新 Skills 快照。在 `skills.load` 下进行配置:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -324,12 +338,12 @@ OpenClaw 会在会话开始时对符合条件的 skills 进行快照,并在同
|
||||
}
|
||||
```
|
||||
|
||||
## Token 影响(skills 列表)
|
||||
## Token 影响(Skills 列表)
|
||||
|
||||
当 skills 符合条件时,OpenClaw 会将一个紧凑的可用 skills XML 列表注入系统提示词中(通过 `pi-coding-agent` 中的 `formatSkillsForPrompt`)。其成本是确定性的:
|
||||
当有符合条件的 Skills 时,OpenClaw 会将一个紧凑的 XML Skills 列表注入系统提示中(通过 `pi-coding-agent` 中的 `formatSkillsForPrompt`)。成本是确定性的:
|
||||
|
||||
- **基础开销(仅当 ≥1 个 skill 时):** 195 个字符。
|
||||
- **每个 skill:** 97 个字符 + XML 转义后的 `<name>`、`<description>` 和 `<location>` 值的长度。
|
||||
- **基础开销(仅当 ≥1 个 Skill 时):** 195 个字符。
|
||||
- **每个 Skill:** 97 个字符 + XML 转义后的 `<name>`、`<description>` 和 `<location>` 值的长度。
|
||||
|
||||
公式(字符数):
|
||||
|
||||
@ -339,26 +353,29 @@ total = 195 + Σ (97 + len(name_escaped) + len(description_escaped) + len(locati
|
||||
|
||||
说明:
|
||||
|
||||
- XML 转义会将 `& < > " '` 扩展为实体(如 `&`、`<` 等),从而增加长度。
|
||||
- Token 数会因模型分词器而异。粗略按 OpenAI 风格估算,约为每 4 个字符 1 个 token,因此**97 个字符 ≈ 24 个 token**,外加你实际字段的长度。
|
||||
- XML 转义会将 `& < > " '` 扩展为实体(`&`、`<` 等),从而增加长度。
|
||||
- Token 数量取决于模型的 tokenizer。一个粗略的 OpenAI 风格估算是约 4 个字符/token,因此**97 个字符 ≈ 24 个 token**,再加上你的实际字段长度。
|
||||
|
||||
## 托管 skills 生命周期
|
||||
## 托管 Skills 生命周期
|
||||
|
||||
OpenClaw 会随安装(`npm` 包或 OpenClaw.app)附带一组基础 skills,作为**内置 skills** 提供。`~/.openclaw/skills` 用于本地覆盖(例如,在不更改内置副本的情况下固定/修补某个 skill)。工作区 skills 由用户拥有,在名称冲突时会覆盖前两者。
|
||||
OpenClaw 会将一组基线 Skills 作为安装的一部分以**内置 Skills**
|
||||
形式提供(npm 包或 OpenClaw.app)。`~/.openclaw/skills` 用于本地
|
||||
覆盖(例如固定/修补某个 Skill,而不修改内置副本)。
|
||||
工作区 Skills 由用户拥有,并且在名称冲突时会覆盖前两者。
|
||||
|
||||
## 配置参考
|
||||
|
||||
完整配置 schema 请参见 [Skills 配置](/zh-CN/tools/skills-config)。
|
||||
完整配置模式请参见 [Skills 配置](/zh-CN/tools/skills-config)。
|
||||
|
||||
## 想找更多 skills?
|
||||
## 想找更多 Skills?
|
||||
|
||||
浏览 [https://clawhub.ai](https://clawhub.ai)。
|
||||
请浏览 [https://clawhub.ai](https://clawhub.ai)。
|
||||
|
||||
---
|
||||
|
||||
## 相关内容
|
||||
|
||||
- [创建 Skills](/zh-CN/tools/creating-skills) — 构建自定义 skills
|
||||
- [Skills 配置](/zh-CN/tools/skills-config) — skill 配置参考
|
||||
- [创建 Skills](/zh-CN/tools/creating-skills) — 构建自定义 Skills
|
||||
- [Skills 配置](/zh-CN/tools/skills-config) — Skill 配置参考
|
||||
- [Slash Commands](/zh-CN/tools/slash-commands) — 所有可用的斜杠命令
|
||||
- [Plugins](/zh-CN/tools/plugin) — 插件系统概览
|
||||
- [插件](/zh-CN/tools/plugin) — 插件系统概览
|
||||
|
||||
Loading…
Reference in New Issue
Block a user