diff --git a/docs/zh-CN/concepts/context.md b/docs/zh-CN/concepts/context.md index c7ccef4a3..482a82fa3 100644 --- a/docs/zh-CN/concepts/context.md +++ b/docs/zh-CN/concepts/context.md @@ -1,44 +1,44 @@ --- read_when: - 你想了解 OpenClaw 中“上下文”的含义 - - 你正在调试模型为什么“知道”某些内容(或为什么忘记了它) + - 你正在调试为什么模型“知道”某些内容(或忘记了它) - 你想减少上下文开销(`/context`、`/status`、`/compact`) -summary: 上下文:模型能看到什么、它是如何构建的,以及如何检查它 +summary: 上下文:模型会看到什么、它是如何构建的,以及如何检查它 title: 上下文 x-i18n: - generated_at: "2026-04-05T08:21:29Z" + generated_at: "2026-04-05T18:13:28Z" model: gpt-5.4 provider: openai - source_hash: a75b4cd65bf6385d46265b9ce1643310bc99d220e35ec4b4924096bed3ca4aa0 + source_hash: fe7dfe52cb1a64df229c8622feed1804df6c483a6243e0d2f309f6ff5c9fe521 source_path: concepts/context.md workflow: 15 --- # 上下文 -“上下文”是**OpenClaw 在一次运行中发送给模型的全部内容**。它受模型的**上下文窗口**(token 限制)约束。 +“上下文”是 **OpenClaw 在一次运行中发送给模型的全部内容**。它受限于模型的 **上下文窗口**(token 限制)。 -适合初学者的心智模型: +适合初学者的理解方式: -- **系统提示词**(由 OpenClaw 构建):规则、工具、Skills 列表、时间 / 运行时信息,以及注入的工作区文件。 -- **对话历史**:你在此会话中的消息 + 助手消息。 -- **工具调用 / 结果 + 附件**:命令输出、文件读取、图像 / 音频等。 +- **系统提示词**(由 OpenClaw 构建):规则、工具、Skills 列表、时间/运行时信息,以及注入的工作区文件。 +- **对话历史**:你在此会话中的消息,以及助手的消息。 +- **工具调用/结果 + 附件**:命令输出、文件读取、图片/音频等。 -上下文 _并不等同于_ “memory”:memory 可以存储到磁盘并在之后重新加载;上下文则是模型当前窗口中的内容。 +上下文 _并不等同于_ “记忆”:记忆可以存储在磁盘上并在之后重新加载;上下文则是模型当前窗口中的内容。 ## 快速开始(检查上下文) -- `/status` → 快速查看“我的窗口有多满?”以及会话设置。 -- `/context list` → 查看注入了哪些内容 + 大致大小(每个文件 + 总计)。 +- `/status` → 快速查看“我的窗口用了多少?”以及会话设置。 +- `/context list` → 查看注入了什么 + 粗略大小(每个文件 + 总计)。 - `/context detail` → 更深入的细分:每个文件、每个工具 schema 的大小、每个 skill 条目的大小,以及系统提示词大小。 - `/usage tokens` → 在普通回复后附加每次回复的用量页脚。 - `/compact` → 将较早的历史总结为一条紧凑条目,以释放窗口空间。 -另见:[Slash commands](/tools/slash-commands)、[Token use & costs](/reference/token-use)、[Compaction](/concepts/compaction)。 +另见:[Slash commands](/zh-CN/tools/slash-commands)、[Token 用量与成本](/zh-CN/reference/token-use)、[压缩](/zh-CN/concepts/compaction)。 ## 示例输出 -具体值会因模型、提供商、工具策略以及你的工作区内容而异。 +具体数值会因模型、提供商、工具策略以及你的工作区内容而异。 ### `/context list` @@ -90,22 +90,22 @@ Top tools (schema size): - 系统提示词(所有部分)。 - 对话历史。 - 工具调用 + 工具结果。 -- 附件 / 转录内容(图像 / 音频 / 文件)。 -- 压缩摘要和剪枝产物。 -- 提供商“包装层”或隐藏头部(虽然不可见,仍会计入)。 +- 附件/转录内容(图片/音频/文件)。 +- 压缩摘要和裁剪产物。 +- 提供商“包装层”或隐藏头信息(不可见,但仍会计入)。 ## OpenClaw 如何构建系统提示词 -系统提示词由 **OpenClaw 拥有**,并会在每次运行时重新构建。它包括: +系统提示词由 **OpenClaw 持有**,并会在每次运行时重新构建。它包括: -- 工具列表 + 简短说明。 +- 工具列表 + 简短描述。 - Skills 列表(仅元数据;见下文)。 - 工作区位置。 -- 时间(UTC + 如果已配置则包含换算后的用户时间)。 -- 运行时元数据(主机 / OS / 模型 / thinking)。 -- **Project Context** 下已注入的工作区 bootstrap 文件。 +- 时间(UTC + 如果已配置则包含转换后的用户时区时间)。 +- 运行时元数据(主机/OS/模型/思考设置)。 +- 在 **Project Context** 下注入的工作区引导文件。 -完整细分参见:[System Prompt](/concepts/system-prompt)。 +完整细分请参见:[System Prompt](/zh-CN/concepts/system-prompt)。 ## 注入的工作区文件(Project Context) @@ -119,62 +119,68 @@ Top tools (schema size): - `HEARTBEAT.md` - `BOOTSTRAP.md`(仅首次运行) -大文件会按文件使用 `agents.defaults.bootstrapMaxChars`(默认 `20000` 个字符)进行截断。OpenClaw 还会对所有文件的 bootstrap 注入总量施加上限 `agents.defaults.bootstrapTotalMaxChars`(默认 `150000` 个字符)。`/context` 会显示**原始大小与注入后大小**,以及是否发生了截断。 +大型文件会按文件依据 `agents.defaults.bootstrapMaxChars`(默认 `20000` 个字符)进行截断。OpenClaw 还会通过 `agents.defaults.bootstrapTotalMaxChars`(默认 `150000` 个字符)对所有文件的总引导注入量施加上限。`/context` 会显示 **原始大小 vs 注入后大小**,以及是否发生了截断。 -发生截断时,运行时可以在 Project Context 下方于提示词内注入一个警告块。可通过 `agents.defaults.bootstrapPromptTruncationWarning` 进行配置(`off`、`once`、`always`;默认 `once`)。 +发生截断时,运行时可以在 Project Context 下方注入一个提示词内警告块。可通过 `agents.defaults.bootstrapPromptTruncationWarning` 进行配置(`off`、`once`、`always`;默认 `once`)。 -## Skills:注入与按需加载 +## Skills:默认注入与按需加载 -系统提示词包含一个精简的 **Skills 列表**(名称 + 描述 + 位置)。这个列表会带来真实的开销。 +系统提示词中包含一个紧凑的 **skills 列表**(名称 + 描述 + 位置)。这个列表会带来真实的上下文开销。 -默认情况下不会包含 skill 指令本身。模型应当只在需要时 `read` 该 skill 的 `SKILL.md`。 +Skill 指令默认 _不会_ 被包含进去。模型应当只在需要时才 `read` 该 skill 的 `SKILL.md`。 -## Tools:有两类成本 +## 工具:有两种成本 工具会通过两种方式影响上下文: -1. 系统提示词中的**工具列表文本**(你看到的 “Tooling”)。 -2. **工具 schema**(JSON)。这些内容会发送给模型,以便它能够调用工具。即使你看不到它们的纯文本形式,它们仍会计入上下文。 +1. 系统提示词中的 **工具列表文本**(也就是你看到的 “Tooling”)。 +2. **工具 schemas**(JSON)。这些会发送给模型,以便它调用工具。即使你看不到它们的纯文本形式,它们也会计入上下文。 -`/context detail` 会细分最大的工具 schema,以便你看到主要开销来自哪里。 +`/context detail` 会拆分出最大的工具 schema,让你看清哪些部分占比最高。 -## 命令、指令和“内联快捷方式” +## 命令、指令和“行内快捷方式” -Slash 命令由 Gateway 网关处理。这里有几种不同的行为: +Slash commands 由 Gateway 网关处理。这里有几种不同的行为: -- **独立命令**:如果一条消息只包含 `/...`,它会作为命令运行。 -- **指令**:`/think`、`/verbose`、`/reasoning`、`/elevated`、`/model`、`/queue` 会在模型看到消息前被剥离。 - - 只包含指令的消息会持久化会话设置。 - - 普通消息中的内联指令会作为单条消息级提示生效。 -- **内联快捷方式**(仅允许列表中的发件人):普通消息中的某些 `/...` 标记可以立即执行(例如:“hey /status”),并会在模型看到剩余文本前被剥离。 +- **独立命令**:一条只包含 `/...` 的消息会作为命令运行。 +- **指令**:`/think`、`/verbose`、`/reasoning`、`/elevated`、`/model`、`/queue` 会在消息被模型看到之前被剥离。 + - 仅包含指令的消息会持久化会话设置。 + - 普通消息中的行内指令会作为单条消息级别的提示。 +- **行内快捷方式**(仅限于白名单发送者):普通消息中的某些 `/...` token 可以立即运行(例如:“hey /status”),并会在模型看到剩余文本之前被剥离。 -详情参见:[Slash commands](/tools/slash-commands)。 +详情请参见:[Slash commands](/zh-CN/tools/slash-commands)。 -## 会话、压缩和剪枝(哪些内容会持久化) +## 会话、压缩和裁剪(哪些内容会持久化) -跨消息持久化的内容取决于所用机制: +跨消息持久化哪些内容,取决于所使用的机制: -- **普通历史** 会保留在会话转录中,直到按策略被压缩 / 剪枝。 +- **普通历史** 会保留在会话转录中,直到根据策略被压缩/裁剪。 - **压缩** 会将摘要持久化到转录中,并保留最近的消息不变。 -- **剪枝** 会从一次运行的**内存中**提示词移除旧的工具结果,但不会重写转录。 +- **裁剪** 会从某次运行的 _内存中_ 提示词里移除旧的工具结果,但不会重写转录。 -文档参见:[会话](/concepts/session)、[压缩](/concepts/compaction)、[会话剪枝](/concepts/session-pruning)。 +文档:[Session](/zh-CN/concepts/session)、[压缩](/zh-CN/concepts/compaction)、[会话裁剪](/zh-CN/concepts/session-pruning)。 -默认情况下,OpenClaw 使用内置的 `legacy` 上下文引擎进行组装和压缩。如果你安装了提供 `kind: "context-engine"` 的插件,并通过 `plugins.slots.contextEngine` 选择它,OpenClaw 就会将上下文组装、`/compact` 以及相关的子智能体上下文生命周期 hook 委托给该引擎。`ownsCompaction: false` 不会自动回退到 legacy 引擎;活动引擎仍必须正确实现 `compact()`。完整的可插拔接口、生命周期 hooks 和配置参见 -[Context Engine](/concepts/context-engine)。 +默认情况下,OpenClaw 使用内置的 `legacy` 上下文引擎进行组装和 +压缩。如果你安装了一个提供 `kind: "context-engine"` 的插件,并通过 +`plugins.slots.contextEngine` 选择它,OpenClaw 就会将上下文组装、 +`/compact` 以及相关的子智能体上下文生命周期钩子委托给该 +引擎处理。`ownsCompaction: false` 不会自动回退到 legacy +引擎;当前激活的引擎仍必须正确实现 `compact()`。完整的 +可插拔接口、生命周期钩子和配置请参见 +[Context Engine](/zh-CN/concepts/context-engine)。 -## `/context` 实际报告了什么 +## `/context` 实际报告的是什么 -`/context` 在可用时会优先使用最新的**按运行构建**系统提示词报告: +在可用时,`/context` 会优先使用最新的 **按运行构建** 的系统提示词报告: -- `System prompt (run)` = 从上一次嵌入式(支持工具)运行中捕获,并持久化到会话存储中。 -- `System prompt (estimate)` = 当不存在运行报告时按需即时计算(或者当通过不会生成该报告的 CLI 后端运行时计算)。 +- `System prompt (run)` = 从最近一次嵌入式(支持工具)运行中捕获,并持久化到会话存储中的数据。 +- `System prompt (estimate)` = 当还没有运行报告时,动态计算得出的估算值。 -无论哪种方式,它都会报告大小和主要贡献项;它**不会**转储完整系统提示词或工具 schema。 +无论哪种方式,它报告的都是大小和主要贡献项;它**不会**输出完整的系统提示词或工具 schema。 ## 相关内容 -- [Context Engine](/concepts/context-engine) — 通过插件进行自定义上下文注入 -- [Compaction](/concepts/compaction) — 总结长对话 -- [System Prompt](/concepts/system-prompt) — 系统提示词如何构建 -- [Agent Loop](/concepts/agent-loop) — 完整的智能体执行循环 +- [Context Engine](/zh-CN/concepts/context-engine) —— 通过插件实现自定义上下文注入 +- [压缩](/zh-CN/concepts/compaction) —— 对长对话进行总结 +- [System Prompt](/zh-CN/concepts/system-prompt) —— 系统提示词是如何构建的 +- [Agent Loop](/zh-CN/concepts/agent-loop) —— 完整的智能体执行周期 diff --git a/docs/zh-CN/concepts/model-providers.md b/docs/zh-CN/concepts/model-providers.md index 0e003fc55..a740d4912 100644 --- a/docs/zh-CN/concepts/model-providers.md +++ b/docs/zh-CN/concepts/model-providers.md @@ -1,125 +1,125 @@ --- read_when: - - 你需要按提供商分类的模型设置参考 - - 你想要模型提供商的示例配置或 CLI 新手引导命令 + - 你需要按提供商区分的模型设置参考 + - 你想查看模型提供商的示例配置或 CLI 新手引导命令 summary: 模型提供商概览,包含示例配置和 CLI 流程 title: 模型提供商 x-i18n: - generated_at: "2026-04-05T17:48:13Z" + generated_at: "2026-04-05T18:14:49Z" model: gpt-5.4 provider: openai - source_hash: bbe1b0cd1243804fcef3fc75ea1face72257d6e7c93ffb85c15766766193b490 + source_hash: 24e6275b0bf137fa8143baa2a1d729439ecec6a0d7c0c14fed78c522f691476f source_path: concepts/model-providers.md workflow: 15 --- # 模型提供商 -本页介绍的是 **LLM/模型提供商**(不是像 WhatsApp/Telegram 这样的聊天渠道)。 +本页介绍 **LLM/模型提供商**(不是像 WhatsApp/Telegram 这样的聊天渠道)。 关于模型选择规则,请参见 [/concepts/models](/zh-CN/concepts/models)。 ## 快速规则 - 模型引用使用 `provider/model`(例如:`opencode/claude-opus-4-6`)。 - 如果你设置了 `agents.defaults.models`,它就会成为允许列表。 -- CLI 辅助命令:`openclaw onboard`、`openclaw models list`、`openclaw models set `。 +- CLI 助手:`openclaw onboard`、`openclaw models list`、`openclaw models set `。 - 回退运行时规则、冷却探测和会话覆盖持久化记录在 [/concepts/model-failover](/zh-CN/concepts/model-failover) 中。 -- `models.providers.*.models[].contextWindow` 是模型原生元数据;`models.providers.*.models[].contextTokens` 是生效的运行时上限。 +- `models.providers.*.models[].contextWindow` 是原生模型元数据;`models.providers.*.models[].contextTokens` 是生效的运行时上限。 - 提供商插件可以通过 `registerProvider({ catalog })` 注入模型目录;OpenClaw 会在写入 `models.json` 之前将该输出合并到 `models.providers` 中。 -- 提供商清单可以声明 `providerAuthEnvVars`,这样通用的基于环境变量的凭证探测就不需要加载插件运行时。剩余的核心环境变量映射现在仅用于非插件/核心提供商,以及少数通用优先级场景,例如 Anthropic 的“API key 优先”新手引导。 -- 提供商插件还可以通过 `normalizeModelId`、`normalizeTransport`、`normalizeConfig`、`applyNativeStreamingUsageCompat`、`resolveConfigApiKey`、`resolveSyntheticAuth`、`shouldDeferSyntheticProfileAuth`、`resolveDynamicModel`、`prepareDynamicModel`、`normalizeResolvedModel`、`contributeResolvedModelCompat`、`capabilities`、`normalizeToolSchemas`、`inspectToolSchemas`、`resolveReasoningOutputMode`、`prepareExtraParams`、`createStreamFn`、`wrapStreamFn`、`resolveTransportTurnState`、`resolveWebSocketSessionPolicy`、`createEmbeddingProvider`、`formatApiKey`、`refreshOAuth`、`buildAuthDoctorHint`、`matchesContextOverflowError`、`classifyFailoverReason`、`isCacheTtlEligible`、`buildMissingAuthMessage`、`suppressBuiltInModel`、`augmentModelCatalog`、`isBinaryThinking`、`supportsXHighThinking`、`resolveDefaultThinkingLevel`、`applyConfigDefaults`、`isModernModelRef`、`prepareRuntimeAuth`、`resolveUsageAuth`、`fetchUsageSnapshot` 和 `onModelSelected` 来管理提供商运行时行为。 -- 注意:提供商运行时 `capabilities` 是共享运行器元数据(提供商家族、转录/工具行为差异、传输/缓存提示)。它与[公共能力模型](/zh-CN/plugins/architecture#public-capability-model)不同,后者描述的是插件注册了什么能力(文本推理、语音等)。 +- 提供商清单可以声明 `providerAuthEnvVars`,这样基于通用环境变量的认证探测就不需要加载插件运行时。剩余的核心环境变量映射现在仅用于非插件/核心提供商,以及少数通用优先级场景,例如 Anthropic 的“API 密钥优先”新手引导。 +- 提供商插件还可以通过 `normalizeModelId`、`normalizeTransport`、`normalizeConfig`、`applyNativeStreamingUsageCompat`、`resolveConfigApiKey`、`resolveSyntheticAuth`、`shouldDeferSyntheticProfileAuth`、`resolveDynamicModel`、`prepareDynamicModel`、`normalizeResolvedModel`、`contributeResolvedModelCompat`、`capabilities`、`normalizeToolSchemas`、`inspectToolSchemas`、`resolveReasoningOutputMode`、`prepareExtraParams`、`createStreamFn`、`wrapStreamFn`、`resolveTransportTurnState`、`resolveWebSocketSessionPolicy`、`createEmbeddingProvider`、`formatApiKey`、`refreshOAuth`、`buildAuthDoctorHint`、`matchesContextOverflowError`、`classifyFailoverReason`、`isCacheTtlEligible`、`buildMissingAuthMessage`、`suppressBuiltInModel`、`augmentModelCatalog`、`isBinaryThinking`、`supportsXHighThinking`、`resolveDefaultThinkingLevel`、`applyConfigDefaults`、`isModernModelRef`、`prepareRuntimeAuth`、`resolveUsageAuth`、`fetchUsageSnapshot` 以及 `onModelSelected` 来接管提供商运行时行为。 +- 注意:提供商运行时 `capabilities` 是共享的运行器元数据(提供商家族、转录/工具差异、传输/缓存提示)。它与[公共能力模型](/zh-CN/plugins/architecture#public-capability-model)不同,后者描述的是插件注册了什么内容(文本推理、语音等)。 ## 插件自有的提供商行为 -现在,提供商插件可以拥有大多数提供商特定逻辑,而 OpenClaw 保持通用推理循环。 +现在,提供商插件可以接管大多数提供商特定逻辑,而 OpenClaw 保留通用推理循环。 -典型分工: +典型划分如下: -- `auth[].run` / `auth[].runNonInteractive`:提供商拥有用于 `openclaw onboard`、`openclaw models auth` 和无头设置的 onboarding/登录流程 -- `wizard.setup` / `wizard.modelPicker`:提供商拥有认证选择标签、旧版别名、新手引导允许列表提示,以及新手引导/模型选择器中的设置项 +- `auth[].run` / `auth[].runNonInteractive`:提供商负责 `openclaw onboard`、`openclaw models auth` 和无头设置的 onboarding/登录流程 +- `wizard.setup` / `wizard.modelPicker`:提供商负责认证选项标签、旧别名、onboarding 允许列表提示,以及 onboarding/模型选择器中的设置项 - `catalog`:提供商会出现在 `models.providers` 中 -- `normalizeModelId`:提供商会在查找或规范化之前标准化旧版/预览模型 id -- `normalizeTransport`:提供商会在通用模型组装之前标准化传输家族的 `api` / `baseUrl`;OpenClaw 会先检查匹配的提供商,然后再检查其他具备 hook 能力的提供商插件,直到某个插件实际修改了传输 -- `normalizeConfig`:提供商会在运行时使用前标准化 `models.providers.` 配置;OpenClaw 会先检查匹配的提供商,然后再检查其他具备 hook 能力的提供商插件,直到某个插件实际修改了配置。如果没有提供商 hook 重写配置,内置的 Google 家族辅助逻辑仍会标准化受支持的 Google 提供商条目。 -- `applyNativeStreamingUsageCompat`:提供商会对配置型提供商应用由端点驱动的原生流式使用量兼容性重写 -- `resolveConfigApiKey`:提供商会为配置型提供商解析基于环境变量标记的认证,而无需强制加载完整运行时认证。`amazon-bedrock` 在这里也有内置的 AWS 环境变量标记解析器,尽管 Bedrock 运行时认证使用的是 AWS SDK 默认链。 -- `resolveSyntheticAuth`:提供商可以在不持久化明文密钥的情况下暴露本地/自托管或其他基于配置的认证可用性 -- `shouldDeferSyntheticProfileAuth`:提供商可以将已存储的合成配置文件占位符标记为低于环境变量/配置型认证的优先级 -- `resolveDynamicModel`:提供商可以接受尚未出现在本地静态目录中的模型 id +- `normalizeModelId`:提供商会在查找或规范化之前规范旧版/预览模型 ID +- `normalizeTransport`:提供商会在通用模型组装之前规范传输族的 `api` / `baseUrl`;OpenClaw 会先检查匹配的提供商,再检查其他支持此 Hook 的提供商插件,直到某个插件实际更改了传输 +- `normalizeConfig`:提供商会在运行时使用前规范 `models.providers.` 配置;OpenClaw 会先检查匹配的提供商,再检查其他支持此 Hook 的提供商插件,直到某个插件实际更改了配置。如果没有提供商 Hook 重写配置,内置的 Google 系列助手仍会规范受支持的 Google 提供商条目。 +- `applyNativeStreamingUsageCompat`:提供商会对配置提供商应用由端点驱动的原生流式用量兼容重写 +- `resolveConfigApiKey`:提供商会为配置提供商解析环境变量标记认证,而无需强制加载完整运行时认证。`amazon-bedrock` 在这里还内置了 AWS 环境变量标记解析器,尽管 Bedrock 运行时认证使用的是 AWS SDK 默认链。 +- `resolveSyntheticAuth`:提供商可以暴露本地/自托管或其他基于配置的可用认证,而无需持久化明文密钥 +- `shouldDeferSyntheticProfileAuth`:提供商可以将已存储的合成配置档占位符标记为优先级低于环境变量/配置支持的认证 +- `resolveDynamicModel`:提供商可以接受尚未出现在本地静态目录中的模型 ID - `prepareDynamicModel`:提供商在重试动态解析前需要刷新元数据 - `normalizeResolvedModel`:提供商需要进行传输或基础 URL 重写 -- `contributeResolvedModelCompat`:即使模型通过其他兼容传输到达,提供商也可以为其厂商模型贡献兼容标记 -- `capabilities`:提供商发布转录/工具/提供商家族的行为差异 -- `normalizeToolSchemas`:提供商会在嵌入式运行器看到工具 schema 之前对其进行清理 -- `inspectToolSchemas`:提供商会在标准化后暴露传输特定的 schema 警告 +- `contributeResolvedModelCompat`:即使供应商模型是通过另一种兼容传输到达的,提供商也能为其贡献兼容标志 +- `capabilities`:提供商发布转录/工具/提供商家族差异信息 +- `normalizeToolSchemas`:提供商会在嵌入式运行器看到工具模式前对其进行清理 +- `inspectToolSchemas`:提供商会在规范化后暴露特定于传输的模式警告 - `resolveReasoningOutputMode`:提供商选择原生或带标签的推理输出契约 -- `prepareExtraParams`:提供商为每个模型的请求参数设置默认值或进行标准化 -- `createStreamFn`:提供商用完全自定义的传输替换正常的流式路径 +- `prepareExtraParams`:提供商为每个模型的请求参数设置默认值或进行规范化 +- `createStreamFn`:提供商使用完全自定义的传输替换常规流路径 - `wrapStreamFn`:提供商应用请求头/请求体/模型兼容包装器 -- `resolveTransportTurnState`:提供商提供每轮原生传输头或元数据 -- `resolveWebSocketSessionPolicy`:提供商提供原生 WebSocket 会话头或会话冷却策略 -- `createEmbeddingProvider`:当记忆嵌入行为更适合归属于提供商插件而不是核心嵌入切换板时,由提供商拥有这部分行为 -- `formatApiKey`:提供商将存储的认证配置文件格式化为传输所需的运行时 `apiKey` 字符串 -- `refreshOAuth`:当共享的 `pi-ai` 刷新器不够用时,由提供商负责 OAuth 刷新 -- `buildAuthDoctorHint`:当 OAuth 刷新失败时,提供商附加修复指导 -- `matchesContextOverflowError`:提供商识别通用启发式规则无法捕获的、提供商特定的上下文窗口溢出错误 -- `classifyFailoverReason`:提供商将原始的提供商特定传输/API 错误映射为回退原因,例如速率限制或过载 -- `isCacheTtlEligible`:提供商决定哪些上游模型 id 支持提示缓存 TTL -- `buildMissingAuthMessage`:提供商用提供商特定的恢复提示替换通用的认证存储错误 -- `suppressBuiltInModel`:提供商隐藏陈旧的上游条目,并可在直接解析失败时返回厂商自有错误 -- `augmentModelCatalog`:提供商在发现和配置合并后追加合成/最终目录条目 -- `isBinaryThinking`:提供商拥有二元开/关思考 UX -- `supportsXHighThinking`:提供商为选定模型启用 `xhigh` -- `resolveDefaultThinkingLevel`:提供商拥有某个模型家族的默认 `/think` 策略 -- `applyConfigDefaults`:提供商在配置物化期间,根据认证模式、环境或模型家族应用提供商特定的全局默认值 -- `isModernModelRef`:提供商拥有 live/smoke 首选模型匹配逻辑 +- `resolveTransportTurnState`:提供商为每一轮提供原生传输请求头或元数据 +- `resolveWebSocketSessionPolicy`:提供商提供原生 WebSocket 会话请求头或会话冷却策略 +- `createEmbeddingProvider`:当内存嵌入行为更适合归属提供商插件而不是核心嵌入分发器时,由提供商接管 +- `formatApiKey`:提供商将已存储的认证配置档格式化为传输所期望的运行时 `apiKey` 字符串 +- `refreshOAuth`:当共享的 `pi-ai` 刷新器不足时,由提供商负责 OAuth 刷新 +- `buildAuthDoctorHint`:当 OAuth 刷新失败时,由提供商追加修复指导 +- `matchesContextOverflowError`:提供商识别通用启发式规则遗漏的、特定于提供商的上下文窗口溢出错误 +- `classifyFailoverReason`:提供商将特定于提供商的原始传输/API 错误映射为回退原因,例如速率限制或过载 +- `isCacheTtlEligible`:提供商决定哪些上游模型 ID 支持提示缓存 TTL +- `buildMissingAuthMessage`:提供商用特定于提供商的恢复提示替换通用认证存储错误 +- `suppressBuiltInModel`:提供商隐藏过时的上游条目,并且可以在直接解析失败时返回供应商自有错误 +- `augmentModelCatalog`:提供商在发现和配置合并之后追加合成/最终目录条目 +- `isBinaryThinking`:提供商接管二元开/关 thinking 体验 +- `supportsXHighThinking`:提供商让选定模型启用 `xhigh` +- `resolveDefaultThinkingLevel`:提供商接管某个模型家族的默认 `/think` 策略 +- `applyConfigDefaults`:提供商根据认证模式、环境变量或模型家族,在配置具体化期间应用提供商特定的全局默认值 +- `isModernModelRef`:提供商接管 live/smoke 首选模型匹配 - `prepareRuntimeAuth`:提供商将已配置凭证转换为短时效运行时令牌 -- `resolveUsageAuth`:提供商为 `/usage` 及相关状态/报告界面解析使用量/配额凭证 -- `fetchUsageSnapshot`:提供商拥有使用量端点的获取/解析逻辑,而核心仍拥有摘要外壳和格式化 -- `onModelSelected`:提供商在选中模型后运行副作用,例如遥测或提供商自有的会话记账 +- `resolveUsageAuth`:提供商为 `/usage` 及相关状态/报告界面解析用量/配额凭证 +- `fetchUsageSnapshot`:提供商接管用量端点获取/解析,而核心仍负责摘要外壳和格式化 +- `onModelSelected`:提供商在模型选定后运行后续副作用,例如遥测或提供商自有的会话簿记 当前内置示例: -- `anthropic`:Claude 4.6 前向兼容回退、认证修复提示、使用量端点抓取、缓存 TTL/提供商家族元数据,以及具备认证感知的全局配置默认值 -- `amazon-bedrock`:提供商自有的上下文溢出匹配,以及针对 Bedrock 特定限流/未就绪错误的回退原因分类,外加共享的 `anthropic-by-model` 重放家族,用于 Anthropic 流量上仅限 Claude 的重放策略保护 -- `anthropic-vertex`:用于 Anthropic-message 流量的仅限 Claude 的重放策略保护 -- `openrouter`:透传模型 id、请求包装器、提供商能力提示、代理 Gemini 流量上的 Gemini thought-signature 清理、通过 `openrouter-thinking` 流家族进行代理推理注入、路由元数据转发和缓存 TTL 策略 -- `github-copilot`:新手引导/设备登录、前向兼容模型回退、Claude 思考转录提示、运行时令牌交换和使用量端点抓取 -- `openai`:GPT-5.4 前向兼容回退、直接 OpenAI 传输标准化、支持 Codex 的缺失认证提示、Spark 抑制、合成 OpenAI/Codex 目录条目、思考/live-model 策略、使用量令牌别名标准化(`input` / `output` 以及 `prompt` / `completion` 家族)、用于原生 OpenAI/Codex 包装器的共享 `openai-responses-defaults` 流家族,以及提供商家族元数据 -- `google` 和 `google-gemini-cli`:Gemini 3.1 前向兼容回退、原生 Gemini 重放校验、bootstrap 重放清理、带标签的推理输出模式和现代模型匹配;Gemini CLI OAuth 还拥有认证配置文件令牌格式化、使用量令牌解析和用于使用量界面的配额端点抓取 -- `moonshot`:共享传输、插件自有的思考载荷标准化 -- `kilocode`:共享传输、插件自有请求头、推理载荷标准化、代理 Gemini thought-signature 清理和缓存 TTL 策略 -- `zai`:GLM-5 前向兼容回退、`tool_stream` 默认值、缓存 TTL 策略、二元思考/live-model 策略,以及使用量认证 + 配额抓取;未知的 `glm-5*` id 会基于内置的 `glm-4.7` 模板进行合成 -- `xai`:原生 Responses 传输标准化、针对 Grok 快速变体的 `/fast` 别名重写、默认 `tool_stream`,以及 xAI 特定的工具 schema / 推理载荷清理 -- `mistral`:插件自有能力元数据 -- `opencode` 和 `opencode-go`:插件自有能力元数据,外加代理 Gemini thought-signature 清理 +- `anthropic`:Claude 4.6 前向兼容回退、认证修复提示、用量端点抓取、缓存 TTL/提供商家族元数据,以及具备认证感知的全局配置默认值 +- `amazon-bedrock`:提供商自有的上下文溢出匹配和针对 Bedrock 特有节流/未就绪错误的回退原因分类,外加共享的 `anthropic-by-model` 重放家族,用于 Anthropic 流量上的仅 Claude 重放策略保护 +- `anthropic-vertex`:面向 Anthropic-message 流量的仅 Claude 重放策略保护 +- `openrouter`:透传模型 ID、请求包装器、提供商能力提示、代理 Gemini 流量上的 Gemini thought-signature 清理、通过 `openrouter-thinking` 流家族注入代理推理、路由元数据转发,以及缓存 TTL 策略 +- `github-copilot`:onboarding/设备登录、前向兼容模型回退、Claude-thinking 转录提示、运行时令牌交换,以及用量端点抓取 +- `openai`:GPT-5.4 前向兼容回退、直接 OpenAI 传输规范化、具备 Codex 感知的缺失认证提示、Spark 抑制、合成 OpenAI/Codex 目录条目、thinking/live-model 策略、用量令牌别名规范化(`input` / `output` 和 `prompt` / `completion` 家族)、共享的 `openai-responses-defaults` 流家族用于原生 OpenAI/Codex 包装器,以及提供商家族元数据 +- `google`:Gemini 3.1 前向兼容回退、原生 Gemini 重放验证、引导重放清理、带标签的推理输出模式,以及现代模型匹配 +- `moonshot`:共享传输、插件自有的 thinking 负载规范化 +- `kilocode`:共享传输、插件自有的请求头、推理负载规范化、代理 Gemini thought-signature 清理,以及缓存 TTL 策略 +- `zai`:GLM-5 前向兼容回退、`tool_stream` 默认值、缓存 TTL 策略、二元 thinking/live-model 策略,以及用量认证 + 配额抓取;未知的 `glm-5*` ID 会基于内置的 `glm-4.7` 模板合成 +- `xai`:原生 Responses 传输规范化、针对 Grok 快速变体的 `/fast` 别名重写、默认 `tool_stream`,以及 xAI 特有的工具模式 / 推理负载清理 +- `mistral`:插件自有的能力元数据 +- `opencode` 和 `opencode-go`:插件自有的能力元数据,外加代理 Gemini thought-signature 清理 - `byteplus`、`cloudflare-ai-gateway`、`huggingface`、`kimi`、`nvidia`、`qianfan`、`stepfun`、`synthetic`、`together`、`venice`、`vercel-ai-gateway` 和 `volcengine`:仅插件自有目录 -- `qwen`:文本模型的插件自有目录,外加其多模态界面的共享 media-understanding 和视频生成提供商注册;Qwen 视频生成使用标准 DashScope 视频端点以及内置的 Wan 模型,例如 `wan2.6-t2v` 和 `wan2.7-r2v` -- `minimax`:插件自有目录、混合 Anthropic/OpenAI 重放策略选择,以及使用量认证/快照逻辑 -- `xiaomi`:插件自有目录以及使用量认证/快照逻辑 +- `qwen`:文本模型的插件自有目录,以及用于其多模态界面的共享媒体理解和视频生成提供商注册;Qwen 视频生成使用标准 DashScope 视频端点和内置的 Wan 模型,例如 `wan2.6-t2v` 和 `wan2.7-r2v` +- `minimax`:插件自有目录、混合 Anthropic/OpenAI 重放策略选择,以及用量认证/快照逻辑 +- `xiaomi`:插件自有目录,以及用量认证/快照逻辑 -内置的 `openai` 插件现在同时拥有两个提供商 id:`openai` 和 `openai-codex`。 +内置的 `openai` 插件现在同时拥有两个提供商 ID:`openai` 和 `openai-codex`。 -以上涵盖了仍适用于 OpenClaw 正常传输方式的提供商。若提供商需要完全自定义的请求执行器,那就是另一个更深层的扩展接口了。 +以上涵盖了仍适配 OpenClaw 常规传输方式的提供商。若某个提供商需要完全自定义的请求执行器,那就是另一层更深入的扩展接口了。 -## API key 轮换 +## API 密钥轮换 - 支持为选定提供商进行通用提供商轮换。 -- 通过以下方式配置多个 key: - - `OPENCLAW_LIVE__KEY`(单个 live 覆盖,优先级最高) +- 通过以下方式配置多个密钥: + - `OPENCLAW_LIVE__KEY`(单个 live 覆盖,最高优先级) - `_API_KEYS`(逗号或分号分隔列表) - - `_API_KEY`(主 key) + - `_API_KEY`(主密钥) - `_API_KEY_*`(编号列表,例如 `_API_KEY_1`) -- 对于 Google 提供商,还会将 `GOOGLE_API_KEY` 作为后备项。 -- key 选择顺序会保留优先级并对值去重。 -- 仅在遇到速率限制响应时,请求才会使用下一个 key 重试(例如 `429`、`rate_limit`、`quota`、`resource exhausted`、`Too many concurrent requests`、`ThrottlingException`、`concurrency limit reached`、`workers_ai ... quota limit exceeded` 或周期性使用量限制消息)。 -- 非速率限制失败会立即失败;不会尝试 key 轮换。 -- 当所有候选 key 都失败时,返回最后一次尝试的最终错误。 +- 对于 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 目录) -OpenClaw 内置了 pi‑ai 目录。这些提供商**不需要** `models.providers` 配置;只需设置认证并选择模型即可。 +OpenClaw 附带 pi‑ai 目录。这些提供商**不需要** `models.providers` 配置;只需设置认证并选择一个模型。 ### OpenAI @@ -128,14 +128,14 @@ OpenClaw 内置了 pi‑ai 目录。这些提供商**不需要** `models.provide - 可选轮换:`OPENAI_API_KEYS`、`OPENAI_API_KEY_1`、`OPENAI_API_KEY_2`,以及 `OPENCLAW_LIVE_OPENAI_KEY`(单个覆盖) - 示例模型:`openai/gpt-5.4`、`openai/gpt-5.4-pro` - CLI:`openclaw onboard --auth-choice openai-api-key` -- 默认传输为 `auto`(优先 WebSocket,回退到 SSE) -- 可通过 `agents.defaults.models["openai/"].params.transport` 按模型覆盖(`"sse"`、`"websocket"` 或 `"auto"`) +- 默认传输是 `auto`(优先 WebSocket,回退到 SSE) +- 可通过 `agents.defaults.models["openai/"].params.transport` 为每个模型覆盖(`"sse"`、`"websocket"` 或 `"auto"`) - OpenAI Responses WebSocket 预热默认通过 `params.openaiWsWarmup` 启用(`true`/`false`) -- 可通过 `agents.defaults.models["openai/"].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 推理兼容载荷整形;代理路由则不会 +- 可通过 `agents.defaults.models["openai/"].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 中被有意抑制,因为 live OpenAI API 会拒绝它;Spark 被视为仅限 Codex ```json5 @@ -151,9 +151,9 @@ OpenClaw 内置了 pi‑ai 目录。这些提供商**不需要** `models.provide - 可选轮换:`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 key 和 OAuth 认证流量;OpenClaw 会将其映射为 Anthropic `service_tier`(`auto` 或 `standard_only`) -- 计费说明:对于 OpenClaw 中的 Anthropic,实际上的区分是**API key**或**带 Extra Usage 的 Claude 订阅**。Anthropic 于 **2026 年 4 月 4 日太平洋时间中午 12:00 / 英国夏令时晚上 8:00** 通知 OpenClaw 用户,**OpenClaw** 的 Claude 登录路径会被计为第三方 harness 使用,需要**单独于订阅计费**的 **Extra Usage**。我们的本地复现还表明,带有 OpenClaw 标识的提示字符串不会在 Anthropic SDK + API key 路径上复现。 -- Anthropic setup-token 现已再次作为传统/手动 OpenClaw 路径提供。使用时请预期 Anthropic 已告知 OpenClaw 用户,该路径需要 **Extra Usage**。 +- 直接公共 Anthropic 请求支持共享的 `/fast` 开关和 `params.fastMode`,包括发送到 `api.anthropic.com` 的 API 密钥和 OAuth 认证流量;OpenClaw 会将其映射为 Anthropic `service_tier`(`auto` 与 `standard_only`) +- 计费说明:对于 Anthropic 在 OpenClaw 中的使用,实际区分是 **API 密钥** 或 **带 Extra Usage 的 Claude 订阅**。Anthropic 在 **2026 年 4 月 4 日下午 12:00(PT)/ 晚上 8:00(BST)** 通知 OpenClaw 用户,**OpenClaw** 的 Claude 登录路径会被计为第三方工具链使用,因此需要单独于订阅计费的 **Extra Usage**。我们的本地复现还表明,Anthropic SDK + API 密钥路径不会复现 OpenClaw 标识提示字符串。 +- Anthropic setup-token 现已再次作为旧版/手动 OpenClaw 路径提供。使用它时,请预期 Anthropic 已告知 OpenClaw 用户,此路径需要 **Extra Usage**。 ```json5 { @@ -167,14 +167,14 @@ OpenClaw 内置了 pi‑ai 目录。这些提供商**不需要** `models.provide - 认证:OAuth(ChatGPT) - 示例模型:`openai-codex/gpt-5.4` - CLI:`openclaw onboard --auth-choice openai-codex` 或 `openclaw models auth login --provider openai-codex` -- 默认传输为 `auto`(优先 WebSocket,回退到 SSE) -- 可通过 `agents.defaults.models["openai-codex/"].params.transport` 按模型覆盖(`"sse"`、`"websocket"` 或 `"auto"`) +- 默认传输是 `auto`(优先 WebSocket,回退到 SSE) +- 可通过 `agents.defaults.models["openai-codex/"].params.transport` 为每个模型覆盖(`"sse"`、`"websocket"` 或 `"auto"`) - `params.serviceTier` 也会转发到原生 Codex Responses 请求(`chatgpt.com/backend-api`) -- 隐藏的 OpenClaw 归因头(`originator`、`version`、`User-Agent`)仅附加到发往 `chatgpt.com/backend-api` 的原生 Codex 流量,不适用于通用的 OpenAI 兼容代理 +- 隐藏的 OpenClaw 归属请求头(`originator`、`version`、`User-Agent`)仅会附加到发往 `chatgpt.com/backend-api` 的原生 Codex 流量,不适用于通用的 OpenAI 兼容代理 - 与直接 `openai/*` 共享相同的 `/fast` 开关和 `params.fastMode` 配置;OpenClaw 会将其映射为 `service_tier=priority` -- 当 Codex OAuth 目录暴露 `openai-codex/gpt-5.3-codex-spark` 时,该模型仍然可用;是否可用取决于权益 -- `openai-codex/gpt-5.4` 保持原生 `contextWindow = 1050000` 和默认运行时 `contextTokens = 272000`;可通过 `models.providers.openai-codex.models[].contextTokens` 覆盖运行时上限 -- 策略说明:OpenAI Codex OAuth 明确支持用于像 OpenClaw 这样的外部工具/工作流。 +- 当 Codex OAuth 目录暴露 `openai-codex/gpt-5.3-codex-spark` 时,它仍可用;是否可用取决于 entitlement +- `openai-codex/gpt-5.4` 保留原生 `contextWindow = 1050000` 和默认运行时 `contextTokens = 272000`;可通过 `models.providers.openai-codex.models[].contextTokens` 覆盖运行时上限 +- 策略说明:OpenAI Codex OAuth 明确支持用于 OpenClaw 这类外部工具/工作流。 ```json5 { @@ -197,7 +197,7 @@ OpenClaw 内置了 pi‑ai 目录。这些提供商**不需要** `models.provide ### 其他订阅式托管选项 - [Qwen Cloud](/zh-CN/providers/qwen):Qwen Cloud 提供商界面,以及 Alibaba DashScope 和 Coding Plan 端点映射 -- [MiniMax](/zh-CN/providers/minimax):MiniMax Coding Plan OAuth 或 API key 访问 +- [MiniMax](/zh-CN/providers/minimax):MiniMax Coding Plan OAuth 或 API 密钥访问 - [GLM Models](/zh-CN/providers/glm):Z.AI Coding Plan 或通用 API 端点 ### OpenCode @@ -214,31 +214,21 @@ OpenClaw 内置了 pi‑ai 目录。这些提供商**不需要** `models.provide } ``` -### Google Gemini(API key) +### Google Gemini(API 密钥) - 提供商:`google` - 认证:`GEMINI_API_KEY` -- 可选轮换:`GEMINI_API_KEYS`、`GEMINI_API_KEY_1`、`GEMINI_API_KEY_2`、后备 `GOOGLE_API_KEY`,以及 `OPENCLAW_LIVE_GEMINI_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` -- 直接 Gemini 运行还接受 `agents.defaults.models["google/"].params.cachedContent`(或旧版 `cached_content`),以转发提供商原生的 `cachedContents/...` 句柄;Gemini 缓存命中会以 OpenClaw `cacheRead` 的形式显示 +- 直接 Gemini 运行也接受 `agents.defaults.models["google/"].params.cachedContent`(或旧版 `cached_content`),以转发提供商原生的 `cachedContents/...` 句柄;Gemini 缓存命中会以 OpenClaw `cacheRead` 形式显示 -### Google Vertex 和 Gemini CLI +### Google Vertex -- 提供商:`google-vertex`、`google-gemini-cli` -- 认证:Vertex 使用 gcloud ADC;Gemini CLI 使用其 OAuth 流程 -- 注意:OpenClaw 中的 Gemini CLI OAuth 是非官方集成。一些用户报告称,使用第三方客户端后 Google 账号会受到限制。若你选择继续,请先查看 Google 条款并使用非关键账号。 -- Gemini CLI OAuth 作为内置 `google` 插件的一部分提供。 - - 先安装 Gemini CLI: - - `brew install gemini-cli` - - 或 `npm install -g @google/gemini-cli` - - 启用:`openclaw plugins enable google` - - 登录:`openclaw models auth login --provider google-gemini-cli --set-default` - - 默认模型:`google-gemini-cli/gemini-3.1-pro-preview` - - 注意:你**不需要**把 client id 或 secret 粘贴到 `openclaw.json` 中。CLI 登录流程会将令牌存储在 Gateway 网关主机上的认证配置文件中。 - - 如果登录后请求失败,请在 Gateway 网关主机上设置 `GOOGLE_CLOUD_PROJECT` 或 `GOOGLE_CLOUD_PROJECT_ID`。 - - Gemini CLI JSON 回复会从 `response` 解析;使用量回退到 `stats`,其中 `stats.cached` 会被标准化为 OpenClaw `cacheRead`。 +- 提供商:`google-vertex` +- 认证:gcloud ADC + - Gemini CLI JSON 回复从 `response` 解析;用量会回退到 `stats`,其中 `stats.cached` 会被规范化为 OpenClaw `cacheRead`。 ### Z.AI(GLM) @@ -246,43 +236,43 @@ OpenClaw 内置了 pi‑ai 目录。这些提供商**不需要** `models.provide - 认证:`ZAI_API_KEY` - 示例模型:`zai/glm-5` - 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 +### Vercel AI Gateway 网关 - 提供商:`vercel-ai-gateway` - 认证:`AI_GATEWAY_API_KEY` - 示例模型:`vercel-ai-gateway/anthropic/claude-opus-4.6` - CLI:`openclaw onboard --auth-choice ai-gateway-api-key` -### Kilo Gateway +### Kilo Gateway 网关 - 提供商:`kilocode` - 认证:`KILOCODE_API_KEY` - 示例模型:`kilocode/kilo/auto` - CLI:`openclaw onboard --auth-choice kilocode-api-key` - 基础 URL:`https://api.kilo.ai/api/gateway/` -- 静态后备目录内置 `kilocode/kilo/auto`;live `https://api.kilo.ai/api/gateway/models` 发现可以进一步扩展运行时目录。 -- `kilocode/kilo/auto` 背后的确切上游路由由 Kilo Gateway 拥有,不是 OpenClaw 中硬编码的。 +- 静态回退目录附带 `kilocode/kilo/auto`;live `https://api.kilo.ai/api/gateway/models` 发现可进一步扩展运行时目录。 +- `kilocode/kilo/auto` 背后的确切上游路由由 Kilo Gateway 网关负责,不在 OpenClaw 中硬编码。 -有关设置详情,请参见 [/providers/kilocode](/zh-CN/providers/kilocode)。 +设置详情请参见 [/providers/kilocode](/zh-CN/providers/kilocode)。 ### 其他内置提供商插件 - OpenRouter:`openrouter`(`OPENROUTER_API_KEY`) - 示例模型:`openrouter/auto` -- 仅当请求实际指向 `openrouter.ai` 时,OpenClaw 才会应用 OpenRouter 文档中说明的应用归因头 -- OpenRouter 特有的 Anthropic `cache_control` 标记同样仅对已验证的 OpenRouter 路由生效,不适用于任意代理 URL -- OpenRouter 仍然走代理式的 OpenAI 兼容路径,因此不会转发原生 OpenAI 专用的请求整形(`serviceTier`、Responses `store`、提示缓存提示、OpenAI 推理兼容载荷) -- 基于 Gemini 的 OpenRouter 引用仅保留代理 Gemini thought-signature 清理;原生 Gemini 重放校验和 bootstrap 重写仍然关闭 -- Kilo Gateway:`kilocode`(`KILOCODE_API_KEY`) +- 仅当请求实际指向 `openrouter.ai` 时,OpenClaw 才会应用 OpenRouter 文档中的应用归属请求头 +- OpenRouter 特有的 Anthropic `cache_control` 标记同样仅限已验证的 OpenRouter 路由,不适用于任意代理 URL +- OpenRouter 仍使用代理式 OpenAI 兼容路径,因此不会转发原生 OpenAI 专属请求整形(`serviceTier`、Responses `store`、提示缓存提示、OpenAI 推理兼容负载) +- 基于 Gemini 的 OpenRouter 引用仅保留代理 Gemini thought-signature 清理;原生 Gemini 重放验证和引导重写不会启用 +- Kilo Gateway 网关:`kilocode`(`KILOCODE_API_KEY`) - 示例模型:`kilocode/kilo/auto` -- 基于 Gemini 的 Kilo 引用保留相同的代理 Gemini thought-signature 清理路径;`kilocode/kilo/auto` 和其他不支持代理推理提示的模型会跳过代理推理注入 -- MiniMax:`minimax`(API key)和 `minimax-portal`(OAuth) -- 认证:`minimax` 使用 `MINIMAX_API_KEY`;`minimax-portal` 使用 `MINIMAX_OAUTH_TOKEN` 或 `MINIMAX_API_KEY` +- 基于 Gemini 的 Kilo 引用保留相同的代理 Gemini thought-signature 清理路径;`kilocode/kilo/auto` 及其他不支持代理推理提示的路径会跳过代理推理注入 +- MiniMax:`minimax`(API 密钥)和 `minimax-portal`(OAuth) +- 认证:`MINIMAX_API_KEY` 用于 `minimax`;`MINIMAX_OAUTH_TOKEN` 或 `MINIMAX_API_KEY` 用于 `minimax-portal` - 示例模型:`minimax/MiniMax-M2.7` 或 `minimax-portal/MiniMax-M2.7` -- MiniMax onboarding/API key 设置会写入显式的 M2.7 模型定义,并包含 `input: ["text", "image"]`;在该提供商配置物化之前,内置提供商目录会将聊天引用保持为仅文本 +- MiniMax onboarding/API 密钥设置会写入显式的 M2.7 模型定义,并带有 `input: ["text", "image"]`;在该提供商配置具体化之前,内置提供商目录会将聊天引用保持为仅文本 - Moonshot:`moonshot`(`MOONSHOT_API_KEY`) - 示例模型:`moonshot/kimi-k2.5` - Kimi Coding:`kimi`(`KIMI_API_KEY` 或 `KIMICODE_API_KEY`) @@ -300,15 +290,15 @@ OpenClaw 内置了 pi‑ai 目录。这些提供商**不需要** `models.provide - Venice:`venice`(`VENICE_API_KEY`) - Xiaomi:`xiaomi`(`XIAOMI_API_KEY`) - 示例模型:`xiaomi/mimo-v2-flash` -- Vercel AI Gateway:`vercel-ai-gateway`(`AI_GATEWAY_API_KEY`) +- Vercel AI Gateway 网关:`vercel-ai-gateway`(`AI_GATEWAY_API_KEY`) - Hugging Face Inference:`huggingface`(`HUGGINGFACE_HUB_TOKEN` 或 `HF_TOKEN`) -- Cloudflare AI Gateway:`cloudflare-ai-gateway`(`CLOUDFLARE_AI_GATEWAY_API_KEY`) +- Cloudflare AI Gateway 网关:`cloudflare-ai-gateway`(`CLOUDFLARE_AI_GATEWAY_API_KEY`) - Volcengine:`volcengine`(`VOLCANO_ENGINE_API_KEY`) - 示例模型:`volcengine-plan/ark-code-latest` - BytePlus(国际版):`byteplus`(`BYTEPLUS_API_KEY`) - 示例模型:`byteplus-plan/ark-code-latest` - xAI:`xai`(`XAI_API_KEY`) - - 原生内置的 xAI 请求使用 xAI Responses 路径 + - 原生内置 xAI 请求使用 xAI Responses 路径 - `/fast` 或 `params.fastMode: true` 会将 `grok-3`、`grok-3-mini`、`grok-4` 和 `grok-4-0709` 重写为对应的 `*-fast` 变体 - `tool_stream` 默认开启;将 `agents.defaults.models["xai/"].params.tool_stream` 设为 `false` 可关闭 - Mistral:`mistral`(`MISTRAL_API_KEY`) @@ -316,28 +306,28 @@ OpenClaw 内置了 pi‑ai 目录。这些提供商**不需要** `models.provide - CLI:`openclaw onboard --auth-choice mistral-api-key` - Groq:`groq`(`GROQ_API_KEY`) - Cerebras:`cerebras`(`CEREBRAS_API_KEY`) - - Cerebras 上的 GLM 模型使用 id `zai-glm-4.7` 和 `zai-glm-4.6`。 + - Cerebras 上的 GLM 模型使用 ID `zai-glm-4.7` 和 `zai-glm-4.6`。 - OpenAI 兼容基础 URL:`https://api.cerebras.ai/v1`。 - GitHub Copilot:`github-copilot`(`COPILOT_GITHUB_TOKEN` / `GH_TOKEN` / `GITHUB_TOKEN`) - Hugging Face Inference 示例模型:`huggingface/deepseek-ai/DeepSeek-R1`;CLI:`openclaw onboard --auth-choice huggingface-api-key`。参见 [Hugging Face(Inference)](/zh-CN/providers/huggingface)。 -## 通过 `models.providers` 配置的提供商(自定义/基础 URL) +## 通过 `models.providers` 使用的提供商(自定义/基础 URL) -使用 `models.providers`(或 `models.json`)来添加**自定义**提供商或 OpenAI/Anthropic 兼容代理。 +使用 `models.providers`(或 `models.json`)添加**自定义**提供商或 OpenAI/Anthropic 兼容代理。 -下方许多内置提供商插件已经发布了默认目录。 -仅当你想覆盖默认基础 URL、请求头或模型列表时,才使用显式的 `models.providers.` 条目。 +下面许多内置提供商插件已经发布了默认目录。 +仅当你想覆盖默认基础 URL、请求头或模型列表时,才使用显式 `models.providers.` 条目。 ### Moonshot AI(Kimi) -Moonshot 作为内置提供商插件提供。默认请使用内置提供商,只有在你需要覆盖基础 URL 或模型元数据时,才添加显式的 `models.providers.moonshot` 条目: +Moonshot 作为内置提供商插件提供。默认请使用内置提供商,仅当你需要覆盖基础 URL 或模型元数据时,才添加显式 `models.providers.moonshot` 条目: - 提供商:`moonshot` - 认证:`MOONSHOT_API_KEY` - 示例模型:`moonshot/kimi-k2.5` - 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" @@ -384,13 +374,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` @@ -403,9 +393,9 @@ Volcano Engine(火山引擎)为中国用户提供 Doubao 和其他模型访 } ``` -新手引导默认使用编码界面,但通用 `volcengine/*` 目录也会同时注册。 +onboarding 默认使用编程界面,但同时也会注册通用 `volcengine/*` 目录。 -在 onboarding/configure 模型选择器中,Volcengine 认证选项会优先显示 `volcengine/*` 和 `volcengine-plan/*` 两类条目。如果这些模型尚未加载,OpenClaw 会回退到未过滤目录,而不是显示一个空的提供商范围选择器。 +在 onboarding/配置模型选择器中,Volcengine 认证选项会优先显示 `volcengine/*` 和 `volcengine-plan/*` 两类条目。如果这些模型尚未加载,OpenClaw 会回退到未过滤的目录,而不是显示一个空的提供商范围选择器。 可用模型: @@ -415,7 +405,7 @@ Volcano Engine(火山引擎)为中国用户提供 Doubao 和其他模型访 - `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` @@ -425,9 +415,9 @@ Volcano Engine(火山引擎)为中国用户提供 Doubao 和其他模型访 ### 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` @@ -440,9 +430,9 @@ BytePlus ARK 为国际用户提供与 Volcano Engine 相同的模型访问。 } ``` -新手引导默认使用编码界面,但通用 `byteplus/*` 目录也会同时注册。 +onboarding 默认使用编程界面,但同时也会注册通用 `byteplus/*` 目录。 -在 onboarding/configure 模型选择器中,BytePlus 认证选项会优先显示 `byteplus/*` 和 `byteplus-plan/*` 两类条目。如果这些模型尚未加载,OpenClaw 会回退到未过滤目录,而不是显示一个空的提供商范围选择器。 +在 onboarding/配置模型选择器中,BytePlus 认证选项会优先显示 `byteplus/*` 和 `byteplus-plan/*` 两类条目。如果这些模型尚未加载,OpenClaw 会回退到未过滤的目录,而不是显示一个空的提供商范围选择器。 可用模型: @@ -450,7 +440,7 @@ BytePlus ARK 为国际用户提供与 Volcano Engine 相同的模型访问。 - `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` @@ -490,22 +480,22 @@ Synthetic 通过 `synthetic` 提供商提供 Anthropic 兼容模型: MiniMax 通过 `models.providers` 配置,因为它使用自定义端点: -- MiniMax OAuth(Global):`--auth-choice minimax-global-oauth` -- MiniMax OAuth(CN):`--auth-choice minimax-cn-oauth` -- MiniMax API key(Global):`--auth-choice minimax-global-api` -- MiniMax API key(CN):`--auth-choice minimax-cn-api` -- 认证:`minimax` 使用 `MINIMAX_API_KEY`;`minimax-portal` 使用 `MINIMAX_OAUTH_TOKEN` 或 `MINIMAX_API_KEY` +- 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_API_KEY` 用于 `minimax`;`MINIMAX_OAUTH_TOKEN` 或 `MINIMAX_API_KEY` 用于 `minimax-portal` -有关设置详情、模型选项和配置片段,请参见 [/providers/minimax](/zh-CN/providers/minimax)。 +设置详情、模型选项和配置片段请参见 [/providers/minimax](/zh-CN/providers/minimax)。 -在 MiniMax 的 Anthropic 兼容流式路径上,OpenClaw 默认关闭 thinking,除非你显式设置它,并且 `/fast on` 会将 `MiniMax-M2.7` 重写为 `MiniMax-M2.7-highspeed`。 +在 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` -- 网页搜索保持在提供商 id `minimax` +- 图像理解在两个 MiniMax 认证路径上都使用插件自有的 `MiniMax-VL-01` +- Web 搜索保持在提供商 ID `minimax` ### Ollama @@ -529,7 +519,7 @@ ollama pull llama3.3 } ``` -当你使用 `OLLAMA_API_KEY` 选择加入时,系统会在本地 `http://127.0.0.1:11434` 检测 Ollama,内置提供商插件会将 Ollama 直接添加到 `openclaw onboard` 和模型选择器中。有关 onboarding、云端/本地模式和自定义配置,请参见 [/providers/ollama](/zh-CN/providers/ollama)。 +当你通过 `OLLAMA_API_KEY` 选择启用时,Ollama 会在本地 `http://127.0.0.1:11434` 被检测到,内置提供商插件会将 Ollama 直接添加到 `openclaw onboard` 和模型选择器中。关于 onboarding、云端/本地模式和自定义配置,请参见 [/providers/ollama](/zh-CN/providers/ollama)。 ### vLLM @@ -539,13 +529,13 @@ vLLM 作为内置提供商插件提供,用于本地/自托管的 OpenAI 兼容 - 认证:可选(取决于你的服务器) - 默认基础 URL:`http://127.0.0.1:8000/v1` -要在本地选择加入自动发现(如果你的服务器不强制认证,任意值都可以): +要选择启用本地自动发现(如果你的服务器不强制认证,任意值都可以): ```bash export VLLM_API_KEY="vllm-local" ``` -然后设置一个模型(替换为 `/v1/models` 返回的其中一个 id): +然后设置一个模型(替换为 `/v1/models` 返回的某个 ID): ```json5 { @@ -559,19 +549,19 @@ export VLLM_API_KEY="vllm-local" ### SGLang -SGLang 作为内置提供商插件提供,用于高性能自托管 OpenAI 兼容服务器: +SGLang 作为内置提供商插件提供,用于高速自托管的 OpenAI 兼容服务器: - 提供商:`sglang` - 认证:可选(取决于你的服务器) - 默认基础 URL:`http://127.0.0.1:30000/v1` -要在本地选择加入自动发现(如果你的服务器不强制认证,任意值都可以): +要选择启用本地自动发现(如果你的服务器不强制认证,任意值都可以): ```bash export SGLANG_API_KEY="sglang-local" ``` -然后设置一个模型(替换为 `/v1/models` 返回的其中一个 id): +然后设置一个模型(替换为 `/v1/models` 返回的某个 ID): ```json5 { @@ -620,18 +610,18 @@ export SGLANG_API_KEY="sglang-local" 说明: -- 对于自定义提供商,`reasoning`、`input`、`cost`、`contextWindow` 和 `maxTokens` 是可选的。 - 省略时,OpenClaw 默认使用: +- 对于自定义提供商,`reasoning`、`input`、`cost`、`contextWindow` 和 `maxTokens` 都是可选项。 + 省略时,OpenClaw 默认值为: - `reasoning: false` - `input: ["text"]` - `cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }` - `contextWindow: 200000` - `maxTokens: 8192` -- 建议:设置与你的代理/模型限制相匹配的显式值。 -- 对于非原生端点上的 `api: "openai-completions"`(任何非空 `baseUrl` 且主机不是 `api.openai.com`),OpenClaw 会强制 `compat.supportsDeveloperRole: false`,以避免提供商因不支持 `developer` 角色而返回 400 错误。 -- 代理式 OpenAI 兼容路由也会跳过原生 OpenAI 专用请求整形:没有 `service_tier`,没有 Responses `store`,没有提示缓存提示,没有 OpenAI 推理兼容载荷整形,也没有隐藏的 OpenClaw 归因头。 -- 如果 `baseUrl` 为空/省略,OpenClaw 会保留默认 OpenAI 行为(其会解析为 `api.openai.com`)。 -- 出于安全考虑,即使显式设置 `compat.supportsDeveloperRole: true`,在非原生 `openai-completions` 端点上仍会被覆盖。 +- 建议:设置与你的代理/模型限制匹配的显式值。 +- 对于非原生端点上的 `api: "openai-completions"`(任意非空 `baseUrl`,且其主机不是 `api.openai.com`),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` 仍会被覆盖。 ## CLI 示例 @@ -641,7 +631,7 @@ openclaw models set opencode/claude-opus-4-6 openclaw models list ``` -另见:[/gateway/configuration](/zh-CN/gateway/configuration) 查看完整配置示例。 +另请参见:[/gateway/configuration](/zh-CN/gateway/configuration) 了解完整配置示例。 ## 相关内容 diff --git a/docs/zh-CN/gateway/cli-backends.md b/docs/zh-CN/gateway/cli-backends.md deleted file mode 100644 index b19d25fb1..000000000 --- a/docs/zh-CN/gateway/cli-backends.md +++ /dev/null @@ -1,289 +0,0 @@ ---- -read_when: - - 你希望在 API 提供商失败时有一个可靠的回退方案 - - 你正在运行 Codex CLI 或其他本地 AI CLI,并希望复用它们 - - 你想了解用于 CLI 后端工具访问的 MCP loopback 桥接 -summary: CLI 后端:带可选 MCP 工具桥接的本地 AI CLI 回退方案 -title: CLI 后端 -x-i18n: - generated_at: "2026-04-05T17:47:31Z" - model: gpt-5.4 - provider: openai - source_hash: fe30bb4d5f51adcda53bf69a4f88e27832e78630ed5bfd8a33a66b6412b66f2d - source_path: gateway/cli-backends.md - workflow: 15 ---- - -# CLI 后端(回退运行时) - -当 API 提供商宕机、受到速率限制或暂时行为异常时,OpenClaw 可以运行**本地 AI CLI** 作为**纯文本回退**。这是一个有意保守的设计: - -- **OpenClaw 工具不会被直接注入**,但设置了 `bundleMcp: true` 的后端 - 可以通过 loopback MCP 桥接接收 Gateway 网关工具。 -- 对支持该能力的 CLI 提供 **JSONL 分块流式传输**。 -- **支持会话**(因此后续轮次能保持连贯)。 -- 如果 CLI 接受图像路径,**图像可以透传**。 - -这被设计为一个**安全网**,而不是主要路径。当你希望在不依赖外部 API 的情况下获得“始终可用”的文本回复时,可以使用它。 - -如果你想要完整的封装运行时,包括 ACP 会话控制、后台任务、 -线程 / 对话绑定以及持久化的外部编码会话,请改用 -[ACP 智能体](/zh-CN/tools/acp-agents)。CLI 后端不是 ACP。 - -## 适合初学者的快速开始 - -你可以**无需任何配置**使用 Codex CLI(内置 OpenAI 插件 -会注册一个默认后端): - -```bash -openclaw agent --message "hi" --model codex-cli/gpt-5.4 -``` - -如果你的 Gateway 网关运行在 launchd / systemd 下,并且 PATH 很精简,只需添加 -命令路径: - -```json5 -{ - agents: { - defaults: { - cliBackends: { - "codex-cli": { - command: "/opt/homebrew/bin/codex", - }, - }, - }, - }, -} -``` - -就是这样。除了 CLI 本身之外,不需要密钥,也不需要额外的认证配置。 - -如果你在 Gateway 网关主机上将某个内置 CLI 后端作为**主要消息提供商**使用,OpenClaw 现在会在你的配置 -明确在模型引用或 -`agents.defaults.cliBackends` 下引用该后端时,自动加载其所属的内置插件。 - -## 作为回退使用 - -将 CLI 后端添加到你的回退列表中,这样它只会在主模型失败时运行: - -```json5 -{ - agents: { - defaults: { - model: { - primary: "anthropic/claude-opus-4-6", - fallbacks: ["codex-cli/gpt-5.4"], - }, - models: { - "anthropic/claude-opus-4-6": { alias: "Opus" }, - "codex-cli/gpt-5.4": {}, - }, - }, - }, -} -``` - -说明: - -- 如果你使用 `agents.defaults.models`(允许列表),你也必须将 CLI 后端模型包含在其中。 -- 如果主提供商失败(认证、速率限制、超时),OpenClaw 会 - 接着尝试 CLI 后端。 - -## 配置概览 - -所有 CLI 后端都位于: - -``` -agents.defaults.cliBackends -``` - -每个条目以**提供商 ID** 为键(例如 `codex-cli`、`my-cli`)。 -该提供商 ID 会成为你的模型引用左侧部分: - -``` -/ -``` - -### 配置示例 - -```json5 -{ - agents: { - defaults: { - cliBackends: { - "codex-cli": { - command: "/opt/homebrew/bin/codex", - }, - "my-cli": { - command: "my-cli", - args: ["--json"], - output: "json", - input: "arg", - modelArg: "--model", - modelAliases: { - "claude-opus-4-6": "opus", - "claude-sonnet-4-6": "sonnet", - }, - sessionArg: "--session", - sessionMode: "existing", - sessionIdFields: ["session_id", "conversation_id"], - systemPromptArg: "--system", - systemPromptWhen: "first", - imageArg: "--image", - imageMode: "repeat", - serialize: true, - }, - }, - }, - }, -} -``` - -## 工作原理 - -1. 根据提供商前缀(`codex-cli/...`)**选择后端**。 -2. 使用相同的 OpenClaw 提示词和工作区上下文**构建系统提示词**。 -3. 如果支持,会使用会话 ID **执行 CLI**,以保持历史一致。 -4. **解析输出**(JSON 或纯文本)并返回最终文本。 -5. 按后端**持久化会话 ID**,以便后续轮次复用相同的 CLI 会话。 - - -内置 Anthropic `claude-cli` 后端已被移除,因为 Anthropic 的 -OpenClaw 计费边界发生了变化。OpenClaw 仍然支持通用 CLI -后端,但 Anthropic API 流量应直接使用 Anthropic 提供商, -而不是已移除的本地 Claude CLI 路径。 - - -## 会话 - -- 如果 CLI 支持会话,请设置 `sessionArg`(例如 `--session-id`)或 - `sessionArgs`(占位符为 `{sessionId}`),用于需要将该 ID 插入 - 多个标志的情况。 -- 如果 CLI 使用带有不同标志的**恢复子命令**,请设置 - `resumeArgs`(恢复时替换 `args`),并可选设置 `resumeOutput` - (用于非 JSON 恢复)。 -- `sessionMode`: - - `always`:始终发送会话 ID(若未存储则生成新的 UUID)。 - - `existing`:仅当之前已存储会话 ID 时才发送。 - - `none`:从不发送会话 ID。 - -串行化说明: - -- `serialize: true` 会保持同一通道中的运行按顺序执行。 -- 大多数 CLI 会在一个提供商通道上串行执行。 -- 当后端认证状态发生变化时,包括重新登录、令牌轮换或认证配置文件凭证变化,OpenClaw 会丢弃已存储的 CLI 会话复用状态。 - -## 图像(透传) - -如果你的 CLI 接受图像路径,请设置 `imageArg`: - -```json5 -imageArg: "--image", -imageMode: "repeat" -``` - -OpenClaw 会将 base64 图像写入临时文件。如果设置了 `imageArg`,这些 -路径会作为 CLI 参数传递。如果缺少 `imageArg`,OpenClaw 会将 -文件路径附加到提示词中(路径注入);这对于那些能从普通路径自动加载本地文件的 CLI 来说已经足够。 - -## 输入 / 输出 - -- `output: "json"`(默认)会尝试解析 JSON 并提取文本 + 会话 ID。 -- 对于 Gemini CLI JSON 输出,当 `usage` 缺失或为空时,OpenClaw 会从 `response` 读取回复文本,并从 - `stats` 读取用量。 -- `output: "jsonl"` 会解析 JSONL 流(例如 Codex CLI `--json`),并提取最终智能体消息以及存在时的会话 - 标识符。 -- `output: "text"` 会将 stdout 视为最终响应。 - -输入模式: - -- `input: "arg"`(默认)会将提示词作为最后一个 CLI 参数传递。 -- `input: "stdin"` 会通过 stdin 发送提示词。 -- 如果提示词很长且设置了 `maxPromptArgChars`,则会改用 stdin。 - -## 默认值(插件所有) - -内置 OpenAI 插件也会为 `codex-cli` 注册一个默认值: - -- `command: "codex"` -- `args: ["exec","--json","--color","never","--sandbox","workspace-write","--skip-git-repo-check"]` -- `resumeArgs: ["exec","resume","{sessionId}","--color","never","--sandbox","workspace-write","--skip-git-repo-check"]` -- `output: "jsonl"` -- `resumeOutput: "text"` -- `modelArg: "--model"` -- `imageArg: "--image"` -- `sessionMode: "existing"` - -内置 Google 插件也会为 `google-gemini-cli` 注册一个默认值: - -- `command: "gemini"` -- `args: ["--prompt", "--output-format", "json"]` -- `resumeArgs: ["--resume", "{sessionId}", "--prompt", "--output-format", "json"]` -- `modelArg: "--model"` -- `sessionMode: "existing"` -- `sessionIdFields: ["session_id", "sessionId"]` - -前提条件:本地 Gemini CLI 必须已安装,并可在 -`PATH` 中通过 `gemini` 使用(`brew install gemini-cli` 或 -`npm install -g @google/gemini-cli`)。 - -Gemini CLI JSON 说明: - -- 回复文本从 JSON `response` 字段读取。 -- 当 `usage` 缺失或为空时,用量会回退到 `stats`。 -- `stats.cached` 会被标准化为 OpenClaw `cacheRead`。 -- 如果 `stats.input` 缺失,OpenClaw 会通过 - `stats.input_tokens - stats.cached` 推导输入令牌数。 - -仅在需要时覆盖(常见情况:使用绝对 `command` 路径)。 - -## 插件所有的默认值 - -CLI 后端默认值现在是插件表面的一部分: - -- 插件通过 `api.registerCliBackend(...)` 注册它们。 -- 后端 `id` 会成为模型引用中的提供商前缀。 -- `agents.defaults.cliBackends.` 中的用户配置仍会覆盖插件默认值。 -- 后端特定的配置清理仍通过可选的 - `normalizeConfig` hook 由插件自身负责。 - -## 内置 MCP 叠加层 - -CLI 后端**不会**直接接收 OpenClaw 工具调用,但后端可以通过设置 -`bundleMcp: true` 选择接收自动生成的 MCP 配置叠加层。 - -当前内置行为: - -- `codex-cli`:无内置 MCP 叠加层 -- `google-gemini-cli`:无内置 MCP 叠加层 - -启用内置 MCP 时,OpenClaw 会: - -- 启动一个 loopback HTTP MCP 服务器,将 Gateway 网关工具暴露给 CLI 进程 -- 使用每会话令牌(`OPENCLAW_MCP_TOKEN`)对桥接进行认证 -- 将工具访问范围限定在当前会话、账户和渠道上下文内 -- 为当前工作区加载已启用的内置 MCP 服务器 -- 将它们与任何现有的后端 `--mcp-config` 合并 -- 重写 CLI 参数以传递 `--strict-mcp-config --mcp-config ` - -如果没有启用任何 MCP 服务器,只要后端选择了内置 MCP,OpenClaw 仍会注入严格配置,以便后台运行保持隔离。 - -## 限制 - -- **没有直接的 OpenClaw 工具调用。** OpenClaw 不会将工具调用直接注入 - CLI 后端协议。只有当后端选择 - `bundleMcp: true` 时,后端才能看到 Gateway 网关工具。 -- **流式传输取决于后端。** 某些后端会流式输出 JSONL;另一些则会 - 缓冲到退出时再输出。 -- **结构化输出**取决于 CLI 的 JSON 格式。 -- **Codex CLI 会话**通过文本输出恢复(不是 JSONL),其结构性 - 不如初始的 `--json` 运行。OpenClaw 会话仍然可以 - 正常工作。 - -## 故障排除 - -- **找不到 CLI**:将 `command` 设置为完整路径。 -- **模型名称错误**:使用 `modelAliases` 将 `provider/model` 映射到 CLI 模型。 -- **没有会话连续性**:确保已设置 `sessionArg` 且 `sessionMode` 不是 - `none`(Codex CLI 当前无法使用 JSON 输出进行恢复)。 -- **图像被忽略**:设置 `imageArg`(并确认 CLI 支持文件路径)。 diff --git a/docs/zh-CN/gateway/configuration-reference.md b/docs/zh-CN/gateway/configuration-reference.md index 81cd9ef15..8b9d43893 100644 --- a/docs/zh-CN/gateway/configuration-reference.md +++ b/docs/zh-CN/gateway/configuration-reference.md @@ -1,56 +1,56 @@ --- read_when: - - 你需要精确到字段级别的配置语义或默认值时 - - 你正在校验渠道、模型、Gateway 网关或工具配置块时 + - 你需要精确的字段级配置语义或默认值 + - 你正在验证渠道、模型、Gateway 网关或工具配置块 summary: 每个 OpenClaw 配置键、默认值和渠道设置的完整参考 title: 配置参考 x-i18n: - generated_at: "2026-04-05T17:52:05Z" + generated_at: "2026-04-05T18:18:46Z" model: gpt-5.4 provider: openai - source_hash: 77d9dffa815b3171b10137b95eebcb6dcd7b2a4f5e925ccc5f935dce66419a62 + source_hash: c3b087ff868e25165e7b80dd7505f8b29c218cd6894304179b7a9426da231276 source_path: gateway/configuration-reference.md workflow: 15 --- # 配置参考 -`~/.openclaw/openclaw.json` 中可用的每个字段。若需面向任务的概览,请参见 [Configuration](/zh-CN/gateway/configuration)。 +`~/.openclaw/openclaw.json` 中可用的每个字段。若需按任务组织的概览,请参见 [Configuration](/zh-CN/gateway/configuration)。 -配置格式为 **JSON5**(允许注释和尾随逗号)。所有字段都是可选的——省略时,OpenClaw 会使用安全默认值。 +配置格式为 **JSON5**(允许注释和尾随逗号)。所有字段都是可选的——省略时,OpenClaw 会使用安全的默认值。 --- ## 渠道 -每个渠道在其配置部分存在时都会自动启动(除非 `enabled: false`)。 +每个渠道在其配置节存在时都会自动启动(除非设置了 `enabled: false`)。 ### 私信和群组访问 所有渠道都支持私信策略和群组策略: -| 私信策略 | 行为 | -| ------------------- | ------------------------------------------------ | -| `pairing`(默认) | 未知发送者会收到一次性配对码;所有者必须批准 | -| `allowlist` | 仅允许 `allowFrom` 中的发送者(或已配对允许存储) | -| `open` | 允许所有传入私信(要求 `allowFrom: ["*"]`) | -| `disabled` | 忽略所有传入私信 | +| 私信策略 | 行为 | +| --------------------- | -------------------------------------------------------- | +| `pairing`(默认) | 未知发送者会收到一次性配对码;必须由所有者批准 | +| `allowlist` | 仅允许 `allowFrom` 中的发送者(或已配对的允许存储) | +| `open` | 允许所有传入私信(需要 `allowFrom: ["*"]`) | +| `disabled` | 忽略所有传入私信 | -| 群组策略 | 行为 | -| --------------------- | -------------------------------------------- | -| `allowlist`(默认) | 仅允许匹配已配置允许列表的群组 | -| `open` | 绕过群组允许列表(仍会应用提及门控) | -| `disabled` | 屏蔽所有群组 / 房间消息 | +| 群组策略 | 行为 | +| ----------------------- | ------------------------------------------------------ | +| `allowlist`(默认) | 仅允许与已配置允许列表匹配的群组 | +| `open` | 绕过群组允许列表(仍会应用提及门控) | +| `disabled` | 阻止所有群组/房间消息 | `channels.defaults.groupPolicy` 会在提供商的 `groupPolicy` 未设置时作为默认值。 -配对码在 1 小时后过期。待处理的私信配对请求每个渠道最多 **3 个**。 -如果整个提供商配置块缺失(`channels.` 不存在),运行时群组策略会回退为 `allowlist`(默认拒绝),并在启动时发出警告。 +配对码会在 1 小时后过期。待处理的私信配对请求上限为**每个渠道 3 个**。 +如果提供商配置块完全缺失(即不存在 `channels.`),运行时群组策略会回退为 `allowlist`(默认拒绝),并在启动时发出警告。 ### 渠道模型覆盖 -使用 `channels.modelByChannel` 将特定渠道 ID 固定到某个模型。值接受 `provider/model` 或已配置的模型别名。当会话尚未有模型覆盖时(例如通过 `/model` 设置),将应用该渠道映射。 +使用 `channels.modelByChannel` 可将特定渠道 ID 固定到某个模型。值可接受 `provider/model` 或已配置的模型别名。当会话尚未有模型覆盖时(例如通过 `/model` 设置),渠道映射才会生效。 ```json5 { @@ -91,15 +91,15 @@ x-i18n: } ``` -- `channels.defaults.groupPolicy`:当提供商级别的 `groupPolicy` 未设置时的回退群组策略。 -- `channels.defaults.contextVisibility`:所有渠道的默认补充上下文可见性模式。取值:`all`(默认,包含所有引用 / 线程 / 历史上下文)、`allowlist`(仅包含来自允许列表发送者的上下文)、`allowlist_quote`(与 allowlist 相同,但保留显式引用 / 回复上下文)。每渠道覆盖:`channels..contextVisibility`。 +- `channels.defaults.groupPolicy`:当提供商级 `groupPolicy` 未设置时的回退群组策略。 +- `channels.defaults.contextVisibility`:所有渠道的默认补充上下文可见性模式。取值:`all`(默认,包含所有引用/线程/历史上下文)、`allowlist`(仅包含来自允许列表发送者的上下文)、`allowlist_quote`(与 allowlist 相同,但保留显式引用/回复上下文)。每渠道覆盖:`channels..contextVisibility`。 - `channels.defaults.heartbeat.showOk`:在心跳输出中包含健康渠道状态。 -- `channels.defaults.heartbeat.showAlerts`:在心跳输出中包含降级 / 错误状态。 -- `channels.defaults.heartbeat.useIndicator`:以紧凑的指示器样式渲染心跳输出。 +- `channels.defaults.heartbeat.showAlerts`:在心跳输出中包含降级/错误状态。 +- `channels.defaults.heartbeat.useIndicator`:渲染紧凑的指示器样式心跳输出。 ### WhatsApp -WhatsApp 通过 Gateway 网关的 web 渠道(Baileys Web)运行。存在已链接会话时会自动启动。 +WhatsApp 通过 Gateway 网关的 Web 渠道(Baileys Web)运行。当存在已关联的会话时会自动启动。 ```json5 { @@ -110,7 +110,7 @@ WhatsApp 通过 Gateway 网关的 web 渠道(Baileys Web)运行。存在已 textChunkLimit: 4000, chunkMode: "length", // length | newline mediaMaxMb: 50, - sendReadReceipts: true, // 蓝色双勾(在 self-chat 模式下为 false) + sendReadReceipts: true, // 蓝色对勾(自聊模式下为 false) groups: { "*": { requireMention: true }, }, @@ -150,9 +150,9 @@ WhatsApp 通过 Gateway 网关的 web 渠道(Baileys Web)运行。存在已 } ``` -- 出站命令默认使用账号 `default`(如果存在);否则使用首个已配置账号 ID(排序后)。 -- 可选的 `channels.whatsapp.defaultAccount` 会在其匹配某个已配置账号 ID 时覆盖该默认账号选择。 -- 旧版单账号 Baileys 凭证目录会由 `openclaw doctor` 迁移到 `whatsapp/default`。 +- 出站命令默认使用 `default` 账号(如果存在);否则使用第一个已配置的账号 ID(排序后)。 +- 可选的 `channels.whatsapp.defaultAccount` 会在其匹配某个已配置账号 ID 时,覆盖上述默认账号选择。 +- 旧版单账号 Baileys 认证目录会由 `openclaw doctor` 迁移到 `whatsapp/default`。 - 每账号覆盖:`channels.whatsapp.accounts..sendReadReceipts`、`channels.whatsapp.accounts..dmPolicy`、`channels.whatsapp.accounts..allowFrom`。 @@ -182,13 +182,13 @@ WhatsApp 通过 Gateway 网关的 web 渠道(Baileys Web)运行。存在已 }, }, customCommands: [ - { command: "backup", description: "Git 备份" }, - { command: "generate", description: "创建图像" }, + { command: "backup", description: "Git backup" }, + { command: "generate", description: "Create an image" }, ], historyLimit: 50, replyToMode: "first", // off | first | all linkPreview: true, - streaming: "partial", // off | partial | block | progress(默认:off;显式选择启用以避免预览编辑速率限制) + streaming: "partial", // off | partial | block | progress(默认:off;需显式启用以避免预览编辑速率限制) actions: { reactions: true, sendMessage: true }, reactionNotifications: "own", // off | own | all mediaMaxMb: 100, @@ -211,12 +211,12 @@ WhatsApp 通过 Gateway 网关的 web 渠道(Baileys Web)运行。存在已 } ``` -- Bot token:`channels.telegram.botToken` 或 `channels.telegram.tokenFile`(仅接受普通文件;拒绝符号链接),默认账号还可回退到 `TELEGRAM_BOT_TOKEN`。 +- Bot Token:`channels.telegram.botToken` 或 `channels.telegram.tokenFile`(仅允许常规文件;拒绝符号链接),默认账号还可回退到 `TELEGRAM_BOT_TOKEN`。 - 可选的 `channels.telegram.defaultAccount` 会在其匹配某个已配置账号 ID 时覆盖默认账号选择。 -- 在多账号配置(2 个及以上账号 ID)中,设置显式默认值(`channels.telegram.defaultAccount` 或 `channels.telegram.accounts.default`)以避免回退路由;若缺失或无效,`openclaw doctor` 会发出警告。 -- `configWrites: false` 会阻止 Telegram 发起的配置写入(supergroup ID 迁移、`/config set|unset`)。 -- 顶层 `bindings[]` 中 `type: "acp"` 的条目会为论坛话题配置持久 ACP 绑定(在 `match.peer.id` 中使用规范形式 `chatId:topic:topicId`)。字段语义参见 [ACP Agents](/zh-CN/tools/acp-agents#channel-specific-settings)。 -- Telegram 流式预览使用 `sendMessage` + `editMessageText`(在私聊和群聊中均有效)。 +- 在多账号设置中(2 个及以上账号 ID),请设置显式默认值(`channels.telegram.defaultAccount` 或 `channels.telegram.accounts.default`)以避免回退路由;若缺失或无效,`openclaw doctor` 会发出警告。 +- `configWrites: false` 会阻止由 Telegram 发起的配置写入(超级群组 ID 迁移、`/config set|unset`)。 +- 顶层 `bindings[]` 中带有 `type: "acp"` 的条目会为论坛话题配置持久 ACP 绑定(在 `match.peer.id` 中使用规范的 `chatId:topic:topicId`)。字段语义与 [ACP Agents](/zh-CN/tools/acp-agents#channel-specific-settings) 共享。 +- Telegram 流式预览使用 `sendMessage` + `editMessageText`(在私聊和群聊中都可用)。 - 重试策略:参见 [Retry policy](/zh-CN/concepts/retry)。 ### Discord @@ -264,7 +264,7 @@ WhatsApp 通过 Gateway 网关的 web 渠道(Baileys Web)运行。存在已 requireMention: true, users: ["987654321098765432"], skills: ["docs"], - systemPrompt: "仅限简短回答。", + systemPrompt: "Short answers only.", }, }, }, @@ -272,7 +272,7 @@ WhatsApp 通过 Gateway 网关的 web 渠道(Baileys Web)运行。存在已 historyLimit: 20, textChunkLimit: 2000, chunkMode: "length", // length | newline - streaming: "off", // off | partial | block | progress(在 Discord 上,progress 映射为 partial) + streaming: "off", // off | partial | block | progress(在 Discord 上 progress 映射为 partial) maxLinesPerMessage: 17, ui: { components: { @@ -283,7 +283,7 @@ WhatsApp 通过 Gateway 网关的 web 渠道(Baileys Web)运行。存在已 enabled: true, idleHours: 24, maxAgeHours: 0, - spawnSubagentSessions: false, // 为 sessions_spawn({ thread: true }) 显式启用 + spawnSubagentSessions: false, // 为 `sessions_spawn({ thread: true })` 显式启用 }, voice: { enabled: true, @@ -320,35 +320,35 @@ WhatsApp 通过 Gateway 网关的 web 渠道(Baileys Web)运行。存在已 ``` - Token:`channels.discord.token`,默认账号还可回退到 `DISCORD_BOT_TOKEN`。 -- 显式提供 Discord `token` 的直接出站调用会使用该 token 发起调用;账号级重试 / 策略设置仍来自活动运行时快照中选定的账号。 +- 直接出站调用若显式提供 Discord `token`,将使用该 token 发起调用;账号级重试/策略设置仍来自当前运行时快照中选定的账号。 - 可选的 `channels.discord.defaultAccount` 会在其匹配某个已配置账号 ID 时覆盖默认账号选择。 -- 发送目标使用 `user:`(私信)或 `channel:`(guild 渠道);不接受纯数字 ID。 -- Guild slug 会转为小写并将空格替换为 `-`;渠道键使用 slug 化名称(不含 `#`)。优先使用 guild ID。 -- 默认忽略机器人编写的消息。`allowBots: true` 会启用;使用 `allowBots: "mentions"` 则仅接受提及机器人的机器人消息(仍会过滤机器人自己的消息)。 -- `channels.discord.guilds..ignoreOtherMentions`(及渠道级覆盖)会丢弃提及其他用户或角色但未提及机器人的消息(不含 @everyone/@here)。 -- `maxLinesPerMessage`(默认 17)会拆分高消息,即使未超过 2000 字符。 -- `channels.discord.threadBindings` 控制 Discord 基于线程的路由: - - `enabled`:针对线程绑定会话功能的 Discord 覆盖(`/focus`、`/unfocus`、`/agents`、`/session idle`、`/session max-age` 以及绑定的投递 / 路由) - - `idleHours`:Discord 对不活跃自动取消聚焦时长(小时)的覆盖(`0` 表示禁用) - - `maxAgeHours`:Discord 对最大硬时长(小时)的覆盖(`0` 表示禁用) - - `spawnSubagentSessions`:为 `sessions_spawn({ thread: true })` 自动创建 / 绑定线程的显式开关 -- 顶层 `bindings[]` 中 `type: "acp"` 的条目会为渠道和线程配置持久 ACP 绑定(在 `match.peer.id` 中使用渠道 / 线程 ID)。字段语义参见 [ACP Agents](/zh-CN/tools/acp-agents#channel-specific-settings)。 +- 使用 `user:`(私信)或 `channel:`(服务器频道)作为投递目标;裸数字 ID 会被拒绝。 +- 服务器 slug 使用小写并将空格替换为 `-`;频道键使用 slug 化名称(不含 `#`)。优先使用服务器 ID。 +- 默认忽略机器人发送的消息。`allowBots: true` 会启用它们;使用 `allowBots: "mentions"` 仅接受提及机器人的机器人消息(仍会过滤机器人自己的消息)。 +- `channels.discord.guilds..ignoreOtherMentions`(以及频道级覆盖)会丢弃提及其他用户或角色但未提及机器人的消息(不含 @everyone/@here)。 +- `maxLinesPerMessage`(默认 17)会拆分行数过多的消息,即使总字符数未超过 2000。 +- `channels.discord.threadBindings` 控制 Discord 线程绑定路由: + - `enabled`:线程绑定会话功能的 Discord 覆盖(`/focus`、`/unfocus`、`/agents`、`/session idle`、`/session max-age` 以及绑定投递/路由) + - `idleHours`:按小时计算的无活动自动取消聚焦 Discord 覆盖(`0` 表示禁用) + - `maxAgeHours`:按小时计算的硬性最大存活时间 Discord 覆盖(`0` 表示禁用) + - `spawnSubagentSessions`:为 `sessions_spawn({ thread: true })` 自动创建/绑定线程的显式开关 +- 顶层 `bindings[]` 中带有 `type: "acp"` 的条目会为频道和线程配置持久 ACP 绑定(在 `match.peer.id` 中使用频道/线程 ID)。字段语义与 [ACP Agents](/zh-CN/tools/acp-agents#channel-specific-settings) 共享。 - `channels.discord.ui.components.accentColor` 设置 Discord components v2 容器的强调色。 -- `channels.discord.voice` 启用 Discord 语音频道对话,以及可选的自动加入 + TTS 覆盖。 -- `channels.discord.voice.daveEncryption` 和 `channels.discord.voice.decryptionFailureTolerance` 会透传到 `@discordjs/voice` 的 DAVE 选项(默认分别为 `true` 和 `24`)。 -- OpenClaw 还会在多次解密失败后通过离开 / 重新加入语音会话来尝试恢复语音接收。 -- `channels.discord.streaming` 是规范的流模式键。旧版 `streamMode` 和布尔型 `streaming` 值会自动迁移。 -- `channels.discord.autoPresence` 将运行时可用性映射为机器人在线状态(healthy => online、degraded => idle、exhausted => dnd),并允许可选的状态文本覆盖。 -- `channels.discord.dangerouslyAllowNameMatching` 会重新启用可变的名称 / tag 匹配(紧急兼容模式)。 -- `channels.discord.execApprovals`:Discord 原生 exec 审批投递和审批者授权。 - - `enabled`:`true`、`false` 或 `"auto"`(默认)。在 auto 模式下,当能从 `approvers` 或 `commands.ownerAllowFrom` 解析出审批者时,会激活 exec 审批。 +- `channels.discord.voice` 启用 Discord 语音频道对话以及可选的自动加入 + TTS 覆盖。 +- `channels.discord.voice.daveEncryption` 和 `channels.discord.voice.decryptionFailureTolerance` 会透传给 `@discordjs/voice` 的 DAVE 选项(默认分别为 `true` 和 `24`)。 +- OpenClaw 还会在重复解密失败后,通过离开/重新加入语音会话来尝试恢复语音接收。 +- `channels.discord.streaming` 是规范的流式模式键。旧版 `streamMode` 和布尔型 `streaming` 值会被自动迁移。 +- `channels.discord.autoPresence` 将运行时可用性映射为机器人在线状态(healthy => online,degraded => idle,exhausted => dnd),并允许可选的状态文本覆盖。 +- `channels.discord.dangerouslyAllowNameMatching` 会重新启用可变的名称/标签匹配(紧急兼容模式)。 +- `channels.discord.execApprovals`:Discord 原生 exec 审批投递与审批人授权。 + - `enabled`:`true`、`false` 或 `"auto"`(默认)。在自动模式下,当可以从 `approvers` 或 `commands.ownerAllowFrom` 解析出审批人时,exec 审批会激活。 - `approvers`:允许批准 exec 请求的 Discord 用户 ID。省略时回退到 `commands.ownerAllowFrom`。 - `agentFilter`:可选的智能体 ID 允许列表。省略则转发所有智能体的审批请求。 - `sessionFilter`:可选的会话键模式(子串或正则)。 - - `target`:审批提示发送位置。`"dm"`(默认)发送到审批者私信,`"channel"` 发送到原始渠道,`"both"` 同时发送到两者。当目标包含 `"channel"` 时,按钮仅可由已解析的审批者使用。 - - `cleanupAfterResolve`:为 `true` 时,会在批准、拒绝或超时后删除审批私信。 + - `target`:发送审批提示的位置。`"dm"`(默认)发送到审批人私信,`"channel"` 发送到原始频道,`"both"` 两处都发。若目标包含 `"channel"`,按钮仅解析出的审批人可用。 + - `cleanupAfterResolve`:为 `true` 时,在批准、拒绝或超时后删除审批私信。 -**反应通知模式:** `off`(无)、`own`(机器人的消息,默认)、`all`(所有消息)、`allowlist`(来自 `guilds..users`,作用于所有消息)。 +**反应通知模式:** `off`(无)、`own`(机器人自己的消息,默认)、`all`(所有消息)、`allowlist`(`guilds..users` 中用户发出的所有消息)。 ### Google Chat @@ -379,11 +379,11 @@ WhatsApp 通过 Gateway 网关的 web 渠道(Baileys Web)运行。存在已 } ``` -- Service account JSON:可内联(`serviceAccount`)或基于文件(`serviceAccountFile`)。 -- 也支持 Service account SecretRef(`serviceAccountRef`)。 +- 服务账号 JSON:可内联(`serviceAccount`)或基于文件(`serviceAccountFile`)。 +- 也支持服务账号 SecretRef(`serviceAccountRef`)。 - 环境变量回退:`GOOGLE_CHAT_SERVICE_ACCOUNT` 或 `GOOGLE_CHAT_SERVICE_ACCOUNT_FILE`。 -- 发送目标使用 `spaces/` 或 `users/`。 -- `channels.googlechat.dangerouslyAllowNameMatching` 会重新启用可变的电子邮件主体匹配(紧急兼容模式)。 +- 使用 `spaces/` 或 `users/` 作为投递目标。 +- `channels.googlechat.dangerouslyAllowNameMatching` 会重新启用可变邮箱主体匹配(紧急兼容模式)。 ### Slack @@ -405,7 +405,7 @@ WhatsApp 通过 Gateway 网关的 web 渠道(Baileys Web)运行。存在已 allowBots: false, users: ["U123"], skills: ["docs"], - systemPrompt: "仅限简短回答。", + systemPrompt: "Short answers only.", }, }, historyLimit: 50, @@ -448,33 +448,37 @@ WhatsApp 通过 Gateway 网关的 web 渠道(Baileys Web)运行。存在已 } ``` -- **Socket 模式**要求同时提供 `botToken` 和 `appToken`(默认账号环境变量回退使用 `SLACK_BOT_TOKEN` + `SLACK_APP_TOKEN`)。 -- **HTTP 模式**要求提供 `botToken` 加 `signingSecret`(可位于根级或每账号级)。 -- `botToken`、`appToken`、`signingSecret` 和 `userToken` 接受明文字符串或 SecretRef 对象。 -- Slack 账号快照会暴露按凭证划分的来源 / 状态字段,例如 `botTokenSource`、`botTokenStatus`、`appTokenStatus`,以及在 HTTP 模式下的 `signingSecretStatus`。`configured_unavailable` 表示该账号通过 SecretRef 配置,但当前命令 / 运行时路径无法解析出 secret 值。 -- `configWrites: false` 会阻止 Slack 发起的配置写入。 +- **Socket mode** 需要同时提供 `botToken` 和 `appToken`(默认账号环境变量回退为 `SLACK_BOT_TOKEN` + `SLACK_APP_TOKEN`)。 +- **HTTP mode** 需要 `botToken` 和 `signingSecret`(可在根级或每账号级配置)。 +- `botToken`、`appToken`、`signingSecret` 和 `userToken` 接受明文字符串 + 或 SecretRef 对象。 +- Slack 账号快照会暴露每项凭证的来源/状态字段,例如 + `botTokenSource`、`botTokenStatus`、`appTokenStatus`,以及在 HTTP 模式下的 + `signingSecretStatus`。`configured_unavailable` 表示该账号通过 SecretRef + 配置,但当前命令/运行时路径无法解析该密钥值。 +- `configWrites: false` 会阻止由 Slack 发起的配置写入。 - 可选的 `channels.slack.defaultAccount` 会在其匹配某个已配置账号 ID 时覆盖默认账号选择。 -- `channels.slack.streaming` 是规范的流模式键。旧版 `streamMode` 和布尔型 `streaming` 值会自动迁移。 -- 发送目标使用 `user:`(私信)或 `channel:`(渠道)。 +- `channels.slack.streaming` 是规范的流式模式键。旧版 `streamMode` 和布尔型 `streaming` 值会被自动迁移。 +- 使用 `user:`(私信)或 `channel:` 作为投递目标。 **反应通知模式:** `off`、`own`(默认)、`all`、`allowlist`(来自 `reactionAllowlist`)。 -**线程会话隔离:** `thread.historyScope` 可为每线程(默认)或整渠道共享。`thread.inheritParent` 会将父渠道转录复制到新线程。 +**线程会话隔离:** `thread.historyScope` 为每线程(默认)或跨频道共享。`thread.inheritParent` 会将父频道转录复制到新线程。 -- `typingReaction` 会在回复运行期间为入站 Slack 消息添加临时 reaction,并在完成时移除。请使用 Slack emoji shortcode,例如 `"hourglass_flowing_sand"`。 -- `channels.slack.execApprovals`:Slack 原生 exec 审批投递和审批者授权。与 Discord 使用相同 schema:`enabled`(`true`/`false`/`"auto"`)、`approvers`(Slack 用户 ID)、`agentFilter`、`sessionFilter` 和 `target`(`"dm"`、`"channel"` 或 `"both"`)。 +- `typingReaction` 会在回复进行期间给传入的 Slack 消息添加一个临时反应,并在完成后移除。使用 Slack emoji 简码,例如 `"hourglass_flowing_sand"`。 +- `channels.slack.execApprovals`:Slack 原生 exec 审批投递与审批人授权。与 Discord 使用相同 schema:`enabled`(`true`/`false`/`"auto"`)、`approvers`(Slack 用户 ID)、`agentFilter`、`sessionFilter` 和 `target`(`"dm"`、`"channel"` 或 `"both"`)。 -| 操作组 | 默认值 | 说明 | -| ------------ | ------- | -------------------- | -| reactions | 启用 | 添加 reaction + 列出 reactions | -| messages | 启用 | 读取 / 发送 / 编辑 / 删除 | -| pins | 启用 | 固定 / 取消固定 / 列出 | -| memberInfo | 启用 | 成员信息 | -| emojiList | 启用 | 自定义 emoji 列表 | +| 动作组 | 默认值 | 说明 | +| ------------ | -------- | -------------------- | +| reactions | 已启用 | 添加反应 + 列出反应 | +| messages | 已启用 | 读取/发送/编辑/删除 | +| pins | 已启用 | 置顶/取消置顶/列出 | +| memberInfo | 已启用 | 成员信息 | +| emojiList | 已启用 | 自定义 emoji 列表 | ### Mattermost -Mattermost 以插件形式提供:`openclaw plugins install @openclaw/mattermost`。 +Mattermost 作为插件提供:`openclaw plugins install @openclaw/mattermost`。 ```json5 { @@ -494,7 +498,7 @@ Mattermost 以插件形式提供:`openclaw plugins install @openclaw/mattermos native: true, // 显式启用 nativeSkills: true, callbackPath: "/api/channels/mattermost/command", - // 面向反向代理 / 公网部署的可选显式 URL + // 反向代理/公网部署时可选的显式 URL callbackUrl: "https://gateway.example.com/api/channels/mattermost/command", }, textChunkLimit: 4000, @@ -508,17 +512,16 @@ Mattermost 以插件形式提供:`openclaw plugins install @openclaw/mattermos 启用 Mattermost 原生命令时: -- `commands.callbackPath` 必须是路径(例如 `/api/channels/mattermost/command`),不能是完整 URL。 -- `commands.callbackUrl` 必须解析到 OpenClaw Gateway 网关端点,并且 Mattermost 服务器可访问。 -- 原生 slash 回调使用 Mattermost 在注册 slash 命令期间返回的每命令 token 进行身份验证。如果注册失败,或没有激活任何命令,OpenClaw 会以 - `Unauthorized: invalid command token.` - 拒绝回调。 -- 对于私有 / tailnet / 内部回调主机,Mattermost 可能要求 - `ServiceSettings.AllowedUntrustedInternalConnections` 包含回调主机 / 域名。 - 请使用主机 / 域名值,而不是完整 URL。 -- `channels.mattermost.configWrites`:允许或拒绝 Mattermost 发起的配置写入。 -- `channels.mattermost.requireMention`:在渠道中回复前要求 `@mention`。 -- `channels.mattermost.groups..requireMention`:每渠道提及门控覆盖(默认值使用 `"*"`)。 +- `commands.callbackPath` 必须是一个路径(例如 `/api/channels/mattermost/command`),不能是完整 URL。 +- `commands.callbackUrl` 必须解析到 OpenClaw Gateway 网关端点,并且 Mattermost 服务器必须能访问到。 +- 原生斜杠命令回调使用 Mattermost 在斜杠命令注册期间返回的每命令 token 进行认证。如果注册失败或没有激活任何命令,OpenClaw 会拒绝回调,并返回 + `Unauthorized: invalid command token.`。 +- 对于私有/tailnet/内部回调主机,Mattermost 可能要求 + `ServiceSettings.AllowedUntrustedInternalConnections` 包含该回调主机/域名。 + 请使用主机/域名值,而不是完整 URL。 +- `channels.mattermost.configWrites`:允许或拒绝由 Mattermost 发起的配置写入。 +- `channels.mattermost.requireMention`:要求在频道中必须先 `@mention` 才会回复。 +- `channels.mattermost.groups..requireMention`:每频道提及门控覆盖(`"*"` 表示默认值)。 - 可选的 `channels.mattermost.defaultAccount` 会在其匹配某个已配置账号 ID 时覆盖默认账号选择。 ### Signal @@ -528,7 +531,7 @@ Mattermost 以插件形式提供:`openclaw plugins install @openclaw/mattermos channels: { signal: { enabled: true, - account: "+15555550123", // 可选的账号绑定 + account: "+15555550123", // 可选账号绑定 dmPolicy: "pairing", allowFrom: ["+15551234567", "uuid:123e4567-e89b-12d3-a456-426614174000"], configWrites: true, @@ -542,13 +545,13 @@ Mattermost 以插件形式提供:`openclaw plugins install @openclaw/mattermos **反应通知模式:** `off`、`own`(默认)、`all`、`allowlist`(来自 `reactionAllowlist`)。 -- `channels.signal.account`:将渠道启动固定到特定 Signal 账号身份。 -- `channels.signal.configWrites`:允许或拒绝 Signal 发起的配置写入。 +- `channels.signal.account`:将渠道启动固定到特定的 Signal 账号身份。 +- `channels.signal.configWrites`:允许或拒绝由 Signal 发起的配置写入。 - 可选的 `channels.signal.defaultAccount` 会在其匹配某个已配置账号 ID 时覆盖默认账号选择。 ### BlueBubbles -BlueBubbles 是推荐的 iMessage 路径(插件支持,配置位于 `channels.bluebubbles` 下)。 +BlueBubbles 是推荐的 iMessage 路径(由插件支持,配置位于 `channels.bluebubbles`)。 ```json5 { @@ -556,21 +559,21 @@ BlueBubbles 是推荐的 iMessage 路径(插件支持,配置位于 `channels bluebubbles: { enabled: true, dmPolicy: "pairing", - // serverUrl、password、webhookPath、群组控制和高级 actions: + // serverUrl、password、webhookPath、群组控制和高级动作: // 参见 /channels/bluebubbles }, }, } ``` -- 此处覆盖的核心键路径:`channels.bluebubbles`、`channels.bluebubbles.dmPolicy`。 +- 此处涵盖的核心键路径:`channels.bluebubbles`、`channels.bluebubbles.dmPolicy`。 - 可选的 `channels.bluebubbles.defaultAccount` 会在其匹配某个已配置账号 ID 时覆盖默认账号选择。 -- 顶层 `bindings[]` 中 `type: "acp"` 的条目可将 BlueBubbles 对话绑定到持久 ACP 会话。请在 `match.peer.id` 中使用 BlueBubbles handle 或 target 字符串(`chat_id:*`、`chat_guid:*`、`chat_identifier:*`)。共享字段语义: [ACP Agents](/zh-CN/tools/acp-agents#channel-specific-settings)。 -- 完整的 BlueBubbles 渠道配置文档位于 [BlueBubbles](/zh-CN/channels/bluebubbles)。 +- 顶层 `bindings[]` 中带有 `type: "acp"` 的条目可将 BlueBubbles 对话绑定到持久 ACP 会话。在 `match.peer.id` 中使用 BlueBubbles handle 或目标字符串(`chat_id:*`、`chat_guid:*`、`chat_identifier:*`)。共享字段语义: [ACP Agents](/zh-CN/tools/acp-agents#channel-specific-settings)。 +- 完整的 BlueBubbles 渠道配置见 [BlueBubbles](/zh-CN/channels/bluebubbles)。 ### iMessage -OpenClaw 会生成 `imsg rpc`(通过 stdio 的 JSON-RPC)。无需守护进程或端口。 +OpenClaw 会生成 `imsg rpc`(基于 stdio 的 JSON-RPC)。不需要守护进程或端口。 ```json5 { @@ -596,15 +599,15 @@ OpenClaw 会生成 `imsg rpc`(通过 stdio 的 JSON-RPC)。无需守护进 - 可选的 `channels.imessage.defaultAccount` 会在其匹配某个已配置账号 ID 时覆盖默认账号选择。 -- 需要对 Messages DB 的 Full Disk Access。 +- 需要对 Messages 数据库具有“完全磁盘访问权限”。 - 优先使用 `chat_id:` 目标。使用 `imsg chats --limit 20` 列出聊天。 -- `cliPath` 可以指向 SSH wrapper;设置 `remoteHost`(`host` 或 `user@host`)用于通过 SCP 获取附件。 -- `attachmentRoots` 和 `remoteAttachmentRoots` 会限制入站附件路径(默认:`/Users/*/Library/Messages/Attachments`)。 +- `cliPath` 可以指向 SSH 包装器;设置 `remoteHost`(`host` 或 `user@host`)以通过 SCP 获取附件。 +- `attachmentRoots` 和 `remoteAttachmentRoots` 会限制传入附件路径(默认:`/Users/*/Library/Messages/Attachments`)。 - SCP 使用严格主机密钥检查,因此请确保中继主机密钥已存在于 `~/.ssh/known_hosts` 中。 -- `channels.imessage.configWrites`:允许或拒绝 iMessage 发起的配置写入。 -- 顶层 `bindings[]` 中 `type: "acp"` 的条目可将 iMessage 对话绑定到持久 ACP 会话。请在 `match.peer.id` 中使用规范化 handle 或显式聊天目标(`chat_id:*`、`chat_guid:*`、`chat_identifier:*`)。共享字段语义: [ACP Agents](/zh-CN/tools/acp-agents#channel-specific-settings)。 +- `channels.imessage.configWrites`:允许或拒绝由 iMessage 发起的配置写入。 +- 顶层 `bindings[]` 中带有 `type: "acp"` 的条目可将 iMessage 对话绑定到持久 ACP 会话。在 `match.peer.id` 中使用规范化 handle 或显式聊天目标(`chat_id:*`、`chat_guid:*`、`chat_identifier:*`)。共享字段语义: [ACP Agents](/zh-CN/tools/acp-agents#channel-specific-settings)。 - + ```bash #!/usr/bin/env bash @@ -615,7 +618,7 @@ exec ssh -T gateway-host imsg "$@" ### Matrix -Matrix 由扩展支持,配置位于 `channels.matrix` 下。 +Matrix 由扩展支持,配置位于 `channels.matrix`。 ```json5 { @@ -645,23 +648,23 @@ Matrix 由扩展支持,配置位于 `channels.matrix` 下。 } ``` -- Token 身份验证使用 `accessToken`;密码身份验证使用 `userId` + `password`。 -- `channels.matrix.proxy` 会将 Matrix HTTP 流量路由到显式 HTTP(S) 代理。命名账号可用 `channels.matrix.accounts..proxy` 覆盖。 -- `channels.matrix.allowPrivateNetwork` 允许私有 / 内部 homeserver。`proxy` 和 `allowPrivateNetwork` 是相互独立的控制项。 -- `channels.matrix.defaultAccount` 在多账号配置中选择首选账号。 -- `channels.matrix.execApprovals`:Matrix 原生 exec 审批投递和审批者授权。 - - `enabled`:`true`、`false` 或 `"auto"`(默认)。在 auto 模式下,当能从 `approvers` 或 `commands.ownerAllowFrom` 解析出审批者时,会激活 exec 审批。 +- Token 认证使用 `accessToken`;密码认证使用 `userId` + `password`。 +- `channels.matrix.proxy` 会将 Matrix HTTP 流量路由到显式 HTTP(S) 代理。命名账号可通过 `channels.matrix.accounts..proxy` 覆盖。 +- `channels.matrix.allowPrivateNetwork` 允许私有/内部 homeserver。`proxy` 和 `allowPrivateNetwork` 是相互独立的控制项。 +- `channels.matrix.defaultAccount` 在多账号设置中选择首选账号。 +- `channels.matrix.execApprovals`:Matrix 原生 exec 审批投递与审批人授权。 + - `enabled`:`true`、`false` 或 `"auto"`(默认)。在自动模式下,当可以从 `approvers` 或 `commands.ownerAllowFrom` 解析出审批人时,exec 审批会激活。 - `approvers`:允许批准 exec 请求的 Matrix 用户 ID(例如 `@owner:example.org`)。 - `agentFilter`:可选的智能体 ID 允许列表。省略则转发所有智能体的审批请求。 - `sessionFilter`:可选的会话键模式(子串或正则)。 - - `target`:审批提示发送位置。`"dm"`(默认)、`"channel"`(原始房间)或 `"both"`。 + - `target`:发送审批提示的位置。`"dm"`(默认)、`"channel"`(原始房间)或 `"both"`。 - 每账号覆盖:`channels.matrix.accounts..execApprovals`。 - Matrix 状态探测和实时目录查找使用与运行时流量相同的代理策略。 -- 完整的 Matrix 配置、目标规则和设置示例文档位于 [Matrix](/zh-CN/channels/matrix)。 +- 完整的 Matrix 配置、目标规则和设置示例见 [Matrix](/zh-CN/channels/matrix)。 ### Microsoft Teams -Microsoft Teams 由扩展支持,配置位于 `channels.msteams` 下。 +Microsoft Teams 由扩展支持,配置位于 `channels.msteams`。 ```json5 { @@ -669,19 +672,19 @@ Microsoft Teams 由扩展支持,配置位于 `channels.msteams` 下。 msteams: { enabled: true, configWrites: true, - // appId、appPassword、tenantId、webhook、团队 / 渠道策略: + // appId、appPassword、tenantId、webhook、团队/频道策略: // 参见 /channels/msteams }, }, } ``` -- 此处覆盖的核心键路径:`channels.msteams`、`channels.msteams.configWrites`。 -- 完整的 Teams 配置(凭证、webhook、私信 / 群组策略、每团队 / 每渠道覆盖)文档位于 [Microsoft Teams](/zh-CN/channels/msteams)。 +- 此处涵盖的核心键路径:`channels.msteams`、`channels.msteams.configWrites`。 +- 完整的 Teams 配置(凭证、webhook、私信/群组策略、每团队/每频道覆盖)见 [Microsoft Teams](/zh-CN/channels/msteams)。 ### IRC -IRC 由扩展支持,配置位于 `channels.irc` 下。 +IRC 由扩展支持,配置位于 `channels.irc`。 ```json5 { @@ -702,13 +705,13 @@ IRC 由扩展支持,配置位于 `channels.irc` 下。 } ``` -- 此处覆盖的核心键路径:`channels.irc`、`channels.irc.dmPolicy`、`channels.irc.configWrites`、`channels.irc.nickserv.*`。 +- 此处涵盖的核心键路径:`channels.irc`、`channels.irc.dmPolicy`、`channels.irc.configWrites`、`channels.irc.nickserv.*`。 - 可选的 `channels.irc.defaultAccount` 会在其匹配某个已配置账号 ID 时覆盖默认账号选择。 -- 完整的 IRC 渠道配置(host / port / TLS / 渠道 / allowlist / 提及门控)文档位于 [IRC](/zh-CN/channels/irc)。 +- 完整的 IRC 渠道配置(主机/端口/TLS/频道/允许列表/提及门控)见 [IRC](/zh-CN/channels/irc)。 ### 多账号(所有渠道) -每个渠道运行多个账号(每个都有自己的 `accountId`): +为每个渠道运行多个账号(每个账号都有自己的 `accountId`): ```json5 { @@ -716,11 +719,11 @@ IRC 由扩展支持,配置位于 `channels.irc` 下。 telegram: { accounts: { default: { - name: "主 Bot", + name: "Primary bot", botToken: "123456:ABC...", }, alerts: { - name: "告警 Bot", + name: "Alerts bot", botToken: "987654:XYZ...", }, }, @@ -729,18 +732,18 @@ IRC 由扩展支持,配置位于 `channels.irc` 下。 } ``` -- 当省略 `accountId` 时使用 `default`(CLI + 路由)。 -- 环境变量 token 仅适用于 **default** 账号。 -- 基础渠道设置适用于所有账号,除非在每账号级别覆盖。 +- 当省略 `accountId` 时,使用 `default`(CLI + 路由)。 +- 环境变量 token 仅适用于**默认**账号。 +- 基础渠道设置适用于所有账号,除非在账号级被覆盖。 - 使用 `bindings[].match.accountId` 将每个账号路由到不同智能体。 -- 如果你在仍处于单账号顶层渠道配置的情况下,通过 `openclaw channels add`(或渠道新手引导)添加非默认账号,OpenClaw 会先将带有账号作用域的顶层单账号值提升到渠道账号映射中,以保持原始账号继续工作。大多数渠道会将它们移到 `channels..accounts.default`;Matrix 则可以保留现有的匹配命名 / 默认目标。 -- 现有仅渠道级绑定(无 `accountId`)将继续匹配默认账号;账号作用域绑定仍是可选的。 -- `openclaw doctor --fix` 也会修复混合形状,将带账号作用域的顶层单账号值移动到该渠道选择的提升账号下。大多数渠道使用 `accounts.default`;Matrix 可保留现有匹配的命名 / 默认目标。 +- 如果你通过 `openclaw channels add`(或渠道新手引导)添加非默认账号,而当前仍使用单账号顶层渠道配置,OpenClaw 会先将账号范围的顶层单账号值提升到该渠道的账号映射中,这样原账号仍可继续工作。大多数渠道会将它们移入 `channels..accounts.default`;Matrix 则可保留现有匹配的命名/默认目标。 +- 现有仅渠道级绑定(无 `accountId`)将继续匹配默认账号;账号范围绑定仍是可选的。 +- `openclaw doctor --fix` 也会通过将账号范围的顶层单账号值移入该渠道所选择的提升账号,来修复混合结构。大多数渠道使用 `accounts.default`;Matrix 可保留现有匹配的命名/默认目标。 ### 其他扩展渠道 -许多扩展渠道都配置为 `channels.`,并在各自的专属渠道页面中有文档说明(例如 Feishu、Matrix、LINE、Nostr、Zalo、Nextcloud Talk、Synology Chat 和 Twitch)。 -参见完整渠道索引:[Channels](/zh-CN/channels)。 +许多扩展渠道以 `channels.` 配置,并记录在各自专属的渠道页面中(例如 Feishu、Matrix、LINE、Nostr、Zalo、Nextcloud Talk、Synology Chat 和 Twitch)。 +请参见完整渠道索引:[Channels](/zh-CN/channels)。 ### 群聊提及门控 @@ -748,9 +751,9 @@ IRC 由扩展支持,配置位于 `channels.irc` 下。 **提及类型:** -- **元数据提及**:原生平台 @ 提及。在 WhatsApp self-chat 模式下会被忽略。 +- **元数据提及**:平台原生 @ 提及。在 WhatsApp 自聊模式下会被忽略。 - **文本模式**:位于 `agents.list[].groupChat.mentionPatterns` 中的安全正则模式。无效模式和不安全的嵌套重复会被忽略。 -- 仅在可检测到提及的情况下(原生提及或至少一个模式)才会强制执行提及门控。 +- 仅当可检测到提及(原生提及或至少一个模式)时,才会强制执行提及门控。 ```json5 { @@ -763,9 +766,9 @@ IRC 由扩展支持,配置位于 `channels.irc` 下。 } ``` -`messages.groupChat.historyLimit` 设置全局默认值。渠道可通过 `channels..historyLimit`(或每账号配置)覆盖。设为 `0` 可禁用。 +`messages.groupChat.historyLimit` 设置全局默认值。渠道可通过 `channels..historyLimit`(或每账号级)覆盖。设置为 `0` 可禁用。 -#### 私信历史上限 +#### 私信历史限制 ```json5 { @@ -780,13 +783,13 @@ IRC 由扩展支持,配置位于 `channels.irc` 下。 } ``` -解析顺序:每私信覆盖 → 提供商默认值 → 不限(全部保留)。 +解析顺序:每私信覆盖 → 提供商默认值 → 不限制(全部保留)。 支持:`telegram`、`whatsapp`、`discord`、`slack`、`signal`、`imessage`、`msteams`。 -#### Self-chat 模式 +#### 自聊模式 -将你自己的号码包含在 `allowFrom` 中可启用 self-chat 模式(忽略原生 @ 提及,仅响应文本模式): +将你自己的号码加入 `allowFrom` 以启用自聊模式(忽略原生 @ 提及,仅响应文本模式): ```json5 { @@ -812,8 +815,8 @@ IRC 由扩展支持,配置位于 `channels.irc` 下。 ```json5 { commands: { - native: "auto", // 在支持时注册原生命令 - text: true, // 解析聊天消息中的 /commands + native: "auto", // 在支持的平台上注册原生命令 + text: true, // 在聊天消息中解析 /commands bash: false, // 允许 !(别名:/bash) bashForegroundMs: 2000, config: false, // 允许 /config @@ -830,16 +833,16 @@ IRC 由扩展支持,配置位于 `channels.irc` 下。 -- 文本命令必须是带前导 `/` 的**独立**消息。 -- `native: "auto"` 会为 Discord / Telegram 打开原生命令,而保持 Slack 关闭。 -- 每渠道覆盖:`channels.discord.commands.native`(布尔值或 `"auto"`)。`false` 会清除先前注册的命令。 +- 文本命令必须是带有前导 `/` 的**独立**消息。 +- `native: "auto"` 会开启 Discord/Telegram 的原生命令,而保持 Slack 关闭。 +- 每渠道覆盖:`channels.discord.commands.native`(布尔值或 `"auto"`)。`false` 会清除先前已注册命令。 - `channels.telegram.customCommands` 会添加额外的 Telegram 机器人菜单项。 -- `bash: true` 会为主机 shell 启用 `! `。要求 `tools.elevated.enabled`,且发送者位于 `tools.elevated.allowFrom.` 中。 -- `config: true` 会启用 `/config`(读取 / 写入 `openclaw.json`)。对于 Gateway 网关 `chat.send` 客户端,持久化 `/config set|unset` 写入还需要 `operator.admin`;只读的 `/config show` 对普通具写权限的 operator 客户端仍可用。 -- `channels..configWrites` 会按渠道控制配置变更(默认:true)。 -- 对于多账号渠道,`channels..accounts..configWrites` 也会控制针对该账号的写入(例如 `/allowlist --config --account ` 或 `/config set channels..accounts....`)。 -- `allowFrom` 是按提供商生效的。设置后,它将成为**唯一**授权来源(渠道 allowlist / pairing 和 `useAccessGroups` 将被忽略)。 -- `useAccessGroups: false` 允许在未设置 `allowFrom` 时绕过 access-group 策略来执行命令。 +- `bash: true` 启用主机 shell 的 `! `。要求 `tools.elevated.enabled` 且发送者位于 `tools.elevated.allowFrom.` 中。 +- `config: true` 启用 `/config`(读取/写入 `openclaw.json`)。对于 gateway `chat.send` 客户端,持久的 `/config set|unset` 写入还需要 `operator.admin`;只读的 `/config show` 对普通具备写权限的 operator 客户端仍然可用。 +- `channels..configWrites` 按渠道控制配置变更(默认:true)。 +- 对于多账号渠道,`channels..accounts..configWrites` 也控制面向该账号的写入(例如 `/allowlist --config --account ` 或 `/config set channels..accounts....`)。 +- `allowFrom` 是按提供商划分的。设置后,它会成为**唯一**授权来源(渠道允许列表/配对和 `useAccessGroups` 都会被忽略)。 +- `useAccessGroups: false` 会在未设置 `allowFrom` 时允许命令绕过访问组策略。 @@ -859,7 +862,7 @@ IRC 由扩展支持,配置位于 `channels.irc` 下。 ### `agents.defaults.repoRoot` -可选仓库根目录,会显示在系统提示词的 Runtime 行中。若未设置,OpenClaw 会从工作区向上遍历自动检测。 +可选的仓库根目录,会显示在系统提示的 Runtime 行中。若未设置,OpenClaw 会从 workspace 向上遍历自动检测。 ```json5 { @@ -869,7 +872,7 @@ IRC 由扩展支持,配置位于 `channels.irc` 下。 ### `agents.defaults.skills` -为未设置 `agents.list[].skills` 的智能体提供的可选默认 skill 允许列表。 +为未设置 `agents.list[].skills` 的智能体提供可选的默认 Skills 允许列表。 ```json5 { @@ -885,13 +888,14 @@ IRC 由扩展支持,配置位于 `channels.irc` 下。 ``` - 省略 `agents.defaults.skills` 表示默认不限制 Skills。 -- 省略 `agents.list[].skills` 表示继承默认值。 -- 设置 `agents.list[].skills: []` 表示无 Skills。 -- 非空的 `agents.list[].skills` 列表会成为该智能体的最终集合;不会与默认值合并。 +- 省略 `agents.list[].skills` 会继承默认值。 +- 设置 `agents.list[].skills: []` 表示没有 Skills。 +- 非空的 `agents.list[].skills` 列表是该智能体的最终集合; + 不会与默认值合并。 ### `agents.defaults.skipBootstrap` -禁用工作区引导文件(`AGENTS.md`、`SOUL.md`、`TOOLS.md`、`IDENTITY.md`、`USER.md`、`HEARTBEAT.md`、`BOOTSTRAP.md`)的自动创建。 +禁用自动创建 workspace 引导文件(`AGENTS.md`、`SOUL.md`、`TOOLS.md`、`IDENTITY.md`、`USER.md`、`HEARTBEAT.md`、`BOOTSTRAP.md`)。 ```json5 { @@ -901,7 +905,7 @@ IRC 由扩展支持,配置位于 `channels.irc` 下。 ### `agents.defaults.bootstrapMaxChars` -每个工作区引导文件在截断前允许的最大字符数。默认值:`20000`。 +每个 workspace 引导文件在截断前的最大字符数。默认值:`20000`。 ```json5 { @@ -911,7 +915,7 @@ IRC 由扩展支持,配置位于 `channels.irc` 下。 ### `agents.defaults.bootstrapTotalMaxChars` -所有工作区引导文件跨文件注入的总字符上限。默认值:`150000`。 +所有 workspace 引导文件注入内容的总最大字符数。默认值:`150000`。 ```json5 { @@ -921,12 +925,12 @@ IRC 由扩展支持,配置位于 `channels.irc` 下。 ### `agents.defaults.bootstrapPromptTruncationWarning` -控制在引导上下文被截断时,是否向智能体显示警告文本。 +控制当引导上下文被截断时,对智能体可见的警告文本。 默认值:`"once"`。 -- `"off"`:绝不将警告文本注入系统提示词。 -- `"once"`:对每个唯一的截断签名仅注入一次警告(推荐)。 -- `"always"`:每次运行只要存在截断就注入警告。 +- `"off"`:绝不将警告文本注入系统提示。 +- `"once"`:每个唯一的截断签名仅注入一次警告(推荐)。 +- `"always"`:只要存在截断,每次运行都注入警告。 ```json5 { @@ -936,10 +940,10 @@ IRC 由扩展支持,配置位于 `channels.irc` 下。 ### `agents.defaults.imageMaxDimensionPx` -在调用提供商之前,转录 / 工具图像块中图像最长边的最大像素尺寸。 +在调用提供商之前,转录/工具图像块中最长边允许的最大像素尺寸。 默认值:`1200`。 -较低值通常会减少 vision token 用量和截图密集型运行的请求负载大小。 +较低值通常会减少视觉 token 用量和截图密集型运行的请求负载大小。 较高值可保留更多视觉细节。 ```json5 @@ -950,7 +954,7 @@ IRC 由扩展支持,配置位于 `channels.irc` 下。 ### `agents.defaults.userTimezone` -用于系统提示词上下文的时区(不是消息时间戳)。回退到主机时区。 +系统提示上下文使用的时区(不影响消息时间戳)。默认回退到主机时区。 ```json5 { @@ -960,7 +964,7 @@ IRC 由扩展支持,配置位于 `channels.irc` 下。 ### `agents.defaults.timeFormat` -系统提示词中的时间格式。默认值:`auto`(操作系统偏好)。 +系统提示中的时间格式。默认值:`auto`(操作系统偏好)。 ```json5 { @@ -1013,36 +1017,36 @@ IRC 由扩展支持,配置位于 `channels.irc` 下。 } ``` -- `model`:接受字符串(`"provider/model"`)或对象(`{ primary, fallbacks }`)。 +- `model`:既可接受字符串(`"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-1`(OpenAI Images)。 - - 如果你直接选择某个 provider/model,也要配置对应的提供商认证 / API key(例如 `google/*` 对应 `GEMINI_API_KEY` 或 `GOOGLE_API_KEY`,`openai/*` 对应 `OPENAI_API_KEY`,`fal/*` 对应 `FAL_KEY`)。 - - 若省略,`image_generate` 仍可推断带认证的提供商默认值。它会先尝试当前默认提供商,然后按提供商 ID 顺序尝试其余已注册的图像生成提供商。 -- `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 顺序尝试其余已注册的视频生成提供商。 - - 如果你直接选择某个 provider/model,也要配置对应的提供商认证 / API key。 - - 内置的 Qwen 视频生成提供商当前最多支持 1 个输出视频、1 张输入图片、4 个输入视频、10 秒时长,以及提供商级别的 `size`、`aspectRatio`、`resolution`、`audio` 和 `watermark` 选项。 -- `pdfModel`:接受字符串(`"provider/model"`)或对象(`{ primary, fallbacks }`)。 - - 用于 `pdf` 工具的模型路由。 - - 若省略,PDF 工具会回退到 `imageModel`,再回退到已解析的会话 / 默认模型。 -- `pdfMaxBytesMb`:当调用时未传入 `maxBytesMb` 时,`pdf` 工具的默认 PDF 大小上限。 -- `pdfMaxPages`:`pdf` 工具中提取回退模式所考虑的默认最大页数。 -- `verboseDefault`:智能体的默认 verbose 级别。取值:`"off"`、`"on"`、`"full"`。默认值:`"off"`。 -- `elevatedDefault`:智能体的默认 elevated-output 级别。取值:`"off"`、`"on"`、`"ask"`、`"full"`。默认值:`"on"`。 -- `model.primary`:格式为 `provider/model`(例如 `openai/gpt-5.4`)。若省略 provider,OpenClaw 会先尝试别名,然后尝试对该精确模型 ID 的唯一已配置提供商匹配,最后才回退到已配置的默认提供商(这是已弃用的兼容行为,因此请优先使用显式 `provider/model`)。如果该提供商不再暴露已配置的默认模型,OpenClaw 会回退到首个已配置的 provider/model,而不是暴露已陈旧的已移除提供商默认值。 -- `models`:为 `/model` 配置的模型目录和允许列表。每个条目可包含 `alias`(快捷方式)和 `params`(提供商特定参数,例如 `temperature`、`maxTokens`、`cacheRetention`、`context1m`)。 -- `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)。 -- 修改这些字段的配置写入器(例如 `/models set`、`/models set-image` 以及 fallback add/remove 命令)会保存规范对象形式,并尽可能保留现有 fallback 列表。 -- `maxConcurrent`:会话间并行智能体运行的最大值(每个会话仍保持串行)。默认值:4。 + - 对象形式可设置主模型以及有序故障切换模型。 +- `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-1`(OpenAI Images)。 + - 如果你直接选择某个提供商/模型,也要配置匹配的提供商认证/API key(例如 `google/*` 使用 `GEMINI_API_KEY` 或 `GOOGLE_API_KEY`,`openai/*` 使用 `OPENAI_API_KEY`,`fal/*` 使用 `FAL_KEY`)。 + - 若省略,`image_generate` 仍可推断基于认证的提供商默认值。它会先尝试当前默认提供商,再按提供商 ID 顺序尝试剩余已注册的图像生成提供商。 +- `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 key。 + - 内置的 Qwen 视频生成提供商目前最多支持 1 个输出视频、1 张输入图片、4 个输入视频、10 秒时长,以及提供商级 `size`、`aspectRatio`、`resolution`、`audio` 和 `watermark` 选项。 +- `pdfModel`:既可接受字符串(`"provider/model"`),也可接受对象(`{ primary, fallbacks }`)。 + - 被 `pdf` 工具用于模型路由。 + - 若省略,PDF 工具会回退到 `imageModel`,再回退到已解析的会话/默认模型。 +- `pdfMaxBytesMb`:当调用时未传入 `maxBytesMb` 时,`pdf` 工具的默认 PDF 大小限制。 +- `pdfMaxPages`:`pdf` 工具在提取回退模式下考虑的默认最大页数。 +- `verboseDefault`:智能体的默认详细级别。取值:`"off"`、`"on"`、`"full"`。默认值:`"off"`。 +- `elevatedDefault`:智能体的默认 elevated 输出级别。取值:`"off"`、`"on"`、`"ask"`、`"full"`。默认值:`"on"`。 +- `model.primary`:格式为 `provider/model`(例如 `openai/gpt-5.4`)。如果省略提供商,OpenClaw 会先尝试别名,然后尝试精确模型 ID 的唯一已配置提供商匹配,最后才回退到已配置的默认提供商(这是已弃用的兼容行为,因此建议优先使用显式 `provider/model`)。如果该提供商不再暴露已配置的默认模型,OpenClaw 会回退到首个已配置的提供商/模型,而不是继续使用陈旧、已移除提供商的默认值。 +- `models`:已配置的模型目录以及 `/model` 的允许列表。每个条目都可以包含 `alias`(快捷方式)和 `params`(提供商特定参数,例如 `temperature`、`maxTokens`、`cacheRetention`、`context1m`)。 +- `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)。 +- 会修改这些字段的配置写入器(例如 `/models set`、`/models set-image` 以及回退模型添加/移除命令)会保存为规范对象形式,并在可能时保留现有回退列表。 +- `maxConcurrent`:跨会话并行运行的最大智能体数量(每个会话内部仍然串行)。默认值:4。 **内置别名简写**(仅当模型位于 `agents.defaults.models` 中时适用): @@ -1057,43 +1061,12 @@ IRC 由扩展支持,配置位于 `channels.irc` 下。 | `gemini-flash` | `google/gemini-3-flash-preview` | | `gemini-flash-lite` | `google/gemini-3.1-flash-lite-preview` | -你自定义的别名始终优先于默认值。 +你自己配置的别名始终优先于默认值。 -Z.AI GLM-4.x 模型会自动启用 thinking mode,除非你设置 `--thinking off` 或自行定义 `agents.defaults.models["zai/"].params.thinking`。 -Z.AI 模型默认启用 `tool_stream` 以进行工具调用流式传输。将 `agents.defaults.models["zai/"].params.tool_stream` 设为 `false` 可关闭。 -当未设置显式 thinking level 时,Anthropic Claude 4.6 模型默认使用 `adaptive` thinking。 +Z.AI GLM-4.x 模型会自动启用 thinking 模式,除非你设置 `--thinking off` 或自行定义 `agents.defaults.models["zai/"].params.thinking`。 +Z.AI 模型默认启用 `tool_stream` 以进行工具调用流式传输。将 `agents.defaults.models["zai/"].params.tool_stream` 设为 `false` 可禁用。 +Anthropic Claude 4.6 模型在未设置显式 thinking 级别时,默认使用 `adaptive` thinking。 -### `agents.defaults.cliBackends` - -用于纯文本回退运行(无工具调用)的可选 CLI 后端。当 API 提供商失败时,它可作为备份。 - -```json5 -{ - agents: { - defaults: { - cliBackends: { - "codex-cli": { - command: "/opt/homebrew/bin/codex", - }, - "my-cli": { - command: "my-cli", - args: ["--json"], - output: "json", - modelArg: "--model", - sessionArg: "--session", - sessionMode: "existing", - systemPromptArg: "--system", - systemPromptWhen: "first", - imageArg: "--image", - imageMode: "repeat", - }, - }, - }, - }, -} -``` - -- CLI 后端以文本为主;工具始终禁用。 - 当设置了 `sessionArg` 时支持会话。 - 当 `imageArg` 接受文件路径时支持图像透传。 @@ -1109,13 +1082,13 @@ Z.AI 模型默认启用 `tool_stream` 以进行工具调用流式传输。将 `a every: "30m", // 0m 表示禁用 model: "openai/gpt-5.4-mini", includeReasoning: false, - lightContext: false, // 默认:false;true 时仅保留工作区引导文件中的 HEARTBEAT.md + lightContext: false, // 默认:false;true 时仅保留 workspace 引导文件中的 HEARTBEAT.md isolatedSession: false, // 默认:false;true 时每次心跳都在全新会话中运行(无对话历史) session: "main", to: "+15555550123", directPolicy: "allow", // allow(默认)| block target: "none", // 默认:none | 可选:last | whatsapp | telegram | discord | ... - prompt: "如果存在,请读取 HEARTBEAT.md...", + prompt: "Read HEARTBEAT.md if it exists...", ackMaxChars: 300, suppressToolErrorWarnings: false, }, @@ -1126,10 +1099,10 @@ Z.AI 模型默认启用 `tool_stream` 以进行工具调用流式传输。将 `a - `every`:时长字符串(ms/s/m/h)。默认值:`30m`(API key 认证)或 `1h`(OAuth 认证)。设为 `0m` 可禁用。 - `suppressToolErrorWarnings`:为 true 时,在心跳运行期间抑制工具错误警告负载。 -- `directPolicy`:direct / 私信投递策略。`allow`(默认)允许 direct-target 投递。`block` 会抑制 direct-target 投递并输出 `reason=dm-blocked`。 -- `lightContext`:为 true 时,心跳运行使用轻量引导上下文,并且只保留工作区引导文件中的 `HEARTBEAT.md`。 -- `isolatedSession`:为 true 时,每次心跳都会在没有先前对话历史的全新会话中运行。与 cron `sessionTarget: "isolated"` 使用相同的隔离模式。可将每次心跳的 token 成本从约 100K 降低到约 2-5K。 -- 每智能体:设置 `agents.list[].heartbeat`。当任意智能体定义了 `heartbeat` 时,**只有这些智能体**会运行心跳。 +- `directPolicy`:直接/私信投递策略。`allow`(默认)允许直接目标投递。`block` 会阻止直接目标投递,并发出 `reason=dm-blocked`。 +- `lightContext`:为 true 时,心跳运行使用轻量引导上下文,并且仅保留 workspace 引导文件中的 `HEARTBEAT.md`。 +- `isolatedSession`:为 true 时,每次心跳都在没有先前对话历史的全新会话中运行。与 cron 的 `sessionTarget: "isolated"` 使用相同的隔离模式。可将每次心跳的 token 成本从约 100K 降低到约 2-5K token。 +- 每智能体:设置 `agents.list[].heartbeat`。当任一智能体定义了 `heartbeat` 时,**只有这些智能体**会运行心跳。 - 心跳会运行完整的智能体回合——更短的间隔会消耗更多 token。 ### `agents.defaults.compaction` @@ -1143,15 +1116,15 @@ Z.AI 模型默认启用 `tool_stream` 以进行工具调用流式传输。将 `a timeoutSeconds: 900, reserveTokensFloor: 24000, identifierPolicy: "strict", // strict | off | custom - identifierInstructions: "精确保留部署 ID、工单 ID 和 host:port 对。", // 当 identifierPolicy=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", // 可选,仅用于 compaction 的模型覆盖 - notifyUser: true, // compaction 开始时向用户发送简短通知(默认:false) + notifyUser: true, // compaction 开始时发送简短通知给用户(默认:false) memoryFlush: { enabled: true, softThresholdTokens: 6000, - systemPrompt: "会话即将 compact。请立即存储持久记忆。", - prompt: "将任何持久笔记写入 memory/YYYY-MM-DD.md;如果没有要存储的内容,请回复准确的静默标记 NO_REPLY。", + systemPrompt: "Session nearing compaction. Store durable memories now.", + prompt: "Write any lasting notes to memory/YYYY-MM-DD.md; reply with the exact silent token NO_REPLY if nothing to store.", }, }, }, @@ -1159,18 +1132,18 @@ Z.AI 模型默认启用 `tool_stream` 以进行工具调用流式传输。将 `a } ``` -- `mode`:`default` 或 `safeguard`(适用于长历史的分块摘要)。参见 [Compaction](/zh-CN/concepts/compaction)。 -- `timeoutSeconds`:OpenClaw 中止单次 compaction 操作前允许的最长秒数。默认值:`900`。 -- `identifierPolicy`:`strict`(默认)、`off` 或 `custom`。`strict` 会在 compaction 摘要期间预置内置的不透明标识符保留指引。 +- `mode`:`default` 或 `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 静默。 -- `memoryFlush`:在自动 compaction 之前执行静默智能体回合,以存储持久记忆。当工作区为只读时会跳过。 +- `postCompactionSections`:compaction 后重新注入的可选 AGENTS.md H2/H3 节名称。默认值为 `["Session Startup", "Red Lines"]`;设为 `[]` 可禁用重新注入。未设置或显式设置为这对默认值时,也接受旧版 `Every Session`/`Safety` 标题作为兼容回退。 +- `model`:仅用于 compaction 摘要的可选 `provider/model-id` 覆盖。当主会话应保持一个模型、而 compaction 摘要应使用另一个模型时使用;未设置时,compaction 使用会话的主模型。 +- `notifyUser`:为 `true` 时,在 compaction 开始时向用户发送简短通知(例如“正在压缩上下文...”)。默认禁用以保持 compaction 静默。 +- `memoryFlush`:自动 compaction 前执行静默智能体回合以存储持久记忆。workspace 为只读时会跳过。 ### `agents.defaults.contextPruning` -在将内容发送给 LLM 之前,从内存上下文中裁剪**旧工具结果**。**不会**修改磁盘上的会话历史。 +在发送到 LLM 之前,从内存上下文中裁剪**旧的工具结果**。**不会**修改磁盘上的会话历史。 ```json5 { @@ -1184,7 +1157,7 @@ Z.AI 模型默认启用 `tool_stream` 以进行工具调用流式传输。将 `a hardClearRatio: 0.5, minPrunableToolChars: 50000, softTrim: { maxChars: 4000, headChars: 1500, tailChars: 1500 }, - hardClear: { enabled: true, placeholder: "[已清除旧工具结果内容]" }, + hardClear: { enabled: true, placeholder: "[Old tool result content cleared]" }, tools: { deny: ["browser", "canvas"] }, }, }, @@ -1194,9 +1167,9 @@ Z.AI 模型默认启用 `tool_stream` 以进行工具调用流式传输。将 `a -- `mode: "cache-ttl"` 会启用裁剪过程。 -- `ttl` 控制在上次缓存触碰后,多久后才能再次运行裁剪。 -- 裁剪会先对超大工具结果进行软裁剪,必要时再对更旧的工具结果进行硬清除。 +- `mode: "cache-ttl"` 启用裁剪过程。 +- `ttl` 控制再次运行裁剪的最短间隔(自上次缓存触碰后计算)。 +- 裁剪会先对过大的工具结果执行软裁剪,如仍有需要,再对更旧的工具结果执行硬清除。 **软裁剪**会保留开头和结尾,并在中间插入 `...`。 @@ -1204,13 +1177,13 @@ Z.AI 模型默认启用 `tool_stream` 以进行工具调用流式传输。将 `a 说明: -- 图像块永远不会被裁剪 / 清除。 -- 比例基于字符数(近似值),而非精确 token 数。 -- 如果 assistant 消息少于 `keepLastAssistants`,则跳过裁剪。 +- 图像块永远不会被裁剪/清除。 +- 比例是基于字符的(近似),不是精确 token 数。 +- 如果 assistant 消息少于 `keepLastAssistants` 条,则跳过裁剪。 -行为细节参见 [Session Pruning](/zh-CN/concepts/session-pruning)。 +行为详情见 [Session Pruning](/zh-CN/concepts/session-pruning)。 ### 分块流式传输 @@ -1228,13 +1201,13 @@ Z.AI 模型默认启用 `tool_stream` 以进行工具调用流式传输。将 `a } ``` -- 非 Telegram 渠道需要显式 `*.blockStreaming: true` 才会启用分块回复。 -- 渠道覆盖:`channels..blockStreamingCoalesce`(及每账号变体)。Signal / Slack / Discord / Google Chat 默认 `minChars: 1500`。 -- `humanDelay`:分块回复之间的随机停顿。`natural` = 800–2500 ms。每智能体覆盖:`agents.list[].humanDelay`。 +- 非 Telegram 渠道需要显式 `*.blockStreaming: true` 才能启用分块回复。 +- 渠道覆盖:`channels..blockStreamingCoalesce`(以及每账号变体)。Signal/Slack/Discord/Google Chat 默认 `minChars: 1500`。 +- `humanDelay`:分块回复之间的随机暂停。`natural` = 800–2500ms。每智能体覆盖:`agents.list[].humanDelay`。 -行为和分块细节参见 [Streaming](/zh-CN/concepts/streaming)。 +行为和分块详情见 [Streaming](/zh-CN/concepts/streaming)。 -### 输入中指示器 +### 输入状态指示器 ```json5 { @@ -1247,7 +1220,7 @@ Z.AI 模型默认启用 `tool_stream` 以进行工具调用流式传输。将 `a } ``` -- 默认值:对私聊 / 提及使用 `instant`,对未被提及的群聊使用 `message`。 +- 默认值:私聊/被提及时为 `instant`,未提及的群聊为 `message`。 - 每会话覆盖:`session.typingMode`、`session.typingIntervalSeconds`。 参见 [Typing Indicators](/zh-CN/concepts/typing-indicators)。 @@ -1256,7 +1229,7 @@ Z.AI 模型默认启用 `tool_stream` 以进行工具调用流式传输。将 `a ### `agents.defaults.sandbox` -嵌入式智能体的可选沙箱隔离。完整指南参见 [Sandboxing](/zh-CN/gateway/sandboxing)。 +嵌入式智能体的可选沙箱隔离。完整指南见 [Sandboxing](/zh-CN/gateway/sandboxing)。 ```json5 { @@ -1359,16 +1332,16 @@ Z.AI 模型默认启用 `tool_stream` 以进行工具调用流式传输。将 `a - `ssh`:通用 SSH 远程运行时 - `openshell`:OpenShell 运行时 -选择 `backend: "openshell"` 时,运行时专属设置会移到 +选择 `backend: "openshell"` 时,运行时特定设置会移到 `plugins.entries.openshell.config`。 **SSH 后端配置:** - `target`:`user@host[:port]` 形式的 SSH 目标 - `command`:SSH 客户端命令(默认:`ssh`) -- `workspaceRoot`:用于各 scope 工作区的绝对远程根目录 -- `identityFile` / `certificateFile` / `knownHostsFile`:传递给 OpenSSH 的现有本地文件 -- `identityData` / `certificateData` / `knownHostsData`:内联内容或 SecretRef,OpenClaw 会在运行时将其物化为临时文件 +- `workspaceRoot`:用于每作用域 workspace 的绝对远程根目录 +- `identityFile` / `certificateFile` / `knownHostsFile`:传给 OpenSSH 的现有本地文件 +- `identityData` / `certificateData` / `knownHostsData`:内联内容或 SecretRef,OpenClaw 会在运行时将其实体化为临时文件 - `strictHostKeyChecking` / `updateHostKeys`:OpenSSH 主机密钥策略开关 **SSH 认证优先级:** @@ -1376,27 +1349,27 @@ Z.AI 模型默认启用 `tool_stream` 以进行工具调用流式传输。将 `a - `identityData` 优先于 `identityFile` - `certificateData` 优先于 `certificateFile` - `knownHostsData` 优先于 `knownHostsFile` -- SecretRef 支持的 `*Data` 值会在沙箱会话启动前,从当前活动的 secrets 运行时快照中解析 +- 由 SecretRef 支持的 `*Data` 值会在沙箱会话启动前,从当前活跃的 secrets 运行时快照中解析 **SSH 后端行为:** -- 在创建或重建后,会先为远程工作区执行一次初始填充 -- 然后保持远程 SSH 工作区为规范副本 +- 在创建或重建后仅为远程 workspace 执行一次初始化 +- 然后持续将远程 SSH workspace 作为规范 workspace - 通过 SSH 路由 `exec`、文件工具和媒体路径 - 不会自动将远程更改同步回主机 - 不支持沙箱浏览器容器 -**工作区访问:** +**workspace 访问:** -- `none`:在 `~/.openclaw/sandboxes` 下为各 scope 提供沙箱工作区 -- `ro`:沙箱工作区位于 `/workspace`,智能体工作区以只读方式挂载到 `/agent` -- `rw`:智能体工作区以读写方式挂载到 `/workspace` +- `none`:在 `~/.openclaw/sandboxes` 下按作用域创建沙箱 workspace +- `ro`:沙箱 workspace 位于 `/workspace`,智能体 workspace 只读挂载到 `/agent` +- `rw`:智能体 workspace 以读写方式挂载到 `/workspace` -**Scope:** +**作用域:** -- `session`:每会话一个容器 + 工作区 -- `agent`:每个智能体一个容器 + 工作区(默认) -- `shared`:共享容器和工作区(无跨会话隔离) +- `session`:每会话一个容器 + workspace +- `agent`:每智能体一个容器 + workspace(默认) +- `shared`:共享容器和 workspace(无跨会话隔离) **OpenShell 插件配置:** @@ -1413,7 +1386,7 @@ Z.AI 模型默认启用 `tool_stream` 以进行工具调用流式传输。将 `a remoteAgentWorkspaceDir: "/agent", gateway: "lab", // 可选 gatewayEndpoint: "https://lab.example", // 可选 - policy: "strict", // 可选 OpenShell policy id + policy: "strict", // 可选 OpenShell 策略 ID providers: ["openai"], // 可选 autoProviders: true, timeoutSeconds: 120, @@ -1426,30 +1399,30 @@ Z.AI 模型默认启用 `tool_stream` 以进行工具调用流式传输。将 `a **OpenShell 模式:** -- `mirror`:在 exec 前从本地填充远程,exec 后同步回来;本地工作区保持为规范副本 -- `remote`:在创建沙箱时仅填充远程一次,之后保持远程工作区为规范副本 +- `mirror`:执行前从本地同步到远程,执行后再同步回本地;本地 workspace 保持为规范副本 +- `remote`:在创建沙箱时仅进行一次远程初始化,之后远程 workspace 保持为规范副本 -在 `remote` 模式下,在 OpenClaw 之外对主机本地所做的编辑,在初始填充步骤之后不会自动同步到沙箱中。 -传输使用 SSH 连接到 OpenShell 沙箱,但插件拥有沙箱生命周期和可选的镜像同步。 +在 `remote` 模式下,于 OpenClaw 外部在主机本地做出的修改,在初始化之后不会自动同步到沙箱中。 +传输通过 SSH 进入 OpenShell 沙箱,但插件负责沙箱生命周期以及可选的镜像同步。 -**`setupCommand`** 在容器创建后运行一次(通过 `sh -lc`)。需要网络出口、可写根文件系统和 root 用户。 +**`setupCommand`** 会在容器创建后运行一次(通过 `sh -lc`)。需要网络出口、可写根文件系统以及 root 用户。 -**容器默认使用 `network: "none"`**——如果智能体需要出站访问,请设为 `"bridge"`(或自定义 bridge 网络)。 +**容器默认使用 `network: "none"`**——如果智能体需要出站访问,请设为 `"bridge"`(或自定义桥接网络)。 默认会阻止 `"host"`。默认也会阻止 `"container:"`,除非你显式设置 -`sandbox.docker.dangerouslyAllowContainerNamespaceJoin: true`(紧急模式)。 +`sandbox.docker.dangerouslyAllowContainerNamespaceJoin: true`(紧急放行)。 -**入站附件**会被暂存到活动工作区中的 `media/inbound/*`。 +**传入附件** 会被暂存到当前活跃 workspace 中的 `media/inbound/*`。 -**`docker.binds`** 会挂载额外的主机目录;全局和每智能体的 binds 会合并。 +**`docker.binds`** 会挂载额外的主机目录;全局和每智能体 binds 会合并。 -**沙箱浏览器**(`sandbox.browser.enabled`):容器中的 Chromium + CDP。noVNC URL 会注入系统提示词。无需在 `openclaw.json` 中启用 `browser.enabled`。 -默认使用 VNC 认证来提供 noVNC 观察者访问,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 网络)。仅当你明确需要全局 bridge 连接时才设为 `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`。 +- `cdpSourceRange` 可选地在容器边界按 CIDR 范围限制 CDP 入站(例如 `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=` - `--user-data-dir=${HOME}/.chrome` @@ -1466,15 +1439,16 @@ Z.AI 模型默认启用 `tool_stream` 以进行工具调用流式传输。将 `a - `--renderer-process-limit=2` - `--no-zygote` - `--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` 可重新启用扩展。 + - `--disable-extensions`(默认启用) + - `--disable-3d-apis`、`--disable-software-rasterizer` 和 `--disable-gpu` 默认启用,如需 WebGL/3D,可通过 + `OPENCLAW_BROWSER_DISABLE_GRAPHICS_FLAGS=0` 禁用。 + - 若你的工作流依赖扩展,可通过 + `OPENCLAW_BROWSER_DISABLE_EXTENSIONS=0` 重新启用扩展。 - `--renderer-process-limit=2` 可通过 - `OPENCLAW_BROWSER_RENDERER_PROCESS_LIMIT=` 调整;设为 `0` 表示使用 Chromium 的 - 默认进程限制。 - - 当启用了 `noSandbox` 时,还会加上 `--no-sandbox` 和 `--disable-setuid-sandbox`。 - - 这些默认值是容器镜像的基线;如需更改容器默认行为,请使用带自定义 entrypoint 的自定义浏览器镜像。 + `OPENCLAW_BROWSER_RENDERER_PROCESS_LIMIT=` 修改;设为 `0` 则使用 Chromium 的默认进程上限。 + - 以及在启用 `noSandbox` 时追加 `--no-sandbox` 和 `--disable-setuid-sandbox`。 + - 这些默认值是容器镜像基线;如需更改容器默认行为,请使用自定义浏览器镜像和自定义 + entrypoint。 @@ -1496,15 +1470,15 @@ scripts/sandbox-browser-setup.sh # 可选浏览器镜像 { id: "main", default: true, - name: "主智能体", + name: "Main Agent", workspace: "~/.openclaw/workspace", agentDir: "~/.openclaw/agents/main/agent", model: "anthropic/claude-opus-4-6", // 或 { primary, fallbacks } - thinkingDefault: "high", // 每智能体 thinking level 覆盖 - reasoningDefault: "on", // 每智能体 reasoning 可见性覆盖 - fastModeDefault: false, // 每智能体 fast mode 覆盖 - params: { cacheRetention: "none" }, // 按键覆盖匹配 defaults.models params - skills: ["docs-search"], // 设置后将替换 agents.defaults.skills + thinkingDefault: "high", // 每智能体 thinking 级别覆盖 + reasoningDefault: "on", // 每智能体推理可见性覆盖 + fastModeDefault: false, // 每智能体快速模式覆盖 + params: { cacheRetention: "none" }, // 按键覆盖匹配 defaults.models 的参数 + skills: ["docs-search"], // 设置时会替换 agents.defaults.skills identity: { name: "Samantha", theme: "helpful sloth", @@ -1536,25 +1510,25 @@ scripts/sandbox-browser-setup.sh # 可选浏览器镜像 ``` - `id`:稳定的智能体 ID(必填)。 -- `default`:如果设置了多个,以第一个为准(会记录警告)。若未设置,则列表首项为默认值。 -- `model`:字符串形式仅覆盖 `primary`;对象形式 `{ primary, fallbacks }` 会同时覆盖两者(`[]` 可禁用全局 fallbacks)。仅覆盖 `primary` 的 cron 作业仍会继承默认 fallbacks,除非你设置 `fallbacks: []`。 -- `params`:按智能体配置的流参数,会合并到 `agents.defaults.models` 中选定的模型条目之上。用于智能体特定覆盖,如 `cacheRetention`、`temperature` 或 `maxTokens`,而无需复制整个模型目录。 -- `skills`:可选的每智能体 skill 允许列表。若省略,且设置了 `agents.defaults.skills`,则该智能体会继承它;显式列表会替换默认值而非合并,`[]` 表示无 Skills。 -- `thinkingDefault`:可选的每智能体默认 thinking level(`off | minimal | low | medium | high | xhigh | adaptive`)。当未设置每消息或会话覆盖时,它会覆盖此智能体的 `agents.defaults.thinkingDefault`。 -- `reasoningDefault`:可选的每智能体默认 reasoning 可见性(`on | off | stream`)。当未设置每消息或会话的 reasoning 覆盖时生效。 -- `fastModeDefault`:可选的每智能体默认 fast mode(`true | false`)。当未设置每消息或会话 fast-mode 覆盖时生效。 -- `runtime`:可选的每智能体运行时描述符。当该智能体应默认使用 ACP harness 会话时,可使用 `type: "acp"` 以及 `runtime.acp` 默认值(`agent`、`backend`、`mode`、`cwd`)。 -- `identity.avatar`:相对于工作区的路径、`http(s)` URL 或 `data:` URI。 -- `identity` 会推导默认值:`ackReaction` 来自 `emoji`,`mentionPatterns` 来自 `name` / `emoji`。 +- `default`:若设置多个,以第一个为准(会记录警告)。如果都未设置,则列表中的第一个是默认值。 +- `model`:字符串形式仅覆盖 `primary`;对象形式 `{ primary, fallbacks }` 会同时覆盖两者(`[]` 会禁用全局回退)。仅覆盖 `primary` 的 cron 任务仍会继承默认回退模型,除非你设置 `fallbacks: []`。 +- `params`:按智能体划分的流式参数,会合并到 `agents.defaults.models` 中选定模型条目之上。用于智能体特定覆盖,例如 `cacheRetention`、`temperature` 或 `maxTokens`,而无需复制整个模型目录。 +- `skills`:可选的每智能体 Skills 允许列表。省略时,如果设置了 `agents.defaults.skills`,智能体会继承它;显式列表会替换默认值而不是合并,`[]` 表示没有 Skills。 +- `thinkingDefault`:可选的每智能体默认 thinking 级别(`off | minimal | low | medium | high | xhigh | adaptive`)。当未设置每消息或会话级覆盖时,会覆盖该智能体的 `agents.defaults.thinkingDefault`。 +- `reasoningDefault`:可选的每智能体默认推理可见性(`on | off | stream`)。当未设置每消息或会话级推理覆盖时生效。 +- `fastModeDefault`:可选的每智能体快速模式默认值(`true | false`)。当未设置每消息或会话级快速模式覆盖时生效。 +- `runtime`:可选的每智能体运行时描述符。当智能体应默认使用 ACP harness 会话时,使用 `type: "acp"` 以及 `runtime.acp` 默认值(`agent`、`backend`、`mode`、`cwd`)。 +- `identity.avatar`:相对于 workspace 的路径、`http(s)` URL 或 `data:` URI。 +- `identity` 会派生默认值:`ackReaction` 来自 `emoji`,`mentionPatterns` 来自 `name`/`emoji`。 - `subagents.allowAgents`:`sessions_spawn` 的智能体 ID 允许列表(`["*"]` = 任意;默认:仅同一智能体)。 -- 沙箱继承保护:如果请求方会话处于沙箱中,`sessions_spawn` 会拒绝运行目标为非沙箱的配置。 -- `subagents.requireAgentId`:为 true 时,阻止未提供 `agentId` 的 `sessions_spawn` 调用(强制显式选择 profile;默认:false)。 +- 沙箱继承保护:如果请求者会话处于沙箱隔离中,`sessions_spawn` 会拒绝会导致目标未沙箱隔离的请求。 +- `subagents.requireAgentId`:为 true 时,阻止省略 `agentId` 的 `sessions_spawn` 调用(强制显式选择配置;默认:false)。 --- ## 多智能体路由 -在一个 Gateway 网关内运行多个隔离智能体。参见 [Multi-Agent](/zh-CN/concepts/multi-agent)。 +在一个 Gateway 网关中运行多个隔离智能体。参见 [Multi-Agent](/zh-CN/concepts/multi-agent)。 ```json5 { @@ -1573,25 +1547,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`(可选;渠道特定) -- `acp`(可选;仅限 `type: "acp"`):`{ mode, label, cwd, backend }` +- `acp`(可选;仅用于 `type: "acp"`):`{ mode, label, cwd, backend }` **确定性匹配顺序:** 1. `match.peer` 2. `match.guildId` 3. `match.teamId` -4. `match.accountId`(精确匹配,无 peer/guild/team) -5. `match.accountId: "*"`(渠道级) +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 绑定分层顺序。 ### 每智能体访问配置 @@ -1613,7 +1587,7 @@ scripts/sandbox-browser-setup.sh # 可选浏览器镜像 - + ```json5 { @@ -1688,7 +1662,7 @@ scripts/sandbox-browser-setup.sh # 可选浏览器镜像 -优先级细节参见 [Multi-Agent Sandbox & Tools](/zh-CN/tools/multi-agent-sandbox-tools)。 +优先级详情见 [Multi-Agent Sandbox & Tools](/zh-CN/tools/multi-agent-sandbox-tools)。 --- @@ -1714,7 +1688,7 @@ scripts/sandbox-browser-setup.sh # 可选浏览器镜像 }, resetTriggers: ["/new", "/reset"], store: "~/.openclaw/agents/{agentId}/sessions/sessions.json", - parentForkMaxTokens: 100000, // 超过此 token 数时跳过父线程 fork(0 表示禁用) + parentForkMaxTokens: 100000, // 超过该 token 数则跳过父线程 fork(0 表示禁用) maintenance: { mode: "warn", // warn | enforce pruneAfter: "30d", @@ -1726,10 +1700,10 @@ scripts/sandbox-browser-setup.sh # 可选浏览器镜像 }, threadBindings: { enabled: true, - idleHours: 24, // 默认不活跃自动取消聚焦时长(小时)(`0` 表示禁用) - maxAgeHours: 0, // 默认最大硬时长(小时)(`0` 表示禁用) + idleHours: 24, // 默认按小时计算的无活动自动取消聚焦(`0` 表示禁用) + maxAgeHours: 0, // 默认按小时计算的硬性最大存活时间(`0` 表示禁用) }, - mainKey: "main", // 旧版(运行时始终使用 "main") + mainKey: "main", // 旧字段(运行时始终使用 "main") agentToAgent: { maxPingPongTurns: 5 }, sendPolicy: { rules: [{ action: "deny", match: { channel: "discord", chatType: "group" } }], @@ -1742,34 +1716,34 @@ scripts/sandbox-browser-setup.sh # 可选浏览器镜像 - **`scope`**:群聊上下文的基础会话分组策略。 - - `per-sender`(默认):在渠道上下文中,每个发送者使用隔离会话。 - - `global`:在渠道上下文中,所有参与者共享一个会话(仅在明确需要共享上下文时使用)。 -- **`dmScope`**:私信如何分组。 - - `main`:所有私信共享 main 会话。 - - `per-peer`:按跨渠道的发送者 ID 隔离。 + - `per-sender`(默认):在某个渠道上下文中,每个发送者都有隔离的会话。 + - `global`:一个渠道上下文中的所有参与者共享同一个会话(仅在确实需要共享上下文时使用)。 +- **`dmScope`**:私信的分组方式。 + - `main`:所有私信共享主会话。 + - `per-peer`:按跨渠道发送者 ID 隔离。 - `per-channel-peer`:按渠道 + 发送者隔离(推荐用于多用户收件箱)。 - `per-account-channel-peer`:按账号 + 渠道 + 发送者隔离(推荐用于多账号)。 -- **`identityLinks`**:将规范 ID 映射到带提供商前缀的 peer,用于跨渠道会话共享。 -- **`reset`**:主重置策略。`daily` 会在本地时间 `atHour` 重置;`idle` 会在 `idleMinutes` 后重置。若两者都配置,以先到期者为准。 +- **`identityLinks`**:将规范 ID 映射到带提供商前缀的 peer,用于跨渠道共享会话。 +- **`reset`**:主重置策略。`daily` 会在本地时间 `atHour` 重置;`idle` 会在空闲 `idleMinutes` 后重置。当两者都配置时,以先到期者为准。 - **`resetByType`**:按类型覆盖(`direct`、`group`、`thread`)。旧版 `dm` 可作为 `direct` 的别名。 -- **`parentForkMaxTokens`**:创建 forked thread 会话时,允许的父会话 `totalTokens` 最大值(默认 `100000`)。 - - 如果父会话的 `totalTokens` 高于该值,OpenClaw 会启动一个新的线程会话,而不是继承父转录历史。 - - 设为 `0` 可禁用此保护,并始终允许父级 fork。 -- **`mainKey`**:旧版字段。运行时现在始终对主 direct-chat bucket 使用 `"main"`。 -- **`agentToAgent.maxPingPongTurns`**:智能体之间 exchange 期间允许的最大往返回复轮数(整数,范围:`0`–`5`)。`0` 表示禁用 ping-pong 链接。 -- **`sendPolicy`**:按 `channel`、`chatType`(`direct|group|channel`,旧版 `dm` 为别名)、`keyPrefix` 或 `rawKeyPrefix` 匹配。第一个 deny 生效。 +- **`parentForkMaxTokens`**:创建 fork 线程会话时,允许父会话 `totalTokens` 的最大值(默认 `100000`)。 + - 如果父会话 `totalTokens` 高于该值,OpenClaw 会启动一个全新的线程会话,而不是继承父级转录历史。 + - 设为 `0` 可禁用该保护,并始终允许父级 fork。 +- **`mainKey`**:旧字段。运行时现在始终对主私聊桶使用 `"main"`。 +- **`agentToAgent.maxPingPongTurns`**:智能体之间在 agent-to-agent 交换中允许的最大来回回复轮数(整数,范围:`0`–`5`)。`0` 会禁用 ping-pong 链式交互。 +- **`sendPolicy`**:按 `channel`、`chatType`(`direct|group|channel`,旧版 `dm` 为别名)、`keyPrefix` 或 `rawKeyPrefix` 匹配。第一个 deny 规则获胜。 - **`maintenance`**:会话存储清理 + 保留控制。 - - `mode`:`warn` 仅发出警告;`enforce` 会执行清理。 + - `mode`:`warn` 仅发出警告;`enforce` 会实际执行清理。 - `pruneAfter`:陈旧条目的年龄截止(默认 `30d`)。 - - `maxEntries`:`sessions.json` 中的最大条目数(默认 `500`)。 - - `rotateBytes`:当 `sessions.json` 超过此大小时轮转(默认 `10mb`)。 - - `resetArchiveRetention`:`*.reset.` 转录归档的保留期。默认值与 `pruneAfter` 相同;设为 `false` 可禁用。 - - `maxDiskBytes`:可选的 sessions 目录磁盘预算。在 `warn` 模式下记录警告;在 `enforce` 模式下先移除最旧的工件 / 会话。 - - `highWaterBytes`:预算清理后的可选目标值。默认是 `maxDiskBytes` 的 `80%`。 -- **`threadBindings`**:基于线程的会话功能的全局默认值。 + - `maxEntries`:`sessions.json` 中条目的最大数量(默认 `500`)。 + - `rotateBytes`:当 `sessions.json` 超过该大小时轮转(默认 `10mb`)。 + - `resetArchiveRetention`:`*.reset.` 转录归档的保留时间。默认等于 `pruneAfter`;设为 `false` 可禁用。 + - `maxDiskBytes`:可选的 sessions 目录磁盘预算。在 `warn` 模式下会记录警告;在 `enforce` 模式下会优先移除最旧的产物/会话。 + - `highWaterBytes`:预算清理后的可选目标值。默认为 `maxDiskBytes` 的 `80%`。 +- **`threadBindings`**:线程绑定会话功能的全局默认值。 - `enabled`:主默认开关(提供商可覆盖;Discord 使用 `channels.discord.threadBindings.enabled`) - - `idleHours`:默认不活跃自动取消聚焦时长(小时)(`0` 表示禁用;提供商可覆盖) - - `maxAgeHours`:默认最大硬时长(小时)(`0` 表示禁用;提供商可覆盖) + - `idleHours`:默认按小时计算的无活动自动取消聚焦(`0` 表示禁用;提供商可覆盖) + - `maxAgeHours`:默认按小时计算的硬性最大存活时间(`0` 表示禁用;提供商可覆盖) @@ -1807,36 +1781,36 @@ scripts/sandbox-browser-setup.sh # 可选浏览器镜像 ### 响应前缀 -每渠道 / 每账号覆盖:`channels..responsePrefix`、`channels..accounts..responsePrefix`。 +每渠道/账号覆盖:`channels..responsePrefix`、`channels..accounts..responsePrefix`。 解析顺序(越具体越优先):账号 → 渠道 → 全局。`""` 会禁用并停止级联。`"auto"` 会派生为 `[{identity.name}]`。 **模板变量:** -| 变量 | 描述 | 示例 | -| ----------------- | ---------------- | --------------------------- | -| `{model}` | 短模型名 | `claude-opus-4-6` | -| `{modelFull}` | 完整模型标识符 | `anthropic/claude-opus-4-6` | -| `{provider}` | 提供商名称 | `anthropic` | -| `{thinkingLevel}` | 当前 thinking level | `high`、`low`、`off` | -| `{identity.name}` | 智能体 identity 名称 |(与 `"auto"` 相同) | +| 变量 | 描述 | 示例 | +| ----------------- | ------------------ | --------------------------- | +| `{model}` | 短模型名 | `claude-opus-4-6` | +| `{modelFull}` | 完整模型标识符 | `anthropic/claude-opus-4-6` | +| `{provider}` | 提供商名称 | `anthropic` | +| `{thinkingLevel}` | 当前 thinking 级别 | `high`、`low`、`off` | +| `{identity.name}` | 智能体身份名称 | (与 `"auto"` 相同) | 变量不区分大小写。`{think}` 是 `{thinkingLevel}` 的别名。 -### 确认 reaction +### 确认反应 -- 默认使用活动智能体的 `identity.emoji`,否则为 `"👀"`。设为 `""` 可禁用。 +- 默认使用当前智能体的 `identity.emoji`,否则为 `"👀"`。设为 `""` 可禁用。 - 每渠道覆盖:`channels..ackReaction`、`channels..accounts..ackReaction`。 - 解析顺序:账号 → 渠道 → `messages.ackReaction` → identity 回退。 -- 范围:`group-mentions`(默认)、`group-all`、`direct`、`all`。 -- `removeAckAfterReply`:会在 Slack、Discord 和 Telegram 上于回复后移除 ack。 -- `messages.statusReactions.enabled`:在 Slack、Discord 和 Telegram 上启用生命周期状态 reactions。 - 在 Slack 和 Discord 上,未设置时会在 ack reactions 激活时保持状态 reactions 启用。 - 在 Telegram 上,需显式设置为 `true` 才会启用生命周期状态 reactions。 +- 作用范围:`group-mentions`(默认)、`group-all`、`direct`、`all`。 +- `removeAckAfterReply`:在 Slack、Discord 和 Telegram 上,在回复后移除确认反应。 +- `messages.statusReactions.enabled`:在 Slack、Discord 和 Telegram 上启用生命周期状态反应。 + 在 Slack 和 Discord 上,未设置时如果确认反应处于激活状态,则状态反应保持启用。 + 在 Telegram 上,需要显式设为 `true` 才会启用生命周期状态反应。 -### 入站防抖 +### 入站去抖 -将来自同一发送者的快速纯文本消息批量合并为一个智能体回合。媒体 / 附件会立即刷新。控制命令会绕过防抖。 +将来自同一发送者的快速文本消息批处理为一次智能体回合。媒体/附件会立即冲刷。控制命令会绕过去抖。 ### TTS(文本转语音) @@ -1881,16 +1855,16 @@ scripts/sandbox-browser-setup.sh # 可选浏览器镜像 - `auto` 控制自动 TTS。`/tts off|always|inbound|tagged` 会按会话覆盖。 - `summaryModel` 会覆盖自动摘要所使用的 `agents.defaults.model.primary`。 -- `modelOverrides` 默认启用;`modelOverrides.allowProvider` 默认是 `false`(显式启用)。 -- API key 可回退到 `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 服务器,并放宽模型 / voice 校验。 +- `modelOverrides` 默认启用;`modelOverrides.allowProvider` 默认为 `false`(需显式启用)。 +- API key 回退为 `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 服务器,并放宽模型/语音校验。 --- ## Talk -Talk mode(macOS / iOS / Android)的默认值。 +Talk 模式(macOS/iOS/Android)的默认值。 ```json5 { @@ -1914,51 +1888,51 @@ Talk mode(macOS / iOS / Android)的默认值。 } ``` -- `talk.provider` 在配置多个 Talk 提供商时必须匹配 `talk.providers` 中的某个键。 -- 旧版扁平 Talk 键(`talk.voiceId`、`talk.voiceAliases`、`talk.modelId`、`talk.outputFormat`、`talk.apiKey`)仅用于兼容,会自动迁移到 `talk.providers.` 中。 -- Voice ID 可回退到 `ELEVENLABS_VOICE_ID` 或 `SAG_VOICE_ID`。 +- 当配置了多个 Talk 提供商时,`talk.provider` 必须与 `talk.providers` 中的某个键匹配。 +- 旧版扁平 Talk 键(`talk.voiceId`、`talk.voiceAliases`、`talk.modelId`、`talk.outputFormat`、`talk.apiKey`)仅用于兼容,并会自动迁移到 `talk.providers.` 中。 +- Voice ID 会回退到 `ELEVENLABS_VOICE_ID` 或 `SAG_VOICE_ID`。 - `providers.*.apiKey` 接受明文字符串或 SecretRef 对象。 -- 仅当未配置 Talk API key 时才会应用 `ELEVENLABS_API_KEY` 回退。 +- 仅当未配置 Talk API key 时,才会回退到 `ELEVENLABS_API_KEY`。 - `providers.*.voiceAliases` 允许 Talk 指令使用友好名称。 -- `silenceTimeoutMs` 控制 Talk mode 在用户静音后等待多长时间再发送转录。未设置时保留平台默认暂停窗口(`macOS 和 Android 为 700 ms,iOS 为 900 ms`)。 +- `silenceTimeoutMs` 控制 Talk 模式在用户停止说话后等待多久才发送转录。未设置时保留平台默认停顿窗口(`macOS 和 Android 为 700 ms,iOS 为 900 ms`)。 --- ## 工具 -### 工具配置文件 +### 工具配置 -`tools.profile` 会在 `tools.allow` / `tools.deny` 之前设置基础 allowlist: +`tools.profile` 会在 `tools.allow`/`tools.deny` 之前设置基础允许列表: -当未设置时,本地新手引导会将新的本地配置默认设为 `tools.profile: "coding"`(已存在的显式 profile 会保留)。 +本地新手引导在未设置时,会将新的本地配置默认设为 `tools.profile: "coding"`(现有显式配置会被保留)。 -| Profile | 包含内容 | -| ----------- | ------------------------------------------------------------------------------------------------------------------------------ | -| `minimal` | 仅 `session_status` | -| `coding` | `group:fs`、`group:runtime`、`group:web`、`group:sessions`、`group:memory`、`cron`、`image`、`image_generate`、`video_generate` | -| `messaging` | `group:messaging`、`sessions_list`、`sessions_history`、`sessions_send`、`session_status` | -| `full` | 无限制(与未设置相同) | +| 配置 | 包含内容 | +| ------------- | ------------------------------------------------------------------------------------------------------------------------------ | +| `minimal` | 仅 `session_status` | +| `coding` | `group:fs`、`group:runtime`、`group:web`、`group:sessions`、`group:memory`、`cron`、`image`、`image_generate`、`video_generate` | +| `messaging` | `group:messaging`、`sessions_list`、`sessions_history`、`sessions_send`、`session_status` | +| `full` | 不做限制(与未设置相同) | ### 工具组 -| 组 | 工具 | -| -------------------- | ---------------------------------------------------------------------------------------------------------------------- | -| `group:runtime` | `exec`、`process`、`code_execution`(`bash` 可作为 `exec` 的别名) | -| `group:fs` | `read`、`write`、`edit`、`apply_patch` | -| `group:sessions` | `sessions_list`、`sessions_history`、`sessions_send`、`sessions_spawn`、`sessions_yield`、`subagents`、`session_status` | -| `group:memory` | `memory_search`、`memory_get` | -| `group:web` | `web_search`、`x_search`、`web_fetch` | -| `group:ui` | `browser`、`canvas` | -| `group:automation` | `cron`、`gateway` | -| `group:messaging` | `message` | -| `group:nodes` | `nodes` | -| `group:agents` | `agents_list` | -| `group:media` | `image`、`image_generate`、`video_generate`、`tts` | -| `group:openclaw` | 所有内置工具(不含 provider 插件) | +| 工具组 | 工具 | +| ------------------- | ----------------------------------------------------------------------------------------------------------------------- | +| `group:runtime` | `exec`、`process`、`code_execution`(`bash` 可作为 `exec` 的别名) | +| `group:fs` | `read`、`write`、`edit`、`apply_patch` | +| `group:sessions` | `sessions_list`、`sessions_history`、`sessions_send`、`sessions_spawn`、`sessions_yield`、`subagents`、`session_status` | +| `group:memory` | `memory_search`、`memory_get` | +| `group:web` | `web_search`、`x_search`、`web_fetch` | +| `group:ui` | `browser`、`canvas` | +| `group:automation` | `cron`、`gateway` | +| `group:messaging` | `message` | +| `group:nodes` | `nodes` | +| `group:agents` | `agents_list` | +| `group:media` | `image`、`image_generate`、`video_generate`、`tts` | +| `group:openclaw` | 所有内置工具(不含提供商插件) | ### `tools.allow` / `tools.deny` -全局工具 allow / deny 策略(deny 优先)。不区分大小写,支持 `*` 通配符。即使 Docker 沙箱关闭也会应用。 +全局工具允许/拒绝策略(拒绝优先)。不区分大小写,支持 `*` 通配符。即使 Docker 沙箱关闭也会生效。 ```json5 { @@ -1968,7 +1942,7 @@ Talk mode(macOS / iOS / Android)的默认值。 ### `tools.byProvider` -对特定提供商或模型进一步限制工具。顺序:基础 profile → 提供商 profile → allow / deny。 +为特定提供商或模型进一步限制工具。顺序:基础配置 → 提供商配置 → allow/deny。 ```json5 { @@ -2001,8 +1975,8 @@ Talk mode(macOS / iOS / Android)的默认值。 ``` - 每智能体覆盖(`agents.list[].tools.elevated`)只能进一步收紧限制。 -- `/elevated on|off|ask|full` 会按会话存储状态;内联指令只作用于单条消息。 -- Elevated `exec` 会绕过沙箱隔离,并使用已配置的 escape 路径(默认是 `gateway`,当 exec 目标为 `node` 时则使用 `node`)。 +- `/elevated on|off|ask|full` 会按会话存储状态;内联指令仅对单条消息生效。 +- Elevated `exec` 会绕过沙箱隔离,并使用已配置的逃逸路径(默认 `gateway`,若 exec 目标为 `node` 则使用 `node`)。 ### `tools.exec` @@ -2026,8 +2000,8 @@ Talk mode(macOS / iOS / Android)的默认值。 ### `tools.loopDetection` -工具循环安全检查**默认关闭**。设置 `enabled: true` 以启用检测。 -设置可在全局 `tools.loopDetection` 中定义,并在每智能体 `agents.list[].tools.loopDetection` 中覆盖。 +工具循环安全检查**默认禁用**。设置 `enabled: true` 可启用检测。 +设置可全局定义在 `tools.loopDetection` 中,也可在每智能体级通过 `agents.list[].tools.loopDetection` 覆盖。 ```json5 { @@ -2048,14 +2022,14 @@ Talk mode(macOS / iOS / Android)的默认值。 } ``` -- `historySize`:用于循环分析的最大工具调用历史保留数。 -- `warningThreshold`:对重复无进展模式发出警告的阈值。 +- `historySize`:用于循环分析所保留的最大工具调用历史数。 +- `warningThreshold`:触发警告的重复无进展模式阈值。 - `criticalThreshold`:阻止严重循环的更高重复阈值。 -- `globalCircuitBreakerThreshold`:对任意无进展运行的硬停止阈值。 -- `detectors.genericRepeat`:对重复的同工具 / 同参数调用发出警告。 -- `detectors.knownPollNoProgress`:对已知轮询工具(`process.poll`、`command_status` 等)的无进展轮询发出警告 / 阻止。 -- `detectors.pingPong`:对交替出现的无进展成对模式发出警告 / 阻止。 -- 如果 `warningThreshold >= criticalThreshold` 或 `criticalThreshold >= globalCircuitBreakerThreshold`,则校验失败。 +- `globalCircuitBreakerThreshold`:任何无进展运行的硬停止阈值。 +- `detectors.genericRepeat`:对重复调用“同工具/同参数”发出警告。 +- `detectors.knownPollNoProgress`:对已知轮询工具(`process.poll`、`command_status` 等)的无进展模式发出警告/阻止。 +- `detectors.pingPong`:对交替出现的无进展成对模式发出警告/阻止。 +- 如果 `warningThreshold >= criticalThreshold` 或 `criticalThreshold >= globalCircuitBreakerThreshold`,验证会失败。 ### `tools.web` @@ -2089,7 +2063,7 @@ Talk mode(macOS / iOS / Android)的默认值。 ### `tools.media` -配置入站媒体理解(图像 / 音频 / 视频): +配置入站媒体理解(图像/音频/视频): ```json5 { @@ -2124,7 +2098,7 @@ Talk mode(macOS / iOS / Android)的默认值。 - `provider`:API 提供商 ID(`openai`、`anthropic`、`google`/`gemini`、`groq` 等) - `model`:模型 ID 覆盖 -- `profile` / `preferredProfile`:`auth-profiles.json` profile 选择 +- `profile` / `preferredProfile`:`auth-profiles.json` 配置选择 **CLI 条目**(`type: "cli"`): @@ -2133,7 +2107,7 @@ Talk mode(macOS / iOS / Android)的默认值。 **公共字段:** -- `capabilities`:可选列表(`image`、`audio`、`video`)。默认:`openai` / `anthropic` / `minimax` → image,`google` → image+audio+video,`groq` → audio。 +- `capabilities`:可选列表(`image`、`audio`、`video`)。默认值:`openai`/`anthropic`/`minimax` → image,`google` → image+audio+video,`groq` → audio。 - `prompt`、`maxChars`、`maxBytes`、`timeoutSeconds`、`language`:每条目覆盖。 - 失败时会回退到下一个条目。 @@ -2156,9 +2130,9 @@ Talk mode(macOS / iOS / Android)的默认值。 ### `tools.sessions` -控制哪些会话可以被会话工具(`sessions_list`、`sessions_history`、`sessions_send`)选中。 +控制哪些会话可被会话工具(`sessions_list`、`sessions_history`、`sessions_send`)定位。 -默认值:`tree`(当前会话 + 其生成的会话,例如子智能体)。 +默认值:`tree`(当前会话 + 由它生成的会话,例如子智能体)。 ```json5 { @@ -2175,9 +2149,9 @@ Talk mode(macOS / iOS / Android)的默认值。 - `self`:仅当前会话键。 - `tree`:当前会话 + 由当前会话生成的会话(子智能体)。 -- `agent`:属于当前智能体 ID 的任意会话(如果你在同一智能体 ID 下运行 per-sender 会话,也可能包含其他用户)。 -- `all`:任意会话。跨智能体定向仍需要 `tools.agentToAgent`。 -- 沙箱钳制:当当前会话处于沙箱中,且 `agents.defaults.sandbox.sessionToolsVisibility="spawned"` 时,即使 `tools.sessions.visibility="all"`,可见性也会被强制为 `tree`。 +- `agent`:属于当前智能体 ID 的任意会话(如果你在同一智能体 ID 下运行按发送者划分的会话,则可能包含其他用户)。 +- `all`:任意会话。跨智能体定位仍然需要 `tools.agentToAgent`。 +- 沙箱钳制:当当前会话处于沙箱隔离中,且 `agents.defaults.sandbox.sessionToolsVisibility="spawned"` 时,即使 `tools.sessions.visibility="all"`,可见性也会被强制为 `tree`。 ### `tools.sessions_spawn` @@ -2189,10 +2163,10 @@ Talk mode(macOS / iOS / Android)的默认值。 sessions_spawn: { attachments: { enabled: false, // 显式启用:设为 true 以允许内联文件附件 - maxTotalBytes: 5242880, // 所有文件合计 5 MB + maxTotalBytes: 5242880, // 所有文件总计 5 MB maxFiles: 50, maxFileBytes: 1048576, // 每文件 1 MB - retainOnSessionKeep: false, // cleanup="keep" 时保留附件 + retainOnSessionKeep: false, // 当 cleanup="keep" 时保留附件 }, }, }, @@ -2201,16 +2175,16 @@ Talk mode(macOS / iOS / Android)的默认值。 说明: -- 附件仅支持 `runtime: "subagent"`。ACP runtime 会拒绝它们。 -- 文件会被物化到子工作区 `.openclaw/attachments//` 中,并包含 `.manifest.json`。 +- 附件仅对 `runtime: "subagent"` 提供支持。ACP 运行时会拒绝它们。 +- 文件会实体化到子 workspace 的 `.openclaw/attachments//` 中,并带有 `.manifest.json`。 - 附件内容会自动从转录持久化中脱敏。 -- Base64 输入会执行严格的字母表 / 填充校验以及解码前大小保护。 +- Base64 输入会使用严格的字母表/填充校验以及解码前大小保护。 - 文件权限为:目录 `0700`,文件 `0600`。 -- 清理遵循 `cleanup` 策略:`delete` 始终删除附件;`keep` 仅在 `retainOnSessionKeep: true` 时保留。 +- 清理遵循 `cleanup` 策略:`delete` 总是删除附件;`keep` 仅在 `retainOnSessionKeep: true` 时保留。 ### `tools.experimental` -实验性内置工具标志。除非某个运行时特定的自动启用规则生效,否则默认关闭。 +实验性内置工具标志。除非有运行时特定自动启用规则,否则默认关闭。 ```json5 { @@ -2224,9 +2198,9 @@ Talk mode(macOS / iOS / Android)的默认值。 说明: -- `planTool`:启用结构化 `update_plan` 工具,用于跟踪非平凡多步骤工作。 +- `planTool`:为非简单的多步骤工作跟踪启用结构化 `update_plan` 工具。 - 默认值:对非 OpenAI 提供商为 `false`。OpenAI 和 OpenAI Codex 运行会自动启用它。 -- 启用后,系统提示词还会加入使用指引,要求模型仅将其用于较重工作,并最多保持一个步骤为 `in_progress`。 +- 启用后,系统提示也会添加使用说明,以便模型仅在实质性工作中使用它,并始终最多仅有一个步骤处于 `in_progress`。 ### `agents.defaults.subagents` @@ -2246,9 +2220,9 @@ Talk mode(macOS / iOS / Android)的默认值。 } ``` -- `model`:生成的子智能体默认模型。若省略,子智能体会继承调用方的模型。 -- `allowAgents`:当请求方智能体未设置自己的 `subagents.allowAgents` 时,`sessions_spawn` 目标智能体 ID 的默认 allowlist(`["*"]` = 任意;默认:仅同一智能体)。 -- `runTimeoutSeconds`:当工具调用省略 `runTimeoutSeconds` 时,`sessions_spawn` 使用的默认超时(秒)。`0` 表示无超时。 +- `model`:生成子智能体时使用的默认模型。若省略,子智能体会继承调用者的模型。 +- `allowAgents`:当请求智能体未设置自己的 `subagents.allowAgents` 时,`sessions_spawn` 目标智能体 ID 的默认允许列表(`["*"]` = 任意;默认:仅同一智能体)。 +- `runTimeoutSeconds`:当工具调用省略 `runTimeoutSeconds` 时,`sessions_spawn` 的默认超时(秒)。`0` 表示无超时。 - 每子智能体工具策略:`tools.subagents.tools.allow` / `tools.subagents.tools.deny`。 --- @@ -2284,46 +2258,46 @@ OpenClaw 使用内置模型目录。通过配置中的 `models.providers` 或 `~ } ``` -- 使用 `authHeader: true` + `headers` 以满足自定义认证需求。 +- 如需自定义认证,请使用 `authHeader: true` + `headers`。 - 使用 `OPENCLAW_AGENT_DIR`(或旧版环境变量别名 `PI_CODING_AGENT_DIR`)覆盖智能体配置根目录。 - 对匹配提供商 ID 的合并优先级: - - 非空的智能体 `models.json` `baseUrl` 优先。 - - 非空的智能体 `apiKey` 仅在该提供商在当前配置 / auth-profile 上下文中不是 SecretRef 管理时优先。 - - SecretRef 管理的提供商 `apiKey` 值会从源标记刷新(环境变量引用使用 `ENV_VAR_NAME`,文件 / exec 引用使用 `secretref-managed`),而不是持久化已解析的 secrets。 - - SecretRef 管理的提供商 header 值会从源标记刷新(环境变量引用使用 `secretref-env:ENV_VAR_NAME`,文件 / exec 引用使用 `secretref-managed`)。 - - 空或缺失的智能体 `apiKey` / `baseUrl` 会回退到配置中的 `models.providers`。 - - 匹配模型的 `contextWindow` / `maxTokens` 会在显式配置值和隐式目录值中取较高值。 - - 匹配模型的 `contextTokens` 会在存在时保留显式运行时上限;用它可以限制有效上下文,而不改变模型的原生元数据。 - - 当你希望配置完全重写 `models.json` 时,请使用 `models.mode: "replace"`。 - - 标记持久化是源权威的:标记会从活动源配置快照(解析前)写入,而非从已解析的运行时 secret 值写入。 + - 非空的智能体 `models.json` `baseUrl` 值优先。 + - 非空的智能体 `apiKey` 值仅在当前配置/auth-profile 上下文中该提供商未由 SecretRef 管理时优先。 + - 由 SecretRef 管理的提供商 `apiKey` 值会从源标记(环境变量引用使用 `ENV_VAR_NAME`,文件/exec 引用使用 `secretref-managed`)刷新,而不是持久化已解析的 secret。 + - 由 SecretRef 管理的提供商 header 值会从源标记刷新(环境变量引用使用 `secretref-env:ENV_VAR_NAME`,文件/exec 引用使用 `secretref-managed`)。 + - 为空或缺失的智能体 `apiKey`/`baseUrl` 会回退到配置中的 `models.providers`。 + - 匹配模型的 `contextWindow`/`maxTokens` 会使用显式配置值和隐式目录值中的较高者。 + - 匹配模型的 `contextTokens` 会在存在时保留显式运行时上限;可用它限制有效上下文,而不改变模型原生元数据。 + - 如果你希望配置完全重写 `models.json`,请使用 `models.mode: "replace"`。 + - 标记持久化是“源权威”的:标记写入基于当前活跃的源配置快照(解析前),而不是基于已解析的运行时 secret 值。 ### 提供商字段详情 - `models.mode`:提供商目录行为(`merge` 或 `replace`)。 -- `models.providers`:按提供商 ID 键控的自定义提供商映射。 +- `models.providers`:以提供商 ID 为键的自定义提供商映射。 - `models.providers.*.api`:请求适配器(`openai-completions`、`openai-responses`、`anthropic-messages`、`google-generative-ai` 等)。 -- `models.providers.*.apiKey`:提供商凭证(优先使用 SecretRef / 环境变量替换)。 +- `models.providers.*.apiKey`:提供商凭证(优先使用 SecretRef/环境变量替换)。 - `models.providers.*.auth`:认证策略(`api-key`、`token`、`oauth`、`aws-sdk`)。 -- `models.providers.*.injectNumCtxForOpenAICompat`:对于 Ollama + `openai-completions`,将 `options.num_ctx` 注入请求中(默认:`true`)。 +- `models.providers.*.injectNumCtxForOpenAICompat`:对 Ollama + `openai-completions`,将 `options.num_ctx` 注入请求(默认:`true`)。 - `models.providers.*.authHeader`:在需要时强制通过 `Authorization` header 传输凭证。 - `models.providers.*.baseUrl`:上游 API base URL。 -- `models.providers.*.headers`:用于代理 / 租户路由的额外静态 headers。 +- `models.providers.*.headers`:用于代理/租户路由的额外静态 headers。 - `models.providers.*.request`:模型提供商 HTTP 请求的传输覆盖。 - `request.headers`:额外 headers(与提供商默认值合并)。值接受 SecretRef。 - `request.auth`:认证策略覆盖。模式:`"provider-default"`(使用提供商内置认证)、`"authorization-bearer"`(配合 `token`)、`"header"`(配合 `headerName`、`value`,可选 `prefix`)。 - - `request.proxy`:HTTP 代理覆盖。模式:`"env-proxy"`(使用 `HTTP_PROXY` / `HTTPS_PROXY` 环境变量)、`"explicit-proxy"`(配合 `url`)。两种模式都接受可选的 `tls` 子对象。 - - `request.tls`:直连时的 TLS 覆盖。字段:`ca`、`cert`、`key`、`passphrase`(均接受 SecretRef)、`serverName`、`insecureSkipVerify`。 + - `request.proxy`:HTTP 代理覆盖。模式:`"env-proxy"`(使用 `HTTP_PROXY`/`HTTPS_PROXY` 环境变量)、`"explicit-proxy"`(配合 `url`)。两种模式都接受可选的 `tls` 子对象。 + - `request.tls`:直连的 TLS 覆盖。字段:`ca`、`cert`、`key`、`passphrase`(均接受 SecretRef)、`serverName`、`insecureSkipVerify`。 - `models.providers.*.models`:显式提供商模型目录条目。 - `models.providers.*.models.*.contextWindow`:模型原生上下文窗口元数据。 - `models.providers.*.models.*.contextTokens`:可选运行时上下文上限。当你希望有效上下文预算小于模型原生 `contextWindow` 时使用。 -- `models.providers.*.models.*.compat.supportsDeveloperRole`:可选兼容性提示。对于 `api: "openai-completions"` 且 `baseUrl` 非空且非原生(host 不是 `api.openai.com`)的情况,OpenClaw 会在运行时强制其为 `false`。空 / 省略的 `baseUrl` 会保留默认的 OpenAI 行为。 +- `models.providers.*.models.*.compat.supportsDeveloperRole`:可选兼容性提示。对于 `api: "openai-completions"` 且 `baseUrl` 非空且非原生(host 不是 `api.openai.com`)的情况,OpenClaw 会在运行时将其强制设为 `false`。空或省略的 `baseUrl` 保持 OpenAI 默认行为。 - `plugins.entries.amazon-bedrock.config.discovery`:Bedrock 自动发现设置根。 -- `plugins.entries.amazon-bedrock.config.discovery.enabled`:开启 / 关闭隐式发现。 -- `plugins.entries.amazon-bedrock.config.discovery.region`:用于发现的 AWS 区域。 -- `plugins.entries.amazon-bedrock.config.discovery.providerFilter`:用于定向发现的可选 provider-id 过滤器。 -- `plugins.entries.amazon-bedrock.config.discovery.refreshInterval`:刷新发现的轮询间隔。 -- `plugins.entries.amazon-bedrock.config.discovery.defaultContextWindow`:已发现模型的回退上下文窗口。 -- `plugins.entries.amazon-bedrock.config.discovery.defaultMaxTokens`:已发现模型的回退最大输出 token。 +- `plugins.entries.amazon-bedrock.config.discovery.enabled`:开启/关闭隐式发现。 +- `plugins.entries.amazon-bedrock.config.discovery.region`:发现所用的 AWS 区域。 +- `plugins.entries.amazon-bedrock.config.discovery.providerFilter`:可选的 provider-id 过滤器,用于定向发现。 +- `plugins.entries.amazon-bedrock.config.discovery.refreshInterval`:发现刷新轮询间隔。 +- `plugins.entries.amazon-bedrock.config.discovery.defaultContextWindow`:发现到的模型的回退上下文窗口。 +- `plugins.entries.amazon-bedrock.config.discovery.defaultMaxTokens`:发现到的模型的回退最大输出 token。 ### 提供商示例 @@ -2339,8 +2313,8 @@ OpenClaw 使用内置模型目录。通过配置中的 `models.providers` 或 `~ fallbacks: ["cerebras/zai-glm-4.6"], }, models: { - "cerebras/zai-glm-4.7": { alias: "GLM 4.7(Cerebras)" }, - "cerebras/zai-glm-4.6": { alias: "GLM 4.6(Cerebras)" }, + "cerebras/zai-glm-4.7": { alias: "GLM 4.7 (Cerebras)" }, + "cerebras/zai-glm-4.6": { alias: "GLM 4.6 (Cerebras)" }, }, }, }, @@ -2352,8 +2326,8 @@ OpenClaw 使用内置模型目录。通过配置中的 `models.providers` 或 `~ apiKey: "${CEREBRAS_API_KEY}", api: "openai-completions", models: [ - { id: "zai-glm-4.7", name: "GLM 4.7(Cerebras)" }, - { id: "zai-glm-4.6", name: "GLM 4.6(Cerebras)" }, + { id: "zai-glm-4.7", name: "GLM 4.7 (Cerebras)" }, + { id: "zai-glm-4.6", name: "GLM 4.6 (Cerebras)" }, ], }, }, @@ -2395,11 +2369,11 @@ Cerebras 请使用 `cerebras/zai-glm-4.7`;Z.AI 直连请使用 `zai/glm-4.7` } ``` -设置 `ZAI_API_KEY`。`z.ai/*` 和 `z-ai/*` 都是可接受别名。快捷方式:`openclaw onboard --auth-choice zai-api-key`。 +设置 `ZAI_API_KEY`。`z.ai/*` 和 `z-ai/*` 都是可接受的别名。快捷方式:`openclaw onboard --auth-choice zai-api-key`。 - 通用端点:`https://api.z.ai/api/paas/v4` -- Coding 端点(默认):`https://api.z.ai/api/coding/paas/v4` -- 若要使用通用端点,请定义带 base URL 覆盖的自定义提供商。 +- 编码端点(默认):`https://api.z.ai/api/coding/paas/v4` +- 若使用通用端点,请定义带有 base URL 覆盖的自定义提供商。 @@ -2441,7 +2415,7 @@ Cerebras 请使用 `cerebras/zai-glm-4.7`;Z.AI 直连请使用 `zai/glm-4.7` 中国端点请使用:`baseUrl: "https://api.moonshot.cn/v1"` 或 `openclaw onboard --auth-choice moonshot-api-key-cn`。 原生 Moonshot 端点会在共享的 -`openai-completions` 传输上声明流式使用兼容性,OpenClaw 现在会根据端点能力而不是仅根据内置 provider id 来判断这一点。 +`openai-completions` 传输上声明流式用法兼容性,而 OpenClaw 现在会基于端点能力而非仅内置提供商 ID 来判断这一点。 @@ -2459,7 +2433,7 @@ Cerebras 请使用 `cerebras/zai-glm-4.7`;Z.AI 直连请使用 `zai/glm-4.7` } ``` -Anthropic 兼容,内置提供商。快捷方式:`openclaw onboard --auth-choice kimi-code-api-key`。 +兼容 Anthropic 的内置提供商。快捷方式:`openclaw onboard --auth-choice kimi-code-api-key`。 @@ -2498,7 +2472,7 @@ Anthropic 兼容,内置提供商。快捷方式:`openclaw onboard --auth-cho } ``` -Base URL 不应包含 `/v1`(Anthropic 客户端会自行追加)。快捷方式:`openclaw onboard --auth-choice synthetic-api-key`。 +base URL 不应包含 `/v1`(Anthropic 客户端会自行追加)。快捷方式:`openclaw onboard --auth-choice synthetic-api-key`。 @@ -2542,15 +2516,16 @@ Base URL 不应包含 `/v1`(Anthropic 客户端会自行追加)。快捷方 `openclaw onboard --auth-choice minimax-global-api` 或 `openclaw onboard --auth-choice minimax-cn-api`。 模型目录现在默认仅包含 M2.7。 -在兼容 Anthropic 的流式路径上,除非你显式设置 `thinking`,否则 OpenClaw 默认会关闭 MiniMax thinking。 -`/fast on` 或 `params.fastMode: true` 会将 `MiniMax-M2.7` 重写为 +在兼容 Anthropic 的流式路径上,除非你显式设置 `thinking`,否则 OpenClaw 默认会禁用 MiniMax thinking。 +`/fast on` 或 +`params.fastMode: true` 会将 `MiniMax-M2.7` 重写为 `MiniMax-M2.7-highspeed`。 -参见 [Local Models](/zh-CN/gateway/local-models)。简要说明:在高性能硬件上通过 LM Studio Responses API 运行大型本地模型,并保留托管模型作为回退。 +参见 [Local Models](/zh-CN/gateway/local-models)。简而言之:在高性能硬件上通过 LM Studio Responses API 运行大型本地模型;同时保留合并的托管模型作为回退。 @@ -2581,12 +2556,13 @@ Base URL 不应包含 `/v1`(Anthropic 客户端会自行追加)。快捷方 } ``` -- `allowBundled`:仅针对内置 skills 的可选 allowlist(不影响托管 / 工作区 skills)。 -- `load.extraDirs`:额外共享 skill 根目录(最低优先级)。 -- `install.preferBrew`:为 true 时,如果存在 `brew`,优先使用 Homebrew 安装器,然后才回退到其他安装器类型。 -- `install.nodeManager`:`metadata.openclaw.install` 规范的 node 安装器偏好(`npm` | `pnpm` | `yarn` | `bun`)。 -- `entries..enabled: false`:即使 skill 已内置 / 已安装,也会禁用它。 -- `entries..apiKey`:为声明了主环境变量的 skill 提供便捷 API key 字段(明文字符串或 SecretRef 对象)。 +- `allowBundled`:仅对内置 Skills 生效的可选允许列表(托管/workspace Skills 不受影响)。 +- `load.extraDirs`:额外的共享 Skills 根目录(优先级最低)。 +- `install.preferBrew`:为 true 时,若 `brew` 可用,则优先使用 Homebrew 安装器,然后再回退到其他安装类型。 +- `install.nodeManager`:`metadata.openclaw.install` 规范的 Node 安装器偏好 + (`npm` | `pnpm` | `yarn` | `bun`)。 +- `entries..enabled: false`:即使某个 Skill 已内置/已安装,也将其禁用。 +- `entries..apiKey`:为声明主环境变量的 Skill 提供便捷 API key 字段(明文字符串或 SecretRef 对象)。 --- @@ -2614,42 +2590,42 @@ Base URL 不应包含 `/v1`(Anthropic 客户端会自行追加)。快捷方 } ``` -- 从 `~/.openclaw/extensions`、`/.openclaw/extensions` 和 `plugins.load.paths` 加载。 -- 设备发现接受原生 OpenClaw 插件以及兼容的 Codex bundle 和 Claude bundle,包括无 manifest 的 Claude 默认布局 bundle。 -- **配置更改需要重启 Gateway 网关。** -- `allow`:可选 allowlist(仅加载列出的插件)。`deny` 优先。 -- `plugins.entries..apiKey`:插件级 API key 便捷字段(插件支持时)。 +- 从 `~/.openclaw/extensions`、`/.openclaw/extensions` 以及 `plugins.load.paths` 加载。 +- 发现机制接受原生 OpenClaw 插件,以及兼容的 Codex bundle 和 Claude bundle,包括无 manifest 的 Claude 默认布局 bundle。 +- **配置变更需要重启 Gateway 网关。** +- `allow`:可选允许列表(仅加载列出的插件)。`deny` 优先。 +- `plugins.entries..apiKey`:插件级 API key 便捷字段(当插件支持时)。 - `plugins.entries..env`:插件作用域环境变量映射。 -- `plugins.entries..hooks.allowPromptInjection`:为 `false` 时,core 会阻止 `before_prompt_build`,并忽略旧版 `before_agent_start` 中修改提示词的字段,同时保留旧版 `modelOverride` 和 `providerOverride`。适用于原生插件 hooks 和受支持 bundle 提供的 hook 目录。 -- `plugins.entries..subagent.allowModelOverride`:显式信任此插件在后台子智能体运行中请求每次运行的 `provider` 和 `model` 覆盖。 -- `plugins.entries..subagent.allowedModels`:受信任子智能体覆盖可使用的规范 `provider/model` 目标的可选 allowlist。仅在你明确希望允许任意模型时才使用 `"*"`。 -- `plugins.entries..config`:插件定义的配置对象(若可用,会由原生 OpenClaw 插件 schema 校验)。 -- `plugins.entries.firecrawl.config.webFetch`:Firecrawl web 抓取提供商设置。 - - `apiKey`:Firecrawl API key(接受 SecretRef)。回退顺序:`plugins.entries.firecrawl.config.webSearch.apiKey`、旧版 `tools.web.fetch.firecrawl.apiKey`,或 `FIRECRAWL_API_KEY` 环境变量。 +- `plugins.entries..hooks.allowPromptInjection`:为 `false` 时,core 会阻止 `before_prompt_build`,并忽略旧版 `before_agent_start` 中会改变提示的字段,同时保留旧版 `modelOverride` 和 `providerOverride`。适用于原生插件 hooks 以及受支持 bundle 提供的 hook 目录。 +- `plugins.entries..subagent.allowModelOverride`:显式信任该插件可以为后台子智能体运行请求每次运行级的 `provider` 和 `model` 覆盖。 +- `plugins.entries..subagent.allowedModels`:可信子智能体覆盖允许使用的规范 `provider/model` 目标可选允许列表。仅当你明确想允许任意模型时才使用 `"*"`。 +- `plugins.entries..config`:插件定义的配置对象(若可用,会由原生 OpenClaw 插件 schema 验证)。 +- `plugins.entries.firecrawl.config.webFetch`:Firecrawl Web 抓取提供商设置。 + - `apiKey`:Firecrawl API key(接受 SecretRef)。会回退到 `plugins.entries.firecrawl.config.webSearch.apiKey`、旧版 `tools.web.fetch.firecrawl.apiKey` 或 `FIRECRAWL_API_KEY` 环境变量。 - `baseUrl`:Firecrawl API base URL(默认:`https://api.firecrawl.dev`)。 - `onlyMainContent`:仅提取页面主体内容(默认:`true`)。 - `maxAgeMs`:最大缓存年龄(毫秒)(默认:`172800000` / 2 天)。 - `timeoutSeconds`:抓取请求超时(秒)(默认:`60`)。 -- `plugins.entries.xai.config.xSearch`:xAI X Search(Grok web 搜索)设置。 +- `plugins.entries.xai.config.xSearch`:xAI X Search(Grok Web 搜索)设置。 - `enabled`:启用 X Search 提供商。 - - `model`:用于搜索的 Grok 模型(例如 `"grok-4-1-fast"`)。 -- `plugins.entries.memory-core.config.dreaming`:memory dreaming(实验性)设置。模式和阈值参见 [Dreaming](/concepts/dreaming)。 + - `model`:搜索所使用的 Grok 模型(例如 `"grok-4-1-fast"`)。 +- `plugins.entries.memory-core.config.dreaming`:记忆 dreaming(实验性)设置。有关模式和阈值,请参见 [Dreaming](/zh-CN/concepts/dreaming)。 - `mode`:dreaming 频率预设(`"off"`、`"core"`、`"rem"`、`"deep"`)。默认:`"off"`。 - - `cron`:可选的 dreaming 调度 cron 表达式覆盖。 - - `timezone`:调度评估时区(回退到 `agents.defaults.userTimezone`)。 - - `limit`:每个周期可提升的最大候选数。 - - `minScore`:提升所需的最小加权分数阈值。 - - `minRecallCount`:最小 recall 次数阈值。 + - `cron`:dreaming 调度的可选 cron 表达式覆盖。 + - `timezone`:调度评估使用的时区(回退到 `agents.defaults.userTimezone`)。 + - `limit`:每个周期提升的候选项最大数。 + - `minScore`:提升所需的最小加权分阈值。 + - `minRecallCount`:最小回忆次数阈值。 - `minUniqueQueries`:最小不同查询数阈值。 - - `recencyHalfLifeDays`:最近性分数衰减到一半所需天数。默认:`14`。 - - `maxAgeDays`:允许被提升的每日笔记的可选最大年龄(天)。 - - `verboseLogging`:将详细的每次运行 dreaming 日志输出到普通 Gateway 网关日志流中。 -- 已启用的 Claude bundle 插件也可从 `settings.json` 贡献嵌入式 Pi 默认值;OpenClaw 会将其作为清洗后的智能体设置应用,而不是作为原始 OpenClaw 配置补丁。 -- `plugins.slots.memory`:选择活动 memory 插件 ID,或设为 `"none"` 以禁用 memory 插件。 -- `plugins.slots.contextEngine`:选择活动 context engine 插件 ID;默认是 `"legacy"`,除非你安装并选择了其他 engine。 + - `recencyHalfLifeDays`:新近度分数衰减为一半所需的天数。默认:`14`。 + - `maxAgeDays`:可选的每日笔记最大年龄(天),超过则不允许提升。 + - `verboseLogging`:将详细的每次运行 dreaming 日志输出到常规 Gateway 网关日志流。 +- 已启用的 Claude bundle 插件也可从 `settings.json` 提供嵌入式 Pi 默认值;OpenClaw 会将它们作为已净化的智能体设置应用,而不是原始 OpenClaw 配置补丁。 +- `plugins.slots.memory`:选择活跃的 memory 插件 ID,或使用 `"none"` 禁用 memory 插件。 +- `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 命令,而不是手动编辑。 参见 [Plugins](/zh-CN/tools/plugin)。 @@ -2664,8 +2640,8 @@ Base URL 不应包含 `/v1`(Anthropic 客户端会自行追加)。快捷方 evaluateEnabled: true, defaultProfile: "user", ssrfPolicy: { - dangerouslyAllowPrivateNetwork: true, // 默认的受信网络模式 - // allowPrivateNetwork: true, // 旧版别名 + dangerouslyAllowPrivateNetwork: true, // 默认的受信任网络模式 + // allowPrivateNetwork: true, // 旧别名 // hostnameAllowlist: ["*.example.com", "example.com"], // allowedHostnames: ["localhost"], }, @@ -2692,27 +2668,27 @@ Base URL 不应包含 `/v1`(Anthropic 客户端会自行追加)。快捷方 ``` - `evaluateEnabled: false` 会禁用 `act:evaluate` 和 `wait --fn`。 -- `ssrfPolicy.dangerouslyAllowPrivateNetwork` 在未设置时默认为 `true`(受信网络模型)。 -- 若需严格仅允许公网浏览器导航,请设置 `ssrfPolicy.dangerouslyAllowPrivateNetwork: false`。 -- 在严格模式下,远程 CDP profile 端点(`profiles.*.cdpUrl`)在可达性 / 发现检查期间也会受到相同的私有网络阻止。 -- `ssrfPolicy.allowPrivateNetwork` 仍作为旧版别名受支持。 -- 在严格模式下,使用 `ssrfPolicy.hostnameAllowlist` 和 `ssrfPolicy.allowedHostnames` 作为显式例外。 -- 远程 profile 为 attach-only(start / stop / reset 被禁用)。 +- `ssrfPolicy.dangerouslyAllowPrivateNetwork` 在未设置时默认是 `true`(受信任网络模型)。 +- 如需严格的仅公网浏览器导航,请设置 `ssrfPolicy.dangerouslyAllowPrivateNetwork: false`。 +- 在严格模式下,远程 CDP 配置端点(`profiles.*.cdpUrl`)在可达性/发现检查时也会受到同样的私有网络阻止策略约束。 +- `ssrfPolicy.allowPrivateNetwork` 仍然支持作为旧版别名。 +- 在严格模式下,请使用 `ssrfPolicy.hostnameAllowlist` 和 `ssrfPolicy.allowedHostnames` 作为显式例外。 +- 远程配置是仅附加模式(不支持 start/stop/reset)。 - `profiles.*.cdpUrl` 接受 `http://`、`https://`、`ws://` 和 `wss://`。 - 当你希望 OpenClaw 发现 `/json/version` 时,请使用 HTTP(S); - 如果你的提供商提供的是直接 DevTools WebSocket URL,请使用 WS(S)。 -- `existing-session` profiles 仅适用于主机,并使用 Chrome MCP 而不是 CDP。 -- `existing-session` profiles 可设置 `userDataDir`,以指向特定的 - Chromium 系浏览器 profile,例如 Brave 或 Edge。 -- `existing-session` profiles 保留当前 Chrome MCP 路由限制: - 使用 snapshot / ref 驱动的操作而不是 CSS 选择器定位、单文件上传 - hooks、无对话框超时覆盖、无 `wait --load networkidle`,并且不支持 - `responsebody`、PDF 导出、下载拦截或批量操作。 -- 本地托管的 `openclaw` profiles 会自动分配 `cdpPort` 和 `cdpUrl`;仅在远程 CDP 场景下显式设置 `cdpUrl`。 -- 自动检测顺序:默认浏览器(如果是 Chromium 系)→ Chrome → Brave → Edge → Chromium → Chrome Canary。 -- 控制服务:仅 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。 +- 控制服务:仅 loopback(端口由 `gateway.port` 推导,默认 `18791`)。 +- `extraArgs` 会为本地 Chromium 启动追加额外标志(例如 + `--disable-gpu`、窗口大小或调试标志)。 --- @@ -2724,14 +2700,14 @@ Base URL 不应包含 `/v1`(Anthropic 客户端会自行追加)。快捷方 seamColor: "#FF4500", assistant: { name: "OpenClaw", - avatar: "CB", // emoji、简短文本、图像 URL 或 data URI + avatar: "CB", // emoji、短文本、图像 URL 或 data URI }, }, } ``` - `seamColor`:原生应用 UI 外观的强调色(Talk Mode 气泡色调等)。 -- `assistant`:Control UI identity 覆盖。回退到活动智能体 identity。 +- `assistant`:Control UI 身份覆盖。默认回退到当前活跃智能体身份。 --- @@ -2747,7 +2723,7 @@ Base URL 不应包含 `/v1`(Anthropic 客户端会自行追加)。快捷方 mode: "token", // none | token | password | trusted-proxy token: "your-token", // password: "your-password", // 或 OPENCLAW_GATEWAY_PASSWORD - // trustedProxy: { userHeader: "x-forwarded-user" }, // 用于 mode=trusted-proxy;参见 /gateway/trusted-proxy-auth + // trustedProxy: { userHeader: "x-forwarded-user" }, // 供 mode=trusted-proxy 使用;参见 /gateway/trusted-proxy-auth allowTailscale: true, rateLimit: { maxAttempts: 10, @@ -2764,8 +2740,8 @@ Base URL 不应包含 `/v1`(Anthropic 客户端会自行追加)。快捷方 enabled: true, basePath: "/openclaw", // root: "dist/control-ui", - // allowedOrigins: ["https://control.example.com"], // 非 loopback Control UI 必需 - // dangerouslyAllowHostHeaderOriginFallback: false, // 危险的 Host-header origin 回退模式 + // allowedOrigins: ["https://control.example.com"], // 非 loopback Control UI 必填 + // dangerouslyAllowHostHeaderOriginFallback: false, // 危险的 Host 头来源回退模式 // allowInsecureAuth: false, // dangerouslyDisableDeviceAuth: false, }, @@ -2779,7 +2755,7 @@ Base URL 不应包含 `/v1`(Anthropic 客户端会自行追加)。快捷方 // 可选。默认 false。 allowRealIpFallback: false, tools: { - // 额外的 /tools/invoke HTTP deny + // 对 /tools/invoke HTTP 的额外 deny deny: ["browser"], // 从默认 HTTP deny 列表中移除工具 allow: ["gateway"], @@ -2798,38 +2774,40 @@ Base URL 不应包含 `/v1`(Anthropic 客户端会自行追加)。快捷方 -- `mode`:`local`(运行 gateway)或 `remote`(连接远程 gateway)。除非为 `local`,否则 Gateway 网关拒绝启动。 -- `port`:用于 WS + HTTP 的单一复用端口。优先级:`--port` > `OPENCLAW_GATEWAY_PORT` > `gateway.port` > `18789`。 +- `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 mode 值(`auto`、`loopback`、`lan`、`tailnet`、`custom`),不要使用 host 别名(`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` 的身份 headers(参见 [Trusted Proxy Auth](/zh-CN/gateway/trusted-proxy-auth))。该模式要求**非 loopback** 代理源;同主机 loopback 反向代理不满足 trusted-proxy 认证要求。 -- `gateway.auth.allowTailscale`:为 `true` 时,Tailscale Serve 的身份 headers 可满足 Control UI / WebSocket 认证(通过 `tailscale whois` 验证)。HTTP API 端点**不会**使用该 Tailscale header 认证;它们仍遵循 gateway 的普通 HTTP 认证模式。该免 token 流程假定 gateway 主机是受信的。当 `tailscale.mode = "serve"` 时,默认值为 `true`。 -- `gateway.auth.rateLimit`:可选的认证失败限速器。按客户端 IP 和认证作用域应用(共享 secret 和设备 token 会独立跟踪)。被阻止的尝试将返回 `429` + `Retry-After`。 - - 在异步 Tailscale Serve Control UI 路径上,同一 `{scope, clientIp}` 的失败尝试会在写入失败记录前被串行化。因此,同一客户端的并发错误尝试可能会在第二个请求时触发限速,而不是两个都以普通不匹配方式竞争通过。 - - `gateway.auth.rateLimit.exemptLoopback` 默认值为 `true`;若你有意希望 localhost 流量也被限速(用于测试环境或严格代理部署),请设为 `false`。 -- 来自浏览器 origin 的 WS 认证尝试始终会在禁用 loopback 豁免的情况下被限速(作为针对基于浏览器的 localhost 暴力破解的纵深防御)。 -- 在 loopback 上,这些来自浏览器 origin 的锁定会按规范化后的 `Origin` - 值隔离,因此某个 localhost origin 的重复失败不会自动 +- **旧版 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 暴力破解的纵深防御)。 +- 在 loopback 上,这些浏览器来源锁定会按标准化后的 `Origin` + 值相互隔离,因此来自一个 localhost origin 的重复失败不会自动 锁定另一个 origin。 - `tailscale.mode`:`serve`(仅 tailnet,loopback bind)或 `funnel`(公网,需要认证)。 -- `controlUi.allowedOrigins`:用于 Gateway 网关 WebSocket 连接的显式浏览器 origin allowlist。当预期浏览器客户端来自非 loopback origin 时为必需。 -- `controlUi.dangerouslyAllowHostHeaderOriginFallback`:危险模式,为有意依赖 Host-header origin 策略的部署启用 Host-header origin 回退。 -- `remote.transport`:`ssh`(默认)或 `direct`(ws/wss)。对于 `direct`,`remote.url` 必须为 `ws://` 或 `wss://`。 -- `OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1`:客户端侧的紧急覆盖,允许对受信私有网络 IP 使用明文 `ws://`;默认仍仅对 loopback 允许明文。 -- `gateway.remote.token` / `.password` 是远程客户端凭证字段。它们本身不会配置 gateway 认证。 -- `gateway.push.apns.relay.baseUrl`:用于官方 / TestFlight iOS 构建在将基于 relay 的注册发布到 gateway 后所使用的外部 APNs relay 的 base HTTPS URL。该 URL 必须与编译进 iOS 构建的 relay URL 一致。 -- `gateway.push.apns.relay.timeoutMs`:gateway 到 relay 的发送超时(毫秒)。默认值:`10000`。 -- 基于 relay 的注册会委托给特定 gateway identity。配对的 iOS 应用会获取 `gateway.identity.get`,将该 identity 包含进 relay 注册中,并将注册作用域的发送授权转发给 gateway。其他 gateway 无法复用该已存储注册。 +- `controlUi.allowedOrigins`:Gateway 网关 WebSocket 连接的显式浏览器来源允许列表。当预期浏览器客户端来自非 loopback 来源时必须设置。 +- `controlUi.dangerouslyAllowHostHeaderOriginFallback`:危险模式,为有意依赖 Host 头来源策略的部署启用 Host 头来源回退。 +- `remote.transport`:`ssh`(默认)或 `direct`(ws/wss)。对于 `direct`,`remote.url` 必须是 `ws://` 或 `wss://`。 +- `OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1`:客户端侧紧急放行覆盖,允许对受信任私有网络 IP 使用明文 `ws://`;默认仍仅允许 loopback 使用明文。 +- `gateway.remote.token` / `.password` 是远程客户端凭证字段。它们本身不会配置 Gateway 网关认证。 +- `gateway.push.apns.relay.baseUrl`:外部 APNs relay 的 base HTTPS URL,供官方/TestFlight iOS 构建在将 relay 支持的注册发布到 Gateway 网关后使用。此 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..healthMonitor.enabled`:在保留全局监视器启用的前提下,按渠道选择退出健康监视器重启。 -- `channels..accounts..healthMonitor.enabled`:针对多账号渠道的每账号覆盖。设置后,其优先于渠道级覆盖。 -- 仅当 `gateway.auth.*` 未设置时,本地 gateway 调用路径才可使用 `gateway.remote.*` 作为回退。 -- 如果 `gateway.auth.token` / `gateway.auth.password` 通过 SecretRef 显式配置但未解析,则解析会默认拒绝 \ No newline at end of file +- `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..healthMonitor.enabled`:每渠道选择退出健康监控重启,但保留全局监控启用。 +- `channels..accounts..healthMonitor.enabled`:多账号渠道的每账号覆盖。设置后优先于渠道级覆盖。 +- 本地 Gateway 网关调用路径仅在 `gateway.auth.*` 未设置时,才可将 `gateway.remote.*` 用作回退。 +- 如果 `gateway.auth.token` / `gateway.auth.password` 通过 SecretRef 显式配置但未解析成功,则解析会默认关闭(不会使用远程回退进行掩盖)。 +- `trustedProxies`:终止 TLS 或注入转发客户端头的反向代理 IP。仅列出你控制的代理。loopback 条目对同主机代理/本地检测设置(例如 Tailscale Serve 或本地反向代理)仍然有效,但它们**不会**让 loopback 请求有资格使用 `gateway.auth.mode: "trusted-proxy"`。 +- `allowRealIpFallback`:为 `true` 时,当缺少 `X-Forwarded-For` 时,Gateway 网关接受 `X \ No newline at end of file diff --git a/docs/zh-CN/gateway/doctor.md b/docs/zh-CN/gateway/doctor.md index e6db8cf63..aad6338ea 100644 --- a/docs/zh-CN/gateway/doctor.md +++ b/docs/zh-CN/gateway/doctor.md @@ -1,14 +1,14 @@ --- read_when: - - 添加或修改 doctor 迁移时 - - 引入破坏性配置变更时 + - 添加或修改 Doctor 迁移 + - 引入破坏性配置更改 summary: Doctor 命令:健康检查、配置迁移和修复步骤 title: Doctor x-i18n: - generated_at: "2026-04-05T17:48:14Z" + generated_at: "2026-04-05T18:14:18Z" model: gpt-5.4 provider: openai - source_hash: f20637d373c3b1be7c4a3d5424228908b5639cfded8ad5acb9c29f882d0f8d2b + source_hash: 6c0a15c522994552a1eef39206bed71fc5bf45746776372f24f31c101bfbd411 source_path: gateway/doctor.md workflow: 15 --- @@ -35,7 +35,7 @@ openclaw doctor --yes openclaw doctor --repair ``` -无需提示即可应用推荐修复(在安全情况下执行修复 + 重启)。 +应用推荐的修复而不提示(在安全的情况下执行修复 + 重启)。 ```bash openclaw doctor --repair --force @@ -47,16 +47,16 @@ openclaw doctor --repair --force openclaw doctor --non-interactive ``` -无提示运行,并且只应用安全迁移(配置规范化 + 磁盘状态移动)。会跳过需要人工确认的重启/服务/沙箱操作。 +在无提示模式下运行,并且只应用安全迁移(配置规范化 + 磁盘状态移动)。跳过需要人工确认的重启/服务/沙箱操作。 检测到旧版状态迁移时会自动运行。 ```bash openclaw doctor --deep ``` -扫描系统服务以查找额外的 Gateway 网关安装(launchd/systemd/schtasks)。 +扫描系统服务以查找额外的 Gateway 网关安装(`launchd`/`systemd`/`schtasks`)。 -如果你想在写入前先检查变更,请先打开配置文件: +如果你想在写入前先查看更改,请先打开配置文件: ```bash cat ~/.openclaw/openclaw.json @@ -64,67 +64,67 @@ cat ~/.openclaw/openclaw.json ## 它会做什么(摘要) -- 针对 git 安装的可选预检更新(仅交互模式)。 +- 为 git 安装提供可选的预检更新(仅交互模式)。 - UI 协议新鲜度检查(当协议 schema 更新时重建 Control UI)。 - 健康检查 + 重启提示。 -- Skills 状态摘要(可用/缺失/被阻止)和插件状态。 -- 旧版值的配置规范化。 -- 将旧版扁平 `talk.*` 字段迁移为 `talk.provider` + `talk.providers.` 的 Talk 配置迁移。 +- Skills 状态摘要(符合条件/缺失/被阻止)和插件状态。 +- 旧值的配置规范化。 +- 将旧版扁平 `talk.*` 字段迁移到 `talk.provider` + `talk.providers.` 的 Talk 配置迁移。 - 针对旧版 Chrome 扩展配置和 Chrome MCP 就绪情况的浏览器迁移检查。 - OpenCode 提供商覆盖警告(`models.providers.opencode` / `models.providers.opencode-go`)。 -- OpenAI Codex OAuth 配置档案的 OAuth TLS 前置条件检查。 -- 旧版磁盘状态迁移(sessions/agent 目录/WhatsApp 凭证)。 -- 旧版插件清单 contract 键迁移(`speechProviders`、`realtimeTranscriptionProviders`、`realtimeVoiceProviders`、`mediaUnderstandingProviders`、`imageGenerationProviders`、`videoGenerationProviders`、`webFetchProviders`、`webSearchProviders` → `contracts`)。 +- OpenAI Codex OAuth 配置的 OAuth TLS 前置条件检查。 +- 旧版磁盘状态迁移(会话/智能体目录/WhatsApp 认证)。 +- 旧版插件清单契约键迁移(`speechProviders`、`realtimeTranscriptionProviders`、`realtimeVoiceProviders`、`mediaUnderstandingProviders`、`imageGenerationProviders`、`videoGenerationProviders`、`webFetchProviders`、`webSearchProviders` → `contracts`)。 - 旧版 cron 存储迁移(`jobId`、`schedule.cron`、顶层 delivery/payload 字段、payload `provider`、简单的 `notify: true` webhook 回退任务)。 -- 会话锁文件检查和过时锁清理。 -- 状态完整性和权限检查(sessions、transcripts、state 目录)。 -- 本地运行时的配置文件权限检查(chmod 600)。 -- 模型凭证健康检查:检查 OAuth 过期情况,可刷新即将过期的 token,并报告 auth-profile 冷却/禁用状态。 -- 检测额外的工作区目录(`~/openclaw`)。 -- 启用沙箱隔离时的沙箱镜像修复。 +- 会话锁文件检查和过期锁清理。 +- 状态完整性和权限检查(会话、转录、状态目录)。 +- 本地运行时的配置文件权限检查(`chmod 600`)。 +- 模型认证健康状况:检查 OAuth 过期情况,可刷新即将过期的令牌,并报告 auth-profile 的冷却/禁用状态。 +- 检测额外工作区目录(`~/openclaw`)。 +- 在启用沙箱隔离时修复沙箱镜像。 - 旧版服务迁移和额外 Gateway 网关检测。 - Matrix 渠道旧版状态迁移(在 `--fix` / `--repair` 模式下)。 -- Gateway 网关运行时检查(服务已安装但未运行;缓存的 launchd 标签)。 +- Gateway 网关运行时检查(服务已安装但未运行;缓存的 `launchd` 标签)。 - 渠道状态警告(从正在运行的 Gateway 网关探测)。 -- Supervisor 配置审计(launchd/systemd/schtasks)及可选修复。 +- Supervisor 配置审计(`launchd`/`systemd`/`schtasks`),并可选择修复。 - Gateway 网关运行时最佳实践检查(Node 与 Bun、版本管理器路径)。 - Gateway 网关端口冲突诊断(默认 `18789`)。 -- 开放私信策略的安全警告。 -- 本地 token 模式的 Gateway 网关认证检查(在没有 token 来源时提供生成 token;不会覆盖 token SecretRef 配置)。 -- Linux 上的 systemd linger 检查。 -- 工作区 bootstrap 文件大小检查(上下文文件的截断/接近限制警告)。 +- 针对开放私信策略的安全警告。 +- 本地令牌模式下的 Gateway 网关认证检查(当没有令牌来源时提供生成令牌;不会覆盖令牌 SecretRef 配置)。 +- Linux 上的 `systemd linger` 检查。 +- 工作区引导文件大小检查(上下文文件的截断/接近限制警告)。 - Shell 补全状态检查和自动安装/升级。 -- 记忆搜索 embedding 提供商就绪情况检查(本地模型、远程 API 密钥或 QMD 二进制)。 -- 源码安装检查(pnpm workspace 不匹配、缺失 UI 资源、缺失 tsx 二进制)。 +- 记忆搜索嵌入提供商就绪检查(本地模型、远程 API 密钥或 `QMD` 二进制)。 +- 源码安装检查(`pnpm` 工作区不匹配、缺失 UI 资源、缺失 `tsx` 二进制)。 - 写入更新后的配置 + 向导元数据。 -## 详细行为与原理 +## 详细行为和原因说明 ### 0)可选更新(git 安装) -如果这是一个 git checkout,且 doctor 在交互模式下运行,它会先提供在运行 doctor 之前进行更新(fetch/rebase/build)的选项。 +如果这是一个 git 检出副本,并且 doctor 以交互模式运行,它会在运行 doctor 之前提供更新选项(fetch/rebase/build)。 ### 1)配置规范化 -如果配置中包含旧版值形态(例如没有渠道特定覆盖的 `messages.ackReaction`),doctor 会将其规范化为当前 schema。 +如果配置包含旧版值结构(例如 `messages.ackReaction` 没有特定于渠道的覆盖),doctor 会将其规范化为当前 schema。 这也包括旧版 Talk 扁平字段。当前公开的 Talk 配置是 `talk.provider` + `talk.providers.`。Doctor 会将旧的 `talk.voiceId` / `talk.voiceAliases` / `talk.modelId` / `talk.outputFormat` / -`talk.apiKey` 形态重写到提供商映射中。 +`talk.apiKey` 结构重写到提供商映射中。 ### 2)旧版配置键迁移 -当配置中包含已弃用键时,其他命令会拒绝运行,并要求你运行 +当配置包含已弃用键时,其他命令会拒绝运行,并要求你执行 `openclaw doctor`。 -Doctor 将会: +Doctor 会: -- 解释发现了哪些旧版键。 +- 说明发现了哪些旧版键。 - 显示它应用的迁移。 -- 用更新后的 schema 重写 `~/.openclaw/openclaw.json`。 +- 使用更新后的 schema 重写 `~/.openclaw/openclaw.json`。 -当 Gateway 网关在启动时检测到旧版配置格式,也会自动运行 doctor 迁移,因此无需手动干预即可修复过时配置。 +当 Gateway 网关在启动时检测到旧版配置格式,它也会自动运行 doctor 迁移,因此过时配置无需手动干预即可修复。 Cron 任务存储迁移由 `openclaw doctor --fix` 处理。 当前迁移包括: @@ -149,275 +149,330 @@ Cron 任务存储迁移由 `openclaw doctor --fix` 处理。 - `plugins.entries.voice-call.config.streaming.openaiApiKey|sttModel|silenceDurationMs|vadThreshold` → `plugins.entries.voice-call.config.streaming.providers.openai.*` - `bindings[].match.accountID` → `bindings[].match.accountId` -- 对于具有命名 `accounts` 但仍保留单账户顶层渠道值的渠道,将这些账户范围的值移动到为该渠道选定的提升账户中(大多数渠道使用 `accounts.default`;Matrix 可以保留现有的匹配命名/默认目标) +- 对于具有命名 `accounts`、但仍保留单账户顶层渠道值的渠道,将这些账户范围的值移动到为该渠道选择的提升账户中(大多数渠道使用 `accounts.default`;Matrix 可以保留现有匹配的命名/默认目标) - `identity` → `agents.list[].identity` - `agent.*` → `agents.defaults` + `tools.*`(tools/elevated/exec/sandbox/subagents) - `agent.model`/`allowedModels`/`modelAliases`/`modelFallbacks`/`imageModelFallbacks` → `agents.defaults.models` + `agents.defaults.model.primary/fallbacks` + `agents.defaults.imageModel.primary/fallbacks` - `browser.ssrfPolicy.allowPrivateNetwork` → `browser.ssrfPolicy.dangerouslyAllowPrivateNetwork` - `browser.profiles.*.driver: "extension"` → `"existing-session"` -- 移除 `browser.relayBindHost`(旧版扩展 relay 设置) +- 删除 `browser.relayBindHost`(旧版扩展 relay 设置) -Doctor 警告还包括多账户渠道的默认账户指导: +Doctor 警告还包括多账户渠道的默认账户指引: -- 如果配置了两个或更多 `channels..accounts` 条目,但没有 `channels..defaultAccount` 或 `accounts.default`,doctor 会警告回退路由可能选中意外的账户。 -- 如果 `channels..defaultAccount` 被设置为未知账户 ID,doctor 会发出警告并列出已配置的账户 ID。 +- 如果配置了两个或更多 `channels..accounts` 条目,但没有设置 `channels..defaultAccount` 或 `accounts.default`,doctor 会警告回退路由可能会选中意外的账户。 +- 如果 `channels..defaultAccount` 设置为未知账户 ID,doctor 会发出警告并列出已配置的账户 ID。 ### 2b)OpenCode 提供商覆盖 如果你手动添加了 `models.providers.opencode`、`opencode-zen` 或 `opencode-go`, 它会覆盖来自 `@mariozechner/pi-ai` 的内置 OpenCode 目录。 -这可能会强制模型走错误的 API,或将成本归零。Doctor 会发出警告,以便你移除该覆盖并恢复按模型的 API 路由 + 成本。 +这可能会把模型强制路由到错误的 API,或将成本清零。Doctor 会发出警告,以便你移除覆盖并恢复按模型进行的 API 路由 + 成本设置。 ### 2c)浏览器迁移和 Chrome MCP 就绪情况 -如果你的浏览器配置仍指向已移除的 Chrome 扩展路径,doctor 会将其规范化为当前的主机本地 Chrome MCP 附加模型: +如果你的浏览器配置仍然指向已移除的 Chrome 扩展路径,doctor +会将其规范化为当前基于主机本地的 Chrome MCP 附加模型: -- `browser.profiles.*.driver: "extension"` 会变为 `"existing-session"` +- `browser.profiles.*.driver: "extension"` 变为 `"existing-session"` - `browser.relayBindHost` 会被移除 -当你使用 `defaultProfile: "user"` 或已配置的 `existing-session` 配置档案时,doctor 还会审计主机本地 Chrome MCP 路径: +当你使用 `defaultProfile: +"user"` 或已配置的 `existing-session` 配置文件时,doctor 还会审计主机本地的 Chrome MCP 路径: -- 检查 Google Chrome 是否已安装在同一主机上,用于默认自动连接配置档案 -- 检查检测到的 Chrome 版本,并在其低于 Chrome 144 时发出警告 +- 检查默认自动连接配置文件所用的同一主机上是否安装了 Google Chrome +- 检查检测到的 Chrome 版本,并在低于 Chrome 144 时发出警告 - 提醒你在浏览器 inspect 页面中启用远程调试(例如 `chrome://inspect/#remote-debugging`、`brave://inspect/#remote-debugging`, 或 `edge://inspect/#remote-debugging`) -Doctor 无法替你启用 Chrome 侧设置。主机本地 Chrome MCP 仍然需要: +Doctor 无法替你启用 Chrome 侧设置。主机本地 Chrome MCP +仍然要求: -- Gateway 网关/节点主机上安装 144+ 的 Chromium 内核浏览器 +- Gateway 网关/节点主机上有一个 144+ 的 Chromium 内核浏览器 - 浏览器在本地运行 - 在该浏览器中启用远程调试 -- 在浏览器中批准首次附加授权提示 +- 在浏览器中批准首次附加的同意提示 -这里的就绪情况仅涉及本地附加前置条件。Existing-session 会保留当前 Chrome MCP 的路由限制;像 `responsebody`、PDF 导出、下载拦截和批处理操作这样的高级路由,仍然需要受管浏览器或原始 CDP 配置档案。 +这里的就绪情况仅涉及本地附加前提条件。`existing-session` 会保留 +当前 Chrome MCP 路由限制;像 `responsebody`、PDF +导出、下载拦截和批量操作等高级路由,仍然需要受管浏览器 +或原始 CDP 配置文件。 -此检查**不**适用于 Docker、沙箱、remote-browser 或其他无头流程。这些流程将继续使用原始 CDP。 +此检查**不**适用于 Docker、沙箱、remote-browser 或其他 +无头流程。这些流程会继续使用原始 CDP。 ### 2d)OAuth TLS 前置条件 -当配置了 OpenAI Codex OAuth 配置档案时,doctor 会探测 OpenAI 授权端点,以验证本地 Node/OpenSSL TLS 栈是否能够验证证书链。如果探测因证书错误失败(例如 `UNABLE_TO_GET_ISSUER_CERT_LOCALLY`、证书过期或自签名证书),doctor 会输出特定平台的修复指导。在 macOS 上,如果使用的是 Homebrew Node,修复方式通常是 `brew postinstall ca-certificates`。使用 `--deep` 时,即使 Gateway 网关健康,该探测也会运行。 +当配置了 OpenAI Codex OAuth 配置文件时,doctor 会探测 OpenAI +授权端点,以验证本地 Node/OpenSSL TLS 栈是否可以校验证书链。如果探测因证书错误失败(例如 +`UNABLE_TO_GET_ISSUER_CERT_LOCALLY`、证书过期或自签名证书),doctor 会打印特定于平台的修复指引。在使用 Homebrew Node 的 macOS 上, +修复通常是 `brew postinstall ca-certificates`。使用 `--deep` 时, +即使 Gateway 网关健康,此探测也会运行。 ### 3)旧版状态迁移(磁盘布局) -Doctor 可以将较旧的磁盘布局迁移到当前结构: +Doctor 可以将旧版磁盘布局迁移到当前结构: -- Sessions 存储 + transcripts: +- 会话存储 + 转录: - 从 `~/.openclaw/sessions/` 到 `~/.openclaw/agents//sessions/` -- Agent 目录: +- 智能体目录: - 从 `~/.openclaw/agent/` 到 `~/.openclaw/agents//agent/` -- WhatsApp 凭证状态(Baileys): - - 从旧版 `~/.openclaw/credentials/*.json`(`oauth.json` 除外) +- WhatsApp 认证状态(Baileys): + - 从旧版 `~/.openclaw/credentials/*.json`(不包括 `oauth.json`) - 到 `~/.openclaw/credentials/whatsapp//...`(默认账户 ID:`default`) -这些迁移尽力而为且是幂等的;如果它保留了任何旧版文件夹作为备份,doctor 会发出警告。Gateway 网关/CLI 在启动时也会自动迁移旧版 sessions + agent 目录,因此历史记录/凭证/模型会落到按智能体划分的路径中,而无需手动运行 doctor。WhatsApp 凭证有意仅通过 `openclaw doctor` 迁移。Talk 提供商/提供商映射规范化现在会按结构相等性比较,因此仅键顺序差异不会再触发重复的无操作 `doctor --fix` 更改。 +这些迁移是尽力而为且幂等的;doctor 会在留下任何旧版文件夹作为备份时发出警告。Gateway 网关/CLI 也会在启动时自动迁移旧版会话 + 智能体目录,因此历史记录/认证/模型会进入每个智能体路径,而无需手动运行 doctor。WhatsApp 认证则有意只通过 `openclaw doctor` 迁移。Talk provider/provider-map 规范化现在按结构相等进行比较,因此仅键顺序不同的差异不再触发重复的无操作 `doctor --fix` 更改。 ### 3a)旧版插件清单迁移 -Doctor 会扫描所有已安装插件清单中的已弃用顶层能力键 -(`speechProviders`、`realtimeTranscriptionProviders`、 +Doctor 会扫描所有已安装的插件清单,查找已弃用的顶层能力 +键(`speechProviders`、`realtimeTranscriptionProviders`、 `realtimeVoiceProviders`、`mediaUnderstandingProviders`、 `imageGenerationProviders`、`videoGenerationProviders`、`webFetchProviders`、 -`webSearchProviders`)。发现后,它会提供将其移入 `contracts` -对象并原地重写清单文件的选项。该迁移是幂等的; -如果 `contracts` 键中已经有相同值,就会移除旧版键而不重复数据。 +`webSearchProviders`)。找到后,它会提供将这些键移动到 `contracts` +对象中的选项,并原地重写清单文件。此迁移是幂等的; +如果 `contracts` 键中已存在相同值,则会移除旧版键, +而不会重复数据。 ### 3b)旧版 cron 存储迁移 Doctor 还会检查 cron 任务存储(默认是 `~/.openclaw/cron/jobs.json`, -若被覆盖则使用 `cron.store`)中调度器仍为兼容性而接受的旧任务形态。 +或在覆盖时使用 `cron.store`),查找调度器仍出于兼容性而接受的旧任务结构。 -当前的 cron 清理包括: +当前 cron 清理包括: - `jobId` → `id` - `schedule.cron` → `schedule.expr` - 顶层 payload 字段(`message`、`model`、`thinking`、...)→ `payload` - 顶层 delivery 字段(`deliver`、`channel`、`to`、`provider`、...)→ `delivery` -- payload 中的 `provider` delivery 别名 → 显式 `delivery.channel` -- 简单的旧版 `notify: true` webhook 回退任务 → 显式 `delivery.mode="webhook"` 且 `delivery.to=cron.webhook` +- payload `provider` delivery 别名 → 显式 `delivery.channel` +- 简单的旧版 `notify: true` webhook 回退任务 → 显式 `delivery.mode="webhook"`,并配合 `delivery.to=cron.webhook` -Doctor 仅会在能够不改变行为的情况下自动迁移 `notify: true` 任务。 -如果某个任务同时包含旧版 notify 回退和现有的非 webhook delivery 模式,doctor 会发出警告,并将该任务留待手动检查。 +Doctor 仅在能够不改变行为的情况下自动迁移 `notify: true` 任务。 +如果某个任务将旧版 notify 回退与现有 +非 webhook delivery 模式结合使用,doctor 会发出警告,并将该任务留给人工审查。 ### 3c)会话锁清理 -Doctor 会扫描每个智能体会话目录中的过时写锁文件——这些文件是在会话异常退出时遗留的。对于找到的每个锁文件,它会报告: -路径、PID、该 PID 是否仍存活、锁的存在时间,以及它是否被视为过时(PID 已死或超过 30 分钟)。在 `--fix` / `--repair` -模式下,它会自动删除过时锁文件;否则会输出说明,并指示你使用 `--fix` 重新运行。 +Doctor 会扫描每个智能体会话目录中是否存在过期写锁文件——即会话异常退出后遗留的文件。对于找到的每个锁文件,它会报告: +路径、PID、该 PID 是否仍然存活、锁文件存在时长,以及它是否 +被视为过期(PID 已死或存在时间超过 30 分钟)。在 `--fix` / `--repair` +模式下,它会自动移除过期锁文件;否则它会打印说明,并指示你使用 `--fix` 重新运行。 ### 4)状态完整性检查(会话持久化、路由和安全) -状态目录是运行系统的大脑中枢。如果它消失了,你将丢失 -sessions、凭证、日志和配置(除非你在别处有备份)。 +状态目录是运行中的中枢神经。如果它消失了,你会失去 +会话、凭证、日志和配置(除非你在其他地方有备份)。 Doctor 会检查: -- **状态目录缺失**:警告灾难性的状态丢失,提示重新创建目录,并提醒你它无法恢复丢失的数据。 -- **状态目录权限**:验证是否可写;提供修复权限的选项 +- **状态目录缺失**:警告灾难性的状态丢失,提示重新创建 + 目录,并提醒你它无法恢复缺失数据。 +- **状态目录权限**:验证可写性;提供修复权限选项 (并在检测到所有者/组不匹配时给出 `chown` 提示)。 - **macOS 云同步状态目录**:当状态解析到 iCloud Drive (`~/Library/Mobile Documents/com~apple~CloudDocs/...`)或 - `~/Library/CloudStorage/...` 下时发出警告,因为同步支持路径可能导致更慢的 I/O 以及锁/同步竞争。 + `~/Library/CloudStorage/...` 下时发出警告,因为基于同步的路径可能导致更慢的 I/O + 和锁/同步竞争。 - **Linux SD 或 eMMC 状态目录**:当状态解析到 `mmcblk*` - 挂载源时发出警告,因为基于 SD 或 eMMC 的随机 I/O 在会话和凭证写入场景中可能更慢且磨损更快。 -- **会话目录缺失**:`sessions/` 和会话存储目录是持久化历史记录并避免 `ENOENT` 崩溃所必需的。 -- **Transcript 不匹配**:当最近的会话条目缺少 transcript 文件时发出警告。 -- **主会话“单行 JSONL”**:当主 transcript 只有一行时标记出来(历史记录没有持续累积)。 -- **多个状态目录**:当多个主目录下存在多个 `~/.openclaw` 文件夹,或 `OPENCLAW_STATE_DIR` 指向其他位置时发出警告(历史记录可能在多个安装间分裂)。 -- **远程模式提醒**:如果 `gateway.mode=remote`,doctor 会提醒你在远程主机上运行它(状态存储在那里)。 -- **配置文件权限**:如果 `~/.openclaw/openclaw.json` 对组/全局可读,则发出警告,并提供将权限收紧到 `600` 的选项。 + 挂载源时发出警告,因为基于 SD 或 eMMC 的随机 I/O 在会话和凭证写入场景下可能更慢且磨损更快。 +- **会话目录缺失**:`sessions/` 和会话存储目录是 + 持久化历史并避免 `ENOENT` 崩溃所必需的。 +- **转录不匹配**:当最近的会话条目缺少 + 转录文件时发出警告。 +- **主会话“单行 JSONL”**:当主转录只有一行时标记出来(历史未持续累积)。 +- **多个状态目录**:当不同主目录下存在多个 `~/.openclaw` 文件夹, + 或 `OPENCLAW_STATE_DIR` 指向其他位置时发出警告(历史记录可能在不同安装之间分裂)。 +- **远程模式提醒**:如果 `gateway.mode=remote`,doctor 会提醒你在远程主机上运行它 + (状态存储在那里)。 +- **配置文件权限**:如果 `~/.openclaw/openclaw.json` 可被 + 组/所有用户读取,则会发出警告,并提供将权限收紧为 `600` 的选项。 -### 5)模型凭证健康检查(OAuth 过期) +### 5)模型认证健康状况(OAuth 过期) -Doctor 会检查凭证存储中的 OAuth 配置档案,在 token 即将过期/已过期时发出警告,并可在安全时刷新它们。如果 Anthropic -OAuth/token 配置档案已过时,它会建议使用 Anthropic API 密钥或旧版 Anthropic setup-token 路径。 +Doctor 会检查认证存储中的 OAuth 配置文件,在令牌 +即将过期/已过期时发出警告,并可在安全的情况下刷新它们。如果 Anthropic +OAuth/令牌配置文件已过期,它会建议使用 Anthropic API 密钥或旧版 +Anthropic setup-token 路径。 刷新提示仅在交互模式(TTY)下出现;`--non-interactive` 会跳过刷新尝试。 -Doctor 还会检测已移除的 Anthropic Claude CLI 旧状态。如果旧的 +Doctor 还会检测过期且已移除的 Anthropic Claude CLI 状态。如果旧的 `anthropic:claude-cli` 凭证字节仍存在于 `auth-profiles.json` 中, -doctor 会将其转换回 Anthropic token/OAuth 配置档案,并重写过时的 -`claude-cli/...` 模型引用以及 `agents.defaults.cliBackends.claude-cli`。 -如果这些字节已不存在,doctor 会移除过时配置并输出恢复命令。 +doctor 会将其转换回 Anthropic 令牌/OAuth 配置文件,并重写 +过期的 `claude-cli/...` 模型引用。 +如果这些字节已不存在,doctor 会移除过期配置并打印恢复 +命令。 -Doctor 还会报告由于以下原因而暂时不可用的 auth profiles: +Doctor 还会报告由于以下原因而暂时不可用的 auth profile: -- 短期冷却(速率限制/超时/凭证失败) -- 较长时间禁用(计费/额度失败) +- 短期冷却(限流/超时/认证失败) +- 长期禁用(账单/余额失败) -### 6)Hooks 模型校验 +### 6)Hooks 模型验证 -如果设置了 `hooks.gmail.model`,doctor 会根据目录和允许列表验证模型引用,并在其无法解析或不被允许时发出警告。 +如果设置了 `hooks.gmail.model`,doctor 会根据目录和 allowlist 验证模型引用,并在它无法解析或不被允许时发出警告。 ### 7)沙箱镜像修复 -启用沙箱隔离时,doctor 会检查 Docker 镜像,并在当前镜像缺失时提供构建或切换到旧版名称的选项。 +当启用沙箱隔离时,doctor 会检查 Docker 镜像,并在当前镜像缺失时提供构建或切换到旧版名称的选项。 ### 7b)内置插件运行时依赖 -Doctor 会验证内置插件运行时依赖(例如 Discord 插件运行时包)是否存在于 OpenClaw 安装根目录中。 +Doctor 会验证内置插件运行时依赖(例如 +Discord 插件运行时包)是否存在于 OpenClaw 安装根目录中。 如果缺失,doctor 会报告这些包,并在 `openclaw doctor --fix` / `openclaw doctor --repair` 模式下安装它们。 ### 8)Gateway 网关服务迁移和清理提示 -Doctor 会检测旧版 Gateway 网关服务(launchd/systemd/schtasks),并提供移除它们以及使用当前 Gateway 网关端口安装 OpenClaw 服务的选项。它还可以扫描额外的类似 Gateway 网关服务并输出清理提示。 -按配置档案命名的 OpenClaw Gateway 网关服务被视为一等公民,不会被标记为“额外”。 +Doctor 会检测旧版 Gateway 网关服务(`launchd`/`systemd`/`schtasks`),并 +提供移除它们及使用当前 Gateway 网关端口安装 OpenClaw 服务的选项。它还可以扫描额外的类 Gateway 网关服务并打印清理提示。 +按 profile 命名的 OpenClaw Gateway 网关服务被视为一等公民,不会 +被标记为“额外”服务。 ### 8b)启动 Matrix 迁移 当 Matrix 渠道账户存在待处理或可执行的旧版状态迁移时, -doctor(在 `--fix` / `--repair` 模式下)会先创建迁移前快照,然后运行尽力而为的迁移步骤:旧版 Matrix 状态迁移和旧版加密状态准备。这两个步骤都不是致命的;错误会被记录,启动会继续。在只读模式下(不带 `--fix` 的 `openclaw doctor`),此检查会被完全跳过。 +doctor(在 `--fix` / `--repair` 模式下)会先创建迁移前快照,然后 +运行尽力而为的迁移步骤:旧版 Matrix 状态迁移和旧版 +加密状态准备。这两个步骤都不是致命的;错误会被记录,启动会继续进行。在只读模式下(不带 `--fix` 的 `openclaw doctor`),此检查 +会被完全跳过。 ### 9)安全警告 -当某个提供商对私信开放但没有允许列表,或某项策略以危险方式配置时,doctor 会发出警告。 +当某个提供商对私信开放却没有 allowlist,或 +某项策略以危险方式配置时,doctor 会发出警告。 ### 10)systemd linger(Linux) -如果作为 systemd 用户服务运行,doctor 会确保已启用 lingering,以便 Gateway 网关在注销后仍保持运行。 +如果作为 `systemd` 用户服务运行,doctor 会确保启用了 lingering,以便 +Gateway 网关在注销后仍保持运行。 ### 11)工作区状态(Skills、插件和旧版目录) -Doctor 会输出默认智能体的工作区状态摘要: +Doctor 会为默认智能体打印工作区状态摘要: -- **Skills 状态**:统计可用、缺少要求、和被允许列表阻止的 Skills 数量。 -- **旧版工作区目录**:当 `~/openclaw` 或其他旧版工作区目录与当前工作区并存时发出警告。 -- **插件状态**:统计已加载/已禁用/出错的插件数量;列出所有出错插件的插件 ID;报告内置插件能力。 +- **Skills 状态**:统计符合条件、缺失要求和被 allowlist 阻止的 Skills 数量。 +- **旧版工作区目录**:当 `~/openclaw` 或其他旧版工作区目录 + 与当前工作区并存时发出警告。 +- **插件状态**:统计已加载/已禁用/出错的插件数量;列出出错插件的插件 ID; + 报告 bundle 插件能力。 - **插件兼容性警告**:标记与当前运行时存在兼容性问题的插件。 -- **插件诊断**:显示插件注册表在加载时发出的任何警告或错误。 +- **插件诊断**:呈现插件注册表在加载时发出的任何警告或错误。 -### 11b)Bootstrap 文件大小 +### 11b)引导文件大小 -Doctor 会检查工作区 bootstrap 文件(例如 `AGENTS.md`、 -`CLAUDE.md` 或其他注入的上下文文件)是否接近或超过配置的字符预算。它会报告每个文件的原始字符数与注入字符数、截断百分比、截断原因(`max/file` 或 `max/total`),以及总注入字符数占总预算的比例。当文件被截断或接近限制时,doctor 会给出调优 `agents.defaults.bootstrapMaxChars` -和 `agents.defaults.bootstrapTotalMaxChars` 的建议。 +Doctor 会检查工作区引导文件(例如 `AGENTS.md`、 +`CLAUDE.md` 或其他注入的上下文文件)是否接近或超过已配置的 +字符预算。它会报告每个文件的原始字符数与注入字符数、截断 +百分比、截断原因(`max/file` 或 `max/total`),以及总注入 +字符数占总预算的比例。当文件被截断或接近 +限制时,doctor 会打印有关调整 `agents.defaults.bootstrapMaxChars` +和 `agents.defaults.bootstrapTotalMaxChars` 的提示。 ### 11c)Shell 补全 -Doctor 会检查当前 shell 是否已安装 Tab 补全 -(zsh、bash、fish 或 PowerShell): +Doctor 会检查当前 shell +(zsh、bash、fish 或 PowerShell)是否已安装 tab 补全: -- 如果 shell 配置文件使用了较慢的动态补全模式 - (`source <(openclaw completion ...)`),doctor 会将其升级为更快的缓存文件变体。 +- 如果 shell 配置文件使用较慢的动态补全模式 + (`source <(openclaw completion ...)`),doctor 会将其升级为更快的 + 缓存文件变体。 - 如果补全已在配置文件中配置,但缓存文件缺失, doctor 会自动重新生成缓存。 -- 如果完全未配置补全,它会提示你安装 +- 如果完全未配置补全,它会提示进行安装 (仅交互模式;使用 `--non-interactive` 时跳过)。 运行 `openclaw completion --write-state` 可手动重新生成缓存。 -### 12)Gateway 网关认证检查(本地 token) +### 12)Gateway 网关认证检查(本地令牌) -Doctor 会检查本地 Gateway 网关 token 认证的就绪情况。 +Doctor 会检查本地 Gateway 网关令牌认证的就绪情况。 -- 如果 token 模式需要 token 且没有 token 来源,doctor 会提供生成一个 token 的选项。 -- 如果 `gateway.auth.token` 由 SecretRef 管理但不可用,doctor 会发出警告,且不会用明文覆盖它。 -- 仅当未配置 token SecretRef 时,`openclaw doctor --generate-gateway-token` 才会强制生成。 +- 如果令牌模式需要令牌且没有令牌来源,doctor 会提供生成令牌的选项。 +- 如果 `gateway.auth.token` 由 SecretRef 管理但不可用,doctor 会发出警告,并且不会用明文覆盖它。 +- `openclaw doctor --generate-gateway-token` 仅在未配置任何令牌 SecretRef 时强制生成。 -### 12b)只读的 SecretRef 感知修复 +### 12b)只读 SecretRef 感知修复 -某些修复流程需要检查已配置的凭证,而不能削弱运行时快速失败行为。 +某些修复流程需要检查已配置的凭证,同时又不能削弱运行时快速失败行为。 -- `openclaw doctor --fix` 现在对目标配置修复使用与 status 系列命令相同的只读 SecretRef 摘要模型。 +- `openclaw doctor --fix` 现在使用与状态类命令相同的只读 SecretRef 摘要模型,用于有针对性的配置修复。 - 示例:Telegram `allowFrom` / `groupAllowFrom` 的 `@username` 修复会在可用时尝试使用已配置的机器人凭证。 -- 如果 Telegram bot token 通过 SecretRef 配置,但在当前命令路径中不可用,doctor 会报告该凭证已配置但不可用,并跳过自动解析,而不是崩溃或错误地将 token 报告为缺失。 +- 如果 Telegram 机器人令牌是通过 SecretRef 配置的,但在当前命令路径中不可用,doctor 会报告该凭证“已配置但不可用”,并跳过自动解析,而不是崩溃或误报令牌缺失。 ### 13)Gateway 网关健康检查 + 重启 -Doctor 会运行健康检查,并在 Gateway 网关看起来不健康时提供重启选项。 +Doctor 会运行健康检查,并在 Gateway 网关看起来 +不健康时提供重启选项。 ### 13b)记忆搜索就绪情况 -Doctor 会检查为默认智能体配置的记忆搜索 embedding 提供商是否已就绪。其行为取决于已配置的后端和提供商: +Doctor 会检查为默认智能体配置的记忆搜索嵌入提供商是否已就绪。 +具体行为取决于已配置的后端和提供商: - **QMD 后端**:探测 `qmd` 二进制是否可用且可启动。 - 如果不能,则输出修复指导,包括 npm 包和手动二进制路径选项。 -- **显式本地提供商**:检查本地模型文件或已识别的远程/可下载模型 URL。 - 如果缺失,则建议切换到远程提供商。 -- **显式远程提供商**(`openai`、`voyage` 等):验证环境中或凭证存储中是否存在 API 密钥。若缺失,则输出可执行的修复提示。 -- **自动提供商**:先检查本地模型可用性,再按自动选择顺序尝试每个远程提供商。 + 如果不可用,会打印修复指引,包括 npm 包和手动二进制路径选项。 +- **显式本地提供商**:检查本地模型文件或已识别的 + 远程/可下载模型 URL 是否存在。如果缺失,则建议切换到远程提供商。 +- **显式远程提供商**(`openai`、`voyage` 等):验证环境中或认证存储中是否存在 API 密钥。 + 如果缺失,会打印可执行的修复提示。 +- **自动提供商**:先检查本地模型可用性,然后按自动选择顺序尝试每个远程 + 提供商。 -当 Gateway 网关探测结果可用时(检查时 Gateway 网关是健康的),doctor 会将其结果与 CLI 可见配置交叉比对,并指出任何不一致之处。 +当 Gateway 网关探测结果可用时(即检查时 Gateway 网关健康),doctor 会将其与 CLI 可见配置交叉对照,并指出 +任何差异。 -使用 `openclaw memory status --deep` 可在运行时验证 embedding 就绪情况。 +使用 `openclaw memory status --deep` 在运行时验证嵌入就绪情况。 ### 14)渠道状态警告 -如果 Gateway 网关健康,doctor 会运行渠道状态探测,并报告带有建议修复方式的警告。 +如果 Gateway 网关健康,doctor 会运行渠道状态探测,并报告 +附带建议修复方法的警告。 ### 15)Supervisor 配置审计 + 修复 -Doctor 会检查已安装的 supervisor 配置(launchd/systemd/schtasks)是否缺少或落后于当前默认值(例如 systemd network-online 依赖项和重启延迟)。当发现不匹配时,它会建议更新,并可将服务文件/任务重写为当前默认值。 +Doctor 会检查已安装的 supervisor 配置(`launchd`/`systemd`/`schtasks`),查看 +是否缺少或过期了默认值(例如 `systemd` 的 `network-online` 依赖和 +重启延迟)。当发现不匹配时,它会 +建议更新,并可将服务文件/任务重写为当前默认值。 说明: -- `openclaw doctor` 会在重写 supervisor 配置前进行提示。 +- `openclaw doctor` 会在重写 supervisor 配置前提示确认。 - `openclaw doctor --yes` 会接受默认修复提示。 -- `openclaw doctor --repair` 会无提示应用推荐修复。 +- `openclaw doctor --repair` 会在无提示的情况下应用推荐修复。 - `openclaw doctor --repair --force` 会覆盖自定义 supervisor 配置。 -- 如果 token 认证需要 token,且 `gateway.auth.token` 由 SecretRef 管理,doctor 的服务安装/修复会验证 SecretRef,但不会将解析后的明文 token 值持久化到 supervisor 服务环境元数据中。 -- 如果 token 认证需要 token,而已配置的 token SecretRef 未解析,doctor 会阻止安装/修复路径,并提供可执行的指导。 +- 如果令牌认证需要令牌,而 `gateway.auth.token` 由 SecretRef 管理,doctor 在安装/修复服务时会验证 SecretRef,但不会将解析出的明文令牌值持久化到 supervisor 服务环境元数据中。 +- 如果令牌认证需要令牌,而配置的令牌 SecretRef 无法解析,doctor 会阻止安装/修复路径,并提供可执行的指引。 - 如果同时配置了 `gateway.auth.token` 和 `gateway.auth.password`,而 `gateway.auth.mode` 未设置,doctor 会阻止安装/修复,直到显式设置 mode。 -- 对于 Linux user-systemd 单元,doctor 的 token 漂移检查现在在比较服务认证元数据时会同时包含 `Environment=` 和 `EnvironmentFile=` 来源。 -- 你始终可以通过 `openclaw gateway install --force` 强制完整重写。 +- 对于 Linux user-systemd 单元,doctor 的令牌漂移检查现在在比较服务认证元数据时会同时包含 `Environment=` 和 `EnvironmentFile=` 来源。 +- 你始终可以通过 `openclaw gateway install --force` 强制执行完整重写。 ### 16)Gateway 网关运行时 + 端口诊断 -Doctor 会检查服务运行时(PID、上次退出状态),并在服务已安装但实际未运行时发出警告。它还会检查 Gateway 网关端口(默认 `18789`)上的端口冲突,并报告可能原因(Gateway 网关已在运行、SSH 隧道)。 +Doctor 会检查服务运行时(PID、上次退出状态),并在 +服务已安装但实际上未运行时发出警告。它还会检查 Gateway 网关端口 +(默认 `18789`)上的端口冲突,并报告可能原因(Gateway 网关已在运行、 +SSH 隧道)。 ### 17)Gateway 网关运行时最佳实践 -当 Gateway 网关服务运行在 Bun 上或运行在版本管理的 Node 路径 -(`nvm`、`fnm`、`volta`、`asdf` 等)时,doctor 会发出警告。WhatsApp + Telegram 渠道需要 Node,而版本管理器路径在升级后可能失效,因为服务不会加载你的 shell 初始化。Doctor 会在系统 Node 可用时提供迁移到系统 Node 安装的选项(Homebrew/apt/choco)。 +当 Gateway 网关服务运行在 Bun 或版本管理的 Node 路径 +(`nvm`、`fnm`、`volta`、`asdf` 等)上时,doctor 会发出警告。WhatsApp + Telegram 渠道需要 Node, +而版本管理器路径在升级后可能会失效,因为服务不会 +加载你的 shell 初始化。Doctor 会在可用时提供迁移到系统 Node 安装(Homebrew/apt/choco)的选项。 ### 18)配置写入 + 向导元数据 -Doctor 会持久化任何配置变更,并写入向导元数据以记录本次 doctor 运行。 +Doctor 会持久化所有配置更改,并写入向导元数据以记录 +doctor 运行。 ### 19)工作区提示(备份 + 记忆系统) -当工作区缺少记忆系统时,doctor 会提出建议;如果工作区尚未由 git 管理,它还会输出备份提示。 +当工作区缺少记忆系统时,doctor 会给出建议;如果工作区尚未处于 git 管理下,它还会打印备份提示。 -有关工作区结构和 git 备份(推荐使用私有 GitHub 或 GitLab)的完整指南,请参见 [/concepts/agent-workspace](/zh-CN/concepts/agent-workspace)。 +参见 [/concepts/agent-workspace](/zh-CN/concepts/agent-workspace) 了解有关 +工作区结构和 git 备份(推荐使用私有 GitHub 或 GitLab)的完整指南。 diff --git a/docs/zh-CN/help/faq.md b/docs/zh-CN/help/faq.md index abb898b7c..04b62af7d 100644 --- a/docs/zh-CN/help/faq.md +++ b/docs/zh-CN/help/faq.md @@ -1,39 +1,39 @@ --- read_when: - - 回答常见的设置、安装、新手引导或运行时支持问题 - - 在进行更深入调试之前分流用户报告的问题 -summary: 关于 OpenClaw 设置、配置和使用的常见问题 + - 回答常见的设置、安装、新手引导或运行时支持问题时 + - 在深入调试之前分流用户报告的问题时 +summary: 关于 OpenClaw 安装、配置和使用的常见问题解答 title: 常见问题 x-i18n: - generated_at: "2026-04-05T17:52:35Z" + generated_at: "2026-04-05T18:19:00Z" model: gpt-5.4 provider: openai - source_hash: f1e79991c3293477cadfd1bffa7c7457106ba178c343d3f8c60b7cbf79c85320 + source_hash: f1004466a417ae57373048f4353ab4040a5c567980542375fbf55ff93132de31 source_path: help/faq.md workflow: 15 --- # 常见问题 -针对真实世界部署场景(本地开发、VPS、多智能体、OAuth/API 密钥、模型故障转移)的快速回答和更深入的故障排除。有关运行时诊断,请参阅 [故障排除](/zh-CN/gateway/troubleshooting)。有关完整配置参考,请参阅 [配置](/zh-CN/gateway/configuration)。 +针对真实环境配置(本地开发、VPS、多智能体、OAuth/API 密钥、模型故障切换)的快速解答与更深入的故障排除。有关运行时诊断,请参见 [故障排除](/zh-CN/gateway/troubleshooting)。有关完整配置参考,请参见 [Configuration](/zh-CN/gateway/configuration)。 -## 最初的六十秒:如果出了问题 +## 如果出了问题,最初的六十秒 -1. **快速状态(首次检查)** +1. **快速状态(第一项检查)** ```bash openclaw status ``` - 快速本地摘要:操作系统 + 更新、Gateway 网关 / 服务可达性、智能体 / 会话、提供商配置 + 运行时问题(当 Gateway 网关可达时)。 + 快速本地摘要:操作系统 + 更新、Gateway 网关/服务可达性、智能体/会话、提供商配置 + 运行时问题(当 Gateway 网关可达时)。 -2. **可粘贴的报告(可安全分享)** +2. **可直接粘贴的报告(可安全分享)** ```bash openclaw status --all ``` - 只读诊断,包含日志尾部(token 已脱敏)。 + 只读诊断,附带日志尾部(令牌已打码)。 3. **守护进程 + 端口状态** @@ -41,7 +41,7 @@ x-i18n: openclaw gateway status ``` - 显示 supervisor 运行状态与 RPC 可达性、探测目标 URL,以及服务可能使用了哪份配置。 + 显示监督器运行时与 RPC 可达性、探测目标 URL,以及服务可能使用的是哪个配置。 4. **深度探测** @@ -49,22 +49,22 @@ x-i18n: openclaw status --deep ``` - 运行实时 Gateway 网关健康探测,包括在支持时的渠道探测 - (需要 Gateway 网关可达)。请参阅 [健康检查](/zh-CN/gateway/health)。 + 运行实时 Gateway 网关健康探测,包括支持时的渠道探测 + (要求 Gateway 网关可达)。参见 [Health](/zh-CN/gateway/health)。 -5. **跟踪最新日志** +5. **查看最新日志尾部** ```bash openclaw logs --follow ``` - 如果 RPC 不可用,则退回到: + 如果 RPC 不可用,退回到: ```bash tail -f "$(ls -t /tmp/openclaw/openclaw-*.log | head -1)" ``` - 文件日志与服务日志分开;请参阅 [日志记录](/zh-CN/logging) 和 [故障排除](/zh-CN/gateway/troubleshooting)。 + 文件日志与服务日志是分开的;参见 [Logging](/zh-CN/logging) 和 [故障排除](/zh-CN/gateway/troubleshooting)。 6. **运行 Doctor(修复)** @@ -72,7 +72,7 @@ x-i18n: openclaw doctor ``` - 修复 / 迁移配置 / 状态并运行健康检查。请参阅 [Doctor](/zh-CN/gateway/doctor)。 + 修复/迁移配置与状态 + 运行健康检查。参见 [Doctor](/zh-CN/gateway/doctor)。 7. **Gateway 网关快照** @@ -81,34 +81,39 @@ x-i18n: openclaw health --verbose # 出错时显示目标 URL + 配置路径 ``` - 向正在运行的 Gateway 网关请求完整快照(仅 WS)。请参阅 [健康检查](/zh-CN/gateway/health)。 + 向正在运行的 Gateway 网关请求完整快照(仅 WS)。参见 [Health](/zh-CN/gateway/health)。 -## 快速开始和首次运行设置 +## 快速开始与首次运行设置 - - 使用一个能**看到你的机器**的本地 AI 智能体。这比去 Discord 提问有效得多,因为大多数“我卡住了”的情况都是**本地配置或环境问题**,远程协助者无法直接检查。 + + 使用一个能够**看见你的机器**的本地 AI 智能体。这比去 Discord 里求助有效得多, + 因为大多数“我卡住了”的情况其实都是**本地配置或环境问题**, + 远程协助者无法直接检查。 - - **Claude Code**:[https://www.anthropic.com/claude-code/](https://www.anthropic.com/claude-code/) - - **OpenAI Codex**:[https://openai.com/codex/](https://openai.com/codex/) + - **Claude Code**: [https://www.anthropic.com/claude-code/](https://www.anthropic.com/claude-code/) + - **OpenAI Codex**: [https://openai.com/codex/](https://openai.com/codex/) - 这些工具可以读取仓库、运行命令、检查日志,并帮助修复你机器上的设置问题 - (PATH、服务、权限、认证文件)。请通过可修改的(git)安装方式向它们提供**完整源码检出**: + 这些工具可以读取仓库、运行命令、检查日志,并帮助修复你机器级别的 + 设置问题(PATH、服务、权限、认证文件)。通过可修改的(git)安装方式, + 将**完整源码检出**提供给它们: ```bash curl -fsSL https://openclaw.ai/install.sh | bash -s -- --install-method git ``` - 这会**从 git 检出**安装 OpenClaw,因此智能体可以读取代码和文档,并基于你正在运行的准确版本进行分析。你之后随时可以通过重新运行安装器并去掉 `--install-method git` 切回稳定版。 + 这会**从一个 git 检出目录**安装 OpenClaw,这样智能体就可以读取代码 + 文档, + 并针对你正在运行的确切版本进行分析。你随时都可以稍后 + 通过不带 `--install-method git` 重新运行安装器来切回稳定版。 - 提示:让智能体先**规划并监督**修复过程(逐步执行),然后只运行必要的 - 命令。这样变更更小,也更容易审计。 + 提示:让智能体先**规划并监督**修复过程(逐步进行),然后只执行 + 必要的命令。这样改动更小,也更容易审计。 - 如果你发现了真实的 bug 或修复,请提交一个 GitHub issue 或发送 PR: + 如果你发现了真实的 bug 或修复,请提交 GitHub issue 或发送 PR: [https://github.com/openclaw/openclaw/issues](https://github.com/openclaw/openclaw/issues) [https://github.com/openclaw/openclaw/pulls](https://github.com/openclaw/openclaw/pulls) - 从这些命令开始(在求助时分享输出): + 先从这些命令开始(求助时请分享输出): ```bash openclaw status @@ -118,137 +123,138 @@ x-i18n: 它们的作用: - - `openclaw status`:快速查看 Gateway 网关 / 智能体健康状态 + 基本配置。 + - `openclaw status`:快速查看 Gateway 网关/智能体健康状态 + 基本配置。 - `openclaw models status`:检查提供商认证 + 模型可用性。 - - `openclaw doctor`:验证并修复常见配置 / 状态问题。 + - `openclaw doctor`:验证并修复常见配置/状态问题。 其他有用的 CLI 检查:`openclaw status --all`、`openclaw logs --follow`、 `openclaw gateway status`、`openclaw health --verbose`。 - 快速调试循环:[最初的六十秒:如果出了问题](#first-60-seconds-if-something-is-broken)。 - 安装文档:[安装](/zh-CN/install)、[安装器标志](/zh-CN/install/installer)、[更新](/zh-CN/install/updating)。 + 快速调试循环:[如果出了问题,最初的六十秒](#如果出了问题最初的六十秒)。 + 安装文档:[Install](/zh-CN/install)、[Installer flags](/zh-CN/install/installer)、[Updating](/zh-CN/install/updating)。 - + 常见的 Heartbeat 跳过原因: - - `quiet-hours`:当前不在配置的 active-hours 时间窗口内 - - `empty-heartbeat-file`:`HEARTBEAT.md` 存在,但仅包含空白 / 只有标题的脚手架内容 - - `no-tasks-due`:`HEARTBEAT.md` 任务模式已启用,但还没有任何任务到达执行时间间隔 - - `alerts-disabled`:所有 Heartbeat 可见性都被禁用(`showOk`、`showAlerts` 和 `useIndicator` 全都关闭) + - `quiet-hours`:当前不在配置的活动时间窗口内 + - `empty-heartbeat-file`:`HEARTBEAT.md` 存在,但只包含空白/仅标题骨架内容 + - `no-tasks-due`:`HEARTBEAT.md` 任务模式已启用,但还没有任何任务到达执行间隔 + - `alerts-disabled`:所有 Heartbeat 可见性都被禁用(`showOk`、`showAlerts` 和 `useIndicator` 全部关闭) - 在任务模式下,只有在真正的 Heartbeat 运行完成后,任务的到期时间戳才会推进。 - 被跳过的运行不会将任务标记为已完成。 + 在任务模式下,只有在真正的 Heartbeat 运行完成后, + 到期时间戳才会推进。被跳过的运行不会将任务标记为已完成。 - 文档:[Heartbeat](/zh-CN/gateway/heartbeat)、[自动化与任务](/zh-CN/automation)。 + 文档:[Heartbeat](/zh-CN/gateway/heartbeat)、[Automation & Tasks](/zh-CN/automation)。 - - 仓库推荐从源码运行并使用新手引导: + + 该仓库推荐从源码运行并使用新手引导: ```bash curl -fsSL https://openclaw.ai/install.sh | bash openclaw onboard --install-daemon ``` - 向导也可以自动构建 UI 资源。新手引导完成后,你通常会在 **18789** 端口运行 Gateway 网关。 + 向导还可以自动构建 UI 资源。完成新手引导后,你通常会在 **18789** 端口运行 Gateway 网关。 - 从源码运行(贡献者 / 开发者): + 从源码开始(贡献者/开发者): ```bash git clone https://github.com/openclaw/openclaw.git cd openclaw pnpm install pnpm build - pnpm ui:build # 首次运行会自动安装 UI 依赖 + pnpm ui:build # 首次运行时会自动安装 UI 依赖 openclaw onboard ``` - 如果你还没有全局安装,可以通过 `pnpm openclaw onboard` 运行。 + 如果你还没有全局安装,可以通过 `pnpm openclaw onboard` 来运行。 - - 向导会在新手引导结束后立即使用一个干净的(不带 token 的)仪表板 URL 打开你的浏览器,并且也会在摘要中打印该链接。保持那个标签页打开;如果没有自动启动,就在同一台机器上复制 / 粘贴打印出来的 URL。 + + 向导会在新手引导结束后立即打开你的浏览器,并使用一个干净的(不带令牌的)仪表盘 URL,同时也会在摘要中打印该链接。请保持这个标签页打开;如果它没有自动启动,请在同一台机器上复制/粘贴打印出的 URL。 - + **Localhost(同一台机器):** - 打开 `http://127.0.0.1:18789/`。 - - 如果它要求 shared-secret 认证,请将已配置的 token 或 password 粘贴到 Control UI 设置中。 - - token 来源:`gateway.auth.token`(或 `OPENCLAW_GATEWAY_TOKEN`)。 - - password 来源:`gateway.auth.password`(或 `OPENCLAW_GATEWAY_PASSWORD`)。 - - 如果尚未配置 shared secret,可使用 `openclaw doctor --generate-gateway-token` 生成一个 token。 + - 如果它要求共享密钥认证,请将配置的令牌或密码粘贴到 Control UI 设置中。 + - 令牌来源:`gateway.auth.token`(或 `OPENCLAW_GATEWAY_TOKEN`)。 + - 密码来源:`gateway.auth.password`(或 `OPENCLAW_GATEWAY_PASSWORD`)。 + - 如果还没有配置共享密钥,可使用 `openclaw doctor --generate-gateway-token` 生成一个令牌。 - **不在 localhost 上:** + **不在 localhost:** - - **Tailscale Serve**(推荐):保持绑定到 loopback,运行 `openclaw gateway --tailscale serve`,打开 `https:///`。如果 `gateway.auth.allowTailscale` 为 `true`,身份标头会满足 Control UI/WebSocket 认证(无需粘贴 shared secret,前提是信任 Gateway 网关主机);HTTP API 仍然需要 shared-secret 认证,除非你明确使用 private-ingress `none` 或 trusted-proxy HTTP 认证。 - 来自同一客户端的并发错误 Serve 认证尝试会在 failed-auth 限流器记录之前被串行化,因此第二次错误重试时就可能已经显示 `retry later`。 - - **Tailnet 绑定**:运行 `openclaw gateway --bind tailnet --token ""`(或配置 password 认证),打开 `http://:18789/`,然后在仪表板设置中粘贴匹配的 shared secret。 - - **身份感知反向代理**:将 Gateway 网关保持在非 loopback 的 trusted proxy 后面,配置 `gateway.auth.mode: "trusted-proxy"`,然后打开代理 URL。 - - **SSH 隧道**:`ssh -N -L 18789:127.0.0.1:18789 user@host`,然后打开 `http://127.0.0.1:18789/`。通过隧道时仍适用 shared-secret 认证;如果被提示,请粘贴已配置的 token 或 password。 + - **Tailscale Serve**(推荐):保持绑定到 loopback,运行 `openclaw gateway --tailscale serve`,然后打开 `https:///`。如果 `gateway.auth.allowTailscale` 为 `true`,身份头部将满足 Control UI/WebSocket 认证(无需粘贴共享密钥,前提是信任 Gateway 网关主机);HTTP API 仍然需要共享密钥认证,除非你明确使用私有入口的 `none` 或 trusted-proxy HTTP 认证。 + 来自同一客户端的并发错误 Serve 认证尝试会先被串行化,然后失败认证限流器才会记录,因此第二次错误重试可能已经显示 `retry later`。 + - **Tailnet 绑定**:运行 `openclaw gateway --bind tailnet --token ""`(或配置密码认证),打开 `http://:18789/`,然后在仪表盘设置中粘贴匹配的共享密钥。 + - **具备身份感知的反向代理**:让 Gateway 网关继续位于一个非 loopback 的 trusted proxy 后面,配置 `gateway.auth.mode: "trusted-proxy"`,然后打开代理 URL。 + - **SSH 隧道**:`ssh -N -L 18789:127.0.0.1:18789 user@host`,然后打开 `http://127.0.0.1:18789/`。通过隧道时仍然适用共享密钥认证;如有提示,请粘贴配置的令牌或密码。 - 有关绑定模式和认证详情,请参阅 [仪表板](/web/dashboard) 和 [Web 界面](/web)。 + 关于绑定模式和认证详情,请参见 [Dashboard](/web/dashboard) 和 [Web surfaces](/web)。 - + 它们控制的是不同层级: - `approvals.exec`:将审批提示转发到聊天目标 - - `channels..execApprovals`:让该渠道充当 exec 审批的原生审批客户端 + - `channels..execApprovals`:使该渠道作为 exec 审批的原生审批客户端 - 主机 exec 策略仍然是真正的审批门槛。聊天配置只控制审批提示出现在哪里,以及人们可以如何响应。 + 主机 exec 策略仍然是真正的审批门槛。聊天配置只控制审批提示 + 出现在哪里,以及人们可以如何作答。 - 在大多数部署中,你**不**需要同时启用两者: + 在大多数配置中,你**不**需要两者都用: - - 如果该聊天已经支持命令和回复,则同一聊天中的 `/approve` 会通过共享路径工作。 - - 如果某个受支持的原生渠道能够安全推断 approver,OpenClaw 现在会在 `channels..execApprovals.enabled` 未设置或为 `"auto"` 时自动启用私信优先的原生审批。 - - 当原生审批卡片 / 按钮可用时,该原生 UI 是主路径;只有当工具结果表明聊天审批不可用,或手动审批是唯一可行路径时,智能体才应包含手动 `/approve` 命令。 - - 只有当提示也必须转发到其他聊天或显式运维房间时,才使用 `approvals.exec`。 - - 只有当你明确希望审批提示也发回原始房间 / 主题时,才使用 `channels..execApprovals.target: "channel"` 或 `"both"`。 - - 插件审批是另一套机制:默认使用同一聊天中的 `/approve`,可选地使用 `approvals.plugin` 转发,并且只有部分原生渠道还会在其上保留原生插件审批处理。 + - 如果聊天已经支持命令和回复,那么同一聊天中的 `/approve` 会通过共享路径工作。 + - 如果某个受支持的原生渠道可以安全推断审批人,OpenClaw 现在会在 `channels..execApprovals.enabled` 未设置或为 `"auto"` 时自动启用“私信优先”的原生审批。 + - 当原生审批卡片/按钮可用时,该原生 UI 是主路径;只有当工具结果表明聊天审批不可用,或者手动审批是唯一可行路径时,智能体才应附带手动 `/approve` 命令。 + - 仅当提示还必须转发到其他聊天或明确的运维房间时,才使用 `approvals.exec`。 + - 仅当你明确希望将审批提示发回原始房间/主题时,才使用 `channels..execApprovals.target: "channel"` 或 `"both"`。 + - 插件审批又是单独一套:它们默认使用同一聊天中的 `/approve`,可选 `approvals.plugin` 转发,而且只有部分原生渠道还会在此之上保留原生插件审批处理。 - 简单来说:转发用于路由,原生客户端配置用于更丰富的渠道特定 UX。 - 请参阅 [Exec 审批](/zh-CN/tools/exec-approvals)。 + 简单来说:转发用于路由,原生客户端配置用于提供更丰富的渠道特定用户体验。 + 参见 [Exec Approvals](/zh-CN/tools/exec-approvals)。 - - 需要 Node **>= 22**。推荐使用 `pnpm`。**不推荐**将 Bun 用于 Gateway 网关。 + + 需要 Node **>= 22**。推荐使用 `pnpm`。**不推荐**使用 Bun 来运行 Gateway 网关。 - - 可以。Gateway 网关很轻量——文档列出的要求是**512MB-1GB 内存**、**1 个核心**和约 **500MB** - 磁盘空间即可满足个人使用,并指出**Raspberry Pi 4 可以运行它**。 + + 可以。Gateway 网关很轻量——文档中列出的个人使用配置是 **512MB-1GB RAM**、**1 个核心** 和大约 **500MB** + 磁盘空间,并说明**Raspberry Pi 4 可以运行它**。 - 如果你想留出更多余量(日志、媒体、其他服务),**推荐 2GB**,但这 - 不是硬性最低要求。 + 如果你想留出更多余量(日志、媒体、其他服务),**推荐 2GB**, + 但这不是硬性最低要求。 - 提示:一个小型 Pi/VPS 就能承载 Gateway 网关,你还可以在笔记本 / 手机上配对**节点**,用于 - 本地屏幕 / 摄像头 / Canvas 或命令执行。请参阅 [节点](/zh-CN/nodes)。 + 提示:一个小型 Pi/VPS 可以托管 Gateway 网关,而你可以在笔记本/手机上配对**节点**, + 以提供本地屏幕/摄像头/canvas 或命令执行。参见 [Nodes](/zh-CN/nodes)。 - - 简短回答:可以运行,但要预期会有一些边角问题。 + + 简短回答:可以运行,但要预期会有一些粗糙边角。 - - 使用**64 位**操作系统,并保持 Node >= 22。 + - 使用 **64 位**操作系统,并保持 Node >= 22。 - 优先使用**可修改的(git)安装**,这样你可以查看日志并快速更新。 - - 先不要启用 channels/Skills,然后逐个添加。 - - 如果遇到奇怪的二进制问题,通常是**ARM 兼容性**问题。 + - 先不要启用渠道/Skills,然后一个个添加。 + - 如果你遇到奇怪的二进制问题,通常是 **ARM 兼容性**问题。 - 文档:[Linux](/zh-CN/platforms/linux)、[安装](/zh-CN/install)。 + 文档:[Linux](/zh-CN/platforms/linux)、[Install](/zh-CN/install)。 - - 该界面依赖 Gateway 网关可达且已认证。TUI 也会在第一次 hatch 时自动发送 - “Wake up, my friend!”。如果你看到这行文字但**没有任何回复** - 且 token 一直是 0,就说明智能体根本没有运行。 + + 这个界面依赖于 Gateway 网关可达并已认证。TUI 也会在首次 hatch 时自动发送 + “Wake up, my friend!”。如果你看到这行字却**没有回复**, + 并且令牌数一直为 0,说明智能体根本没有运行。 1. 重启 Gateway 网关: @@ -264,20 +270,20 @@ x-i18n: openclaw logs --follow ``` - 3. 如果仍然卡住,请运行: + 3. 如果仍然卡住,运行: ```bash openclaw doctor ``` - 如果 Gateway 网关是远程的,请确保隧道 / Tailscale 连接已建立,并且 UI - 指向了正确的 Gateway 网关。请参阅 [远程访问](/zh-CN/gateway/remote)。 + 如果 Gateway 网关是远程的,请确保隧道/Tailscale 连接正常, + 并且 UI 指向了正确的 Gateway 网关。参见 [Remote access](/zh-CN/gateway/remote)。 - - 可以。复制**状态目录**和**工作区**,然后运行一次 Doctor。这会 - 保持你的机器人“完全一样”(内存、会话历史、认证和渠道 + + 可以。复制**状态目录**和**工作区**,然后运行一次 Doctor。这样 + 就能保持你的机器人“完全一样”(记忆、会话历史、认证和渠道 状态),前提是你复制了**这两个**位置: 1. 在新机器上安装 OpenClaw。 @@ -285,60 +291,61 @@ x-i18n: 3. 复制你的工作区(默认:`~/.openclaw/workspace`)。 4. 运行 `openclaw doctor` 并重启 Gateway 网关服务。 - 这样会保留配置、auth profile、WhatsApp 凭据、会话和内存。如果你使用的是 - 远程模式,请记住会话存储和工作区都归 gateway 主机所有。 + 这样会保留配置、认证配置文件、WhatsApp 凭证、会话和记忆。如果你处于 + 远程模式,请记住会话存储和工作区由 gateway host 持有。 - **重要:**如果你只是把工作区 commit/push 到 GitHub,你备份的只是 - **内存 + 引导文件**,**而不是**会话历史或认证。后者位于 + **重要:**如果你只是把工作区 commit/push 到 GitHub,你备份的 + 只有**记忆 + 引导文件**,**不包括**会话历史或认证。这些内容位于 `~/.openclaw/` 下(例如 `~/.openclaw/agents//sessions/`)。 - 相关内容:[迁移](/zh-CN/install/migrating)、[磁盘上的文件位置](#where-things-live-on-disk)、 - [智能体工作区](/zh-CN/concepts/agent-workspace)、[Doctor](/zh-CN/gateway/doctor)、 - [远程模式](/zh-CN/gateway/remote)。 + 相关内容:[Migrating](/zh-CN/install/migrating)、[文件在磁盘上的位置](#文件在磁盘上的位置)、 + [Agent workspace](/zh-CN/concepts/agent-workspace)、[Doctor](/zh-CN/gateway/doctor)、 + [Remote mode](/zh-CN/gateway/remote)。 - + 查看 GitHub 更新日志: [https://github.com/openclaw/openclaw/blob/main/CHANGELOG.md](https://github.com/openclaw/openclaw/blob/main/CHANGELOG.md) - 最新条目在最上方。如果顶部区块标记为 **Unreleased**,则下一个带日期的 - 区块就是最新已发布版本。条目按 **Highlights**、**Changes** 和 - **Fixes** 分组(必要时还会有文档 / 其他部分)。 + 最新条目位于顶部。如果顶部章节标记为 **Unreleased**,那么下一个带日期的 + 章节就是最新发布版本。条目按 **Highlights**、**Changes** 和 + **Fixes** 分组(必要时还会有文档/其他章节)。 - 某些 Comcast/Xfinity 连接会因 Xfinity - Advanced Security 而错误拦截 `docs.openclaw.ai`。请禁用它或将 `docs.openclaw.ai` 加入允许列表,然后重试。 + 一些 Comcast/Xfinity 连接会通过 Xfinity + Advanced Security 错误地拦截 `docs.openclaw.ai`。请禁用该功能 + 或将 `docs.openclaw.ai` 加入允许列表,然后重试。 也请通过这里帮助我们解除拦截:[https://spa.xfinity.com/check_url_status](https://spa.xfinity.com/check_url_status)。 - 如果你仍无法访问该站点,文档在 GitHub 上有镜像: + 如果你仍然无法访问该站点,文档在 GitHub 上也有镜像: [https://github.com/openclaw/openclaw/tree/main/docs](https://github.com/openclaw/openclaw/tree/main/docs) - - **稳定版**和 **beta** 是 **npm dist-tags**,不是独立的代码分支: + + **稳定版**和**beta**是 **npm dist-tag**,不是不同的代码线: - `latest` = 稳定版 - `beta` = 用于测试的早期构建 - 通常,一个稳定版本会先发布到 **beta**,然后再通过显式的 - 提升步骤把同一版本移动到 `latest`。维护者也可以在需要时 - 直接发布到 `latest`。这就是为什么 beta 和稳定版在提升之后可能 - 指向**同一个版本**。 + 通常,稳定版会先发布到 **beta**,然后通过一个明确的 + 提升步骤将同一版本移动到 `latest`。维护者在必要时也可以 + 直接发布到 `latest`。这就是为什么 beta 和稳定版在提升后 + 可能指向**同一版本**。 查看变更内容: [https://github.com/openclaw/openclaw/blob/main/CHANGELOG.md](https://github.com/openclaw/openclaw/blob/main/CHANGELOG.md) - 关于安装单行命令,以及 beta 和 dev 的区别,请参阅下方折叠项。 + 关于安装单行命令以及 beta 与 dev 的区别,请参见下方折叠项。 **Beta** 是 npm dist-tag `beta`(提升后可能与 `latest` 相同)。 - **Dev** 是不断前进的 `main` 分支头部(git);在发布时,它使用 npm dist-tag `dev`。 + **Dev** 是 `main` 的移动头部(git);发布时使用 npm dist-tag `dev`。 单行命令(macOS/Linux): @@ -353,12 +360,12 @@ x-i18n: Windows 安装器(PowerShell): [https://openclaw.ai/install.ps1](https://openclaw.ai/install.ps1) - 更多细节:[开发渠道](/zh-CN/install/development-channels) 和 [安装器标志](/zh-CN/install/installer)。 + 更多细节:[Development channels](/zh-CN/install/development-channels) 和 [Installer flags](/zh-CN/install/installer)。 - - 有两个选项: + + 两种方式: 1. **Dev 渠道(git 检出):** @@ -374,9 +381,9 @@ x-i18n: curl -fsSL https://openclaw.ai/install.sh | bash -s -- --install-method git ``` - 这样你会得到一个本地仓库,你可以编辑它,然后通过 git 更新。 + 这样你会得到一个可在本地编辑的仓库,然后通过 git 更新。 - 如果你更喜欢手动进行干净克隆,可以使用: + 如果你更喜欢手动进行一次干净克隆,请使用: ```bash git clone https://github.com/openclaw/openclaw.git @@ -385,24 +392,24 @@ x-i18n: pnpm build ``` - 文档:[更新](/cli/update)、[开发渠道](/zh-CN/install/development-channels)、 - [安装](/zh-CN/install)。 + 文档:[Update](/cli/update)、[Development channels](/zh-CN/install/development-channels)、 + [Install](/zh-CN/install)。 - 粗略参考: + 粗略估计: - **安装:**2-5 分钟 - - **新手引导:**5-15 分钟,取决于你配置了多少渠道 / 模型 + - **新手引导:**5-15 分钟,取决于你配置了多少渠道/模型 - 如果卡住,请参阅 [安装器卡住了](#quick-start-and-first-run-setup) - 和 [我卡住了](#quick-start-and-first-run-setup) 中的快速调试循环。 + 如果卡住,请使用 [Installer stuck](#快速开始与首次运行设置) + 和 [我卡住了](#快速开始与首次运行设置) 中的快速调试循环。 - 使用**详细输出**重新运行安装器: + 用**详细输出**重新运行安装器: ```bash curl -fsSL https://openclaw.ai/install.sh | bash -s -- --verbose @@ -414,13 +421,13 @@ x-i18n: curl -fsSL https://openclaw.ai/install.sh | bash -s -- --beta --verbose ``` - 对于可修改的(git)安装: + 使用可修改的(git)安装: ```bash curl -fsSL https://openclaw.ai/install.sh | bash -s -- --install-method git --verbose ``` - Windows(PowerShell)对应方式: + Windows(PowerShell)等效方式: ```powershell # install.ps1 目前还没有专门的 -Verbose 标志。 @@ -429,44 +436,44 @@ x-i18n: Set-PSDebug -Trace 0 ``` - 更多选项:[安装器标志](/zh-CN/install/installer)。 + 更多选项:[Installer flags](/zh-CN/install/installer)。 - - Windows 上有两个常见问题: + + 两个常见的 Windows 问题: - **1)npm 错误 spawn git / git not found** + **1) npm error spawn git / git not found** - - 安装 **Git for Windows**,并确保 `git` 已加入你的 PATH。 + - 安装 **Git for Windows** 并确保 `git` 在你的 PATH 中。 - 关闭并重新打开 PowerShell,然后重新运行安装器。 - **2)安装后 openclaw 无法识别** + **2) 安装后 openclaw is not recognized** - - 你的 npm 全局 bin 文件夹不在 PATH 中。 + - 你的 npm 全局 bin 目录没有加入 PATH。 - 检查路径: ```powershell npm config get prefix ``` - - 将该目录加入你的用户 PATH(Windows 上不需要 `\bin` 后缀;大多数系统上是 `%AppData%\npm`)。 - - 更新 PATH 后关闭并重新打开 PowerShell。 + - 将该目录添加到你的用户 PATH 中(Windows 上不需要 `\bin` 后缀;大多数系统上它是 `%AppData%\npm`)。 + - 更新 PATH 后,关闭并重新打开 PowerShell。 - 如果你想获得最顺畅的 Windows 部署体验,请使用 **WSL2** 而不是原生 Windows。 + 如果你希望获得最顺滑的 Windows 设置体验,请使用 **WSL2** 而不是原生 Windows。 文档:[Windows](/zh-CN/platforms/windows)。 - - 这通常是原生 Windows shell 中控制台代码页不匹配导致的。 + + 这通常是原生 Windows shell 的控制台代码页不匹配问题。 症状: - `system.run`/`exec` 输出中的中文显示为乱码 - 同一命令在另一个终端配置文件中显示正常 - 在 PowerShell 中的快速解决方案: + PowerShell 中的快速解决办法: ```powershell chcp 65001 @@ -481,21 +488,21 @@ x-i18n: openclaw gateway restart ``` - 如果你在最新版 OpenClaw 上仍然能复现此问题,请在这里跟踪 / 报告: + 如果在最新的 OpenClaw 上你仍然可以复现这个问题,请在这里跟踪/报告: - [Issue #30640](https://github.com/openclaw/openclaw/issues/30640) - - 使用**可修改的(git)安装**,这样你本地就有完整源码和文档,然后 - 在_该文件夹中_向你的机器人(或 Claude/Codex)提问,这样它就可以读取仓库并给出精确回答。 + + 使用**可修改的(git)安装**,这样你就能在本地拥有完整源码和文档,然后 + 在_那个目录里_向你的机器人(或 Claude/Codex)提问,这样它就能读取仓库并给出更准确的答案。 ```bash curl -fsSL https://openclaw.ai/install.sh | bash -s -- --install-method git ``` - 更多细节:[安装](/zh-CN/install) 和 [安装器标志](/zh-CN/install/installer)。 + 更多细节:[Install](/zh-CN/install) 和 [Installer flags](/zh-CN/install/installer)。 @@ -503,44 +510,44 @@ x-i18n: 简短回答:按照 Linux 指南操作,然后运行新手引导。 - Linux 快速路径 + 服务安装:[Linux](/zh-CN/platforms/linux)。 - - 完整步骤说明:[入门指南](/zh-CN/start/getting-started)。 - - 安装器 + 更新:[安装与更新](/zh-CN/install/updating)。 + - 完整演练:[入门指南](/zh-CN/start/getting-started)。 + - 安装器 + 更新:[Install & updates](/zh-CN/install/updating)。 - 任何 Linux VPS 都可以。安装到服务器上,然后使用 SSH/Tailscale 访问 Gateway 网关。 + 任何 Linux VPS 都可以。把它安装在服务器上,然后使用 SSH/Tailscale 访问 Gateway 网关。 指南:[exe.dev](/zh-CN/install/exe-dev)、[Hetzner](/zh-CN/install/hetzner)、[Fly.io](/zh-CN/install/fly)。 - 远程访问:[Gateway 网关远程访问](/zh-CN/gateway/remote)。 + 远程访问:[Gateway remote](/zh-CN/gateway/remote)。 - - 我们维护了一个**托管中心**,汇总常见提供商。选择其中一个并按照指南操作: + + 我们提供了一个**托管中心**,汇总常见提供商。选择一个并按指南操作: - - [VPS 托管](/zh-CN/vps)(所有提供商集中在一处) + - [VPS hosting](/zh-CN/vps)(所有提供商集中在一处) - [Fly.io](/zh-CN/install/fly) - [Hetzner](/zh-CN/install/hetzner) - [exe.dev](/zh-CN/install/exe-dev) - 它在云端的工作方式是:**Gateway 网关运行在服务器上**,而你通过 - Control UI(或 Tailscale/SSH)从笔记本 / 手机访问它。你的状态和工作区 - 都保存在服务器上,所以应将该主机视为事实来源并做好备份。 + 它在云中的工作方式是:**Gateway 网关运行在服务器上**,而你通过 Control UI(或 Tailscale/SSH) + 从笔记本/手机访问它。你的状态 + 工作区 + 存储在服务器上,因此请把该主机视为事实来源并做好备份。 - 你还可以将**节点**(Mac/iOS/Android/headless)配对到该云端 Gateway 网关,以访问 - 本地屏幕 / 摄像头 / Canvas,或在你的笔记本上执行命令,同时让 - Gateway 网关保留在云端。 + 你可以将**节点**(Mac/iOS/Android/无头)配对到这个云端 Gateway 网关, + 以访问本地屏幕/摄像头/canvas,或在你的笔记本上运行命令, + 同时让 Gateway 网关保留在云端。 - 中心:[平台](/zh-CN/platforms)。远程访问:[Gateway 网关远程访问](/zh-CN/gateway/remote)。 - 节点:[节点](/zh-CN/nodes)、[节点 CLI](/cli/nodes)。 + 中心页:[Platforms](/zh-CN/platforms)。远程访问:[Gateway remote](/zh-CN/gateway/remote)。 + 节点:[Nodes](/zh-CN/nodes)、[Nodes CLI](/cli/nodes)。 简短回答:**可以,但不推荐**。更新流程可能会重启 - Gateway 网关(导致当前会话中断),可能需要干净的 git 检出,还可能 - 需要确认提示。更安全的方式是由操作人员在 shell 中运行更新。 + Gateway 网关(从而断开当前会话),可能需要一个干净的 git 检出, + 还可能要求确认。更安全的做法是由操作员在 shell 中运行更新。 使用 CLI: @@ -552,85 +559,87 @@ x-i18n: openclaw update --no-restart ``` - 如果你必须从智能体中自动化执行: + 如果你确实必须从智能体自动化执行: ```bash openclaw update --yes --no-restart openclaw gateway restart ``` - 文档:[更新](/cli/update)、[更新](/zh-CN/install/updating)。 + 文档:[Update](/cli/update)、[Updating](/zh-CN/install/updating)。 - + `openclaw onboard` 是推荐的设置路径。在**本地模式**下,它会引导你完成: - - **模型 / 认证设置**(提供商 OAuth、API 密钥、Anthropic 旧版 setup-token,以及 LM Studio 等本地模型选项) + - **模型/认证设置**(提供商 OAuth、API 密钥、Anthropic 旧版 setup-token,以及 LM Studio 之类的本地模型选项) - **工作区**位置 + 引导文件 - - **Gateway 网关设置**(bind/port/auth/tailscale) + - **Gateway 网关设置**(绑定/端口/认证/Tailscale) - **渠道**(WhatsApp、Telegram、Discord、Mattermost、Signal、iMessage,以及像 QQ Bot 这样的内置渠道插件) - - **守护进程安装**(macOS 上为 LaunchAgent;Linux/WSL2 上为 systemd 用户单元) + - **守护进程安装**(macOS 上为 LaunchAgent;Linux/WSL2 上为 systemd user unit) - **健康检查**和 **Skills** 选择 如果你配置的模型未知或缺少认证,它还会发出警告。 - - 不需要。你可以使用**API 密钥**(Anthropic/OpenAI/其他)运行 OpenClaw,或者使用 - **纯本地模型**,这样你的数据就能保留在设备上。订阅(Claude + + 不需要。你可以使用 **API 密钥**(Anthropic/OpenAI/其他)运行 OpenClaw,也可以使用 + **纯本地模型**,这样你的数据就能保留在你的设备上。订阅(Claude Pro/Max 或 OpenAI Codex)只是认证这些提供商的可选方式。 - 对于 Anthropic 在 OpenClaw 中的情况,实际区分是: + 对于 OpenClaw 中的 Anthropic,实际区分如下: - - **Anthropic API 密钥**:普通 Anthropic API 计费 + - **Anthropic API 密钥**:正常的 Anthropic API 计费 - **OpenClaw 中的 Claude 订阅认证**:Anthropic 于 - **2026 年 4 月 4 日太平洋时间中午 12:00 / 英国夏令时晚上 8:00** 告知 OpenClaw 用户,这需要 - **额外用量**,并且会在订阅之外单独计费 + **2026 年 4 月 4 日太平洋时间中午 12:00 / 英国夏令时晚上 8:00** + 通知 OpenClaw 用户,这需要 + **Extra Usage**,并且与订阅分开计费 - 我们的本地复现还表明,`claude -p --append-system-prompt ...` 在追加提示中标识 - OpenClaw 时,也可能触发相同的额外用量限制;而相同的提示字符串在 - Anthropic SDK + API 密钥路径上**不会**复现该拦截。OpenAI Codex OAuth 则被明确 - 支持用于 OpenClaw 这类外部工具。 + 我们的本地复现还表明,`claude -p --append-system-prompt ...` 在附加提示中标识 + OpenClaw 时,也会触发相同的 Extra Usage 限制; + 而同样的提示字符串在 Anthropic SDK + API 密钥路径上 + **不会**复现该限制。OpenAI Codex OAuth 明确 + 支持像 OpenClaw 这样的外部工具。 - OpenClaw 还支持其他托管的订阅式选项,包括 + OpenClaw 还支持其他托管式订阅选项,包括 **Qwen Cloud Coding Plan**、**MiniMax Coding Plan** 和 **Z.AI / GLM Coding Plan**。 文档:[Anthropic](/zh-CN/providers/anthropic)、[OpenAI](/zh-CN/providers/openai)、 [Qwen Cloud](/zh-CN/providers/qwen)、 [MiniMax](/zh-CN/providers/minimax)、[GLM Models](/zh-CN/providers/glm)、 - [本地模型](/zh-CN/gateway/local-models)、[模型](/zh-CN/concepts/models)。 + [Local models](/zh-CN/gateway/local-models)、[Models](/zh-CN/concepts/models)。 - - 可以,但应将其视为**带额外用量的 Claude 订阅认证**。 + + 可以,但请把它视为**带 Extra Usage 的 Claude 订阅认证**。 - Claude Pro/Max 订阅不包含 API 密钥。在 OpenClaw 中,这意味着 - Anthropic 针对 OpenClaw 的专用计费说明适用:订阅流量需要 - **额外用量**。如果你希望 Anthropic 流量不走这条额外用量路径, - 请改用 Anthropic API 密钥。 + Claude Pro/Max 订阅不包含 API 密钥。在 OpenClaw 中,这 + 意味着 Anthropic 面向 OpenClaw 的专用计费通知仍然适用:订阅 + 流量需要 **Extra Usage**。如果你希望使用 Anthropic 流量而不走 + Extra Usage 这一路径,请改用 Anthropic API 密钥。 - 支持,但当前支持的解释是: + 支持,但目前推荐的理解方式是: - - 在 OpenClaw 中使用 Anthropic 订阅意味着**额外用量** - - 如果不走这条路径,那么 Anthropic 在 OpenClaw 中就意味着**API 密钥** + - OpenClaw 中的 Anthropic + 订阅,意味着 **Extra Usage** + - OpenClaw 中的 Anthropic + 非 Extra Usage 路径,意味着 **API key** - Anthropic setup-token 仍然作为 OpenClaw 中的旧版 / 手动路径保留, - 并且 Anthropic 针对 OpenClaw 的专用计费说明在此仍然适用。我们 - 也在本地通过直接使用 + Anthropic setup-token 仍然作为旧版/手动 OpenClaw 路径可用, + 并且 Anthropic 针对 OpenClaw 的专用计费通知在这里仍然适用。我们 + 还在本地通过直接使用 `claude -p --append-system-prompt ...` 复现了相同的计费限制, - 当追加的提示标识 OpenClaw 时会触发;而相同的提示字符串在 + 条件是附加提示中标识了 OpenClaw;而同样的提示字符串在 Anthropic SDK + API 密钥路径上**不会**复现。 - 对于生产环境或多用户工作负载,Anthropic API 密钥认证是 + 对于生产环境或多用户工作负载,Anthropic API key 认证是 更安全、也更推荐的选择。如果你想在 OpenClaw 中使用其他订阅式托管 - 选项,请参阅 [OpenAI](/zh-CN/providers/openai)、[Qwen / Model + 选项,请参见 [OpenAI](/zh-CN/providers/openai)、[Qwen / Model Cloud](/zh-CN/providers/qwen)、[MiniMax](/zh-CN/providers/minimax) 和 [GLM Models](/zh-CN/providers/glm)。 @@ -638,93 +647,87 @@ x-i18n: -这意味着你当前窗口中的 **Anthropic 配额 / 限速** 已耗尽。如果你 -使用的是 **Claude CLI**,请等待窗口重置或升级你的套餐。如果你 -使用的是 **Anthropic API 密钥**,请检查 Anthropic Console -中的使用量 / 计费情况,并在需要时提高限额。 +这表示你在当前时间窗口内的 **Anthropic 配额/速率限制** 已经耗尽。如果你 +使用 **Claude CLI**,请等待窗口重置或升级你的套餐。如果你 +使用 **Anthropic API 密钥**,请检查 Anthropic Console +中的使用量/计费情况,并按需提高限制。 如果消息明确是: - `Extra usage is required for long context requests`,说明该请求正在尝试使用 - Anthropic 的 1M context beta(`context1m: true`)。这仅在你的 - 凭证符合长上下文计费资格时可用(API 密钥计费,或 - 启用了额外用量的 OpenClaw Claude 登录路径)。 + `Extra usage is required for long context requests`,则说明该请求正在尝试使用 + Anthropic 的 1M 上下文测试版(`context1m: true`)。这只有在你的 + 凭证符合长上下文计费资格时才可用(API 密钥计费或 + 启用了 Extra Usage 的 OpenClaw Claude 登录路径)。 - 提示:设置一个**回退模型**,这样当某个提供商被限流时,OpenClaw 仍可继续回复。 - 请参阅 [模型](/cli/models)、[OAuth](/zh-CN/concepts/oauth) 和 + 提示:设置一个**回退模型**,这样当某个提供商遭遇速率限制时,OpenClaw 仍能继续回复。 + 参见 [Models](/cli/models)、[OAuth](/zh-CN/concepts/oauth) 和 [/gateway/troubleshooting#anthropic-429-extra-usage-required-for-long-context](/zh-CN/gateway/troubleshooting#anthropic-429-extra-usage-required-for-long-context)。 - 支持。OpenClaw 内置了 **Amazon Bedrock(Converse)** 提供商。存在 AWS 环境标记时,OpenClaw 可以自动发现流式 / 文本 Bedrock 目录,并将其合并为一个隐式的 `amazon-bedrock` 提供商;否则你也可以显式启用 `plugins.entries.amazon-bedrock.config.discovery.enabled` 或添加手动提供商条目。请参阅 [Amazon Bedrock](/zh-CN/providers/bedrock) 和 [模型提供商](/zh-CN/providers/models)。如果你更喜欢托管密钥流程,在 Bedrock 前面使用 OpenAI 兼容代理仍然是一个有效选项。 + 支持。OpenClaw 内置了 **Amazon Bedrock(Converse)** 提供商。当存在 AWS 环境标记时,OpenClaw 可以自动发现支持流式/文本的 Bedrock 模型目录,并将其合并为隐式的 `amazon-bedrock` 提供商;否则你也可以显式启用 `plugins.entries.amazon-bedrock.config.discovery.enabled`,或者手动添加一个提供商条目。参见 [Amazon Bedrock](/zh-CN/providers/bedrock) 和 [Model providers](/zh-CN/providers/models)。如果你更喜欢托管密钥流程,在 Bedrock 前面使用一个兼容 OpenAI 的代理仍然是有效选择。 - OpenClaw 通过 OAuth(ChatGPT 登录)支持 **OpenAI Code(Codex)**。新手引导可以运行 OAuth 流程,并会在合适时将默认模型设置为 `openai-codex/gpt-5.4`。请参阅 [模型提供商](/zh-CN/concepts/model-providers) 和 [设置向导(CLI)](/zh-CN/start/wizard)。 + OpenClaw 通过 OAuth(ChatGPT 登录)支持 **OpenAI Code(Codex)**。新手引导可以运行 OAuth 流程,并在合适时将默认模型设置为 `openai-codex/gpt-5.4`。参见 [Model providers](/zh-CN/concepts/model-providers) 和 [新手引导(CLI)](/zh-CN/start/wizard)。 - + 支持。OpenClaw 完全支持 **OpenAI Code(Codex)订阅 OAuth**。 - OpenAI 明确允许在像 OpenClaw 这样的外部工具 / 工作流中 - 使用订阅 OAuth。新手引导也可以替你运行 OAuth 流程。 + OpenAI 明确允许在 OpenClaw 这样的外部工具/工作流中 + 使用订阅 OAuth。新手引导可以为你运行 OAuth 流程。 - 请参阅 [OAuth](/zh-CN/concepts/oauth)、[模型提供商](/zh-CN/concepts/model-providers) 和 [设置向导(CLI)](/zh-CN/start/wizard)。 + 参见 [OAuth](/zh-CN/concepts/oauth)、[Model providers](/zh-CN/concepts/model-providers) 和 [新手引导(CLI)](/zh-CN/start/wizard)。 - Gemini CLI 使用的是**插件认证流程**,而不是在 `openclaw.json` 中填写 client id 或 secret。 + Gemini CLI 使用的是**插件认证流程**,而不是在 `openclaw.json` 中配置 `client id` 或 `secret`。 - 步骤: + 请改用 Gemini API 提供商: - 1. 在本地安装 Gemini CLI,使 `gemini` 可通过 `PATH` 访问 - - Homebrew:`brew install gemini-cli` - - npm:`npm install -g @google/gemini-cli` - 2. 启用插件:`openclaw plugins enable google` - 3. 登录:`openclaw models auth login --provider google-gemini-cli --set-default` - 4. 登录后的默认模型:`google-gemini-cli/gemini-3.1-pro-preview` - 5. 如果请求失败,请在 gateway 主机上设置 `GOOGLE_CLOUD_PROJECT` 或 `GOOGLE_CLOUD_PROJECT_ID` - - 这会将 OAuth token 存储在 gateway 主机上的 auth profile 中。详情请参阅:[模型提供商](/zh-CN/concepts/model-providers)。 + 1. 启用插件:`openclaw plugins enable google` + 2. 运行 `openclaw onboard --auth-choice gemini-api-key` + 3. 设置一个 Google 模型,例如 `google/gemini-3.1-pro-preview` - 通常不适合。OpenClaw 需要大上下文和强安全性;小卡模型会截断并泄露内容。如果你必须使用,请在本地运行你能承受的**最大**模型构建(LM Studio),并参阅 [/gateway/local-models](/zh-CN/gateway/local-models)。更小 / 量化更高的模型会增加 prompt injection 风险——请参阅 [安全](/zh-CN/gateway/security)。 + 通常不适合。OpenClaw 需要大上下文 + 强安全性;小模型会截断并泄漏。如果你必须这么做,请在本地运行你能承载的**最大**模型构建(LM Studio),并参见 [/gateway/local-models](/zh-CN/gateway/local-models)。更小/量化更强的模型会增加提示注入风险——参见 [Security](/zh-CN/gateway/security)。 - - 请选择固定区域的端点。OpenRouter 为 MiniMax、Kimi 和 GLM 提供美国托管选项;选择美国托管变体即可将数据保留在该区域。你仍然可以通过设置 `models.mode: "merge"` 将 Anthropic/OpenAI 与这些模型一同列出,这样既能尊重你选定的区域提供商,也能保留回退能力。 + + 选择固定区域的端点。OpenRouter 为 MiniMax、Kimi 和 GLM 提供美国托管选项;选择美国托管变体即可将数据保留在该区域。你仍然可以通过 `models.mode: "merge"` 同时列出 Anthropic/OpenAI,这样在保持故障切换可用的同时,也能遵循你所选的区域化提供商。 - - 不需要。OpenClaw 可运行在 macOS 或 Linux 上(Windows 通过 WSL2)。Mac mini 是可选项——有些人 - 会买一台作为始终在线的主机,但小型 VPS、家用服务器或 Raspberry Pi 级设备也完全可以。 + + 不需要。OpenClaw 可运行在 macOS 或 Linux 上(Windows 通过 WSL2)。Mac mini 是可选的——有些人 + 会买一台作为始终在线的主机,但小型 VPS、家用服务器或 Raspberry Pi 级别的设备也可以。 - 只有在你需要 **macOS 专属工具**时才必须有 Mac。对于 iMessage,请使用 [BlueBubbles](/zh-CN/channels/bluebubbles)(推荐)——BlueBubbles 服务器运行在任意 Mac 上,而 Gateway 网关可以运行在 Linux 或其他地方。如果你还想使用其他 macOS 专属工具,就在 Mac 上运行 Gateway 网关,或者配对一个 macOS 节点。 + 只有在你需要**仅限 macOS 的工具**时才需要 Mac。对于 iMessage,请使用 [BlueBubbles](/zh-CN/channels/bluebubbles)(推荐)——BlueBubbles 服务器运行在任意 Mac 上,而 Gateway 网关可以运行在 Linux 或其他地方。如果你需要其他仅限 macOS 的工具,请在 Mac 上运行 Gateway 网关,或者配对一个 macOS 节点。 - 文档:[BlueBubbles](/zh-CN/channels/bluebubbles)、[节点](/zh-CN/nodes)、[Mac 远程模式](/zh-CN/platforms/mac/remote)。 + 文档:[BlueBubbles](/zh-CN/channels/bluebubbles)、[Nodes](/zh-CN/nodes)、[Mac remote mode](/zh-CN/platforms/mac/remote)。 - + 你需要**某台已登录 Messages 的 macOS 设备**。它**不一定**是 Mac mini—— - 任何 Mac 都可以。对于 iMessage,请**使用 [BlueBubbles](/zh-CN/channels/bluebubbles)**(推荐)——BlueBubbles 服务器运行在 macOS 上,而 Gateway 网关可以运行在 Linux 或其他地方。 + 任意 Mac 都可以。对于 iMessage,**请使用 [BlueBubbles](/zh-CN/channels/bluebubbles)**(推荐)——BlueBubbles 服务器运行在 macOS 上,而 Gateway 网关可以运行在 Linux 或其他地方。 - 常见部署方式: + 常见配置: - - 在 Linux/VPS 上运行 Gateway 网关,并在任意已登录 Messages 的 Mac 上运行 BlueBubbles 服务器。 - - 如果你希望最简单的单机部署,也可以把所有东西都运行在 Mac 上。 + - 在 Linux/VPS 上运行 Gateway 网关,在任意已登录 Messages 的 Mac 上运行 BlueBubbles 服务器。 + - 如果你想要最简单的单机配置,也可以把所有组件都运行在同一台 Mac 上。 - 文档:[BlueBubbles](/zh-CN/channels/bluebubbles)、[节点](/zh-CN/nodes)、 - [Mac 远程模式](/zh-CN/platforms/mac/remote)。 + 文档:[BlueBubbles](/zh-CN/channels/bluebubbles)、[Nodes](/zh-CN/nodes)、 + [Mac remote mode](/zh-CN/platforms/mac/remote)。 - + 可以。**Mac mini 可以运行 Gateway 网关**,而你的 MacBook Pro 可以作为 - **节点**(配套设备)连接。节点不运行 Gateway 网关——它们提供额外 - 能力,例如该设备上的屏幕 / 摄像头 / Canvas 和 `system.run`。 + **节点**(配套设备)连接。节点不会运行 Gateway 网关——它们提供额外的 + 能力,例如该设备上的屏幕/摄像头/canvas 和 `system.run`。 常见模式: @@ -732,49 +735,50 @@ x-i18n: - MacBook Pro 运行 macOS 应用或节点主机,并与 Gateway 网关配对。 - 使用 `openclaw nodes status` / `openclaw nodes list` 查看它。 - 文档:[节点](/zh-CN/nodes)、[节点 CLI](/cli/nodes)。 + 文档:[Nodes](/zh-CN/nodes)、[Nodes CLI](/cli/nodes)。 - - **不推荐**使用 Bun。我们观察到一些运行时 bug,尤其是在 WhatsApp 和 Telegram 场景下。 - 对于稳定运行的 Gateway 网关,请使用 **Node**。 + + **不推荐**使用 Bun。我们观察到一些运行时 bug,尤其是在 WhatsApp 和 Telegram 上。 + 稳定运行 Gateway 网关请使用 **Node**。 - 如果你仍想尝试 Bun,请只在非生产 Gateway 网关上进行, - 并且不要配合 WhatsApp/Telegram 使用。 + 如果你仍然想试验 Bun,请在非生产 Gateway 网关上进行, + 并且不要启用 WhatsApp/Telegram。 - - `channels.telegram.allowFrom` 是**人工发送者的 Telegram 用户 ID**(数字)。它不是机器人用户名。 + + `channels.telegram.allowFrom` 填写的是**人工发送者的 Telegram 用户 ID**(数字)。 + 不是机器人用户名。 - 新手引导接受 `@username` 输入并会将其解析为数字 ID,但 OpenClaw 的授权只使用数字 ID。 + 新手引导接受 `@username` 输入并将其解析为数字 ID,但 OpenClaw 的授权仅使用数字 ID。 - 更安全的方式(不借助第三方机器人): + 更安全的方式(不依赖第三方机器人): - - 向你的机器人发送私信,然后运行 `openclaw logs --follow` 并读取 `from.id`。 + - 给你的机器人发送私信,然后运行 `openclaw logs --follow` 并读取 `from.id`。 官方 Bot API: - - 向你的机器人发送私信,然后调用 `https://api.telegram.org/bot/getUpdates` 并读取 `message.from.id`。 + - 给你的机器人发送私信,然后调用 `https://api.telegram.org/bot/getUpdates` 并读取 `message.from.id`。 第三方方式(隐私性较差): - - 向 `@userinfobot` 或 `@getidsbot` 发送私信。 + - 私信 `@userinfobot` 或 `@getidsbot`。 - 请参阅 [/channels/telegram](/zh-CN/channels/telegram#access-control-and-activation)。 + 参见 [/channels/telegram](/zh-CN/channels/telegram#access-control-and-activation)。 - - 可以,通过**多智能体路由**实现。将每个发送者的 WhatsApp **私信**(peer `kind: "direct"`,发送者 E.164 形如 `+15551234567`)绑定到不同的 `agentId`,这样每个人都会拥有自己的工作区和会话存储。回复仍然来自**同一个 WhatsApp 账户**,而私信访问控制(`channels.whatsapp.dmPolicy` / `channels.whatsapp.allowFrom`)对于每个 WhatsApp 账户来说是全局的。请参阅 [多智能体路由](/zh-CN/concepts/multi-agent) 和 [WhatsApp](/zh-CN/channels/whatsapp)。 + + 可以,通过**多智能体路由**实现。将每个发送者的 WhatsApp **私信**(peer `kind: "direct"`,发送者 E.164 格式如 `+15551234567`)绑定到不同的 `agentId`,这样每个人都会拥有自己的工作区和会话存储。回复仍然来自**同一个 WhatsApp 账号**,而私信访问控制(`channels.whatsapp.dmPolicy` / `channels.whatsapp.allowFrom`)对于每个 WhatsApp 账号是全局的。参见 [Multi-Agent Routing](/zh-CN/concepts/multi-agent) 和 [WhatsApp](/zh-CN/channels/whatsapp)。 - 可以。使用多智能体路由:为每个智能体设置各自的默认模型,然后将入站路由(provider account 或特定 peer)绑定到各个智能体。示例配置见 [多智能体路由](/zh-CN/concepts/multi-agent)。另请参阅 [模型](/zh-CN/concepts/models) 和 [配置](/zh-CN/gateway/configuration)。 + 可以。使用多智能体路由:给每个智能体设置各自的默认模型,然后把入站路由(提供商账号或特定 peer)绑定到各自的智能体。配置示例见 [Multi-Agent Routing](/zh-CN/concepts/multi-agent)。另见 [Models](/zh-CN/concepts/models) 和 [Configuration](/zh-CN/gateway/configuration)。 - + 可以。Homebrew 支持 Linux(Linuxbrew)。快速设置: ```bash @@ -784,27 +788,27 @@ x-i18n: brew install ``` - 如果你通过 systemd 运行 OpenClaw,请确保服务 PATH 包含 `/home/linuxbrew/.linuxbrew/bin`(或你的 brew 前缀),这样 `brew` 安装的工具才能在非登录 shell 中解析。 - 近期构建还会在 Linux systemd 服务中预先加入常见用户 bin 目录(例如 `~/.local/bin`、`~/.npm-global/bin`、`~/.local/share/pnpm`、`~/.bun/bin`),并在设置后尊重 `PNPM_HOME`、`NPM_CONFIG_PREFIX`、`BUN_INSTALL`、`VOLTA_HOME`、`ASDF_DATA_DIR`、`NVM_DIR` 和 `FNM_DIR`。 + 如果你通过 systemd 运行 OpenClaw,请确保服务的 PATH 包含 `/home/linuxbrew/.linuxbrew/bin`(或你的 brew 前缀),这样 `brew` 安装的工具才能在非登录 shell 中被找到。 + 较新的构建还会在 Linux systemd 服务中预置常见用户 bin 目录(例如 `~/.local/bin`、`~/.npm-global/bin`、`~/.local/share/pnpm`、`~/.bun/bin`),并在设置后识别 `PNPM_HOME`、`NPM_CONFIG_PREFIX`、`BUN_INSTALL`、`VOLTA_HOME`、`ASDF_DATA_DIR`、`NVM_DIR` 和 `FNM_DIR`。 - **可修改的(git)安装:**完整源码检出,可编辑,最适合贡献者。 - 你可以本地构建并修改代码 / 文档。 - - **npm install:**全局 CLI 安装,没有仓库,最适合“直接运行”。 - 更新来自 npm dist-tags。 + 你需要在本地运行构建,并且可以修改代码/文档。 + - **npm install:**全局 CLI 安装,没有仓库,最适合“装好就用”。 + 更新来自 npm dist-tag。 - 文档:[入门指南](/zh-CN/start/getting-started)、[更新](/zh-CN/install/updating)。 + 文档:[入门指南](/zh-CN/start/getting-started)、[Updating](/zh-CN/install/updating)。 可以。安装另一种形式后,运行 Doctor,让 gateway 服务指向新的入口点。 - 这**不会删除你的数据**——它只会更换 OpenClaw 的代码安装方式。你的状态 + 这**不会删除你的数据**——它只会改变 OpenClaw 的代码安装方式。你的状态 (`~/.openclaw`)和工作区(`~/.openclaw/workspace`)都会保持不变。 - 从 npm 切到 git: + 从 npm 切换到 git: ```bash git clone https://github.com/openclaw/openclaw.git @@ -815,7 +819,7 @@ x-i18n: openclaw gateway restart ``` - 从 git 切到 npm: + 从 git 切换到 npm: ```bash npm install -g openclaw@latest @@ -823,68 +827,68 @@ x-i18n: openclaw gateway restart ``` - Doctor 会检测 gateway 服务入口点是否与当前安装不匹配,并提供将服务配置重写为匹配当前安装的选项(自动化中使用 `--repair`)。 + Doctor 会检测到 gateway 服务入口点不匹配,并提供将服务配置重写为匹配当前安装的选项(自动化场景下使用 `--repair`)。 - 备份建议:请参阅 [备份策略](#where-things-live-on-disk)。 + 备份建议:参见 [备份策略](#文件在磁盘上的位置)。 - - 简短回答:**如果你需要 24/7 的可靠性,请使用 VPS**。如果你希望 - 阻力最低,并且能接受睡眠 / 重启,就在本地运行。 + + 简短回答:**如果你想要 24/7 的可靠性,请使用 VPS**。如果你希望 + 摩擦最小,并且可以接受休眠/重启,那就在本地运行。 **笔记本(本地 Gateway 网关)** - - **优点:**没有服务器成本,可直接访问本地文件,有可见的浏览器窗口。 - - **缺点:**睡眠 / 网络中断 = 断开连接,操作系统更新 / 重启会打断运行,机器必须保持唤醒。 + - **优点:**没有服务器成本,直接访问本地文件,可见的浏览器窗口。 + - **缺点:**休眠/网络中断 = 连接中断,操作系统更新/重启会打断运行,机器必须保持唤醒。 **VPS / 云端** - - **优点:**始终在线,网络稳定,不受笔记本睡眠影响,更容易持续运行。 - - **缺点:**通常以 headless 方式运行(使用截图),只能远程访问文件,更新时需要 SSH。 + - **优点:**始终在线,网络稳定,没有笔记本休眠问题,更容易长期运行。 + - **缺点:**通常是无头运行(需要截图),只能远程访问文件,你必须通过 SSH 更新。 - **OpenClaw 特定说明:**WhatsApp/Telegram/Slack/Mattermost/Discord 在 VPS 上都运行良好。真正的权衡只在于**headless 浏览器**还是可见窗口。请参阅 [浏览器](/zh-CN/tools/browser)。 + **OpenClaw 特定说明:**WhatsApp/Telegram/Slack/Mattermost/Discord 在 VPS 上都能正常工作。唯一真正的权衡是**无头浏览器**与可见窗口。参见 [Browser](/zh-CN/tools/browser)。 - **推荐默认方案:**如果你以前遇到过 gateway 断连,优先使用 VPS。本地方案适合你积极在 Mac 上使用、并希望获得本地文件访问或具有可见浏览器的 UI 自动化时使用。 + **推荐默认方案:**如果你以前遇到过 gateway 断连,就用 VPS。本地运行则非常适合你正在主动使用 Mac、并希望访问本地文件或使用带可见浏览器的 UI 自动化时。 不是必须,但**为了可靠性和隔离性,推荐这样做**。 - - **专用主机(VPS/Mac mini/Pi):**始终在线,较少受到睡眠 / 重启打断,权限更干净,更容易保持运行。 - - **共享笔记本 / 台式机:**用于测试和主动使用完全没问题,但要预期机器睡眠或更新时会暂停。 + - **专用主机(VPS/Mac mini/Pi):**始终在线,较少受休眠/重启影响,权限更干净,更容易持续运行。 + - **共用笔记本/台式机:**用于测试和主动使用完全没问题,但机器休眠或更新时会出现暂停。 - 如果你想两者兼得,可以把 Gateway 网关放在专用主机上,再把你的笔记本作为**节点**配对,用于本地 screen/camera/exec 工具。请参阅 [节点](/zh-CN/nodes)。 - 有关安全指导,请阅读 [安全](/zh-CN/gateway/security)。 + 如果你想兼顾两者优势,可以把 Gateway 网关放在专用主机上,再把你的笔记本作为**节点**配对,以提供本地屏幕/摄像头/exec 工具。参见 [Nodes](/zh-CN/nodes)。 + 有关安全建议,请阅读 [Security](/zh-CN/gateway/security)。 - - OpenClaw 很轻量。对于基础 Gateway 网关 + 一个聊天渠道: + + OpenClaw 很轻量。对于一个基础 Gateway 网关 + 一个聊天渠道: - - **绝对最低配置:**1 vCPU、1GB RAM、约 500MB 磁盘。 - - **推荐配置:**1-2 vCPU、2GB RAM 或更多余量(日志、媒体、多渠道)。Node 工具和浏览器自动化可能比较吃资源。 + - **绝对最低:**1 vCPU、1GB RAM、约 500MB 磁盘。 + - **推荐:**1-2 vCPU、2GB RAM 或更多余量(日志、媒体、多渠道)。节点工具和浏览器自动化可能比较吃资源。 - 操作系统:使用 **Ubuntu LTS**(或任何现代 Debian/Ubuntu)。Linux 安装路径在这些系统上测试最充分。 + 操作系统:使用 **Ubuntu LTS**(或任意现代 Debian/Ubuntu)。Linux 安装路径在这些系统上经过最多测试。 - 文档:[Linux](/zh-CN/platforms/linux)、[VPS 托管](/zh-CN/vps)。 + 文档:[Linux](/zh-CN/platforms/linux)、[VPS hosting](/zh-CN/vps)。 - - 可以。把 VM 当作 VPS 来看待:它需要始终在线、可访问,并且有足够的 - RAM 来运行 Gateway 网关和你启用的任何渠道。 + + 可以。把虚拟机当成 VPS 即可:它需要始终在线、可访问,并且有足够的 + RAM 来运行 Gateway 网关和你启用的渠道。 - 基础建议: + 基本建议: - - **绝对最低配置:**1 vCPU、1GB RAM。 - - **推荐配置:**如果你运行多个渠道、浏览器自动化或媒体工具,建议 2GB RAM 或更多。 + - **绝对最低:**1 vCPU、1GB RAM。 + - **推荐:**如果你运行多个渠道、浏览器自动化或媒体工具,建议 2GB RAM 或更多。 - **操作系统:**Ubuntu LTS 或其他现代 Debian/Ubuntu。 - 如果你使用 Windows,**WSL2 是最容易的 VM 风格部署方式**,并且工具兼容性最好。 - 请参阅 [Windows](/zh-CN/platforms/windows)、[VPS 托管](/zh-CN/vps)。 - 如果你在 VM 中运行 macOS,请参阅 [macOS VM](/zh-CN/install/macos-vm)。 + 如果你使用的是 Windows,**WSL2 是最容易上手的类 VM 配置**,并且工具兼容性最好。 + 参见 [Windows](/zh-CN/platforms/windows)、[VPS hosting](/zh-CN/vps)。 + 如果你在虚拟机中运行 macOS,请参见 [macOS VM](/zh-CN/install/macos-vm)。 @@ -893,83 +897,83 @@ x-i18n: - OpenClaw 是一个运行在你自己设备上的个人 AI 助手。它会在你已经使用的消息界面上回复你(WhatsApp、Telegram、Slack、Mattermost、Discord、Google Chat、Signal、iMessage、WebChat,以及如 QQ Bot 这类内置渠道插件),并且在受支持的平台上还可以提供语音和实时 Canvas。**Gateway 网关**是始终在线的控制平面;这个助手本身才是产品。 + OpenClaw 是一个运行在你自己设备上的个人 AI 助手。它会在你已经使用的消息界面上回复你(WhatsApp、Telegram、Slack、Mattermost、Discord、Google Chat、Signal、iMessage、WebChat,以及如 QQ Bot 等内置渠道插件),并且在受支持的平台上还能提供语音 + 实时 Canvas。**Gateway 网关**是始终在线的控制平面;这个助手本身才是产品。 - OpenClaw 不是“只是一个 Claude 包装器”。它是一个**本地优先的控制平面**,让你能够在**自己的硬件**上运行一个 - 强大的助手,并且可以通过你已经使用的聊天应用访问,同时具备 - 有状态会话、内存和工具——而不必把你的工作流控制权交给托管式 + OpenClaw 并不只是“一个 Claude 包装器”。它是一个**本地优先的控制平面**,让你可以在 + **自己的硬件**上运行一个强大的助手,并通过你已经使用的聊天应用访问它,同时具备 + 有状态会话、记忆和工具——而无需把你的工作流控制权交给托管式 SaaS。 亮点: - - **你的设备,你的数据:**你可以在任何地方运行 Gateway 网关(Mac、Linux、VPS),并将 - 工作区和会话历史保留在本地。 - - **真实渠道,而不是 Web 沙箱:**WhatsApp/Telegram/Slack/Discord/Signal/iMessage 等, - 以及在支持平台上的移动语音和 Canvas。 - - **模型无关:**使用 Anthropic、OpenAI、MiniMax、OpenRouter 等,并支持按智能体路由 - 和故障转移。 - - **纯本地选项:**运行本地模型,这样如果你愿意,**所有数据都可以留在你的设备上**。 - - **多智能体路由:**按渠道、账户或任务拆分不同智能体,每个智能体都有各自的 + - **你的设备,你的数据:**可将 Gateway 网关运行在任何你希望的地方(Mac、Linux、VPS),并将 + 工作区 + 会话历史保留在本地。 + - **真实渠道,而非 Web 沙箱:**WhatsApp/Telegram/Slack/Discord/Signal/iMessage 等, + 以及在受支持平台上的移动语音和 Canvas。 + - **模型无关:**使用 Anthropic、OpenAI、MiniMax、OpenRouter 等,并支持按智能体进行路由 + 与故障切换。 + - **纯本地选项:**运行本地模型,这样**所有数据都可以保留在你的设备上**。 + - **多智能体路由:**按渠道、账号或任务拆分不同智能体,每个智能体都有自己的 工作区和默认设置。 - - **开源且可修改:**你可以检查、扩展并自行托管,而不受供应商锁定。 + - **开源且可修改:**可检查、扩展和自托管,无供应商锁定。 - 文档:[Gateway 网关](/zh-CN/gateway)、[渠道](/zh-CN/channels)、[多智能体](/zh-CN/concepts/multi-agent)、 - [内存](/zh-CN/concepts/memory)。 + 文档:[Gateway 网关](/zh-CN/gateway)、[Channels](/zh-CN/channels)、[Multi-agent](/zh-CN/concepts/multi-agent)、 + [Memory](/zh-CN/concepts/memory)。 - - 适合入门的项目包括: + + 适合作为入门的项目: - 搭建一个网站(WordPress、Shopify,或简单静态站点)。 - - 设计一个移动应用原型(大纲、界面、API 规划)。 + - 原型设计一个移动应用(大纲、界面、API 计划)。 - 整理文件和文件夹(清理、命名、打标签)。 - - 连接 Gmail,并自动生成摘要或后续跟进。 + - 连接 Gmail 并自动生成摘要或后续跟进。 - 它可以处理大型任务,但如果你将其拆分为多个阶段,并 - 使用子智能体并行处理,效果会更好。 + 它可以处理大型任务,但当你把任务拆分为多个阶段,并 + 使用子智能体并行工作时,效果最好。 - - 日常最有价值的使用场景通常是: + + 日常最常见的收益通常包括: - - **个人简报:**总结你关心的收件箱、日历和新闻。 - - **研究与起草:**快速调研、生成摘要,以及撰写邮件或文档初稿。 - - **提醒与跟进:**通过 cron 或 heartbeat 驱动提醒和检查清单。 + - **个人简报:**汇总你关心的收件箱、日历和新闻。 + - **研究与起草:**快速调研、摘要,以及邮件或文档的初稿。 + - **提醒与跟进:**由 cron 或 Heartbeat 驱动的提示和清单。 - **浏览器自动化:**填写表单、收集数据、重复执行 Web 任务。 - - **跨设备协作:**你从手机发起任务,让 Gateway 网关在服务器上执行,再把结果返回到聊天中。 + - **跨设备协作:**从手机发送任务,让 Gateway 网关在服务器上执行,再把结果回传到聊天中。 - - 对于**研究、筛选和起草**来说,可以。它可以扫描网站、建立候选名单、 - 总结潜在客户,并撰写外联或广告文案草稿。 + + 可以,适用于**研究、筛选和起草**。它可以扫描网站、建立候选名单、 + 总结潜在客户情况,并撰写外联或广告文案草稿。 - 对于**外联或广告投放**,请保留人工参与。避免垃圾信息,遵守当地法律和 - 平台政策,并在发送前审核所有内容。最安全的方式是让 + 但对于**外联或广告投放**,请让人类参与把关。避免垃圾信息,遵守当地法律和 + 平台政策,并在发送前审阅所有内容。最安全的模式是让 OpenClaw 起草,由你审批。 - 文档:[安全](/zh-CN/gateway/security)。 + 文档:[Security](/zh-CN/gateway/security)。 - - OpenClaw 是一个**个人助手**和协作协调层,而不是 IDE 替代品。对于仓库中的 - 直接编码循环,使用 Claude Code 或 Codex 速度最快。使用 OpenClaw 则是在你 - 需要持久内存、跨设备访问和工具编排时。 + + OpenClaw 是一个**个人助手**和协调层,而不是 IDE 替代品。若想获得仓库内 + 最快的直接编码循环,请使用 Claude Code 或 Codex。当你 + 需要持久记忆、跨设备访问和工具编排时,请使用 OpenClaw。 优势: - - 跨会话的**持久内存 + 工作区** + - **持久记忆 + 工作区**,可跨会话保留 - **多平台访问**(WhatsApp、Telegram、TUI、WebChat) - **工具编排**(浏览器、文件、调度、hooks) - - **始终在线的 Gateway 网关**(可运行在 VPS 上,随时随地交互) - - 通过**节点**获得本地浏览器 / 屏幕 / 摄像头 / exec + - **始终在线的 Gateway 网关**(运行在 VPS 上,随时随地交互) + - 用于本地浏览器/屏幕/摄像头/exec 的 **Nodes** - 展示:[https://openclaw.ai/showcase](https://openclaw.ai/showcase) + 展示页:[https://openclaw.ai/showcase](https://openclaw.ai/showcase) @@ -977,69 +981,70 @@ x-i18n: ## Skills 和自动化 - - 使用托管覆盖,而不是直接编辑仓库副本。将你的更改放到 `~/.openclaw/skills//SKILL.md`(或通过 `~/.openclaw/openclaw.json` 中的 `skills.load.extraDirs` 添加目录)。优先级为 `/skills` → `/.agents/skills` → `~/.agents/skills` → `~/.openclaw/skills` → 内置 → `skills.load.extraDirs`,因此托管覆盖仍会优先于内置 Skills,而无需修改 git。如果你需要让某个 skill 全局安装但只对部分智能体可见,可将共享副本放在 `~/.openclaw/skills` 中,并通过 `agents.defaults.skills` 和 `agents.list[].skills` 控制可见性。只有值得上游合并的修改才应存在于仓库中并通过 PR 提交。 + + 使用托管覆盖,而不是编辑仓库中的副本。将你的更改放到 `~/.openclaw/skills//SKILL.md`(或通过 `~/.openclaw/openclaw.json` 中的 `skills.load.extraDirs` 添加一个文件夹)。优先级为 `/skills` → `/.agents/skills` → `~/.agents/skills` → `~/.openclaw/skills` → 内置 → `skills.load.extraDirs`,因此托管覆盖仍然会优先于内置 Skills,而无需修改 git。如果你需要全局安装该 skill,但只让某些智能体可见,请将共享副本放在 `~/.openclaw/skills` 中,并通过 `agents.defaults.skills` 和 `agents.list[].skills` 控制可见性。只有真正值得上游采纳的修改才应该放在仓库中并通过 PR 提交。 - - 可以。通过 `~/.openclaw/openclaw.json` 中的 `skills.load.extraDirs` 添加额外目录(最低优先级)。默认优先级为 `/skills` → `/.agents/skills` → `~/.agents/skills` → `~/.openclaw/skills` → 内置 → `skills.load.extraDirs`。`clawhub` 默认安装到 `./skills`,OpenClaw 会在下一次会话中将其视为 `/skills`。如果某个 skill 只应对特定智能体可见,请再结合 `agents.defaults.skills` 或 `agents.list[].skills` 一起使用。 + + 可以。在 `~/.openclaw/openclaw.json` 中通过 `skills.load.extraDirs` 添加额外目录(最低优先级)。默认优先级是 `/skills` → `/.agents/skills` → `~/.agents/skills` → `~/.openclaw/skills` → 内置 → `skills.load.extraDirs`。`clawhub` 默认会安装到 `./skills`,OpenClaw 会在下一次会话中将其视为 `/skills`。如果某个 skill 只应对特定智能体可见,请结合 `agents.defaults.skills` 或 `agents.list[].skills` 使用。 当前支持的模式有: - **Cron 作业**:隔离作业可以为每个作业设置 `model` 覆盖。 - - **子智能体**:将任务路由到具有不同默认模型的独立智能体。 - - **按需切换**:随时使用 `/model` 切换当前会话模型。 + - **子智能体**:将任务路由给具有不同默认模型的独立智能体。 + - **按需切换**:使用 `/model` 随时切换当前会话模型。 - 请参阅 [Cron 作业](/zh-CN/automation/cron-jobs)、[多智能体路由](/zh-CN/concepts/multi-agent) 和 [斜杠命令](/zh-CN/tools/slash-commands)。 + 参见 [Cron jobs](/zh-CN/automation/cron-jobs)、[Multi-Agent Routing](/zh-CN/concepts/multi-agent) 和 [Slash commands](/zh-CN/tools/slash-commands)。 - - 对于长任务或并行任务,请使用**子智能体**。子智能体在自己的会话中运行, - 返回摘要,并保持你的主聊天保持响应。 + + 对于长时间任务或并行任务,请使用**子智能体**。子智能体运行在独立会话中, + 返回摘要,并让你的主聊天保持响应。 - 你可以让机器人“为这个任务生成一个子智能体”,或使用 `/subagents`。 - 使用聊天中的 `/status` 查看 Gateway 网关当前在做什么(以及它是否繁忙)。 + 让你的机器人“为这个任务生成一个子智能体”,或者使用 `/subagents`。 + 在聊天中使用 `/status` 可以查看 Gateway 网关当前正在做什么(以及它是否繁忙)。 - token 提示:长任务和子智能体都会消耗 token。如果成本是个问题,可以通过 `agents.defaults.subagents.model` 为子智能体设置一个 + 令牌提示:长任务和子智能体都会消耗令牌。如果你担心成本,可以通过 + `agents.defaults.subagents.model` 为子智能体设置一个 更便宜的模型。 - 文档:[子智能体](/zh-CN/tools/subagents)、[后台任务](/zh-CN/automation/tasks)。 + 文档:[Sub-agents](/zh-CN/tools/subagents)、[Background Tasks](/zh-CN/automation/tasks)。 - - 使用线程绑定。你可以把某个 Discord 线程绑定到一个子智能体或会话目标上,这样该线程中的后续消息就会一直停留在这个绑定的会话中。 + + 使用线程绑定。你可以将一个 Discord 线程绑定到某个子智能体或会话目标,这样该线程中的后续消息会持续发送到绑定的会话。 基本流程: - - 使用 `sessions_spawn` 并设置 `thread: true` 启动(可选地设置 `mode: "session"` 以实现持久后续跟进)。 + - 使用 `sessions_spawn` 并设置 `thread: true` 生成(如需持久跟进,可选 `mode: "session"`)。 - 或者通过 `/focus ` 手动绑定。 - - 使用 `/agents` 查看绑定状态。 - - 使用 `/session idle ` 和 `/session max-age ` 控制自动取消聚焦。 + - 使用 `/agents` 检查绑定状态。 + - 使用 `/session idle ` 和 `/session max-age ` 控制自动取消焦点。 - 使用 `/unfocus` 解除线程绑定。 所需配置: - 全局默认值:`session.threadBindings.enabled`、`session.threadBindings.idleHours`、`session.threadBindings.maxAgeHours`。 - - Discord 覆盖值:`channels.discord.threadBindings.enabled`、`channels.discord.threadBindings.idleHours`、`channels.discord.threadBindings.maxAgeHours`。 + - Discord 覆盖:`channels.discord.threadBindings.enabled`、`channels.discord.threadBindings.idleHours`、`channels.discord.threadBindings.maxAgeHours`。 - 生成时自动绑定:设置 `channels.discord.threadBindings.spawnSubagentSessions: true`。 - 文档:[子智能体](/zh-CN/tools/subagents)、[Discord](/zh-CN/channels/discord)、[配置参考](/zh-CN/gateway/configuration-reference)、[斜杠命令](/zh-CN/tools/slash-commands)。 + 文档:[Sub-agents](/zh-CN/tools/subagents)、[Discord](/zh-CN/channels/discord)、[Configuration Reference](/zh-CN/gateway/configuration-reference)、[Slash commands](/zh-CN/tools/slash-commands)。 - - 先检查解析后的请求方路由: + + 首先检查解析后的请求者路由: - - 完成模式的子智能体投递会优先使用任何已绑定的线程或会话路由。 - - 如果完成来源仅携带一个渠道,OpenClaw 会退回到请求方会话保存的路由(`lastChannel` / `lastTo` / `lastAccountId`),从而仍可实现直接投递。 - - 如果既没有绑定路由,也没有可用的已保存路由,则直接投递可能失败,结果会退回为排队会话投递,而不是立即发到聊天中。 - - 无效或过期的目标仍然可能导致退回到队列,或最终投递失败。 - - 如果子任务最后一条可见的助手回复恰好是静默 token `NO_REPLY` / `no_reply`,或恰好是 `ANNOUNCE_SKIP`,OpenClaw 会有意抑制通知,而不是发布陈旧的早期进度。 - - 如果子任务在只调用了工具之后超时,通知可能会将其压缩为简短的部分进展摘要,而不是重放原始工具输出。 + - 完成模式下的子智能体投递会优先使用任何已绑定的线程或会话路由(如果存在)。 + - 如果完成来源只携带了一个渠道,OpenClaw 会退回到请求者会话中存储的路由(`lastChannel` / `lastTo` / `lastAccountId`),这样仍然可以进行直接投递。 + - 如果既没有绑定路由,也没有可用的存储路由,直接投递可能失败,结果会退回到排队的会话投递,而不是立即发到聊天中。 + - 无效或陈旧的目标仍然可能导致回退到队列投递或最终投递失败。 + - 如果子会话最后一条可见助手回复恰好是静默令牌 `NO_REPLY` / `no_reply`,或者恰好是 `ANNOUNCE_SKIP`,OpenClaw 会有意抑制公告,而不会发布之前的旧进度。 + - 如果子会话在仅执行了工具调用后超时,公告可能会把这部分内容折叠为简短的部分进度摘要,而不是重放原始工具输出。 调试: @@ -1047,18 +1052,18 @@ x-i18n: openclaw tasks show ``` - 文档:[子智能体](/zh-CN/tools/subagents)、[后台任务](/zh-CN/automation/tasks)、[会话工具](/zh-CN/concepts/session-tool)。 + 文档:[Sub-agents](/zh-CN/tools/subagents)、[Background Tasks](/zh-CN/automation/tasks)、[Session Tools](/zh-CN/concepts/session-tool)。 - Cron 在 Gateway 网关进程内运行。如果 Gateway 网关没有持续运行, - 计划作业就不会执行。 + Cron 在 Gateway 网关进程内部运行。如果 Gateway 网关没有持续运行, + 定时作业就不会执行。 检查清单: - - 确认已启用 cron(`cron.enabled`),并且没有设置 `OPENCLAW_SKIP_CRON`。 - - 检查 Gateway 网关是否 24/7 持续运行(没有睡眠 / 重启)。 + - 确认 cron 已启用(`cron.enabled`),并且未设置 `OPENCLAW_SKIP_CRON`。 + - 检查 Gateway 网关是否 24/7 运行(没有休眠/重启)。 - 验证作业的时区设置(`--tz` 与主机时区)。 调试: @@ -1068,21 +1073,21 @@ x-i18n: openclaw cron runs --id --limit 50 ``` - 文档:[Cron 作业](/zh-CN/automation/cron-jobs)、[自动化与任务](/zh-CN/automation)。 + 文档:[Cron jobs](/zh-CN/automation/cron-jobs)、[Automation & Tasks](/zh-CN/automation)。 - + 先检查投递模式: - - `--no-deliver` / `delivery.mode: "none"` 表示预期不会发送任何外部消息。 - - 缺失或无效的通知目标(`channel` / `to`)表示运行器跳过了出站投递。 - - 渠道认证失败(`unauthorized`、`Forbidden`)表示运行器尝试了投递,但凭证阻止了它。 - - 静默的隔离结果(仅有 `NO_REPLY` / `no_reply`)会被视为有意不可投递,因此运行器也会抑制排队回退投递。 + - `--no-deliver` / `delivery.mode: "none"` 表示不会有外部消息。 + - 缺少或无效的公告目标(`channel` / `to`)意味着运行器跳过了对外投递。 + - 渠道认证失败(`unauthorized`、`Forbidden`)表示运行器尝试投递了,但被凭证阻止。 + - 静默的隔离结果(只有 `NO_REPLY` / `no_reply`)会被视为有意不可投递,因此运行器也会抑制队列回退投递。 - 对于隔离的 cron 作业,最终投递由运行器负责。智能体应当 - 返回一个纯文本摘要供运行器发送。`--no-deliver` 会将 - 结果保留在内部;它并不意味着允许智能体改为通过 + 对于隔离 cron 作业,最终投递由运行器负责。期望智能体 + 返回一个纯文本摘要,由运行器发送。`--no-deliver` 只是让 + 该结果保留在内部;它并不是让智能体改用 message 工具直接发送。 调试: @@ -1092,27 +1097,27 @@ x-i18n: openclaw tasks show ``` - 文档:[Cron 作业](/zh-CN/automation/cron-jobs)、[后台任务](/zh-CN/automation/tasks)。 + 文档:[Cron jobs](/zh-CN/automation/cron-jobs)、[Background Tasks](/zh-CN/automation/tasks)。 - + 这通常是实时模型切换路径,而不是重复调度。 - 隔离的 cron 会在活动运行抛出 `LiveSessionModelSwitchError` 时, - 持久化运行时模型切换并重试。重试会保留切换后的 - provider/model;如果该切换还携带了新的 auth profile 覆盖,cron - 也会在重试前持久化它。 + 隔离 cron 在活动运行抛出 `LiveSessionModelSwitchError` 时, + 可以持久化一个运行时模型切换并进行重试。重试会保留切换后的 + 提供商/模型,如果切换还携带了新的认证配置文件覆盖, + cron 也会在重试前将其持久化。 相关选择规则: - - 若适用,Gmail hook 模型覆盖优先级最高。 + - 如适用,Gmail hook 模型覆盖优先级最高。 - 然后是每个作业的 `model`。 - - 然后是任何已保存的 cron 会话模型覆盖。 - - 最后才是普通的智能体 / 默认模型选择。 + - 然后是任何已存储的 cron 会话模型覆盖。 + - 最后是普通的智能体/默认模型选择。 - 重试循环是有上限的。经过初次尝试再加上 2 次切换重试后, - cron 会中止,而不会无限循环。 + 重试循环是有边界的。初次尝试再加 2 次切换重试之后, + cron 会中止,而不是无限循环。 调试: @@ -1121,13 +1126,13 @@ x-i18n: openclaw tasks show ``` - 文档:[Cron 作业](/zh-CN/automation/cron-jobs)、[cron CLI](/cli/cron)。 + 文档:[Cron jobs](/zh-CN/automation/cron-jobs)、[cron CLI](/cli/cron)。 - 使用原生 `openclaw skills` 命令,或将 Skills 放入你的工作区。macOS 的 Skills UI 在 Linux 上不可用。 - 可在 [https://clawhub.ai](https://clawhub.ai) 浏览 Skills。 + 使用原生 `openclaw skills` 命令,或将 Skills 直接放入你的工作区。macOS 的 Skills UI 在 Linux 上不可用。 + 在 [https://clawhub.ai](https://clawhub.ai) 浏览 Skills。 ```bash openclaw skills search "calendar" @@ -1140,39 +1145,41 @@ x-i18n: openclaw skills check ``` - 原生 `openclaw skills install` 会写入当前工作区的 `skills/` - 目录。只有在你想发布或同步自己的 Skills 时,才需要安装独立的 `clawhub` CLI。若要让多个智能体共享安装,请将 skill 放到 `~/.openclaw/skills` 下,并在需要缩小可见范围时使用 `agents.defaults.skills` 或 - `agents.list[].skills`。 + 原生 `openclaw skills install` 会写入当前活动工作区的 `skills/` + 目录。只有在你想发布或 + 同步自己的 Skills 时,才需要安装单独的 `clawhub` CLI。若要在多个智能体之间共享安装,请将该 skill 放到 + `~/.openclaw/skills` 下,并使用 `agents.defaults.skills` 或 + `agents.list[].skills` 来缩小哪些智能体可见。 - + 可以。使用 Gateway 网关调度器: - - **Cron 作业**:适用于定时或周期性任务(在重启后仍会保留)。 - - **Heartbeat**:用于“主会话”的周期性检查。 - - **隔离作业**:用于自主智能体发布摘要或向聊天投递结果。 + - **Cron 作业**:用于计划任务或循环任务(重启后仍保留)。 + - **Heartbeat**:用于“主会话”周期性检查。 + - **隔离作业**:用于可自主运行并发布摘要或投递到聊天的智能体。 - 文档:[Cron 作业](/zh-CN/automation/cron-jobs)、[自动化与任务](/zh-CN/automation)、 + 文档:[Cron jobs](/zh-CN/automation/cron-jobs)、[Automation & Tasks](/zh-CN/automation)、 [Heartbeat](/zh-CN/gateway/heartbeat)。 - - 不能直接运行。macOS Skills 受 `metadata.openclaw.os` 及所需二进制文件控制,并且只有在 **Gateway 网关主机** 上满足条件时,Skills 才会出现在系统提示中。在 Linux 上,仅限 `darwin` 的 Skills(例如 `apple-notes`、`apple-reminders`、`things-mac`)不会加载,除非你覆盖了这些限制。 + + 不能直接运行。macOS Skills 受 `metadata.openclaw.os` 和必需二进制约束,而且只有当它们在**Gateway 网关主机**上符合条件时,才会出现在系统提示中。在 Linux 上,仅限 `darwin` 的 Skills(如 `apple-notes`、`apple-reminders`、`things-mac`)不会加载,除非你覆盖这些限制。 - 有三种受支持的模式: + 你有三种受支持模式: **选项 A - 在 Mac 上运行 Gateway 网关(最简单)。** - 在存在 macOS 二进制文件的地方运行 Gateway 网关,然后通过 [远程模式](#gateway-ports-already-running-and-remote-mode) 或 Tailscale 从 Linux 连接。由于 Gateway 网关主机是 macOS,Skills 会正常加载。 + 在存在 macOS 二进制的地方运行 Gateway 网关,然后从 Linux 通过 [远程模式](#gateway-网关端口已被占用和远程模式) 或 Tailscale 连接。由于 Gateway 网关主机是 macOS,这些 Skills 会正常加载。 **选项 B - 使用 macOS 节点(无需 SSH)。** - 在 Linux 上运行 Gateway 网关,配对一个 macOS 节点(菜单栏应用),并在 Mac 上将**节点运行命令**设置为 “Always Ask” 或 “Always Allow”。当节点上存在所需二进制文件时,OpenClaw 可以将 macOS 专属 Skills 视为符合条件。智能体会通过 `nodes` 工具运行这些 Skills。如果你选择 “Always Ask”,在提示中批准 “Always Allow” 会将该命令加入允许列表。 + 在 Linux 上运行 Gateway 网关,配对一个 macOS 节点(菜单栏应用),并将 Mac 上的 **Node Run Commands** 设置为 “Always Ask” 或 “Always Allow”。当节点上存在所需二进制时,OpenClaw 可以将这些仅限 macOS 的 Skills 视为符合条件。智能体会通过 `nodes` 工具运行这些 Skills。如果你选择 “Always Ask”,那么在提示中批准 “Always Allow” 会将该命令加入允许列表。 - **选项 C - 通过 SSH 代理 macOS 二进制文件(高级)。** - 让 Gateway 网关继续运行在 Linux 上,但通过 SSH 包装器把所需 CLI 二进制文件解析到一台 Mac 上执行。然后覆盖该 skill,使其允许 Linux,从而保持符合条件。 + **选项 C - 通过 SSH 代理 macOS 二进制(高级)。** + 将 Gateway 网关保留在 Linux 上,但让必需的 CLI 二进制解析为 SSH 包装器,在 Mac 上执行。然后覆盖该 skill,使其允许 Linux,从而保持可用。 - 1. 为该二进制文件创建一个 SSH 包装器(示例:Apple Notes 的 `memo`): + 1. 为该二进制创建一个 SSH 包装器(示例:Apple Notes 的 `memo`): ```bash #!/usr/bin/env bash @@ -1180,35 +1187,36 @@ x-i18n: exec ssh -T user@mac-host /opt/homebrew/bin/memo "$@" ``` - 2. 将该包装器放入 Linux 主机的 `PATH` 中(例如 `~/bin/memo`)。 - 3. 覆盖 skill 元数据(工作区或 `~/.openclaw/skills`),使其允许 Linux: + 2. 将该包装器放到 Linux 主机的 `PATH` 中(例如 `~/bin/memo`)。 + 3. 覆盖 skill 元数据(工作区或 `~/.openclaw/skills`)以允许 Linux: ```markdown --- name: apple-notes - description: Manage Apple Notes via the memo CLI on macOS. + description: 通过 macOS 上的 memo CLI 管理 Apple Notes。 metadata: { "openclaw": { "os": ["darwin", "linux"], "requires": { "bins": ["memo"] } } } --- ``` - 4. 启动一个新会话以刷新 Skills 快照。 + 4. 开始一个新会话,以便刷新 Skills 快照。 目前没有内置。 - 可选方式: + 可选方案: - - **自定义 skill / plugin:**最适合可靠的 API 访问(Notion/HeyGen 都提供 API)。 + - **自定义 skill / 插件:**最适合可靠的 API 访问(Notion/HeyGen 都有 API)。 - **浏览器自动化:**无需写代码,但速度更慢,也更脆弱。 - 如果你想按客户保留上下文(例如代理机构工作流),一种简单模式是: + 如果你希望为每个客户保留上下文(例如代理机构工作流),一个简单模式是: - 每个客户一个 Notion 页面(上下文 + 偏好 + 当前工作)。 - - 在会话开始时让智能体先抓取那个页面。 + - 让智能体在会话开始时获取该页面。 - 如果你想要原生集成,可以提功能请求,或者自行构建一个针对这些 API 的 skill。 + 如果你想要原生集成,请提交功能请求,或构建一个 + 面向这些 API 的 skill。 安装 Skills: @@ -1217,180 +1225,180 @@ x-i18n: openclaw skills update --all ``` - 原生安装会落到当前工作区的 `skills/` 目录中。若要在多个智能体之间共享 Skills,请将它们放到 `~/.openclaw/skills//SKILL.md`。如果只希望部分智能体看到某个共享安装,请配置 `agents.defaults.skills` 或 `agents.list[].skills`。某些 Skills 需要通过 Homebrew 安装二进制文件;在 Linux 上这意味着 Linuxbrew(请参阅上文的 Homebrew Linux FAQ 条目)。请参阅 [Skills](/zh-CN/tools/skills)、[Skills 配置](/zh-CN/tools/skills-config) 和 [ClawHub](/zh-CN/tools/clawhub)。 + 原生安装会进入当前活动工作区的 `skills/` 目录。若要在多个智能体之间共享 Skills,请将它们放在 `~/.openclaw/skills//SKILL.md`。如果共享安装只应对部分智能体可见,请配置 `agents.defaults.skills` 或 `agents.list[].skills`。某些 Skills 需要通过 Homebrew 安装二进制;在 Linux 上,这意味着 Linuxbrew(参见上面的 Homebrew Linux 常见问题条目)。参见 [Skills](/zh-CN/tools/skills)、[Skills 配置](/zh-CN/tools/skills-config) 和 [ClawHub](/zh-CN/tools/clawhub)。 - - 使用内置的 `user` 浏览器 profile,它通过 Chrome DevTools MCP 附加到现有会话: + + 使用内置的 `user` 浏览器配置文件,它会通过 Chrome DevTools MCP 连接: ```bash openclaw browser --browser-profile user tabs openclaw browser --browser-profile user snapshot ``` - 如果你想使用自定义名称,可以创建一个显式 MCP profile: + 如果你想使用自定义名称,请创建一个显式 MCP 配置文件: ```bash openclaw browser create-profile --name chrome-live --driver existing-session openclaw browser --browser-profile chrome-live tabs ``` - 这条路径是主机本地的。如果 Gateway 网关运行在其他地方,要么在浏览器所在机器上运行节点主机,要么改用远程 CDP。 + 这条路径是主机本地的。如果 Gateway 网关运行在别处,那么你需要在浏览器所在机器上运行一个节点主机,或者改用远程 CDP。 `existing-session` / `user` 当前的限制: - - 操作基于 ref 驱动,而不是基于 CSS 选择器 - - 上传要求使用 `ref` / `inputRef`,并且当前一次只支持一个文件 - - `responsebody`、PDF 导出、下载拦截和批量操作仍然需要托管浏览器或原始 CDP profile + - 操作是基于 ref 驱动的,而不是基于 CSS 选择器 + - 上传需要 `ref` / `inputRef`,并且当前一次只支持一个文件 + - `responsebody`、PDF 导出、下载拦截和批量操作仍然需要托管浏览器或原始 CDP 配置文件 -## 沙箱隔离和内存 +## 沙箱隔离和记忆 - 有。请参阅 [沙箱隔离](/zh-CN/gateway/sandboxing)。对于 Docker 专属设置(完整 Gateway 网关运行在 Docker 中或使用沙箱镜像),请参阅 [Docker](/zh-CN/install/docker)。 + 有。参见 [沙箱隔离](/zh-CN/gateway/sandboxing)。关于 Docker 专用设置(完整 Gateway 网关运行在 Docker 中,或沙箱镜像),参见 [Docker](/zh-CN/install/docker)。 - - 默认镜像以安全优先,并以 `node` 用户运行,因此它不包含 - 系统包、Homebrew 或内置浏览器。要获得更完整的环境: + + 默认镜像以安全优先的方式运行,并使用 `node` 用户,因此它不 + 包含系统包、Homebrew 或内置浏览器。若要获得更完整的设置: - - 使用 `OPENCLAW_HOME_VOLUME` 持久化 `/home/node`,让缓存可以保留。 - - 使用 `OPENCLAW_DOCKER_APT_PACKAGES` 将系统依赖烘焙进镜像。 + - 持久化 `/home/node`,使用 `OPENCLAW_HOME_VOLUME`,这样缓存可以保留。 + - 使用 `OPENCLAW_DOCKER_APT_PACKAGES` 将系统依赖打包进镜像。 - 通过内置 CLI 安装 Playwright 浏览器: `node /app/node_modules/playwright-core/cli.js install chromium` - - 设置 `PLAYWRIGHT_BROWSERS_PATH` 并确保该路径是持久化的。 + - 设置 `PLAYWRIGHT_BROWSERS_PATH` 并确保该路径被持久化。 - 文档:[Docker](/zh-CN/install/docker)、[浏览器](/zh-CN/tools/browser)。 + 文档:[Docker](/zh-CN/install/docker)、[Browser](/zh-CN/tools/browser)。 - - 可以——前提是你的私有流量是**私信**,而公开流量是**群组**。 + + 可以——前提是你的私人流量是**私信**,公开流量是**群组**。 - 使用 `agents.defaults.sandbox.mode: "non-main"`,这样群组 / 渠道会话(非主键)会在 Docker 中运行,而主私信会话仍在主机上运行。然后通过 `tools.sandbox.tools` 限制沙箱会话中可用的工具。 + 使用 `agents.defaults.sandbox.mode: "non-main"`,这样群组/渠道会话(非主会话键)会在 Docker 中运行,而主私信会话仍在主机上运行。然后通过 `tools.sandbox.tools` 限制沙箱隔离会话中可用的工具。 - 设置演练 + 示例配置:[群组:个人私信 + 公开群组](/zh-CN/channels/groups#pattern-personal-dms-public-groups-single-agent) + 设置演练 + 示例配置:[Groups: personal DMs + public groups](/zh-CN/channels/groups#pattern-personal-dms-public-groups-single-agent) - 关键配置参考:[Gateway 网关配置](/zh-CN/gateway/configuration-reference#agentsdefaultssandbox) + 关键配置参考:[Gateway configuration](/zh-CN/gateway/configuration-reference#agentsdefaultssandbox) - 将 `agents.defaults.sandbox.docker.binds` 设置为 `["host:path:mode"]`(例如 `"/home/user/src:/src:ro"`)。全局和按智能体的绑定会合并;当 `scope: "shared"` 时,每个智能体的绑定会被忽略。对于敏感内容请使用 `:ro`,并记住绑定会绕过沙箱文件系统边界。 + 将 `agents.defaults.sandbox.docker.binds` 设置为 `["host:path:mode"]`(例如 `"/home/user/src:/src:ro"`)。全局和按智能体的绑定会合并;当 `scope: "shared"` 时,会忽略按智能体的绑定。对任何敏感内容都请使用 `:ro`,并记住绑定会绕过沙箱文件系统边界。 - OpenClaw 会同时根据规范化路径以及通过最深存在祖先解析出的规范路径来验证绑定源。这意味着即使最后一个路径段尚不存在,父级符号链接逃逸仍会以失败关闭的方式被阻止,并且在符号链接解析之后仍会应用允许根路径检查。 + OpenClaw 会根据规范化路径和通过最深已存在祖先解析出的规范路径同时验证绑定源。这意味着即使最后一个路径段尚不存在,通过符号链接父目录逃逸仍会以封闭失败的方式被阻止,并且在符号链接解析后,允许根目录检查仍然适用。 - 示例和安全说明请参阅 [沙箱隔离](/zh-CN/gateway/sandboxing#custom-bind-mounts) 和 [沙箱 vs 工具策略 vs 提权](/zh-CN/gateway/sandbox-vs-tool-policy-vs-elevated#bind-mounts-security-quick-check)。 + 示例和安全说明请参见 [Sandboxing](/zh-CN/gateway/sandboxing#custom-bind-mounts) 和 [Sandbox vs Tool Policy vs Elevated](/zh-CN/gateway/sandbox-vs-tool-policy-vs-elevated#bind-mounts-security-quick-check)。 - - OpenClaw 的内存其实就是智能体工作区中的 Markdown 文件: + + OpenClaw 记忆本质上就是智能体工作区中的 Markdown 文件: - - 每日笔记保存在 `memory/YYYY-MM-DD.md` - - 整理后的长期笔记保存在 `MEMORY.md`(仅主 / 私密会话) + - 每日笔记位于 `memory/YYYY-MM-DD.md` + - 精选的长期笔记位于 `MEMORY.md`(仅主/私密会话) - OpenClaw 还会在压缩前运行一个**静默的预压缩内存刷新**,提醒模型 - 在自动压缩前写入持久笔记。该过程只会在工作区 - 可写时运行(只读沙箱会跳过)。请参阅 [内存](/zh-CN/concepts/memory)。 + OpenClaw 还会运行一个**静默的压缩前记忆刷新**,提醒模型 + 在自动压缩前写入持久笔记。这只会在工作区 + 可写时运行(只读沙箱会跳过)。参见 [Memory](/zh-CN/concepts/memory)。 - - 让机器人**把事实写入内存**。长期笔记应写入 `MEMORY.md`, + + 让机器人**把事实写入记忆**。长期笔记应写入 `MEMORY.md`, 短期上下文写入 `memory/YYYY-MM-DD.md`。 - 这仍是我们在持续改进的领域。提醒模型去存储内存会很有帮助; - 它会知道该怎么做。如果它还是忘记,请确认 Gateway 网关每次运行时都在使用相同的 + 这是我们仍在持续改进的领域。提醒模型存储记忆会有帮助; + 它会知道该怎么做。如果它仍然持续遗忘,请确认 Gateway 网关每次运行时都在使用同一个 工作区。 - 文档:[内存](/zh-CN/concepts/memory)、[智能体工作区](/zh-CN/concepts/agent-workspace)。 + 文档:[Memory](/zh-CN/concepts/memory)、[Agent workspace](/zh-CN/concepts/agent-workspace)。 - - 内存文件存储在磁盘上,除非你手动删除,否则会一直保留。限制来自你的 - 存储空间,而不是模型。**会话上下文**仍受模型上下文窗口 - 限制,因此长对话可能会被压缩或截断。这正是 - 内存搜索存在的原因——它只会把相关部分重新拉回上下文中。 + + 记忆文件存储在磁盘上,除非你删除,否则会一直保留。限制来自你的 + 存储空间,而不是模型。**会话上下文**仍然受模型 + 上下文窗口限制,因此长对话可能会压缩或截断。这就是为什么 + 需要记忆搜索——它只会把相关部分拉回上下文。 - 文档:[内存](/zh-CN/concepts/memory)、[上下文](/zh-CN/concepts/context)。 + 文档:[Memory](/zh-CN/concepts/memory)、[Context](/zh-CN/concepts/context)。 - - 只有在你使用 **OpenAI embeddings** 时才需要。Codex OAuth 只覆盖聊天 / completions, - **不**提供 embeddings 访问,因此**使用 Codex 登录(OAuth 或 - Codex CLI 登录)**对语义内存搜索没有帮助。OpenAI embeddings - 仍然需要真实 API 密钥(`OPENAI_API_KEY` 或 `models.providers.openai.apiKey`)。 + + 只有在你使用 **OpenAI embeddings** 时才需要。Codex OAuth 只覆盖聊天/补全, + **不**提供 embeddings 访问,因此**仅使用 Codex 登录(OAuth 或 + Codex CLI 登录)**对语义记忆搜索没有帮助。OpenAI embeddings + 仍然需要真实的 API key(`OPENAI_API_KEY` 或 `models.providers.openai.apiKey`)。 - 如果你没有显式设置提供商,OpenClaw 会在 - 能解析到 API 密钥时自动选择一个提供商(auth profile、`models.providers.*.apiKey` 或环境变量)。 - 如果能解析到 OpenAI 密钥,它会优先选择 OpenAI;否则如果能解析到 Gemini 密钥,则选择 Gemini; - 接着是 Voyage,然后是 Mistral。如果没有可用的远程密钥, - 内存搜索会保持禁用,直到你进行配置。如果你配置并存在本地模型路径,OpenClaw + 如果你没有显式设置提供商,OpenClaw 会在能解析出 API key 时 + 自动选择一个提供商(认证配置文件、`models.providers.*.apiKey` 或环境变量)。 + 如果能解析出 OpenAI 密钥,它会优先选择 OpenAI;否则如果能解析出 Gemini 密钥, + 就会选择 Gemini;然后是 Voyage,再然后是 Mistral。如果没有任何远程密钥可用, + 记忆搜索会保持禁用状态,直到你完成配置。如果你配置并提供了本地模型路径,OpenClaw 会优先选择 `local`。当你显式设置 `memorySearch.provider = "ollama"` 时,也支持 Ollama。 - 如果你更想保持本地化,可设置 `memorySearch.provider = "local"`(并可选地 - 设置 `memorySearch.fallback = "none"`)。如果你想使用 Gemini embeddings,请设置 + 如果你希望保持纯本地,请设置 `memorySearch.provider = "local"`(可选再加上 + `memorySearch.fallback = "none"`)。如果你想使用 Gemini embeddings,请设置 `memorySearch.provider = "gemini"` 并提供 `GEMINI_API_KEY`(或 - `memorySearch.remote.apiKey`)。我们支持 **OpenAI、Gemini、Voyage、Mistral、Ollama 或 local** embeddings - 模型——设置详情请参阅 [内存](/zh-CN/concepts/memory)。 + `memorySearch.remote.apiKey`)。我们支持 **OpenAI、Gemini、Voyage、Mistral、Ollama 或 local** embedding + 模型——设置细节请参见 [Memory](/zh-CN/concepts/memory)。 -## 磁盘上的文件位置 +## 文件在磁盘上的位置 - 不会——**OpenClaw 的状态是本地的**,但**外部服务仍会看到你发送给它们的内容**。 + 不会——**OpenClaw 的状态是本地的**,但**外部服务仍然会看到你发给它们的内容**。 - - **默认保存在本地:**会话、内存文件、配置和工作区都位于 Gateway 网关主机上 + - **默认本地:**会话、记忆文件、配置和工作区都位于 Gateway 网关主机上 (`~/.openclaw` + 你的工作区目录)。 - - **必须远程发送:**你发送给模型提供商(Anthropic/OpenAI 等)的消息会进入 - 它们的 API,而聊天平台(WhatsApp/Telegram/Slack 等)也会将消息数据存储在 - 它们的服务器上。 - - **你可以控制影响范围:**使用本地模型可让提示保留在你的机器上,但渠道 - 流量仍会经过相应渠道的服务器。 + - **必然远程:**你发送给模型提供商(Anthropic/OpenAI 等)的消息会进入 + 他们的 API,而聊天平台(WhatsApp/Telegram/Slack 等)会在它们的 + 服务器上存储消息数据。 + - **你可以控制暴露范围:**使用本地模型可将提示保留在你的机器上,但渠道 + 流量仍会经过该渠道的服务器。 - 相关内容:[智能体工作区](/zh-CN/concepts/agent-workspace)、[内存](/zh-CN/concepts/memory)。 + 相关内容:[Agent workspace](/zh-CN/concepts/agent-workspace)、[Memory](/zh-CN/concepts/memory)。 - + 所有内容都位于 `$OPENCLAW_STATE_DIR` 下(默认:`~/.openclaw`): - | Path | 用途 | - | --------------------------------------------------------------- | ------------------------------------------------------------------- | - | `$OPENCLAW_STATE_DIR/openclaw.json` | 主配置(JSON5) | - | `$OPENCLAW_STATE_DIR/credentials/oauth.json` | 旧版 OAuth 导入(首次使用时复制到 auth profile 中) | - | `$OPENCLAW_STATE_DIR/agents//agent/auth-profiles.json` | Auth profile(OAuth、API 密钥,以及可选的 `keyRef`/`tokenRef`) | - | `$OPENCLAW_STATE_DIR/secrets.json` | 可选的文件后备 secret 载荷,用于 `file` SecretRef 提供商 | - | `$OPENCLAW_STATE_DIR/agents//agent/auth.json` | 旧版兼容文件(静态 `api_key` 条目已清理) | - | `$OPENCLAW_STATE_DIR/credentials/` | 提供商状态(例如 `whatsapp//creds.json`) | - | `$OPENCLAW_STATE_DIR/agents/` | 每个智能体的状态(agentDir + sessions) | - | `$OPENCLAW_STATE_DIR/agents//sessions/` | 会话历史和状态(按智能体分开) | - | `$OPENCLAW_STATE_DIR/agents//sessions/sessions.json` | 会话元数据(按智能体分开) | + | 路径 | 用途 | + | --------------------------------------------------------------- | ------------------------------------------------------------------ | + | `$OPENCLAW_STATE_DIR/openclaw.json` | 主配置(JSON5) | + | `$OPENCLAW_STATE_DIR/credentials/oauth.json` | 旧版 OAuth 导入(首次使用时复制到认证配置文件) | + | `$OPENCLAW_STATE_DIR/agents//agent/auth-profiles.json` | 认证配置文件(OAuth、API key,以及可选的 `keyRef`/`tokenRef`) | + | `$OPENCLAW_STATE_DIR/secrets.json` | `file` SecretRef 提供商的可选文件型 secret 载荷 | + | `$OPENCLAW_STATE_DIR/agents//agent/auth.json` | 旧版兼容文件(静态 `api_key` 条目已被清理) | + | `$OPENCLAW_STATE_DIR/credentials/` | 提供商状态(例如 `whatsapp//creds.json`) | + | `$OPENCLAW_STATE_DIR/agents/` | 每个智能体的状态(agentDir + 会话) | + | `$OPENCLAW_STATE_DIR/agents//sessions/` | 对话历史和状态(按智能体) | + | `$OPENCLAW_STATE_DIR/agents//sessions/sessions.json` | 会话元数据(按智能体) | 旧版单智能体路径:`~/.openclaw/agent/*`(由 `openclaw doctor` 迁移)。 - 你的**工作区**(AGENTS.md、内存文件、Skills 等)是单独的,并通过 `agents.defaults.workspace` 配置(默认:`~/.openclaw/workspace`)。 + 你的**工作区**(AGENTS.md、记忆文件、Skills 等)是分开的,通过 `agents.defaults.workspace` 配置(默认:`~/.openclaw/workspace`)。 这些文件位于**智能体工作区**中,而不是 `~/.openclaw`。 - - **工作区(每个智能体)**:`AGENTS.md`、`SOUL.md`、`IDENTITY.md`、`USER.md`、 - `MEMORY.md`(若 `MEMORY.md` 不存在,则使用旧版回退 `memory.md`)、 - `memory/YYYY-MM-DD.md`、可选的 `HEARTBEAT.md`。 - - **状态目录(`~/.openclaw`)**:配置、渠道 / 提供商状态、auth profile、sessions、logs, + - **工作区(按智能体):**`AGENTS.md`、`SOUL.md`、`IDENTITY.md`、`USER.md`、 + `MEMORY.md`(或在 `MEMORY.md` 缺失时使用旧版回退 `memory.md`)、 + `memory/YYYY-MM-DD.md`,可选的 `HEARTBEAT.md`。 + - **状态目录(`~/.openclaw`):**配置、渠道/提供商状态、认证配置文件、会话、日志, 以及共享 Skills(`~/.openclaw/skills`)。 默认工作区是 `~/.openclaw/workspace`,可通过以下方式配置: @@ -1401,42 +1409,42 @@ x-i18n: } ``` - 如果机器人在重启后“忘记”了内容,请确认 Gateway 网关每次启动时都在使用相同的 - 工作区(并记住:远程模式使用的是**gateway 主机的** + 如果机器人在重启后“忘事”,请确认 Gateway 网关每次启动时都在使用同一个 + 工作区(并记住:远程模式使用的是**gateway host 的** 工作区,而不是你的本地笔记本)。 - 提示:如果你希望保留某个长期行为或偏好,请让机器人**把它写入 + 提示:如果你想保留某种长期行为或偏好,应该让机器人**把它写入 AGENTS.md 或 MEMORY.md**,而不是依赖聊天历史。 - 请参阅 [智能体工作区](/zh-CN/concepts/agent-workspace) 和 [内存](/zh-CN/concepts/memory)。 + 参见 [Agent workspace](/zh-CN/concepts/agent-workspace) 和 [Memory](/zh-CN/concepts/memory)。 - 将你的**智能体工作区**放到一个**私有** git 仓库中,并备份到其他 - 私有位置(例如 GitHub 私有仓库)。这样可以保留内存 + AGENTS/SOUL/USER - 文件,并让你之后恢复助手的“思维”。 + 将你的**智能体工作区**放到一个**私有** git 仓库中,并备份到某个 + 私有位置(例如 GitHub private)。这样可以保存记忆 + AGENTS/SOUL/USER + 文件,并在以后恢复助手的“思维状态”。 - **不要**提交 `~/.openclaw` 下的任何内容(凭证、会话、token 或加密 secrets 载荷)。 + **不要**提交 `~/.openclaw` 下的任何内容(凭证、会话、令牌或加密 secret 载荷)。 如果你需要完整恢复,请分别备份工作区和状态目录 - (见上面的迁移问题)。 + (参见上面的迁移问题)。 - 文档:[智能体工作区](/zh-CN/concepts/agent-workspace)。 + 文档:[Agent workspace](/zh-CN/concepts/agent-workspace)。 - 请参阅专门指南:[卸载](/zh-CN/install/uninstall)。 + 请参见专门指南:[Uninstall](/zh-CN/install/uninstall)。 - 可以。工作区是**默认 cwd** 和内存锚点,而不是硬性沙箱。 - 相对路径会在工作区内解析,但绝对路径仍可访问其他 + 可以。工作区是**默认 cwd** 和记忆锚点,而不是硬性沙箱。 + 相对路径会解析到工作区内,但绝对路径仍然可以访问其他 主机位置,除非启用了沙箱隔离。如果你需要隔离,请使用 - [`agents.defaults.sandbox`](/zh-CN/gateway/sandboxing) 或按智能体设置的沙箱配置。如果你 - 想让某个仓库成为默认工作目录,就把那个智能体的 - `workspace` 指向仓库根目录。OpenClaw 仓库本身只是源码;除非你明确希望智能体在其中工作,否则应将 - 工作区与仓库分开。 + [`agents.defaults.sandbox`](/zh-CN/gateway/sandboxing) 或按智能体的沙箱设置。如果你 + 希望某个仓库成为默认工作目录,请将该智能体的 + `workspace` 指向该仓库根目录。OpenClaw 仓库本身只是源码;除非你明确想让智能体在其中工作,否则应将 + 工作区与其分开。 示例(将仓库作为默认 cwd): @@ -1453,28 +1461,28 @@ x-i18n: - 会话状态归**gateway 主机**所有。如果你使用远程模式,那么你关心的会话存储在远程机器上,而不是本地笔记本。请参阅 [会话管理](/zh-CN/concepts/session)。 + 会话状态由 **gateway host** 持有。如果你处于远程模式,你真正关心的会话存储位于远程机器上,而不是你的本地笔记本。参见 [Session management](/zh-CN/concepts/session)。 ## 配置基础 - - OpenClaw 会从 `$OPENCLAW_CONFIG_PATH` 读取可选的 **JSON5** 配置(默认:`~/.openclaw/openclaw.json`): + + OpenClaw 从 `$OPENCLAW_CONFIG_PATH` 读取一个可选的 **JSON5** 配置(默认:`~/.openclaw/openclaw.json`): ``` $OPENCLAW_CONFIG_PATH ``` - 如果文件不存在,它会使用相对安全的默认值(包括默认工作区 `~/.openclaw/workspace`)。 + 如果文件缺失,它会使用相对安全的默认值(包括默认工作区 `~/.openclaw/workspace`)。 - - 非 loopback 绑定**要求存在有效的 gateway 认证路径**。实践中这意味着: + + 非 loopback 绑定**要求有一个有效的 gateway 认证路径**。实际来说,这意味着: - - shared-secret 认证:token 或 password + - 共享密钥认证:令牌或密码 - 在正确配置的非 loopback 身份感知反向代理后使用 `gateway.auth.mode: "trusted-proxy"` ```json5 @@ -1489,29 +1497,29 @@ x-i18n: } ``` - 说明: + 注意: - - `gateway.remote.token` / `.password` 本身**不会**启用本地 gateway 认证。 - - 仅当 `gateway.auth.*` 未设置时,本地调用路径才会把 `gateway.remote.*` 用作回退。 - - 对于 password 认证,请设置 `gateway.auth.mode: "password"`,并配置 `gateway.auth.password`(或 `OPENCLAW_GATEWAY_PASSWORD`)。 - - 如果 `gateway.auth.token` / `gateway.auth.password` 通过 SecretRef 显式配置但无法解析,则会以失败关闭方式处理(不会被远程回退掩盖)。 - - shared-secret 的 Control UI 设置通过 `connect.params.auth.token` 或 `connect.params.auth.password` 进行认证(存储在应用 / UI 设置中)。像 Tailscale Serve 或 `trusted-proxy` 这样的身份承载模式则使用请求头。避免把 shared secret 放进 URL 中。 - - 使用 `gateway.auth.mode: "trusted-proxy"` 时,同一主机上的 loopback 反向代理仍**不能**满足 trusted-proxy 认证。trusted proxy 必须是已配置的非 loopback 来源。 + - `gateway.remote.token` / `.password` **本身不会**启用本地 gateway 认证。 + - 只有在 `gateway.auth.*` 未设置时,本地调用路径才会将 `gateway.remote.*` 用作回退。 + - 对于密码认证,请改设 `gateway.auth.mode: "password"` 并同时设置 `gateway.auth.password`(或 `OPENCLAW_GATEWAY_PASSWORD`)。 + - 如果通过 SecretRef 显式配置了 `gateway.auth.token` / `gateway.auth.password` 但无法解析,解析会以封闭失败方式结束(不会被远程回退掩盖)。 + - 共享密钥 Control UI 配置通过 `connect.params.auth.token` 或 `connect.params.auth.password` 认证(存储在应用/UI 设置中)。像 Tailscale Serve 或 `trusted-proxy` 这类带身份的模式则改用请求头。避免把共享密钥放进 URL。 + - 使用 `gateway.auth.mode: "trusted-proxy"` 时,同一主机上的 loopback 反向代理**仍然不**满足 trusted-proxy 认证。trusted proxy 必须是已配置的非 loopback 来源。 - - OpenClaw 默认强制执行 gateway 认证,包括 loopback。在普通默认路径中,这意味着 token 认证:如果没有显式配置任何认证路径,gateway 启动时会解析为 token 模式并自动生成一个 token,保存到 `gateway.auth.token` 中,因此**本地 WS 客户端也必须认证**。这样可以阻止其他本地进程调用 Gateway 网关。 + + OpenClaw 默认强制执行 gateway 认证,包括 loopback。按通常的默认路径,这意味着令牌认证:如果没有显式配置认证路径,gateway 启动时会解析到令牌模式并自动生成一个令牌,保存到 `gateway.auth.token` 中,因此**本地 WS 客户端也必须认证**。这样可以阻止其他本地进程调用 Gateway 网关。 - 如果你更喜欢其他认证路径,可以显式选择 password 模式(或在非 loopback 的身份感知反向代理场景中选择 `trusted-proxy`)。如果你**真的**想开放 loopback,请在配置中显式设置 `gateway.auth.mode: "none"`。你随时可以让 Doctor 为你生成 token:`openclaw doctor --generate-gateway-token`。 + 如果你更喜欢其他认证路径,可以显式选择密码模式(或者,对于非 loopback 的身份感知反向代理,使用 `trusted-proxy`)。如果你**真的**想开放 loopback,请在配置中显式设置 `gateway.auth.mode: "none"`。Doctor 可随时帮你生成令牌:`openclaw doctor --generate-gateway-token`。 - Gateway 网关会监视配置并支持热重载: + Gateway 网关会监视配置,并支持热重载: - `gateway.reload.mode: "hybrid"`(默认):安全变更热应用,关键变更则重启 - - 也支持 `hot`、`restart`、`off` + - 同时也支持 `hot`、`restart`、`off` @@ -1528,21 +1536,21 @@ x-i18n: } ``` - - `off`:隐藏标语文本,但保留横幅标题 / 版本行。 - - `default`:始终使用 `All your chats, one OpenClaw.`。 - - `random`:轮换有趣 / 节日标语(默认行为)。 - - 如果你完全不想显示横幅,可设置环境变量 `OPENCLAW_HIDE_BANNER=1`。 + - `off`:隐藏标语文本,但保留横幅标题/版本行。 + - `default`:每次都使用 `All your chats, one OpenClaw.`。 + - `random`:轮换有趣/季节性标语(默认行为)。 + - 如果你想完全不显示横幅,请设置环境变量 `OPENCLAW_HIDE_BANNER=1`。 - `web_fetch` 无需 API 密钥即可工作。`web_search` 则取决于你选择的 + `web_fetch` 无需 API key 即可工作。`web_search` 取决于你所选的 提供商: - - Brave、Exa、Firecrawl、Gemini、Grok、Kimi、MiniMax Search、Perplexity 和 Tavily 等基于 API 的提供商需要其常规 API 密钥配置。 - - Ollama Web 搜索无需密钥,但它使用你配置的 Ollama 主机,并要求执行 `ollama signin`。 - - DuckDuckGo 无需密钥,但它是一个非官方的基于 HTML 的集成。 - - SearXNG 无需密钥 / 可自托管;配置 `SEARXNG_BASE_URL` 或 `plugins.entries.searxng.config.webSearch.baseUrl`。 + - Brave、Exa、Firecrawl、Gemini、Grok、Kimi、MiniMax Search、Perplexity 和 Tavily 等基于 API 的提供商需要按其正常方式配置 API key。 + - Ollama Web 搜索不需要密钥,但它使用你配置的 Ollama 主机,并要求执行 `ollama signin`。 + - DuckDuckGo 不需要密钥,但这是一个基于 HTML 的非官方集成。 + - SearXNG 不需要密钥/可自托管;请配置 `SEARXNG_BASE_URL` 或 `plugins.entries.searxng.config.webSearch.baseUrl`。 **推荐:**运行 `openclaw configure --section web` 并选择一个提供商。 环境变量替代方案: @@ -1588,57 +1596,57 @@ x-i18n: ``` 提供商特定的 Web 搜索配置现在位于 `plugins.entries..config.webSearch.*` 下。 - 出于兼容性,旧版 `tools.web.search.*` 提供商路径暂时仍可加载,但不应再用于新配置。 + 旧版 `tools.web.search.*` 提供商路径目前仍会为兼容性而临时加载,但不应用于新配置。 Firecrawl Web 抓取回退配置位于 `plugins.entries.firecrawl.config.webFetch.*` 下。 - 说明: + 注意: - - 如果你使用 allowlist,请加入 `web_search`/`web_fetch`/`x_search` 或 `group:web`。 + - 如果你使用允许列表,请添加 `web_search`/`web_fetch`/`x_search` 或 `group:web`。 - `web_fetch` 默认启用(除非显式禁用)。 - - 如果省略 `tools.web.fetch.provider`,OpenClaw 会从可用凭证中自动检测第一个可用的抓取回退提供商。当前内置提供商是 Firecrawl。 + - 如果省略 `tools.web.fetch.provider`,OpenClaw 会根据可用凭证自动检测第一个可用的抓取回退提供商。目前内置提供商是 Firecrawl。 - 守护进程会从 `~/.openclaw/.env`(或服务环境)读取环境变量。 - 文档:[Web 工具](/zh-CN/tools/web)。 + 文档:[Web tools](/zh-CN/tools/web)。 - `config.apply` 会替换**整个配置**。如果你发送的是部分对象,其余所有内容 - 都会被移除。 + `config.apply` 会替换**整个配置**。如果你发送的是部分对象, + 其他所有内容都会被移除。 恢复方法: - 从备份恢复(git 或复制的 `~/.openclaw/openclaw.json`)。 - - 如果没有备份,请重新运行 `openclaw doctor` 并重新配置 channels/models。 - - 如果这并非预期行为,请提交一个 bug,并附上你已知的最后配置或任何备份。 - - 一个本地编码智能体通常可以从日志或历史中重建可用配置。 + - 如果没有备份,请重新运行 `openclaw doctor` 并重新配置渠道/模型。 + - 如果这不是你预期的行为,请提交 bug,并附上你最后已知的配置或任何备份。 + - 本地编码智能体通常可以根据日志或历史重建一个可工作的配置。 避免方式: - - 小修改请使用 `openclaw config set`。 + - 小改动请使用 `openclaw config set`。 - 交互式编辑请使用 `openclaw configure`。 - - 当你不确定确切路径或字段形状时,先使用 `config.schema.lookup`;它会返回一个浅层 schema 节点,以及用于逐步钻取的直接子节点摘要。 - - 部分 RPC 编辑请使用 `config.patch`;仅在需要完整替换配置时才使用 `config.apply`。 - - 如果你是在智能体运行中使用仅所有者可用的 `gateway` 工具,它仍会拒绝写入 `tools.exec.ask` / `tools.exec.security`(包括会标准化到相同受保护 exec 路径的旧版 `tools.bash.*` 别名)。 + - 当你不确定精确路径或字段结构时,先使用 `config.schema.lookup`;它会返回一个浅层 schema 节点及其直接子项摘要,便于继续深入。 + - 对部分 RPC 编辑请使用 `config.patch`;`config.apply` 只用于替换完整配置。 + - 如果你在智能体运行中使用仅限 owner 的 `gateway` 工具,它仍会拒绝对 `tools.exec.ask` / `tools.exec.security` 的写入(包括会规范化为同一受保护 exec 路径的旧版 `tools.bash.*` 别名)。 - 文档:[配置](/cli/config)、[配置向导](/cli/configure)、[Doctor](/zh-CN/gateway/doctor)。 + 文档:[Config](/cli/config)、[Configure](/cli/configure)、[Doctor](/zh-CN/gateway/doctor)。 - - 常见模式是**一个 Gateway 网关**(例如 Raspberry Pi)加上**节点**和**智能体**: + + 常见模式是**一个 Gateway 网关**(例如 Raspberry Pi)+ **节点**和**智能体**: - **Gateway 网关(中心):**负责渠道(Signal/WhatsApp)、路由和会话。 - - **节点(设备):**Mac/iOS/Android 作为外围设备连接,暴露本地工具(`system.run`、`canvas`、`camera`)。 - - **智能体(工作节点):**拥有各自工作区和角色的独立“大脑”(例如“Hetzner 运维”“个人数据”)。 - - **子智能体:**当你需要并行处理时,从主智能体中生成后台工作。 - - **TUI:**连接到 Gateway 网关,并切换智能体 / 会话。 + - **节点(设备):**Mac/iOS/Android 作为外设连接,并暴露本地工具(`system.run`、`canvas`、`camera`)。 + - **智能体(工作节点):**针对特定角色拆分不同的大脑/工作区(例如“Hetzner 运维”“个人数据”)。 + - **子智能体:**当你需要并行处理时,从主智能体派生后台工作。 + - **TUI:**连接到 Gateway 网关并切换智能体/会话。 - 文档:[节点](/zh-CN/nodes)、[远程访问](/zh-CN/gateway/remote)、[多智能体路由](/zh-CN/concepts/multi-agent)、[子智能体](/zh-CN/tools/subagents)、[TUI](/web/tui)。 + 文档:[Nodes](/zh-CN/nodes)、[Remote access](/zh-CN/gateway/remote)、[Multi-Agent Routing](/zh-CN/concepts/multi-agent)、[Sub-agents](/zh-CN/tools/subagents)、[TUI](/web/tui)。 - + 可以。这是一个配置选项: ```json5 @@ -1652,29 +1660,28 @@ x-i18n: } ``` - 默认值是 `false`(有头)。无头模式更容易触发某些网站的反机器人检查。请参阅 [浏览器](/zh-CN/tools/browser)。 + 默认是 `false`(有头模式)。无头模式在某些网站上更容易触发反机器人检查。参见 [Browser](/zh-CN/tools/browser)。 - 无头模式使用**相同的 Chromium 引擎**,适用于大多数自动化(表单、点击、抓取、登录)。主要区别在于: + 无头模式使用**相同的 Chromium 引擎**,适用于大多数自动化场景(表单、点击、抓取、登录)。主要差异: - - 没有可见的浏览器窗口(如果需要视觉反馈,请使用截图)。 + - 没有可见的浏览器窗口(如需可视化可使用截图)。 - 某些网站对无头模式下的自动化更严格(CAPTCHA、反机器人)。 例如,X/Twitter 经常会拦截无头会话。 - 将 `browser.executablePath` 设置为你的 Brave 二进制路径(或任何基于 Chromium 的浏览器),然后重启 Gateway 网关。 - 完整配置示例请参阅 [浏览器](/zh-CN/tools/browser#use-brave-or-another-chromium-based-browser)。 + 将 `browser.executablePath` 设置为你的 Brave 二进制路径(或任意基于 Chromium 的浏览器),然后重启 Gateway 网关。 + 完整配置示例请参见 [Browser](/zh-CN/tools/browser#use-brave-or-another-chromium-based-browser)。 ## 远程 Gateway 网关和节点 - - Telegram 消息由**gateway**处理。gateway 运行智能体, - 只有在需要节点工具时,才会通过**Gateway WebSocket** - 调用节点: + + Telegram 消息由**gateway**处理。gateway 运行智能体,然后 + 只在需要节点工具时,才通过**Gateway WebSocket** 调用节点: Telegram → Gateway → 智能体 → `node.*` → 节点 → Gateway → Telegram @@ -1682,17 +1689,17 @@ x-i18n: - - 简短回答:**把你的电脑配对为一个节点**。Gateway 网关运行在其他地方,但它可以 - 通过 Gateway WebSocket 在你的本地机器上调用 `node.*` 工具(screen、camera、system)。 + + 简短回答:**把你的电脑配对为一个节点**。Gateway 网关运行在别处,但它可以 + 通过 Gateway WebSocket 在你的本地机器上调用 `node.*` 工具(屏幕、摄像头、系统)。 - 典型部署方式: + 典型配置: 1. 在始终在线的主机(VPS/家庭服务器)上运行 Gateway 网关。 2. 让 Gateway 网关主机和你的电脑位于同一个 tailnet 中。 - 3. 确保 Gateway WS 可达(tailnet 绑定或 SSH 隧道)。 - 4. 在本地打开 macOS 应用,并以**Remote over SSH** 模式(或直接 tailnet) - 连接,使其能注册为一个节点。 + 3. 确保 Gateway WS 可访问(tailnet 绑定或 SSH 隧道)。 + 4. 在本地打开 macOS 应用,并以**通过 SSH 远程连接**模式(或直接 tailnet) + 连接,这样它就可以注册为一个节点。 5. 在 Gateway 网关上批准该节点: ```bash @@ -1700,19 +1707,19 @@ x-i18n: openclaw devices approve ``` - 不需要额外的 TCP bridge;节点会通过 Gateway WebSocket 连接。 + 不需要单独的 TCP bridge;节点通过 Gateway WebSocket 连接。 - 安全提醒:配对 macOS 节点后,就允许在该机器上运行 `system.run`。 - 只配对你信任的设备,并请阅读 [安全](/zh-CN/gateway/security)。 + 安全提醒:配对 macOS 节点会允许在该机器上执行 `system.run`。只 + 配对你信任的设备,并查看 [Security](/zh-CN/gateway/security)。 - 文档:[节点](/zh-CN/nodes)、[Gateway protocol](/zh-CN/gateway/protocol)、[macOS 远程模式](/zh-CN/platforms/mac/remote)、[安全](/zh-CN/gateway/security)。 + 文档:[Nodes](/zh-CN/nodes)、[Gateway protocol](/zh-CN/gateway/protocol)、[macOS remote mode](/zh-CN/platforms/mac/remote)、[Security](/zh-CN/gateway/security)。 - + 先检查基础项: - - Gateway 网关正在运行:`openclaw gateway status` + - Gateway 网关是否正在运行:`openclaw gateway status` - Gateway 网关健康状态:`openclaw status` - 渠道健康状态:`openclaw channels status` @@ -1720,23 +1727,23 @@ x-i18n: - 如果你使用 Tailscale Serve,请确保 `gateway.auth.allowTailscale` 设置正确。 - 如果你通过 SSH 隧道连接,请确认本地隧道已建立并指向正确端口。 - - 确认你的 allowlist(私信或群组)包含你的账户。 + - 确认你的允许列表(私信或群组)包含你的账号。 - 文档:[Tailscale](/zh-CN/gateway/tailscale)、[远程访问](/zh-CN/gateway/remote)、[渠道](/zh-CN/channels)。 + 文档:[Tailscale](/zh-CN/gateway/tailscale)、[Remote access](/zh-CN/gateway/remote)、[Channels](/zh-CN/channels)。 - 可以。虽然没有内置的“bot-to-bot”桥接功能,但你可以通过几种 - 可靠方式实现: + 可以。虽然没有内置的“机器人对机器人”桥接,但你可以通过几种 + 可靠方式自行连起来: - **最简单:**使用两个机器人都能访问的普通聊天渠道(Telegram/Slack/WhatsApp)。 - 让 Bot A 向 Bot B 发送消息,然后让 Bot B 像平常一样回复。 + **最简单:**使用一个两个机器人都能访问的普通聊天渠道(Telegram/Slack/WhatsApp)。 + 让 Bot A 给 Bot B 发消息,然后让 Bot B 正常回复。 - **CLI 桥接(通用):**运行一个脚本,通过 - `openclaw agent --message ... --deliver` 调用另一个 Gateway 网关,目标是另一个机器人 - 监听的聊天。如果某个机器人在远程 VPS 上,请让你的 CLI - 通过 SSH/Tailscale 指向那个远程 Gateway 网关(参见 [远程访问](/zh-CN/gateway/remote))。 + **CLI 桥接(通用):**运行一个脚本,使用 + `openclaw agent --message ... --deliver` 调用另一个 Gateway 网关, + 并将目标指向对方机器人正在监听的聊天。若其中一个机器人部署在远程 VPS 上,请让你的 CLI 通过 SSH/Tailscale 指向那个远程 Gateway 网关 + (参见 [Remote access](/zh-CN/gateway/remote))。 示例模式(在能够访问目标 Gateway 网关的机器上运行): @@ -1744,59 +1751,59 @@ x-i18n: openclaw agent --message "Hello from local bot" --deliver --channel telegram --reply-to ``` - 提示:加入一些护栏,避免两个机器人无限循环回复(只响应提及、渠道 - allowlist,或设置“不要回复机器人消息”的规则)。 + 提示:添加一个防护措施,避免两个机器人无限循环互相回复(只响应提及、渠道 + 允许列表,或添加“不要回复机器人消息”的规则)。 - 文档:[远程访问](/zh-CN/gateway/remote)、[智能体 CLI](/cli/agent)、[智能体发送](/zh-CN/tools/agent-send)。 + 文档:[Remote access](/zh-CN/gateway/remote)、[Agent CLI](/cli/agent)、[Agent send](/zh-CN/tools/agent-send)。 - 不需要。一个 Gateway 网关可以承载多个智能体,每个智能体都有自己的工作区、默认模型 - 和路由。这是标准部署方式,而且比 - 每个智能体运行一个 VPS 更便宜、更简单。 + 不需要。一个 Gateway 网关可以托管多个智能体,每个智能体都有自己的工作区、默认模型 + 和路由。这是正常配置,而且比为每个智能体单独运行 + 一个 VPS 更便宜也更简单。 - 只有当你需要硬隔离(安全边界)或完全不同、互不共享的配置时, - 才需要使用多个 VPS。否则,保持一个 Gateway 网关,并 + 只有在你需要强隔离(安全边界)或非常 + 不同且不想共享的配置时,才使用独立的 VPS。否则,保持一个 Gateway 网关并 使用多个智能体或子智能体即可。 - - 有——节点是从远程 Gateway 网关访问你笔记本的一等方式,而且它们 - 不止提供 shell 访问。Gateway 网关可运行在 macOS/Linux(Windows 通过 WSL2),而且非常 - 轻量(小型 VPS 或 Raspberry Pi 级设备即可;4 GB RAM 已很充裕),因此常见 - 部署方式是一个始终在线的主机加上你的笔记本作为节点。 + + 有——节点是从远程 Gateway 网关访问你的笔记本的一等方式,而且它们 + 提供的不只是 shell 访问。Gateway 网关可运行在 macOS/Linux(Windows 通过 WSL2)上, + 并且很轻量(小型 VPS 或 Raspberry Pi 级别的设备就足够;4 GB RAM 已绰绰有余),因此一种常见 + 配置是始终在线的主机 + 你的笔记本作为节点。 - - **无需入站 SSH。**节点会主动连接到 Gateway WebSocket,并通过设备配对工作。 - - **更安全的执行控制。**`system.run` 在该笔记本上受节点 allowlist/approvals 控制。 - - **更多设备工具。**节点除了 `system.run` 之外,还提供 `canvas`、`camera` 和 `screen`。 - - **本地浏览器自动化。**将 Gateway 网关放在 VPS 上,但通过笔记本上的节点主机在本地运行 Chrome,或通过 Chrome MCP 连接主机上的本地 Chrome。 + - **无需入站 SSH。**节点主动连接到 Gateway WebSocket,并使用设备配对。 + - **更安全的执行控制。**`system.run` 受该笔记本上的节点允许列表/审批控制。 + - **更多设备工具。**除了 `system.run`,节点还提供 `canvas`、`camera` 和 `screen`。 + - **本地浏览器自动化。**将 Gateway 网关放在 VPS 上,但通过笔记本上的节点主机在本地运行 Chrome,或者通过 Chrome MCP 连接主机上的本地 Chrome。 - SSH 适合临时 shell 访问,但对于持续性的智能体工作流和 + 对于临时 shell 访问,SSH 没问题;但对于持续性的智能体工作流和 设备自动化,节点更简单。 - 文档:[节点](/zh-CN/nodes)、[节点 CLI](/cli/nodes)、[浏览器](/zh-CN/tools/browser)。 + 文档:[Nodes](/zh-CN/nodes)、[Nodes CLI](/cli/nodes)、[Browser](/zh-CN/tools/browser)。 - 不会。除非你有意运行隔离配置文件(参见 [多个 Gateway 网关](/zh-CN/gateway/multiple-gateways)),否则每台主机只应运行**一个 gateway**。节点是连接到 - gateway 的外围设备(iOS/Android 节点,或菜单栏应用中的 macOS“节点模式”)。对于 headless 节点 - 主机和 CLI 控制,请参阅 [节点主机 CLI](/cli/node)。 + 不会。每台主机通常只应运行**一个 gateway**,除非你有意运行隔离配置文件(参见 [Multiple gateways](/zh-CN/gateway/multiple-gateways))。节点是连接到 + gateway 的外设(iOS/Android 节点,或菜单栏应用中的 macOS “node mode”)。关于无头节点 + 主机和 CLI 控制,请参见 [Node host CLI](/cli/node)。 - `gateway`、`discovery` 和 `canvasHost` 的更改都需要完整重启。 + 对 `gateway`、`discovery` 和 `canvasHost` 的更改需要完整重启。 - + 有。 - - `config.schema.lookup`:在写入前检查某个配置子树,包括其浅层 schema 节点、匹配的 UI 提示以及直接子节点摘要 - - `config.get`:获取当前快照 + hash - - `config.patch`:安全的部分更新(大多数 RPC 编辑首选) + - `config.schema.lookup`:在写入前检查一个配置子树及其浅层 schema 节点、匹配的 UI 提示和直接子项摘要 + - `config.get`:获取当前快照 + 哈希值 + - `config.patch`:安全的局部更新(大多数 RPC 编辑首选) - `config.apply`:验证并替换完整配置,然后重启 - - 仅所有者可用的 `gateway` 运行时工具仍会拒绝重写 `tools.exec.ask` / `tools.exec.security`;旧版 `tools.bash.*` 别名会标准化到同一组受保护的 exec 路径 + - 仅限 owner 的 `gateway` 运行时工具仍然拒绝重写 `tools.exec.ask` / `tools.exec.security`;旧版 `tools.bash.*` 别名会规范化到相同的受保护 exec 路径 @@ -1812,8 +1819,8 @@ x-i18n: - - 最简步骤: + + 最小步骤: 1. **在 VPS 上安装并登录** @@ -1822,51 +1829,51 @@ x-i18n: sudo tailscale up ``` - 2. **在你的 Mac 上安装并登录** - - 使用 Tailscale 应用,并登录到同一个 tailnet。 + 2. **在 Mac 上安装并登录** + - 使用 Tailscale 应用并登录到同一个 tailnet。 3. **启用 MagicDNS(推荐)** - - 在 Tailscale 管理控制台中启用 MagicDNS,这样 VPS 就会有一个稳定的名称。 + - 在 Tailscale 管理控制台中启用 MagicDNS,以便 VPS 拥有稳定名称。 4. **使用 tailnet 主机名** - SSH:`ssh user@your-vps.tailnet-xxxx.ts.net` - Gateway WS:`ws://your-vps.tailnet-xxxx.ts.net:18789` - 如果你想在不使用 SSH 的情况下访问 Control UI,请在 VPS 上使用 Tailscale Serve: + 如果你希望无需 SSH 就使用 Control UI,请在 VPS 上启用 Tailscale Serve: ```bash openclaw gateway --tailscale serve ``` - 这样会让 gateway 继续绑定到 loopback,并通过 Tailscale 暴露 HTTPS。请参阅 [Tailscale](/zh-CN/gateway/tailscale)。 + 这样会让 gateway 继续绑定到 loopback,并通过 Tailscale 暴露 HTTPS。参见 [Tailscale](/zh-CN/gateway/tailscale)。 - - Serve 暴露的是 **Gateway Control UI + WS**。节点也通过同一个 Gateway WS 端点连接。 + + Serve 暴露的是**Gateway Control UI + WS**。节点通过同一个 Gateway WS 端点连接。 - 推荐部署方式: + 推荐配置: - 1. **确保 VPS 和 Mac 位于同一个 tailnet 中**。 - 2. **在 macOS 应用中使用 Remote 模式**(SSH 目标可使用 tailnet 主机名)。 - 应用会隧道 Gateway 端口,并作为节点连接。 - 3. **在 gateway 上批准该节点:** + 1. **确保 VPS 和 Mac 处于同一个 tailnet**。 + 2. **在远程模式下使用 macOS 应用**(SSH 目标可以是 tailnet 主机名)。 + 该应用会隧道化 Gateway 网关端口并作为节点连接。 + 3. **在 gateway 上批准节点**: ```bash openclaw devices list openclaw devices approve ``` - 文档:[Gateway protocol](/zh-CN/gateway/protocol)、[设备发现](/zh-CN/gateway/discovery)、[macOS 远程模式](/zh-CN/platforms/mac/remote)。 + 文档:[Gateway protocol](/zh-CN/gateway/protocol)、[设备发现](/zh-CN/gateway/discovery)、[macOS remote mode](/zh-CN/platforms/mac/remote)。 - - 如果你只需要在第二台笔记本上使用**本地工具**(screen/camera/exec),就把它作为 - **节点**添加。这可以保持一个统一的 Gateway 网关,并避免重复配置。当前本地节点工具 + + 如果你只需要第二台笔记本上的**本地工具**(屏幕/摄像头/exec),就把它添加为 + **节点**。这样可以保留单一 Gateway 网关,并避免重复配置。当前本地节点工具 仅支持 macOS,但我们计划将其扩展到其他操作系统。 - 只有在你需要**硬隔离**或两个完全独立的机器人时,才安装第二个 Gateway 网关。 + 只有当你需要**强隔离**或两个完全独立的机器人时,才安装第二个 Gateway 网关。 - 文档:[节点](/zh-CN/nodes)、[节点 CLI](/cli/nodes)、[多个 Gateway 网关](/zh-CN/gateway/multiple-gateways)。 + 文档:[Nodes](/zh-CN/nodes)、[Nodes CLI](/cli/nodes)、[Multiple gateways](/zh-CN/gateway/multiple-gateways)。 @@ -1875,14 +1882,14 @@ x-i18n: - OpenClaw 会读取父进程中的环境变量(shell、launchd/systemd、CI 等),并额外加载: + OpenClaw 从父进程(shell、launchd/systemd、CI 等)读取环境变量,并额外加载: - - 当前工作目录下的 `.env` - - 来自 `~/.openclaw/.env`(即 `$OPENCLAW_STATE_DIR/.env`)的全局回退 `.env` + - 当前工作目录中的 `.env` + - `~/.openclaw/.env`(即 `$OPENCLAW_STATE_DIR/.env`)中的全局回退 `.env` 这两个 `.env` 文件都不会覆盖现有环境变量。 - 你也可以在配置中定义内联环境变量(仅在进程环境中缺失时应用): + 你还可以在配置中定义内联环境变量(仅在进程环境中缺失时应用): ```json5 { @@ -1893,15 +1900,15 @@ x-i18n: } ``` - 完整优先级和来源请参阅 [/environment](/zh-CN/help/environment)。 + 完整优先级和来源请参见 [/environment](/zh-CN/help/environment)。 - - 两个常见修复方法: + + 两个常见修复方式: - 1. 将缺失的 key 放入 `~/.openclaw/.env`,这样即使服务没有继承你的 shell 环境,也能被读取。 - 2. 启用 shell 导入(选择加入式便利功能): + 1. 将缺失的密钥放到 `~/.openclaw/.env` 中,这样即使服务没有继承你的 shell 环境,也能读取到。 + 2. 启用 shell 导入(可选的便捷功能): ```json5 { @@ -1914,36 +1921,36 @@ x-i18n: } ``` - 这会运行你的登录 shell,并且仅导入缺失的预期键名(永不覆盖)。对应环境变量: + 这会运行你的登录 shell,并且只导入缺失的预期键名(绝不覆盖)。对应环境变量: `OPENCLAW_LOAD_SHELL_ENV=1`、`OPENCLAW_SHELL_ENV_TIMEOUT_MS=15000`。 - `openclaw models status` 报告的是是否启用了**shell 环境导入**。“Shell env: off” - **不**意味着你的环境变量不存在——它只是表示 OpenClaw 不会自动加载 - 你的登录 shell。 + `openclaw models status` 报告的是**是否启用了 shell 环境导入**。“Shell env: off” + **不**表示你的环境变量不存在——它只是表示 OpenClaw 不会 + 自动加载你的登录 shell。 如果 Gateway 网关作为服务运行(launchd/systemd),它不会继承你的 shell - 环境。修复方法之一如下: + 环境。可通过以下任一方式修复: - 1. 将 token 放入 `~/.openclaw/.env`: + 1. 将令牌放到 `~/.openclaw/.env` 中: ``` COPILOT_GITHUB_TOKEN=... ``` 2. 或启用 shell 导入(`env.shellEnv.enabled: true`)。 - 3. 或将其加入配置中的 `env` 块(仅在缺失时应用)。 + 3. 或将其添加到配置的 `env` 块中(仅在缺失时应用)。 - 然后重启 gateway 并重新检查: + 然后重启 gateway 并再次检查: ```bash openclaw models status ``` - Copilot token 会从 `COPILOT_GITHUB_TOKEN` 读取(也支持 `GH_TOKEN` / `GITHUB_TOKEN`)。 - 请参阅 [/concepts/model-providers](/zh-CN/concepts/model-providers) 和 [/environment](/zh-CN/help/environment)。 + Copilot 令牌会从 `COPILOT_GITHUB_TOKEN` 读取(也支持 `GH_TOKEN` / `GITHUB_TOKEN`)。 + 参见 [/concepts/model-providers](/zh-CN/concepts/model-providers) 和 [/environment](/zh-CN/help/environment)。 @@ -1951,15 +1958,15 @@ x-i18n: ## 会话和多个聊天 - - 发送 `/new` 或 `/reset` 作为独立消息即可。请参阅 [会话管理](/zh-CN/concepts/session)。 + + 发送 `/new` 或 `/reset` 作为独立消息。参见 [Session management](/zh-CN/concepts/session)。 - 会话可以在 `session.idleMinutes` 后过期,但这项功能**默认禁用**(默认值为 **0**)。 - 将其设置为正值即可启用空闲过期。启用后,空闲期之后的**下一条** - 消息会为该聊天键开启一个新的会话 id。 - 这不会删除对话记录——它只是开始一个新会话。 + 会话可在 `session.idleMinutes` 后过期,但这项功能**默认禁用**(默认值为 **0**)。 + 将其设为正值即可启用空闲过期。启用后,空闲期后的**下一条** + 消息会为该聊天键启动一个新的会话 ID。 + 这不会删除转录记录——它只是开始一个新会话。 ```json5 { @@ -1971,34 +1978,34 @@ x-i18n: - - 可以,通过**多智能体路由**和**子智能体**实现。你可以创建一个协调者 - 智能体和多个拥有各自工作区与模型的工作智能体。 + + 可以,通过**多智能体路由**和**子智能体**。你可以创建一个协调者 + 智能体和多个工作智能体,它们拥有各自的工作区和模型。 - 不过,这更适合作为一种**有趣的实验**。它会消耗大量 token,而且通常 - 不如使用一个机器人加多个独立会话来得高效。我们设想的典型模式是: - 一个你进行交流的机器人,搭配多个用于并行工作的不同会话。该 + 但这更适合作为一个**有趣的实验**来看待。它会消耗大量令牌,而且通常 + 不如使用一个机器人配合多个会话高效。我们更典型 + 设想的模式是:你与一个机器人交流,并用不同会话处理并行工作。该 机器人在需要时也可以生成子智能体。 - 文档:[多智能体路由](/zh-CN/concepts/multi-agent)、[子智能体](/zh-CN/tools/subagents)、[智能体 CLI](/cli/agents)。 + 文档:[Multi-agent routing](/zh-CN/concepts/multi-agent)、[Sub-agents](/zh-CN/tools/subagents)、[Agents CLI](/cli/agents)。 - 会话上下文受模型窗口限制。长聊天、大量工具输出或过多 + 会话上下文受模型窗口限制。长聊天、大量工具输出或许多 文件都可能触发压缩或截断。 - 有帮助的做法: + 有帮助的方法: - 让机器人总结当前状态并写入文件。 - - 在长任务前使用 `/compact`,切换话题时使用 `/new`。 - - 将重要上下文保留在工作区中,并让机器人重新读回。 - - 对于长任务或并行工作使用子智能体,这样主聊天能保持更小。 - - 如果这种情况经常发生,选择一个具有更大上下文窗口的模型。 + - 在长任务前使用 `/compact`,切换主题时使用 `/new`。 + - 将重要上下文保存在工作区中,并让机器人重新读取。 + - 对长任务或并行工作使用子智能体,以保持主聊天更精简。 + - 如果这种情况经常发生,请选择一个上下文窗口更大的模型。 - + 使用 reset 命令: ```bash @@ -2017,59 +2024,59 @@ x-i18n: openclaw onboard --install-daemon ``` - 说明: + 注意: - - 如果发现已有配置,新手引导也会提供**重置**选项。请参阅 [设置向导(CLI)](/zh-CN/start/wizard)。 - - 如果你使用了 profile(`--profile` / `OPENCLAW_PROFILE`),请分别重置每个状态目录(默认是 `~/.openclaw-`)。 - - 开发重置:`openclaw gateway --dev --reset`(仅用于开发;会清除开发配置 + 凭证 + 会话 + 工作区)。 + - 如果检测到现有配置,新手引导也会提供 **Reset**。参见 [新手引导(CLI)](/zh-CN/start/wizard)。 + - 如果你使用了配置文件(`--profile` / `OPENCLAW_PROFILE`),请重置每个状态目录(默认是 `~/.openclaw-`)。 + - 开发重置:`openclaw gateway --dev --reset`(仅开发环境;会清空开发配置 + 凭证 + 会话 + 工作区)。 - + 使用以下任一方式: - - **压缩**(保留对话,但总结较早轮次): + - **压缩**(保留对话,但总结较早的轮次): ``` /compact ``` - 或使用 `/compact ` 来指导摘要内容。 + 或使用 `/compact ` 来指导总结方式。 - - **重置**(对同一聊天键生成新的会话 ID): + - **重置**(为相同聊天键生成新的会话 ID): ``` /new /reset ``` - 如果问题持续发生: + 如果还是频繁发生: - - 启用或调整**会话裁剪**(`agents.defaults.contextPruning`)来修剪旧工具输出。 - - 使用具有更大上下文窗口的模型。 + - 启用或调整**会话修剪**(`agents.defaults.contextPruning`)以裁剪旧工具输出。 + - 使用上下文窗口更大的模型。 - 文档:[压缩](/zh-CN/concepts/compaction)、[会话裁剪](/zh-CN/concepts/session-pruning)、[会话管理](/zh-CN/concepts/session)。 + 文档:[Compaction](/zh-CN/concepts/compaction)、[Session pruning](/zh-CN/concepts/session-pruning)、[Session management](/zh-CN/concepts/session)。 - 这是一个提供商校验错误:模型发出了一个 `tool_use` 块,但缺少必需的 - `input`。这通常意味着会话历史陈旧或损坏(通常出现在长线程 - 或工具 / schema 变更之后)。 + 这是一个提供商验证错误:模型发出了一个 `tool_use` 块,但缺少必需的 + `input`。这通常表示会话历史已过时或损坏(通常发生在长线程 + 或工具/schema 变化之后)。 - 修复方法:用 `/new`(独立消息)开始一个新会话。 + 解决方法:发送 `/new`(独立消息)开始一个新会话。 - Heartbeat 默认每 **30m** 运行一次(使用 OAuth 认证时为 **1h**)。可进行调优或禁用: + Heartbeat 默认每 **30m** 运行一次(使用 OAuth 认证时为 **1h**)。你可以调整或禁用它们: ```json5 { agents: { defaults: { heartbeat: { - every: "2h", // 或 "0m" 来禁用 + every: "2h", // 或 "0m" 以禁用 }, }, }, @@ -2077,18 +2084,18 @@ x-i18n: ``` 如果 `HEARTBEAT.md` 存在但实际上为空(只有空行和 Markdown - 标题如 `# Heading`),OpenClaw 会跳过 heartbeat 运行以节省 API 调用。 - 如果该文件不存在,heartbeat 仍会运行,并由模型决定接下来做什么。 + 标题,例如 `# Heading`),OpenClaw 会跳过 heartbeat 运行以节省 API 调用。 + 如果该文件不存在,heartbeat 仍会运行,并由模型决定该怎么做。 - 按智能体覆盖使用 `agents.list[].heartbeat`。文档:[Heartbeat](/zh-CN/gateway/heartbeat)。 + 每个智能体的覆盖项使用 `agents.list[].heartbeat`。文档:[Heartbeat](/zh-CN/gateway/heartbeat)。 - + 不需要。OpenClaw 运行在**你自己的账号**上,所以只要你在群里,OpenClaw 就能看到它。 默认情况下,在你允许发送者之前,群组回复会被阻止(`groupPolicy: "allowlist"`)。 - 如果你只想让**你自己**能够触发群组回复: + 如果你希望只有**你自己**可以触发群组回复: ```json5 { @@ -2104,7 +2111,7 @@ x-i18n: - 方式 1(最快):跟踪日志,并在群里发送一条测试消息: + 方式 1(最快):查看日志尾部,然后在群里发送一条测试消息: ```bash openclaw logs --follow --json @@ -2113,62 +2120,62 @@ x-i18n: 查找以 `@g.us` 结尾的 `chatId`(或 `from`),例如: `1234567890-1234567890@g.us`。 - 方式 2(如果已配置 / 已加入 allowlist):从配置中列出群组: + 方式 2(如果已配置/加入允许列表):从配置中列出群组: ```bash openclaw directory groups list --channel whatsapp ``` - 文档:[WhatsApp](/zh-CN/channels/whatsapp)、[目录](/cli/directory)、[日志](/cli/logs)。 + 文档:[WhatsApp](/zh-CN/channels/whatsapp)、[Directory](/cli/directory)、[Logs](/cli/logs)。 - + 两个常见原因: - - 提及门控处于开启状态(默认)。你必须 @ 提及机器人(或匹配 `mentionPatterns`)。 - - 你配置了 `channels.whatsapp.groups` 但没有包含 `"*"`,且该群组不在 allowlist 中。 + - 提及门控已开启(默认)。你必须 @ 提及机器人(或匹配 `mentionPatterns`)。 + - 你配置了 `channels.whatsapp.groups` 但没有包含 `"*"`,且该群组未加入允许列表。 - 请参阅 [群组](/zh-CN/channels/groups) 和 [群组消息](/zh-CN/channels/group-messages)。 + 参见 [Groups](/zh-CN/channels/groups) 和 [Group messages](/zh-CN/channels/group-messages)。 - - 直接聊天默认会折叠到主会话。群组 / 渠道拥有各自的会话键,而 Telegram 主题 / Discord 线程是独立会话。请参阅 [群组](/zh-CN/channels/groups) 和 [群组消息](/zh-CN/channels/group-messages)。 + + 直接聊天默认会折叠到主会话。群组/渠道拥有各自独立的会话键,而 Telegram 主题 / Discord 线程也是独立会话。参见 [Groups](/zh-CN/channels/groups) 和 [Group messages](/zh-CN/channels/group-messages)。 - - 没有硬性上限。几十个(甚至上百个)都没问题,但要注意: + + 没有硬性限制。几十个(甚至上百个)都可以,但请注意: - - **磁盘增长:**会话 + 对话记录都位于 `~/.openclaw/agents//sessions/` 下。 - - **token 成本:**更多智能体意味着更多并发模型使用。 - - **运维开销:**每个智能体都要维护 auth profile、工作区和渠道路由。 + - **磁盘增长:**会话 + 转录内容存储在 `~/.openclaw/agents//sessions/` 下。 + - **令牌成本:**智能体越多,模型并发使用越多。 + - **运维开销:**每个智能体都可能有各自的认证配置文件、工作区和渠道路由。 - 建议: + 提示: - - 每个智能体只保留一个**活跃**工作区(`agents.defaults.workspace`)。 - - 如果磁盘增长过快,可清理旧会话(删除 JSONL 或 store 条目)。 - - 使用 `openclaw doctor` 检查游离工作区和 profile 不匹配问题。 + - 每个智能体只保留一个**活动**工作区(`agents.defaults.workspace`)。 + - 如果磁盘增长,可以修剪旧会话(删除 JSONL 或存储条目)。 + - 使用 `openclaw doctor` 查找游离工作区和配置文件不匹配。 - 可以。使用**多智能体路由**来运行多个隔离的智能体,并按 - channel/account/peer 路由入站消息。Slack 支持作为一个渠道,并且可以绑定到特定智能体。 + 可以。使用**多智能体路由**来运行多个隔离智能体,并根据 + 渠道/账号/peer 路由入站消息。Slack 作为一个渠道受支持,也可以绑定到特定智能体。 - 浏览器访问很强大,但并不是“能做到人类能做的任何事”——反机器人、CAPTCHA 和 MFA - 仍然会阻止自动化。若要获得最可靠的浏览器控制,请在主机上使用本地 Chrome MCP, - 或在真正运行浏览器的机器上使用 CDP。 + 浏览器访问功能很强大,但并不等于“人类能做的都能做”——反机器人机制、CAPTCHA 和 MFA + 仍然可能阻止自动化。若要获得最可靠的浏览器控制,请在主机上使用本地 Chrome MCP, + 或在实际运行浏览器的机器上使用 CDP。 - 最佳实践部署方式: + 最佳实践配置: - 始终在线的 Gateway 网关主机(VPS/Mac mini)。 - - 每个角色一个智能体(绑定)。 + - 每个角色一个智能体(bindings)。 - 将 Slack 渠道绑定到这些智能体。 - 在需要时通过 Chrome MCP 或节点访问本地浏览器。 - 文档:[多智能体路由](/zh-CN/concepts/multi-agent)、[Slack](/zh-CN/channels/slack)、 - [浏览器](/zh-CN/tools/browser)、[节点](/zh-CN/nodes)。 + 文档:[Multi-Agent Routing](/zh-CN/concepts/multi-agent)、[Slack](/zh-CN/channels/slack)、 + [Browser](/zh-CN/tools/browser)、[Nodes](/zh-CN/nodes)。 @@ -2177,90 +2184,90 @@ x-i18n: - OpenClaw 的默认模型就是你在以下位置设置的内容: + OpenClaw 的默认模型就是你设置在这里的模型: ``` agents.defaults.model.primary ``` - 模型采用 `provider/model` 格式引用(例如 `openai/gpt-5.4`)。如果你省略了提供商,OpenClaw 会先尝试别名,然后尝试与该确切模型 id 唯一匹配的已配置提供商,最后才会回退到已配置的默认提供商,这是一条已弃用的兼容路径。如果该提供商不再公开已配置的默认模型,OpenClaw 会回退到第一个已配置的 provider/model,而不是继续使用陈旧的、已移除提供商默认值。你仍然应该**显式**设置 `provider/model`。 + 模型以 `provider/model` 的形式引用(示例:`openai/gpt-5.4`)。如果你省略提供商,OpenClaw 会先尝试别名,然后尝试对该确切模型 ID 进行唯一配置提供商匹配,最后才会退回到已配置默认提供商这一已弃用的兼容路径。如果该提供商不再暴露配置中的默认模型,OpenClaw 会退回到第一个已配置的提供商/模型,而不是继续使用一个已移除提供商的陈旧默认值。你仍然应该**显式**设置 `provider/model`。 - **推荐默认值:**使用你当前提供商栈中最新一代最强的模型。 - **对于启用了工具或面对不受信输入的智能体:**优先考虑模型能力,而不是成本。 - **对于日常 / 低风险聊天:**使用更便宜的回退模型,并按智能体角色进行路由。 + **推荐默认值:**使用你提供商栈中可用的最新一代最强模型。 + **对于启用了工具或会处理不可信输入的智能体:**优先考虑模型强度,而非成本。 + **对于日常/低风险聊天:**使用更便宜的回退模型,并按智能体角色进行路由。 MiniMax 有自己的文档:[MiniMax](/zh-CN/providers/minimax) 和 - [本地模型](/zh-CN/gateway/local-models)。 + [Local models](/zh-CN/gateway/local-models)。 经验法则:对于高风险工作,使用你能负担得起的**最佳模型**;对于日常聊天或摘要, - 使用更便宜的模型。你可以按智能体路由模型,并使用子智能体对长任务进行 - 并行处理(每个子智能体都会消耗 token)。请参阅 [模型](/zh-CN/concepts/models) 和 - [子智能体](/zh-CN/tools/subagents)。 + 使用更便宜的模型。你可以按智能体路由模型,并用子智能体 + 并行处理长任务(每个子智能体都会消耗令牌)。参见 [Models](/zh-CN/concepts/models) 和 + [Sub-agents](/zh-CN/tools/subagents)。 - 强烈警告:较弱 / 过度量化的模型更容易受到 prompt - injection 和不安全行为影响。请参阅 [安全](/zh-CN/gateway/security)。 + 强烈警告:较弱或过度量化的模型更容易受到提示 + 注入和不安全行为影响。参见 [Security](/zh-CN/gateway/security)。 - 更多背景:[模型](/zh-CN/concepts/models)。 + 更多背景:[Models](/zh-CN/concepts/models)。 使用**模型命令**,或只编辑**模型**字段。避免整体替换配置。 - 安全选项: + 安全方式: - - 聊天中使用 `/model`(快速、按会话) + - 在聊天中使用 `/model`(快速、按会话) - `openclaw models set ...`(只更新模型配置) - `openclaw configure --section model`(交互式) - 编辑 `~/.openclaw/openclaw.json` 中的 `agents.defaults.model` - 除非你真的打算替换整个配置,否则不要用部分对象调用 `config.apply`。 - 对于 RPC 编辑,先用 `config.schema.lookup` 进行检查,并优先使用 `config.patch`。lookup 载荷会给出规范化路径、浅层 schema 文档 / 约束以及直接子节点摘要, - 以便进行部分更新。 + 避免对部分对象使用 `config.apply`,除非你确实打算替换整个配置。 + 对于 RPC 编辑,请先用 `config.schema.lookup` 检查,并优先使用 `config.patch`。lookup 载荷会给出规范化路径、浅层 schema 文档/约束以及直接子项摘要, + 适合做部分更新。 如果你确实覆盖了配置,请从备份恢复,或重新运行 `openclaw doctor` 进行修复。 - 文档:[模型](/zh-CN/concepts/models)、[配置向导](/cli/configure)、[配置](/cli/config)、[Doctor](/zh-CN/gateway/doctor)。 + 文档:[Models](/zh-CN/concepts/models)、[Configure](/cli/configure)、[Config](/cli/config)、[Doctor](/zh-CN/gateway/doctor)。 - - 可以。Ollama 是使用本地模型最简单的路径。 + + 可以。Ollama 是本地模型最容易上手的路径。 最快设置方式: 1. 从 `https://ollama.com/download` 安装 Ollama 2. 拉取一个本地模型,例如 `ollama pull glm-4.7-flash` - 3. 如果你还想使用云模型,请运行 `ollama signin` + 3. 如果你也想使用云模型,运行 `ollama signin` 4. 运行 `openclaw onboard` 并选择 `Ollama` 5. 选择 `Local` 或 `Cloud + Local` - 说明: + 注意: - `Cloud + Local` 会同时提供云模型和你的本地 Ollama 模型 - - 像 `kimi-k2.5:cloud` 这样的云模型不需要本地 pull - - 若要手动切换,请使用 `openclaw models list` 和 `openclaw models set ollama/` + - 诸如 `kimi-k2.5:cloud` 之类的云模型不需要本地拉取 + - 手动切换时,使用 `openclaw models list` 和 `openclaw models set ollama/` - 安全说明:较小或高度量化的模型更容易受到 prompt - injection 影响。对于任何可使用工具的机器人,我们强烈推荐**大型模型**。 - 如果你仍然想使用小模型,请启用沙箱隔离并使用严格的工具 allowlist。 + 安全提示:更小或高度量化的模型更容易受到提示 + 注入影响。对于任何可使用工具的机器人,我们强烈推荐**大模型**。 + 如果你仍然想使用小模型,请启用沙箱隔离并使用严格的工具允许列表。 - 文档:[Ollama](/zh-CN/providers/ollama)、[本地模型](/zh-CN/gateway/local-models)、 - [模型提供商](/zh-CN/concepts/model-providers)、[安全](/zh-CN/gateway/security)、 + 文档:[Ollama](/zh-CN/providers/ollama)、[Local models](/zh-CN/gateway/local-models)、 + [Model providers](/zh-CN/concepts/model-providers)、[Security](/zh-CN/gateway/security)、 [沙箱隔离](/zh-CN/gateway/sandboxing)。 - - 这些部署可能不同,并且会随时间变化;没有固定的提供商推荐。 + - 这些部署可能不同,并且会随着时间变化;没有固定的提供商推荐。 - 在每个 gateway 上使用 `openclaw models status` 检查当前运行时设置。 - - 对于安全敏感 / 启用了工具的智能体,请使用可用的最新一代最强模型。 + - 对于安全敏感/启用工具的智能体,请使用当前可用的最新一代最强模型。 - 将 `/model` 命令作为独立消息发送: + 发送 `/model` 命令作为独立消息: ``` /model sonnet @@ -2276,73 +2283,73 @@ x-i18n: 你可以使用 `/model`、`/model list` 或 `/model status` 列出可用模型。 - `/model`(以及 `/model list`)会显示一个紧凑的编号选择器。可通过编号选择: + `/model`(以及 `/model list`)会显示一个紧凑的编号选择器。按编号选择: ``` /model 3 ``` - 你还可以为该提供商强制指定某个 auth profile(按会话): + 你还可以为该提供商强制指定一个特定认证配置文件(按会话): ``` /model opus@anthropic:default /model opus@anthropic:work ``` - 提示:`/model status` 会显示当前活动的是哪个智能体、正在使用哪个 `auth-profiles.json` 文件,以及接下来将尝试哪个 auth profile。 - 若有可用,它还会显示已配置的提供商端点(`baseUrl`)和 API 模式(`api`)。 + 提示:`/model status` 会显示当前活动的是哪个智能体、正在使用哪个 `auth-profiles.json` 文件,以及接下来将尝试哪个认证配置文件。 + 它还会在可用时显示已配置的提供商端点(`baseUrl`)和 API 模式(`api`)。 - **如何取消我用 @profile 固定的 profile?** + **如何取消我通过 @profile 设置的固定配置文件?** - 重新运行 `/model`,**不要**带 `@profile` 后缀: + 重新运行 `/model`,但**不要**带 `@profile` 后缀: ``` /model anthropic/claude-opus-4-6 ``` - 如果你想恢复默认值,可以在 `/model` 中选择它(或发送 `/model `)。 - 使用 `/model status` 确认当前启用了哪个 auth profile。 + 如果你想回到默认值,可以从 `/model` 中选回默认项(或发送 `/model `)。 + 使用 `/model status` 确认当前激活的是哪个认证配置文件。 - - 可以。将其中一个设为默认值,并在需要时切换: + + 可以。设置一个为默认模型,并按需切换: - - **快速切换(按会话):**日常任务使用 `/model gpt-5.4`,编码时使用 `/model openai-codex/gpt-5.4` 搭配 Codex OAuth。 - - **默认值 + 切换:**将 `agents.defaults.model.primary` 设为 `openai/gpt-5.4`,编码时切换到 `openai-codex/gpt-5.4`(或反过来)。 + - **快速切换(按会话):**日常任务使用 `/model gpt-5.4`,编码时使用 `/model openai-codex/gpt-5.4` 配合 Codex OAuth。 + - **默认值 + 切换:**将 `agents.defaults.model.primary` 设为 `openai/gpt-5.4`,编码时切换到 `openai-codex/gpt-5.4`(反过来也可以)。 - **子智能体:**将编码任务路由到拥有不同默认模型的子智能体。 - 请参阅 [模型](/zh-CN/concepts/models) 和 [斜杠命令](/zh-CN/tools/slash-commands)。 + 参见 [Models](/zh-CN/concepts/models) 和 [Slash commands](/zh-CN/tools/slash-commands)。 如果设置了 `agents.defaults.models`,它就会成为 `/model` 和任何 - 会话覆盖的**allowlist**。选择不在该列表中的模型时,会返回: + 会话覆盖的**允许列表**。选择一个不在该列表中的模型会返回: ``` Model "provider/model" is not allowed. Use /model to list available models. ``` - 这个错误会**替代**正常回复返回。修复方法:将该模型加入 - `agents.defaults.models`,移除 allowlist,或从 `/model list` 中选择一个模型。 + 这个错误会**替代**正常回复返回。修复方式:将该模型加入 + `agents.defaults.models`,移除允许列表,或从 `/model list` 中选择一个模型。 - 这意味着**提供商没有配置好**(未找到 MiniMax 提供商配置或 auth - profile),因此无法解析该模型。 + 这表示**提供商未配置**(找不到 MiniMax 提供商配置或认证 + 配置文件),因此无法解析该模型。 修复清单: - 1. 升级到当前的 OpenClaw 版本(或直接运行源码 `main`),然后重启 gateway。 - 2. 确保 MiniMax 已配置(通过向导或 JSON),或环境变量 / auth profiles 中已存在 MiniMax 认证, - 这样对应的提供商才能被注入 - (`minimax` 使用 `MINIMAX_API_KEY`,`minimax-portal` 使用 `MINIMAX_OAUTH_TOKEN` 或已保存的 MiniMax + 1. 升级到当前的 OpenClaw 版本(或从源码 `main` 运行),然后重启 gateway。 + 2. 确保 MiniMax 已配置好(通过向导或 JSON),或者 MiniMax 认证 + 已存在于环境变量/认证配置文件中,以便注入匹配的提供商 + (`minimax` 使用 `MINIMAX_API_KEY`,`minimax-portal` 使用 `MINIMAX_OAUTH_TOKEN` 或已存储的 MiniMax OAuth)。 - 3. 针对你的认证路径使用大小写敏感的精确模型 id: - API 密钥方式使用 `minimax/MiniMax-M2.7` 或 `minimax/MiniMax-M2.7-highspeed`, - OAuth 方式使用 `minimax-portal/MiniMax-M2.7` / + 3. 对应你的认证路径,使用**精确**模型 ID(区分大小写): + API key 配置使用 `minimax/MiniMax-M2.7` 或 `minimax/MiniMax-M2.7-highspeed`, + OAuth 配置使用 `minimax-portal/MiniMax-M2.7` / `minimax-portal/MiniMax-M2.7-highspeed`。 4. 运行: @@ -2350,15 +2357,15 @@ x-i18n: openclaw models list ``` - 并从列表中选择(或在聊天中使用 `/model list`)。 + 并从列表中选择一个(或在聊天中用 `/model list`)。 - 请参阅 [MiniMax](/zh-CN/providers/minimax) 和 [模型](/zh-CN/concepts/models)。 + 参见 [MiniMax](/zh-CN/providers/minimax) 和 [Models](/zh-CN/concepts/models)。 - - 可以。将 **MiniMax 设为默认值**,并在需要时**按会话**切换模型。 - 回退是为了解决**错误**,而不是“高难任务”,所以请使用 `/model` 或单独的智能体。 + + 可以。将 **MiniMax 设为默认值**,并在需要时**按会话** + 切换模型。回退用于处理**错误**,而不是“困难任务”,所以请使用 `/model` 或单独的智能体。 **选项 A:按会话切换** @@ -2383,18 +2390,18 @@ x-i18n: /model gpt ``` - **选项 B:单独的智能体** + **选项 B:独立智能体** - - 智能体 A 默认:MiniMax - - 智能体 B 默认:OpenAI - - 按智能体路由,或使用 `/agent` 进行切换 + - 智能体 A 默认值:MiniMax + - 智能体 B 默认值:OpenAI + - 按智能体路由,或使用 `/agent` 切换 - 文档:[模型](/zh-CN/concepts/models)、[多智能体路由](/zh-CN/concepts/multi-agent)、[MiniMax](/zh-CN/providers/minimax)、[OpenAI](/zh-CN/providers/openai)。 + 文档:[Models](/zh-CN/concepts/models)、[Multi-Agent Routing](/zh-CN/concepts/multi-agent)、[MiniMax](/zh-CN/providers/minimax)、[OpenAI](/zh-CN/providers/openai)。 - 是的。OpenClaw 内置了一些默认简写(仅当模型存在于 `agents.defaults.models` 中时才会生效): + 是的。OpenClaw 自带一些默认简写(仅当模型存在于 `agents.defaults.models` 中时适用): - `opus` → `anthropic/claude-opus-4-6` - `sonnet` → `anthropic/claude-sonnet-4-6` @@ -2409,7 +2416,7 @@ x-i18n: - + 别名来自 `agents.defaults.models..alias`。示例: ```json5 @@ -2427,12 +2434,12 @@ x-i18n: } ``` - 之后,`/model sonnet`(或在支持时使用 `/`)就会解析为对应模型 ID。 + 然后 `/model sonnet`(或在支持时使用 `/`)就会解析到该模型 ID。 - - OpenRouter(按 token 计费;很多模型): + + OpenRouter(按令牌计费;许多模型): ```json5 { @@ -2460,11 +2467,11 @@ x-i18n: } ``` - 如果你引用了某个 provider/model,但缺少所需的提供商 key,就会收到运行时认证错误(例如 `No API key found for provider "zai"`)。 + 如果你引用了某个提供商/模型,但缺少所需的提供商密钥,就会收到运行时认证错误(例如 `No API key found for provider "zai"`)。 **添加新智能体后出现 No API key found for provider** - 这通常意味着**新智能体**的 auth store 是空的。认证是按智能体分开的, + 这通常意味着**新智能体**的认证存储是空的。认证按智能体区分, 存储在: ``` @@ -2473,110 +2480,133 @@ x-i18n: 修复方式: - - 运行 `openclaw agents add `,并在向导中配置认证。 + - 运行 `openclaw agents add ` 并在向导中配置认证。 - 或将主智能体 `agentDir` 中的 `auth-profiles.json` 复制到新智能体的 `agentDir`。 - **不要**在多个智能体之间复用 `agentDir`;这会导致认证 / 会话冲突。 + **不要**在多个智能体之间复用 `agentDir`;这会导致认证/会话冲突。 -## 模型故障转移和 “All models failed” +## 模型故障切换与“All models failed” - - 故障转移分两个阶段: + + 故障切换分为两个阶段: - 1. 同一提供商内部的 **Auth profile 轮换**。 - 2. 回退到 `agents.defaults.model.fallbacks` 中的下一个**模型回退**。 + 1. 同一提供商内的**认证配置文件轮换**。 + 2. 回退到 `agents.defaults.model.fallbacks` 中的下一个模型。 - 对失败的 profile 会应用冷却(指数退避),因此即便某个提供商被限流或临时失败,OpenClaw 仍能持续响应。 + 对失败的配置文件会应用冷却时间(指数退避),因此即使提供商遭遇速率限制或临时故障,OpenClaw 仍可继续响应。 - 限流桶不仅包括纯粹的 `429` 响应。OpenClaw + 限速桶不仅包含普通的 `429` 响应。OpenClaw 还会将诸如 `Too many concurrent requests`、 `ThrottlingException`、`concurrency limit reached`、 `workers_ai ... quota limit exceeded`、`resource exhausted` 以及周期性 - 用量窗口限制(`weekly/monthly limit reached`)这类消息视为值得进行故障转移的 - 限流错误。 + 用量窗口限制(`weekly/monthly limit reached`)视为值得故障切换的 + 限速信号。 某些看起来像计费问题的响应并不是 `402`,而某些 HTTP `402` - 响应也仍会保留在该临时桶中。如果某个提供商在 `401` 或 `403` 上返回了明确的计费文本, - OpenClaw 仍可将其保留在计费类别中,但提供商特定的文本匹配器始终只作用于其对应提供商 - (例如 OpenRouter 的 `Key limit exceeded`)。如果一条 `402` - 消息看起来更像可重试的用量窗口或 - 组织 / 工作区支出上限(`daily limit reached, resets tomorrow`、 + 响应也仍然会归入瞬时错误桶。如果提供商在 `401` 或 `403` 上返回 + 明确的计费文本,OpenClaw 仍可将其保留在 + 计费通道中,但提供商特定的文本匹配器只会作用于 + 拥有它们的提供商(例如 OpenRouter 的 `Key limit exceeded`)。如果某个 `402` + 消息看起来像可重试的用量窗口或 + 组织/工作区支出限制(`daily limit reached, resets tomorrow`、 `organization spending limit exceeded`),OpenClaw 会将其视为 `rate_limit`,而不是长期计费禁用。 - 上下文溢出错误则不同:像 + 上下文溢出错误则不同:诸如 `request_too_large`、`input exceeds the maximum number of tokens`、 `input token count exceeds the maximum number of input tokens`、 `input is too long for the model` 或 `ollama error: context length - exceeded` 这类特征,会继续走压缩 / 重试路径,而不会推进模型 - 回退。 + exceeded` 之类的特征,会保留在压缩/重试路径上,而不是推进模型回退。 - 通用服务器错误文本的判定范围会刻意比“任何包含 - unknown/error 的内容”更窄。OpenClaw 会将一些提供商特定的瞬态形态 - 视为值得故障转移的超时 / 过载信号,例如 Anthropic 的裸消息 `An unknown error occurred`、OpenRouter 的裸消息 - `Provider returned error`、像 `Unhandled stop reason: - error` 这样的 stop-reason 错误、带瞬态服务器文本的 JSON `api_error` 载荷 + 通用服务器错误文本的判断范围有意比“任何包含 + unknown/error 的内容”更窄。OpenClaw 确实会将带有提供商上下文的瞬时形态视为故障切换信号, + 例如 Anthropic 裸 `An unknown error occurred`、OpenRouter 裸 + `Provider returned error`、停止原因错误如 `Unhandled stop reason: + error`、带有瞬时服务器文本的 JSON `api_error` 载荷 (`internal server error`、`unknown error, 520`、`upstream error`、`backend - error`),以及 `ModelNotReadyException` 之类的提供商繁忙错误,前提是提供商上下文匹配。 + error`),以及诸如 `ModelNotReadyException` 之类的提供商繁忙错误, + 当前提是提供商上下文匹配。 像 `LLM request failed with an unknown error.` 这样的通用内部回退文本则保持保守,不会仅凭自身触发模型回退。 - 这意味着系统试图使用 auth profile ID `anthropic:default`,但在预期的 auth store 中找不到对应凭证。 + 这意味着系统尝试使用认证配置文件 ID `anthropic:default`,但无法在预期的认证存储中找到对应凭证。 **修复清单:** - - **确认 auth profile 的存储位置**(新路径 vs 旧路径) - - 当前路径:`~/.openclaw/agents//agent/auth-profiles.json` - - 旧路径:`~/.openclaw/agent/*`(由 `openclaw doctor` 迁移) + - **确认认证配置文件存放位置**(新路径与旧路径) + - 当前:`~/.openclaw/agents//agent/auth-profiles.json` + - 旧版:`~/.openclaw/agent/*`(由 `openclaw doctor` 迁移) - **确认 Gateway 网关已加载你的环境变量** - - 如果你在 shell 中设置了 `ANTHROPIC_API_KEY`,但 Gateway 网关通过 systemd/launchd 运行,它可能不会继承该变量。请将其放入 `~/.openclaw/.env` 或启用 `env.shellEnv`。 - - **确保你正在编辑正确的智能体** - - 多智能体部署意味着可能存在多个 `auth-profiles.json` 文件。 - - **进行模型 / 认证状态完整性检查** - - 使用 `openclaw models status` 查看已配置模型以及提供商是否已认证。 + - 如果你在 shell 中设置了 `ANTHROPIC_API_KEY`,但通过 systemd/launchd 运行 Gateway 网关,它可能不会继承。请将其放入 `~/.openclaw/.env`,或启用 `env.shellEnv`。 + - **确保你编辑的是正确的智能体** + - 多智能体设置意味着可能存在多个 `auth-profiles.json` 文件。 + - **进行模型/认证状态完整性检查** + - 使用 `openclaw models status` 查看已配置模型,以及提供商是否已认证。 - **针对 “No credentials found for profile anthropic” 的修复清单** + **“No credentials found for profile anthropic”的修复清单** - 这意味着当前运行被固定到某个 Anthropic auth profile,但 Gateway 网关 - 无法在其 auth store 中找到它。 + 这意味着当前运行被固定到某个 Anthropic 认证配置文件,但 Gateway 网关 + 无法在其认证存储中找到它。 - **使用 Claude CLI** - - 在 gateway 主机上运行 `openclaw models auth login --provider anthropic --method cli --set-default`。 - - **如果你想改用 API 密钥** - - 将 `ANTHROPIC_API_KEY` 放到**gateway 主机**上的 `~/.openclaw/.env` 中。 - - 清除任何强制要求缺失 profile 的固定顺序: + - 在 gateway host 上运行 `openclaw models auth login --provider anthropic --method cli --set-default`。 + - **如果你想改用 API key** + - 将 `ANTHROPIC_API_KEY` 放入 **gateway host** 上的 `~/.openclaw/.env`。 + - 清除任何强制指定缺失配置文件的固定顺序: ```bash openclaw models auth order clear --provider anthropic ``` - - **确认你是在 gateway 主机上运行命令** - - 在远程模式下,auth profile 存储在 gateway 机器上,而不是你的笔记本上。 + - **确认你运行命令的地方就是 gateway host** + - 在远程模式下,认证配置文件位于 gateway 机器上,而不是你的笔记本。 - - 如果你的模型配置里包含 Google Gemini 作为回退项(或者你切换到了 Gemini 简写),OpenClaw 就会在模型回退期间尝试它。如果你没有配置 Google 凭证,就会看到 `No API key found for provider "google"`。 + + 如果你的模型配置将 Google Gemini 设为回退项(或者你切换到了 Gemini 简写),OpenClaw 会在模型回退期间尝试它。如果你没有配置 Google 凭证,就会看到 `No API key found for provider "google"`。 - 修复方法:要么提供 Google 认证,要么从 `agents.defaults.model.fallbacks` / aliases 中移除或避免使用 Google 模型,这样回退就不会路由到那里。 + 修复:提供 Google 认证,或者从 `agents.defaults.model.fallbacks` / 别名中移除或避免使用 Google 模型,这样回退时就不会路由过去。 **LLM request rejected: thinking signature required(Google Antigravity)** 原因:会话历史中包含**没有签名的 thinking 块**(通常来自 - 中止 / 部分流式输出)。Google Antigravity 要求 thinking 块必须带签名。 + 中止/部分流式传输)。Google Antigravity 要求 thinking 块必须有签名。 - 修复方法:OpenClaw 现在会为 Google Antigravity Claude 去掉未签名的 thinking 块。如果仍然出现,请开始一个**新会话**,或为该智能体设置 `/thinking off`。 + 修复:OpenClaw 现在会为 Google Antigravity Claude 去除无签名的 thinking 块。如果仍然出现,请开启一个**新会话**,或为该智能体设置 `/thinking off`。 -## Auth profile:它是什么,以及如何管理 +## 认证配置文件:是什么以及如何管理 -相关 \ No newline at end of file +相关内容:[/concepts/oauth](/zh-CN/concepts/oauth)(OAuth 流程、令牌存储、多账号模式) + + + + 认证配置文件是与某个提供商绑定的命名凭证记录(OAuth 或 API key)。配置文件存储在: + + ``` + ~/.openclaw/agents//agent/auth-profiles.json + ``` + + + + + OpenClaw 使用带提供商前缀的 ID,例如: + + - `anthropic:default`(无邮箱身份时常见) + - `anthropic:` 用于 OAuth 身份 + - 你自定义的 ID(例如 `anthropic:work`) + + + + + 可以。配置支持可选的配置文件元数据,以及按提供商排序(`auth.order.`)。这**不会**存储秘密;它 \ No newline at end of file diff --git a/docs/zh-CN/help/testing.md b/docs/zh-CN/help/testing.md index 06572e897..906bcce9d 100644 --- a/docs/zh-CN/help/testing.md +++ b/docs/zh-CN/help/testing.md @@ -1,28 +1,28 @@ --- read_when: - - 在本地或 CI 中运行测试时 - - 为模型/提供商缺陷添加回归测试时 - - 调试 Gateway 网关 + 智能体行为时 -summary: 测试套件:单元/e2e/实时套件、Docker 运行器,以及各类测试覆盖的内容 + - 在本地或 CI 中运行测试 + - 为模型/提供商 Bug 添加回归测试 + - 调试 Gateway 网关 + 智能体行为 +summary: 测试工具包:unit/e2e/live 测试套件、Docker 运行器,以及各项测试覆盖的内容 title: 测试 x-i18n: - generated_at: "2026-04-05T17:49:14Z" + generated_at: "2026-04-05T18:14:58Z" model: gpt-5.4 provider: openai - source_hash: 646f7bc92f15fc7c0270d6febee9f192ec1c8a6e9bb0cc8730bce73757521cac + source_hash: 65305c0de33287f48f182bb9f276e4f3ba9cc49c65a54e115e1d77ec89f56ab7 source_path: help/testing.md workflow: 15 --- # 测试 -OpenClaw 有三个 Vitest 测试套件(单元/集成、e2e、实时)以及一小组 Docker 运行器。 +OpenClaw 有三个 Vitest 测试套件(unit/integration、e2e、live)以及一小组 Docker 运行器。 本文档是一份“我们如何测试”的指南: -- 每个套件覆盖什么(以及它刻意**不**覆盖什么) +- 每个测试套件覆盖什么内容(以及它刻意 _不_ 覆盖什么) - 常见工作流应运行哪些命令(本地、推送前、调试) -- 实时测试如何发现凭证并选择模型/提供商 +- live 测试如何发现凭证并选择模型/提供商 - 如何为真实世界中的模型/提供商问题添加回归测试 ## 快速开始 @@ -30,68 +30,70 @@ OpenClaw 有三个 Vitest 测试套件(单元/集成、e2e、实时)以及 大多数时候: - 完整门禁(预期在推送前运行):`pnpm build && pnpm check && pnpm test` -- 在资源充足的机器上更快地运行本地完整套件:`pnpm test:max` -- 直接运行 Vitest 监听循环(现代项目配置):`pnpm test:watch` -- 直接指定文件现在也支持扩展/渠道路径:`pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` +- 在配置充裕的机器上更快地运行本地完整测试套件:`pnpm test:max` +- 直接使用 Vitest 监视循环(现代 projects 配置):`pnpm test:watch` +- 直接按文件定位现在也会路由扩展/渠道路径:`pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` -当你修改测试或想要更高信心时: +当你改动了测试或想获得更高信心时: - 覆盖率门禁:`pnpm test:coverage` -- E2E 套件:`pnpm test:e2e` +- E2E 测试套件:`pnpm test:e2e` -当你调试真实提供商/模型时(需要真实凭证): +当你在调试真实提供商/模型时(需要真实凭证): -- 实时套件(模型 + Gateway 网关工具/图像探针):`pnpm test:live` -- 安静地只跑一个实时文件:`pnpm test:live -- src/agents/models.profiles.live.test.ts` +- Live 测试套件(模型 + Gateway 网关工具/图像探测):`pnpm test:live` +- 安静地只跑一个 live 文件:`pnpm test:live -- src/agents/models.profiles.live.test.ts` -提示:如果你只需要一个失败用例,优先使用下面描述的允许名单环境变量来缩小实时测试范围。 +提示:当你只需要一个失败用例时,优先使用下文描述的 allowlist 环境变量来缩小 live 测试范围。 -## 测试套件(各自运行位置) +## 测试套件(各自在哪里运行) -可以把这些套件理解为“真实性逐步提升”(同时不稳定性/成本也逐步提高): +可以把这些测试套件理解为“真实度逐步提升”(同时不稳定性/成本也逐步提升): -### 单元 / 集成(默认) +### Unit / integration(默认) - 命令:`pnpm test` - 配置:通过 `vitest.config.ts` 使用原生 Vitest `projects` -- 文件:`src/**/*.test.ts`、`packages/**/*.test.ts`、`test/**/*.test.ts` 下的核心/单元测试清单,以及 `vitest.unit.config.ts` 覆盖的白名单 `ui` Node 测试 +- 文件:`src/**/*.test.ts`、`packages/**/*.test.ts`、`test/**/*.test.ts` 下的 core/unit 测试清单,以及 `vitest.unit.config.ts` 覆盖的白名单 `ui` node 测试 - 范围: - 纯单元测试 - 进程内集成测试(Gateway 网关认证、路由、工具、解析、配置) - - 已知缺陷的确定性回归测试 + - 已知 Bug 的确定性回归测试 - 预期: - 在 CI 中运行 - 不需要真实密钥 - 应该快速且稳定 - Projects 说明: - - `pnpm test`、`pnpm test:watch` 和 `pnpm test:changed` 现在都使用同一套原生 Vitest 根 `projects` 配置。 - - 直接文件过滤现在会原生通过根项目图路由,因此 `pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` 无需自定义包装器即可工作。 -- 嵌入式运行器说明: - - 当你更改消息工具发现输入或压缩运行时上下文时, - 请同时保留这两个层级的覆盖。 - - 为纯路由/归一化边界添加聚焦的辅助回归测试。 - - 同时也要保持嵌入式运行器集成套件健康: + - `pnpm test`、`pnpm test:watch` 和 `pnpm test:changed` 现在都使用相同的原生 Vitest 根 `projects` 配置。 + - 直接文件过滤现在会原生通过根项目图进行路由,因此 `pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` 无需自定义包装器即可运行。 +- Embedded runner 说明: + - 当你修改消息工具发现输入或压缩运行时上下文时, + 需要同时保留两个层级的覆盖。 + - 为纯路由/规范化边界添加聚焦的辅助回归测试。 + - 同时也要保持 embedded runner 集成测试套件健康: `src/agents/pi-embedded-runner/compact.hooks.test.ts`、 `src/agents/pi-embedded-runner/run.overflow-compaction.test.ts` 和 `src/agents/pi-embedded-runner/run.overflow-compaction.loop.test.ts`。 - - 这些套件会验证作用域 id 和压缩行为仍然会流经真实的 `run.ts` / `compact.ts` 路径;仅有辅助函数测试并不能充分替代这些集成路径。 -- 线程池说明: + - 这些测试套件会验证带作用域的 id 和压缩行为仍然会通过真实的 + `run.ts` / `compact.ts` 路径流转;仅有 helper 测试 + 不足以替代这些集成路径。 +- Pool 说明: - 基础 Vitest 配置现在默认使用 `threads`。 - - 共享 Vitest 配置还固定设置了 `isolate: false`,并在根项目、e2e 和实时配置中使用非隔离运行器。 - - 根 UI 测试通道保留其 `jsdom` 设置和优化器,但现在也运行在共享的非隔离运行器上。 - - `pnpm test` 现在也从根 `vitest.config.ts` 的 projects 配置继承相同的 `threads` + `isolate: false` 默认值。 - - 共享的 `scripts/run-vitest.mjs` 启动器现在默认还会为 Vitest 子 Node 进程添加 `--no-maglev`,以减少大型本地运行期间的 V8 编译抖动。如果你需要与原始 V8 行为进行对比,请设置 `OPENCLAW_VITEST_ENABLE_MAGLEV=1`。 -- 快速本地迭代说明: - - `pnpm test:changed` 使用原生 projects 配置并附加 `--changed origin/main`。 - - `pnpm test:max` 和 `pnpm test:changed:max` 保持相同的原生 projects 配置,只是使用更高的 worker 上限。 - - 本地 worker 自动扩缩现在有意更保守,而且当主机平均负载已经较高时也会退让,因此默认情况下多个并发 Vitest 运行造成的影响会更小。 - - 基础 Vitest 配置会将 projects/config 文件标记为 `forceRerunTriggers`,这样当测试接线发生变化时,changed 模式重跑仍然正确。 - - 在受支持的主机上,配置会保持启用 `OPENCLAW_VITEST_FS_MODULE_CACHE`;如果你希望为直接性能分析指定一个明确缓存位置,请设置 `OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=/abs/path`。 + - 共享 Vitest 配置还固定了 `isolate: false`,并在根 projects、e2e 和 live 配置中使用非隔离运行器。 + - 根 UI 通道仍保留其 `jsdom` 设置和优化器,但现在也在共享的非隔离运行器上运行。 + - `pnpm test` 现在会从根 `vitest.config.ts` 的 projects 配置继承相同的 `threads` + `isolate: false` 默认值。 + - 共享的 `scripts/run-vitest.mjs` 启动器现在也会默认为 Vitest 子 Node 进程添加 `--no-maglev`,以减少大型本地运行期间的 V8 编译抖动。如果你需要与原始 V8 行为对比,可设置 `OPENCLAW_VITEST_ENABLE_MAGLEV=1`。 +- 本地快速迭代说明: + - `pnpm test:changed` 会用 `--changed origin/main` 运行原生 projects 配置。 + - `pnpm test:max` 和 `pnpm test:changed:max` 保持相同的原生 projects 配置,只是提高了 worker 上限。 + - 本地 worker 自动扩缩容现在有意更保守,并且当主机平均负载已经较高时也会回退,因此默认情况下多个并发 Vitest 运行造成的影响更小。 + - 基础 Vitest 配置会将 projects/config 文件标记为 `forceRerunTriggers`,以便在测试接线发生变化时,changed 模式下的重跑仍然正确。 + - 配置会在受支持主机上保持启用 `OPENCLAW_VITEST_FS_MODULE_CACHE`;如果你想为直接性能分析指定一个显式缓存位置,可设置 `OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=/abs/path`。 - 性能调试说明: - - `pnpm test:perf:imports` 会启用 Vitest 导入耗时报告以及导入细分输出。 - - `pnpm test:perf:imports:changed` 会将相同的分析视图限定为自 `origin/main` 以来变更的文件。 + - `pnpm test:perf:imports` 会启用 Vitest 导入耗时报告以及导入明细输出。 + - `pnpm test:perf:imports:changed` 会将相同的分析视图限定到相对 `origin/main` 已变更的文件。 - `pnpm test:perf:profile:main` 会为 Vitest/Vite 启动和 transform 开销写出主线程 CPU profile。 - - `pnpm test:perf:profile:runner` 会在禁用文件并行的情况下,为单元测试套件写出运行器 CPU + 堆 profile。 + - `pnpm test:perf:profile:runner` 会在禁用文件并行的情况下,为 unit 测试套件写出 runner CPU + heap profile。 ### E2E(Gateway 网关冒烟) @@ -99,219 +101,179 @@ OpenClaw 有三个 Vitest 测试套件(单元/集成、e2e、实时)以及 - 配置:`vitest.e2e.config.ts` - 文件:`src/**/*.e2e.test.ts`、`test/**/*.e2e.test.ts` - 运行时默认值: - - 使用带 `isolate: false` 的 Vitest `threads`,与仓库其余部分保持一致。 - - 使用自适应 workers(CI:最多 2 个,本地:默认 1 个)。 + - 使用 Vitest `threads` 且 `isolate: false`,与仓库其余部分保持一致。 + - 使用自适应 worker(CI:最多 2 个,本地:默认 1 个)。 - 默认以静默模式运行,以减少控制台 I/O 开销。 - 常用覆盖项: - `OPENCLAW_E2E_WORKERS=` 强制指定 worker 数量(上限为 16)。 - `OPENCLAW_E2E_VERBOSE=1` 重新启用详细控制台输出。 - 范围: - 多实例 Gateway 网关端到端行为 - - WebSocket/HTTP 界面、节点配对及更重的网络场景 + - WebSocket/HTTP 接口、节点配对以及更重的网络交互 - 预期: - 在 CI 中运行(当流水线启用时) - 不需要真实密钥 - - 比单元测试包含更多活动部件(可能更慢) + - 比单元测试有更多活动部件(可能更慢) ### E2E:OpenShell 后端冒烟 - 命令:`pnpm test:e2e:openshell` - 文件:`test/openshell-sandbox.e2e.test.ts` - 范围: - - 通过 Docker 在主机上启动一个隔离的 OpenShell Gateway 网关 - - 从临时本地 Dockerfile 创建一个沙箱 + - 通过 Docker 在宿主机上启动一个隔离的 OpenShell Gateway 网关 + - 从一个临时本地 Dockerfile 创建沙箱 - 通过真实的 `sandbox ssh-config` + SSH exec 运行 OpenClaw 的 OpenShell 后端 - 通过沙箱 fs bridge 验证远端规范文件系统行为 - 预期: - - 仅按需启用;不属于默认 `pnpm test:e2e` 运行的一部分 + - 仅限选择性启用;不属于默认 `pnpm test:e2e` 运行的一部分 - 需要本地 `openshell` CLI 和可用的 Docker daemon - 使用隔离的 `HOME` / `XDG_CONFIG_HOME`,然后销毁测试 Gateway 网关和沙箱 - 常用覆盖项: - - `OPENCLAW_E2E_OPENSHELL=1`,在手动运行更广泛的 e2e 套件时启用该测试 + - `OPENCLAW_E2E_OPENSHELL=1`,在手动运行更广泛的 e2e 测试套件时启用该测试 - `OPENCLAW_E2E_OPENSHELL_COMMAND=/path/to/openshell`,指向非默认 CLI 二进制或包装脚本 -### 实时(真实提供商 + 真实模型) +### Live(真实提供商 + 真实模型) - 命令:`pnpm test:live` - 配置:`vitest.live.config.ts` - 文件:`src/**/*.live.test.ts` - 默认:由 `pnpm test:live` **启用**(设置 `OPENCLAW_LIVE_TEST=1`) - 范围: - - “这个提供商/模型今天在真实凭证下是否真的能工作?” - - 捕获提供商格式变化、工具调用怪癖、认证问题和速率限制行为 + - “这个提供商/模型 _今天_ 在真实凭证下是否确实能工作?” + - 捕获提供商格式变化、工具调用怪癖、认证问题和限流行为 - 预期: - - 按设计不适合 CI 稳定运行(真实网络、真实提供商策略、配额、宕机) - - 会花钱 / 消耗速率限制 + - 按设计不保证 CI 稳定(真实网络、真实提供商策略、配额、故障) + - 会花钱 / 消耗限流额度 - 优先运行缩小范围的子集,而不是“全部” -- 实时运行会读取 `~/.profile`,以获取缺失的 API 密钥。 -- 默认情况下,实时运行仍会隔离 `HOME`,并将配置/认证材料复制到临时测试 home 中,这样单元测试夹具就不会修改你的真实 `~/.openclaw`。 -- 只有在你明确需要让实时测试使用真实 home 目录时,才设置 `OPENCLAW_LIVE_USE_REAL_HOME=1`。 -- `pnpm test:live` 现在默认采用更安静的模式:保留 `[live] ...` 进度输出,但抑制额外的 `~/.profile` 提示,并静默 Gateway 网关启动日志/Bonjour 噪声。如果你想恢复完整启动日志,请设置 `OPENCLAW_LIVE_TEST_QUIET=0`。 -- API 密钥轮换(提供商特定):设置 `*_API_KEYS`(逗号/分号格式)或 `*_API_KEY_1`、`*_API_KEY_2`(例如 `OPENAI_API_KEYS`、`ANTHROPIC_API_KEYS`、`GEMINI_API_KEYS`),或者通过 `OPENCLAW_LIVE_*_KEY` 进行实时测试覆盖;测试在收到速率限制响应时会重试。 +- Live 运行会读取 `~/.profile` 以获取缺失的 API 密钥。 +- 默认情况下,live 运行仍会隔离 `HOME`,并把配置/认证材料复制到临时测试 home 中,这样 unit fixture 就不能修改你真实的 `~/.openclaw`。 +- 只有当你明确需要 live 测试使用真实 home 目录时,才设置 `OPENCLAW_LIVE_USE_REAL_HOME=1`。 +- `pnpm test:live` 现在默认更安静:它会保留 `[live] ...` 进度输出,但会抑制额外的 `~/.profile` 提示,并静音 Gateway 网关启动日志/Bonjour 噪声。如果你想恢复完整启动日志,请设置 `OPENCLAW_LIVE_TEST_QUIET=0`。 +- API 密钥轮换(提供商特定):设置 `*_API_KEYS`(逗号/分号格式)或 `*_API_KEY_1`、`*_API_KEY_2`(例如 `OPENAI_API_KEYS`、`ANTHROPIC_API_KEYS`、`GEMINI_API_KEYS`),或者通过 `OPENCLAW_LIVE_*_KEY` 做每个 live 运行的单独覆盖;测试会在收到限流响应时重试。 - 进度/心跳输出: - - 实时套件现在会将进度行输出到 stderr,因此即使 Vitest 控制台捕获很安静,长时间的提供商调用也会明显显示为活跃状态。 - - `vitest.live.config.ts` 禁用了 Vitest 控制台拦截,因此在实时运行期间,提供商/Gateway 网关进度行会立即流式输出。 - - 使用 `OPENCLAW_LIVE_HEARTBEAT_MS` 调整直连模型心跳。 - - 使用 `OPENCLAW_LIVE_GATEWAY_HEARTBEAT_MS` 调整 Gateway 网关/探针心跳。 + - Live 测试套件现在会向 stderr 输出进度行,因此即使 Vitest 控制台捕获较安静,长时间的提供商调用也能明显看出仍在活动。 + - `vitest.live.config.ts` 会禁用 Vitest 控制台拦截,以便提供商/Gateway 网关进度行在 live 运行期间立即流式输出。 + - 使用 `OPENCLAW_LIVE_HEARTBEAT_MS` 调整 direct-model 心跳。 + - 使用 `OPENCLAW_LIVE_GATEWAY_HEARTBEAT_MS` 调整 Gateway 网关/探测心跳。 -## 我应该运行哪个套件? +## 我应该运行哪个测试套件? -使用这个决策表: +使用这张决策表: -- 编辑逻辑/测试:运行 `pnpm test`(如果你改动很多,也可运行 `pnpm test:coverage`) -- 修改 Gateway 网关网络 / WS 协议 / 配对:额外运行 `pnpm test:e2e` -- 调试“我的机器人挂了” / 提供商特定故障 / 工具调用:运行缩小范围的 `pnpm test:live` +- 编辑逻辑/测试:运行 `pnpm test`(如果改动较多,也运行 `pnpm test:coverage`) +- 触及 Gateway 网关网络 / WS 协议 / 配对:额外运行 `pnpm test:e2e` +- 调试“我的 bot 挂了” / 提供商特定故障 / 工具调用:运行缩小范围的 `pnpm test:live` -## 实时:Android 节点能力扫描 +## Live:Android 节点能力扫查 - 测试:`src/gateway/android-node.capabilities.live.test.ts` - 脚本:`pnpm android:test:integration` -- 目标:调用已连接 Android 节点当前**公开的每一条命令**,并断言命令契约行为。 +- 目标:调用已连接 Android 节点当前**公布的每一条命令**,并断言命令契约行为。 - 范围: - - 有前置条件/手动设置(该套件不会安装/运行/配对应用)。 + - 预置/手动设置(该测试套件不会安装/运行/配对 app)。 - 针对所选 Android 节点逐条执行 Gateway 网关 `node.invoke` 验证。 -- 必需的预先设置: - - Android 应用已连接并与 Gateway 网关配对。 - - 应用保持在前台。 - - 你希望通过的能力所需权限/捕获同意已授予。 -- 可选目标覆盖: +- 必需的预设置: + - Android app 已连接并已与 Gateway 网关配对。 + - App 保持在前台。 + - 已授予你期望通过的能力所需的权限/采集同意。 +- 可选目标覆盖项: - `OPENCLAW_ANDROID_NODE_ID` 或 `OPENCLAW_ANDROID_NODE_NAME`。 - `OPENCLAW_ANDROID_GATEWAY_URL` / `OPENCLAW_ANDROID_GATEWAY_TOKEN` / `OPENCLAW_ANDROID_GATEWAY_PASSWORD`。 - 完整 Android 设置详情:[Android App](/zh-CN/platforms/android) -## 实时:模型冒烟(profile keys) +## Live:模型冒烟(profile keys) -实时测试分成两层,以便我们隔离故障: +Live 测试分成两层,以便我们隔离故障: -- “Direct model” 告诉我们:在给定密钥下,该提供商/模型是否至少能回答。 -- “Gateway smoke” 告诉我们:该模型的完整 Gateway 网关 + 智能体流水线是否工作正常(会话、历史、工具、沙箱策略等)。 +- “Direct model” 告诉我们,在给定密钥下,该提供商/模型是否至少能响应。 +- “Gateway smoke” 告诉我们,该模型的完整 Gateway 网关 + 智能体流水线是否工作(会话、历史、工具、沙箱策略等)。 ### 第 1 层:Direct model completion(无 Gateway 网关) - 测试:`src/agents/models.profiles.live.test.ts` - 目标: - 枚举已发现的模型 - - 使用 `getApiKeyForModel` 选择你已有凭证的模型 - - 为每个模型运行一个小型 completion(必要时附带定向回归测试) -- 启用方式: - - `pnpm test:live`(如果直接调用 Vitest,则设置 `OPENCLAW_LIVE_TEST=1`) -- 设置 `OPENCLAW_LIVE_MODELS=modern`(或 `all`,是 modern 的别名)后,该套件才会真正运行;否则它会跳过,以让 `pnpm test:live` 聚焦于 Gateway 网关冒烟 + - 使用 `getApiKeyForModel` 选择你有凭证的模型 + - 为每个模型运行一个小型 completion(必要时附带定向回归) +- 如何启用: + - `pnpm test:live`(或者如果你直接调用 Vitest,则设置 `OPENCLAW_LIVE_TEST=1`) +- 设置 `OPENCLAW_LIVE_MODELS=modern`(或 `all`,即 modern 的别名)才会实际运行该测试套件;否则会跳过,以便让 `pnpm test:live` 聚焦在 Gateway 网关冒烟 - 如何选择模型: - - `OPENCLAW_LIVE_MODELS=modern` 运行现代允许名单(Opus/Sonnet 4.6+、GPT-5.x + Codex、Gemini 3、GLM 4.7、MiniMax M2.7、Grok 4) - - `OPENCLAW_LIVE_MODELS=all` 是现代允许名单的别名 - - 或 `OPENCLAW_LIVE_MODELS="openai/gpt-5.4,anthropic/claude-opus-4-6,..."`(逗号分隔的允许名单) + - `OPENCLAW_LIVE_MODELS=modern` 运行现代 allowlist(Opus/Sonnet 4.6+、GPT-5.x + Codex、Gemini 3、GLM 4.7、MiniMax M2.7、Grok 4) + - `OPENCLAW_LIVE_MODELS=all` 是现代 allowlist 的别名 + - 或者 `OPENCLAW_LIVE_MODELS="openai/gpt-5.4,anthropic/claude-opus-4-6,..."`(逗号分隔的 allowlist) - 如何选择提供商: - - `OPENCLAW_LIVE_PROVIDERS="google,google-antigravity,google-gemini-cli"`(逗号分隔的允许名单) + - `OPENCLAW_LIVE_PROVIDERS="google,google-antigravity"`(逗号分隔的 allowlist) - 密钥来源: - 默认:profile 存储和环境变量回退 - - 设置 `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 可强制**仅使用 profile 存储** + - 设置 `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 可强制**仅**使用 profile 存储 - 存在原因: - - 将“提供商 API 坏了 / 密钥无效”和“Gateway 网关智能体流水线坏了”区分开 - - 包含小型、隔离的回归测试(例如:OpenAI Responses/Codex Responses 的推理回放 + 工具调用流程) + - 将“提供商 API 坏了 / 密钥无效”和“Gateway 网关智能体流水线坏了”分开 + - 包含小型、隔离的回归测试(例如:OpenAI Responses/Codex Responses 推理重放 + 工具调用流) ### 第 2 层:Gateway 网关 + dev 智能体冒烟(也就是 “@openclaw” 实际做的事) - 测试:`src/gateway/gateway-models.profiles.live.test.ts` - 目标: - 启动一个进程内 Gateway 网关 - - 创建/修补一个 `agent:dev:*` 会话(每次运行可覆盖模型) + - 创建/修补一个 `agent:dev:*` 会话(每次运行按模型覆盖) - 遍历带密钥的模型并断言: - - “有意义”的回复(无工具) - - 一次真实工具调用可用(read 探针) - - 可选的额外工具探针(exec+read 探针) - - OpenAI 回归路径(仅工具调用 → 后续跟进)持续有效 -- 探针细节(便于你快速解释故障): - - `read` 探针:测试会在工作区中写入一个 nonce 文件,并要求智能体 `read` 它并把 nonce 原样回显。 - - `exec+read` 探针:测试会要求智能体通过 `exec` 将 nonce 写入临时文件,然后再 `read` 回来。 - - 图像探针:测试会附加一个生成的 PNG(猫 + 随机代码),并期望模型返回 `cat `。 + - “有意义”的响应(无工具) + - 真实工具调用可用(read 探测) + - 可选的额外工具探测(exec+read 探测) + - OpenAI 回归路径(仅工具调用 → 后续跟进)继续可用 +- 探测细节(这样你可以快速解释失败原因): + - `read` 探测:测试会在工作区写入一个 nonce 文件,并要求智能体 `read` 该文件后回显 nonce。 + - `exec+read` 探测:测试会要求智能体通过 `exec` 将 nonce 写入一个临时文件,然后再 `read` 回来。 + - 图像探测:测试会附加一个生成的 PNG(cat + 随机代码),并期望模型返回 `cat `。 - 实现参考:`src/gateway/gateway-models.profiles.live.test.ts` 和 `src/gateway/live-image-probe.ts`。 -- 启用方式: - - `pnpm test:live`(如果直接调用 Vitest,则设置 `OPENCLAW_LIVE_TEST=1`) +- 如何启用: + - `pnpm test:live`(或者如果你直接调用 Vitest,则设置 `OPENCLAW_LIVE_TEST=1`) - 如何选择模型: - - 默认:现代允许名单(Opus/Sonnet 4.6+、GPT-5.x + Codex、Gemini 3、GLM 4.7、MiniMax M2.7、Grok 4) - - `OPENCLAW_LIVE_GATEWAY_MODELS=all` 是现代允许名单的别名 - - 或设置 `OPENCLAW_LIVE_GATEWAY_MODELS="provider/model"`(或逗号列表)来缩小范围 + - 默认:现代 allowlist(Opus/Sonnet 4.6+、GPT-5.x + Codex、Gemini 3、GLM 4.7、MiniMax M2.7、Grok 4) + - `OPENCLAW_LIVE_GATEWAY_MODELS=all` 是现代 allowlist 的别名 + - 或者设置 `OPENCLAW_LIVE_GATEWAY_MODELS="provider/model"`(或逗号列表)来缩小范围 - 如何选择提供商(避免“OpenRouter 全家桶”): - - `OPENCLAW_LIVE_GATEWAY_PROVIDERS="google,google-antigravity,google-gemini-cli,openai,anthropic,zai,minimax"`(逗号分隔的允许名单) -- 工具 + 图像探针在这个实时测试中始终开启: - - `read` 探针 + `exec+read` 探针(工具压力测试) - - 当模型宣告支持图像输入时,会运行图像探针 + - `OPENCLAW_LIVE_GATEWAY_PROVIDERS="google,google-antigravity,openai,anthropic,zai,minimax"`(逗号分隔的 allowlist) +- 在这个 live 测试中,工具 + 图像探测始终启用: + - `read` 探测 + `exec+read` 探测(工具压力测试) + - 当模型宣告支持图像输入时,会运行图像探测 - 流程(高层): - - 测试生成一个带有 “CAT” + 随机代码的小 PNG(`src/gateway/live-image-probe.ts`) + - 测试生成一个带有 “CAT” + 随机代码的小型 PNG(`src/gateway/live-image-probe.ts`) - 通过 `agent` `attachments: [{ mimeType: "image/png", content: "" }]` 发送 - - Gateway 网关将附件解析到 `images[]`(`src/gateway/server-methods/agent.ts` + `src/gateway/chat-attachments.ts`) - - 嵌入式智能体将多模态用户消息转发给模型 + - Gateway 网关将附件解析为 `images[]`(`src/gateway/server-methods/agent.ts` + `src/gateway/chat-attachments.ts`) + - Embedded agent 将多模态用户消息转发给模型 - 断言:回复包含 `cat` + 该代码(OCR 容错:允许轻微错误) -提示:如果你想查看自己的机器上能测试哪些内容(以及精确的 `provider/model` id),请运行: +提示:如果你想查看在自己的机器上可以测试什么(以及精确的 `provider/model` id),请运行: ```bash openclaw models list openclaw models list --json ``` -## 实时:CLI 后端冒烟(Codex CLI 或其他本地 CLI) - -- 测试:`src/gateway/gateway-cli-backend.live.test.ts` -- 目标:在不触碰默认配置的前提下,使用本地 CLI 后端验证 Gateway 网关 + 智能体流水线。 -- 启用: - - `pnpm test:live`(如果直接调用 Vitest,则设置 `OPENCLAW_LIVE_TEST=1`) - - `OPENCLAW_LIVE_CLI_BACKEND=1` -- 默认值: - - 模型:`codex-cli/gpt-5.4` - - 命令:`codex` - - 参数:`["exec","--json","--color","never","--sandbox","read-only","--skip-git-repo-check"]` -- 覆盖项(可选): - - `OPENCLAW_LIVE_CLI_BACKEND_MODEL="codex-cli/gpt-5.4"` - - `OPENCLAW_LIVE_CLI_BACKEND_COMMAND="/full/path/to/codex"` - - `OPENCLAW_LIVE_CLI_BACKEND_ARGS='["exec","--json","--color","never","--sandbox","read-only","--skip-git-repo-check"]'` - - `OPENCLAW_LIVE_CLI_BACKEND_IMAGE_PROBE=1` 发送真实图像附件(路径会注入到提示中)。 - - `OPENCLAW_LIVE_CLI_BACKEND_IMAGE_ARG="--image"` 将图像文件路径作为 CLI 参数传递,而不是注入到提示中。 - - `OPENCLAW_LIVE_CLI_BACKEND_IMAGE_MODE="repeat"`(或 `"list"`)控制在设置 `IMAGE_ARG` 时如何传递图像参数。 - - `OPENCLAW_LIVE_CLI_BACKEND_RESUME_PROBE=1` 发送第二轮并验证恢复流程。 - -示例: - -```bash -OPENCLAW_LIVE_CLI_BACKEND=1 \ - OPENCLAW_LIVE_CLI_BACKEND_MODEL="codex-cli/gpt-5.4" \ - pnpm test:live src/gateway/gateway-cli-backend.live.test.ts -``` - -Docker 配方: - -```bash -pnpm test:docker:live-cli-backend -``` - -说明: - -- Docker 运行器位于 `scripts/test-live-cli-backend-docker.sh`。 -- 它会在仓库 Docker 镜像中以非 root 的 `node` 用户运行实时 CLI 后端冒烟测试。 -- 对于 `codex-cli`,它会将 Linux 版 `@openai/codex` 安装到可缓存的可写前缀 `OPENCLAW_DOCKER_CLI_TOOLS_DIR` 中(默认:`~/.cache/openclaw/docker-cli-tools`)。 - -## 实时:ACP 绑定冒烟(`/acp spawn ... --bind here`) +## Live:ACP 绑定冒烟(`/acp spawn ... --bind here`) - 测试:`src/gateway/gateway-acp-bind.live.test.ts` -- 目标:使用实时 ACP 智能体验证真实 ACP 会话绑定流程: +- 目标:用一个 live ACP 智能体验证真实的 ACP 会话绑定流程: - 发送 `/acp spawn --bind here` - - 就地绑定一个合成的消息渠道会话 - - 在同一会话上发送普通后续消息 - - 验证该后续消息落入已绑定 ACP 会话的转录中 + - 原地绑定一个合成的 message-channel 会话 + - 在同一会话上发送一条普通的后续消息 + - 验证该后续消息会落入已绑定的 ACP 会话 transcript 中 - 启用: - `pnpm test:live src/gateway/gateway-acp-bind.live.test.ts` - `OPENCLAW_LIVE_ACP_BIND=1` - 默认值: - ACP 智能体:`claude` - - 合成渠道:类似 Slack 私信风格的会话上下文 + - 合成渠道:Slack 私信风格的会话上下文 - ACP 后端:`acpx` - 覆盖项: - `OPENCLAW_LIVE_ACP_BIND_AGENT=claude` - `OPENCLAW_LIVE_ACP_BIND_AGENT=codex` - `OPENCLAW_LIVE_ACP_BIND_AGENT_COMMAND='npx -y @agentclientprotocol/claude-agent-acp@'` - 说明: - - 此测试通道使用 Gateway 网关 `chat.send` 界面,并带有仅管理员可用的合成 originating-route 字段,因此测试可以附加消息渠道上下文,而无需伪装为对外投递。 - - 当未设置 `OPENCLAW_LIVE_ACP_BIND_AGENT_COMMAND` 时,测试会对所选 ACP harness 智能体使用内置 `acpx` 插件中的内建智能体注册表。 + - 该通道使用 Gateway 网关 `chat.send` 接口,并附带仅限管理员使用的合成 originating-route 字段,因此测试可以附着消息渠道上下文,而无需假装真的对外投递。 + - 当未设置 `OPENCLAW_LIVE_ACP_BIND_AGENT_COMMAND` 时,测试会使用内置 `acpx` 插件的内建智能体注册表来选择 ACP harness 智能体。 示例: @@ -330,14 +292,14 @@ pnpm test:docker:live-acp-bind Docker 说明: - Docker 运行器位于 `scripts/test-live-acp-bind-docker.sh`。 -- 它会读取 `~/.profile`,将匹配的 CLI 认证材料暂存到容器内,把 `acpx` 安装到可写 npm 前缀中,然后在缺失时安装请求的实时 CLI(`@anthropic-ai/claude-code` 或 `@openai/codex`)。 -- 在 Docker 内,运行器会设置 `OPENCLAW_LIVE_ACP_BIND_ACPX_COMMAND=$HOME/.npm-global/bin/acpx`,这样 `acpx` 能让从 profile 中读取到的提供商环境变量继续提供给子 harness CLI。 +- 它会读取 `~/.profile`,将匹配的 CLI 认证材料暂存到容器中,把 `acpx` 安装到可写的 npm prefix 中,然后在缺失时安装所请求的 live CLI(`@anthropic-ai/claude-code` 或 `@openai/codex`)。 +- 在 Docker 内,运行器会设置 `OPENCLAW_LIVE_ACP_BIND_ACPX_COMMAND=$HOME/.npm-global/bin/acpx`,从而使 acpx 保留来自已读取 profile 的提供商环境变量,并传递给子 harness CLI。 -### 推荐的实时配方 +### 推荐的 live 配方 -范围窄、明确的允许名单最快,也最不容易出问题: +缩小范围、显式的 allowlist 最快也最不容易不稳定: -- 单模型,直连(无 Gateway 网关): +- 单模型,direct(无 Gateway 网关): - `OPENCLAW_LIVE_MODELS="openai/gpt-5.4" pnpm test:live src/agents/models.profiles.live.test.ts` - 单模型,Gateway 网关冒烟: @@ -353,19 +315,15 @@ Docker 说明: 说明: - `google/...` 使用 Gemini API(API 密钥)。 -- `google-antigravity/...` 使用 Antigravity OAuth bridge(Cloud Code Assist 风格的智能体端点)。 -- `google-gemini-cli/...` 使用你机器上的本地 Gemini CLI(独立认证 + 工具行为差异)。 -- Gemini API 与 Gemini CLI: - - API:OpenClaw 通过 HTTP 调用 Google 托管的 Gemini API(API 密钥 / profile 认证);这也是大多数用户说“Gemini”时的含义。 - - CLI:OpenClaw 会调用本地 `gemini` 二进制;它有自己的认证方式,而且行为可能不同(流式传输/工具支持/版本偏差)。 +- `google-antigravity/...` 使用 Antigravity OAuth bridge(类似 Cloud Code Assist 风格的智能体端点)。 -## 实时:模型矩阵(我们覆盖什么) +## Live:模型矩阵(我们覆盖什么) -没有固定的“CI 模型列表”(实时测试是按需启用的),但以下是**推荐**在有密钥的开发机器上定期覆盖的模型。 +没有固定的“CI 模型列表”(live 是可选启用的),但以下这些是**推荐**在带密钥的开发机器上定期覆盖的模型。 ### 现代冒烟集(工具调用 + 图像) -这是我们预期应持续保持可用的“常用模型”运行集: +这是我们期望持续可用的“常见模型”运行集: - OpenAI(非 Codex):`openai/gpt-5.4`(可选:`openai/gpt-5.4-mini`) - OpenAI Codex:`openai-codex/gpt-5.4` @@ -388,64 +346,64 @@ Docker 说明: - Z.AI(GLM):`zai/glm-4.7` - MiniMax:`minimax/MiniMax-M2.7` -可选的额外覆盖(最好有): +可选的额外覆盖(有的话更好): - xAI:`xai/grok-4`(或最新可用版本) -- Mistral:`mistral/`…(选择一个你已启用且支持工具的模型) -- Cerebras:`cerebras/`…(如果你有权限) +- Mistral:`mistral/`…(选择一个你已启用、支持 “tools” 的模型) +- Cerebras:`cerebras/`…(如果你有访问权限) - LM Studio:`lmstudio/`…(本地;工具调用取决于 API 模式) -### Vision:图像发送(附件 → 多模态消息) +### Vision:发送图像(附件 → 多模态消息) -在 `OPENCLAW_LIVE_GATEWAY_MODELS` 中至少包含一个支持图像的模型(Claude/Gemini/OpenAI 支持视觉的变体等),以触发图像探针。 +在 `OPENCLAW_LIVE_GATEWAY_MODELS` 中至少包含一个支持图像的模型(Claude/Gemini/OpenAI 的视觉变体等),以触发图像探测。 ### 聚合器 / 替代 Gateway 网关 -如果你已启用密钥,我们也支持通过以下方式测试: +如果你启用了相应密钥,我们也支持通过以下方式测试: -- OpenRouter:`openrouter/...`(数百种模型;使用 `openclaw models scan` 查找支持工具 + 图像的候选) -- OpenCode:Zen 使用 `opencode/...`,Go 使用 `opencode-go/...`(通过 `OPENCODE_API_KEY` / `OPENCODE_ZEN_API_KEY` 认证) +- OpenRouter:`openrouter/...`(数百个模型;使用 `openclaw models scan` 找出支持 tool+image 的候选项) +- OpenCode:`opencode/...` 用于 Zen,`opencode-go/...` 用于 Go(通过 `OPENCODE_API_KEY` / `OPENCODE_ZEN_API_KEY` 认证) -你还可以在实时矩阵中加入更多提供商(如果你有凭证/配置): +如果你有凭证/配置,还可以把更多提供商加入 live 矩阵: -- 内置:`openai`、`openai-codex`、`anthropic`、`google`、`google-vertex`、`google-antigravity`、`google-gemini-cli`、`zai`、`openrouter`、`opencode`、`opencode-go`、`xai`、`groq`、`cerebras`、`mistral`、`github-copilot` -- 通过 `models.providers`(自定义端点):`minimax`(云/API),以及任意兼容 OpenAI/Anthropic 的代理(LM Studio、vLLM、LiteLLM 等) +- 内置:`openai`、`openai-codex`、`anthropic`、`google`、`google-vertex`、`google-antigravity`、`zai`、`openrouter`、`opencode`、`opencode-go`、`xai`、`groq`、`cerebras`、`mistral`、`github-copilot` +- 通过 `models.providers`(自定义端点):`minimax`(云/API),以及任何兼容 OpenAI/Anthropic 的代理(LM Studio、vLLM、LiteLLM 等) -提示:不要试图在文档里硬编码“所有模型”。权威列表始终是你机器上 `discoverModels(...)` 的返回结果 + 可用密钥。 +提示:不要试图在文档里硬编码“所有模型”。权威列表始终是你机器上 `discoverModels(...)` 的返回结果 + 当前可用的密钥。 -## 凭证(切勿提交) +## 凭证(绝不要提交) -实时测试发现凭证的方式与 CLI 相同。实际含义如下: +Live 测试发现凭证的方式与 CLI 相同。实际含义如下: -- 如果 CLI 可用,实时测试通常也应能找到相同密钥。 -- 如果某个实时测试提示“没有凭证”,请按调试 `openclaw models list` / 模型选择的相同方式调试。 +- 如果 CLI 可用,live 测试应该能找到相同的密钥。 +- 如果 live 测试提示“无凭证”,请像调试 `openclaw models list` / 模型选择那样调试。 -- 按智能体划分的认证 profile:`~/.openclaw/agents//agent/auth-profiles.json`(这就是实时测试中 “profile keys” 的含义) +- 每个智能体的认证 profile:`~/.openclaw/agents//agent/auth-profiles.json`(这就是 live 测试中 “profile keys” 的含义) - 配置:`~/.openclaw/openclaw.json`(或 `OPENCLAW_CONFIG_PATH`) -- 旧版状态目录:`~/.openclaw/credentials/`(若存在,会复制到暂存的实时测试 home 中,但它不是主 profile-key 存储) -- 本地实时运行默认会复制当前有效配置、每个智能体的 `auth-profiles.json` 文件、旧版 `credentials/` 以及受支持的外部 CLI 认证目录到临时测试 home;在这份暂存配置中,会去掉 `agents.*.workspace` / `agentDir` 路径覆盖,以保证探针不会落到你的真实主机工作区。 +- 旧版状态目录:`~/.openclaw/credentials/`(若存在,会被复制到暂存的 live home 中,但这不是主 profile-key 存储) +- 本地 live 运行默认会把当前配置、每个智能体的 `auth-profiles.json` 文件、旧版 `credentials/` 以及受支持的外部 CLI 认证目录复制到一个临时测试 home 中;在这个暂存配置里,`agents.*.workspace` / `agentDir` 路径覆盖会被移除,从而保证探测不会触及你真实宿主机工作区。 -如果你想依赖环境变量密钥(例如导出在你的 `~/.profile` 中),请在 `source ~/.profile` 后运行本地测试,或者使用下面的 Docker 运行器(它们可以将 `~/.profile` 挂载进容器)。 +如果你想依赖环境变量密钥(例如导出在你的 `~/.profile` 中),请在本地测试前运行 `source ~/.profile`,或者使用下面的 Docker 运行器(它们可以把 `~/.profile` 挂载进容器)。 -## Deepgram 实时测试(音频转录) +## Deepgram live(音频转写) - 测试:`src/media-understanding/providers/deepgram/audio.live.test.ts` - 启用:`DEEPGRAM_API_KEY=... DEEPGRAM_LIVE_TEST=1 pnpm test:live src/media-understanding/providers/deepgram/audio.live.test.ts` -## BytePlus(国际版) 编码计划实时测试 +## BytePlus 编码计划 live - 测试:`src/agents/byteplus.live.test.ts` - 启用:`BYTEPLUS_API_KEY=... BYTEPLUS_LIVE_TEST=1 pnpm test:live src/agents/byteplus.live.test.ts` - 可选模型覆盖:`BYTEPLUS_CODING_MODEL=ark-code-latest` -## 图像生成实时测试 +## 图像生成 live - 测试:`src/image-generation/runtime.live.test.ts` - 命令:`pnpm test:live src/image-generation/runtime.live.test.ts` - 范围: - 枚举每个已注册的图像生成提供商插件 - 在探测前从你的登录 shell(`~/.profile`)加载缺失的提供商环境变量 - - 默认优先使用实时/环境变量 API 密钥,而不是存储的认证 profile,因此 `auth-profiles.json` 中过期的测试密钥不会掩盖真实 shell 凭证 + - 默认优先使用 live/env API 密钥,而不是存储的 auth profile,因此 `auth-profiles.json` 中过期的测试密钥不会掩盖真实 shell 凭证 - 跳过没有可用认证/profile/模型的提供商 - 通过共享运行时能力运行标准图像生成变体: - `google:flash-generate` @@ -460,133 +418,156 @@ Docker 说明: - `OPENCLAW_LIVE_IMAGE_GENERATION_MODELS="openai/gpt-image-1,google/gemini-3.1-flash-image-preview"` - `OPENCLAW_LIVE_IMAGE_GENERATION_CASES="google:flash-generate,google:pro-edit"` - 可选认证行为: - - `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 强制使用 profile 存储认证,忽略仅环境变量覆盖 + - `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 强制使用 profile 存储认证,并忽略仅环境变量的覆盖 -## Docker 运行器(可选的“在 Linux 中能工作”检查) +## Docker 运行器(可选的“在 Linux 中可运行”检查) -这些 Docker 运行器分成两类: +这些 Docker 运行器分为两类: -- 实时模型运行器:`test:docker:live-models` 和 `test:docker:live-gateway` 仅在仓库 Docker 镜像中运行与其匹配的 profile-key 实时测试文件(`src/agents/models.profiles.live.test.ts` 和 `src/gateway/gateway-models.profiles.live.test.ts`),并挂载你的本地配置目录和工作区(如果挂载了 `~/.profile`,也会读取它)。对应的本地入口点是 `test:live:models-profiles` 和 `test:live:gateway-profiles`。 -- Docker 实时运行器默认使用较小的冒烟上限,这样完整的 Docker 扫描仍然可行: +- Live-model 运行器:`test:docker:live-models` 和 `test:docker:live-gateway` 只会在仓库 Docker 镜像中运行各自匹配的 profile-key live 文件(`src/agents/models.profiles.live.test.ts` 和 `src/gateway/gateway-models.profiles.live.test.ts`),并挂载你的本地配置目录和工作区(如果已挂载,也会读取 `~/.profile`)。相应的本地入口点是 `test:live:models-profiles` 和 `test:live:gateway-profiles`。 +- Docker live 运行器默认有更小的冒烟上限,以便完整的 Docker 扫查仍然实用: `test:docker:live-models` 默认设置 `OPENCLAW_LIVE_MAX_MODELS=12`,并且 `test:docker:live-gateway` 默认设置 `OPENCLAW_LIVE_GATEWAY_SMOKE=1`、 `OPENCLAW_LIVE_GATEWAY_MAX_MODELS=8`、 `OPENCLAW_LIVE_GATEWAY_STEP_TIMEOUT_MS=45000` 和 - `OPENCLAW_LIVE_GATEWAY_MODEL_TIMEOUT_MS=90000`。当你明确想要更大范围的穷举扫描时,再覆盖这些环境变量。 -- `test:docker:all` 会先通过 `test:docker:live-build` 构建一次实时 Docker 镜像,然后在两个实时 Docker 通道中复用它。 -- 容器冒烟运行器:`test:docker:openwebui`、`test:docker:onboard`、`test:docker:gateway-network`、`test:docker:mcp-channels` 和 `test:docker:plugins` 会启动一个或多个真实容器,并验证更高层的集成路径。 + `OPENCLAW_LIVE_GATEWAY_MODEL_TIMEOUT_MS=90000`。当你 + 明确想进行更大范围的穷举扫描时,可覆盖这些环境变量。 +- `test:docker:all` 会先通过 `test:docker:live-build` 构建一次 live Docker 镜像,然后在两个 live Docker 通道中复用它。 +- 容器冒烟运行器:`test:docker:openwebui`、`test:docker:onboard`、`test:docker:gateway-network`、`test:docker:mcp-channels` 和 `test:docker:plugins` 会启动一个或多个真实容器,并验证更高层级的集成路径。 -实时模型 Docker 运行器还会只 bind-mount 所需的 CLI 认证 home(如果运行未缩小范围,则会挂载所有支持的项),然后在运行前将它们复制到容器 home 中,以便外部 CLI OAuth 刷新令牌,而不会修改主机上的认证存储: +Live-model Docker 运行器还会只 bind-mount 所需的 CLI 认证 home(如果运行未缩小范围,则挂载所有受支持的),然后在运行前将它们复制到容器 home 中,这样外部 CLI OAuth 就可以刷新令牌,而不会修改宿主机认证存储: -- Direct model:`pnpm test:docker:live-models`(脚本:`scripts/test-live-models-docker.sh`) +- Direct models:`pnpm test:docker:live-models`(脚本:`scripts/test-live-models-docker.sh`) - ACP 绑定冒烟:`pnpm test:docker:live-acp-bind`(脚本:`scripts/test-live-acp-bind-docker.sh`) -- CLI 后端冒烟:`pnpm test:docker:live-cli-backend`(脚本:`scripts/test-live-cli-backend-docker.sh`) - Gateway 网关 + dev 智能体:`pnpm test:docker:live-gateway`(脚本:`scripts/test-live-gateway-models-docker.sh`) -- Open WebUI 实时冒烟:`pnpm test:docker:openwebui`(脚本:`scripts/e2e/openwebui-docker.sh`) +- Open WebUI live 冒烟:`pnpm test:docker:openwebui`(脚本:`scripts/e2e/openwebui-docker.sh`) - 新手引导向导(TTY,完整脚手架):`pnpm test:docker:onboard`(脚本:`scripts/e2e/onboard-docker.sh`) -- Gateway 网关网络(两个容器,WS 认证 + health):`pnpm test:docker:gateway-network`(脚本:`scripts/e2e/gateway-network-docker.sh`) +- Gateway 网关网络(两个容器,WS 认证 + 健康检查):`pnpm test:docker:gateway-network`(脚本:`scripts/e2e/gateway-network-docker.sh`) - MCP 渠道桥接(带预置数据的 Gateway 网关 + stdio bridge + 原始 Claude notification-frame 冒烟):`pnpm test:docker:mcp-channels`(脚本:`scripts/e2e/mcp-channels-docker.sh`) - 插件(安装冒烟 + `/plugin` 别名 + Claude bundle 重启语义):`pnpm test:docker:plugins`(脚本:`scripts/e2e/plugins-docker.sh`) -实时模型 Docker 运行器还会以只读方式 bind-mount 当前检出,并将其暂存到容器内的临时工作目录中。这样既能保持运行时镜像精简,又能让 Vitest 针对你精确的本地源代码/配置运行。 -它们还会设置 `OPENCLAW_SKIP_CHANNELS=1`,这样 Gateway 网关实时探针就不会在容器内启动真实的 Telegram/Discord 等渠道 worker。 -`test:docker:live-models` 仍然运行 `pnpm test:live`,因此当你需要缩小或排除该 Docker 通道中的 Gateway 网关实时覆盖时,也请一并传入 `OPENCLAW_LIVE_GATEWAY_*`。 -`test:docker:openwebui` 是更高层级的兼容性冒烟:它会启动一个启用了 OpenAI 兼容 HTTP 端点的 OpenClaw Gateway 网关容器,针对该网关再启动一个固定版本的 Open WebUI 容器,通过 Open WebUI 登录,验证 `/api/models` 暴露 `openclaw/default`,然后通过 Open WebUI 的 `/api/chat/completions` 代理发送真实聊天请求。 -第一次运行可能明显更慢,因为 Docker 可能需要拉取 Open WebUI 镜像,而 Open WebUI 也可能需要完成自身的冷启动设置。 -这个测试通道需要可用的实时模型密钥,而 `OPENCLAW_PROFILE_FILE`(默认是 `~/.profile`)是在 Docker 化运行中提供该密钥的主要方式。 -成功运行会打印一小段 JSON 载荷,例如 `{ "ok": true, "model": "openclaw/default", ... }`。 -`test:docker:mcp-channels` 是有意设计成确定性的,不需要真实的 Telegram、Discord 或 iMessage 账号。它会启动一个带预置数据的 Gateway 网关容器,启动第二个容器来运行 `openclaw mcp serve`,然后通过真实 stdio MCP bridge 验证路由会话发现、转录读取、附件元数据、实时事件队列行为、出站发送路由,以及 Claude 风格的渠道 + 权限通知。通知检查会直接检查原始 stdio MCP 帧,因此这个冒烟测试验证的是 bridge 实际发出了什么,而不仅仅是某个特定客户端 SDK 恰好暴露了什么。 +Live-model Docker 运行器还会将当前 checkout 以只读方式 bind-mount, +并将其暂存到容器内的一个临时工作目录中。这样既能保持运行时 +镜像精简,又仍然能针对你精确的本地源码/配置运行 Vitest。 +它们还会设置 `OPENCLAW_SKIP_CHANNELS=1`,这样 Gateway 网关 live 探测就不会在容器内 +启动真实的 Telegram/Discord/等渠道 worker。 +`test:docker:live-models` 仍然会运行 `pnpm test:live`,因此当你需要缩小范围或排除该 Docker 通道中的 +Gateway 网关 live 覆盖时,也请同时传入 +`OPENCLAW_LIVE_GATEWAY_*`。 +`test:docker:openwebui` 是更高层级的兼容性冒烟:它会启动一个 +启用了 OpenAI 兼容 HTTP 端点的 OpenClaw Gateway 网关容器, +再针对该 Gateway 网关启动一个固定版本的 Open WebUI 容器,通过 +Open WebUI 完成登录,验证 `/api/models` 会暴露 `openclaw/default`,然后通过 +Open WebUI 的 `/api/chat/completions` 代理发送一条真实聊天请求。 +第一次运行可能会明显更慢,因为 Docker 可能需要拉取 +Open WebUI 镜像,而 Open WebUI 也可能需要完成自己的冷启动设置。 +这个通道需要可用的 live 模型密钥,而 `OPENCLAW_PROFILE_FILE` +(默认是 `~/.profile`)是在 Docker 化运行中提供该密钥的主要方式。 +成功运行会打印一小段 JSON 负载,例如 `{ "ok": true, "model": +"openclaw/default", ... }`。 +`test:docker:mcp-channels` 是有意设计成确定性的,不需要 +真实的 Telegram、Discord 或 iMessage 账号。它会启动一个带预置数据的 Gateway 网关 +容器,再启动第二个容器来运行 `openclaw mcp serve`,然后 +验证路由后的会话发现、transcript 读取、附件元数据、 +实时事件队列行为、出站发送路由,以及 Claude 风格的渠道 + +权限通知在真实 stdio MCP bridge 上的表现。通知检查 +会直接检查原始 stdio MCP frame,因此这个冒烟测试验证的是 bridge +实际发出的内容,而不仅仅是某个特定客户端 SDK 恰好暴露出来的内容。 手动 ACP 自然语言线程冒烟(非 CI): - `bun scripts/dev/discord-acp-plain-language-smoke.ts --channel ...` -- 请为回归/调试工作流保留此脚本。它未来可能还会再次用于 ACP 线程路由验证,因此不要删除。 +- 保留此脚本用于回归/调试工作流。它未来仍可能用于 ACP 线程路由验证,因此不要删除它。 常用环境变量: - `OPENCLAW_CONFIG_DIR=...`(默认:`~/.openclaw`)挂载到 `/home/node/.openclaw` - `OPENCLAW_WORKSPACE_DIR=...`(默认:`~/.openclaw/workspace`)挂载到 `/home/node/.openclaw/workspace` - `OPENCLAW_PROFILE_FILE=...`(默认:`~/.profile`)挂载到 `/home/node/.profile`,并在运行测试前读取 -- `OPENCLAW_DOCKER_CLI_TOOLS_DIR=...`(默认:`~/.cache/openclaw/docker-cli-tools`)挂载到 `/home/node/.npm-global`,用于 Docker 内缓存 CLI 安装 +- `OPENCLAW_DOCKER_CLI_TOOLS_DIR=...`(默认:`~/.cache/openclaw/docker-cli-tools`)挂载到 `/home/node/.npm-global`,用于缓存 Docker 内部的 CLI 安装 - `$HOME` 下的外部 CLI 认证目录/文件会以只读方式挂载到 `/host-auth...` 下,然后在测试开始前复制到 `/home/node/...` - 默认目录:`.codex`、`.minimax` - 默认文件:`.claude.json`、`~/.claude/.credentials.json`、`~/.claude/settings.json`、`~/.claude/settings.local.json` - - 缩小范围的提供商运行仅挂载由 `OPENCLAW_LIVE_PROVIDERS` / `OPENCLAW_LIVE_GATEWAY_PROVIDERS` 推断出的所需目录/文件 - - 可通过 `OPENCLAW_DOCKER_AUTH_DIRS=all`、`OPENCLAW_DOCKER_AUTH_DIRS=none` 或逗号列表(如 `OPENCLAW_DOCKER_AUTH_DIRS=.claude,.codex`)手动覆盖 + - 已缩小提供商范围的运行只会挂载从 `OPENCLAW_LIVE_PROVIDERS` / `OPENCLAW_LIVE_GATEWAY_PROVIDERS` 推断出的必需目录/文件 + - 可通过 `OPENCLAW_DOCKER_AUTH_DIRS=all`、`OPENCLAW_DOCKER_AUTH_DIRS=none` 或类似 `OPENCLAW_DOCKER_AUTH_DIRS=.claude,.codex` 的逗号列表手动覆盖 - `OPENCLAW_LIVE_GATEWAY_MODELS=...` / `OPENCLAW_LIVE_MODELS=...` 用于缩小运行范围 -- `OPENCLAW_LIVE_GATEWAY_PROVIDERS=...` / `OPENCLAW_LIVE_PROVIDERS=...` 用于过滤容器内提供商 -- `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 确保凭证来自 profile 存储(而非环境变量) -- `OPENCLAW_OPENWEBUI_MODEL=...` 选择在 Open WebUI 冒烟中由 Gateway 网关暴露的模型 -- `OPENCLAW_OPENWEBUI_PROMPT=...` 覆盖 Open WebUI 冒烟中用于 nonce 检查的提示 +- `OPENCLAW_LIVE_GATEWAY_PROVIDERS=...` / `OPENCLAW_LIVE_PROVIDERS=...` 用于在容器内筛选提供商 +- `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 确保凭证来自 profile 存储(而不是环境变量) +- `OPENCLAW_OPENWEBUI_MODEL=...` 选择 Gateway 网关为 Open WebUI 冒烟暴露的模型 +- `OPENCLAW_OPENWEBUI_PROMPT=...` 覆盖 Open WebUI 冒烟使用的 nonce 检查提示词 - `OPENWEBUI_IMAGE=...` 覆盖固定的 Open WebUI 镜像标签 ## 文档完整性检查 编辑文档后运行文档检查:`pnpm check:docs`。 -如果还需要完整的 Mintlify 锚点校验(包括页内标题检查),运行:`pnpm docs:check-links:anchors`。 +当你还需要进行页内标题检查时,运行完整的 Mintlify anchor 验证:`pnpm docs:check-links:anchors`。 ## 离线回归(CI 安全) -这些是“不依赖真实提供商”的“真实流水线”回归: +这些是在没有真实提供商的情况下进行的“真实流水线”回归测试: -- Gateway 网关工具调用(模拟 OpenAI,真实 Gateway 网关 + 智能体循环):`src/gateway/gateway.test.ts`(用例:“runs a mock OpenAI tool call end-to-end via gateway agent loop”) -- Gateway 网关向导(WS `wizard.start`/`wizard.next`,强制写入配置 + auth):`src/gateway/gateway.test.ts`(用例:“runs wizard over ws and writes auth token config”) +- Gateway 网关工具调用(mock OpenAI,真实 Gateway 网关 + 智能体循环):`src/gateway/gateway.test.ts`(用例:“runs a mock OpenAI tool call end-to-end via gateway agent loop”) +- Gateway 网关向导(WS `wizard.start`/`wizard.next`,强制写入配置 + 认证):`src/gateway/gateway.test.ts`(用例:“runs wizard over ws and writes auth token config”) ## 智能体可靠性评估(Skills) -我们已经有一些 CI 安全的测试,它们的行为类似“智能体可靠性评估”: +我们已经有一些 CI 安全的测试,行为上类似“智能体可靠性评估”: -- 通过真实 Gateway 网关 + 智能体循环执行模拟工具调用(`src/gateway/gateway.test.ts`)。 -- 验证会话接线和配置效果的端到端向导流程(`src/gateway/gateway.test.ts`)。 +- 通过真实的 Gateway 网关 + 智能体循环进行 mock 工具调用(`src/gateway/gateway.test.ts`)。 +- 验证会话接线与配置效果的端到端向导流程(`src/gateway/gateway.test.ts`)。 -对于 Skills(参见 [Skills](/zh-CN/tools/skills))目前仍缺少的是: +对于 Skills(见 [Skills](/zh-CN/tools/skills)),目前仍缺少: -- **决策能力:** 当提示中列出 Skills 时,智能体是否会选择正确的 Skill(或避免选择无关项)? -- **合规性:** 智能体是否会在使用前读取 `SKILL.md`,并遵循所需步骤/参数? -- **工作流契约:** 断言工具顺序、会话历史延续和沙箱边界的多轮场景。 +- **决策能力:** 当提示词中列出了 skill 时,智能体是否会选择正确的 skill(或避开无关的 skill)? +- **合规性:** 智能体在使用前是否会读取 `SKILL.md`,并遵循要求的步骤/参数? +- **工作流契约:** 断言工具顺序、会话历史延续以及沙箱边界的多轮场景。 未来的评估应优先保持确定性: -- 一个使用模拟提供商的场景运行器,用于断言工具调用 + 顺序、Skill 文件读取和会话接线。 -- 一小组聚焦 Skill 的场景(使用 vs 避免、门控、提示注入)。 -- 只有在 CI 安全套件到位之后,才加入可选的实时评估(按需启用、由环境变量控制)。 +- 一个使用 mock 提供商的场景运行器,用于断言工具调用 + 顺序、skill 文件读取以及会话接线。 +- 一小组聚焦 skill 的场景(应使用 vs 应避免、门控、提示注入)。 +- 可选的 live 评估(选择性启用、由环境变量控制)应在 CI 安全套件就位后再添加。 -## 契约测试(插件和渠道形状) +## Contract 测试(插件和渠道形状) -契约测试会验证每个已注册插件和渠道都符合其接口契约。它们会遍历所有已发现的插件,并运行一套关于结构和行为的断言。默认的 `pnpm test` 单元测试通道会有意跳过这些共享接缝和冒烟文件;当你修改共享渠道或提供商表面时,请显式运行契约命令。 +Contract 测试用于验证每个已注册插件和渠道都符合其 +接口契约。它们会遍历所有已发现插件,并运行一组 +形状和行为断言。默认的 `pnpm test` unit 通道会有意 +跳过这些共享 seam 和 smoke 文件;当你修改共享渠道或提供商接口时, +请显式运行这些 contract 命令。 ### 命令 -- 所有契约:`pnpm test:contracts` -- 仅渠道契约:`pnpm test:contracts:channels` -- 仅提供商契约:`pnpm test:contracts:plugins` +- 所有 contract:`pnpm test:contracts` +- 仅渠道 contract:`pnpm test:contracts:channels` +- 仅提供商 contract:`pnpm test:contracts:plugins` -### 渠道契约 +### 渠道 contract 位于 `src/channels/plugins/contracts/*.contract.test.ts`: - **plugin** - 基本插件形状(id、name、capabilities) - **setup** - 设置向导契约 - **session-binding** - 会话绑定行为 -- **outbound-payload** - 消息载荷结构 +- **outbound-payload** - 消息负载结构 - **inbound** - 入站消息处理 -- **actions** - 渠道动作处理器 +- **actions** - 渠道操作处理器 - **threading** - 线程 ID 处理 - **directory** - 目录/成员列表 API - **group-policy** - 群组策略强制执行 -### 提供商状态契约 +### 提供商状态 contract 位于 `src/plugins/contracts/*.contract.test.ts`。 -- **status** - 渠道状态探针 +- **status** - 渠道状态探测 - **registry** - 插件注册表形状 -### 提供商契约 +### 提供商 contract 位于 `src/plugins/contracts/*.contract.test.ts`: -- **auth** - 认证流程契约 +- **auth** - 认证流契约 - **auth-choice** - 认证选项/选择 - **catalog** - 模型目录 API - **discovery** - 插件发现 @@ -601,17 +582,17 @@ Docker 说明: - 添加或修改渠道或提供商插件之后 - 重构插件注册或发现逻辑之后 -契约测试会在 CI 中运行,不需要真实 API 密钥。 +Contract 测试会在 CI 中运行,并且不需要真实 API 密钥。 -## 添加回归测试(指南) +## 添加回归测试(指导) -当你修复一个在实时测试中发现的提供商/模型问题时: +当你修复了一个在 live 中发现的提供商/模型问题时: -- 如果可能,添加一个 CI 安全的回归测试(模拟/存根提供商,或捕获精确的请求形状转换) -- 如果问题本质上只能在实时环境中出现(速率限制、认证策略),请让实时测试保持范围窄,并通过环境变量按需启用 -- 优先瞄准能捕获该缺陷的最小层级: - - 提供商请求转换/回放缺陷 → direct models test - - Gateway 网关会话/历史/工具流水线缺陷 → gateway 实时冒烟或 CI 安全的 gateway mock 测试 -- SecretRef 遍历保护规则: +- 如果可能,添加一个 CI 安全的回归测试(mock/stub 提供商,或者捕获精确的请求形状转换) +- 如果它本质上只能在 live 中复现(限流、认证策略),请保持 live 测试足够窄,并通过环境变量选择性启用 +- 优先定位到能捕获该 Bug 的最小层: + - 提供商请求转换/重放 Bug → direct models 测试 + - Gateway 网关会话/历史/工具流水线 Bug → Gateway 网关 live 冒烟或 CI 安全的 Gateway 网关 mock 测试 +- SecretRef 遍历防护: - `src/secrets/exec-secret-ref-id-parity.test.ts` 会从注册表元数据(`listSecretTargetRegistryEntries()`)中为每个 SecretRef 类派生一个采样目标,然后断言遍历段 exec id 会被拒绝。 - - 如果你在 `src/secrets/target-registry-data.ts` 中添加了新的 `includeInPlan` SecretRef 目标家族,请更新该测试中的 `classifyTargetClass`。该测试会有意在遇到未分类的目标 id 时失败,以防新的类别被悄悄跳过。 + - 如果你在 `src/secrets/target-registry-data.ts` 中新增了一个 `includeInPlan` SecretRef 目标族,请更新该测试中的 `classifyTargetClass`。该测试会在出现未分类的目标 id 时故意失败,以防新的类别被悄悄跳过。 diff --git a/docs/zh-CN/plugins/architecture.md b/docs/zh-CN/plugins/architecture.md index 4be1f706b..09951872f 100644 --- a/docs/zh-CN/plugins/architecture.md +++ b/docs/zh-CN/plugins/architecture.md @@ -1,42 +1,41 @@ --- read_when: - - 构建或调试原生 OpenClaw 插件 - - 了解插件能力模型或所有权边界 - - 处理插件加载流水线或注册表 - - 实现提供商运行时钩子或渠道插件 + - 构建或调试原生 OpenClaw 插件时 + - 了解插件能力模型或归属边界时 + - 处理插件加载流水线或注册表时 + - 实现提供商运行时钩子或渠道插件时 sidebarTitle: Internals -summary: 插件内部机制:能力模型、所有权、契约、加载流水线和运行时辅助工具 -title: 插件内部机制 +summary: Plugin 内部机制:能力模型、归属关系、契约、加载流水线和运行时辅助函数 +title: Plugin 内部机制 x-i18n: - generated_at: "2026-04-05T10:07:50Z" + generated_at: "2026-04-05T18:16:45Z" model: gpt-5.4 provider: openai - source_hash: 1bc9d7261c3c7878d37140be77f210dd262d6c3edee2491ea534aa599e2800c0 + source_hash: 70424e2745e6e289aa2e7ff899d33bea4b04f5c18bd3f73de38287f788bd939b source_path: plugins/architecture.md workflow: 15 --- -# 插件内部机制 +# Plugin 内部机制 这是**深度架构参考**。如需实用指南,请参阅: - - [安装和使用插件](/zh-CN/tools/plugin) — 用户指南 + - [安装并使用插件](/zh-CN/tools/plugin) — 用户指南 - [入门指南](/zh-CN/plugins/building-plugins) — 第一个插件教程 - [渠道插件](/zh-CN/plugins/sdk-channel-plugins) — 构建一个消息渠道 - [提供商插件](/zh-CN/plugins/sdk-provider-plugins) — 构建一个模型提供商 - [SDK 概览](/zh-CN/plugins/sdk-overview) — 导入映射与注册 API -本页介绍 OpenClaw 插件系统的内部架构。 +本页面介绍 OpenClaw 插件系统的内部架构。 ## 公共能力模型 能力是 OpenClaw 内部公开的**原生插件**模型。每个原生 OpenClaw 插件都会针对一种或多种能力类型进行注册: -| 能力 | 注册方式 | 示例插件 | +| 能力 | 注册方法 | 示例插件 | | ---------------------- | ------------------------------------------------ | ------------------------------------ | | 文本推理 | `api.registerProvider(...)` | `openai`, `anthropic` | -| CLI 推理后端 | `api.registerCliBackend(...)` | `openai`, `anthropic` | | 语音 | `api.registerSpeechProvider(...)` | `elevenlabs`, `microsoft` | | 实时转录 | `api.registerRealtimeTranscriptionProvider(...)` | `openai` | | 实时语音 | `api.registerRealtimeVoiceProvider(...)` | `openai` | @@ -47,99 +46,100 @@ x-i18n: | Web 搜索 | `api.registerWebSearchProvider(...)` | `google` | | 渠道 / 消息 | `api.registerChannel(...)` | `msteams`, `matrix` | -如果某个插件注册了零个能力,但提供了 hooks、tools 或 services,那么它就是一个**仅 legacy hook** 插件。这种模式仍然被完全支持。 +如果某个插件注册了零个能力,但提供了 hooks、工具或服务,那么它就是一个**仅 legacy hook** 插件。该模式仍然得到完全支持。 -### 外部兼容性立场 +### 对外兼容性立场 -能力模型已经在 core 中落地,并且今天已被内置/原生插件使用,但外部插件兼容性仍需要比“它被导出了,因此它被冻结了”更严格的标准。 +能力模型已经在 core 中落地,并且如今已被内置/原生插件使用,但外部插件的兼容性仍需要比“它已导出,因此它已冻结”更严格的标准。 当前指导原则: -- **现有外部插件:**保持基于 hook 的集成继续可用;将其视为兼容性的基线 -- **新的内置/原生插件:**优先选择显式能力注册,而不是针对供应商的特定内部访问或新的仅 hook 设计 -- **采用能力注册的外部插件:**允许,但应将特定于能力的辅助接口视为仍在演进中,除非文档明确将某个契约标记为稳定 +- **现有外部插件:** 保持基于 hook 的集成可用;将其视为兼容性基线 +- **新的内置/原生插件:** 优先使用显式能力注册,而不是面向特定厂商的深度接入或新的仅 hook 设计 +- **采用能力注册的外部插件:** 允许,但除非文档明确将某个契约标记为稳定,否则应将能力专用辅助接口视为仍在演进 -实际规则: +实践规则: -- 能力注册 API 是预期方向 -- 在过渡期间,legacy hook 仍然是外部插件最安全、最不容易破坏的路径 -- 并非所有导出的 helper 子路径都同等稳定;优先使用范围狭窄且有文档说明的契约,而不是偶然导出的 helper +- 能力注册 API 是预期的发展方向 +- 在过渡期间,legacy hook 仍然是对外部插件最安全、最不易破坏的路径 +- 并非所有导出的辅助子路径都同等稳定;优先使用有文档说明的狭义契约,而不是偶然暴露的辅助导出 -### 插件形态 +### Plugin 形态 -OpenClaw 会根据每个已加载插件的实际注册行为(而不仅仅是静态元数据)将其分类为某种形态: +OpenClaw 会根据每个已加载插件的实际注册行为来判定其形态(而不仅仅是静态元数据): - **plain-capability** -- 恰好注册一种能力类型(例如仅提供商插件 `mistral`) -- **hybrid-capability** -- 注册多种能力类型(例如 `openai` 拥有文本推理、语音、媒体理解和图像生成) -- **hook-only** -- 仅注册 hooks(类型化或自定义),不注册能力、tools、commands 或 services -- **non-capability** -- 注册 tools、commands、services 或 routes,但不注册能力 +- **hybrid-capability** -- 注册多种能力类型(例如 `openai` 同时拥有文本推理、语音、媒体理解和图像生成) +- **hook-only** -- 只注册 hooks(类型化或自定义),不注册能力、工具、命令或服务 +- **non-capability** -- 注册工具、命令、服务或路由,但不注册任何能力 -使用 `openclaw plugins inspect ` 可以查看某个插件的形态和能力拆分。详情请参阅 [CLI 参考](/cli/plugins#inspect)。 +使用 `openclaw plugins inspect ` 可查看插件的形态及能力拆分详情。详见 [CLI 参考](/cli/plugins#inspect)。 ### Legacy hooks -`before_agent_start` hook 仍然作为仅 hook 插件的兼容路径被支持。现实中的 legacy 插件仍然依赖它。 +`before_agent_start` hook 仍然作为仅 hook 插件的兼容路径受到支持。现实中的 legacy 插件仍然依赖它。 -方向: +方向如下: - 保持其可用 -- 在文档中将其标记为 legacy -- 在模型/提供商覆盖场景中优先使用 `before_model_resolve` -- 在 prompt 变更场景中优先使用 `before_prompt_build` -- 仅在真实使用量下降且 fixture 覆盖证明迁移安全之后再移除 +- 将其记录为 legacy +- 对于模型/提供商覆盖工作,优先使用 `before_model_resolve` +- 对于提示词变更工作,优先使用 `before_prompt_build` +- 仅在真实使用量下降且 fixture 覆盖验证迁移安全之后再移除 ### 兼容性信号 -当你运行 `openclaw doctor` 或 `openclaw plugins inspect ` 时,你可能会看到以下标签之一: +当你运行 `openclaw doctor` 或 `openclaw plugins inspect ` 时,可能会看到以下标签之一: | 信号 | 含义 | | -------------------------- | ------------------------------------------------------------ | -| **配置有效** | 配置解析正常,插件可解析 | -| **兼容性提示** | 插件使用受支持但较旧的模式(例如 `hook-only`) | -| **legacy 警告** | 插件使用了 `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 的插件系统有四个层级: +OpenClaw 的插件系统分为四层: -1. **Manifest + 设备发现** - OpenClaw 从已配置路径、工作区根目录、全局扩展根目录以及内置扩展中查找候选插件。设备发现会先读取原生 `openclaw.plugin.json` manifests 以及受支持的 bundle manifests。 -2. **启用 + 验证** - Core 决定某个已发现插件是启用、禁用、阻止,还是被选中用于某个独占插槽,例如 memory。 +1. **清单 + 发现** + OpenClaw 会从已配置路径、工作区根目录、全局扩展根目录和内置扩展中查找候选插件。发现阶段会优先读取原生 `openclaw.plugin.json` 清单以及受支持 bundle 的清单。 +2. **启用 + 校验** + Core 决定已发现插件是启用、禁用、阻止,还是被选入某个独占槽位(例如 memory)。 3. **运行时加载** - 原生 OpenClaw 插件通过 jiti 在进程内加载,并将能力注册到中心注册表中。兼容 bundle 会被规范化为注册表记录,而无需导入运行时代码。 + 原生 OpenClaw 插件通过 jiti 在进程内加载,并将能力注册到中央注册表中。兼容 bundle 会被标准化为注册表记录,而无需导入运行时代码。 4. **接口消费** - OpenClaw 的其余部分会读取注册表,以暴露 tools、channels、provider 设置、hooks、HTTP routes、CLI commands 和 services。 + OpenClaw 的其他部分读取该注册表,以暴露工具、渠道、提供商设置、hooks、HTTP 路由、CLI 命令和服务。 -对于插件 CLI,根命令发现明确分为两个阶段: +对于插件 CLI,根命令发现被拆分为两个阶段: -- 解析时元数据来自 `registerCli(..., { descriptors: [...] })` -- 真正的插件 CLI 模块可以保持惰性,只在首次调用时注册 +- 解析阶段元数据来自 `registerCli(..., { descriptors: [...] })` +- 真正的插件 CLI 模块可以保持惰性,并在首次调用时再注册 -这使插件拥有的 CLI 代码保留在插件内部,同时仍让 OpenClaw 能够在解析前预留根命令名称。 +这样可以让插件自有的 CLI 代码保留在插件内部,同时仍让 OpenClaw 在解析前预留根命令名称。 -重要设计边界: +重要的设计边界: -- 设备发现 + 配置验证应基于 **manifest/schema 元数据** 工作,而无需执行插件代码 +- 发现 + 配置校验应基于**清单/模式元数据**完成,而无需执行插件代码 - 原生运行时行为来自插件模块的 `register(api)` 路径 -这种拆分让 OpenClaw 能够在完整运行时尚未激活前,就验证配置、解释缺失/禁用的插件,并构建 UI/schema 提示。 +这种拆分使 OpenClaw 能在完整运行时尚未激活前,就完成配置校验、解释缺失/禁用的插件,并构建 UI/模式提示。 ### 渠道插件与共享消息工具 -对于常规聊天操作,渠道插件不需要单独注册发送/编辑/回应工具。OpenClaw 在 core 中保留一个共享的 `message` 工具,而渠道插件拥有其背后的渠道特定发现和执行逻辑。 +渠道插件在普通聊天操作中,无需分别注册独立的发送/编辑/反应工具。OpenClaw 在 core 中保留了一个共享的 `message` 工具,而渠道插件负责其背后的渠道专属发现与执行。 当前边界如下: -- core 拥有共享 `message` 工具宿主、prompt 接线、session/thread 账务以及执行分发 -- 渠道插件拥有作用域内操作发现、能力发现以及任何渠道特定的 schema 片段 -- 渠道插件拥有提供商特定的 session 会话语法,例如会话 id 如何编码 thread id,或如何从父会话继承 -- 渠道插件通过其 action adapter 执行最终操作 +- core 拥有共享 `message` 工具宿主、提示词接线、会话/线程记录和执行分发 +- 渠道插件拥有作用域动作发现、能力发现以及任何渠道专属模式片段 +- 渠道插件拥有提供商专属的会话对话语法,例如对话 id 如何编码线程 id,或如何从父对话继承 +- 渠道插件通过其动作适配器执行最终动作 -对于渠道插件,SDK 接口是 `ChannelMessageActionAdapter.describeMessageTool(...)`。这个统一的发现调用让插件能够一起返回其可见操作、能力和 schema 贡献,从而避免这些部分彼此漂移。 +对于渠道插件,SDK 接口是 +`ChannelMessageActionAdapter.describeMessageTool(...)`。这个统一的发现调用允许插件一起返回其可见动作、能力和模式贡献,从而避免这些部分发生漂移。 Core 会将运行时作用域传入该发现步骤。重要字段包括: @@ -150,86 +150,87 @@ Core 会将运行时作用域传入该发现步骤。重要字段包括: - `sessionKey` - `sessionId` - `agentId` -- 受信任入站的 `requesterSenderId` +- 受信任的入站 `requesterSenderId` -这对上下文敏感型插件很重要。某个渠道可以根据活动账户、当前 room/thread/message 或受信任的请求方身份来隐藏或暴露消息操作,而无需在 core 的 `message` 工具中硬编码渠道特定分支。 +这对于上下文敏感型插件很重要。渠道可以根据当前活跃账号、当前房间/线程/消息,或受信任的请求者身份来隐藏或暴露消息动作,而无需在 core 的 `message` 工具中硬编码渠道专属分支。 -这也是为什么嵌入式 runner 路由更改仍然属于插件工作:runner 负责将当前 chat/session 身份转发到插件发现边界,以便共享 `message` 工具在当前轮次中暴露正确的、由渠道拥有的接口。 +这也是为什么嵌入式运行器路由变更仍属于插件工作:运行器负责将当前聊天/会话身份转发到插件发现边界,以便共享的 `message` 工具为当前轮次暴露正确的渠道自有接口。 -对于渠道拥有的执行 helper,内置插件应将执行运行时保留在它们自己的扩展模块中。Core 不再拥有位于 `src/agents/tools` 下的 Discord、Slack、Telegram 或 WhatsApp 消息操作运行时。我们不会发布单独的 `plugin-sdk/*-action-runtime` 子路径,内置插件应直接从各自扩展拥有的模块中导入本地运行时代码。 +对于渠道自有的执行辅助函数,内置插件应将执行运行时保留在其自身扩展模块内。Core 不再拥有位于 `src/agents/tools` 下的 Discord、Slack、Telegram 或 WhatsApp 消息动作运行时。我们不会发布单独的 `plugin-sdk/*-action-runtime` 子路径,内置插件应直接从其扩展自有模块导入本地运行时代码。 -同样的边界也适用于一般情况下以提供商命名的 SDK 接缝:core 不应导入面向 Slack、Discord、Signal、WhatsApp 或类似扩展的渠道特定便利 barrel。如果 core 需要某种行为,要么消费该内置插件自己的 `api.ts` / `runtime-api.ts` barrel,要么将该需求提升为共享 SDK 中的狭窄通用能力。 +同样的边界也适用于一般意义上的提供商命名 SDK 接缝:core 不应导入面向 Slack、Discord、Signal、WhatsApp 或类似扩展的渠道专用便捷 barrel。如果 core 需要某种行为,要么消费内置插件自身的 `api.ts` / `runtime-api.ts` barrel,要么将该需求提升为共享 SDK 中一个狭义通用能力。 -对于投票,具体有两条执行路径: +对于投票,当前有两条执行路径: - `outbound.sendPoll` 是适用于符合通用投票模型的渠道的共享基线 -- `actions.handleAction("poll")` 是用于渠道特定投票语义或额外投票参数的首选路径 +- `actions.handleAction("poll")` 是处理渠道专属投票语义或额外投票参数的首选路径 -现在,core 会先让插件投票分发尝试处理该操作,只有在其拒绝后,才会执行共享投票解析。因此,由插件拥有的投票处理器可以接受渠道特定的投票字段,而不会先被通用投票解析器拦住。 +现在,只有在插件投票分发拒绝该动作之后,core 才会延迟执行共享投票解析,因此插件自有的投票处理器可以接受渠道专属投票字段,而不会先被通用投票解析器拦住。 -完整启动顺序请参阅 [加载流水线](#load-pipeline)。 +完整启动顺序请参阅[加载流水线](#load-pipeline)。 -## 能力所有权模型 +## 能力归属模型 -OpenClaw 将原生插件视为**公司**或**功能**的所有权边界,而不是一堆无关集成的杂物袋。 +OpenClaw 将一个原生插件视为某个**公司**或某项**功能**的归属边界,而不是各种无关集成的杂物袋。 这意味着: -- 公司插件通常应拥有该公司的所有 OpenClaw 对外接口 -- 功能插件通常应拥有它引入的完整功能接口 -- channels 应消费共享 core 能力,而不是临时重新实现提供商行为 +- 一个公司插件通常应拥有该公司面向 OpenClaw 的所有接口 +- 一个功能插件通常应拥有它引入的完整功能接口 +- 渠道应消费共享的 core 能力,而不是临时重写提供商行为 -示例: +例如: -- 内置 `openai` 插件拥有 OpenAI 模型提供商行为,以及 OpenAI 语音 + 实时语音 + 媒体理解 + 图像生成行为 +- 内置 `openai` 插件拥有 OpenAI 模型提供商行为,以及 OpenAI 的语音 + 实时语音 + 媒体理解 + 图像生成行为 - 内置 `elevenlabs` 插件拥有 ElevenLabs 语音行为 - 内置 `microsoft` 插件拥有 Microsoft 语音行为 -- 内置 `google` 插件拥有 Google 模型提供商行为,以及 Google 媒体理解 + 图像生成 + Web 搜索行为 +- 内置 `google` 插件拥有 Google 模型提供商行为,以及 Google 的媒体理解 + 图像生成 + Web 搜索行为 - 内置 `firecrawl` 插件拥有 Firecrawl Web 抓取行为 -- 内置 `minimax`、`mistral`、`moonshot` 和 `zai` 插件拥有它们的媒体理解后端 -- `voice-call` 插件是一个功能插件:它拥有通话传输、tools、CLI、routes 和 Twilio 媒体流桥接,但它消费共享的 speech、实时转录和实时语音能力,而不是直接导入供应商插件 +- 内置 `minimax`、`mistral`、`moonshot` 和 `zai` 插件拥有其媒体理解后端 +- 内置 `qwen` 插件拥有 Qwen 文本提供商行为,以及媒体理解和视频生成行为 +- `voice-call` 插件是一个功能插件:它拥有通话传输、工具、CLI、路由和 Twilio 媒体流桥接,但它消费共享的语音以及实时转录和实时语音能力,而不是直接导入厂商插件 预期的最终状态是: -- OpenAI 位于同一个插件中,即使它跨越文本模型、语音、图像和未来的视频 -- 另一个供应商也可以对自己的功能范围做同样的事情 -- channels 不关心哪个供应商插件拥有这个 provider;它们消费的是 core 暴露的共享能力契约 +- OpenAI 即使同时涵盖文本模型、语音、图像以及未来的视频,也应位于同一个插件中 +- 其他厂商也可以对自己的接口范围采取同样方式 +- 渠道不关心哪个厂商插件拥有该提供商;它们消费的是 core 暴露的共享能力契约 这是关键区别: -- **plugin** = 所有权边界 -- **capability** = 多个插件都可以实现或消费的 core 契约 +- **plugin** = 归属边界 +- **capability** = 多个插件都可实现或消费的 core 契约 -因此,如果 OpenClaw 添加了一个新领域,比如视频,第一个问题不应该是“哪个 provider 应该硬编码视频处理?”第一个问题应该是“core 的视频能力契约是什么?”一旦该契约存在,供应商插件就可以针对它进行注册,而渠道/功能插件可以消费它。 +因此,如果 OpenClaw 新增了视频这样的领域,第一个问题不应是“哪个提供商应该硬编码视频处理?”而应是“core 的视频能力契约是什么?”一旦该契约存在,厂商插件就可以针对它进行注册,而渠道/功能插件也可以消费它。 -如果该能力还不存在,正确的做法通常是: +如果该能力还不存在,通常正确的做法是: 1. 在 core 中定义缺失的能力 2. 通过插件 API/运行时以类型化方式暴露它 -3. 让 channels/功能对接到该能力 -4. 让供应商插件注册实现 +3. 让渠道/功能围绕该能力接线 +4. 让厂商插件注册实现 -这样可以在保持所有权明确的同时,避免 core 行为依赖单一供应商或一次性的插件专用代码路径。 +这样可以保持归属明确,同时避免 core 行为依赖于某一个厂商或一次性的插件专用代码路径。 ### 能力分层 -在决定代码归属位置时,可以使用以下思维模型: +在决定代码归属位置时,可使用如下心智模型: - **core 能力层**:共享编排、策略、回退、配置合并规则、交付语义和类型化契约 -- **供应商插件层**:供应商特定 API、auth、模型目录、语音合成、图像生成、未来视频后端、使用量端点 -- **渠道/功能插件层**:Slack/Discord/voice-call 等集成,它们消费 core 能力并将其呈现在某个接口上 +- **厂商插件层**:厂商专属 API、认证、模型目录、语音合成、图像生成、未来视频后端、用量端点 +- **渠道/功能插件层**:Slack/Discord/voice-call 等集成,消费 core 能力并将其呈现在某个界面上 -例如,TTS 遵循这种形态: +例如,TTS 遵循如下结构: -- core 拥有回复时 TTS 策略、回退顺序、偏好和渠道投递 +- core 拥有回复阶段 TTS 策略、回退顺序、偏好和渠道交付 - `openai`、`elevenlabs` 和 `microsoft` 拥有合成实现 -- `voice-call` 消费电话 TTS 运行时 helper +- `voice-call` 消费电话 TTS 运行时辅助函数 -未来能力也应优先遵循同样模式。 +未来的能力也应优先采用相同模式。 ### 多能力公司插件示例 -从外部看,一个公司插件应该感觉是内聚的。如果 OpenClaw 具备模型、语音、实时转录、实时语音、媒体理解、图像生成、视频生成、Web 抓取和 Web 搜索这些共享契约,那么某个供应商就可以在一个地方拥有自己的所有接口: +一个公司插件在外部看起来应当是连贯的。如果 OpenClaw 对模型、语音、实时转录、实时语音、媒体理解、图像生成、视频生成、Web 抓取和 Web 搜索都有共享契约,那么一个厂商就可以在一个地方拥有其所有接口: ```ts import type { OpenClawPluginDefinition } from "openclaw/plugin-sdk/plugin-entry"; @@ -244,12 +245,12 @@ const plugin: OpenClawPluginDefinition = { register(api) { api.registerProvider({ id: "exampleai", - // auth/model catalog/runtime hooks + // 认证/模型目录/运行时钩子 }); api.registerSpeechProvider({ id: "exampleai", - // vendor speech config — implement the SpeechProviderPlugin interface directly + // 厂商语音配置——直接实现 SpeechProviderPlugin 接口 }); api.registerMediaUnderstandingProvider({ @@ -274,7 +275,7 @@ const plugin: OpenClawPluginDefinition = { api.registerWebSearchProvider( createPluginBackedWebSearchProvider({ id: "exampleai-search", - // credential + fetch logic + // 凭证 + 抓取逻辑 }), ); }, @@ -283,175 +284,180 @@ const plugin: OpenClawPluginDefinition = { export default plugin; ``` -重要的不是精确的 helper 名称,而是这种形态: +关键不在于辅助函数的准确名称,而在于这种结构: -- 一个插件拥有供应商接口 +- 一个插件拥有该厂商的接口 - core 仍然拥有能力契约 -- channels 和功能插件消费 `api.runtime.*` helper,而不是供应商代码 -- 契约测试可以断言该插件注册了它声称拥有的能力 +- 渠道和功能插件消费 `api.runtime.*` 辅助函数,而不是厂商代码 +- 契约测试可以断言该插件已注册它声称拥有的能力 ### 能力示例:视频理解 -OpenClaw 已经将图像/音频/视频理解视为一个共享能力。同样的所有权模型也适用于此: +OpenClaw 已经将图像/音频/视频理解视为一个共享能力。相同的归属模型也适用于这里: 1. core 定义媒体理解契约 -2. 供应商插件按需注册 `describeImage`、`transcribeAudio` 和 `describeVideo` -3. channels 和功能插件消费共享 core 行为,而不是直接接到供应商代码 +2. 厂商插件按需注册 `describeImage`、`transcribeAudio` 和 `describeVideo` +3. 渠道和功能插件消费共享 core 行为,而不是直接接入厂商代码 -这样可以避免将某个提供商的视频假设固化到 core 中。插件拥有供应商接口;core 拥有能力契约和回退行为。 +这样可以避免把某一家提供商的视频假设固化进 core。插件拥有厂商接口;core 拥有能力契约和回退行为。 -视频生成已经遵循同样的顺序:core 拥有类型化能力契约和运行时 helper,而供应商插件则注册 `api.registerVideoGenerationProvider(...)` 实现。 +视频生成也已遵循同样流程:core 拥有类型化能力契约和运行时辅助函数,厂商插件针对其注册 `api.registerVideoGenerationProvider(...)` 实现。 -需要一个具体的发布检查清单?请参阅 [能力扩展手册](/tools/capability-cookbook)。 +需要具体的发布清单吗?请参阅[能力扩展手册](/zh-CN/plugins/architecture)。 ## 契约与强制执行 -插件 API 接口有意集中并进行了类型化,位于 `OpenClawPluginApi`。该契约定义了受支持的注册点以及插件可依赖的运行时 helper。 +插件 API 接口被有意设计为类型化且集中于 `OpenClawPluginApi`。该契约定义了受支持的注册点,以及插件可依赖的运行时辅助函数。 这很重要,因为: - 插件作者获得一个稳定的内部标准 -- core 可以拒绝重复所有权,例如两个插件注册同一个 provider id -- 启动时可以为格式错误的注册暴露可操作的诊断信息 -- 契约测试可以强制执行内置插件的所有权,并防止静默漂移 +- core 可以拒绝重复归属,例如两个插件注册相同提供商 id +- 启动时可以为格式错误的注册提供可执行的诊断信息 +- 契约测试可以强制内置插件归属,并防止无声漂移 -有两层强制执行机制: +强制执行分为两层: 1. **运行时注册强制执行** - 插件注册表会在插件加载时验证注册。例如:重复的 provider id、重复的 speech provider id 以及格式错误的注册,都会产生插件诊断,而不是未定义行为。 + 插件注册表会在插件加载时验证注册内容。例如:重复的 provider id、重复的 speech provider id,以及格式错误的注册,都会生成插件诊断信息,而不是导致未定义行为。 2. **契约测试** - 内置插件会在测试运行期间被捕获到契约注册表中,这样 OpenClaw 就可以显式断言所有权。如今这用于模型提供商、语音提供商、Web 搜索提供商以及内置注册所有权。 + 在测试运行期间,内置插件会被捕获到契约注册表中,这样 OpenClaw 就能显式断言归属关系。目前这用于模型提供商、语音提供商、Web 搜索提供商以及内置注册归属。 -其实际效果是,OpenClaw 会预先知道哪个插件拥有哪些接口。这让 core 与 channels 可以无缝组合,因为所有权是声明式、类型化且可测试的,而不是隐式的。 +实际效果是,OpenClaw 能够预先知道哪个插件拥有哪个接口。这使得 core 和渠道可以无缝组合,因为归属关系是声明式、类型化并可测试的,而不是隐式的。 -### 什么应该属于契约 +### 什么适合作为契约 -好的插件契约应当: +好的插件契约应当是: - 类型化 - 小而精 -- 针对特定能力 +- 面向特定能力 - 由 core 拥有 - 可被多个插件复用 -- 可被 channels/功能消费,而无需了解供应商知识 +- 可在无需厂商知识的情况下被渠道/功能消费 -坏的插件契约包括: +不好的插件契约则是: -- 隐藏在 core 中的供应商特定策略 +- 隐藏在 core 中的厂商专属策略 - 绕过注册表的一次性插件逃生口 -- 渠道代码直接访问某个供应商实现 +- 渠道代码直接深入某个厂商实现 - 不属于 `OpenClawPluginApi` 或 `api.runtime` 的临时运行时对象 -如有疑问,请提高抽象层级:先定义能力,再让插件接入它。 +如有疑问,请提升抽象层级:先定义能力,再让插件接入。 ## 执行模型 -原生 OpenClaw 插件与 Gateway 网关**在同一进程内**运行。它们不是沙箱隔离的。一个已加载的原生插件与 core 代码处于相同的进程级信任边界内。 +原生 OpenClaw 插件与 Gateway 网关**在同一进程中**运行。它们不在沙箱隔离中。已加载的原生插件与 core 代码具有相同的进程级信任边界。 这意味着: -- 原生插件可以注册 tools、网络处理器、hooks 和 services -- 原生插件中的 bug 可能导致 gateway 崩溃或不稳定 +- 原生插件可以注册工具、网络处理器、hooks 和服务 +- 原生插件中的 bug 可能导致网关崩溃或不稳定 - 恶意原生插件等同于在 OpenClaw 进程内执行任意代码 -兼容 bundle 默认更安全,因为 OpenClaw 当前将其视为元数据/内容包。在当前版本中,这主要意味着内置 skills。 +兼容 bundle 默认更安全,因为 OpenClaw 当前将它们视为元数据/内容包。在当前版本中,这主要意味着内置 Skills。 -对于非内置插件,请使用 allowlists 和显式的安装/加载路径。将工作区插件视为开发时代码,而不是生产默认项。 +对于非内置插件,应使用 allowlist 和显式安装/加载路径。将工作区插件视为开发期代码,而不是生产默认项。 -对于内置工作区包名,请保持插件 id 锚定在 npm 名称中:默认是 `@openclaw/`,或者在包有意暴露更窄插件角色时使用批准的类型后缀,例如 `-provider`、`-plugin`、`-speech`、`-sandbox` 或 `-media-understanding`。 +对于内置工作区包名,应让插件 id 锚定在 npm 名称中:默认使用 `@openclaw/`,或使用批准的类型化后缀,例如 `-provider`、`-plugin`、`-speech`、`-sandbox` 或 `-media-understanding`,前提是该包有意暴露更窄的插件角色。 重要信任说明: -- `plugins.allow` 信任的是**插件 id**,而不是来源出处。 -- 当工作区插件与内置插件使用相同 id,且该工作区插件被启用/加入 allowlist 时,它会有意遮蔽内置副本。 -- 这很正常,而且对本地开发、补丁测试和热修复很有用。 +- `plugins.allow` 信任的是**插件 id**,而不是来源证明。 +- 若某个工作区插件与内置插件使用相同 id,那么当该工作区插件被启用/加入 allowlist 时,它会有意覆盖内置副本。 +- 这是正常且有用的,适用于本地开发、补丁测试和热修复。 ## 导出边界 -OpenClaw 导出的是能力,而不是实现便利接口。 +OpenClaw 导出的是能力,而不是实现便捷层。 -保持能力注册公开。收紧非契约 helper 导出: +应保持能力注册为公共接口,同时收紧非契约辅助导出: -- 内置插件特定的 helper 子路径 -- 不打算作为公共 API 的运行时 plumbing 子路径 -- 供应商特定的便利 helper -- 属于实现细节的 setup/onboarding helpers +- 内置插件专属辅助子路径 +- 无意作为公共 API 的运行时管线子路径 +- 厂商专属便捷辅助函数 +- 属于实现细节的 setup / onboarding 辅助函数 -某些内置插件 helper 子路径仍出于兼容性和内置插件维护需要而保留在生成的 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 模式。 ## 加载流水线 启动时,OpenClaw 大致会执行以下步骤: 1. 发现候选插件根目录 -2. 读取原生或兼容 bundle 的 manifest 和包元数据 +2. 读取原生或兼容 bundle 的清单与包元数据 3. 拒绝不安全候选项 -4. 规范化插件配置(`plugins.enabled`、`allow`、`deny`、`entries`、`slots`、`load.paths`) -5. 为每个候选项决定启用状态 +4. 规范化插件配置(`plugins.enabled`、`allow`、`deny`、`entries`、 + `slots`、`load.paths`) +5. 决定每个候选项的启用状态 6. 通过 jiti 加载已启用的原生模块 -7. 调用原生 `register(api)`(或 `activate(api)`——这是一个 legacy 别名)hook,并将注册结果收集到插件注册表中 -8. 将注册表暴露给 commands/运行时接口 +7. 调用原生 `register(api)`(或 `activate(api)`——一个 legacy 别名)hook,并将注册内容收集到插件注册表中 +8. 将注册表暴露给命令/运行时接口 -`activate` 是 `register` 的 legacy 别名——加载器会解析现有的任意一个(`def.register ?? def.activate`),并在同一时机调用。所有内置插件都使用 `register`;新插件请优先使用 `register`。 +`activate` 是 `register` 的 legacy 别名——加载器会解析存在的那个(`def.register ?? def.activate`),并在同一时机调用它。所有内置插件都使用 `register`;新插件应优先使用 `register`。 -安全门会发生在**运行时执行之前**。当入口逃离插件根目录、路径对所有人可写,或对于非内置插件来说路径所有权看起来可疑时,候选项会被阻止。 +安全门禁发生在**运行时执行之前**。当入口逃逸出插件根目录、路径对所有人可写,或对于非内置插件而言路径归属看起来可疑时,候选项会被阻止。 ### Manifest-first 行为 -manifest 是控制平面的真实来源。OpenClaw 用它来: +清单是控制平面的事实来源。OpenClaw 使用它来: -- 标识插件 -- 发现已声明的 channels/skills/config schema 或 bundle 能力 -- 验证 `plugins.entries..config` +- 识别插件 +- 发现声明的渠道/Skills/配置模式或 bundle 能力 +- 校验 `plugins.entries..config` - 增强 Control UI 标签/占位符 - 显示安装/目录元数据 -对于原生插件,运行时模块是数据平面部分。它会注册实际行为,例如 hooks、tools、commands 或 provider 流程。 +对于原生插件,运行时模块是数据平面部分。它负责注册实际行为,例如 hooks、工具、命令或提供商流程。 ### 加载器会缓存什么 -OpenClaw 会保留一些短生命周期的进程内缓存,用于: +OpenClaw 为以下内容保留短期进程内缓存: -- 设备发现结果 -- manifest 注册表数据 -- 已加载插件注册表 +- 发现结果 +- 清单注册表数据 +- 已加载的插件注册表 -这些缓存可以减少突发式启动和重复命令开销。可以将它们视为短生命周期的性能缓存,而不是持久化。 +这些缓存可减少突发启动开销和重复命令负担。你可以将它们视为短生命周期的性能缓存,而不是持久化机制。 性能说明: -- 设置 `OPENCLAW_DISABLE_PLUGIN_DISCOVERY_CACHE=1` 或 `OPENCLAW_DISABLE_PLUGIN_MANIFEST_CACHE=1` 可以禁用这些缓存。 -- 使用 `OPENCLAW_PLUGIN_DISCOVERY_CACHE_MS` 和 `OPENCLAW_PLUGIN_MANIFEST_CACHE_MS` 调整缓存时间窗口。 +- 设置 `OPENCLAW_DISABLE_PLUGIN_DISCOVERY_CACHE=1` 或 + `OPENCLAW_DISABLE_PLUGIN_MANIFEST_CACHE=1` 可禁用这些缓存。 +- 可通过 `OPENCLAW_PLUGIN_DISCOVERY_CACHE_MS` 和 + `OPENCLAW_PLUGIN_MANIFEST_CACHE_MS` 调整缓存窗口。 ## 注册表模型 -已加载插件不会直接修改任意 core 全局对象。它们会注册到一个中心插件注册表中。 +已加载插件不会直接修改各种随机的 core 全局状态。它们会注册到中央插件注册表中。 -注册表会跟踪: +注册表跟踪: -- 插件记录(身份、来源、origin、状态、诊断信息) -- tools +- 插件记录(身份、来源、源头、状态、诊断) +- 工具 - legacy hooks 和类型化 hooks -- channels -- providers +- 渠道 +- 提供商 - Gateway 网关 RPC 处理器 -- HTTP routes -- CLI registrars -- 后台 services -- 插件拥有的 commands +- HTTP 路由 +- CLI 注册器 +- 后台服务 +- 插件自有命令 -然后 core 功能会从该注册表读取,而不是直接与插件模块通信。这使加载保持单向: +之后,core 功能会从该注册表中读取,而不是直接与插件模块对话。这样可保持单向加载: - 插件模块 -> 注册表注册 - core 运行时 -> 注册表消费 -这种分离对可维护性很重要。它意味着大多数 core 接口只需要一个集成点:“读取注册表”,而不是“为每个插件模块写特例”。 +这种分离对可维护性非常重要。它意味着大多数 core 接口只需要一个集成点:“读取注册表”,而不是“为每个插件模块写特殊分支”。 ## 会话绑定回调 -绑定会话的插件可以在审批被解决后做出响应。 +绑定会话的插件可以在审批结果解析后作出响应。 使用 `api.onConversationBindingResolved(...)` 可在绑定请求被批准或拒绝后接收回调: @@ -461,38 +467,55 @@ export default { register(api) { api.onConversationBindingResolved(async (event) => { if (event.status === "approved") { - // A binding now exists for this plugin + conversation. + // 现在该插件 + 会话已存在一个绑定。 console.log(event.binding?.conversationId); return; } - // The request was denied; clear any local pending state. + // 请求被拒绝;清理本地待处理状态。 console.log(event.request.conversation.conversationId); }); }, }; ``` -回调载荷字段: +回调负载字段: - `status`:`"approved"` 或 `"denied"` - `decision`:`"allow-once"`、`"allow-always"` 或 `"deny"` -- `binding`:已批准请求对应的解析后绑定 -- `request`:原始请求摘要、detach 提示、发送者 id 和会话元数据 +- `binding`:用于已批准请求的已解析绑定 +- `request`:原始请求摘要、分离提示、发送者 id 和会话元数据 -此回调仅用于通知。它不会改变谁有权限绑定会话,并且会在 core 审批处理完成后运行。 +此回调仅用于通知。它不会改变谁被允许绑定会话,并且会在 core 完成审批处理之后运行。 ## 提供商运行时钩子 -提供商插件现在有两层: +提供商插件现在分为两层: -- manifest 元数据:`providerAuthEnvVars` 用于在运行时加载前进行低成本 env-auth 查找,`providerAuthChoices` 用于在运行时加载前提供低成本的新手引导/auth-choice 标签和 CLI flag 元数据 -- 配置时钩子:`catalog` / legacy `discovery` 以及 `applyConfigDefaults` -- 运行时钩子:`normalizeModelId`、`normalizeTransport`、`normalizeConfig`、`applyNativeStreamingUsageCompat`、`resolveConfigApiKey`、`resolveSyntheticAuth`、`shouldDeferSyntheticProfileAuth`、`resolveDynamicModel`、`prepareDynamicModel`、`normalizeResolvedModel`、`contributeResolvedModelCompat`、`capabilities`、`normalizeToolSchemas`、`inspectToolSchemas`、`resolveReasoningOutputMode`、`prepareExtraParams`、`createStreamFn`、`wrapStreamFn`、`resolveTransportTurnState`、`resolveWebSocketSessionPolicy`、`formatApiKey`、`refreshOAuth`、`buildAuthDoctorHint`、`matchesContextOverflowError`、`classifyFailoverReason`、`isCacheTtlEligible`、`buildMissingAuthMessage`、`suppressBuiltInModel`、`augmentModelCatalog`、`isBinaryThinking`、`supportsXHighThinking`、`resolveDefaultThinkingLevel`、`isModernModelRef`、`prepareRuntimeAuth`、`resolveUsageAuth`、`fetchUsageSnapshot`、`createEmbeddingProvider`、`buildReplayPolicy`、`sanitizeReplayHistory`、`validateReplayTurns`、`onModelSelected` +- 清单元数据:`providerAuthEnvVars` 用于在运行时加载前进行低成本环境认证查找,`providerAuthChoices` 用于在运行时加载前提供低成本的新手引导/认证选项标签和 CLI flag 元数据 +- 配置阶段 hooks:`catalog` / legacy `discovery` 以及 `applyConfigDefaults` +- 运行时 hooks:`normalizeModelId`、`normalizeTransport`, + `normalizeConfig`, + `applyNativeStreamingUsageCompat`、`resolveConfigApiKey`, + `resolveSyntheticAuth`、`shouldDeferSyntheticProfileAuth`, + `resolveDynamicModel`、`prepareDynamicModel`、`normalizeResolvedModel`, + `contributeResolvedModelCompat`、`capabilities`, + `normalizeToolSchemas`、`inspectToolSchemas`, + `resolveReasoningOutputMode`、`prepareExtraParams`、`createStreamFn`, + `wrapStreamFn`、`resolveTransportTurnState`, + `resolveWebSocketSessionPolicy`、`formatApiKey`、`refreshOAuth`, + `buildAuthDoctorHint`、`matchesContextOverflowError`, + `classifyFailoverReason`、`isCacheTtlEligible`, + `buildMissingAuthMessage`、`suppressBuiltInModel`、`augmentModelCatalog`, + `isBinaryThinking`、`supportsXHighThinking`, + `resolveDefaultThinkingLevel`、`isModernModelRef`、`prepareRuntimeAuth`, + `resolveUsageAuth`、`fetchUsageSnapshot`、`createEmbeddingProvider`, + `buildReplayPolicy`, + `sanitizeReplayHistory`、`validateReplayTurns`、`onModelSelected` -OpenClaw 仍然拥有通用 agent 循环、failover、transcript 处理和工具策略。这些 hooks 是供应商特定行为的扩展接口,而无需整套自定义推理传输。 +OpenClaw 仍然拥有通用智能体循环、故障切换、转录处理和工具策略。这些 hooks 是提供商专属行为的扩展接口,而无需实现完整的自定义推理传输层。 -当提供商使用基于环境变量的凭证,且通用 auth/status/model-picker 路径需要在不加载插件运行时的情况下看到它们时,使用 manifest `providerAuthEnvVars`。当新手引导/auth-choice CLI 接口需要在不加载提供商运行时的情况下了解该提供商的 choice id、分组标签和简单单 flag auth 接线时,使用 manifest `providerAuthChoices`。将提供商运行时的 `envVars` 保留给面向操作员的提示,例如新手引导标签或 OAuth client-id/client-secret 设置变量。 +当提供商具有基于环境变量的凭证,且通用认证/状态/模型选择器路径需要在不加载插件运行时的前提下识别它们时,请使用清单中的 `providerAuthEnvVars`。当新手引导/认证选择 CLI 接口需要在不加载提供商运行时的前提下了解该提供商的 choice id、分组标签和简单的单 flag 认证接线时,请使用清单中的 `providerAuthChoices`。将提供商运行时的 `envVars` 保留给面向运维者的提示,例如新手引导标签或 OAuth client id / client secret 设置环境变量。 ### Hook 顺序与使用方式 @@ -501,54 +524,54 @@ OpenClaw 仍然拥有通用 agent 循环、failover、transcript 处理和工具 | # | Hook | 作用 | 何时使用 | | --- | --------------------------------- | ---------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | -| 1 | `catalog` | 在生成 `models.json` 期间,将 provider 配置发布到 `models.providers` | 提供商拥有目录或 base URL 默认值 | -| 2 | `applyConfigDefaults` | 在配置具体化期间应用由提供商拥有的全局配置默认值 | 默认值依赖 auth 模式、环境或提供商模型家族语义 | -| -- | _(内置模型查找)_ | OpenClaw 先尝试常规 registry/catalog 路径 | _(不是插件 hook)_ | -| 3 | `normalizeModelId` | 在查找前规范化 legacy 或 preview model-id 别名 | 提供商在规范模型解析前拥有别名清理逻辑 | -| 4 | `normalizeTransport` | 在通用模型组装前规范化提供商家族的 `api` / `baseUrl` | 提供商拥有同一传输家族中自定义 provider id 的传输清理逻辑 | -| 5 | `normalizeConfig` | 在运行时/提供商解析前规范化 `models.providers.` | 提供商需要将配置清理逻辑放在插件中;内置 Google 家族 helpers 也会为受支持的 Google 配置项兜底 | -| 6 | `applyNativeStreamingUsageCompat` | 对配置提供商应用原生流式使用量兼容重写 | 提供商需要基于端点的原生流式使用量元数据修复 | -| 7 | `resolveConfigApiKey` | 在加载运行时 auth 之前,为配置提供商解析 env-marker auth | 提供商拥有由自己控制的 env-marker API key 解析;`amazon-bedrock` 在这里也有一个内置 AWS env-marker 解析器 | -| 8 | `resolveSyntheticAuth` | 暴露本地/自托管或基于配置的 auth,而不持久化明文 | 提供商可以通过 synthetic/local 凭证标记运行 | -| 9 | `shouldDeferSyntheticProfileAuth` | 将已存储的 synthetic profile 占位符优先级降低到 env/config 支持的 auth 之后 | 提供商会存储 synthetic 占位 profile,这些 profile 不应抢占优先级 | -| 10 | `resolveDynamicModel` | 为尚未进入本地注册表的、由提供商拥有的 model id 提供同步回退 | 提供商接受任意上游 model id | -| 11 | `prepareDynamicModel` | 异步预热,然后再次运行 `resolveDynamicModel` | 提供商在解析未知 id 之前需要网络元数据 | -| 12 | `normalizeResolvedModel` | 在嵌入式 runner 使用已解析模型前进行最终重写 | 提供商需要传输重写,但仍使用 core 传输 | -| 13 | `contributeResolvedModelCompat` | 为通过另一兼容传输暴露的供应商模型贡献兼容标记 | 提供商能够在代理传输上识别自己的模型,而无需接管该 provider | -| 14 | `capabilities` | 由提供商拥有、供共享 core 逻辑使用的 transcript/tooling 元数据 | 提供商需要 transcript/提供商家族特性处理 | -| 15 | `normalizeToolSchemas` | 在嵌入式 runner 看到工具 schema 前先规范化 | 提供商需要传输家族级别的 schema 清理 | -| 16 | `inspectToolSchemas` | 在规范化后暴露由提供商拥有的 schema 诊断信息 | 提供商希望提供关键字警告,而无需让 core 学习提供商特定规则 | -| 17 | `resolveReasoningOutputMode` | 选择原生还是带标签的 reasoning-output 契约 | 提供商需要带标签的 reasoning/final output,而不是原生字段 | -| 18 | `prepareExtraParams` | 在通用 stream 选项包装器之前做请求参数规范化 | 提供商需要默认请求参数或按提供商做参数清理 | -| 19 | `createStreamFn` | 用自定义传输完全替换正常 stream 路径 | 提供商需要自定义线协议,而不只是包装器 | -| 20 | `wrapStreamFn` | 在应用通用包装器后再包装 stream | 提供商需要请求头/请求体/模型兼容包装,但不需要自定义传输 | -| 21 | `resolveTransportTurnState` | 附加原生的逐轮传输头部或元数据 | 提供商希望通用传输发送提供商原生轮次身份 | -| 22 | `resolveWebSocketSessionPolicy` | 附加原生 WebSocket 头部或会话冷却策略 | 提供商希望通用 WS 传输调优会话头或回退策略 | -| 23 | `formatApiKey` | auth-profile 格式化器:已存储 profile 变成运行时 `apiKey` 字符串 | 提供商会存储额外 auth 元数据,并需要自定义运行时 token 形态 | -| 24 | `refreshOAuth` | 用于自定义刷新端点或刷新失败策略的 OAuth 刷新覆盖 | 提供商不适配共享 `pi-ai` 刷新器 | -| 25 | `buildAuthDoctorHint` | 当 OAuth 刷新失败时附加修复提示 | 提供商在刷新失败后需要提供商拥有的 auth 修复指引 | -| 26 | `matchesContextOverflowError` | 由提供商拥有的上下文窗口溢出匹配器 | 提供商存在通用启发式无法识别的原始溢出错误 | -| 27 | `classifyFailoverReason` | 由提供商拥有的 failover 原因分类 | 提供商可以将原始 API/传输错误映射到限流/过载等原因 | -| 28 | `isCacheTtlEligible` | 面向代理/回传提供商的 prompt-cache 策略 | 提供商需要代理特定的缓存 TTL 门控 | -| 29 | `buildMissingAuthMessage` | 替换通用的缺失 auth 恢复消息 | 提供商需要提供商特定的缺失 auth 恢复提示 | -| 30 | `suppressBuiltInModel` | 过时上游模型抑制,可选附带面向用户的错误提示 | 提供商需要隐藏过时上游条目或用供应商提示替换 | -| 31 | `augmentModelCatalog` | 在发现后追加 synthetic/最终目录条目 | 提供商需要在 `models list` 和选择器中提供 synthetic 前向兼容条目 | -| 32 | `isBinaryThinking` | 针对二元 thinking 提供商的开/关推理切换 | 提供商仅暴露二元 thinking 开/关 | -| 33 | `supportsXHighThinking` | 为选定模型提供 `xhigh` 推理支持 | 提供商希望仅为部分模型启用 `xhigh` | -| 34 | `resolveDefaultThinkingLevel` | 为特定模型家族提供默认 `/think` 级别 | 提供商拥有某模型家族的默认 `/think` 策略 | -| 35 | `isModernModelRef` | 用于实时 profile 过滤和 smoke 选择的现代模型匹配器 | 提供商拥有 live/smoke 首选模型匹配逻辑 | -| 36 | `prepareRuntimeAuth` | 在推理前将配置的凭证交换成实际运行时 token/key | 提供商需要 token 交换或短生命周期请求凭证 | -| 37 | `resolveUsageAuth` | 为 `/usage` 和相关状态界面解析使用量/计费凭证 | 提供商需要自定义使用量/配额 token 解析或不同的使用量凭证 | -| 38 | `fetchUsageSnapshot` | 在 auth 解析后拉取并规范化提供商特定的使用量/配额快照 | 提供商需要提供商特定的使用量端点或载荷解析器 | -| 39 | `createEmbeddingProvider` | 为 memory/search 构建由提供商拥有的 embedding adapter | Memory embedding 行为应归属于提供商插件 | -| 40 | `buildReplayPolicy` | 返回控制该提供商 transcript 处理方式的 replay 策略 | 提供商需要自定义 transcript 策略(例如移除 thinking block) | -| 41 | `sanitizeReplayHistory` | 在通用 transcript 清理后重写 replay 历史 | 提供商需要超出共享压缩 helper 之外的 replay 重写 | -| 42 | `validateReplayTurns` | 在嵌入式 runner 之前对 replay turn 做最终校验或整形 | 提供商传输在通用清理后需要更严格的 turn 校验 | -| 43 | `onModelSelected` | 在模型生效后执行提供商拥有的副作用 | 提供商在模型变为活动状态时需要遥测或提供商拥有的状态处理 | +| 1 | `catalog` | 在生成 `models.json` 期间将提供商配置发布到 `models.providers` 中 | 提供商拥有目录或 base URL 默认值时 | +| 2 | `applyConfigDefaults` | 在配置实体化期间应用提供商自有的全局配置默认值 | 默认值依赖认证模式、环境或提供商模型族语义时 | +| -- | _(built-in model lookup)_ | OpenClaw 会先尝试常规注册表/目录路径 | _(不是插件 hook)_ | +| 3 | `normalizeModelId` | 在查找前规范化 legacy 或预览版 model-id 别名 | 提供商在规范模型解析前拥有别名清理逻辑时 | +| 4 | `normalizeTransport` | 在通用模型组装前规范化提供商族的 `api` / `baseUrl` | 提供商在同一传输族内拥有自定义 provider id 的传输清理逻辑时 | +| 5 | `normalizeConfig` | 在运行时/提供商解析前规范化 `models.providers.` | 提供商需要将配置清理逻辑保留在插件中;内置 Google 系辅助函数也会为受支持的 Google 配置项兜底 | +| 6 | `applyNativeStreamingUsageCompat` | 将原生流式用量兼容重写应用到配置提供商 | 提供商需要基于端点的原生流式用量元数据修复时 | +| 7 | `resolveConfigApiKey` | 在运行时认证加载前,为配置提供商解析 env-marker 认证 | 提供商拥有自有的 env-marker API key 解析逻辑;`amazon-bedrock` 在这里也有内置 AWS env-marker 解析器 | +| 8 | `resolveSyntheticAuth` | 在不持久化明文的前提下暴露本地/自托管或配置支持的认证 | 提供商可以使用合成/本地凭证标记运行时 | +| 9 | `shouldDeferSyntheticProfileAuth` | 让存储的合成 profile 占位符优先级低于环境/配置支持的认证 | 提供商存储了不应抢占优先级的合成占位 profile 时 | +| 10 | `resolveDynamicModel` | 针对尚未在本地注册表中的提供商自有 model id 执行同步回退 | 提供商接受任意上游 model id 时 | +| 11 | `prepareDynamicModel` | 异步预热,然后再次运行 `resolveDynamicModel` | 提供商需要先获取网络元数据才能解析未知 id 时 | +| 12 | `normalizeResolvedModel` | 在嵌入式运行器使用已解析模型前做最终重写 | 提供商需要传输重写,但仍使用 core 传输时 | +| 13 | `contributeResolvedModelCompat` | 为另一兼容传输背后的厂商模型补充兼容标记 | 提供商能在代理传输上识别自己的模型,而无需接管该提供商时 | +| 14 | `capabilities` | 提供商自有的转录/工具元数据,供共享 core 逻辑使用 | 提供商有转录或提供商族专属差异时 | +| 15 | `normalizeToolSchemas` | 在嵌入式运行器看到工具模式前进行规范化 | 提供商需要传输族的模式清理逻辑时 | +| 16 | `inspectToolSchemas` | 在规范化后暴露提供商自有的模式诊断信息 | 提供商希望给出关键字警告,而无需让 core 理解提供商专属规则 | +| 17 | `resolveReasoningOutputMode` | 选择原生还是标签化的推理输出契约 | 提供商需要标签化推理/最终输出,而不是原生字段时 | +| 18 | `prepareExtraParams` | 在通用流式选项包装器之前进行请求参数规范化 | 提供商需要默认请求参数或按提供商清理参数时 | +| 19 | `createStreamFn` | 用自定义传输完全替代普通流路径 | 提供商需要自定义线协议,而不只是一个包装器时 | +| 20 | `wrapStreamFn` | 在通用包装器应用后包装流函数 | 提供商需要请求头/请求体/模型兼容包装器,而无需自定义传输时 | +| 21 | `resolveTransportTurnState` | 附加原生的每轮传输请求头或元数据 | 提供商希望通用传输发送其原生轮次身份信息时 | +| 22 | `resolveWebSocketSessionPolicy` | 附加原生 WebSocket 请求头或会话冷却策略 | 提供商希望通用 WS 传输调整会话请求头或回退策略时 | +| 23 | `formatApiKey` | 认证 profile 格式化器:将存储的 profile 转换为运行时 `apiKey` 字符串 | 提供商存储额外认证元数据并需要自定义运行时 token 形态时 | +| 24 | `refreshOAuth` | 覆盖 OAuth 刷新逻辑以支持自定义刷新端点或刷新失败策略 | 提供商不适配共享的 `pi-ai` 刷新器时 | +| 25 | `buildAuthDoctorHint` | 在 OAuth 刷新失败时附加修复提示 | 提供商需要在刷新失败后提供其自有认证修复指导时 | +| 26 | `matchesContextOverflowError` | 提供商自有的上下文窗口溢出错误匹配器 | 提供商有原始溢出错误,而通用启发式无法识别时 | +| 27 | `classifyFailoverReason` | 提供商自有的故障切换原因分类 | 提供商可以将原始 API/传输错误映射为限流/过载等类型时 | +| 28 | `isCacheTtlEligible` | 面向代理/回程提供商的提示词缓存策略 | 提供商需要代理专属的缓存 TTL 门控时 | +| 29 | `buildMissingAuthMessage` | 替换通用缺失认证恢复消息 | 提供商需要专属的缺失认证恢复提示时 | +| 30 | `suppressBuiltInModel` | 过时上游模型隐藏,可附带面向用户的错误提示 | 提供商需要隐藏过时上游目录项,或用厂商提示替换它们时 | +| 31 | `augmentModelCatalog` | 在发现后追加合成/最终目录项 | 提供商需要在 `models list` 和选择器中追加合成的前向兼容目录项时 | +| 32 | `isBinaryThinking` | 面向二元 thinking 提供商的开/关推理切换 | 提供商只暴露二元 thinking 开/关时 | +| 33 | `supportsXHighThinking` | 为选定模型提供 `xhigh` 推理支持 | 提供商只希望在某些模型上启用 `xhigh` 时 | +| 34 | `resolveDefaultThinkingLevel` | 为特定模型族解析默认 `/think` 等级 | 提供商拥有某个模型族的默认 `/think` 策略时 | +| 35 | `isModernModelRef` | 用于 live profile 过滤和 smoke 选择的现代模型匹配器 | 提供商拥有 live/smoke 首选模型匹配逻辑时 | +| 36 | `prepareRuntimeAuth` | 在推理前将已配置凭证交换为实际运行时 token/key | 提供商需要 token 交换或短期请求凭证时 | +| 37 | `resolveUsageAuth` | 为 `/usage` 及相关状态接口解析用量/计费凭证 | 提供商需要自定义用量/配额 token 解析或使用不同的用量凭证时 | +| 38 | `fetchUsageSnapshot` | 在认证解析后获取并规范化提供商专属的用量/配额快照 | 提供商需要提供商专属用量端点或负载解析器时 | +| 39 | `createEmbeddingProvider` | 为 memory/search 构建提供商自有的 embedding 适配器 | memory embedding 行为应归属于提供商插件 | +| 40 | `buildReplayPolicy` | 返回控制该提供商转录处理的 replay 策略 | 提供商需要自定义转录策略(例如剥离 thinking 块)时 | +| 41 | `sanitizeReplayHistory` | 在通用转录清理后重写 replay 历史 | 提供商需要超出共享压缩辅助函数范围的专属 replay 重写时 | +| 42 | `validateReplayTurns` | 在嵌入式运行器之前对 replay turn 做最终校验或重塑 | 提供商传输需要在通用清理后执行更严格的轮次校验时 | +| 43 | `onModelSelected` | 在模型变为活跃后运行提供商自有的后置副作用 | 提供商需要在模型选定时执行遥测或其自有状态逻辑时 | -`normalizeModelId`、`normalizeTransport` 和 `normalizeConfig` 会先检查已匹配的 provider 插件,然后依次回退到其他具备 hook 能力的 provider 插件,直到其中一个真正修改 model id 或 transport/config。这样可以让别名/兼容 provider shim 正常工作,而无需调用方知道哪个内置插件拥有该重写逻辑。如果没有 provider hook 重写受支持的 Google 家族配置项,内置 Google 配置规范化器仍会应用该兼容性清理。 +`normalizeModelId`、`normalizeTransport` 和 `normalizeConfig` 会先检查匹配到的提供商插件,然后继续尝试其他具备相应 hook 能力的提供商插件,直到某个插件实际修改 model id 或 transport/config。这样可以让别名/兼容提供商 shim 正常工作,而无需调用方知道哪个内置插件拥有该重写逻辑。如果没有任何提供商 hook 重写受支持的 Google 系配置项,内置 Google 配置规范化器仍会执行兼容性清理。 -如果提供商需要完全自定义的线协议或自定义请求执行器,那就是另一类扩展。这些 hooks 适用于仍在 OpenClaw 常规推理循环中运行的提供商行为。 +如果提供商需要完全自定义的线协议或自定义请求执行器,那属于另一类扩展。这些 hooks 适用于仍运行在 OpenClaw 常规推理循环上的提供商行为。 ### 提供商示例 @@ -606,29 +629,107 @@ api.registerProvider({ ### 内置示例 -- Anthropic 使用 `resolveDynamicModel`、`capabilities`、`buildAuthDoctorHint`、`resolveUsageAuth`、`fetchUsageSnapshot`、`isCacheTtlEligible`、`resolveDefaultThinkingLevel`、`applyConfigDefaults`、`isModernModelRef` 和 `wrapStreamFn`,因为它拥有 Claude 4.6 前向兼容、provider 家族提示、auth 修复指引、使用量端点集成、prompt-cache 适用性、具备 auth 感知的配置默认值、Claude 默认/自适应 thinking 策略,以及针对 beta headers、`/fast` / `serviceTier` 和 `context1m` 的 Anthropic 特定 stream 整形。 -- Anthropic 的 Claude 特定 stream helpers 当前保留在内置插件自己的公共 `api.ts` / `contract-api.ts` 接缝中。该包接口导出 `wrapAnthropicProviderStream`、`resolveAnthropicBetas`、`resolveAnthropicFastMode`、`resolveAnthropicServiceTier` 以及更底层的 Anthropic 包装器构建器,而不是仅为某一个 provider 的 beta-header 规则去扩展通用 SDK。 -- OpenAI 使用 `resolveDynamicModel`、`normalizeResolvedModel` 和 `capabilities`,以及 `buildMissingAuthMessage`、`suppressBuiltInModel`、`augmentModelCatalog`、`supportsXHighThinking` 和 `isModernModelRef`,因为它拥有 GPT-5.4 前向兼容、直接的 OpenAI `openai-completions` -> `openai-responses` 规范化、具备 Codex 感知的 auth 提示、Spark 抑制、synthetic OpenAI 列表条目,以及 GPT-5 thinking / live-model 策略;`openai-responses-defaults` stream 家族拥有共享的原生 OpenAI Responses 包装器,用于 attribution headers、`/fast`/`serviceTier`、文本详细度、原生 Codex Web 搜索、reasoning-compat 载荷整形,以及 Responses 上下文管理。 -- OpenRouter 使用 `catalog` 以及 `resolveDynamicModel` 和 `prepareDynamicModel`,因为该 provider 是透传型的,可能会在 OpenClaw 静态目录更新之前暴露新的 model id;它还使用 `capabilities`、`wrapStreamFn` 和 `isCacheTtlEligible`,以便将 provider 特定请求头、路由元数据、reasoning 补丁和 prompt-cache 策略留在 core 之外。它的 replay 策略来自 `passthrough-gemini` 家族,而 `openrouter-thinking` stream 家族拥有代理推理注入,以及不受支持模型 / `auto` 的跳过逻辑。 -- GitHub Copilot 使用 `catalog`、`auth`、`resolveDynamicModel` 和 `capabilities`,以及 `prepareRuntimeAuth` 和 `fetchUsageSnapshot`,因为它需要 provider 拥有的设备登录、模型回退行为、Claude transcript 特性、GitHub token -> Copilot token 交换,以及 provider 拥有的使用量端点。 -- OpenAI Codex 使用 `catalog`、`resolveDynamicModel`、`normalizeResolvedModel`、`refreshOAuth` 和 `augmentModelCatalog`,以及 `prepareExtraParams`、`resolveUsageAuth` 和 `fetchUsageSnapshot`,因为它仍运行在 core OpenAI 传输之上,但拥有自己的传输/base URL 规范化、OAuth 刷新回退策略、默认传输选择、synthetic Codex 目录条目以及 ChatGPT 使用量端点集成;它与直接 OpenAI 共用同一个 `openai-responses-defaults` stream 家族。 -- Google AI Studio 和 Gemini CLI OAuth 使用 `resolveDynamicModel`、`buildReplayPolicy`、`sanitizeReplayHistory`、`resolveReasoningOutputMode`、`wrapStreamFn` 和 `isModernModelRef`,因为 `google-gemini` replay 家族拥有 Gemini 3.1 前向兼容回退、原生 Gemini replay 校验、bootstrap replay 清理、带标签的 reasoning-output 模式,以及现代模型匹配;而 `google-thinking` stream 家族拥有 Gemini thinking 载荷规范化;Gemini CLI OAuth 还使用 `formatApiKey`、`resolveUsageAuth` 和 `fetchUsageSnapshot` 来处理 token 格式化、token 解析和配额端点接线。 -- Anthropic Vertex 通过 `anthropic-by-model` replay 家族使用 `buildReplayPolicy`,这样 Claude 特定 replay 清理就只会作用于 Claude id,而不是所有 `anthropic-messages` 传输。 -- Amazon Bedrock 使用 `buildReplayPolicy`、`matchesContextOverflowError`、`classifyFailoverReason` 和 `resolveDefaultThinkingLevel`,因为它拥有针对 Anthropic-on-Bedrock 流量的 Bedrock 特定限流/未就绪/上下文溢出错误分类;它的 replay 策略仍与同一个仅 Claude 的 `anthropic-by-model` 防护共用。 -- OpenRouter、Kilocode、Opencode 和 Opencode Go 通过 `passthrough-gemini` replay 家族使用 `buildReplayPolicy`,因为它们通过 OpenAI 兼容传输代理 Gemini 模型,并需要 Gemini thought-signature 清理,而不需要原生 Gemini replay 校验或 bootstrap 重写。 -- MiniMax 通过 `hybrid-anthropic-openai` replay 家族使用 `buildReplayPolicy`,因为一个 provider 同时拥有 Anthropic-message 和 OpenAI 兼容语义;它在 Anthropic 侧保留仅 Claude 的 thinking-block 丢弃逻辑,同时将 reasoning output mode 覆盖回原生,而 `minimax-fast-mode` stream 家族则在共享 stream 路径上拥有 fast-mode 模型重写。 -- Moonshot 使用 `catalog` 以及 `wrapStreamFn`,因为它仍使用共享 OpenAI 传输,但需要 provider 拥有的 thinking 载荷规范化;`moonshot-thinking` stream 家族会将配置加 `/think` 状态映射到其原生二元 thinking 载荷上。 -- Kilocode 使用 `catalog`、`capabilities`、`wrapStreamFn` 和 `isCacheTtlEligible`,因为它需要 provider 拥有的请求头、reasoning 载荷规范化、Gemini transcript 提示以及 Anthropic cache-TTL 门控;`kilocode-thinking` stream 家族会将 Kilo thinking 注入保留在共享代理 stream 路径上,同时跳过 `kilo/auto` 和其他不支持显式推理载荷的代理模型 id。 -- Z.AI 使用 `resolveDynamicModel`、`prepareExtraParams`、`wrapStreamFn`、`isCacheTtlEligible`、`isBinaryThinking`、`isModernModelRef`、`resolveUsageAuth` 和 `fetchUsageSnapshot`,因为它拥有 GLM-5 回退、`tool_stream` 默认值、二元 thinking UX、现代模型匹配,以及使用量 auth + 配额拉取;`tool-stream-default-on` stream 家族则将默认开启的 `tool_stream` 包装器从各 provider 手写胶水中抽离出来。 -- xAI 使用 `normalizeResolvedModel`、`normalizeTransport`、`contributeResolvedModelCompat`、`prepareExtraParams`、`wrapStreamFn`、`resolveSyntheticAuth`、`resolveDynamicModel` 和 `isModernModelRef`,因为它拥有原生 xAI Responses 传输规范化、Grok fast-mode 别名重写、默认 `tool_stream`、strict-tool / reasoning-payload 清理、为插件拥有工具复用的回退 auth、前向兼容的 Grok 模型解析,以及由 provider 拥有的兼容补丁,例如 xAI 工具 schema 配置文件、不受支持的 schema 关键字、原生 `web_search` 和 HTML 实体工具调用参数解码。 -- Mistral、OpenCode Zen 和 OpenCode Go 仅使用 `capabilities`,以便将 transcript/tooling 特性保留在 core 之外。 -- 仅目录型的内置 providers,例如 `byteplus`、`cloudflare-ai-gateway`、`huggingface`、`kimi-coding`、`nvidia`、`qianfan`、`synthetic`、`together`、`venice`、`vercel-ai-gateway` 和 `volcengine`,只使用 `catalog`。 -- Qwen 使用 `catalog` 作为其文本 provider,并为其多模态接口提供共享的 media-understanding 和 video-generation 注册。 -- MiniMax 和 Xiaomi 使用 `catalog` 加 usage hooks,因为即使推理仍通过共享传输运行,它们的 `/usage` 行为仍由插件拥有。 +- Anthropic 使用 `resolveDynamicModel`、`capabilities`、`buildAuthDoctorHint`、 + `resolveUsageAuth`、`fetchUsageSnapshot`、`isCacheTtlEligible`、 + `resolveDefaultThinkingLevel`、`applyConfigDefaults`、`isModernModelRef` + 和 `wrapStreamFn`,因为它拥有 Claude 4.6 前向兼容、 + 提供商族提示、认证修复指导、用量端点集成、 + 提示词缓存资格、考虑认证状态的配置默认值、Claude 的 + 默认/自适应 thinking 策略,以及针对 beta headers、`/fast` / `serviceTier` + 和 `context1m` 的 Anthropic 专属流包装。 +- Anthropic 的 Claude 专属流辅助函数目前仍保留在该内置插件自己的 + 公共 `api.ts` / `contract-api.ts` 接缝中。该包接口导出了 + `wrapAnthropicProviderStream`、`resolveAnthropicBetas`、 + `resolveAnthropicFastMode`、`resolveAnthropicServiceTier` 以及更底层的 + Anthropic wrapper builder,而没有为了单一提供商的 beta-header 规则去扩大通用 SDK。 +- OpenAI 使用 `resolveDynamicModel`、`normalizeResolvedModel` 和 + `capabilities`,以及 `buildMissingAuthMessage`、`suppressBuiltInModel`、 + `augmentModelCatalog`、`supportsXHighThinking` 和 `isModernModelRef`, + 因为它拥有 GPT-5.4 前向兼容、直接的 OpenAI + `openai-completions` -> `openai-responses` 规范化、面向 Codex 的认证 + 提示、Spark 抑制、合成 OpenAI 目录项,以及 GPT-5 的 thinking / + live-model 策略;`openai-responses-defaults` 流族则拥有共享的原生 OpenAI Responses 包装器,用于 attribution headers、 + `/fast`/`serviceTier`、文本冗长度、原生 Codex Web 搜索、 + reasoning-compat 负载整形,以及 Responses 上下文管理。 +- OpenRouter 使用 `catalog` 以及 `resolveDynamicModel` 和 + `prepareDynamicModel`,因为该提供商是透传型的,可能会在 OpenClaw 的静态目录更新前就暴露新的 + model id;它还使用 `capabilities`、`wrapStreamFn` 和 `isCacheTtlEligible` + 来让提供商专属请求头、路由元数据、推理补丁和 + 提示词缓存策略留在 core 之外。其 replay 策略来自 + `passthrough-gemini` 族,而 `openrouter-thinking` 流族 + 则拥有代理推理注入与不支持模型 / `auto` 跳过逻辑。 +- GitHub Copilot 使用 `catalog`、`auth`、`resolveDynamicModel` 和 + `capabilities`,以及 `prepareRuntimeAuth` 和 `fetchUsageSnapshot`,因为它 + 需要提供商自有的设备登录、模型回退行为、Claude 转录差异、 + GitHub token -> Copilot token 交换,以及提供商自有的用量端点。 +- OpenAI Codex 使用 `catalog`、`resolveDynamicModel`、 + `normalizeResolvedModel`、`refreshOAuth` 和 `augmentModelCatalog`,以及 + `prepareExtraParams`、`resolveUsageAuth` 和 `fetchUsageSnapshot`,因为它 + 仍运行在 core OpenAI 传输之上,但拥有其传输/base URL 规范化、 + OAuth 刷新回退策略、默认传输选择、合成 Codex 目录项,以及 ChatGPT 用量端点集成;它与直接 OpenAI 共享同一个 + `openai-responses-defaults` 流族。 +- Google AI Studio 和 Gemini CLI OAuth 使用 `resolveDynamicModel`、 + `buildReplayPolicy`、`sanitizeReplayHistory`、 + `resolveReasoningOutputMode`、`wrapStreamFn` 和 `isModernModelRef`,因为 + `google-gemini` replay 族拥有 Gemini 3.1 前向兼容回退、 + 原生 Gemini replay 校验、bootstrap replay 清理、标签化 + 推理输出模式,以及现代模型匹配,而 + `google-thinking` 流族拥有 Gemini thinking 负载规范化; + Gemini CLI OAuth 还使用 `formatApiKey`、`resolveUsageAuth` 和 + `fetchUsageSnapshot` 来处理 token 格式化、token 解析和配额端点接线。 +- Anthropic Vertex 通过 + `anthropic-by-model` replay 族使用 `buildReplayPolicy`,使 Claude 专属 replay 清理仅作用于 Claude id,而非所有 `anthropic-messages` 传输。 +- Amazon Bedrock 使用 `buildReplayPolicy`、`matchesContextOverflowError`、 + `classifyFailoverReason` 和 `resolveDefaultThinkingLevel`,因为它拥有 + Bedrock 专属的限流/未就绪/上下文溢出错误分类逻辑, + 用于 Anthropic-on-Bedrock 流量;它的 replay 策略仍共享同一个仅 Claude 的 + `anthropic-by-model` 防护。 +- OpenRouter、Kilocode、Opencode 和 Opencode Go 通过 `passthrough-gemini` replay 族使用 `buildReplayPolicy`, + 因为它们通过 OpenAI 兼容传输代理 Gemini 模型,并需要 Gemini + thought-signature 清理,而不需要原生 Gemini replay 校验或 + bootstrap 重写。 +- MiniMax 通过 + `hybrid-anthropic-openai` replay 族使用 `buildReplayPolicy`,因为一个提供商同时拥有 Anthropic-message 和 OpenAI 兼容语义;它在 Anthropic 侧保留仅 Claude 的 + thinking 块丢弃逻辑,同时将推理输出模式重新覆盖为原生,而 + `minimax-fast-mode` 流族则在共享流路径上拥有 fast-mode 模型重写。 +- Moonshot 使用 `catalog` 以及 `wrapStreamFn`,因为它仍使用共享的 + OpenAI 传输,但需要提供商自有的 thinking 负载规范化;而 + `moonshot-thinking` 流族会将配置和 `/think` 状态映射为其 + 原生二元 thinking 负载。 +- Kilocode 使用 `catalog`、`capabilities`、`wrapStreamFn` 和 + `isCacheTtlEligible`,因为它需要提供商自有的请求头、 + 推理负载规范化、Gemini 转录提示和 Anthropic + 缓存 TTL 门控;`kilocode-thinking` 流族会在共享代理流路径上保持 Kilo thinking 注入,同时跳过 `kilo/auto` 和 + 其他不支持显式推理负载的代理 model id。 +- Z.AI 使用 `resolveDynamicModel`、`prepareExtraParams`、`wrapStreamFn`、 + `isCacheTtlEligible`、`isBinaryThinking`、`isModernModelRef`、 + `resolveUsageAuth` 和 `fetchUsageSnapshot`,因为它拥有 GLM-5 回退、 + `tool_stream` 默认值、二元 thinking 用户体验、现代模型匹配,以及 + 用量认证 + 配额获取;`tool-stream-default-on` 流族则让默认开启的 + `tool_stream` 包装器不必写成每个提供商手写的胶水代码。 +- xAI 使用 `normalizeResolvedModel`、`normalizeTransport`、 + `contributeResolvedModelCompat`、`prepareExtraParams`、`wrapStreamFn`、 + `resolveSyntheticAuth`、`resolveDynamicModel` 和 `isModernModelRef`, + 因为它拥有原生 xAI Responses 传输规范化、Grok fast-mode + 别名重写、默认 `tool_stream`、严格工具 / 推理负载 + 清理、用于插件自有工具的回退认证复用、前向兼容的 Grok + 模型解析,以及提供商自有兼容补丁,例如 xAI 工具模式 + 配置、不支持的模式关键字、原生 `web_search`,以及 HTML 实体 + 工具调用参数解码。 +- Mistral、OpenCode Zen 和 OpenCode Go 仅使用 `capabilities`,以便将 + 转录/工具差异保留在 core 之外。 +- 仅目录型的内置提供商,如 `byteplus`、`cloudflare-ai-gateway`、 + `huggingface`、`kimi-coding`、`nvidia`、`qianfan`、 + `synthetic`、`together`、`venice`、`vercel-ai-gateway` 和 `volcengine`, + 仅使用 `catalog`。 +- Qwen 为其文本提供商使用 `catalog`,并为其多模态接口注册共享的媒体理解和 + 视频生成能力。 +- MiniMax 和 Xiaomi 使用 `catalog` 以及用量 hooks,因为尽管推理仍通过共享传输执行,但其 `/usage` + 行为归插件所有。 -## 运行时辅助工具 +## 运行时辅助函数 -插件可以通过 `api.runtime` 访问部分选定的 core helper。对于 TTS: +插件可以通过 `api.runtime` 访问部分 core 辅助函数。对于 TTS: ```ts const clip = await api.runtime.tts.textToSpeech({ @@ -649,12 +750,12 @@ const voices = await api.runtime.tts.listVoices({ 说明: -- `textToSpeech` 返回适用于文件/语音便笺界面的常规 core TTS 输出载荷。 -- 使用 core `messages.tts` 配置和提供商选择。 -- 返回 PCM 音频缓冲区 + 采样率。插件必须为提供商重新采样/编码。 -- `listVoices` 对每个 provider 来说都是可选的。将其用于由供应商拥有的语音选择器或设置流程。 -- 语音列表可以包含更丰富的元数据,例如 locale、gender 和 personality tags,以支持具备提供商感知能力的选择器。 -- 目前 OpenAI 和 ElevenLabs 支持电话场景。Microsoft 不支持。 +- `textToSpeech` 返回用于文件/语音笔记界面的标准 core TTS 输出负载。 +- 使用 core `messages.tts` 配置和提供商选择逻辑。 +- 返回 PCM 音频缓冲区 + 采样率。插件必须为提供商执行重采样/编码。 +- `listVoices` 对每个提供商而言是可选的。可将其用于厂商自有语音选择器或设置流程。 +- 语音列表可包含更丰富的元数据,例如 locale、gender 和 personality tags,供提供商感知型选择器使用。 +- 当前 OpenAI 和 ElevenLabs 支持电话场景。Microsoft 不支持。 插件也可以通过 `api.registerSpeechProvider(...)` 注册语音提供商。 @@ -676,12 +777,14 @@ api.registerSpeechProvider({ 说明: -- 将 TTS 策略、回退和回复投递保留在 core 中。 -- 使用 speech providers 来承载由供应商拥有的合成行为。 -- Legacy Microsoft `edge` 输入会被规范化为 `microsoft` provider id。 -- 首选的所有权模型是面向公司的:随着 OpenClaw 添加这些能力契约,一个供应商插件可以同时拥有文本、语音、图像和未来的媒体 providers。 +- 将 TTS 策略、回退和回复交付保留在 core 中。 +- 使用语音提供商承载厂商自有的合成行为。 +- legacy Microsoft `edge` 输入会被规范化为 `microsoft` provider id。 +- 首选归属模型是按公司组织:随着 OpenClaw 增加这些能力契约,一个厂商插件可以同时拥有 + 文本、语音、图像和未来的媒体提供商。 -对于图像/音频/视频理解,插件会注册一个类型化的媒体理解 provider,而不是通用 key/value 包: +对于图像/音频/视频理解,插件应注册一个类型化的 +媒体理解提供商,而不是泛化的 key/value 包: ```ts api.registerMediaUnderstandingProvider({ @@ -695,15 +798,15 @@ api.registerMediaUnderstandingProvider({ 说明: -- 将编排、回退、配置和渠道接线保留在 core 中。 -- 将供应商行为保留在 provider 插件中。 -- 增量扩展应保持类型化:新的可选方法、新的可选结果字段、新的可选能力。 -- 视频生成已经遵循同样模式: - - core 拥有能力契约和运行时 helper - - 供应商插件注册 `api.registerVideoGenerationProvider(...)` +- 将编排、回退、配置和渠道接线保留在 core。 +- 将厂商行为保留在提供商插件中。 +- 增量扩展应保持类型化:新增可选方法、新增可选结果字段、新增可选能力。 +- 视频生成已经遵循相同模式: + - core 拥有能力契约和运行时辅助函数 + - 厂商插件注册 `api.registerVideoGenerationProvider(...)` - 功能/渠道插件消费 `api.runtime.videoGeneration.*` -对于媒体理解运行时 helper,插件可以调用: +对于媒体理解运行时辅助函数,插件可以调用: ```ts const image = await api.runtime.mediaUnderstanding.describeImageFile({ @@ -718,13 +821,13 @@ const video = await api.runtime.mediaUnderstanding.describeVideoFile({ }); ``` -对于音频转录,插件可以使用媒体理解运行时,或者较旧的 STT 别名: +对于音频转录,插件既可以使用媒体理解运行时,也可以使用旧的 STT 别名: ```ts const { text } = await api.runtime.mediaUnderstanding.transcribeAudioFile({ filePath: "/tmp/inbound-audio.ogg", cfg: api.config, - // Optional when MIME cannot be inferred reliably: + // 当 MIME 无法可靠推断时可选: mime: "audio/ogg", }); ``` @@ -733,10 +836,10 @@ const { text } = await api.runtime.mediaUnderstanding.transcribeAudioFile({ - `api.runtime.mediaUnderstanding.*` 是图像/音频/视频理解的首选共享接口。 - 使用 core 媒体理解音频配置(`tools.media.audio`)和提供商回退顺序。 -- 当没有产生转录输出时返回 `{ text: undefined }`(例如输入被跳过/不受支持)。 +- 当未生成转录输出时(例如输入被跳过/不受支持),返回 `{ text: undefined }`。 - `api.runtime.stt.transcribeAudioFile(...)` 仍保留为兼容别名。 -插件也可以通过 `api.runtime.subagent` 启动后台 subagent 运行: +插件还可以通过 `api.runtime.subagent` 发起后台子智能体运行: ```ts const result = await api.runtime.subagent.run({ @@ -750,13 +853,14 @@ const result = await api.runtime.subagent.run({ 说明: -- `provider` 和 `model` 是每次运行的可选覆盖项,不会持久更改 session。 -- OpenClaw 仅对受信任调用方尊重这些覆盖字段。 -- 对于由插件拥有的回退运行,操作员必须通过 `plugins.entries..subagent.allowModelOverride: true` 显式启用。 -- 使用 `plugins.entries..subagent.allowedModels` 可以将受信任插件限制为特定规范 `provider/model` 目标,或者设置为 `"*"` 以显式允许任意目标。 -- 不受信任的插件 subagent 运行仍可工作,但覆盖请求会被拒绝,而不是静默回退。 +- `provider` 和 `model` 是可选的单次运行覆盖项,不会持久改变会话设置。 +- OpenClaw 仅对受信任调用方接受这些覆盖字段。 +- 对于插件自有回退运行,运维者必须通过 `plugins.entries..subagent.allowModelOverride: true` 显式启用。 +- 使用 `plugins.entries..subagent.allowedModels` 可将受信任插件限制为特定规范 `provider/model` 目标,或设为 `"*"` 以显式允许任意目标。 +- 不受信任的插件子智能体运行仍然可用,但覆盖请求会被拒绝,而不是静默回退。 -对于 Web 搜索,插件可以消费共享运行时 helper,而不是直接访问 agent 工具接线: +对于 Web 搜索,插件可以消费共享运行时辅助函数,而不是 +深入智能体工具接线: ```ts const providers = api.runtime.webSearch.listProviders({ @@ -772,13 +876,14 @@ const result = await api.runtime.webSearch.search({ }); ``` -插件也可以通过 `api.registerWebSearchProvider(...)` 注册 Web 搜索 providers。 +插件也可以通过 +`api.registerWebSearchProvider(...)` 注册 Web 搜索提供商。 说明: -- 将 provider 选择、凭证解析和共享请求语义保留在 core 中。 -- 使用 web-search providers 来承载供应商特定搜索传输。 -- `api.runtime.webSearch.*` 是功能/渠道插件在需要搜索行为且不依赖 agent 工具包装器时的首选共享接口。 +- 将提供商选择、凭证解析和共享请求语义保留在 core 中。 +- 使用 Web 搜索提供商承载厂商专属搜索传输。 +- `api.runtime.webSearch.*` 是功能/渠道插件在需要搜索行为而不依赖智能体工具包装器时的首选共享接口。 ### `api.runtime.imageGeneration` @@ -793,12 +898,12 @@ const providers = api.runtime.imageGeneration.listProviders({ }); ``` -- `generate(...)`:使用已配置的图像生成 provider 链生成图像。 -- `listProviders(...)`:列出可用的图像生成 providers 及其能力。 +- `generate(...)`:使用已配置的图像生成提供商链生成图像。 +- `listProviders(...)`:列出可用的图像生成提供商及其能力。 ## Gateway 网关 HTTP 路由 -插件可以使用 `api.registerHttpRoute(...)` 暴露 HTTP 端点。 +插件可以通过 `api.registerHttpRoute(...)` 暴露 HTTP 端点。 ```ts api.registerHttpRoute({ @@ -816,162 +921,230 @@ api.registerHttpRoute({ 路由字段: - `path`:Gateway 网关 HTTP 服务器下的路由路径。 -- `auth`:必填。使用 `"gateway"` 表示要求常规 gateway auth,或使用 `"plugin"` 表示由插件管理 auth/webhook 校验。 +- `auth`:必填。使用 `"gateway"` 表示需要常规 Gateway 网关认证,或使用 `"plugin"` 表示由插件管理认证/webhook 校验。 - `match`:可选。`"exact"`(默认)或 `"prefix"`。 -- `replaceExisting`:可选。允许同一个插件替换它自己已有的路由注册。 -- `handler`:当路由处理了该请求时返回 `true`。 +- `replaceExisting`:可选。允许同一插件替换自己已有的路由注册。 +- `handler`:当路由处理了请求时返回 `true`。 说明: - `api.registerHttpHandler(...)` 已被移除,并会导致插件加载错误。请改用 `api.registerHttpRoute(...)`。 - 插件路由必须显式声明 `auth`。 - 除非设置 `replaceExisting: true`,否则精确的 `path + match` 冲突会被拒绝,而且一个插件不能替换另一个插件的路由。 -- 不同 `auth` 级别的重叠路由会被拒绝。请仅在相同 auth 级别内保留 `exact`/`prefix` 贯穿链。 -- `auth: "plugin"` 路由**不会**自动接收操作员运行时作用域。它们用于插件管理的 webhook/签名校验,而不是特权 Gateway 网关 helper 调用。 -- `auth: "gateway"` 路由运行在 Gateway 网关请求运行时作用域中,但该作用域有意保持保守: - - 共享密钥 bearer auth(`gateway.auth.mode = "token"` / `"password"`)会将插件路由运行时作用域固定为 `operator.write`,即使调用方发送了 `x-openclaw-scopes` - - 受信任的、具备身份信息的 HTTP 模式(例如 `trusted-proxy` 或私有入口上的 `gateway.auth.mode = "none"`)仅在明确存在该头时才会尊重 `x-openclaw-scopes` - - 如果这些具备身份信息的插件路由请求中缺少 `x-openclaw-scopes`,运行时作用域会回退到 `operator.write` -- 实际规则:不要假定 gateway-auth 插件路由天然就是管理员接口。如果你的路由需要仅管理员行为,请要求使用具备身份信息的 auth 模式,并在文档中说明明确的 `x-openclaw-scopes` header 契约。 +- 具有不同 `auth` 级别的重叠路由会被拒绝。请仅在相同认证级别内保留 `exact`/`prefix` 的贯穿链。 +- `auth: "plugin"` 路由**不会**自动获得运维者运行时作用域。它们用于插件自主管理的 webhook/签名校验,而不是特权 Gateway 网关辅助调用。 +- `auth: "gateway"` 路由会在 Gateway 网关请求运行时作用域内运行,但该作用域被有意设计为保守: + - 共享密钥 bearer 认证(`gateway.auth.mode = "token"` / `"password"`)会将插件路由运行时作用域固定为 `operator.write`,即使调用方发送了 `x-openclaw-scopes` + - 受信任的身份承载型 HTTP 模式(例如 `trusted-proxy`,或私有入口上的 `gateway.auth.mode = "none"`)仅在显式存在该请求头时才会遵循 `x-openclaw-scopes` + - 如果这些身份承载型插件路由请求中缺少 `x-openclaw-scopes`,运行时作用域会回退为 `operator.write` +- 实践规则:不要假设一个使用 gateway-auth 的插件路由天然就是管理员接口。如果你的路由需要仅管理员可用的行为,请要求使用身份承载型认证模式,并记录显式的 `x-openclaw-scopes` 请求头契约。 -## 插件 SDK 导入路径 +## Plugin SDK 导入路径 -编写插件时,请使用 SDK 子路径,而不是单体式的 `openclaw/plugin-sdk` 导入: +在编写插件时,请使用 SDK 子路径,而不是单体式的 `openclaw/plugin-sdk` 导入: - `openclaw/plugin-sdk/plugin-entry` 用于插件注册原语。 -- `openclaw/plugin-sdk/core` 用于通用共享的插件侧契约。 -- `openclaw/plugin-sdk/config-schema` 用于根 `openclaw.json` Zod schema 导出(`OpenClawSchema`)。 -- 稳定的渠道原语,例如 `openclaw/plugin-sdk/channel-setup`、`openclaw/plugin-sdk/setup-runtime`、`openclaw/plugin-sdk/setup-adapter-runtime`、`openclaw/plugin-sdk/setup-tools`、`openclaw/plugin-sdk/channel-pairing`、`openclaw/plugin-sdk/channel-contract`、`openclaw/plugin-sdk/channel-feedback`、`openclaw/plugin-sdk/channel-inbound`、`openclaw/plugin-sdk/channel-lifecycle`、`openclaw/plugin-sdk/channel-reply-pipeline`、`openclaw/plugin-sdk/command-auth`、`openclaw/plugin-sdk/secret-input` 和 `openclaw/plugin-sdk/webhook-ingress`,用于共享 setup/auth/reply/webhook 接线。 - `channel-inbound` 是防抖、提及匹配、信封格式化和入站信封上下文 helper 的共享归属位置。 - `channel-setup` 是可选安装 setup 接缝的窄接口。 - `setup-runtime` 是由 `setupEntry` / 延迟启动使用的运行时安全 setup 接口,包括导入安全的 setup patch adapters。 - `setup-adapter-runtime` 是具备环境感知的账户 setup adapter 接缝。 - `setup-tools` 是小型 CLI/归档/文档 helper 接缝(`formatCliCommand`、`detectBinary`、`extractArchive`、`resolveBrewExecutable`、`formatDocsLink`、`CONFIG_DIR`)。 -- 领域子路径,例如 `openclaw/plugin-sdk/channel-config-helpers`、`openclaw/plugin-sdk/allow-from`、`openclaw/plugin-sdk/channel-config-schema`、`openclaw/plugin-sdk/telegram-command-config`、`openclaw/plugin-sdk/channel-policy`、`openclaw/plugin-sdk/approval-runtime`、`openclaw/plugin-sdk/config-runtime`、`openclaw/plugin-sdk/infra-runtime`、`openclaw/plugin-sdk/agent-runtime`、`openclaw/plugin-sdk/lazy-runtime`、`openclaw/plugin-sdk/reply-history`、`openclaw/plugin-sdk/routing`、`openclaw/plugin-sdk/status-helpers`、`openclaw/plugin-sdk/text-runtime`、`openclaw/plugin-sdk/runtime-store` 和 `openclaw/plugin-sdk/directory-runtime`,用于共享运行时/配置 helper。 - `telegram-command-config` 是 Telegram 自定义命令规范化/校验的狭窄公共接缝,即使内置 Telegram 契约接口暂时不可用,它也会继续可用。 - `text-runtime` 是共享文本/markdown/日志接缝,包括 assistant 可见文本剥离、markdown 渲染/分块 helper、脱敏 helper、directive-tag helpers 和 safe-text utilities。 -- 针对审批的渠道接缝应优先使用插件上的单个 `approvalCapability` 契约。随后 core 会通过这一个能力来读取审批 auth、投递、渲染和原生路由行为,而不是将审批行为混入无关插件字段。 -- `openclaw/plugin-sdk/channel-runtime` 已弃用,目前仅作为旧插件的兼容 shim 保留。新代码应改为导入更窄的通用原语,仓库代码也不应新增对该 shim 的导入。 -- 内置扩展内部实现仍然是私有的。外部插件只能使用 `openclaw/plugin-sdk/*` 子路径。OpenClaw core/test 代码可以使用插件包根目录下的仓库公共入口点,例如 `index.js`、`api.js`、`runtime-api.js`、`setup-entry.js` 以及像 `login-qr-api.js` 这样的窄范围文件。绝不要从 core 或其他扩展中导入某个插件包的 `src/*`。 +- `openclaw/plugin-sdk/core` 用于通用共享的面向插件契约。 +- `openclaw/plugin-sdk/config-schema` 用于根级 `openclaw.json` Zod 模式导出(`OpenClawSchema`)。 +- 稳定的渠道原语,例如 `openclaw/plugin-sdk/channel-setup`、 + `openclaw/plugin-sdk/setup-runtime`、 + `openclaw/plugin-sdk/setup-adapter-runtime`、 + `openclaw/plugin-sdk/setup-tools`、 + `openclaw/plugin-sdk/channel-pairing`、 + `openclaw/plugin-sdk/channel-contract`、 + `openclaw/plugin-sdk/channel-feedback`、 + `openclaw/plugin-sdk/channel-inbound`、 + `openclaw/plugin-sdk/channel-lifecycle`、 + `openclaw/plugin-sdk/channel-reply-pipeline`、 + `openclaw/plugin-sdk/command-auth`、 + `openclaw/plugin-sdk/secret-input` 和 + `openclaw/plugin-sdk/webhook-ingress`,用于共享的设置/认证/回复/webhook + 接线。`channel-inbound` 是 debounce、mention 匹配、 + envelope 格式化和入站 envelope 上下文辅助函数的共享归属路径。 + `channel-setup` 是狭义的可选安装 setup 接缝。 + `setup-runtime` 是 `setupEntry` / + 延迟启动所使用的运行时安全 setup 接口,包括导入安全的 setup patch 适配器。 + `setup-adapter-runtime` 是感知环境的账号 setup 适配器接缝。 + `setup-tools` 是小型 CLI/归档/文档辅助函数接缝(`formatCliCommand`、 + `detectBinary`、`extractArchive`、`resolveBrewExecutable`、`formatDocsLink`、 + `CONFIG_DIR`)。 +- 领域子路径,例如 `openclaw/plugin-sdk/channel-config-helpers`、 + `openclaw/plugin-sdk/allow-from`、 + `openclaw/plugin-sdk/channel-config-schema`、 + `openclaw/plugin-sdk/telegram-command-config`、 + `openclaw/plugin-sdk/channel-policy`、 + `openclaw/plugin-sdk/approval-runtime`、 + `openclaw/plugin-sdk/config-runtime`、 + `openclaw/plugin-sdk/infra-runtime`、 + `openclaw/plugin-sdk/agent-runtime`、 + `openclaw/plugin-sdk/lazy-runtime`、 + `openclaw/plugin-sdk/reply-history`、 + `openclaw/plugin-sdk/routing`、 + `openclaw/plugin-sdk/status-helpers`、 + `openclaw/plugin-sdk/text-runtime`、 + `openclaw/plugin-sdk/runtime-store` 和 + `openclaw/plugin-sdk/directory-runtime`,用于共享的运行时/配置辅助函数。 + `telegram-command-config` 是 Telegram 自定义命令规范化/校验的狭义公共接缝,即使内置 Telegram 契约接口暂时不可用,它也仍然可用。 + `text-runtime` 是共享的文本/Markdown/日志接缝,包括 + assistant 可见文本剥离、Markdown 渲染/分块辅助函数、脱敏 + 辅助函数、directive-tag 辅助函数和安全文本工具。 +- 审批专用渠道接缝应优先使用插件上的单个 `approvalCapability` + 契约。然后 core 会通过该单一能力读取审批认证、交付、渲染和 + 原生路由行为,而不是将审批行为混入不相关的插件字段。 +- `openclaw/plugin-sdk/channel-runtime` 已弃用,仅作为旧插件的兼容 shim 保留。新代码应改为导入更狭义的通用原语,仓库代码也不应新增对该 shim 的导入。 +- 内置扩展内部实现仍为私有。外部插件应仅使用 `openclaw/plugin-sdk/*` 子路径。OpenClaw core / 测试代码可以使用插件包根目录下的仓库公共入口点,例如 `index.js`、`api.js`、 + `runtime-api.js`、`setup-entry.js` 以及狭义文件如 + `login-qr-api.js`。绝不可从 core 或其他扩展中导入某个插件包的 `src/*`。 - 仓库入口点拆分: - `/api.js` 是 helper/types barrel, + `/api.js` 是辅助函数/类型 barrel, `/runtime-api.js` 是仅运行时 barrel, `/index.js` 是内置插件入口, `/setup-entry.js` 是 setup 插件入口。 -- 当前内置 provider 示例: - - Anthropic 使用 `api.js` / `contract-api.js` 来提供 Claude stream helpers,例如 `wrapAnthropicProviderStream`、beta-header helpers 和 `service_tier` 解析。 - - OpenAI 使用 `api.js` 来提供 provider builders、默认模型 helpers 和实时 provider builders。 - - OpenRouter 使用 `api.js` 提供其 provider builder 以及 onboarding/config helpers,而 `register.runtime.js` 仍可为仓库内部使用重新导出通用 `plugin-sdk/provider-stream` helpers。 -- 由 facade 加载的公共入口点会优先使用活动运行时配置快照;当 OpenClaw 尚未提供运行时快照时,再回退到磁盘上解析出的配置文件。 -- 通用共享原语仍然是首选的公共 SDK 契约。仍保留一小组保留的、面向内置渠道的兼容 helper 接缝。请将其视为内置维护/兼容性接缝,而不是新的第三方导入目标;新的跨渠道契约仍应落在通用 `plugin-sdk/*` 子路径或插件本地 `api.js` / `runtime-api.js` barrel 上。 +- 当前内置提供商示例: + - Anthropic 使用 `api.js` / `contract-api.js` 提供 Claude 流辅助函数,例如 + `wrapAnthropicProviderStream`、beta-header 辅助函数和 `service_tier` + 解析。 + - OpenAI 使用 `api.js` 提供 provider builder、默认模型辅助函数和 + realtime provider builder。 + - OpenRouter 使用 `api.js` 提供其 provider builder 以及 onboarding/config + 辅助函数,而 `register.runtime.js` 仍可以为仓库本地用途重新导出通用 + `plugin-sdk/provider-stream` 辅助函数。 +- Facade 加载的公共入口点会优先使用当前活跃的运行时配置快照; + 如果 OpenClaw 尚未提供运行时快照,则回退到磁盘上的已解析配置文件。 +- 通用共享原语仍是首选的公共 SDK 契约。当前仍保留一小组 + 面向内置渠道品牌的兼容辅助接缝。应将它们视为内置维护/兼容接缝,而不是新的第三方导入目标;新的跨渠道契约仍应落在 + 通用 `plugin-sdk/*` 子路径或插件本地的 `api.js` / + `runtime-api.js` barrel 上。 兼容性说明: -- 新代码请避免使用根 `openclaw/plugin-sdk` barrel。 -- 优先使用更窄的稳定原语。较新的 setup/pairing/reply/feedback/contract/inbound/threading/command/secret-input/webhook/infra/allowlist/status/message-tool 子路径是新的内置和外部插件工作的目标契约。 - 目标解析/匹配应归属于 `openclaw/plugin-sdk/channel-targets`。 - 消息操作 gate 和 reaction message-id helpers 应归属于 `openclaw/plugin-sdk/channel-actions`。 -- 面向内置扩展的特定 helper barrels 默认并不稳定。如果某个 helper 只被某个内置扩展需要,请将其保留在该扩展本地的 `api.js` 或 `runtime-api.js` 接缝后面,而不是将其提升到 `openclaw/plugin-sdk/`。 -- 新的共享 helper 接缝应是通用的,而不是带渠道品牌的。共享目标解析应归属于 `openclaw/plugin-sdk/channel-targets`;渠道特定内部实现应保留在拥有该插件的本地 `api.js` 或 `runtime-api.js` 接缝之后。 -- `image-generation`、`media-understanding` 和 `speech` 这类能力特定子路径之所以存在,是因为内置/原生插件今天正在使用它们。仅仅因为它们存在,并不意味着每个导出的 helper 都是长期冻结的外部契约。 +- 新代码应避免使用根级 `openclaw/plugin-sdk` barrel。 +- 优先使用狭义稳定原语。较新的 setup / pairing / reply / + feedback / contract / inbound / threading / command / secret-input / webhook / infra / + allowlist / status / message-tool 子路径,是新的 + 内置和外部插件工作的预期契约。 + 目标解析/匹配应放在 `openclaw/plugin-sdk/channel-targets`。 + 消息动作门控和 reaction message-id 辅助函数应放在 + `openclaw/plugin-sdk/channel-actions`。 +- 内置扩展专属辅助 barrel 默认不稳定。如果某个 + 辅助函数只被某个内置扩展需要,请将它保留在该扩展本地的 + `api.js` 或 `runtime-api.js` 接缝后,而不是提升到 + `openclaw/plugin-sdk/`。 +- 新的共享辅助接缝应当是通用的,而不是带渠道品牌的。共享目标 + 解析应放在 `openclaw/plugin-sdk/channel-targets`;渠道专属 + 内部实现应保留在所属插件的本地 `api.js` 或 `runtime-api.js` + 接缝后。 +- `image-generation`、 + `media-understanding` 和 `speech` 这样的能力专用子路径之所以存在, + 是因为内置/原生插件今天确实在使用它们。但它们的存在本身并不意味着每个导出的辅助函数都是长期冻结的外部契约。 -## 消息工具 schema +## 消息工具模式 -插件应拥有渠道特定的 `describeMessageTool(...)` schema 贡献。请将 provider 特定字段保留在插件中,而不是放入共享 core。 +插件应拥有渠道专属的 `describeMessageTool(...)` 模式 +贡献。请将提供商专属字段保留在插件中,而不是放入共享 core。 -对于可移植的共享 schema 片段,请复用通过 `openclaw/plugin-sdk/channel-actions` 导出的通用 helpers: +对于可共享的可移植模式片段,请复用通过 +`openclaw/plugin-sdk/channel-actions` 导出的通用辅助函数: -- `createMessageToolButtonsSchema()` 用于按钮网格样式载荷 -- `createMessageToolCardSchema()` 用于结构化卡片载荷 +- `createMessageToolButtonsSchema()` 用于按钮网格风格负载 +- `createMessageToolCardSchema()` 用于结构化卡片负载 -如果某种 schema 形态只适用于某个 provider,请在该插件自己的源码中定义,而不是将其提升到共享 SDK 中。 +如果某种模式形状只适用于某一个提供商,请将其定义在该插件自己的 +源代码中,而不是提升到共享 SDK 中。 ## 渠道目标解析 -渠道插件应拥有渠道特定的目标语义。保持共享出站宿主的通用性,并使用消息 adapter 接口处理 provider 规则: +渠道插件应拥有渠道专属的目标语义。请让共享 outbound host 保持通用,并通过消息适配器接口处理提供商规则: -- `messaging.inferTargetChatType({ to })` 决定规范化目标在目录查找前应被视为 `direct`、`group` 还是 `channel` -- `messaging.targetResolver.looksLikeId(raw, normalized)` 告诉 core 某个输入是否应跳过目录搜索,直接进入类似 id 的解析 -- `messaging.targetResolver.resolveTarget(...)` 是在规范化之后或目录未命中之后,core 需要最终由 provider 拥有的解析时使用的插件回退 -- `messaging.resolveOutboundSessionRoute(...)` 则在目标解析完成后,负责 provider 特定的 session route 构造 +- `messaging.inferTargetChatType({ to })` 决定规范化目标在目录查找前 + 应被视为 `direct`、`group` 还是 `channel`。 +- `messaging.targetResolver.looksLikeId(raw, normalized)` 告诉 core + 某个输入是否应跳过目录搜索,直接走类 id 解析。 +- `messaging.targetResolver.resolveTarget(...)` 是当 core 在规范化后或目录未命中后需要最终提供商自有解析时的插件回退。 +- `messaging.resolveOutboundSessionRoute(...)` 在目标解析完成后拥有提供商专属的会话路由构造逻辑。 -推荐拆分方式: +建议拆分如下: -- 将 `inferTargetChatType` 用于应在搜索 peers/groups 之前发生的类别决策 -- 将 `looksLikeId` 用于“把这个视为显式/原生目标 id”的检查 -- 将 `resolveTarget` 用于 provider 特定的规范化回退,而不是广泛的目录搜索 -- 将 provider 原生 id,例如 chat id、thread id、JID、handle 和 room id,保留在 `target` 值或 provider 特定参数中,而不是放入通用 SDK 字段 +- 对于应在搜索 peers/groups 之前执行的类别判定,使用 `inferTargetChatType`。 +- 对于“将其视为显式/原生目标 id”的判断,使用 `looksLikeId`。 +- 将 `resolveTarget` 用于提供商专属的规范化回退,而不是广泛的目录搜索。 +- 将提供商原生 id,例如 chat id、thread id、JID、handle 和 room id,保留在 `target` 值或提供商专属参数中,而不是放入通用 SDK 字段。 -## 配置支持的目录 +## 基于配置的目录 -如果插件根据配置派生目录条目,应将该逻辑保留在插件内部,并复用 `openclaw/plugin-sdk/directory-runtime` 中的共享 helpers。 +从配置派生目录项的插件应将该逻辑保留在插件内,并复用 +`openclaw/plugin-sdk/directory-runtime` 中的共享辅助函数。 -当某个渠道需要配置支持的 peers/groups 时,请使用这种方式,例如: +当渠道需要以下基于配置的 peers/groups 时,请使用此方式: - 由 allowlist 驱动的私信 peers - 已配置的渠道/群组映射 -- 账户级静态目录回退 +- 按账号划分的静态目录回退 -`directory-runtime` 中的共享 helpers 仅处理通用操作: +`directory-runtime` 中的共享辅助函数仅处理通用操作: - 查询过滤 - limit 应用 -- 去重/规范化 helpers +- 去重/规范化辅助函数 - 构建 `ChannelDirectoryEntry[]` -渠道特定的账户检查和 id 规范化应保留在插件实现中。 +渠道专属的账号检查和 id 规范化应保留在插件实现中。 ## 提供商目录 -提供商插件可以使用 `registerProvider({ catalog: { run(...) { ... } } })` 定义用于推理的模型目录。 +提供商插件可以通过 +`registerProvider({ catalog: { run(...) { ... } } })` 为推理定义模型目录。 -`catalog.run(...)` 返回的形态与 OpenClaw 写入 `models.providers` 的形态相同: +`catalog.run(...)` 返回的结构与 OpenClaw 写入 +`models.providers` 的形状一致: -- `{ provider }` 用于单个 provider 条目 -- `{ providers }` 用于多个 provider 条目 +- `{ provider }` 用于一个 provider 项 +- `{ providers }` 用于多个 provider 项 -当插件拥有 provider 特定 model id、base URL 默认值或受 auth 保护的模型元数据时,请使用 `catalog`。 +当插件拥有提供商专属 model id、base URL 默认值或受认证控制的模型元数据时,请使用 `catalog`。 -`catalog.order` 控制插件目录相对于 OpenClaw 内置隐式 providers 的合并时机: +`catalog.order` 控制插件目录相对于 OpenClaw 内置隐式提供商的合并时机: -- `simple`:普通 API key 或环境驱动的 providers -- `profile`:当存在 auth profiles 时出现的 providers -- `paired`:综合生成多个相关 provider 条目的 providers -- `late`:最后一轮,在其他隐式 providers 之后 +- `simple`:普通 API key 或环境驱动的提供商 +- `profile`:存在 auth profiles 时出现的提供商 +- `paired`:合成多个相关 provider 项的提供商 +- `late`:最后一轮,在其他隐式提供商之后 -后出现的 provider 在键冲突时胜出,因此插件可以有意用相同 provider id 覆盖内置 provider 条目。 +发生 key 冲突时,后出现的 provider 获胜,因此插件可以有意覆盖具有相同 provider id 的内置 provider 项。 兼容性: -- `discovery` 仍作为 legacy 别名可用 +- `discovery` 仍然可作为 legacy 别名使用 - 如果同时注册了 `catalog` 和 `discovery`,OpenClaw 会使用 `catalog` ## 只读渠道检查 -如果你的插件注册了某个渠道,除了 `resolveAccount(...)` 之外,也请优先实现 `plugin.config.inspectAccount(cfg, accountId)`。 +如果你的插件注册了一个渠道,建议在实现 `resolveAccount(...)` 的同时,也实现 +`plugin.config.inspectAccount(cfg, accountId)`。 原因: -- `resolveAccount(...)` 是运行时路径。它可以假定凭证已经完全具体化,并且在缺少必需 secret 时快速失败。 -- `openclaw status`、`openclaw status --all`、`openclaw channels status`、`openclaw channels resolve` 以及 doctor/config 修复流程等只读命令路径,不应该仅为了描述配置就必须具体化运行时凭证。 +- `resolveAccount(...)` 是运行时路径。它可以假定凭证已完全实体化,并在缺少必要 Secret 时快速失败。 +- `openclaw status`、`openclaw status --all`、 + `openclaw channels status`、`openclaw channels resolve` 以及 Doctor、配置修复流程等只读命令路径,不应仅为了描述配置就去实体化运行时凭证。 推荐的 `inspectAccount(...)` 行为: -- 仅返回描述性的账户状态。 +- 只返回描述性的账号状态。 - 保留 `enabled` 和 `configured`。 - 在相关时包含凭证来源/状态字段,例如: - `tokenSource`、`tokenStatus` - `botTokenSource`、`botTokenStatus` - `appTokenSource`、`appTokenStatus` - `signingSecretSource`、`signingSecretStatus` -- 你不需要为了报告只读可用性而返回原始 token 值。返回 `tokenStatus: "available"`(以及匹配的 source 字段)就足够用于状态类命令。 -- 当凭证通过 SecretRef 配置,但在当前命令路径不可用时,使用 `configured_unavailable`。 +- 你无需为了报告只读可用性而返回原始 token 值。只返回 `tokenStatus: "available"`(以及匹配的来源字段)就足以支持状态类命令。 +- 当凭证通过 SecretRef 配置、但在当前命令路径中不可用时,请使用 `configured_unavailable`。 -这样只读命令就可以报告“已配置,但在此命令路径中不可用”,而不是崩溃或错误地将该账户报告为未配置。 +这样可让只读命令报告“已配置,但在该命令路径中不可用”,而不是崩溃或错误地报告该账号未配置。 ## 包集合 -插件目录可以包含一个带有 `openclaw.extensions` 的 `package.json`: +插件目录可以包含带有 `openclaw.extensions` 的 `package.json`: ```json { @@ -983,37 +1156,53 @@ api.registerHttpRoute({ } ``` -每个条目都会变成一个插件。如果该 pack 列出多个扩展,插件 id 会变成 `name/`。 +每个条目都会成为一个插件。如果该 pack 列出多个扩展,则插件 id +会变为 `name/`。 -如果你的插件导入了 npm 依赖,请在该目录中安装它们,以便 `node_modules` 可用(`npm install` / `pnpm install`)。 +如果你的插件导入 npm 依赖,请在该目录中安装它们, +以确保 `node_modules` 可用(`npm install` / `pnpm install`)。 -安全护栏:每个 `openclaw.extensions` 条目在解析符号链接后都必须保留在插件目录内。凡是逃离包目录的条目都会被拒绝。 +安全护栏:每个 `openclaw.extensions` 条目在解析符号链接后都必须仍位于插件 +目录内。任何逃逸出包目录的条目都会被拒绝。 -安全说明:`openclaw plugins install` 使用 `npm install --omit=dev --ignore-scripts` 安装插件依赖(运行时不包含生命周期脚本,也不安装 dev dependencies)。请保持插件依赖树为“纯 JS/TS”,并避免需要 `postinstall` 构建的包。 +安全说明:`openclaw plugins install` 会使用 +`npm install --omit=dev --ignore-scripts` 安装插件依赖 +(不运行生命周期脚本,运行时不安装 dev dependencies)。请保持插件依赖树为“纯 JS/TS”,并避免依赖需要 `postinstall` 构建的包。 -可选:`openclaw.setupEntry` 可以指向一个轻量级的仅 setup 模块。当 OpenClaw 需要为一个已禁用的渠道插件提供 setup 接口,或者某个渠道插件已启用但仍未配置时,它会加载 `setupEntry` 而不是完整插件入口。这样当主插件入口还会接入 tools、hooks 或其他仅运行时代码时,启动和 setup 都会更轻。 +可选:`openclaw.setupEntry` 可指向一个轻量级的仅 setup 模块。 +当 OpenClaw 需要为一个已禁用的渠道插件提供 setup 接口,或者 +某个渠道插件已启用但尚未完成配置时,它会加载 `setupEntry`, +而不是完整插件入口。这样可以让启动和 setup 更轻量, +特别是在你的主插件入口还会接线工具、hooks 或其他仅运行时代码时。 -可选:`openclaw.startup.deferConfiguredChannelFullLoadUntilAfterListen` 可以让渠道插件在 Gateway 网关预监听启动阶段,即使该渠道已经配置完成,也走同样的 `setupEntry` 路径。 +可选:`openclaw.startup.deferConfiguredChannelFullLoadUntilAfterListen` +允许渠道插件在 Gateway 网关预监听启动阶段也选择走同一个 `setupEntry` 路径,即使该渠道已经配置完成。 -仅当 `setupEntry` 完全覆盖了 gateway 开始监听前必须存在的启动接口时,才使用这个选项。实际上,这意味着 setup entry 必须注册启动所依赖的每一种渠道拥有能力,例如: +仅当 `setupEntry` 已完整覆盖 Gateway 网关开始监听前必须存在的启动接口时才应使用此选项。实际而言,这意味着 setup entry +必须注册启动所依赖的所有渠道自有能力,例如: - 渠道注册本身 -- 任何必须在 gateway 开始监听前可用的 HTTP routes -- 在同一时间窗口内必须存在的任何 gateway methods、tools 或 services +- 任何必须在 Gateway 网关开始监听前可用的 HTTP 路由 +- 在同一阶段必须存在的任何 Gateway 网关方法、工具或服务 -如果完整入口仍然拥有任何必需的启动能力,就不要启用此标记。保持插件默认行为,让 OpenClaw 在启动期间加载完整入口。 +如果你的完整入口仍拥有任何必需的启动能力,请不要启用此标志。 +保留默认行为,让 OpenClaw 在启动期间加载完整入口。 -内置渠道也可以发布仅 setup 的契约接口 helper,供 core 在完整渠道运行时加载前进行查询。当前的 setup 提升接口包括: +内置渠道还可以发布仅 setup 的契约接口辅助函数,以便 core 在完整渠道运行时加载前进行查询。当前的 setup 提升接口为: - `singleAccountKeysToMove` - `namedAccountPromotionKeys` - `resolveSingleAccountPromotionTarget(...)` -当 core 需要在不加载完整插件入口的情况下,将 legacy 单账户渠道配置提升为 `channels..accounts.*` 时,就会使用该接口。Matrix 是当前的内置示例:当命名账户已存在时,它只会将 auth/bootstrap 键移动到命名提升账户中,并且它可以保留一个已配置的非规范 default-account 键,而不是总是创建 `accounts.default`。 +当 core 需要在不加载完整插件入口的情况下,将 legacy 单账号渠道配置提升到 +`channels..accounts.*` 时,会使用这套接口。Matrix 是当前的内置示例:当已存在命名账号时,它只会将认证/bootstrap 键迁移到某个被提升的命名账号中,并且可以保留一个已配置的非规范默认账号键,而不是总是创建 +`accounts.default`。 -这些 setup patch adapters 会让内置契约接口发现保持惰性。导入时开销保持很轻;提升接口仅在首次使用时加载,而不会在模块导入期间重新进入内置渠道启动。 +这些 setup patch 适配器让内置契约接口发现保持惰性。导入时开销保持较轻;提升接口只会在首次使用时加载,而不会在模块导入时重新进入内置渠道启动流程。 -当这些启动接口包含 gateway RPC methods 时,请将它们保留在插件特定前缀下。Core 管理员命名空间(`config.*`、`exec.approvals.*`、`wizard.*`、`update.*`)仍然是保留的,并且始终解析为 `operator.admin`,即使插件请求了更窄的作用域。 +当这些启动接口包含 Gateway 网关 RPC 方法时,请将它们保留在 +插件专属前缀下。Core 管理员命名空间(`config.*`、 +`exec.approvals.*`、`wizard.*`、`update.*`)仍被保留,并且始终解析为 `operator.admin`,即使某个插件请求更窄的作用域也是如此。 示例: @@ -1032,7 +1221,7 @@ api.registerHttpRoute({ ### 渠道目录元数据 -渠道插件可以通过 `openclaw.channel` 宣传 setup/发现元数据,并通过 `openclaw.install` 宣传安装提示。这样可以让 core 目录保持无数据状态。 +渠道插件可以通过 `openclaw.channel` 声明 setup / 发现元数据,并通过 `openclaw.install` 声明安装提示。这让 core 保持无目录数据。 示例: @@ -1060,31 +1249,34 @@ api.registerHttpRoute({ } ``` -除了最小示例外,实用的 `openclaw.channel` 字段还包括: +除最小示例外,有用的 `openclaw.channel` 字段还包括: -- `detailLabel`:为更丰富的目录/状态接口提供次级标签 +- `detailLabel`:用于更丰富目录/状态界面的次级标签 - `docsLabel`:覆盖文档链接文本 -- `preferOver`:该目录条目应优先于的低优先级插件/渠道 id -- `selectionDocsPrefix`、`selectionDocsOmitLabel`、`selectionExtras`:选择界面文案控制 -- `markdownCapable`:将该渠道标记为支持 markdown,以供出站格式决策使用 -- `showConfigured`:当设置为 `false` 时,在已配置渠道列表界面中隐藏该渠道 -- `quickstartAllowFrom`:让该渠道加入标准快速开始 `allowFrom` 流程 -- `forceAccountBinding`:即使只有一个账户,也要求显式账户绑定 -- `preferSessionLookupForAnnounceTarget`:在解析 announce 目标时优先使用 session 查找 +- `preferOver`:该目录项应优先于的较低优先级插件/渠道 id +- `selectionDocsPrefix`、`selectionDocsOmitLabel`、`selectionExtras`:选择界面的文案控制 +- `markdownCapable`:将该渠道标记为支持 Markdown,以便出站格式化决策 +- `showConfigured`:设为 `false` 时,在已配置渠道列表界面中隐藏该渠道 +- `quickstartAllowFrom`:让该渠道接入标准快速开始 `allowFrom` 流程 +- `forceAccountBinding`:即使只存在一个账号,也要求显式账号绑定 +- `preferSessionLookupForAnnounceTarget`:在解析公告目标时优先使用会话查找 -OpenClaw 还可以合并**外部渠道目录**(例如 MPM 注册表导出)。将 JSON 文件放在以下任一路径: +OpenClaw 还可以合并**外部渠道目录**(例如某个 MPM +注册表导出)。将 JSON 文件放在以下任一位置: - `~/.openclaw/mpm/plugins.json` - `~/.openclaw/mpm/catalog.json` - `~/.openclaw/plugins/catalog.json` -或者将 `OPENCLAW_PLUGIN_CATALOG_PATHS`(或 `OPENCLAW_MPM_CATALOG_PATHS`)指向一个或多个 JSON 文件(以逗号/分号/`PATH` 分隔)。每个文件应包含 `{ "entries": [ { "name": "@scope/pkg", "openclaw": { "channel": {...}, "install": {...} } } ] }`。解析器也接受 `"packages"` 或 `"plugins"` 作为 `"entries"` 键的 legacy 别名。 +或者将 `OPENCLAW_PLUGIN_CATALOG_PATHS`(或 `OPENCLAW_MPM_CATALOG_PATHS`)指向一个或多个 JSON 文件(使用逗号/分号/`PATH` 分隔)。每个文件应包含 `{ "entries": [ { "name": "@scope/pkg", "openclaw": { "channel": {...}, "install": {...} } } ] }`。解析器也接受 `"packages"` 或 `"plugins"` 作为 `"entries"` 键的 legacy 别名。 ## 上下文引擎插件 -上下文引擎插件拥有 session 上下文编排,包括摄取、组装和压缩。通过 `api.registerContextEngine(id, factory)` 从你的插件中注册它们,然后使用 `plugins.slots.contextEngine` 选择活动引擎。 +上下文引擎插件拥有会话上下文编排逻辑,包括摄取、组装和压缩。请在你的插件中通过 +`api.registerContextEngine(id, factory)` 注册它们,然后使用 +`plugins.slots.contextEngine` 选择活跃引擎。 -当你的插件需要替换或扩展默认上下文流水线,而不仅仅是添加 memory 搜索或 hooks 时,请使用这个能力。 +当你的插件需要替换或扩展默认上下文流水线,而不仅仅是添加 memory 搜索或 hooks 时,请使用此方式。 ```ts export default function (api) { @@ -1103,7 +1295,8 @@ export default function (api) { } ``` -如果你的引擎**不**拥有压缩算法,请仍然实现 `compact()` 并显式委托它: +如果你的引擎**并不**拥有压缩算法,请保持 `compact()` +已实现,并显式委托它: ```ts import { delegateCompactionToRuntime } from "openclaw/plugin-sdk/core"; @@ -1130,51 +1323,54 @@ export default function (api) { ## 添加新能力 -当某个插件需要的行为不适合当前 API 时,不要通过私有内部访问绕过插件系统。请添加缺失的能力。 +当某个插件需要当前 API 无法表达的行为时,不要通过私有深度接入来绕过插件系统。请添加缺失的能力。 推荐顺序: 1. 定义 core 契约 - 决定 core 应拥有哪些共享行为:策略、回退、配置合并、生命周期、面向渠道的语义,以及运行时 helper 形态。 + 明确哪些共享行为应由 core 拥有:策略、回退、配置合并、 + 生命周期、面向渠道的语义以及运行时辅助函数形态。 2. 添加类型化插件注册/运行时接口 - 用最小且有用的类型化能力接口扩展 `OpenClawPluginApi` 和/或 `api.runtime`。 -3. 对接 core + 渠道/功能消费者 - 渠道和功能插件应通过 core 消费新能力,而不是直接导入供应商实现。 -4. 注册供应商实现 - 然后由供应商插件将其后端注册到该能力上。 + 用最小但有用的类型化能力接口扩展 `OpenClawPluginApi` 和/或 `api.runtime`。 +3. 接线 core + 渠道/功能消费者 + 渠道和功能插件应通过 core 消费该新能力, + 而不是直接导入某个厂商实现。 +4. 注册厂商实现 + 然后由厂商插件针对该能力注册其后端实现。 5. 添加契约覆盖 - 添加测试,使所有权和注册形态能随着时间保持明确。 + 添加测试,以便归属关系和注册形态能长期保持明确。 -这就是 OpenClaw 如何在保持有主见的同时,不被某个提供商的世界观硬编码。具体文件清单和完整示例请参阅 [能力扩展手册](/tools/capability-cookbook)。 +这就是 OpenClaw 如何在保持明确产品立场的同时,不被某家 +提供商的世界观硬编码。具体文件清单和完整示例请参阅[能力扩展手册](/zh-CN/plugins/architecture)。 -### 能力检查清单 +### 能力清单 -当你添加一个新能力时,实现通常应同时涉及以下接口: +当你添加一个新能力时,实现通常应同时覆盖以下接口: - `src//types.ts` 中的 core 契约类型 -- `src//runtime.ts` 中的 core runner/运行时 helper +- `src//runtime.ts` 中的 core 运行器/运行时辅助函数 - `src/plugins/types.ts` 中的插件 API 注册接口 - `src/plugins/registry.ts` 中的插件注册表接线 -- 当功能/渠道插件需要消费它时,在 `src/plugins/runtime/*` 中暴露插件运行时 -- `src/test-utils/plugin-registration.ts` 中的捕获/测试 helpers -- `src/plugins/contracts/registry.ts` 中的所有权/契约断言 -- `docs/` 中面向操作员/插件的文档 +- 当功能/渠道插件需要消费它时,位于 `src/plugins/runtime/*` 的插件运行时暴露层 +- `src/test-utils/plugin-registration.ts` 中的捕获/测试辅助函数 +- `src/plugins/contracts/registry.ts` 中的归属/契约断言 +- `docs/` 中面向运维者/插件作者的文档 -如果其中某个接口缺失,通常意味着这个能力还没有被完整集成。 +如果这些接口中有某一个缺失,通常说明该能力还没有被完整集成。 ### 能力模板 最小模式: ```ts -// core contract +// core 契约 export type VideoGenerationProviderPlugin = { id: string; label: string; generateVideo: (req: VideoGenerationRequest) => Promise; }; -// plugin API +// 插件 API api.registerVideoGenerationProvider({ id: "openai", label: "OpenAI", @@ -1183,7 +1379,7 @@ api.registerVideoGenerationProvider({ }, }); -// shared runtime helper for feature/channel plugins +// 面向功能/渠道插件的共享运行时辅助函数 const clip = await api.runtime.videoGeneration.generate({ prompt: "Show the robot walking through the lab.", cfg, @@ -1196,9 +1392,9 @@ const clip = await api.runtime.videoGeneration.generate({ expect(findVideoGenerationProviderIdsForPlugin("openai")).toEqual(["openai"]); ``` -这样规则就很简单: +这让规则保持简单: - core 拥有能力契约 + 编排 -- 供应商插件拥有供应商实现 -- 功能/渠道插件消费运行时 helpers -- 契约测试让所有权保持明确 +- 厂商插件拥有厂商实现 +- 功能/渠道插件消费运行时辅助函数 +- 契约测试让归属关系保持明确 diff --git a/docs/zh-CN/plugins/building-plugins.md b/docs/zh-CN/plugins/building-plugins.md index 8112eddb4..5c46ccec7 100644 --- a/docs/zh-CN/plugins/building-plugins.md +++ b/docs/zh-CN/plugins/building-plugins.md @@ -4,59 +4,48 @@ read_when: - 你需要一个用于插件开发的快速开始指南 - 你正在为 OpenClaw 添加新的渠道、提供商、工具或其他能力 sidebarTitle: Getting Started -summary: 在几分钟内创建你的第一个 OpenClaw 插件 +summary: 几分钟内创建你的第一个 OpenClaw 插件 title: 构建插件 x-i18n: - generated_at: "2026-04-05T08:39:05Z" + generated_at: "2026-04-05T18:13:47Z" model: gpt-5.4 provider: openai - source_hash: 26e780d3f04270b79d1d8f8076d6c3c5031915043e78fb8174be921c6bdd60c9 + source_hash: 677da2cfba6706bd502fc055169072eb82d2d3baa5a78f28eb520f821caa3773 source_path: plugins/building-plugins.md workflow: 15 --- # 构建插件 -插件可为 OpenClaw 扩展新能力:渠道、模型提供商、 -语音、实时转写、实时语音、媒体理解、图像生成、 -视频生成、网页抓取、网页搜索、智能体工具,或任意 -组合。 +插件可通过新增能力来扩展 OpenClaw:渠道、模型提供商、语音、实时转录、实时语音、媒体理解、图像生成、视频生成、网页抓取、网页搜索、智能体工具,或以上任意组合。 -你不需要将你的插件添加到 OpenClaw 仓库中。发布到 -[ClawHub](/tools/clawhub) 或 npm,用户即可使用 -`openclaw plugins install ` 进行安装。OpenClaw 会优先尝试 ClawHub, -并自动回退到 npm。 +你不需要把你的插件添加到 OpenClaw 仓库中。发布到 [ClawHub](/zh-CN/tools/clawhub) 或 npm 后,用户可使用 `openclaw plugins install ` 安装。OpenClaw 会先尝试 ClawHub,并在需要时自动回退到 npm。 -## 前提条件 +## 前置条件 -- Node >= 22 和一个包管理器(npm 或 pnpm) +- Node >= 22,以及一个包管理器(npm 或 pnpm) - 熟悉 TypeScript(ESM) - 对于仓库内插件:已克隆仓库并完成 `pnpm install` -## 什么类型的插件? +## 这是什么类型的插件? - + 将 OpenClaw 连接到消息平台(Discord、IRC 等) - - 添加一个模型提供商(LLM、代理或自定义端点) + + 添加模型提供商(LLM、代理或自定义端点) 注册智能体工具、事件 hooks 或服务 —— 继续阅读下文 -如果某个渠道插件是可选的,并且在新手引导 / 设置运行时 -可能尚未安装,请使用来自 -`openclaw/plugin-sdk/channel-setup` 的 `createOptionalChannelSetupSurface(...)`。 -它会生成一个设置适配器 + 向导组合, -用于声明安装要求,并在插件安装完成前对真实配置写入采取默认拒绝策略。 +如果某个渠道插件是可选的,并且在新手引导 / 设置运行时可能尚未安装,请使用 `openclaw/plugin-sdk/channel-setup` 中的 `createOptionalChannelSetupSurface(...)`。它会生成一个设置适配器 + 向导组合,用于提示安装要求,并在插件安装完成前对实际配置写入采取失败关闭策略。 ## 快速开始:工具插件 -本演练将创建一个用于注册智能体工具的最小插件。渠道 -和提供商插件有上方链接中的专门指南。 +本演练将创建一个最小插件,用于注册一个智能体工具。渠道插件和提供商插件有上方链接的专用指南。 @@ -93,9 +82,7 @@ x-i18n: ``` - 每个插件都需要一个清单,即使没有配置也是如此。完整 schema 请参见 - [Manifest](/plugins/manifest)。规范的 ClawHub - 发布片段位于 `docs/snippets/plugin-publish/` 中。 + 每个插件都需要一个清单,即使没有配置也一样。完整模式请参见 [Manifest](/zh-CN/plugins/manifest)。规范的 ClawHub 发布代码片段位于 `docs/snippets/plugin-publish/`。 @@ -123,9 +110,7 @@ x-i18n: }); ``` - `definePluginEntry` 用于非渠道插件。对于渠道,请使用 - `defineChannelPluginEntry` —— 参见 [渠道插件](/plugins/sdk-channel-plugins)。 - 有关完整的入口点选项,请参见 [入口点](/plugins/sdk-entrypoints)。 + `definePluginEntry` 用于非渠道插件。对于渠道,请使用 `defineChannelPluginEntry` —— 参见 [渠道插件](/zh-CN/plugins/sdk-channel-plugins)。完整入口点选项请参见 [入口点](/zh-CN/plugins/sdk-entrypoints)。 @@ -139,8 +124,7 @@ x-i18n: openclaw plugins install clawhub:@myorg/openclaw-my-plugin ``` - 对于像 - `@myorg/openclaw-my-plugin` 这样的裸包规范,OpenClaw 也会先检查 ClawHub,再检查 npm。 + 对于像 `@myorg/openclaw-my-plugin` 这样的裸包规范,OpenClaw 也会在 npm 之前先检查 ClawHub。 **仓库内插件:** 放在内置插件工作区树下 —— 会自动发现。 @@ -153,60 +137,53 @@ x-i18n: ## 插件能力 -单个插件可以通过 `api` 对象注册任意数量的能力: +单个插件可通过 `api` 对象注册任意数量的能力: -| 能力 | 注册方法 | 详细指南 | -| --------------------- | ---------------------------------------------- | ------------------------------------------------------------------------------- | -| 文本推理(LLM) | `api.registerProvider(...)` | [提供商插件](/plugins/sdk-provider-plugins) | -| CLI 推理后端 | `api.registerCliBackend(...)` | [CLI 后端](/gateway/cli-backends) | -| 渠道 / 消息 | `api.registerChannel(...)` | [渠道插件](/plugins/sdk-channel-plugins) | -| 语音(TTS/STT) | `api.registerSpeechProvider(...)` | [提供商插件](/plugins/sdk-provider-plugins#step-5-add-extra-capabilities) | -| 实时转写 | `api.registerRealtimeTranscriptionProvider(...)` | [提供商插件](/plugins/sdk-provider-plugins#step-5-add-extra-capabilities) | -| 实时语音 | `api.registerRealtimeVoiceProvider(...)` | [提供商插件](/plugins/sdk-provider-plugins#step-5-add-extra-capabilities) | -| 媒体理解 | `api.registerMediaUnderstandingProvider(...)` | [提供商插件](/plugins/sdk-provider-plugins#step-5-add-extra-capabilities) | -| 图像生成 | `api.registerImageGenerationProvider(...)` | [提供商插件](/plugins/sdk-provider-plugins#step-5-add-extra-capabilities) | -| 视频生成 | `api.registerVideoGenerationProvider(...)` | [提供商插件](/plugins/sdk-provider-plugins#step-5-add-extra-capabilities) | -| 网页抓取 | `api.registerWebFetchProvider(...)` | [提供商插件](/plugins/sdk-provider-plugins#step-5-add-extra-capabilities) | -| 网页搜索 | `api.registerWebSearchProvider(...)` | [提供商插件](/plugins/sdk-provider-plugins#step-5-add-extra-capabilities) | -| 智能体工具 | `api.registerTool(...)` | 下文 | -| 自定义命令 | `api.registerCommand(...)` | [入口点](/plugins/sdk-entrypoints) | -| 事件 hooks | `api.registerHook(...)` | [入口点](/plugins/sdk-entrypoints) | -| HTTP 路由 | `api.registerHttpRoute(...)` | [内部机制](/plugins/architecture#gateway-http-routes) | -| CLI 子命令 | `api.registerCli(...)` | [入口点](/plugins/sdk-entrypoints) | +| 能力 | 注册方法 | 详细指南 | +| ---------------------- | ------------------------------------------------ | ------------------------------------------------------------------------------- | +| 文本推理(LLM) | `api.registerProvider(...)` | [提供商插件](/zh-CN/plugins/sdk-provider-plugins) | +| 渠道 / 消息传递 | `api.registerChannel(...)` | [渠道插件](/zh-CN/plugins/sdk-channel-plugins) | +| 语音(TTS/STT) | `api.registerSpeechProvider(...)` | [提供商插件](/zh-CN/plugins/sdk-provider-plugins#step-5-add-extra-capabilities) | +| 实时转录 | `api.registerRealtimeTranscriptionProvider(...)` | [提供商插件](/zh-CN/plugins/sdk-provider-plugins#step-5-add-extra-capabilities) | +| 实时语音 | `api.registerRealtimeVoiceProvider(...)` | [提供商插件](/zh-CN/plugins/sdk-provider-plugins#step-5-add-extra-capabilities) | +| 媒体理解 | `api.registerMediaUnderstandingProvider(...)` | [提供商插件](/zh-CN/plugins/sdk-provider-plugins#step-5-add-extra-capabilities) | +| 图像生成 | `api.registerImageGenerationProvider(...)` | [提供商插件](/zh-CN/plugins/sdk-provider-plugins#step-5-add-extra-capabilities) | +| 视频生成 | `api.registerVideoGenerationProvider(...)` | [提供商插件](/zh-CN/plugins/sdk-provider-plugins#step-5-add-extra-capabilities) | +| 网页抓取 | `api.registerWebFetchProvider(...)` | [提供商插件](/zh-CN/plugins/sdk-provider-plugins#step-5-add-extra-capabilities) | +| 网页搜索 | `api.registerWebSearchProvider(...)` | [提供商插件](/zh-CN/plugins/sdk-provider-plugins#step-5-add-extra-capabilities) | +| 智能体工具 | `api.registerTool(...)` | 下文 | +| 自定义命令 | `api.registerCommand(...)` | [入口点](/zh-CN/plugins/sdk-entrypoints) | +| 事件 hooks | `api.registerHook(...)` | [入口点](/zh-CN/plugins/sdk-entrypoints) | +| HTTP 路由 | `api.registerHttpRoute(...)` | [内部机制](/zh-CN/plugins/architecture#gateway-http-routes) | +| CLI 子命令 | `api.registerCli(...)` | [入口点](/zh-CN/plugins/sdk-entrypoints) | -有关完整的注册 API,请参见 [SDK 概览](/plugins/sdk-overview#registration-api)。 +完整注册 API 请参见 [SDK 概览](/zh-CN/plugins/sdk-overview#registration-api)。 -如果你的插件注册了自定义 gateway RPC 方法,请将它们保留在 -插件专属前缀下。核心管理命名空间(`config.*`、 -`exec.approvals.*`、`wizard.*`、`update.*`)保持保留状态,并且始终解析到 -`operator.admin`,即使插件请求了更窄的作用域也是如此。 +如果你的插件注册了自定义 Gateway RPC 方法,请将它们放在插件专属前缀下。核心管理命名空间(`config.*`、`exec.approvals.*`、`wizard.*`、`update.*`)始终保留,并且总是解析到 `operator.admin`,即使插件请求了更窄的作用域也是如此。 -需要注意的 hook 守卫语义: +需要注意的 hook 防护语义: -- `before_tool_call`:`{ block: true }` 是终止性结果,并会停止更低优先级的处理器。 -- `before_tool_call`:`{ block: false }` 会被视为未作决定。 -- `before_tool_call`:`{ requireApproval: true }` 会暂停智能体执行,并通过 exec 批准浮层、Telegram 按钮、Discord 交互或任意渠道上的 `/approve` 命令提示用户批准。 -- `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_tool_call`:`{ requireApproval: true }` 会暂停智能体执行,并通过 exec 审批覆盖层、Telegram 按钮、Discord 交互,或任意渠道上的 `/approve` 命令提示用户审批。 +- `before_install`:`{ block: true }` 是终结结果,并会停止优先级更低的处理器。 +- `before_install`:`{ block: false }` 会被视为没有作出决定。 +- `message_sending`:`{ cancel: true }` 是终结结果,并会停止优先级更低的处理器。 +- `message_sending`:`{ cancel: false }` 会被视为没有作出决定。 -`/approve` 命令会处理 exec 和插件批准,并带有有界回退:当找不到 exec approval id 时,OpenClaw 会使用同一 id 通过插件批准重试。插件批准转发可通过配置中的 `approvals.plugin` 独立设置。 +`/approve` 命令会同时处理 exec 审批和插件审批,并带有有界回退机制:当找不到某个 exec 审批 id 时,OpenClaw 会使用同一个 id 重试插件审批。插件审批转发可以通过配置中的 `approvals.plugin` 独立配置。 -如果自定义批准流程需要检测同样的有界回退场景, -请优先使用来自 `openclaw/plugin-sdk/error-runtime` 的 `isApprovalNotFoundError`, -而不是手动匹配 approval-expiry 字符串。 +如果自定义审批流程需要检测这个相同的有界回退场景,优先使用 `openclaw/plugin-sdk/error-runtime` 中的 `isApprovalNotFoundError`,而不是手动匹配审批过期字符串。 -详情请参见 [SDK 概览 hook 决策语义](/plugins/sdk-overview#hook-decision-semantics)。 +详情请参见 [SDK 概览 hook 决策语义](/zh-CN/plugins/sdk-overview#hook-decision-semantics)。 ## 注册智能体工具 -工具是 LLM 可调用的类型化函数。它们可以是必需的(始终 -可用),也可以是可选的(用户选择启用): +工具是 LLM 可调用的类型化函数。它们可以是必需的(始终可用),也可以是可选的(用户主动选择启用): ```typescript register(api) { - // Required tool — always available + // 必需工具 —— 始终可用 api.registerTool({ name: "my_tool", description: "Do a thing", @@ -216,7 +193,7 @@ register(api) { }, }); - // Optional tool — user must add to allowlist + // 可选工具 —— 用户必须添加到 allowlist api.registerTool( { name: "workflow_tool", @@ -239,9 +216,9 @@ register(api) { } ``` -- 工具名称不得与核心工具冲突(冲突项会被跳过) +- 工具名称不能与核心工具冲突(冲突项会被跳过) - 对于有副作用或需要额外二进制依赖的工具,请使用 `optional: true` -- 用户可以通过将插件 id 添加到 `tools.allow` 来启用某个插件中的全部工具 +- 用户可通过将插件 id 添加到 `tools.allow` 来启用某个插件的所有工具 ## 导入约定 @@ -251,29 +228,23 @@ register(api) { import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry"; import { createPluginRuntimeStore } from "openclaw/plugin-sdk/runtime-store"; -// Wrong: monolithic root (deprecated, will be removed) +// 错误:单体根路径(已弃用,将被移除) import { ... } from "openclaw/plugin-sdk"; ``` -完整的子路径参考请参见 [SDK 概览](/plugins/sdk-overview)。 +完整子路径参考请参见 [SDK 概览](/zh-CN/plugins/sdk-overview)。 -在你的插件内部,请使用本地 barrel 文件(`api.ts`、`runtime-api.ts`)进行 -内部导入 —— 绝不要通过它自己的 SDK 路径导入你自己的插件。 +在你的插件内部,请使用本地 barrel 文件(`api.ts`、`runtime-api.ts`)进行内部导入 —— 绝不要通过其 SDK 路径导入你自己的插件。 -对于提供商插件,请将提供商专属辅助函数保留在这些包根级 -barrel 中,除非该边界确实是通用的。当前的内置示例包括: +对于提供商插件,除非该扩展点确实是通用的,否则应将提供商专属辅助函数保留在这些包根级 barrel 中。当前内置示例包括: -- Anthropic:Claude 流包装器以及 `service_tier` / beta 辅助函数 +- Anthropic:Claude 流包装器,以及 `service_tier` / beta 辅助函数 - OpenAI:提供商构建器、默认模型辅助函数、实时提供商 -- OpenRouter:提供商构建器以及新手引导 / 配置辅助函数 +- OpenRouter:提供商构建器,以及新手引导 / 配置辅助函数 -如果某个辅助函数只在一个内置提供商包内部有用,请将它保留在该 -包根级边界上,而不要将其提升到 `openclaw/plugin-sdk/*` 中。 +如果某个辅助函数只在一个内置提供商包内部有用,就应把它保留在该包根级扩展点上,而不是将其提升到 `openclaw/plugin-sdk/*` 中。 -某些自动生成的 `openclaw/plugin-sdk/` 辅助边界仍然存在, -用于内置插件维护和兼容性,例如 -`plugin-sdk/feishu-setup` 或 `plugin-sdk/zalo-setup`。请将这些视为保留 -表面,而不是新第三方插件的默认模式。 +某些生成的 `openclaw/plugin-sdk/` 辅助扩展点仍然存在,用于内置插件维护和兼容性,例如 `plugin-sdk/feishu-setup` 或 `plugin-sdk/zalo-setup`。应将这些视为保留接口,而不是新第三方插件的默认模式。 ## 提交前检查清单 @@ -285,42 +256,42 @@ barrel 中,除非该边界确实是通用的。当前的内置示例包括: 测试通过(`pnpm test -- /my-plugin/`) `pnpm check` 通过(仓库内插件) -## Beta 发布测试 +## Beta 版本测试 -1. 关注 [openclaw/openclaw](https://github.com/openclaw/openclaw/releases) 上的 GitHub 发布标签,并通过 `Watch` > `Releases` 订阅。Beta 标签看起来像 `v2026.3.N-beta.1`。你也可以为官方 OpenClaw X 账号 [@openclaw](https://x.com/openclaw) 开启通知,以获取发布公告。 -2. Beta 标签一出现,就尽快用它测试你的插件。稳定版发布前的窗口通常只有几个小时。 -3. 测试后,在 Discord 频道 `plugin-forum` 中你插件对应的帖子里发送 `all good`,或者说明损坏了什么。如果你还没有帖子,请创建一个。 -4. 如果出现问题,请创建或更新一个标题为 `Beta blocker: - ` 的 issue,并添加 `beta-blocker` 标签。将该 issue 链接贴到你的帖子中。 -5. 向 `main` 提交一个标题为 `fix(): beta blocker - ` 的 PR,并在 PR 和你的 Discord 帖子中都链接该 issue。贡献者不能为 PR 添加标签,因此标题就是提供给维护者和自动化的 PR 侧信号。有 PR 的阻塞问题会被合并;没有 PR 的阻塞问题仍可能随版本发布。维护者会在 Beta 测试期间关注这些帖子。 -6. 沉默即表示绿色通过。如果你错过了这个窗口,你的修复很可能会进入下一个周期。 +1. 关注 [openclaw/openclaw](https://github.com/openclaw/openclaw/releases) 上的 GitHub 发布标签,并通过 `Watch` > `Releases` 订阅。Beta 标签形式类似 `v2026.3.N-beta.1`。你也可以为 OpenClaw 官方 X 账号 [@openclaw](https://x.com/openclaw) 开启通知,以获取发布公告。 +2. 在 beta 标签出现后尽快使用它测试你的插件。稳定版发布前的窗口通常只有几个小时。 +3. 测试完成后,在 `plugin-forum` Discord 渠道中你的插件线程里发帖,说明是 `all good` 还是哪里出问题了。如果你还没有线程,请创建一个。 +4. 如果出了问题,请创建或更新一个标题为 `Beta blocker: - ` 的 issue,并添加 `beta-blocker` 标签。把该 issue 链接发到你的线程中。 +5. 向 `main` 提交一个标题为 `fix(): beta blocker - ` 的 PR,并在 PR 和你的 Discord 线程中都链接该 issue。贡献者无法给 PR 打标签,因此标题就是给维护者和自动化系统的 PR 侧信号。有 PR 的阻塞问题会被合并;没有 PR 的阻塞问题则可能仍然随版本发布。维护者会在 beta 测试期间关注这些线程。 +6. 没有消息就表示一切正常。如果你错过了窗口,你的修复很可能会在下一个周期落地。 ## 后续步骤 - - 构建一个消息渠道插件 + + 构建消息渠道插件 - - 构建一个模型提供商插件 + + 构建模型提供商插件 - - 导入映射和注册 API 参考 + + 导入映射与注册 API 参考 - + 通过 api.runtime 使用 TTS、搜索、子智能体 - + 测试工具和模式 - - 完整清单 schema 参考 + + 完整清单模式参考 ## 相关内容 -- [插件架构](/plugins/architecture) — 内部架构深入解析 -- [SDK 概览](/plugins/sdk-overview) — 插件 SDK 参考 -- [Manifest](/plugins/manifest) — 插件清单格式 -- [渠道插件](/plugins/sdk-channel-plugins) — 构建渠道插件 -- [提供商插件](/plugins/sdk-provider-plugins) — 构建提供商插件 +- [插件架构](/zh-CN/plugins/architecture) —— 内部架构深度解析 +- [SDK 概览](/zh-CN/plugins/sdk-overview) —— 插件 SDK 参考 +- [Manifest](/zh-CN/plugins/manifest) —— 插件清单格式 +- [渠道插件](/zh-CN/plugins/sdk-channel-plugins) —— 构建渠道插件 +- [提供商插件](/zh-CN/plugins/sdk-provider-plugins) —— 构建提供商插件 diff --git a/docs/zh-CN/plugins/manifest.md b/docs/zh-CN/plugins/manifest.md index 7c15284da..b01d92c38 100644 --- a/docs/zh-CN/plugins/manifest.md +++ b/docs/zh-CN/plugins/manifest.md @@ -1,62 +1,73 @@ --- read_when: - 你正在构建一个 OpenClaw 插件 - - 你需要发布插件配置 schema,或排查插件校验错误 + - 你需要发布插件配置 schema,或调试插件校验错误 summary: 插件清单 + JSON schema 要求(严格配置校验) -title: Plugin Manifest +title: 插件清单 x-i18n: - generated_at: "2026-04-05T08:39:41Z" + generated_at: "2026-04-05T18:14:21Z" model: gpt-5.4 provider: openai - source_hash: 702447ad39f295cfffd4214c3e389bee667d2f9850754f2e02e325dde8e4ac00 + source_hash: 8781fcccef80de68036826833ef46d482e399cdad180bfd799dcc96cd1dfc845 source_path: plugins/manifest.md workflow: 15 --- -# Plugin Manifest(openclaw.plugin.json) +# 插件清单(`openclaw.plugin.json`) 本页仅适用于 **原生 OpenClaw 插件清单**。 -有关兼容的 bundle 布局,请参见 [Plugin bundles](/plugins/bundles)。 +关于兼容的 bundle 布局,请参见 [Plugin bundles](/zh-CN/plugins/bundles)。 兼容的 bundle 格式使用不同的清单文件: - Codex bundle:`.codex-plugin/plugin.json` -- Claude bundle:`.claude-plugin/plugin.json` 或不带清单的默认 Claude 组件布局 +- Claude bundle:`.claude-plugin/plugin.json`,或不带清单的默认 Claude 组件 + 布局 - Cursor bundle:`.cursor-plugin/plugin.json` -OpenClaw 也会自动检测这些 bundle 布局,但它们不会按照此处描述的 `openclaw.plugin.json` schema 进行校验。 +OpenClaw 也会自动检测这些 bundle 布局,但不会按照此处描述的 +`openclaw.plugin.json` schema 对它们进行校验。 -对于兼容 bundle,OpenClaw 当前会在布局符合 OpenClaw 运行时预期时,读取 bundle 元数据以及声明的 skill 根目录、Claude 命令根目录、Claude bundle `settings.json` 默认值、Claude bundle LSP 默认值,以及受支持的 hook 包。 +对于兼容 bundle,OpenClaw 当前会在布局符合 OpenClaw 运行时预期时, +读取 bundle 元数据,以及声明的 skill 根目录、Claude 命令根目录、Claude bundle 的 +`settings.json` 默认值、Claude bundle 的 LSP 默认值,以及受支持的 hook pack。 -每个原生 OpenClaw 插件**必须**在**插件根目录**中提供一个 `openclaw.plugin.json` 文件。OpenClaw 使用这个清单在**不执行插件代码**的情况下验证配置。缺失或无效的清单会被视为插件错误,并阻止配置校验。 +每个原生 OpenClaw 插件**必须**在 **插件根目录** 中提供一个 `openclaw.plugin.json` +文件。OpenClaw 使用该清单在**不执行插件代码的情况下** +校验配置。缺失或无效的清单会被视为 +插件错误,并阻止配置校验。 -完整插件系统指南请参见:[Plugins](/tools/plugin)。 -有关原生能力模型和当前外部兼容性指南,请参见: -[Capability model](/plugins/architecture#public-capability-model)。 +完整的插件系统指南请参见:[Plugins](/zh-CN/tools/plugin)。 +关于原生能力模型和当前的外部兼容性指南,请参见: +[Capability model](/zh-CN/plugins/architecture#public-capability-model)。 ## 这个文件的作用 -`openclaw.plugin.json` 是 OpenClaw 在加载你的插件代码之前读取的元数据。 +`openclaw.plugin.json` 是 OpenClaw 在加载你的 +插件代码之前读取的元数据。 -可用于: +它适用于: -- 插件身份 +- 插件标识 - 配置校验 -- 无需启动插件运行时即可获得的认证和新手引导元数据 -- 应在插件运行时加载前解析的别名和自动启用元数据 -- 应在运行时加载前自动激活插件的简写模型家族归属元数据 -- 用于内置兼容接线和契约覆盖的静态能力归属快照 -- 无需加载运行时即可合并到目录和校验界面的渠道专属配置元数据 +- 无需启动插件运行时即可使用的认证和新手引导元数据 +- 需要在插件运行时加载前解析的别名和自动启用元数据 +- 需要在运行时加载前自动激活 + 插件的简写模型家族归属元数据 +- 用于内置兼容性接线和 + 合同覆盖的静态能力归属快照 +- 无需加载运行时即可合并到目录和校验 + 表面的渠道专用配置元数据 - 配置 UI 提示 -不要用于: +不要将它用于: - 注册运行时行为 - 声明代码入口点 - npm 安装元数据 -这些内容属于你的插件代码和 `package.json`。 +这些属于你的插件代码和 `package.json`。 ## 最小示例 @@ -83,7 +94,6 @@ OpenClaw 也会自动检测这些 bundle 布局,但它们不会按照此处描 "modelSupport": { "modelPrefixes": ["router-"] }, - "cliBackends": ["openrouter-cli"], "providerAuthEnvVars": { "openrouter": ["OPENROUTER_API_KEY"] }, @@ -123,55 +133,54 @@ OpenClaw 也会自动检测这些 bundle 布局,但它们不会按照此处描 ## 顶层字段参考 -| 字段 | 必需 | 类型 | 含义 | -| ----------------------------------- | ---- | -------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `id` | 是 | `string` | 规范插件 id。这就是在 `plugins.entries.` 中使用的 id。 | -| `configSchema` | 是 | `object` | 此插件配置的内联 JSON Schema。 | -| `enabledByDefault` | 否 | `true` | 将内置插件标记为默认启用。省略它,或设置为任何非 `true` 的值,则插件默认保持禁用。 | -| `legacyPluginIds` | 否 | `string[]` | 会归一化到此规范插件 id 的旧版 id。 | -| `autoEnableWhenConfiguredProviders` | 否 | `string[]` | 当认证、配置或模型引用提到这些 provider id 时,应自动启用此插件。 | -| `kind` | 否 | `"memory"` \| `"context-engine"` | 声明供 `plugins.slots.*` 使用的互斥插件类型。 | -| `channels` | 否 | `string[]` | 由此插件拥有的渠道 id。用于发现和配置校验。 | -| `providers` | 否 | `string[]` | 由此插件拥有的 provider id。 | -| `modelSupport` | 否 | `object` | 由清单拥有的简写模型家族元数据,用于在运行时加载前自动加载插件。 | -| `cliBackends` | 否 | `string[]` | 由此插件拥有的 CLI 推理后端 id。用于根据显式配置引用在启动时自动激活。 | -| `providerAuthEnvVars` | 否 | `Record` | OpenClaw 可在不加载插件代码的情况下检查的轻量 provider 认证环境变量元数据。 | -| `providerAuthChoices` | 否 | `object[]` | 用于新手引导选择器、首选 provider 解析和简单 CLI 标志接线的轻量认证选项元数据。 | -| `contracts` | 否 | `object` | 用于 speech、实时转录、实时语音、媒体理解、图像生成、视频生成、网页抓取、网页搜索及工具归属的静态内置能力快照。 | -| `channelConfigs` | 否 | `Record` | 由清单拥有的渠道配置元数据,会在运行时加载前合并到发现和校验界面中。 | -| `skills` | 否 | `string[]` | 要加载的 Skills 目录,相对于插件根目录。 | -| `name` | 否 | `string` | 人类可读的插件名称。 | -| `description` | 否 | `string` | 显示在插件界面中的简短摘要。 | -| `version` | 否 | `string` | 仅供参考的插件版本。 | -| `uiHints` | 否 | `Record` | 配置字段的 UI 标签、占位符和敏感性提示。 | +| 字段 | 必需 | 类型 | 含义 | +| ----------------------------------- | ---- | -------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | +| `id` | 是 | `string` | 规范插件 id。这是 `plugins.entries.` 中使用的 id。 | +| `configSchema` | 是 | `object` | 此插件配置的内联 JSON Schema。 | +| `enabledByDefault` | 否 | `true` | 将某个内置插件标记为默认启用。省略它,或设置为任何非 `true` 的值,则该插件默认禁用。 | +| `legacyPluginIds` | 否 | `string[]` | 会规范化到这个规范插件 id 的旧版 id。 | +| `autoEnableWhenConfiguredProviders` | 否 | `string[]` | 当认证、配置或模型引用提到这些提供商 id 时,应自动启用此插件。 | +| `kind` | 否 | `"memory"` \| `"context-engine"` | 声明一个由 `plugins.slots.*` 使用的互斥插件类型。 | +| `channels` | 否 | `string[]` | 此插件拥有的渠道 id。用于发现和配置校验。 | +| `providers` | 否 | `string[]` | 此插件拥有的提供商 id。 | +| `modelSupport` | 否 | `object` | 由清单持有的简写模型家族元数据,用于在运行时之前自动加载插件。 | +| `providerAuthEnvVars` | 否 | `Record` | OpenClaw 可在不加载插件代码的情况下检查的轻量级提供商认证环境变量元数据。 | +| `providerAuthChoices` | 否 | `object[]` | 用于新手引导选择器、首选提供商解析和简单 CLI flag 接线的轻量级认证选项元数据。 | +| `contracts` | 否 | `object` | 用于语音、实时转录、实时语音、媒体理解、图像生成、视频生成、网页抓取、网页搜索和工具归属的静态内置能力快照。 | +| `channelConfigs` | 否 | `Record` | 由清单持有的渠道配置元数据,在运行时加载前合并到发现和校验表面。 | +| `skills` | 否 | `string[]` | 要加载的 skill 目录,相对于插件根目录。 | +| `name` | 否 | `string` | 人类可读的插件名称。 | +| `description` | 否 | `string` | 显示在插件相关表面中的简短摘要。 | +| `version` | 否 | `string` | 仅供参考的插件版本。 | +| `uiHints` | 否 | `Record` | 配置字段的 UI 标签、占位符和敏感性提示。 | -## providerAuthChoices 参考 +## `providerAuthChoices` 参考 每个 `providerAuthChoices` 条目描述一个新手引导或认证选项。 -OpenClaw 会在 provider 运行时加载前读取它。 +OpenClaw 会在提供商运行时加载之前读取它。 -| 字段 | 必需 | 类型 | 含义 | -| --------------------- | ---- | ----------------------------------------------- | ---------------------------------------------------------------------------------------- | -| `provider` | 是 | `string` | 此选项所属的 provider id。 | -| `method` | 是 | `string` | 要分发到的认证方式 id。 | -| `choiceId` | 是 | `string` | 新手引导和 CLI 流程使用的稳定认证选项 id。 | -| `choiceLabel` | 否 | `string` | 面向用户的标签。如省略,OpenClaw 会回退到 `choiceId`。 | -| `choiceHint` | 否 | `string` | 选择器中的简短辅助文本。 | -| `assistantPriority` | 否 | `number` | 在由助手驱动的交互式选择器中,值越小排序越靠前。 | -| `assistantVisibility` | 否 | `"visible"` \| `"manual-only"` | 在助手选择器中隐藏该选项,但仍允许手动 CLI 选择。 | -| `deprecatedChoiceIds` | 否 | `string[]` | 应将用户重定向到该替代选项的旧 choice id。 | -| `groupId` | 否 | `string` | 用于对相关选项分组的可选组 id。 | -| `groupLabel` | 否 | `string` | 该分组的面向用户标签。 | -| `groupHint` | 否 | `string` | 该分组的简短辅助文本。 | -| `optionKey` | 否 | `string` | 用于简单单标志认证流程的内部选项键。 | -| `cliFlag` | 否 | `string` | CLI 标志名称,例如 `--openrouter-api-key`。 | -| `cliOption` | 否 | `string` | 完整 CLI 选项形式,例如 `--openrouter-api-key `。 | -| `cliDescription` | 否 | `string` | CLI 帮助中使用的描述。 | -| `onboardingScopes` | 否 | `Array<"text-inference" \| "image-generation">` | 该选项应显示在哪些新手引导界面中。如省略,默认值为 `["text-inference"]`。 | +| 字段 | 必需 | 类型 | 含义 | +| --------------------- | ---- | ----------------------------------------------- | ------------------------------------------------------------------ | +| `provider` | 是 | `string` | 此选项所属的提供商 id。 | +| `method` | 是 | `string` | 要分发到的认证方法 id。 | +| `choiceId` | 是 | `string` | 供新手引导和 CLI 流程使用的稳定认证选项 id。 | +| `choiceLabel` | 否 | `string` | 面向用户的标签。如果省略,OpenClaw 会回退到 `choiceId`。 | +| `choiceHint` | 否 | `string` | 选择器中的简短辅助文本。 | +| `assistantPriority` | 否 | `number` | 数值越小,在由助手驱动的交互式选择器中排序越靠前。 | +| `assistantVisibility` | 否 | `"visible"` \| `"manual-only"` | 在助手选择器中隐藏该选项,但仍允许通过手动 CLI 进行选择。 | +| `deprecatedChoiceIds` | 否 | `string[]` | 应将用户重定向到此替代选项的旧版选项 id。 | +| `groupId` | 否 | `string` | 用于对相关选项分组的可选分组 id。 | +| `groupLabel` | 否 | `string` | 该分组的面向用户标签。 | +| `groupHint` | 否 | `string` | 该分组的简短辅助文本。 | +| `optionKey` | 否 | `string` | 用于简单单 flag 认证流程的内部选项键。 | +| `cliFlag` | 否 | `string` | CLI flag 名称,例如 `--openrouter-api-key`。 | +| `cliOption` | 否 | `string` | 完整 CLI 选项形式,例如 `--openrouter-api-key `。 | +| `cliDescription` | 否 | `string` | CLI 帮助中使用的描述。 | +| `onboardingScopes` | 否 | `Array<"text-inference" \| "image-generation">` | 该选项应出现在哪些新手引导表面中。如果省略,默认值为 `["text-inference"]`。 | -## uiHints 参考 +## `uiHints` 参考 -`uiHints` 是一个从配置字段名映射到小型渲染提示的映射表。 +`uiHints` 是从配置字段名映射到小型渲染提示的映射表。 ```json { @@ -186,20 +195,21 @@ OpenClaw 会在 provider 运行时加载前读取它。 } ``` -每个字段提示可包含: +每个字段提示可以包括: -| 字段 | 类型 | 含义 | -| ------------- | ---------- | ------------------------ | -| `label` | `string` | 面向用户的字段标签。 | -| `help` | `string` | 简短辅助文本。 | -| `tags` | `string[]` | 可选 UI 标签。 | -| `advanced` | `boolean` | 将字段标记为高级选项。 | -| `sensitive` | `boolean` | 将字段标记为密钥或敏感项。 | -| `placeholder` | `string` | 表单输入的占位文本。 | +| 字段 | 类型 | 含义 | +| ------------- | ---------- | ---------------------------- | +| `label` | `string` | 面向用户的字段标签。 | +| `help` | `string` | 简短辅助文本。 | +| `tags` | `string[]` | 可选的 UI 标签。 | +| `advanced` | `boolean` | 将该字段标记为高级字段。 | +| `sensitive` | `boolean` | 将该字段标记为秘密或敏感项。 | +| `placeholder` | `string` | 表单输入的占位文本。 | -## contracts 参考 +## `contracts` 参考 -仅当 OpenClaw 需要在不导入插件运行时的情况下读取静态能力归属元数据时,才使用 `contracts`。 +仅在 `contracts` 中放置 OpenClaw 可在不导入插件运行时的情况下 +读取的静态能力归属元数据。 ```json { @@ -219,21 +229,21 @@ OpenClaw 会在 provider 运行时加载前读取它。 每个列表都是可选的: -| 字段 | 类型 | 含义 | -| -------------------------------- | ---------- | ------------------------------------------------ | -| `speechProviders` | `string[]` | 该插件拥有的 speech provider id。 | -| `realtimeTranscriptionProviders` | `string[]` | 该插件拥有的实时转录 provider id。 | -| `realtimeVoiceProviders` | `string[]` | 该插件拥有的实时语音 provider id。 | -| `mediaUnderstandingProviders` | `string[]` | 该插件拥有的媒体理解 provider id。 | -| `imageGenerationProviders` | `string[]` | 该插件拥有的图像生成 provider id。 | -| `videoGenerationProviders` | `string[]` | 该插件拥有的视频生成 provider id。 | -| `webFetchProviders` | `string[]` | 该插件拥有的网页抓取 provider id。 | -| `webSearchProviders` | `string[]` | 该插件拥有的网页搜索 provider id。 | -| `tools` | `string[]` | 该插件拥有的智能体工具名称,用于内置契约检查。 | +| 字段 | 类型 | 含义 | +| -------------------------------- | ---------- | -------------------------------------- | +| `speechProviders` | `string[]` | 此插件拥有的语音提供商 id。 | +| `realtimeTranscriptionProviders` | `string[]` | 此插件拥有的实时转录提供商 id。 | +| `realtimeVoiceProviders` | `string[]` | 此插件拥有的实时语音提供商 id。 | +| `mediaUnderstandingProviders` | `string[]` | 此插件拥有的媒体理解提供商 id。 | +| `imageGenerationProviders` | `string[]` | 此插件拥有的图像生成提供商 id。 | +| `videoGenerationProviders` | `string[]` | 此插件拥有的视频生成提供商 id。 | +| `webFetchProviders` | `string[]` | 此插件拥有的网页抓取提供商 id。 | +| `webSearchProviders` | `string[]` | 此插件拥有的网页搜索提供商 id。 | +| `tools` | `string[]` | 此插件拥有的智能体工具名称,用于内置合同检查。 | -## channelConfigs 参考 +## `channelConfigs` 参考 -当渠道插件需要在运行时加载前提供轻量配置元数据时,请使用 `channelConfigs`。 +当渠道插件需要在运行时加载前获得轻量级配置元数据时,请使用 `channelConfigs`。 ```json { @@ -260,19 +270,21 @@ OpenClaw 会在 provider 运行时加载前读取它。 } ``` -每个渠道条目可包含: +每个渠道条目可以包括: -| 字段 | 类型 | 含义 | -| ------------- | ------------------------ | ---------------------------------------------------------------------------------------- | -| `schema` | `object` | `channels.` 的 JSON Schema。每个已声明的渠道配置条目都必须提供。 | -| `uiHints` | `Record` | 该渠道配置区块可选的 UI 标签/占位符/敏感性提示。 | -| `label` | `string` | 当运行时元数据尚未就绪时,合并到选择器和检查界面的渠道标签。 | -| `description` | `string` | 用于检查和目录界面的简短渠道描述。 | -| `preferOver` | `string[]` | 在选择界面中应优先于的旧版或较低优先级插件 id。 | +| 字段 | 类型 | 含义 | +| ------------- | ------------------------ | -------------------------------------------------------------------- | +| `schema` | `object` | `channels.` 的 JSON Schema。每个声明的渠道配置条目都必须提供。 | +| `uiHints` | `Record` | 该渠道配置部分的可选 UI 标签/占位符/敏感性提示。 | +| `label` | `string` | 当运行时元数据尚未准备好时,合并到选择器和检查表面中的渠道标签。 | +| `description` | `string` | 用于检查和目录表面的简短渠道描述。 | +| `preferOver` | `string[]` | 在选择表面中,此渠道应优先于的旧版或较低优先级插件 id。 | -## modelSupport 参考 +## `modelSupport` 参考 -当 OpenClaw 需要在插件运行时加载前,根据 `gpt-5.4` 或 `claude-sonnet-4.6` 这样的简写模型 id 推断你的 provider 插件时,请使用 `modelSupport`。 +当 OpenClaw 需要从诸如 `gpt-5.4` 或 `claude-sonnet-4.6` 之类的 +简写模型 id 中推断你的提供商插件,并且这一过程发生在插件运行时 +加载之前时,请使用 `modelSupport`。 ```json { @@ -283,97 +295,118 @@ OpenClaw 会在 provider 运行时加载前读取它。 } ``` -OpenClaw 会按以下优先级应用: +OpenClaw 按以下优先级应用规则: -- 显式的 `provider/model` 引用会使用所属 `providers` 清单元数据 +- 显式的 `provider/model` 引用使用拥有该提供商的 `providers` 清单元数据 - `modelPatterns` 优先于 `modelPrefixes` -- 如果一个非内置插件和一个内置插件都匹配,则非内置插件胜出 -- 如果仍有歧义,在用户或配置明确指定 provider 之前将忽略该歧义 +- 如果一个非内置插件和一个内置插件都匹配,则非内置 + 插件胜出 +- 对于剩余的歧义,在用户或配置明确指定提供商之前会被忽略 字段: -| 字段 | 类型 | 含义 | -| --------------- | ---------- | ------------------------------------------------------------------------------- | -| `modelPrefixes` | `string[]` | 对简写模型 id 使用 `startsWith` 匹配的前缀。 | -| `modelPatterns` | `string[]` | 在移除配置后缀后,对简写模型 id 进行匹配的正则表达式源码。 | +| 字段 | 类型 | 含义 | +| --------------- | ---------- | --------------------------------------------------------------------- | +| `modelPrefixes` | `string[]` | 对简写模型 id 使用 `startsWith` 进行匹配的前缀。 | +| `modelPatterns` | `string[]` | 在移除配置文件后缀后,对简写模型 id 进行匹配的正则表达式源码。 | -旧的顶层能力键已废弃。请使用 `openclaw doctor --fix` 将 +旧版顶层能力键已弃用。使用 `openclaw doctor --fix` 将 `speechProviders`、`realtimeTranscriptionProviders`、 `realtimeVoiceProviders`、`mediaUnderstandingProviders`、 `imageGenerationProviders`、`videoGenerationProviders`、 -`webFetchProviders` 和 `webSearchProviders` 移动到 `contracts` 下; -常规清单加载已不再将这些顶层字段视为能力归属。 +`webFetchProviders` 和 `webSearchProviders` 移动到 `contracts` 下;普通 +清单加载已不再将这些顶层字段视为能力归属。 -## Manifest 与 package.json 的区别 +## 清单与 `package.json` 的区别 -这两个文件承担不同职责: +这两个文件承担的职责不同: -| 文件 | 用途 | -| ---------------------- | --------------------------------------------------------------------------------------------------------------------------- | -| `openclaw.plugin.json` | 发现、配置校验、认证选项元数据,以及必须在插件代码运行前就存在的 UI 提示 | -| `package.json` | npm 元数据、依赖安装,以及用于入口点、安装门控、设置或目录元数据的 `openclaw` 配置块 | +| 文件 | 用途 | +| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | +| `openclaw.plugin.json` | 发现、配置校验、认证选项元数据,以及必须在插件代码运行前就存在的 UI 提示 | +| `package.json` | npm 元数据、依赖安装,以及用于入口点、安装门控、设置或目录元数据的 `openclaw` 配置块 | -如果你不确定某项元数据该放在哪里,请使用这条规则: +如果你不确定某段元数据该放在哪里,请使用这条规则: -- 如果 OpenClaw 必须在加载插件代码之前知道它,就把它放在 `openclaw.plugin.json` -- 如果它与打包、入口文件或 npm 安装行为有关,就把它放在 `package.json` +- 如果 OpenClaw 必须在加载插件代码之前知道它,就把它放进 `openclaw.plugin.json` +- 如果它与打包、入口文件或 npm 安装行为有关,就把它放进 `package.json` -### 影响发现流程的 package.json 字段 +### 会影响发现的 `package.json` 字段 -某些运行时前插件元数据会有意放在 `package.json` 的 `openclaw` 配置块下,而不是 `openclaw.plugin.json` 中。 +某些运行前插件元数据有意放在 `package.json` 的 +`openclaw` 配置块下,而不是 `openclaw.plugin.json` 中。 重要示例: -| 字段 | 含义 | -| ----------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | -| `openclaw.extensions` | 声明原生插件入口点。 | -| `openclaw.setupEntry` | 在新手引导和延迟渠道启动期间使用的轻量级仅设置入口点。 | -| `openclaw.channel` | 轻量渠道目录元数据,如标签、文档路径、别名和选择文案。 | -| `openclaw.install.npmSpec` / `openclaw.install.localPath` | 用于内置和外部发布插件的安装/更新提示。 | -| `openclaw.install.defaultChoice` | 当存在多个安装来源时的首选安装路径。 | -| `openclaw.install.minHostVersion` | 最低支持的 OpenClaw 主机版本,使用如 `>=2026.3.22` 这样的 semver 下限。 | -| `openclaw.install.allowInvalidConfigRecovery` | 当配置无效时,允许受限的内置插件重新安装恢复路径。 | -| `openclaw.startup.deferConfiguredChannelFullLoadUntilAfterListen` | 允许仅设置的渠道界面在启动时于完整渠道插件之前加载。 | +| 字段 | 含义 | +| ----------------------------------------------------------------- | ------------------------------------------------------------------------------------- | +| `openclaw.extensions` | 声明原生插件入口点。 | +| `openclaw.setupEntry` | 轻量级、仅用于设置的入口点,用于新手引导和延迟的渠道启动。 | +| `openclaw.channel` | 轻量级渠道目录元数据,例如标签、文档路径、别名和选择文案。 | +| `openclaw.install.npmSpec` / `openclaw.install.localPath` | 为内置插件和外部发布插件提供安装/更新提示。 | +| `openclaw.install.defaultChoice` | 当有多个安装来源可用时的首选安装路径。 | +| `openclaw.install.minHostVersion` | 最低支持的 OpenClaw 主机版本,使用类似 `>=2026.3.22` 的 semver 下限。 | +| `openclaw.install.allowInvalidConfigRecovery` | 当配置无效时,允许狭义的内置插件重装恢复路径。 | +| `openclaw.startup.deferConfiguredChannelFullLoadUntilAfterListen` | 允许仅设置用的渠道表面在启动时于完整渠道插件之前加载。 | -`openclaw.install.minHostVersion` 会在安装期间和清单注册表加载时强制执行。无效值会被拒绝;对于较旧主机,较新但有效的值会跳过该插件。 +`openclaw.install.minHostVersion` 会在安装期间和清单 +注册表加载期间强制执行。无效值会被拒绝;有效但更高的值会在旧主机上 +跳过该插件。 -`openclaw.install.allowInvalidConfigRecovery` 的范围是有意收窄的。它不会让任意损坏的配置变得可安装。当前它仅允许安装流程从特定的旧版内置插件升级失败中恢复,例如缺失的内置插件路径,或该同一内置插件对应的旧 `channels.` 条目。无关的配置错误仍会阻止安装,并将操作员引导到 `openclaw doctor --fix`。 +`openclaw.install.allowInvalidConfigRecovery` 的设计范围刻意很窄。它 +不会让任意损坏的配置都变得可安装。目前它只允许安装 +流程从特定的陈旧内置插件升级失败中恢复,例如缺失的内置插件路径, +或同一内置插件的陈旧 `channels.` 条目。无关的配置错误仍会阻止安装, +并将操作员引导到 `openclaw doctor --fix`。 ## JSON Schema 要求 - **每个插件都必须提供一个 JSON Schema**,即使它不接受任何配置。 -- 可以使用空 schema(例如 `{ "type": "object", "additionalProperties": false }`)。 -- Schema 会在配置读写时校验,而不是在运行时校验。 +- 空 schema 也是可以接受的(例如 `{ "type": "object", "additionalProperties": false }`)。 +- Schema 会在配置读取/写入时校验,而不是在运行时校验。 ## 校验行为 -- 未知的 `channels.*` 键将被视为**错误**,除非该渠道 id 已由某个插件清单声明。 +- 未知的 `channels.*` 键会被视为**错误**,除非该渠道 id 已由 + 某个插件清单声明。 - `plugins.entries.`、`plugins.allow`、`plugins.deny` 和 `plugins.slots.*` - 必须引用**可发现的**插件 id。未知 id 将被视为**错误**。 -- 如果插件已安装,但其清单或 schema 缺失或损坏,校验会失败,Doctor 会报告该插件错误。 -- 如果插件配置存在,但插件已**禁用**,配置会被保留,并在 Doctor + 日志中显示**警告**。 + 必须引用**可发现的**插件 id。未知 id 会被视为**错误**。 +- 如果插件已安装,但其清单或 schema 损坏或缺失, + 校验将失败,Doctor 会报告该插件错误。 +- 如果插件配置存在,但插件被**禁用**,配置会被保留,并且 + Doctor + 日志中会显示一条**警告**。 -完整 `plugins.*` schema 请参见 [Configuration reference](/gateway/configuration)。 +完整的 `plugins.*` schema 请参见 [Configuration reference](/zh-CN/gateway/configuration)。 ## 说明 -- **原生 OpenClaw 插件必须提供该清单**,包括从本地文件系统加载的情况。 -- 运行时仍会单独加载插件模块;清单仅用于发现 + 校验。 -- 原生清单使用 JSON5 解析,因此注释、尾随逗号和未加引号的键都是允许的,只要最终值仍是一个对象。 -- 清单加载器只会读取文档中说明的清单字段。避免在这里添加自定义顶层键。 -- `providerAuthEnvVars` 是用于认证探测、环境变量标记校验以及类似 provider 认证界面的轻量元数据路径,这些场景不应仅为检查环境变量名而启动插件运行时。 -- `providerAuthChoices` 是用于认证选项选择器、`--auth-choice` 解析、首选 provider 映射,以及在 provider 运行时加载前进行简单新手引导 CLI 标志注册的轻量元数据路径。对于需要 provider 代码的运行时向导元数据,请参见 - [Provider runtime hooks](/plugins/architecture#provider-runtime-hooks)。 -- 互斥插件类型通过 `plugins.slots.*` 选择。 - - `kind: "memory"` 通过 `plugins.slots.memory` 选择。 - - `kind: "context-engine"` 通过 `plugins.slots.contextEngine` +- 清单对于**原生 OpenClaw 插件**是**必需的**,包括本地文件系统加载。 +- 运行时仍会单独加载插件模块;清单仅用于 + 发现 + 校验。 +- 原生清单使用 JSON5 解析,因此只要最终值仍是对象, + 注释、尾随逗号和未加引号的键都是允许的。 +- 清单加载器只会读取文档中说明的清单字段。避免在这里添加 + 自定义顶层键。 +- `providerAuthEnvVars` 是用于认证探测、环境变量标记 + 校验以及类似提供商认证表面的轻量级元数据路径,这些场景不应仅为检查环境变量名而启动插件 + 运行时。 +- `providerAuthChoices` 是用于认证选项选择器、 + `--auth-choice` 解析、首选提供商映射以及在提供商运行时加载前进行简单新手引导 + CLI flag 注册的轻量级元数据路径。对于需要提供商代码的运行时向导 + 元数据,请参见 + [Provider runtime hooks](/zh-CN/plugins/architecture#provider-runtime-hooks)。 +- 互斥插件类型通过 `plugins.slots.*` 进行选择。 + - `kind: "memory"` 由 `plugins.slots.memory` 选择。 + - `kind: "context-engine"` 由 `plugins.slots.contextEngine` 选择(默认:内置 `legacy`)。 -- 当插件不需要时,`channels`、`providers`、`cliBackends` 和 `skills` 可以省略。 -- 如果你的插件依赖原生模块,请记录构建步骤以及任何包管理器允许列表要求(例如 pnpm `allow-build-scripts` +- 当插件不需要它们时, + `channels`、`providers` 和 `skills` 可以省略。 +- 如果你的插件依赖原生模块,请记录构建步骤以及任何 + 包管理器允许列表要求(例如 pnpm `allow-build-scripts` - `pnpm rebuild `)。 ## 相关内容 -- [Building Plugins](/plugins/building-plugins) — 插件入门指南 -- [Plugin Architecture](/plugins/architecture) — 内部架构 -- [SDK Overview](/plugins/sdk-overview) — 插件 SDK 概览 +- [Building Plugins](/zh-CN/plugins/building-plugins) —— 插件入门指南 +- [Plugin Architecture](/zh-CN/plugins/architecture) —— 内部架构 +- [SDK Overview](/zh-CN/plugins/sdk-overview) —— 插件 SDK 概览 diff --git a/docs/zh-CN/plugins/sdk-overview.md b/docs/zh-CN/plugins/sdk-overview.md index 83f497e57..a5565bfd1 100644 --- a/docs/zh-CN/plugins/sdk-overview.md +++ b/docs/zh-CN/plugins/sdk-overview.md @@ -1,53 +1,53 @@ --- read_when: - 你需要知道应从哪个 SDK 子路径导入 - - 你想查阅 OpenClawPluginApi 上所有注册方法的参考 + - 你想查看 OpenClawPluginApi 上所有注册方法的参考 - 你正在查找某个特定的 SDK 导出 sidebarTitle: SDK Overview summary: 导入映射、注册 API 参考和 SDK 架构 title: 插件 SDK 概览 x-i18n: - generated_at: "2026-04-05T17:48:58Z" + generated_at: "2026-04-05T18:15:07Z" model: gpt-5.4 provider: openai - source_hash: f6e28e0e41430eba03a1cd11df15fd81bfaa1afb8c11d419554729d55c842b7d + source_hash: d70ea8cc1343b2dc1b4243b0562d19bebb1fdf7eb5065220b17e87cfd8aecc3e source_path: plugins/sdk-overview.md workflow: 15 --- # 插件 SDK 概览 -插件 SDK 是插件与核心之间的类型化契约。本页是关于**该导入什么**以及**你可以注册什么**的参考。 +插件 SDK 是插件与核心之间的类型化契约。本页是关于**导入什么**以及**你可以注册什么**的参考。 **在找操作指南吗?** - 第一个插件?从 [入门指南](/zh-CN/plugins/building-plugins) 开始 - - 渠道插件?请参阅 [渠道插件](/zh-CN/plugins/sdk-channel-plugins) - - 提供商插件?请参阅 [提供商插件](/zh-CN/plugins/sdk-provider-plugins) + - 渠道插件?参见 [渠道插件](/zh-CN/plugins/sdk-channel-plugins) + - 提供商插件?参见 [提供商插件](/zh-CN/plugins/sdk-provider-plugins) ## 导入约定 -始终从特定子路径导入: +始终从具体子路径导入: ```typescript import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry"; import { defineChannelPluginEntry } from "openclaw/plugin-sdk/channel-core"; ``` -每个子路径都是一个小型、自包含模块。这样可以保持快速启动,并防止循环依赖问题。对于特定于渠道的入口 / 构建辅助函数,优先使用 `openclaw/plugin-sdk/channel-core`;将 `openclaw/plugin-sdk/core` 保留给更广泛的总入口表面和共享辅助函数,例如 `buildChannelConfigSchema`。 +每个子路径都是一个小型、独立的模块。这样可以保持启动快速,并防止循环依赖问题。对于渠道专用的入口 / 构建辅助函数,优先使用 `openclaw/plugin-sdk/channel-core`;将 `openclaw/plugin-sdk/core` 保留给更广泛的总入口接口和共享辅助函数,例如 `buildChannelConfigSchema`。 -不要添加或依赖以提供商命名的便捷接缝,例如 `openclaw/plugin-sdk/slack`、`openclaw/plugin-sdk/discord`、`openclaw/plugin-sdk/signal`、`openclaw/plugin-sdk/whatsapp`,或带有渠道品牌的辅助接缝。内置插件应在其自己的 `api.ts` 或 `runtime-api.ts` barrel 中组合通用 SDK 子路径;而核心应使用这些插件本地 barrel,或者仅当需求确实跨渠道时再添加一个狭窄的通用 SDK 契约。 +不要添加或依赖以提供商命名的便捷扩展点,例如 `openclaw/plugin-sdk/slack`、`openclaw/plugin-sdk/discord`、`openclaw/plugin-sdk/signal`、`openclaw/plugin-sdk/whatsapp`,或带有渠道品牌的辅助扩展点。内置插件应在它们自己的 `api.ts` 或 `runtime-api.ts` barrel 中组合通用 SDK 子路径;而核心则应使用这些插件本地的 barrel,或者在需求确实跨渠道时新增一个窄而通用的 SDK 契约。 -生成的导出映射仍包含一小组内置插件辅助接缝,例如 `plugin-sdk/feishu`、`plugin-sdk/feishu-setup`、`plugin-sdk/zalo`、`plugin-sdk/zalo-setup` 和 `plugin-sdk/matrix*`。这些子路径仅为内置插件维护和兼容性而存在;它们在下方常用表中被有意省略,也不是新的第三方插件推荐使用的导入路径。 +生成的导出映射仍包含少量内置插件辅助扩展点,例如 `plugin-sdk/feishu`、`plugin-sdk/feishu-setup`、`plugin-sdk/zalo`、`plugin-sdk/zalo-setup` 以及 `plugin-sdk/matrix*`。这些子路径仅用于内置插件维护和兼容性;它们有意未出现在下方的常用表格中,也不是新第三方插件推荐使用的导入路径。 ## 子路径参考 -以下是最常用的子路径,按用途分组。完整的 200 多个子路径生成列表位于 `scripts/lib/plugin-sdk-entrypoints.json`。 +以下按用途分组列出了最常用的子路径。完整的 200+ 子路径生成列表位于 `scripts/lib/plugin-sdk-entrypoints.json`。 -保留的内置插件辅助子路径仍会出现在该生成列表中。除非某个文档页面明确将其作为公开接口推荐,否则请将它们视为实现细节 / 兼容性表面。 +保留的内置插件辅助子路径仍会出现在该生成列表中。除非某个文档页面明确将其提升为公共接口,否则请将它们视为实现细节 / 兼容性接口。 -### 插件入口点 +### 插件入口 | 子路径 | 关键导出 | | --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | @@ -63,40 +63,40 @@ import { defineChannelPluginEntry } from "openclaw/plugin-sdk/channel-core"; | `plugin-sdk/channel-core` | `defineChannelPluginEntry`, `defineSetupPluginEntry`, `createChatChannelPlugin`, `createChannelPluginBase` | | `plugin-sdk/config-schema` | 根 `openclaw.json` Zod schema 导出(`OpenClawSchema`) | | `plugin-sdk/channel-setup` | `createOptionalChannelSetupSurface`, `createOptionalChannelSetupAdapter`, `createOptionalChannelSetupWizard`,以及 `DEFAULT_ACCOUNT_ID`, `createTopLevelChannelDmPolicy`, `setSetupChannelEnabled`, `splitSetupEntries` | - | `plugin-sdk/setup` | 共享的设置向导辅助函数、允许列表提示、设置状态构建器 | + | `plugin-sdk/setup` | 共享设置向导辅助函数、allowlist 提示、设置状态构建器 | | `plugin-sdk/setup-runtime` | `createPatchedAccountSetupAdapter`, `createEnvPatchedAccountSetupAdapter`, `createSetupInputPresenceValidator`, `noteChannelLookupFailure`, `noteChannelLookupSummary`, `promptResolvedAllowFrom`, `splitSetupEntries`, `createAllowlistSetupWizardProxy`, `createDelegatedSetupWizardProxy` | | `plugin-sdk/setup-adapter-runtime` | `createEnvPatchedAccountSetupAdapter` | | `plugin-sdk/setup-tools` | `formatCliCommand`, `detectBinary`, `extractArchive`, `resolveBrewExecutable`, `formatDocsLink`, `CONFIG_DIR` | | `plugin-sdk/account-core` | 多账户配置 / 操作门控辅助函数、默认账户回退辅助函数 | - | `plugin-sdk/account-id` | `DEFAULT_ACCOUNT_ID`、账户 ID 标准化辅助函数 | + | `plugin-sdk/account-id` | `DEFAULT_ACCOUNT_ID`、account-id 规范化辅助函数 | | `plugin-sdk/account-resolution` | 账户查找 + 默认回退辅助函数 | - | `plugin-sdk/account-helpers` | 狭义的账户列表 / 账户操作辅助函数 | + | `plugin-sdk/account-helpers` | 窄范围的账户列表 / 账户操作辅助函数 | | `plugin-sdk/channel-pairing` | `createChannelPairingController` | | `plugin-sdk/channel-reply-pipeline` | `createChannelReplyPipeline` | | `plugin-sdk/channel-config-helpers` | `createHybridChannelConfigAdapter` | | `plugin-sdk/channel-config-schema` | 渠道配置 schema 类型 | - | `plugin-sdk/telegram-command-config` | 带有内置契约回退的 Telegram 自定义命令标准化 / 校验辅助函数 | + | `plugin-sdk/telegram-command-config` | 带有内置契约回退的 Telegram 自定义命令规范化 / 校验辅助函数 | | `plugin-sdk/channel-policy` | `resolveChannelGroupRequireMention` | | `plugin-sdk/channel-lifecycle` | `createAccountStatusSink` | - | `plugin-sdk/inbound-envelope` | 共享的入站路由 + envelope 构建辅助函数 | - | `plugin-sdk/inbound-reply-dispatch` | 共享的入站记录与分发辅助函数 | + | `plugin-sdk/inbound-envelope` | 共享入站路由 + envelope 构建辅助函数 | + | `plugin-sdk/inbound-reply-dispatch` | 共享入站记录与分发辅助函数 | | `plugin-sdk/messaging-targets` | 目标解析 / 匹配辅助函数 | - | `plugin-sdk/outbound-media` | 共享的出站媒体加载辅助函数 | + | `plugin-sdk/outbound-media` | 共享出站媒体加载辅助函数 | | `plugin-sdk/outbound-runtime` | 出站身份 / 发送委托辅助函数 | | `plugin-sdk/thread-bindings-runtime` | 线程绑定生命周期与适配器辅助函数 | - | `plugin-sdk/agent-media-payload` | 旧版智能体媒体负载构建器 | + | `plugin-sdk/agent-media-payload` | 旧版智能体媒体载荷构建器 | | `plugin-sdk/conversation-runtime` | 会话 / 线程绑定、配对和已配置绑定辅助函数 | | `plugin-sdk/runtime-config-snapshot` | 运行时配置快照辅助函数 | | `plugin-sdk/runtime-group-policy` | 运行时群组策略解析辅助函数 | - | `plugin-sdk/channel-status` | 共享的渠道状态快照 / 摘要辅助函数 | - | `plugin-sdk/channel-config-primitives` | 狭义的渠道配置 schema 基元 | + | `plugin-sdk/channel-status` | 共享渠道状态快照 / 摘要辅助函数 | + | `plugin-sdk/channel-config-primitives` | 窄范围的渠道配置 schema 基元 | | `plugin-sdk/channel-config-writes` | 渠道配置写入授权辅助函数 | - | `plugin-sdk/channel-plugin-common` | 共享的渠道插件前导导出 | - | `plugin-sdk/allowlist-config-edit` | 允许列表配置编辑 / 读取辅助函数 | - | `plugin-sdk/group-access` | 共享的群组访问决策辅助函数 | - | `plugin-sdk/direct-dm` | 共享的直接私信认证 / 守卫辅助函数 | - | `plugin-sdk/interactive-runtime` | 交互式回复负载标准化 / 归约辅助函数 | - | `plugin-sdk/channel-inbound` | 去抖动、提及匹配、envelope 辅助函数 | + | `plugin-sdk/channel-plugin-common` | 共享渠道插件前置导出 | + | `plugin-sdk/allowlist-config-edit` | Allowlist 配置编辑 / 读取辅助函数 | + | `plugin-sdk/group-access` | 共享群组访问决策辅助函数 | + | `plugin-sdk/direct-dm` | 共享直接私信认证 / 防护辅助函数 | + | `plugin-sdk/interactive-runtime` | 交互式回复载荷规范化 / 归约辅助函数 | + | `plugin-sdk/channel-inbound` | 去抖、提及匹配、envelope 辅助函数 | | `plugin-sdk/channel-send-result` | 回复结果类型 | | `plugin-sdk/channel-actions` | `createMessageToolButtonsSchema`, `createMessageToolCardSchema` | | `plugin-sdk/channel-targets` | 目标解析 / 匹配辅助函数 | @@ -108,100 +108,99 @@ import { defineChannelPluginEntry } from "openclaw/plugin-sdk/channel-core"; | 子路径 | 关键导出 | | --- | --- | | `plugin-sdk/provider-entry` | `defineSingleProviderPluginEntry` | - | `plugin-sdk/provider-setup` | 经过筛选的本地 / 自托管提供商设置辅助函数 | - | `plugin-sdk/self-hosted-provider-setup` | 聚焦 OpenAI 兼容自托管提供商的设置辅助函数 | - | `plugin-sdk/cli-backend` | CLI 后端默认值 + watchdog 常量 | - | `plugin-sdk/provider-auth-runtime` | 提供商插件的运行时 API key 解析辅助函数 | - | `plugin-sdk/provider-auth-api-key` | API key 新手引导 / 配置文件写入辅助函数 | + | `plugin-sdk/provider-setup` | 精选的本地 / 自托管提供商设置辅助函数 | + | `plugin-sdk/self-hosted-provider-setup` | 聚焦于 OpenAI 兼容自托管提供商的设置辅助函数 | + | `plugin-sdk/provider-auth-runtime` | 提供商插件的运行时 API 密钥解析辅助函数 | + | `plugin-sdk/provider-auth-api-key` | API 密钥新手引导 / profile 写入辅助函数 | | `plugin-sdk/provider-auth-result` | 标准 OAuth 认证结果构建器 | - | `plugin-sdk/provider-auth-login` | 提供商插件共享的交互式登录辅助函数 | + | `plugin-sdk/provider-auth-login` | 提供商插件的共享交互式登录辅助函数 | | `plugin-sdk/provider-env-vars` | 提供商认证环境变量查找辅助函数 | | `plugin-sdk/provider-auth` | `createProviderApiKeyAuthMethod`, `ensureApiKeyFromOptionEnvOrPrompt`, `upsertAuthProfile` | - | `plugin-sdk/provider-model-shared` | `ProviderReplayFamily`, `buildProviderReplayFamilyHooks`, `normalizeModelCompat`、共享 replay-policy 构建器、provider-endpoint 辅助函数,以及诸如 `normalizeNativeXaiModelId` 之类的模型 ID 标准化辅助函数 | + | `plugin-sdk/provider-model-shared` | `ProviderReplayFamily`, `buildProviderReplayFamilyHooks`, `normalizeModelCompat`、共享重放策略构建器、提供商端点辅助函数,以及如 `normalizeNativeXaiModelId` 之类的 model-id 规范化辅助函数 | | `plugin-sdk/provider-catalog-shared` | `findCatalogTemplate`, `buildSingleProviderApiKeyCatalog`, `supportsNativeStreamingUsageCompat`, `applyProviderNativeStreamingUsageCompat` | - | `plugin-sdk/provider-http` | 通用提供商 HTTP / endpoint 能力辅助函数 | - | `plugin-sdk/provider-web-fetch` | Web 获取提供商注册 / 缓存辅助函数 | - | `plugin-sdk/provider-web-search` | Web 搜索提供商注册 / 缓存 / 配置辅助函数 | - | `plugin-sdk/provider-tools` | `ProviderToolCompatFamily`, `buildProviderToolCompatFamilyHooks`、Gemini schema 清理 + 诊断,以及诸如 `resolveXaiModelCompatPatch` / `applyXaiModelCompat` 之类的 xAI 兼容辅助函数 | - | `plugin-sdk/provider-usage` | `fetchClaudeUsage` 及类似导出 | + | `plugin-sdk/provider-http` | 通用提供商 HTTP / 端点能力辅助函数 | + | `plugin-sdk/provider-web-fetch` | 网页抓取提供商注册 / 缓存辅助函数 | + | `plugin-sdk/provider-web-search` | 网页搜索提供商注册 / 缓存 / 配置辅助函数 | + | `plugin-sdk/provider-tools` | `ProviderToolCompatFamily`, `buildProviderToolCompatFamilyHooks`、Gemini schema 清理 + 诊断,以及如 `resolveXaiModelCompatPatch` / `applyXaiModelCompat` 之类的 xAI 兼容辅助函数 | + | `plugin-sdk/provider-usage` | `fetchClaudeUsage` 及类似函数 | | `plugin-sdk/provider-stream` | `ProviderStreamFamily`, `buildProviderStreamFamilyHooks`, `composeProviderStreamWrappers`、流包装器类型,以及共享的 Anthropic / Bedrock / Google / Kilocode / Moonshot / OpenAI / OpenRouter / Z.A.I / MiniMax / Copilot 包装器辅助函数 | | `plugin-sdk/provider-onboard` | 新手引导配置补丁辅助函数 | - | `plugin-sdk/global-singleton` | 进程本地 singleton / map / 缓存辅助函数 | + | `plugin-sdk/global-singleton` | 进程本地 singleton / map / cache 辅助函数 | | 子路径 | 关键导出 | | --- | --- | | `plugin-sdk/command-auth` | `resolveControlCommandGate`、命令注册表辅助函数、发送者授权辅助函数 | - | `plugin-sdk/approval-auth-runtime` | 审批者解析和同聊天操作认证辅助函数 | - | `plugin-sdk/approval-client-runtime` | 原生 exec 审批配置文件 / 过滤器辅助函数 | + | `plugin-sdk/approval-auth-runtime` | 审批人解析和同聊天操作认证辅助函数 | + | `plugin-sdk/approval-client-runtime` | 原生 exec 审批 profile / 过滤辅助函数 | | `plugin-sdk/approval-delivery-runtime` | 原生审批能力 / 传递适配器 | | `plugin-sdk/approval-native-runtime` | 原生审批目标 + 账户绑定辅助函数 | - | `plugin-sdk/approval-reply-runtime` | exec / 插件审批回复负载辅助函数 | + | `plugin-sdk/approval-reply-runtime` | exec / 插件审批回复载荷辅助函数 | | `plugin-sdk/command-auth-native` | 原生命令认证 + 原生会话目标辅助函数 | | `plugin-sdk/command-detection` | 共享命令检测辅助函数 | - | `plugin-sdk/command-surface` | 命令体标准化和命令表面辅助函数 | + | `plugin-sdk/command-surface` | 命令体规范化和命令表面辅助函数 | | `plugin-sdk/allow-from` | `formatAllowFromLowercase` | | `plugin-sdk/security-runtime` | 共享信任、私信门控、外部内容和密钥收集辅助函数 | - | `plugin-sdk/ssrf-policy` | 主机允许列表和私有网络 SSRF 策略辅助函数 | - | `plugin-sdk/ssrf-runtime` | pinned-dispatcher、受 SSRF 保护的 fetch,以及 SSRF 策略辅助函数 | + | `plugin-sdk/ssrf-policy` | 主机 allowlist 和私有网络 SSRF 策略辅助函数 | + | `plugin-sdk/ssrf-runtime` | 固定调度器、受 SSRF 防护的抓取以及 SSRF 策略辅助函数 | | `plugin-sdk/secret-input` | 密钥输入解析辅助函数 | - | `plugin-sdk/webhook-ingress` | webhook 请求 / 目标辅助函数 | + | `plugin-sdk/webhook-ingress` | Webhook 请求 / 目标辅助函数 | | `plugin-sdk/webhook-request-guards` | 请求体大小 / 超时辅助函数 | | 子路径 | 关键导出 | | --- | --- | - | `plugin-sdk/runtime` | 广义的运行时 / 日志 / 备份 / 插件安装辅助函数 | - | `plugin-sdk/runtime-env` | 狭义的运行时环境、logger、超时、重试和退避辅助函数 | + | `plugin-sdk/runtime` | 广义运行时 / 日志 / 备份 / 插件安装辅助函数 | + | `plugin-sdk/runtime-env` | 窄范围运行时环境、logger、超时、重试和回退辅助函数 | | `plugin-sdk/runtime-store` | `createPluginRuntimeStore` | - | `plugin-sdk/plugin-runtime` | 共享的插件命令 / hook / http / 交互式辅助函数 | - | `plugin-sdk/hook-runtime` | 共享的 webhook / 内部 hook 流水线辅助函数 | - | `plugin-sdk/lazy-runtime` | 延迟运行时导入 / 绑定辅助函数,例如 `createLazyRuntimeModule`、`createLazyRuntimeMethod` 和 `createLazyRuntimeSurface` | - | `plugin-sdk/process-runtime` | 进程 exec 辅助函数 | + | `plugin-sdk/plugin-runtime` | 共享插件命令 / hook / HTTP / 交互辅助函数 | + | `plugin-sdk/hook-runtime` | 共享 webhook / 内部 hook 管道辅助函数 | + | `plugin-sdk/lazy-runtime` | 惰性运行时导入 / 绑定辅助函数,例如 `createLazyRuntimeModule`、`createLazyRuntimeMethod` 和 `createLazyRuntimeSurface` | + | `plugin-sdk/process-runtime` | 进程执行辅助函数 | | `plugin-sdk/cli-runtime` | CLI 格式化、等待和版本辅助函数 | - | `plugin-sdk/gateway-runtime` | Gateway 网关客户端和渠道状态补丁辅助函数 | + | `plugin-sdk/gateway-runtime` | Gateway 客户端和渠道状态补丁辅助函数 | | `plugin-sdk/config-runtime` | 配置加载 / 写入辅助函数 | - | `plugin-sdk/telegram-command-config` | Telegram 命令名 / 描述标准化以及重复 / 冲突检查,即使内置 Telegram 契约表面不可用时也可使用 | - | `plugin-sdk/approval-runtime` | exec / 插件审批辅助函数、审批能力构建器、认证 / 配置文件辅助函数、原生路由 / 运行时辅助函数 | - | `plugin-sdk/reply-runtime` | 共享的入站 / 回复运行时辅助函数、分块、分发、心跳、回复规划器 | - | `plugin-sdk/reply-dispatch-runtime` | 狭义的回复分发 / 完成辅助函数 | - | `plugin-sdk/reply-history` | 共享的短窗口回复历史辅助函数,例如 `buildHistoryContext`、`recordPendingHistoryEntry` 和 `clearHistoryEntriesIfEnabled` | + | `plugin-sdk/telegram-command-config` | Telegram 命令名 / 描述规范化以及重复 / 冲突检查,即使内置 Telegram 契约接口不可用也可使用 | + | `plugin-sdk/approval-runtime` | exec / 插件审批辅助函数、审批能力构建器、认证 / profile 辅助函数、原生路由 / 运行时辅助函数 | + | `plugin-sdk/reply-runtime` | 共享入站 / 回复运行时辅助函数、分块、分发、心跳、回复规划器 | + | `plugin-sdk/reply-dispatch-runtime` | 窄范围回复分发 / 完成辅助函数 | + | `plugin-sdk/reply-history` | 共享短窗口回复历史辅助函数,例如 `buildHistoryContext`、`recordPendingHistoryEntry` 和 `clearHistoryEntriesIfEnabled` | | `plugin-sdk/reply-reference` | `createReplyReferencePlanner` | - | `plugin-sdk/reply-chunking` | 狭义的文本 / markdown 分块辅助函数 | + | `plugin-sdk/reply-chunking` | 窄范围文本 / Markdown 分块辅助函数 | | `plugin-sdk/session-store-runtime` | 会话存储路径 + updated-at 辅助函数 | | `plugin-sdk/state-paths` | 状态 / OAuth 目录路径辅助函数 | | `plugin-sdk/routing` | 路由 / 会话键 / 账户绑定辅助函数,例如 `resolveAgentRoute`、`buildAgentSessionKey` 和 `resolveDefaultAgentBoundAccountId` | - | `plugin-sdk/status-helpers` | 共享的渠道 / 账户状态摘要辅助函数、运行时状态默认值和问题元数据辅助函数 | + | `plugin-sdk/status-helpers` | 共享渠道 / 账户状态摘要辅助函数、运行时状态默认值和问题元数据辅助函数 | | `plugin-sdk/target-resolver-runtime` | 共享目标解析器辅助函数 | - | `plugin-sdk/string-normalization-runtime` | slug / 字符串标准化辅助函数 | + | `plugin-sdk/string-normalization-runtime` | slug / 字符串规范化辅助函数 | | `plugin-sdk/request-url` | 从 fetch / request 类输入中提取字符串 URL | - | `plugin-sdk/run-command` | 带超时的命令运行器,输出标准化的 stdout / stderr 结果 | - | `plugin-sdk/param-readers` | 常用工具 / CLI 参数读取器 | + | `plugin-sdk/run-command` | 带超时的命令运行器,返回规范化 stdout / stderr 结果 | + | `plugin-sdk/param-readers` | 通用工具 / CLI 参数读取器 | | `plugin-sdk/tool-send` | 从工具参数中提取规范发送目标字段 | | `plugin-sdk/temp-path` | 共享临时下载路径辅助函数 | | `plugin-sdk/logging-core` | 子系统 logger 和脱敏辅助函数 | | `plugin-sdk/markdown-table-runtime` | Markdown 表格模式辅助函数 | | `plugin-sdk/json-store` | 小型 JSON 状态读写辅助函数 | | `plugin-sdk/file-lock` | 可重入文件锁辅助函数 | - | `plugin-sdk/persistent-dedupe` | 基于磁盘的去重缓存辅助函数 | + | `plugin-sdk/persistent-dedupe` | 磁盘后备去重缓存辅助函数 | | `plugin-sdk/acp-runtime` | ACP 运行时 / 会话和回复分发辅助函数 | - | `plugin-sdk/agent-config-primitives` | 狭义的智能体运行时配置 schema 基元 | + | `plugin-sdk/agent-config-primitives` | 窄范围智能体运行时配置 schema 基元 | | `plugin-sdk/boolean-param` | 宽松布尔参数读取器 | | `plugin-sdk/dangerous-name-runtime` | 危险名称匹配解析辅助函数 | - | `plugin-sdk/device-bootstrap` | 设备引导和配对 token 辅助函数 | - | `plugin-sdk/extension-shared` | 共享的被动渠道和状态辅助基元 | + | `plugin-sdk/device-bootstrap` | 设备引导和配对令牌辅助函数 | + | `plugin-sdk/extension-shared` | 共享被动渠道和状态辅助基元 | | `plugin-sdk/models-provider-runtime` | `/models` 命令 / 提供商回复辅助函数 | | `plugin-sdk/skill-commands-runtime` | Skills 命令列表辅助函数 | - | `plugin-sdk/native-command-registry` | 原生命令注册表构建 / 序列化辅助函数 | - | `plugin-sdk/provider-zai-endpoint` | Z.A.I endpoint 检测辅助函数 | + | `plugin-sdk/native-command-registry` | 原生命令注册表 / 构建 / 序列化辅助函数 | + | `plugin-sdk/provider-zai-endpoint` | Z.A.I 端点检测辅助函数 | | `plugin-sdk/infra-runtime` | 系统事件 / 心跳辅助函数 | | `plugin-sdk/collection-runtime` | 小型有界缓存辅助函数 | | `plugin-sdk/diagnostic-runtime` | 诊断标志和事件辅助函数 | | `plugin-sdk/error-runtime` | 错误图、格式化、共享错误分类辅助函数、`isApprovalNotFoundError` | | `plugin-sdk/fetch-runtime` | 包装后的 fetch、代理和固定查找辅助函数 | - | `plugin-sdk/host-runtime` | 主机名和 SCP 主机标准化辅助函数 | + | `plugin-sdk/host-runtime` | 主机名和 SCP 主机规范化辅助函数 | | `plugin-sdk/retry-runtime` | 重试配置和重试运行器辅助函数 | | `plugin-sdk/agent-runtime` | 智能体目录 / 身份 / 工作区辅助函数 | | `plugin-sdk/directory-runtime` | 基于配置的目录查询 / 去重 | @@ -211,104 +210,103 @@ import { defineChannelPluginEntry } from "openclaw/plugin-sdk/channel-core"; | 子路径 | 关键导出 | | --- | --- | - | `plugin-sdk/media-runtime` | 共享的媒体获取 / 转换 / 存储辅助函数,以及媒体负载构建器 | + | `plugin-sdk/media-runtime` | 共享媒体抓取 / 转换 / 存储辅助函数,以及媒体载荷构建器 | | `plugin-sdk/media-understanding` | 媒体理解提供商类型,以及面向提供商的图像 / 音频辅助导出 | - | `plugin-sdk/text-runtime` | 共享的文本 / markdown / 日志辅助函数,例如对助手可见文本的剥离、markdown 渲染 / 分块 / 表格辅助函数、脱敏辅助函数、directive-tag 辅助函数和安全文本工具 | + | `plugin-sdk/text-runtime` | 共享文本 / Markdown / 日志辅助函数,例如 assistant 可见文本剥离、Markdown 渲染 / 分块 / 表格辅助函数、脱敏辅助函数、指令标签辅助函数和安全文本工具 | | `plugin-sdk/text-chunking` | 出站文本分块辅助函数 | - | `plugin-sdk/speech` | 语音提供商类型,以及面向提供商的 directive、注册表和校验辅助函数 | - | `plugin-sdk/speech-core` | 共享的语音提供商类型、注册表、directive 和标准化辅助函数 | - | `plugin-sdk/realtime-transcription` | 实时转写提供商类型和注册表辅助函数 | + | `plugin-sdk/speech` | 语音提供商类型,以及面向提供商的指令、注册表和校验辅助函数 | + | `plugin-sdk/speech-core` | 共享语音提供商类型、注册表、指令和规范化辅助函数 | + | `plugin-sdk/realtime-transcription` | 实时转录提供商类型和注册表辅助函数 | | `plugin-sdk/realtime-voice` | 实时语音提供商类型和注册表辅助函数 | | `plugin-sdk/image-generation` | 图像生成提供商类型 | - | `plugin-sdk/image-generation-core` | 共享的图像生成类型、故障转移、认证和注册表辅助函数 | + | `plugin-sdk/image-generation-core` | 共享图像生成类型、故障切换、认证和注册表辅助函数 | | `plugin-sdk/video-generation` | 视频生成提供商 / 请求 / 结果类型 | - | `plugin-sdk/video-generation-core` | 共享的视频生成类型、故障转移辅助函数、提供商查找和 model-ref 解析 | - | `plugin-sdk/webhook-targets` | webhook 目标注册表和路由安装辅助函数 | - | `plugin-sdk/webhook-path` | webhook 路径标准化辅助函数 | + | `plugin-sdk/video-generation-core` | 共享视频生成类型、故障切换辅助函数、提供商查找和 model-ref 解析 | + | `plugin-sdk/webhook-targets` | Webhook 目标注册表和路由安装辅助函数 | + | `plugin-sdk/webhook-path` | Webhook 路径规范化辅助函数 | | `plugin-sdk/web-media` | 共享远程 / 本地媒体加载辅助函数 | - | `plugin-sdk/zod` | 为插件 SDK 使用者重新导出的 `zod` | + | `plugin-sdk/zod` | 面向插件 SDK 使用者重新导出的 `zod` | | `plugin-sdk/testing` | `installCommonResolveTargetErrorCases`, `shouldAckReaction` | - + | 子路径 | 关键导出 | | --- | --- | - | `plugin-sdk/memory-core` | 内置 memory-core 辅助表面,用于 manager / config / file / CLI 辅助函数 | - | `plugin-sdk/memory-core-engine-runtime` | 记忆索引 / 搜索运行时门面 | - | `plugin-sdk/memory-core-host-engine-foundation` | 记忆宿主基础引擎导出 | - | `plugin-sdk/memory-core-host-engine-embeddings` | 记忆宿主嵌入引擎导出 | - | `plugin-sdk/memory-core-host-engine-qmd` | 记忆宿主 QMD 引擎导出 | - | `plugin-sdk/memory-core-host-engine-storage` | 记忆宿主存储引擎导出 | - | `plugin-sdk/memory-core-host-multimodal` | 记忆宿主多模态辅助函数 | - | `plugin-sdk/memory-core-host-query` | 记忆宿主查询辅助函数 | - | `plugin-sdk/memory-core-host-secret` | 记忆宿主密钥辅助函数 | - | `plugin-sdk/memory-core-host-status` | 记忆宿主状态辅助函数 | - | `plugin-sdk/memory-core-host-runtime-cli` | 记忆宿主 CLI 运行时辅助函数 | - | `plugin-sdk/memory-core-host-runtime-core` | 记忆宿主核心运行时辅助函数 | - | `plugin-sdk/memory-core-host-runtime-files` | 记忆宿主文件 / 运行时辅助函数 | - | `plugin-sdk/memory-lancedb` | 内置 memory-lancedb 辅助表面 | + | `plugin-sdk/memory-core` | 内置 memory-core 辅助接口,用于 manager / config / file / CLI 辅助函数 | + | `plugin-sdk/memory-core-engine-runtime` | Memory 索引 / 搜索运行时门面 | + | `plugin-sdk/memory-core-host-engine-foundation` | Memory host foundation 引擎导出 | + | `plugin-sdk/memory-core-host-engine-embeddings` | Memory host embedding 引擎导出 | + | `plugin-sdk/memory-core-host-engine-qmd` | Memory host QMD 引擎导出 | + | `plugin-sdk/memory-core-host-engine-storage` | Memory host 存储引擎导出 | + | `plugin-sdk/memory-core-host-multimodal` | Memory host 多模态辅助函数 | + | `plugin-sdk/memory-core-host-query` | Memory host 查询辅助函数 | + | `plugin-sdk/memory-core-host-secret` | Memory host 密钥辅助函数 | + | `plugin-sdk/memory-core-host-status` | Memory host 状态辅助函数 | + | `plugin-sdk/memory-core-host-runtime-cli` | Memory host CLI 运行时辅助函数 | + | `plugin-sdk/memory-core-host-runtime-core` | Memory host 核心运行时辅助函数 | + | `plugin-sdk/memory-core-host-runtime-files` | Memory host 文件 / 运行时辅助函数 | + | `plugin-sdk/memory-lancedb` | 内置 memory-lancedb 辅助接口 | | 家族 | 当前子路径 | 预期用途 | | --- | --- | --- | - | Browser | `plugin-sdk/browser-cdp`, `plugin-sdk/browser-config-support`, `plugin-sdk/browser-control-auth`, `plugin-sdk/browser-profiles`, `plugin-sdk/browser-support` | 内置 browser 插件支持辅助函数 | - | Matrix | `plugin-sdk/matrix`, `plugin-sdk/matrix-helper`, `plugin-sdk/matrix-runtime-heavy`, `plugin-sdk/matrix-runtime-shared`, `plugin-sdk/matrix-runtime-surface`, `plugin-sdk/matrix-surface`, `plugin-sdk/matrix-thread-bindings` | 内置 Matrix 辅助 / 运行时表面 | - | Line | `plugin-sdk/line`, `plugin-sdk/line-core`, `plugin-sdk/line-runtime`, `plugin-sdk/line-surface` | 内置 LINE 辅助 / 运行时表面 | - | IRC | `plugin-sdk/irc`, `plugin-sdk/irc-surface` | 内置 IRC 辅助表面 | - | 渠道特定辅助函数 | `plugin-sdk/googlechat`, `plugin-sdk/zalouser`, `plugin-sdk/bluebubbles`, `plugin-sdk/bluebubbles-policy`, `plugin-sdk/mattermost`, `plugin-sdk/mattermost-policy`, `plugin-sdk/feishu-conversation`, `plugin-sdk/msteams`, `plugin-sdk/nextcloud-talk`, `plugin-sdk/nostr`, `plugin-sdk/tlon`, `plugin-sdk/twitch` | 内置渠道兼容性 / 辅助接缝 | - | 认证 / 插件特定辅助函数 | `plugin-sdk/github-copilot-login`, `plugin-sdk/github-copilot-token`, `plugin-sdk/diagnostics-otel`, `plugin-sdk/diffs`, `plugin-sdk/llm-task`, `plugin-sdk/thread-ownership`, `plugin-sdk/voice-call` | 内置功能 / 插件辅助接缝;`plugin-sdk/github-copilot-token` 当前导出 `DEFAULT_COPILOT_API_BASE_URL`、`deriveCopilotApiBaseUrlFromToken` 和 `resolveCopilotApiToken` | + | Browser | `plugin-sdk/browser-cdp`, `plugin-sdk/browser-config-support`, `plugin-sdk/browser-control-auth`, `plugin-sdk/browser-profiles`, `plugin-sdk/browser-support` | 内置 Browser 插件支持辅助函数 | + | Matrix | `plugin-sdk/matrix`, `plugin-sdk/matrix-helper`, `plugin-sdk/matrix-runtime-heavy`, `plugin-sdk/matrix-runtime-shared`, `plugin-sdk/matrix-runtime-surface`, `plugin-sdk/matrix-surface`, `plugin-sdk/matrix-thread-bindings` | 内置 Matrix 辅助 / 运行时接口 | + | Line | `plugin-sdk/line`, `plugin-sdk/line-core`, `plugin-sdk/line-runtime`, `plugin-sdk/line-surface` | 内置 LINE 辅助 / 运行时接口 | + | IRC | `plugin-sdk/irc`, `plugin-sdk/irc-surface` | 内置 IRC 辅助接口 | + | 渠道专用辅助函数 | `plugin-sdk/googlechat`, `plugin-sdk/zalouser`, `plugin-sdk/bluebubbles`, `plugin-sdk/bluebubbles-policy`, `plugin-sdk/mattermost`, `plugin-sdk/mattermost-policy`, `plugin-sdk/feishu-conversation`, `plugin-sdk/msteams`, `plugin-sdk/nextcloud-talk`, `plugin-sdk/nostr`, `plugin-sdk/tlon`, `plugin-sdk/twitch` | 内置渠道兼容性 / 辅助扩展点 | + | 认证 / 插件专用辅助函数 | `plugin-sdk/github-copilot-login`, `plugin-sdk/github-copilot-token`, `plugin-sdk/diagnostics-otel`, `plugin-sdk/diffs`, `plugin-sdk/llm-task`, `plugin-sdk/thread-ownership`, `plugin-sdk/voice-call` | 内置功能 / 插件辅助扩展点;`plugin-sdk/github-copilot-token` 当前导出 `DEFAULT_COPILOT_API_BASE_URL`、`deriveCopilotApiBaseUrlFromToken` 和 `resolveCopilotApiToken` | ## 注册 API -`register(api)` 回调会收到一个 `OpenClawPluginApi` 对象,它具有以下方法: +`register(api)` 回调会收到一个 `OpenClawPluginApi` 对象,它包含以下方法: ### 能力注册 -| 方法 | 注册内容 | +| 方法 | 它注册的内容 | | ------------------------------------------------ | -------------------------------- | | `api.registerProvider(...)` | 文本推理(LLM) | -| `api.registerCliBackend(...)` | 本地 CLI 推理后端 | | `api.registerChannel(...)` | 消息渠道 | -| `api.registerSpeechProvider(...)` | 文本转语音 / STT 合成 | -| `api.registerRealtimeTranscriptionProvider(...)` | 流式实时转写 | +| `api.registerSpeechProvider(...)` | 文字转语音 / STT 合成 | +| `api.registerRealtimeTranscriptionProvider(...)` | 流式实时转录 | | `api.registerRealtimeVoiceProvider(...)` | 双工实时语音会话 | | `api.registerMediaUnderstandingProvider(...)` | 图像 / 音频 / 视频分析 | | `api.registerImageGenerationProvider(...)` | 图像生成 | | `api.registerVideoGenerationProvider(...)` | 视频生成 | -| `api.registerWebFetchProvider(...)` | Web 获取 / 抓取提供商 | -| `api.registerWebSearchProvider(...)` | Web 搜索 | +| `api.registerWebFetchProvider(...)` | 网页抓取 / scrape 提供商 | +| `api.registerWebSearchProvider(...)` | 网页搜索 | ### 工具与命令 -| 方法 | 注册内容 | +| 方法 | 它注册的内容 | | ------------------------------- | --------------------------------------------- | | `api.registerTool(tool, opts?)` | 智能体工具(必需或 `{ optional: true }`) | | `api.registerCommand(def)` | 自定义命令(绕过 LLM) | ### 基础设施 -| 方法 | 注册内容 | +| 方法 | 它注册的内容 | | ---------------------------------------------- | --------------------- | | `api.registerHook(events, handler, opts?)` | 事件 hook | -| `api.registerHttpRoute(params)` | Gateway 网关 HTTP endpoint | -| `api.registerGatewayMethod(name, handler)` | Gateway 网关 RPC 方法 | +| `api.registerHttpRoute(params)` | Gateway HTTP 端点 | +| `api.registerGatewayMethod(name, handler)` | Gateway RPC 方法 | | `api.registerCli(registrar, opts?)` | CLI 子命令 | | `api.registerService(service)` | 后台服务 | | `api.registerInteractiveHandler(registration)` | 交互式处理器 | -保留的核心管理命名空间(`config.*`、`exec.approvals.*`、`wizard.*`、`update.*`)始终保持为 `operator.admin`,即使插件尝试分配更窄的 Gateway 网关方法作用域也是如此。对于插件拥有的方法,请优先使用插件特定前缀。 +保留的核心管理命名空间(`config.*`、`exec.approvals.*`、`wizard.*`、`update.*`)始终保持为 `operator.admin`,即使插件尝试为某个 Gateway 方法指定更窄的作用域也是如此。对于插件自有方法,优先使用插件专属前缀。 ### CLI 注册元数据 `api.registerCli(registrar, opts?)` 接受两种顶层元数据: -- `commands`:由注册器拥有的显式命令根 -- `descriptors`:用于根 CLI 帮助、路由和延迟插件 CLI 注册的解析时命令描述符 +- `commands`:由 registrar 拥有的显式命令根 +- `descriptors`:用于根 CLI 帮助、路由和惰性插件 CLI 注册的解析期命令描述符 -如果你希望插件命令在正常根 CLI 路径中保持延迟加载,请提供 `descriptors`,覆盖该注册器公开的每个顶层命令根。 +如果你希望插件命令在普通根 CLI 路径中保持惰性加载,请提供覆盖该 registrar 暴露的每个顶层命令根的 `descriptors`。 ```typescript api.registerCli( @@ -320,7 +318,7 @@ api.registerCli( descriptors: [ { name: "matrix", - description: "管理 Matrix 账户、验证、设备和资料状态", + description: "Manage Matrix accounts, verification, devices, and profile state", hasSubcommands: true, }, ], @@ -328,68 +326,59 @@ api.registerCli( ); ``` -仅使用 `commands` 适用于你不需要延迟根 CLI 注册的场景。该急切兼容路径仍受支持,但不会安装由 descriptor 支持的占位符来实现解析时延迟加载。 - -### CLI 后端注册 - -`api.registerCliBackend(...)` 允许插件拥有本地 AI CLI 后端(如 `codex-cli`)的默认配置。 - -- 后端 `id` 会成为 `codex-cli/gpt-5` 这类 model ref 中的提供商前缀。 -- 后端 `config` 使用与 `agents.defaults.cliBackends.` 相同的结构。 -- 用户配置仍然优先。OpenClaw 会在运行 CLI 前,将 `agents.defaults.cliBackends.` 覆盖合并到插件默认值之上。 -- 当后端在合并后需要兼容性重写时,请使用 `normalizeConfig`(例如标准化旧版 flag 结构)。 +仅在你不需要惰性根 CLI 注册时,才单独使用 `commands`。这条急切兼容路径仍受支持,但它不会安装基于 descriptor 的占位符来实现解析期惰性加载。 ### 独占槽位 -| 方法 | 注册内容 | +| 方法 | 它注册的内容 | | ------------------------------------------ | ------------------------------------- | -| `api.registerContextEngine(id, factory)` | 上下文引擎(一次仅一个处于活动状态) | -| `api.registerMemoryPromptSection(builder)` | 记忆提示词区块构建器 | -| `api.registerMemoryFlushPlan(resolver)` | 记忆刷新计划解析器 | -| `api.registerMemoryRuntime(runtime)` | 记忆运行时适配器 | +| `api.registerContextEngine(id, factory)` | 上下文引擎(同一时间仅一个处于激活状态) | +| `api.registerMemoryPromptSection(builder)` | Memory 提示区段构建器 | +| `api.registerMemoryFlushPlan(resolver)` | Memory 刷新计划解析器 | +| `api.registerMemoryRuntime(runtime)` | Memory 运行时适配器 | -### 记忆嵌入适配器 +### Memory embedding 适配器 -| 方法 | 注册内容 | +| 方法 | 它注册的内容 | | ---------------------------------------------- | ---------------------------------------------- | -| `api.registerMemoryEmbeddingProvider(adapter)` | 活动插件的记忆嵌入适配器 | +| `api.registerMemoryEmbeddingProvider(adapter)` | 活跃插件的 Memory embedding 适配器 | -- `registerMemoryPromptSection`、`registerMemoryFlushPlan` 和 `registerMemoryRuntime` 是记忆插件专属的独占接口。 -- `registerMemoryEmbeddingProvider` 允许活动记忆插件注册一个或多个嵌入适配器 ID(例如 `openai`、`gemini` 或插件自定义 ID)。 -- 用户配置,如 `agents.defaults.memorySearch.provider` 和 `agents.defaults.memorySearch.fallback`,会基于这些已注册适配器 ID 进行解析。 +- `registerMemoryPromptSection`、`registerMemoryFlushPlan` 和 `registerMemoryRuntime` 是 Memory 插件专属的独占接口。 +- `registerMemoryEmbeddingProvider` 允许活跃的 Memory 插件注册一个或多个 embedding 适配器 id(例如 `openai`、`gemini` 或插件自定义 id)。 +- 用户配置(如 `agents.defaults.memorySearch.provider` 和 `agents.defaults.memorySearch.fallback`)会基于这些已注册的适配器 id 进行解析。 ### 事件与生命周期 -| 方法 | 作用 | +| 方法 | 它的作用 | | -------------------------------------------- | ----------------------------- | | `api.on(hookName, handler, opts?)` | 类型化生命周期 hook | -| `api.onConversationBindingResolved(handler)` | 会话绑定解析回调 | +| `api.onConversationBindingResolved(handler)` | 会话绑定回调 | -### Hook 决策语义 +### hook 决策语义 -- `before_tool_call`:返回 `{ block: true }` 是终止性决定。一旦任一处理器设置它,较低优先级的处理器将被跳过。 -- `before_tool_call`:返回 `{ block: false }` 会被视为未作决定(等同于省略 `block`),而不是覆盖。 -- `before_install`:返回 `{ block: true }` 是终止性决定。一旦任一处理器设置它,较低优先级的处理器将被跳过。 -- `before_install`:返回 `{ block: false }` 会被视为未作决定(等同于省略 `block`),而不是覆盖。 -- `reply_dispatch`:返回 `{ handled: true, ... }` 是终止性决定。一旦任一处理器声明已分发,较低优先级的处理器以及默认模型分发路径都会被跳过。 -- `message_sending`:返回 `{ cancel: true }` 是终止性决定。一旦任一处理器设置它,较低优先级的处理器将被跳过。 -- `message_sending`:返回 `{ cancel: false }` 会被视为未作决定(等同于省略 `cancel`),而不是覆盖。 +- `before_tool_call`:返回 `{ block: true }` 是终结结果。一旦任何处理器设置了它,就会跳过优先级更低的处理器。 +- `before_tool_call`:返回 `{ block: false }` 会被视为没有作出决定(等同于省略 `block`),而不是覆盖。 +- `before_install`:返回 `{ block: true }` 是终结结果。一旦任何处理器设置了它,就会跳过优先级更低的处理器。 +- `before_install`:返回 `{ block: false }` 会被视为没有作出决定(等同于省略 `block`),而不是覆盖。 +- `reply_dispatch`:返回 `{ handled: true, ... }` 是终结结果。一旦任何处理器声明已分发,就会跳过优先级更低的处理器以及默认模型分发路径。 +- `message_sending`:返回 `{ cancel: true }` 是终结结果。一旦任何处理器设置了它,就会跳过优先级更低的处理器。 +- `message_sending`:返回 `{ cancel: false }` 会被视为没有作出决定(等同于省略 `cancel`),而不是覆盖。 ### API 对象字段 -| 字段 | 类型 | 说明 | +| 字段 | 类型 | 描述 | | ------------------------ | ------------------------- | ------------------------------------------------------------------------------------------- | -| `api.id` | `string` | 插件 ID | +| `api.id` | `string` | 插件 id | | `api.name` | `string` | 显示名称 | | `api.version` | `string?` | 插件版本(可选) | -| `api.description` | `string?` | 插件说明(可选) | +| `api.description` | `string?` | 插件描述(可选) | | `api.source` | `string` | 插件源路径 | | `api.rootDir` | `string?` | 插件根目录(可选) | -| `api.config` | `OpenClawConfig` | 当前配置快照(可用时为活动内存运行时快照) | -| `api.pluginConfig` | `Record` | 来自 `plugins.entries..config` 的插件特定配置 | -| `api.runtime` | `PluginRuntime` | [运行时](/zh-CN/plugins/sdk-runtime) | +| `api.config` | `OpenClawConfig` | 当前配置快照(如果可用,则为活动内存运行时快照) | +| `api.pluginConfig` | `Record` | 来自 `plugins.entries..config` 的插件专属配置 | +| `api.runtime` | `PluginRuntime` | [运行时辅助函数](/zh-CN/plugins/sdk-runtime) | | `api.logger` | `PluginLogger` | 作用域 logger(`debug`、`info`、`warn`、`error`) | -| `api.registrationMode` | `PluginRegistrationMode` | 当前加载模式;`"setup-runtime"` 是完整入口加载前的轻量启动 / 设置窗口 | +| `api.registrationMode` | `PluginRegistrationMode` | 当前加载模式;`"setup-runtime"` 是完整入口前的轻量启动 / 设置窗口 | | `api.resolvePath(input)` | `(string) => string` | 解析相对于插件根目录的路径 | ## 内部模块约定 @@ -398,21 +387,19 @@ api.registerCli( ``` my-plugin/ - api.ts # 面向外部使用者的公开导出 - runtime-api.ts # 仅供内部使用的运行时导出 + api.ts # 面向外部使用者的公共导出 + runtime-api.ts # 仅内部使用的运行时导出 index.ts # 插件入口点 - setup-entry.ts # 轻量级仅设置入口点(可选) + setup-entry.ts # 仅设置使用的轻量入口(可选) ``` - 不要在生产代码中通过 `openclaw/plugin-sdk/` - 导入你自己的插件。内部导入应通过 `./api.ts` 或 - `./runtime-api.ts`。SDK 路径仅是对外契约。 + 不要在生产代码中通过 `openclaw/plugin-sdk/` 导入你自己的插件。请通过 `./api.ts` 或 `./runtime-api.ts` 进行内部导入。SDK 路径仅是外部契约。 -由门面加载的内置插件公开表面(`api.ts`、`runtime-api.ts`、`index.ts`、`setup-entry.ts` 以及类似公开入口文件)现在在 OpenClaw 已经运行时会优先使用活动运行时配置快照。如果运行时快照尚不存在,则会回退到磁盘上解析后的配置文件。 +由门面加载的内置插件公共接口(`api.ts`、`runtime-api.ts`、`index.ts`、`setup-entry.ts` 以及类似公共入口文件)现在会在 OpenClaw 已运行时优先使用活动运行时配置快照。如果运行时快照尚不存在,它们会回退到磁盘上解析出的配置文件。 -提供商插件也可以公开一个狭义的插件本地契约 barrel,用于那些明确具有提供商特性、但暂时还不属于通用 SDK 子路径的辅助函数。当前的内置示例:Anthropic 提供商将其 Claude 流辅助函数保留在自己的公开 `api.ts` / `contract-api.ts` 接缝中,而不是将 Anthropic beta-header 和 `service_tier` 逻辑提升到通用 `plugin-sdk/*` 契约中。 +当某个辅助函数明确是提供商专用、且暂时不属于通用 SDK 子路径时,提供商插件也可以暴露一个窄范围的插件本地契约 barrel。当前内置示例:Anthropic 提供商将其 Claude 流辅助函数保留在自己的公共 `api.ts` / `contract-api.ts` 扩展点中,而不是把 Anthropic beta-header 和 `service_tier` 逻辑提升到通用 `plugin-sdk/*` 契约中。 其他当前内置示例: @@ -420,17 +407,14 @@ my-plugin/ - `@openclaw/openrouter-provider`:`api.ts` 导出提供商构建器以及新手引导 / 配置辅助函数 - 扩展生产代码也应避免导入 `openclaw/plugin-sdk/`。 - 如果某个辅助函数确实需要共享,请将其提升到中立的 SDK 子路径, - 例如 `openclaw/plugin-sdk/speech`、`.../provider-model-shared`, - 或其他面向能力的表面,而不是让两个插件耦合在一起。 + 扩展生产代码也应避免导入 `openclaw/plugin-sdk/`。如果某个辅助函数确实需要共享,请将其提升到中立的 SDK 子路径,例如 `openclaw/plugin-sdk/speech`、`.../provider-model-shared` 或其他面向能力的接口,而不是把两个插件耦合在一起。 ## 相关内容 -- [入口点](/zh-CN/plugins/sdk-entrypoints) — `definePluginEntry` 和 `defineChannelPluginEntry` 选项 -- [运行时](/zh-CN/plugins/sdk-runtime) — 完整 `api.runtime` 命名空间参考 -- [设置和配置](/zh-CN/plugins/sdk-setup) — 打包、清单、配置 schema -- [测试](/zh-CN/plugins/sdk-testing) — 测试工具和 lint 规则 -- [SDK 迁移](/zh-CN/plugins/sdk-migration) — 从已弃用表面迁移 -- [插件内部机制](/zh-CN/plugins/architecture) — 深入架构和能力模型 +- [入口点](/zh-CN/plugins/sdk-entrypoints) —— `definePluginEntry` 和 `defineChannelPluginEntry` 选项 +- [运行时辅助函数](/zh-CN/plugins/sdk-runtime) —— 完整 `api.runtime` 命名空间参考 +- [设置与配置](/zh-CN/plugins/sdk-setup) —— 打包、清单、配置 schema +- [测试](/zh-CN/plugins/sdk-testing) —— 测试工具和 lint 规则 +- [SDK 迁移](/zh-CN/plugins/sdk-migration) —— 从已弃用接口迁移 +- [插件内部机制](/zh-CN/plugins/architecture) —— 深入架构与能力模型 diff --git a/docs/zh-CN/plugins/sdk-provider-plugins.md b/docs/zh-CN/plugins/sdk-provider-plugins.md index 49e6386b7..7a134c15f 100644 --- a/docs/zh-CN/plugins/sdk-provider-plugins.md +++ b/docs/zh-CN/plugins/sdk-provider-plugins.md @@ -1,30 +1,33 @@ --- read_when: - 你正在构建一个新的模型提供商插件 - - 你想为 OpenClaw 添加一个 OpenAI 兼容代理或自定义 LLM - - 你需要理解提供商认证、目录和运行时 hooks + - 你想为 OpenClaw 添加一个兼容 OpenAI 的代理或自定义 LLM + - 你需要了解提供商认证、目录和运行时 hooks sidebarTitle: Provider Plugins -summary: 在 OpenClaw 中构建模型提供商插件的分步指南 +summary: 为 OpenClaw 构建模型提供商插件的分步指南 title: 构建提供商插件 x-i18n: - generated_at: "2026-04-05T17:49:25Z" + generated_at: "2026-04-05T18:15:33Z" model: gpt-5.4 provider: openai - source_hash: 9411ebf96c1eef0baecee9b743925440edc6714a8947da7712fed2b9ef1405cb + source_hash: 69500f46aa2cfdfe16e85b0ed9ee3c0032074be46f2d9c9d2940d18ae1095f47 source_path: plugins/sdk-provider-plugins.md workflow: 15 --- # 构建提供商插件 -本指南将带你构建一个提供商插件,用于向 OpenClaw 添加模型提供商(LLM)。完成后,你将拥有一个带有模型目录、API key 认证和动态模型解析的提供商。 +本指南将带你构建一个向 OpenClaw 添加模型提供商 +(LLM)的提供商插件。完成后,你将拥有一个带有模型目录、 +API 密钥认证和动态模型解析能力的提供商。 如果你之前没有构建过任何 OpenClaw 插件,请先阅读 - [入门指南](/zh-CN/plugins/building-plugins) 了解基本的包结构和清单设置。 + [入门指南](/zh-CN/plugins/building-plugins),了解基本包 + 结构和清单设置。 -## 操作演练 +## 演练 @@ -83,7 +86,12 @@ x-i18n: ``` - 清单声明了 `providerAuthEnvVars`,这样 OpenClaw 就可以在不加载你的插件运行时的情况下检测凭证。`modelSupport` 是可选的,它允许 OpenClaw 在运行时 hook 存在之前,通过像 `acme-large` 这样的简写模型 id 自动加载你的提供商插件。如果你在 ClawHub 上发布该提供商,那么 `package.json` 中的这些 `openclaw.compat` 和 `openclaw.build` 字段是必需的。 + 清单声明了 `providerAuthEnvVars`,这样 OpenClaw 就可以在不加载你的插件运行时的情况下检测 + 凭证。`modelSupport` 是可选的, + 它让 OpenClaw 可以在运行时 hooks 存在之前,根据简写模型 ID + (如 `acme-large`)自动加载你的提供商插件。如果你在 + ClawHub 上发布该提供商,那么 `package.json` 中的这些 `openclaw.compat` 和 `openclaw.build` 字段 + 是必需的。 @@ -159,11 +167,13 @@ x-i18n: }); ``` - 这就是一个可工作的提供商。用户现在可以执行 + 这就是一个可工作的提供商。用户现在可以 `openclaw onboard --acme-ai-api-key `,并选择 `acme-ai/acme-large` 作为他们的模型。 - 对于只注册一个文本提供商、使用 API key 认证并带有单个目录支持运行时的内置提供商,优先使用更窄的 `defineSingleProviderPluginEntry(...)` 辅助函数: + 对于仅注册一个文本提供商、使用 API 密钥 + 认证并带有单个基于目录的运行时的内置提供商,优先使用更窄的 + `defineSingleProviderPluginEntry(...)` 辅助函数: ```typescript import { defineSingleProviderPluginEntry } from "openclaw/plugin-sdk/provider-entry"; @@ -198,14 +208,27 @@ x-i18n: }); ``` - 如果你的认证流程还需要在 onboarding 期间修补 `models.providers.*`、别名和智能体默认模型,请使用 `openclaw/plugin-sdk/provider-onboard` 中的预设辅助函数。最窄的辅助函数是 `createDefaultModelPresetAppliers(...)`、`createDefaultModelsPresetAppliers(...)` 和 `createModelCatalogPresetAppliers(...)`。 + 如果你的认证流程在新手引导期间还需要修补 `models.providers.*`、别名以及 + 智能体默认模型,请使用 + `openclaw/plugin-sdk/provider-onboard` 中的预设辅助函数。最窄的辅助函数包括 + `createDefaultModelPresetAppliers(...)`、 + `createDefaultModelsPresetAppliers(...)` 和 + `createModelCatalogPresetAppliers(...)`。 - 当某个提供商的原生端点在正常的 `openai-completions` 传输上支持流式使用量块时,请优先使用 `openclaw/plugin-sdk/provider-catalog-shared` 中的共享目录辅助函数,而不要硬编码提供商 id 检查。`supportsNativeStreamingUsageCompat(...)` 和 `applyProviderNativeStreamingUsageCompat(...)` 会根据端点能力映射检测支持情况,因此即使插件使用的是自定义提供商 id,原生 Moonshot/DashScope 风格的端点也仍然可以启用此能力。 + 当某个提供商的原生端点在常规 + `openai-completions` 传输上支持分块流式传输使用量块时,优先使用 + `openclaw/plugin-sdk/provider-catalog-shared` 中的共享目录辅助函数, + 而不是硬编码提供商 ID 检查。 + `supportsNativeStreamingUsageCompat(...)` 和 + `applyProviderNativeStreamingUsageCompat(...)` 会根据端点能力映射检测支持情况, + 因此即使插件使用的是自定义 provider ID,原生 Moonshot/DashScope 风格端点 + 也仍然可以选择启用。 - 如果你的提供商接受任意模型 ID(比如代理或路由器),请添加 `resolveDynamicModel`: + 如果你的提供商接受任意模型 ID(例如代理或路由器), + 请添加 `resolveDynamicModel`: ```typescript api.registerProvider({ @@ -226,14 +249,17 @@ x-i18n: }); ``` - 如果解析需要网络调用,请使用 `prepareDynamicModel` 进行异步预热 —— 在它完成后,会再次运行 `resolveDynamicModel`。 + 如果解析需要进行网络调用,请使用 `prepareDynamicModel` 进行异步 + 预热——完成后会再次运行 `resolveDynamicModel`。 - - 大多数提供商只需要 `catalog` + `resolveDynamicModel`。根据你的提供商需求逐步添加 hooks 即可。 + + 大多数提供商只需要 `catalog` + `resolveDynamicModel`。当你的提供商有需要时, + 再逐步添加 hooks。 - 共享辅助构建器现在已经覆盖了最常见的重放/工具兼容家族,因此插件通常不需要手动一个个接线每个 hook: + 共享辅助构建器现在已经覆盖了最常见的 replay/tool-compat + 系列,因此插件通常不需要手动逐个接线每个 hook: ```typescript import { buildProviderReplayFamilyHooks } from "openclaw/plugin-sdk/provider-model-shared"; @@ -253,39 +279,39 @@ x-i18n: }); ``` - 当前可用的重放家族: + 当前可用的 replay 系列: - | Family | 它会接入什么 | + | 系列 | 接入内容 | | --- | --- | - | `openai-compatible` | 用于 OpenAI 兼容传输的共享 OpenAI 风格重放策略,包括 tool-call-id 清理、assistant-first 顺序修复,以及在传输需要时的通用 Gemini 轮次校验 | - | `anthropic-by-model` | 由 `modelId` 选择的 Claude 感知重放策略,因此 Anthropic-message 传输只有在解析出的模型实际是 Claude id 时,才会获得 Claude 特定的 thinking-block 清理 | - | `google-gemini` | 原生 Gemini 重放策略,以及 bootstrap 重放清理和带标签的推理输出模式 | - | `passthrough-gemini` | 用于通过 OpenAI 兼容代理传输运行的 Gemini 模型的 Gemini thought-signature 清理;不会启用原生 Gemini 重放校验或 bootstrap 重写 | - | `hybrid-anthropic-openai` | 用于在一个插件中混合 Anthropic-message 和 OpenAI 兼容模型界面的提供商的混合策略;可选的仅 Claude thinking-block 丢弃仍然限定在 Anthropic 一侧 | + | `openai-compatible` | 用于兼容 OpenAI 传输的共享 OpenAI 风格 replay 策略,包括 tool-call-id 清理、assistant-first 顺序修复,以及在传输需要时的通用 Gemini 轮次校验 | + | `anthropic-by-model` | 按 `modelId` 选择的 Claude 感知 replay 策略,因此只有当解析后的模型实际是 Claude ID 时,Anthropic-message 传输才会获得 Claude 特有的 thinking block 清理 | + | `google-gemini` | 原生 Gemini replay 策略,加上 bootstrap replay 清理和带标签的 reasoning-output 模式 | + | `passthrough-gemini` | 适用于通过兼容 OpenAI 的代理传输运行的 Gemini 模型的 Gemini thought-signature 清理;不会启用原生 Gemini replay 校验或 bootstrap 重写 | + | `hybrid-anthropic-openai` | 适用于在同一个插件中混合 Anthropic-message 和兼容 OpenAI 模型面板的提供商的混合策略;可选的仅限 Claude 的 thinking block 丢弃仍然只作用于 Anthropic 一侧 | 真实的内置示例: - - `google` 和 `google-gemini-cli`:`google-gemini` + - `google`:`google-gemini` - `openrouter`、`kilocode`、`opencode` 和 `opencode-go`:`passthrough-gemini` - `amazon-bedrock` 和 `anthropic-vertex`:`anthropic-by-model` - `minimax`:`hybrid-anthropic-openai` - `moonshot`、`ollama`、`xai` 和 `zai`:`openai-compatible` - 当前可用的流家族: + 当前可用的 stream 系列: - | Family | 它会接入什么 | + | 系列 | 接入内容 | | --- | --- | - | `google-thinking` | 共享流路径上的 Gemini thinking 载荷标准化 | - | `kilocode-thinking` | 共享代理流路径上的 Kilo 推理包装器,其中 `kilo/auto` 和不支持代理推理的 id 会跳过注入的 thinking | - | `moonshot-thinking` | 基于配置 + `/think` 级别的 Moonshot 二元原生 thinking 载荷映射 | + | `google-thinking` | 共享流路径上的 Gemini thinking 负载规范化 | + | `kilocode-thinking` | 共享代理流路径上的 Kilo reasoning 包装器,其中 `kilo/auto` 和不支持代理 reasoning 的 ID 会跳过注入的 thinking | + | `moonshot-thinking` | 基于配置 + `/think` 级别的 Moonshot 二进制 native-thinking 负载映射 | | `minimax-fast-mode` | 共享流路径上的 MiniMax fast-mode 模型重写 | - | `openai-responses-defaults` | 共享的原生 OpenAI/Codex Responses 包装器:归因头、`/fast`/`serviceTier`、文本详细程度、原生 Codex Web 搜索、推理兼容载荷整形,以及 Responses 上下文管理 | - | `openrouter-thinking` | 用于代理路由的 OpenRouter 推理包装器,不支持模型/`auto` 的跳过逻辑由中央统一处理 | - | `tool-stream-default-on` | 为像 Z.AI 这样希望默认启用工具流式传输、除非显式禁用的提供商提供的默认开启 `tool_stream` 包装器 | + | `openai-responses-defaults` | 共享的原生 OpenAI/Codex Responses 包装器:归属头、`/fast`/`serviceTier`、文本详细度、原生 Codex web 搜索、reasoning-compat 负载塑形,以及 Responses 上下文管理 | + | `openrouter-thinking` | 用于代理路由的 OpenRouter reasoning 包装器,集中处理不支持模型/`auto` 跳过逻辑 | + | `tool-stream-default-on` | 为像 Z.AI 这类希望默认启用工具流式传输的提供商提供默认开启的 `tool_stream` 包装器,除非显式禁用 | 真实的内置示例: - - `google` 和 `google-gemini-cli`:`google-thinking` + - `google`:`google-thinking` - `kilocode`:`kilocode-thinking` - `moonshot`:`moonshot-thinking` - `minimax` 和 `minimax-portal`:`minimax-fast-mode` @@ -293,40 +319,76 @@ x-i18n: - `openrouter`:`openrouter-thinking` - `zai`:`tool-stream-default-on` - `openclaw/plugin-sdk/provider-model-shared` 还导出了 replay-family 枚举,以及这些家族所基于的共享辅助函数。常见公共导出包括: + `openclaw/plugin-sdk/provider-model-shared` 还导出了 replay-family + 枚举,以及构建这些系列所用的共享辅助函数。常见公开导出包括: - `ProviderReplayFamily` - `buildProviderReplayFamilyHooks(...)` - - 共享重放构建器,例如 `buildOpenAICompatibleReplayPolicy(...)`、`buildAnthropicReplayPolicyForModel(...)`、`buildGoogleGeminiReplayPolicy(...)` 和 `buildHybridAnthropicOrOpenAIReplayPolicy(...)` - - Gemini 重放辅助函数,例如 `sanitizeGoogleGeminiReplayHistory(...)` 和 `resolveTaggedReasoningOutputMode()` - - 端点/模型辅助函数,例如 `resolveProviderEndpoint(...)`、`normalizeProviderId(...)`、`normalizeGooglePreviewModelId(...)` 和 `normalizeNativeXaiModelId(...)` + - 共享 replay 构建器,例如 `buildOpenAICompatibleReplayPolicy(...)`、 + `buildAnthropicReplayPolicyForModel(...)`、 + `buildGoogleGeminiReplayPolicy(...)` 和 + `buildHybridAnthropicOrOpenAIReplayPolicy(...)` + - Gemini replay 辅助函数,例如 `sanitizeGoogleGeminiReplayHistory(...)` + 和 `resolveTaggedReasoningOutputMode()` + - 端点/模型辅助函数,例如 `resolveProviderEndpoint(...)`、 + `normalizeProviderId(...)`、`normalizeGooglePreviewModelId(...)` 和 + `normalizeNativeXaiModelId(...)` - `openclaw/plugin-sdk/provider-stream` 同时暴露了家族构建器和这些家族复用的公共包装辅助函数。常见公共导出包括: + `openclaw/plugin-sdk/provider-stream` 同时公开了 family builder + 以及这些 family 复用的公开包装器辅助函数。常见公开导出 + 包括: - `ProviderStreamFamily` - `buildProviderStreamFamilyHooks(...)` - `composeProviderStreamWrappers(...)` - - 共享 OpenAI/Codex 包装器,例如 `createOpenAIAttributionHeadersWrapper(...)`、`createOpenAIFastModeWrapper(...)`、`createOpenAIServiceTierWrapper(...)`、`createOpenAIResponsesContextManagementWrapper(...)` 和 `createCodexNativeWebSearchWrapper(...)` - - 共享代理/提供商包装器,例如 `createOpenRouterWrapper(...)`、`createToolStreamWrapper(...)` 和 `createMinimaxFastModeWrapper(...)` + - 共享 OpenAI/Codex 包装器,例如 + `createOpenAIAttributionHeadersWrapper(...)`、 + `createOpenAIFastModeWrapper(...)`、 + `createOpenAIServiceTierWrapper(...)`、 + `createOpenAIResponsesContextManagementWrapper(...)` 和 + `createCodexNativeWebSearchWrapper(...)` + - 共享代理/提供商包装器,例如 `createOpenRouterWrapper(...)`、 + `createToolStreamWrapper(...)` 和 `createMinimaxFastModeWrapper(...)` - 某些流辅助函数会刻意保持为提供商本地。当前内置示例:`@openclaw/anthropic-provider` 通过其公共 `api.ts` / `contract-api.ts` 接缝导出 `wrapAnthropicProviderStream`、`resolveAnthropicBetas`、`resolveAnthropicFastMode`、`resolveAnthropicServiceTier` 以及更底层的 Anthropic 包装器构建器。这些辅助函数仍然保持 Anthropic 特定,因为它们还编码了 Claude OAuth beta 处理和 `context1m` gating。 + 有些 stream 辅助函数会有意保持为提供商本地。当前的内置 + 示例:`@openclaw/anthropic-provider` 从其公共 `api.ts` / + `contract-api.ts` 接缝导出 + `wrapAnthropicProviderStream`、`resolveAnthropicBetas`、 + `resolveAnthropicFastMode`、`resolveAnthropicServiceTier` 以及 + 更底层的 Anthropic 包装器构建器。这些辅助函数仍然是 Anthropic 专用的,因为 + 它们还编码了 Claude OAuth beta 处理和 `context1m` 门控。 - 其他内置提供商在行为无法在家族之间清晰共享时,也会将传输特定包装器保留在本地。当前示例:内置 xAI 插件将原生 xAI Responses 整形保留在自己的 `wrapStreamFn` 中,包括 `/fast` 别名重写、默认 `tool_stream`、不受支持的 strict-tool 清理,以及 xAI 特定的推理载荷移除。 + 其他内置提供商在 + 行为无法在各 family 之间干净共享时,也会把特定传输的包装器保留在本地。当前示例:内置 + xAI 插件将原生 xAI Responses 塑形保留在它自己的 + `wrapStreamFn` 中,包括 `/fast` 别名重写、默认 `tool_stream`、 + 不支持的 strict-tool 清理以及 xAI 特有的 reasoning-payload + 删除。 - `openclaw/plugin-sdk/provider-tools` 当前暴露了一个共享工具 schema 家族,以及共享 schema/兼容辅助函数: + `openclaw/plugin-sdk/provider-tools` 当前公开了一个共享 + tool schema 系列以及共享 schema/compat 辅助函数: - - `ProviderToolCompatFamily` 记录了当前共享家族清单。 - - `buildProviderToolCompatFamilyHooks("gemini")` 会为需要 Gemini 安全工具 schema 的提供商接入 Gemini schema 清理 + 诊断。 - - `normalizeGeminiToolSchemas(...)` 和 `inspectGeminiToolSchemas(...)` 是底层的公共 Gemini schema 辅助函数。 - - `resolveXaiModelCompatPatch()` 返回内置 xAI 兼容补丁:`toolSchemaProfile: "xai"`、不受支持的 schema 关键字、原生 `web_search` 支持,以及 HTML 实体工具调用参数解码。 - - `applyXaiModelCompat(model)` 会在模型到达运行器之前,将相同的 xAI 兼容补丁应用到解析后的模型上。 + - `ProviderToolCompatFamily` 记录了当前共享的系列清单。 + - `buildProviderToolCompatFamilyHooks("gemini")` 为需要 Gemini 安全工具 schema 的提供商接入 Gemini schema + 清理 + 诊断。 + - `normalizeGeminiToolSchemas(...)` 和 `inspectGeminiToolSchemas(...)` + 是底层公开的 Gemini schema 辅助函数。 + - `resolveXaiModelCompatPatch()` 返回内置 xAI compat patch: + `toolSchemaProfile: "xai"`、不支持的 schema 关键字、原生 + `web_search` 支持,以及 HTML 实体形式的工具调用参数解码。 + - `applyXaiModelCompat(model)` 会在解析后的模型到达 runner 之前 + 对其应用相同的 xAI compat patch。 - 真实的内置示例:xAI 插件使用 `normalizeResolvedModel` 加上 `contributeResolvedModelCompat`,从而让兼容元数据继续由提供商拥有,而不是在核心中硬编码 xAI 规则。 + 真实的内置示例:xAI 插件使用 `normalizeResolvedModel` 加 + `contributeResolvedModelCompat`,以保持这些 compat 元数据归提供商所有, + 而不是在 core 中硬编码 xAI 规则。 - 相同的包根模式也支撑着其他内置提供商: + 相同的 package-root 模式也支撑着其他内置提供商: - - `@openclaw/openai-provider`:`api.ts` 导出提供商构建器、默认模型辅助函数和 realtime 提供商构建器 - - `@openclaw/openrouter-provider`:`api.ts` 导出提供商构建器以及 onboarding/配置辅助函数 + - `@openclaw/openai-provider`:`api.ts` 导出 provider builders、 + 默认模型辅助函数和 realtime provider builders + - `@openclaw/openrouter-provider`:`api.ts` 导出 provider builder + 以及 onboarding/config 辅助函数 @@ -347,7 +409,7 @@ x-i18n: 对于需要自定义请求头或请求体修改的提供商: ```typescript - // wrapStreamFn 返回一个从 ctx.streamFn 派生的 StreamFn + // wrapStreamFn 返回一个从 ctx.streamFn 派生出的 StreamFn wrapStreamFn: (ctx) => { if (!ctx.streamFn) return undefined; const inner = ctx.streamFn; @@ -361,8 +423,8 @@ x-i18n: }, ``` - - 对于在通用 HTTP 或 WebSocket 传输上需要原生请求/会话头或元数据的提供商: + + 对于需要在通用 HTTP 或 WebSocket 传输上附加原生请求/会话头或元数据的提供商: ```typescript resolveTransportTurnState: (ctx) => ({ @@ -382,8 +444,8 @@ x-i18n: }), ``` - - 对于暴露使用量/计费数据的提供商: + + 对于公开用量/计费数据的提供商: ```typescript resolveUsageAuth: async (ctx) => { @@ -398,72 +460,82 @@ x-i18n: - OpenClaw 会按以下顺序调用 hooks。大多数提供商只会用到 2-3 个: + OpenClaw 会按以下顺序调用 hooks。大多数提供商只会用到 2 到 3 个: | # | Hook | 何时使用 | | --- | --- | --- | - | 1 | `catalog` | 模型目录或基础 URL 默认值 | - | 2 | `applyConfigDefaults` | 配置物化期间由提供商拥有的全局默认值 | - | 3 | `normalizeModelId` | 在查找前清理旧版/预览模型 id 别名 | - | 4 | `normalizeTransport` | 在通用模型组装前清理提供商家族的 `api` / `baseUrl` | - | 5 | `normalizeConfig` | 标准化 `models.providers.` 配置 | - | 6 | `applyNativeStreamingUsageCompat` | 配置型提供商的原生流式使用量兼容重写 | - | 7 | `resolveConfigApiKey` | 提供商自有的环境变量标记认证解析 | - | 8 | `resolveSyntheticAuth` | 本地/自托管或基于配置的合成认证 | - | 9 | `shouldDeferSyntheticProfileAuth` | 将合成存储配置文件占位符降到环境变量/配置认证之后 | + | 1 | `catalog` | 模型目录或基础 `base URL` 默认值 | + | 2 | `applyConfigDefaults` | 配置具体化期间由提供商拥有的全局默认值 | + | 3 | `normalizeModelId` | 查找前的旧版/预览模型 ID 别名清理 | + | 4 | `normalizeTransport` | 通用模型组装前,针对提供商系列的 `api` / `baseUrl` 清理 | + | 5 | `normalizeConfig` | 规范化 `models.providers.` 配置 | + | 6 | `applyNativeStreamingUsageCompat` | 面向配置提供商的原生流式用量 compat 重写 | + | 7 | `resolveConfigApiKey` | 由提供商拥有的 env-marker 认证解析 | + | 8 | `resolveSyntheticAuth` | 本地/自托管或由配置支持的 synthetic auth | + | 9 | `shouldDeferSyntheticProfileAuth` | 将 synthetic 的已存储 profile 占位符置于 env/config auth 之后 | | 10 | `resolveDynamicModel` | 接受任意上游模型 ID | - | 11 | `prepareDynamicModel` | 解析前进行异步元数据抓取 | - | 12 | `normalizeResolvedModel` | 在运行器之前进行传输重写 | + | 11 | `prepareDynamicModel` | 解析前的异步元数据获取 | + | 12 | `normalizeResolvedModel` | runner 之前的传输重写 | 运行时回退说明: - - `normalizeConfig` 会先检查匹配的提供商,再检查其他具备 hook 能力的提供商插件,直到其中一个实际修改了配置。如果没有提供商 hook 重写受支持的 Google 家族配置条目,内置的 Google 配置标准化器仍会生效。 - - 当 `resolveConfigApiKey` 被暴露时,会使用该提供商 hook。内置的 `amazon-bedrock` 路径在这里也有 AWS 环境变量标记解析器,尽管 Bedrock 运行时认证本身仍使用 AWS SDK 默认链。 - | 13 | `contributeResolvedModelCompat` | 为另一种兼容传输背后的厂商模型提供兼容标记 | - | 14 | `capabilities` | 旧版静态能力包;仅用于兼容 | - | 15 | `normalizeToolSchemas` | 在注册前由提供商拥有的工具 schema 清理 | + - `normalizeConfig` 会先检查匹配的提供商,然后再检查其他 + 具备 hook 能力的提供商插件,直到其中一个实际更改配置为止。 + 如果没有任何 provider hook 重写受支持的 Google 系列配置条目, + 内置 Google 配置规范化器仍会应用。 + - 如果公开了 provider hook,则 `resolveConfigApiKey` 会使用它。内置的 + `amazon-bedrock` 路径在这里也有一个内建的 AWS env-marker 解析器, + 即使 Bedrock 运行时认证本身仍然使用 AWS SDK 默认链。 + | 13 | `contributeResolvedModelCompat` | 为运行在其他兼容传输之后的供应商模型提供 compat 标志 | + | 14 | `capabilities` | 旧版静态能力包;仅用于兼容性 | + | 15 | `normalizeToolSchemas` | 注册前由提供商拥有的工具 schema 清理 | | 16 | `inspectToolSchemas` | 由提供商拥有的工具 schema 诊断 | - | 17 | `resolveReasoningOutputMode` | 带标签还是原生的推理输出契约 | + | 17 | `resolveReasoningOutputMode` | 带标签 vs 原生 reasoning-output 契约 | | 18 | `prepareExtraParams` | 默认请求参数 | | 19 | `createStreamFn` | 完全自定义的 StreamFn 传输 | - | 20 | `wrapStreamFn` | 正常流路径上的自定义请求头/请求体包装器 | - | 21 | `resolveTransportTurnState` | 原生每轮请求头/元数据 | - | 22 | `resolveWebSocketSessionPolicy` | 原生 WS 会话头/冷却 | - | 23 | `formatApiKey` | 自定义运行时令牌形状 | + | 20 | `wrapStreamFn` | 常规流路径上的自定义请求头/请求体包装器 | + | 21 | `resolveTransportTurnState` | 原生逐轮请求头/元数据 | + | 22 | `resolveWebSocketSessionPolicy` | 原生 WS 会话请求头/冷却时间 | + | 23 | `formatApiKey` | 自定义运行时令牌形态 | | 24 | `refreshOAuth` | 自定义 OAuth 刷新 | - | 25 | `buildAuthDoctorHint` | 认证修复指导 | - | 26 | `matchesContextOverflowError` | 提供商自有的溢出检测 | - | 27 | `classifyFailoverReason` | 提供商自有的限流/过载分类 | - | 28 | `isCacheTtlEligible` | 提示缓存 TTL gating | + | 25 | `buildAuthDoctorHint` | 认证修复指引 | + | 26 | `matchesContextOverflowError` | 由提供商拥有的溢出检测 | + | 27 | `classifyFailoverReason` | 由提供商拥有的限流/过载分类 | + | 28 | `isCacheTtlEligible` | 提示词缓存 TTL 门控 | | 29 | `buildMissingAuthMessage` | 自定义缺失认证提示 | | 30 | `suppressBuiltInModel` | 隐藏陈旧的上游条目 | - | 31 | `augmentModelCatalog` | 合成的前向兼容目录条目 | - | 32 | `isBinaryThinking` | 二元 thinking 开/关 | - | 33 | `supportsXHighThinking` | `xhigh` 推理支持 | + | 31 | `augmentModelCatalog` | synthetic 向前兼容条目 | + | 32 | `isBinaryThinking` | 二进制 thinking 开/关 | + | 33 | `supportsXHighThinking` | `xhigh` reasoning 支持 | | 34 | `resolveDefaultThinkingLevel` | 默认 `/think` 策略 | | 35 | `isModernModelRef` | live/smoke 模型匹配 | | 36 | `prepareRuntimeAuth` | 推理前的令牌交换 | - | 37 | `resolveUsageAuth` | 自定义使用量凭证解析 | - | 38 | `fetchUsageSnapshot` | 自定义使用量端点 | - | 39 | `createEmbeddingProvider` | 用于 memory/search 的提供商自有 embedding 适配器 | - | 40 | `buildReplayPolicy` | 自定义转录重放/压缩策略 | - | 41 | `sanitizeReplayHistory` | 通用清理后由提供商特定执行的重放重写 | - | 42 | `validateReplayTurns` | 嵌入式运行器前的严格重放轮次校验 | + | 37 | `resolveUsageAuth` | 自定义用量凭证解析 | + | 38 | `fetchUsageSnapshot` | 自定义用量端点 | + | 39 | `createEmbeddingProvider` | 由提供商拥有的记忆/搜索 embedding 适配器 | + | 40 | `buildReplayPolicy` | 自定义转录 replay/压缩策略 | + | 41 | `sanitizeReplayHistory` | 通用清理后的提供商特定 replay 重写 | + | 42 | `validateReplayTurns` | 嵌入式 runner 之前的严格 replay turn 校验 | | 43 | `onModelSelected` | 选择模型后的回调(例如遥测) | 提示词调优说明: - - `resolveSystemPromptContribution` 允许提供商为某个模型家族注入具备缓存感知的系统提示词指导。当行为属于单个提供商/模型家族且需要保留稳定/动态缓存拆分时,应优先使用它,而不是 `before_prompt_build`。 + - `resolveSystemPromptContribution` 允许提供商为某个模型系列注入 + 具备缓存感知能力的 system-prompt 指引。当该行为属于某个提供商/模型 + 系列,且应保留稳定/动态缓存拆分时,优先使用它,而不是 + `before_prompt_build`。 有关详细说明和真实示例,请参见 - [内部机制:提供商运行时 hooks](/zh-CN/plugins/architecture#provider-runtime-hooks)。 + [内部机制:提供商运行时 Hooks](/zh-CN/plugins/architecture#provider-runtime-hooks)。 - 提供商插件除了文本推理外,还可以注册语音、实时转录、实时语音、媒体理解、图像生成、视频生成、网页抓取和网页搜索: + 除文本推理外,提供商插件还可以注册语音、实时转录、实时 + 语音、媒体理解、图像生成、视频生成、web 抓取 + 和 web 搜索: ```typescript register(api) { @@ -560,7 +632,8 @@ x-i18n: } ``` - OpenClaw 会将其归类为**混合能力**插件。这是公司级插件的推荐模式(每个厂商一个插件)。参见 + OpenClaw 会将其归类为**混合能力**插件。这是 + 公司插件(每个供应商一个插件)的推荐模式。参见 [内部机制:能力归属](/zh-CN/plugins/architecture#capability-ownership-model)。 @@ -569,7 +642,7 @@ x-i18n: ```typescript src/provider.test.ts import { describe, it, expect } from "vitest"; - // 从 index.ts 或专用文件中导出你的提供商配置对象 + // 从 index.ts 或专门的文件中导出你的 provider 配置对象 import { acmeProvider } from "./provider.js"; describe("acme-ai provider", () => { @@ -609,7 +682,7 @@ clawhub package publish your-org/your-plugin --dry-run clawhub package publish your-org/your-plugin ``` -这里不要使用旧版的仅 Skills 发布别名;插件包应使用 +这里不要使用旧版的仅限 skill 的发布别名;插件包应使用 `clawhub package publish`。 ## 文件结构 @@ -621,23 +694,24 @@ clawhub package publish your-org/your-plugin ├── index.ts # definePluginEntry + registerProvider └── src/ ├── provider.test.ts # 测试 - └── usage.ts # 使用量端点(可选) + └── usage.ts # 用量端点(可选) ``` ## 目录顺序参考 -`catalog.order` 控制你的目录相对于内置提供商的合并时机: +`catalog.order` 控制你的目录相对于内置 +提供商何时合并: -| Order | 时机 | 用例 | -| --------- | ------------- | ------------------------------------------- | -| `simple` | 第一轮 | 纯 API key 提供商 | -| `profile` | 在 simple 之后 | 受认证配置文件控制的提供商 | -| `paired` | 在 profile 之后 | 合成多个相关条目 | -| `late` | 最后一轮 | 覆盖现有提供商(冲突时胜出) | +| Order | 何时 | 使用场景 | +| --------- | ------------- | ----------------------------------------------- | +| `simple` | 第一阶段 | 纯 API 密钥提供商 | +| `profile` | 在 simple 之后 | 受 auth profile 控制的提供商 | +| `paired` | 在 profile 之后 | 合成多个相关条目 | +| `late` | 最后阶段 | 覆盖现有提供商(冲突时生效) | -## 下一步 +## 后续步骤 -- [渠道插件](/zh-CN/plugins/sdk-channel-plugins) — 如果你的插件也提供一个渠道 -- [插件运行时](/zh-CN/plugins/sdk-runtime) — `api.runtime` 辅助函数(TTS、搜索、subagent) +- [渠道插件](/zh-CN/plugins/sdk-channel-plugins) — 如果你的插件还提供一个渠道 +- [插件运行时](/zh-CN/plugins/sdk-runtime) — `api.runtime` 辅助函数(TTS、搜索、子智能体) - [SDK 概览](/zh-CN/plugins/sdk-overview) — 完整的子路径导入参考 -- [插件内部机制](/zh-CN/plugins/architecture#provider-runtime-hooks) — hook 详情和内置示例 +- [插件内部机制](/zh-CN/plugins/architecture#provider-runtime-hooks) — hook 细节和内置示例 diff --git a/docs/zh-CN/providers/anthropic.md b/docs/zh-CN/providers/anthropic.md index 9797a132d..f5cff2056 100644 --- a/docs/zh-CN/providers/anthropic.md +++ b/docs/zh-CN/providers/anthropic.md @@ -1,38 +1,43 @@ --- read_when: - 你想在 OpenClaw 中使用 Anthropic 模型 -summary: 在 OpenClaw 中通过 API 密钥使用 Anthropic Claude +summary: 在 OpenClaw 中通过 API key 使用 Anthropic Claude title: Anthropic x-i18n: - generated_at: "2026-04-05T17:48:50Z" + generated_at: "2026-04-05T18:14:50Z" model: gpt-5.4 provider: openai - source_hash: 6af35571debf5889b63e3b4f6a05aa4e046f39740287e6e1c492916ca00df44b + source_hash: bbc6c4938674aedf20ff944bc04e742c9a7e77a5ff10ae4f95b5718504c57c2d source_path: providers/anthropic.md workflow: 15 --- -# Anthropic (Claude) +# Anthropic(Claude) Anthropic 构建了 **Claude** 模型家族,并通过 API 提供访问。 -在 OpenClaw 中,新的 Anthropic 设置应使用 API 密钥。现有的旧版 -Anthropic token 配置档案如果已经配置,运行时仍会继续生效。 +在 OpenClaw 中,新的 Anthropic 设置应使用 API key。现有的旧版 +Anthropic token 配置文件如果已经配置,运行时仍会继续支持。 -对于 OpenClaw 中的 Anthropic,计费划分如下: +在 OpenClaw 中使用 Anthropic 时,计费方式分为: -- **Anthropic API 密钥**:普通的 Anthropic API 计费。 -- **OpenClaw 内的 Claude 订阅认证**:Anthropic 已于 - **2026 年 4 月 4 日太平洋时间中午 12:00 / 英国夏令时晚上 8:00** - 告知 OpenClaw 用户,这被视为第三方 harness 使用,需要 **Extra Usage**(按量付费,与订阅分开计费)。 +- **Anthropic API key**:标准 Anthropic API 计费。 +- **OpenClaw 内的 Claude 订阅认证**:Anthropic 于 + **2026 年 4 月 4 日太平洋时间中午 12:00 / 英国夏令时间晚上 8:00** + 告知 OpenClaw 用户,这属于第三方 harness 使用,因此需要 **Extra Usage**(按量付费, + 与订阅分开计费)。 -我们的本地复现与这一划分一致: +我们的本地复现结果也符合这一划分: -- 直接 `claude -p` 可能仍然可用 -- `claude -p --append-system-prompt ...` 在提示词标识为 OpenClaw 时,可能触发 Extra Usage 限制 -- 相同的类 OpenClaw 系统提示词,在 Anthropic SDK + `ANTHROPIC_API_KEY` 路径上**不会**复现该拦截 +- 直接使用 `claude -p` 可能仍然可用 +- `claude -p --append-system-prompt ...` 在提示词表明 OpenClaw + 身份时,可能会触发 Extra Usage 限制 +- 相同的类 OpenClaw 系统提示词,在 Anthropic SDK + `ANTHROPIC_API_KEY` + 路径上**不会**复现该拦截 -因此,实际规则是:**Anthropic API 密钥,或启用了 Extra Usage 的 Claude 订阅**。如果你想要最清晰的生产路径,请使用 Anthropic API 密钥。 +所以实际规则是:**Anthropic API key,或启用了 +Extra Usage 的 Claude 订阅**。如果你想采用最明确的生产环境方案,请使用 Anthropic API +key。 Anthropic 当前的公开文档: @@ -42,17 +47,17 @@ Anthropic 当前的公开文档: - [Using Claude Code with your Pro or Max plan](https://support.claude.com/en/articles/11145838-using-claude-code-with-your-pro-or-max-plan) - [Using Claude Code with your Team or Enterprise plan](https://support.anthropic.com/en/articles/11845131-using-claude-code-with-your-team-or-enterprise-plan/) -如果你想要最清晰的计费路径,请改用 Anthropic API 密钥。 -OpenClaw 还支持其他订阅式选项,包括 [OpenAI +如果你希望采用最明确的计费路径,请改用 Anthropic API key。 +OpenClaw 也支持其他订阅式选项,包括 [OpenAI Codex](/zh-CN/providers/openai)、[Qwen Cloud Coding Plan](/zh-CN/providers/qwen)、 [MiniMax Coding Plan](/zh-CN/providers/minimax) 和 [Z.AI / GLM Coding Plan](/zh-CN/providers/glm)。 -## 选项 A:Anthropic API 密钥 +## 选项 A:Anthropic API key **最适合:** 标准 API 访问和按量计费。 -请在 Anthropic Console 中创建你的 API 密钥。 +请在 Anthropic Console 中创建你的 API key。 ### CLI 设置 @@ -84,7 +89,7 @@ openclaw onboard --anthropic-api-key "$ANTHROPIC_API_KEY" ## 快速模式(Anthropic API) -OpenClaw 的共享 `/fast` 开关也支持直连公共 Anthropic 流量,包括发送到 `api.anthropic.com` 的 API 密钥和 OAuth 认证请求。 +OpenClaw 的共享 `/fast` 开关也支持直接面向公开 Anthropic 的流量,包括发送到 `api.anthropic.com` 的 API key 和 OAuth 认证请求。 - `/fast on` 映射为 `service_tier: "auto"` - `/fast off` 映射为 `service_tier: "standard_only"` @@ -106,23 +111,23 @@ OpenClaw 的共享 `/fast` 开关也支持直连公共 Anthropic 流量,包括 重要限制: -- OpenClaw 仅会为直连 `api.anthropic.com` 的请求注入 Anthropic service tiers。如果你通过代理或 Gateway 网关路由 `anthropic/*`,`/fast` 不会修改 `service_tier`。 -- 如果同时设置了显式 Anthropic `serviceTier` 或 `service_tier` 模型参数,它们会覆盖 `/fast` 默认值。 -- Anthropic 会在响应中的 `usage.service_tier` 下报告实际生效的层级。对于没有 Priority Tier 容量的账户,`service_tier: "auto"` 仍可能解析为 `standard`。 +- OpenClaw 仅会为直接发往 `api.anthropic.com` 的请求注入 Anthropic service tier。如果你通过代理或 Gateway 网关路由 `anthropic/*`,`/fast` 不会修改 `service_tier`。 +- 如果同时设置了显式 Anthropic `serviceTier` 或 `service_tier` 模型参数,则它们会覆盖 `/fast` 的默认值。 +- Anthropic 会在响应中的 `usage.service_tier` 报告实际生效的 tier。对于没有 Priority Tier 容量的账户,`service_tier: "auto"` 仍可能解析为 `standard`。 ## 提示词缓存(Anthropic API) -OpenClaw 支持 Anthropic 的提示词缓存功能。这是**仅限 API**的;旧版 Anthropic token 认证不会遵循缓存设置。 +OpenClaw 支持 Anthropic 的提示词缓存功能。这**仅适用于 API**;旧版 Anthropic token 认证不会遵循缓存设置。 ### 配置 在你的模型配置中使用 `cacheRetention` 参数: -| 值 | 缓存时长 | 说明 | -| ------- | -------- | ---------------- | -| `none` | 无缓存 | 禁用提示词缓存 | -| `short` | 5 分钟 | API 密钥认证默认 | -| `long` | 1 小时 | 扩展缓存 | +| 值 | 缓存时长 | 说明 | +| ------- | -------- | -------------------- | +| `none` | 不缓存 | 禁用提示词缓存 | +| `short` | 5 分钟 | API key 认证的默认值 | +| `long` | 1 小时 | 扩展缓存 | ```json5 { @@ -140,9 +145,9 @@ OpenClaw 支持 Anthropic 的提示词缓存功能。这是**仅限 API**的; ### 默认值 -使用 Anthropic API 密钥认证时,OpenClaw 会自动为所有 Anthropic 模型应用 `cacheRetention: "short"`(5 分钟缓存)。你可以通过在配置中显式设置 `cacheRetention` 来覆盖这一行为。 +使用 Anthropic API Key 认证时,OpenClaw 会自动对所有 Anthropic 模型应用 `cacheRetention: "short"`(5 分钟缓存)。你可以通过在配置中显式设置 `cacheRetention` 来覆盖它。 -### 按智能体覆盖 cacheRetention +### 按智能体覆盖 `cacheRetention` 将模型级参数作为基线,然后通过 `agents.list[].params` 覆盖特定智能体。 @@ -159,29 +164,30 @@ OpenClaw 支持 Anthropic 的提示词缓存功能。这是**仅限 API**的; }, list: [ { id: "research", default: true }, - { id: "alerts", params: { cacheRetention: "none" } }, // 仅为此智能体覆盖 + { id: "alerts", params: { cacheRetention: "none" } }, // 仅覆盖此智能体 ], }, } ``` -与缓存相关参数的配置合并顺序: +与缓存相关的配置合并顺序: 1. `agents.defaults.models["provider/model"].params` 2. `agents.list[].params`(匹配 `id`,按键覆盖) -这使得一个智能体可以保持长期缓存,而另一个使用相同模型的智能体则可以禁用缓存,以避免突发/低复用流量的写入成本。 +这样就可以让一个智能体保留长期缓存,而另一个使用同一模型的智能体禁用缓存,以避免突发性/低复用流量带来的写入成本。 ### Bedrock Claude 说明 -- Bedrock 上的 Anthropic Claude 模型(`amazon-bedrock/*anthropic.claude*`)在配置时接受 `cacheRetention` 透传。 +- Bedrock 上的 Anthropic Claude 模型(`amazon-bedrock/*anthropic.claude*`)在配置后可透传 `cacheRetention`。 - 非 Anthropic 的 Bedrock 模型会在运行时被强制设为 `cacheRetention: "none"`。 -- 当未设置显式值时,Anthropic API 密钥智能默认值也会为 Claude-on-Bedrock 模型引用填充 `cacheRetention: "short"`。 +- 当未设置显式值时,Anthropic API key 的智能默认值也会为 Claude-on-Bedrock 模型引用填入 `cacheRetention: "short"`。 ## 100 万上下文窗口(Anthropic beta) Anthropic 的 100 万上下文窗口受 beta 权限控制。在 OpenClaw 中, -可对受支持的 Opus/Sonnet 模型按模型启用 `params.context1m: true`。 +对受支持的 Opus/Sonnet 模型,可通过为每个模型设置 +`params.context1m: true` 启用。 ```json5 { @@ -197,61 +203,73 @@ Anthropic 的 100 万上下文窗口受 beta 权限控制。在 OpenClaw 中, } ``` -OpenClaw 会将其映射为 Anthropic 请求上的 +OpenClaw 会将其映射为 Anthropic 请求中的 `anthropic-beta: context-1m-2025-08-07`。 -只有在该模型明确设置 `params.context1m` 为 `true` 时,这一功能才会启用。 +只有当该模型的 `params.context1m` 被显式设置为 `true` 时, +此功能才会启用。 要求:Anthropic 必须允许该凭证使用长上下文 -(通常是 API 密钥计费,或 OpenClaw 的 Claude 登录路径 / 启用了 Extra Usage 的旧版 token 认证)。否则 Anthropic 会返回: +(通常是 API key 计费,或 OpenClaw 的 Claude 登录路径 / 启用了 +Extra Usage 的旧版 token 认证)。否则 Anthropic 会返回: `HTTP 429: rate_limit_error: Extra usage is required for long context requests`。 -注意:Anthropic 当前会在使用旧版 Anthropic token 认证(`sk-ant-oat-*`)时拒绝 `context-1m-*` beta 请求。如果你在该旧版认证模式下配置了 `context1m: true`,OpenClaw 会记录一条警告,并通过跳过 context1m beta 标头而保留所需的 OAuth beta 标头,从而回退到标准上下文窗口。 +注意:Anthropic 当前在使用 +旧版 Anthropic token 认证(`sk-ant-oat-*`)时,会拒绝 `context-1m-*` +beta 请求。如果你在这种旧版认证模式下配置了 +`context1m: true`,OpenClaw 会记录一条警告,并通过跳过 context1m beta +header 回退到标准上下文窗口,同时保留所需的 OAuth beta。 ## 已移除:Claude CLI 后端 内置的 Anthropic `claude-cli` 后端已被移除。 -- Anthropic 在 2026 年 4 月 4 日的通知中指出,由 OpenClaw 驱动的 Claude 登录流量属于第三方 harness 使用,需要 **Extra Usage**。 -- 我们的本地复现还表明,直接 - `claude -p --append-system-prompt ...` 在附加提示词标识为 OpenClaw 时,也可能触发相同限制。 +- Anthropic 在 2026 年 4 月 4 日的通知中表示,由 OpenClaw 驱动的 Claude 登录流量属于 + 第三方 harness 使用,因此需要 **Extra Usage**。 +- 我们的本地复现也显示,直接使用 + `claude -p --append-system-prompt ...` 在附加提示词表明 OpenClaw + 身份时,也可能触发同样的限制。 - 相同的类 OpenClaw 系统提示词,在 Anthropic SDK + `ANTHROPIC_API_KEY` 路径上不会触发该限制。 -- 在 OpenClaw 中处理 Anthropic 流量时,请使用 Anthropic API 密钥。 -- 如果你需要本地 CLI 回退运行时,请使用其他受支持的 CLI 后端,例如 Codex CLI。请参阅 [/gateway/cli-backends](/zh-CN/gateway/cli-backends)。 +- 在 OpenClaw 中处理 Anthropic 流量时,请使用 Anthropic API key。 ## 说明 - Anthropic 的公开 Claude Code 文档仍然记录了直接 CLI 用法,例如 - `claude -p`,但 Anthropic 单独向 OpenClaw 用户发出的通知指出, - **OpenClaw** 的 Claude 登录路径属于第三方 harness 使用,需要 + `claude -p`,但 Anthropic 面向 OpenClaw 用户的单独通知指出, + **OpenClaw** 的 Claude 登录路径属于第三方 harness 使用,因此需要 **Extra Usage**(按量付费,与订阅分开计费)。 - 我们的本地复现还表明,直接 - `claude -p --append-system-prompt ...` 在附加提示词标识为 OpenClaw 时也可能触发相同限制,而相同的提示词形态在 Anthropic SDK + `ANTHROPIC_API_KEY` 路径上不会复现。对于生产用途,我们建议改用 Anthropic API 密钥。 -- Anthropic setup-token 现已在 OpenClaw 中重新作为旧版/手动路径提供。Anthropic 针对 OpenClaw 的计费通知仍然适用,因此使用该路径时,请预期 Anthropic 会要求 **Extra Usage**。 -- 凭证详情 + 复用规则见 [/concepts/oauth](/zh-CN/concepts/oauth)。 + 我们的本地复现也显示,直接使用 + `claude -p --append-system-prompt ...` 在附加提示词表明 OpenClaw + 身份时可能触发同样的限制,而相同形式的提示词在 + Anthropic SDK + `ANTHROPIC_API_KEY` 路径上不会复现该问题。对于生产环境,我们 + 建议改用 Anthropic API key。 +- Anthropic setup-token 已重新在 OpenClaw 中作为旧版/手动路径提供。Anthropic 针对 OpenClaw 的专用计费通知仍然适用,因此使用此路径时,应预期 Anthropic 会要求 **Extra Usage**。 +- 认证细节和复用规则见 [/concepts/oauth](/zh-CN/concepts/oauth)。 ## 故障排除 **401 错误 / token 突然失效** -- 旧版 Anthropic token 认证可能会过期或被撤销。 -- 对于新的设置,请迁移到 Anthropic API 密钥。 +- 旧版 Anthropic token 认证可能过期或被撤销。 +- 对于新的设置,请迁移到 Anthropic API key。 -**No API key found for provider "anthropic"** +**未找到 provider "anthropic" 的 API key** -- 凭证是**按智能体**隔离的。新智能体不会继承主智能体的密钥。 -- 请为该智能体重新运行新手引导,或在 Gateway 网关主机上配置 API 密钥,然后使用 `openclaw models status` 验证。 +- 认证是**按智能体**区分的。新智能体不会继承主智能体的 key。 +- 重新为该智能体运行新手引导,或在 Gateway 网关 + 主机上配置 API key,然后使用 `openclaw models status` 验证。 -**No credentials found for profile `anthropic:default`** +**未找到配置文件 `anthropic:default` 的凭证** -- 运行 `openclaw models status` 查看当前激活的是哪个凭证配置档案。 -- 重新运行新手引导,或为该配置档案路径配置 API 密钥。 +- 运行 `openclaw models status` 查看当前激活的是哪个认证配置文件。 +- 重新运行新手引导,或为该配置文件路径配置 API key。 -**No available auth profile (all in cooldown/unavailable)** +**没有可用的认证配置文件(全部处于冷却中/不可用)** - 检查 `openclaw models status --json` 中的 `auth.unusableProfiles`。 -- Anthropic 的限流冷却可能是按模型划分的,因此即使当前模型处于冷却中,同一 Anthropic 下的其他模型仍可能可用。 -- 添加另一个 Anthropic 配置档案或等待冷却结束。 +- Anthropic 的速率限制冷却可能是按模型区分的,因此即使当前模型处于冷却中, + 同级的另一个 Anthropic 模型仍可能可用。 +- 添加另一个 Anthropic 配置文件,或等待冷却结束。 -更多信息:[/gateway/troubleshooting](/zh-CN/gateway/troubleshooting) 和 [/help/faq](/zh-CN/help/faq)。 +更多内容:[/gateway/troubleshooting](/zh-CN/gateway/troubleshooting) 和 [/help/faq](/zh-CN/help/faq)。 diff --git a/docs/zh-CN/providers/google.md b/docs/zh-CN/providers/google.md index 3df3aeab8..ae545429c 100644 --- a/docs/zh-CN/providers/google.md +++ b/docs/zh-CN/providers/google.md @@ -1,14 +1,14 @@ --- read_when: - 你想在 OpenClaw 中使用 Google Gemini 模型 - - 你需要 API 密钥或 OAuth 身份验证流程 -summary: Google Gemini 设置(API 密钥 + OAuth、图像生成、媒体理解、Web 搜索) + - 你需要 API 密钥认证流程 +summary: Google Gemini 设置(API 密钥、图像生成、媒体理解、Web 搜索) title: Google(Gemini) x-i18n: - generated_at: "2026-04-05T08:42:18Z" + generated_at: "2026-04-05T18:14:58Z" model: gpt-5.4 provider: openai - source_hash: fa3c4326e83fad277ae4c2cb9501b6e89457afcfa7e3e1d57ae01c9c0c6846e2 + source_hash: 0df5bcbd98e2c1dafea3e9919e9793533ba785120b24f1db12e8e35b1ad23083 source_path: providers/google.md workflow: 15 --- @@ -18,9 +18,8 @@ x-i18n: Google 插件通过 Google AI Studio 提供对 Gemini 模型的访问,以及通过 Gemini Grounding 提供图像生成、媒体理解(图像/音频/视频)和 Web 搜索功能。 - 提供商:`google` -- 身份验证:`GEMINI_API_KEY` 或 `GOOGLE_API_KEY` +- 认证:`GEMINI_API_KEY` 或 `GOOGLE_API_KEY` - API:Google Gemini API -- 替代提供商:`google-gemini-cli`(OAuth) ## 快速开始 @@ -51,39 +50,6 @@ openclaw onboard --non-interactive \ --gemini-api-key "$GEMINI_API_KEY" ``` -## OAuth(Gemini CLI) - -另一个替代提供商 `google-gemini-cli` 使用 PKCE OAuth,而不是 API 密钥。这是一个非官方集成;一些用户报告了账户限制。请自行承担使用风险。 - -- 默认模型:`google-gemini-cli/gemini-3.1-pro-preview` -- 别名:`gemini-cli` -- 安装前提:本地可用的 Gemini CLI,命令名为 `gemini` - - Homebrew:`brew install gemini-cli` - - npm:`npm install -g @google/gemini-cli` -- 登录: - -```bash -openclaw models auth login --provider google-gemini-cli --set-default -``` - -环境变量: - -- `OPENCLAW_GEMINI_OAUTH_CLIENT_ID` -- `OPENCLAW_GEMINI_OAUTH_CLIENT_SECRET` - -(或使用 `GEMINI_CLI_*` 变体。) - -如果 Gemini CLI 的 OAuth 请求在登录后失败,请在 Gateway 网关主机上设置 `GOOGLE_CLOUD_PROJECT` 或 `GOOGLE_CLOUD_PROJECT_ID`,然后重试。 - -如果在浏览器流程开始之前登录就失败,请确认本地 `gemini` 命令已安装并位于 `PATH` 中。OpenClaw 同时支持 Homebrew 安装和全局 npm 安装,包括常见的 Windows/npm 布局。 - -Gemini CLI JSON 使用说明: - -- 回复文本来自 CLI JSON 的 `response` 字段。 -- 当 CLI 将 `usage` 留空时,用量会回退到 `stats`。 -- `stats.cached` 会被规范化为 OpenClaw `cacheRead`。 -- 如果缺少 `stats.input`,OpenClaw 会根据 `stats.input_tokens - stats.cached` 推导输入 token 数。 - ## 功能 | 功能 | 支持情况 | @@ -94,16 +60,16 @@ Gemini CLI JSON 使用说明: | 音频转录 | 是 | | 视频理解 | 是 | | Web 搜索(Grounding) | 是 | -| 思考/推理 | 是(Gemini 3.1+) | +| Thinking/推理 | 是(Gemini 3.1+) | ## 直接复用 Gemini 缓存 -对于直接 Gemini API 运行(`api: "google-generative-ai"`),OpenClaw 现在会将已配置的 `cachedContent` 句柄传递给 Gemini 请求。 +对于直接 Gemini API 运行(`api: "google-generative-ai"`),OpenClaw 现在会将已配置的 `cachedContent` 句柄透传到 Gemini 请求中。 -- 可通过 `cachedContent` 或旧版 `cached_content` 为每个模型或全局参数进行配置 -- 如果两者同时存在,则 `cachedContent` 优先 +- 使用 `cachedContent` 或旧版 `cached_content` 为每个模型或全局参数进行配置 +- 如果两者都存在,则 `cachedContent` 优先 - 示例值:`cachedContents/prebuilt-context` -- Gemini 缓存命中用量会根据上游 `cachedContentTokenCount` 规范化为 OpenClaw `cacheRead` +- Gemini 缓存命中的用量会从上游 `cachedContentTokenCount` 规范化为 OpenClaw `cacheRead` 示例: @@ -132,8 +98,8 @@ Gemini CLI JSON 使用说明: - 编辑模式:已启用,最多支持 5 张输入图像 - 几何控制:`size`、`aspectRatio` 和 `resolution` -仅支持 OAuth 的 `google-gemini-cli` 提供商是一个独立的文本推理接口。图像生成、媒体理解和 Gemini Grounding 仍然使用 `google` 提供商 ID。 +图像生成、媒体理解和 Gemini Grounding 都保持使用 `google` 提供商 ID。 ## 环境说明 -如果 Gateway 网关以守护进程(launchd/systemd)方式运行,请确保该进程可以访问 `GEMINI_API_KEY`(例如,在 `~/.openclaw/.env` 中,或通过 `env.shellEnv`)。 +如果 Gateway 网关以守护进程(launchd/systemd)方式运行,请确保 `GEMINI_API_KEY` 对该进程可用(例如,在 `~/.openclaw/.env` 中,或通过 `env.shellEnv`)。 diff --git a/docs/zh-CN/providers/models.md b/docs/zh-CN/providers/models.md index b73569977..01fd2416a 100644 --- a/docs/zh-CN/providers/models.md +++ b/docs/zh-CN/providers/models.md @@ -1,21 +1,22 @@ --- read_when: - 你想选择一个模型提供商 - - 你想要用于 LLM 认证和模型选择的快速设置示例 + - 你想查看 LLM 认证和模型选择的快速设置示例 summary: OpenClaw 支持的模型提供商(LLM) title: 模型提供商快速开始 x-i18n: - generated_at: "2026-04-05T08:42:47Z" + generated_at: "2026-04-05T18:14:57Z" model: gpt-5.4 provider: openai - source_hash: 83e372193b476c7cee6eb9f5c443b03563d863043f47c633ac0096bca642cc6f + source_hash: bc98c65af5737b2c820f4da3304118c2b449d8f0cd363d73922f81087331e93d source_path: providers/models.md workflow: 15 --- # 模型提供商 -OpenClaw 可以使用许多 LLM 提供商。选择一个,完成认证,然后将默认模型设置为 `provider/model`。 +OpenClaw 可以使用许多 LLM 提供商。选择一个提供商,完成认证,然后将默认 +模型设置为 `provider/model`。 ## 快速开始(两步) @@ -30,32 +31,32 @@ OpenClaw 可以使用许多 LLM 提供商。选择一个,完成认证,然后 ## 支持的提供商(入门集合) -- [Anthropic(API + Claude CLI)](/providers/anthropic) -- [Amazon Bedrock](/providers/bedrock) -- [BytePlus(国际版)](/concepts/model-providers#byteplus-international) -- [Chutes](/providers/chutes) -- [Cloudflare AI Gateway](/providers/cloudflare-ai-gateway) -- [Fireworks](/providers/fireworks) -- [GLM 模型](/providers/glm) -- [MiniMax](/providers/minimax) -- [Mistral](/providers/mistral) -- [Moonshot AI(Kimi + Kimi Coding)](/providers/moonshot) -- [OpenAI(API + Codex)](/providers/openai) -- [OpenCode(Zen + Go)](/providers/opencode) -- [OpenRouter](/providers/openrouter) -- [Qianfan](/providers/qianfan) -- [Qwen](/providers/qwen) -- [StepFun](/providers/stepfun) -- [Synthetic](/providers/synthetic) -- [Vercel AI Gateway](/providers/vercel-ai-gateway) -- [Venice(Venice AI)](/providers/venice) -- [xAI](/providers/xai) -- [Z.AI](/providers/zai) +- [Anthropic(API + Claude CLI)](/zh-CN/providers/anthropic) +- [Amazon Bedrock](/zh-CN/providers/bedrock) +- [BytePlus(国际版)](/zh-CN/concepts/model-providers#byteplus-international) +- [Chutes](/zh-CN/providers/chutes) +- [Cloudflare AI Gateway](/zh-CN/providers/cloudflare-ai-gateway) +- [Fireworks](/zh-CN/providers/fireworks) +- [GLM 模型](/zh-CN/providers/glm) +- [MiniMax](/zh-CN/providers/minimax) +- [Mistral](/zh-CN/providers/mistral) +- [Moonshot AI(Kimi + Kimi Coding)](/zh-CN/providers/moonshot) +- [OpenAI(API + Codex)](/zh-CN/providers/openai) +- [OpenCode(Zen + Go)](/zh-CN/providers/opencode) +- [OpenRouter](/zh-CN/providers/openrouter) +- [Qianfan](/zh-CN/providers/qianfan) +- [Qwen](/zh-CN/providers/qwen) +- [StepFun](/zh-CN/providers/stepfun) +- [Synthetic](/zh-CN/providers/synthetic) +- [Vercel AI Gateway](/zh-CN/providers/vercel-ai-gateway) +- [Venice(Venice AI)](/zh-CN/providers/venice) +- [xAI](/zh-CN/providers/xai) +- [Z.AI](/zh-CN/providers/zai) ## 其他内置变体 -- `anthropic-vertex` - 当 Vertex 凭证可用时,隐式支持 Google Vertex 上的 Anthropic;无需单独的新手引导认证选项 +- `anthropic-vertex` - 当 Vertex 凭证可用时,隐式启用 Google Vertex 上的 Anthropic 支持;无需单独的新手引导认证选项 - `copilot-proxy` - 本地 VS Code Copilot Proxy 桥接;使用 `openclaw onboard --auth-choice copilot-proxy` -- `google-gemini-cli` - 非官方 Gemini CLI OAuth 流程;需要本地安装 `gemini`(`brew install gemini-cli` 或 `npm install -g @google/gemini-cli`);默认模型为 `google-gemini-cli/gemini-3.1-pro-preview`;使用 `openclaw onboard --auth-choice google-gemini-cli` 或 `openclaw models auth login --provider google-gemini-cli --set-default` -如需完整的提供商目录(xAI、Groq、Mistral 等)和高级配置,请参阅[模型提供商](/concepts/model-providers)。 +关于完整的提供商目录(xAI、Groq、Mistral 等)和高级配置, +请参见 [模型提供商](/zh-CN/concepts/model-providers)。 diff --git a/docs/zh-CN/reference/session-management-compaction.md b/docs/zh-CN/reference/session-management-compaction.md index fa53d9998..b734453f0 100644 --- a/docs/zh-CN/reference/session-management-compaction.md +++ b/docs/zh-CN/reference/session-management-compaction.md @@ -1,15 +1,15 @@ --- read_when: - - 你需要调试会话 ID、转录 JSONL 或 sessions.json 字段 - - 你正在更改自动压缩行为或添加“压缩前”整理逻辑 - - 你想实现内存刷新或静默系统轮次 + - 你需要调试会话 id、转录 JSONL 或 sessions.json 字段 + - 你正在修改自动压缩行为,或添加“压缩前”维护逻辑 + - 你想实现记忆刷新或静默系统轮次 summary: 深入解析:会话存储 + 转录、生命周期,以及(自动)压缩内部机制 title: 会话管理深入解析 x-i18n: - generated_at: "2026-04-05T10:08:28Z" + generated_at: "2026-04-05T18:15:37Z" model: gpt-5.4 provider: openai - source_hash: e379d624dd7808d3af25ed011079268ce6a9da64bb3f301598884ad4c46ab091 + source_hash: e0d8c2d30be773eac0424f7a4419ab055fdd50daac8bc654e7d250c891f2c3b8 source_path: reference/session-management-compaction.md workflow: 15 --- @@ -21,12 +21,12 @@ x-i18n: - **会话路由**(入站消息如何映射到 `sessionKey`) - **会话存储**(`sessions.json`)及其跟踪内容 - **转录持久化**(`*.jsonl`)及其结构 -- **转录整理**(运行前的 provider 特定修正) -- **上下文限制**(上下文窗口与已跟踪 token 的区别) -- **压缩**(手动 + 自动压缩)以及压缩前工作的挂接位置 -- **静默整理**(例如不应产生用户可见输出的内存写入) +- **转录清理**(运行前的提供商专用修正) +- **上下文限制**(上下文窗口 vs 已跟踪 token) +- **压缩**(手动 + 自动压缩)以及在何处挂接压缩前逻辑 +- **静默维护**(例如不应产生用户可见输出的记忆写入) -如果你想先看一个更高层的概览,请先阅读: +如果你想先看更高层的概览,请从以下文档开始: - [/concepts/session](/zh-CN/concepts/session) - [/concepts/compaction](/zh-CN/concepts/compaction) @@ -39,26 +39,26 @@ x-i18n: ## 事实来源:Gateway 网关 -OpenClaw 围绕一个拥有会话状态的单一 **Gateway 网关进程** 设计。 +OpenClaw 的设计围绕一个拥有会话状态的单一 **Gateway 网关进程**。 -- UI(macOS 应用、Web Control UI、TUI)应通过 Gateway 网关查询会话列表和 token 计数。 +- UI(macOS 应用、web Control UI、TUI)应向 Gateway 网关查询会话列表和 token 计数。 - 在远程模式下,会话文件位于远程主机上;“检查你本地 Mac 上的文件”并不能反映 Gateway 网关实际使用的内容。 --- ## 两层持久化 -OpenClaw 通过两层来持久化会话: +OpenClaw 通过两层持久化保存会话: 1. **会话存储(`sessions.json`)** - 键值映射:`sessionKey -> SessionEntry` - - 小巧、可变、可安全编辑(或删除条目) - - 跟踪会话元数据(当前会话 ID、最后活动时间、开关、token 计数器等) + - 体积小、可变、安全,可编辑(或删除条目) + - 跟踪会话元数据(当前会话 id、最近活动时间、开关、token 计数器等) 2. **转录(`.jsonl`)** - - 具有树结构的追加式转录(条目带有 `id` + `parentId`) + - 采用树结构的追加式转录(条目包含 `id` + `parentId`) - 存储实际对话 + 工具调用 + 压缩摘要 - - 用于为后续轮次重建模型上下文 + - 用于为未来轮次重建模型上下文 --- @@ -74,25 +74,25 @@ OpenClaw 通过 `src/config/sessions.ts` 解析这些路径。 --- -## 存储维护与磁盘控制 +## 存储维护和磁盘控制 -会话持久化为 `sessions.json` 和转录产物提供自动维护控制(`session.maintenance`): +会话持久化为 `sessions.json` 和转录产物提供了自动维护控制(`session.maintenance`): - `mode`:`warn`(默认)或 `enforce` -- `pruneAfter`:陈旧条目的保留期限阈值(默认 `30d`) -- `maxEntries`:`sessions.json` 中条目数上限(默认 `500`) -- `rotateBytes`:`sessions.json` 过大时轮转(默认 `10mb`) -- `resetArchiveRetention`:`*.reset.` 转录归档的保留期(默认与 `pruneAfter` 相同;`false` 表示禁用清理) +- `pruneAfter`:过期条目的年龄阈值(默认 `30d`) +- `maxEntries`:`sessions.json` 中的条目上限(默认 `500`) +- `rotateBytes`:当 `sessions.json` 过大时轮转(默认 `10mb`) +- `resetArchiveRetention`:`*.reset.` 转录归档的保留期(默认:与 `pruneAfter` 相同;`false` 表示禁用清理) - `maxDiskBytes`:可选的会话目录磁盘预算 - `highWaterBytes`:清理后的可选目标值(默认是 `maxDiskBytes` 的 `80%`) 磁盘预算清理的执行顺序(`mode: "enforce"`): 1. 优先删除最旧的归档或孤立转录产物。 -2. 如果仍高于目标值,则逐出最旧的会话条目及其转录文件。 -3. 持续执行,直到使用量低于或等于 `highWaterBytes`。 +2. 如果仍高于目标值,则驱逐最旧的会话条目及其转录文件。 +3. 持续执行,直到使用量小于等于 `highWaterBytes`。 -在 `mode: "warn"` 下,OpenClaw 会报告潜在逐出项,但不会修改存储或文件。 +在 `mode: "warn"` 下,OpenClaw 会报告潜在驱逐项,但不会修改存储/文件。 按需运行维护: @@ -103,69 +103,69 @@ openclaw sessions cleanup --enforce --- -## Cron 会话与运行日志 +## 定时任务会话和运行日志 -隔离的 cron 运行也会创建会话条目/转录,并具有专用保留控制: +隔离的 cron 运行也会创建会话条目/转录,并且它们有专门的保留控制: - `cron.sessionRetention`(默认 `24h`)会从会话存储中清理旧的隔离 cron 运行会话(`false` 表示禁用)。 -- `cron.runLog.maxBytes` + `cron.runLog.keepLines` 会清理 `~/.openclaw/cron/runs/.jsonl` 文件(默认分别为 `2_000_000` 字节和 `2000` 行)。 +- `cron.runLog.maxBytes` + `cron.runLog.keepLines` 会清理 `~/.openclaw/cron/runs/.jsonl` 文件(默认:`2_000_000` 字节和 `2000` 行)。 --- ## 会话键(`sessionKey`) -`sessionKey` 用于标识你处于_哪个对话桶_中(路由 + 隔离)。 +`sessionKey` 用于标识你当前处于 _哪个对话桶_ 中(路由 + 隔离)。 常见模式: - 主/直接聊天(每个智能体):`agent::`(默认 `main`) - 群组:`agent:::group:` -- 房间/频道(Discord/Slack):`agent:::channel:` 或 `...:room:` +- 房间/渠道(Discord/Slack):`agent:::channel:` 或 `...:room:` - Cron:`cron:` - Webhook:`hook:`(除非被覆盖) -规范规则记录在 [/concepts/session](/zh-CN/concepts/session) 中。 +规范规则见 [/concepts/session](/zh-CN/concepts/session)。 --- -## 会话 ID(`sessionId`) +## 会话 id(`sessionId`) -每个 `sessionKey` 都指向一个当前 `sessionId`(继续该对话的转录文件)。 +每个 `sessionKey` 都指向当前的 `sessionId`(即继续该对话的转录文件)。 经验规则: - **重置**(`/new`、`/reset`)会为该 `sessionKey` 创建新的 `sessionId`。 -- **每日重置**(默认是 Gateway 网关主机本地时间凌晨 4:00)会在跨过重置边界后的下一条消息时创建新的 `sessionId`。 -- **空闲过期**(`session.reset.idleMinutes` 或旧版 `session.idleMinutes`)会在消息于空闲窗口后到达时创建新的 `sessionId`。当每日重置和空闲过期同时配置时,以先到期者为准。 -- **线程父级分叉保护**(`session.parentForkMaxTokens`,默认 `100000`)会在父会话已经过大时跳过父转录分叉;新线程将从头开始。设置为 `0` 可禁用。 +- **每日重置**(默认是 Gateway 网关主机本地时间凌晨 4:00)会在越过重置边界后的下一条消息上创建新的 `sessionId`。 +- **空闲过期**(`session.reset.idleMinutes` 或旧版 `session.idleMinutes`)会在消息于空闲窗口之后到达时创建新的 `sessionId`。当同时配置每日重置和空闲过期时,以先到者为准。 +- **线程父级分叉保护**(`session.parentForkMaxTokens`,默认 `100000`)会在父会话已过大时跳过父转录分叉;新线程将从空白开始。设为 `0` 可禁用。 -实现细节:该决策发生在 `src/auto-reply/reply/session.ts` 中的 `initSessionState()`。 +实现细节:该决策发生在 `src/auto-reply/reply/session.ts` 的 `initSessionState()` 中。 --- -## 会话存储模式(`sessions.json`) +## 会话存储 schema(`sessions.json`) 存储的值类型是 `src/config/sessions.ts` 中的 `SessionEntry`。 关键字段(非完整列表): -- `sessionId`:当前转录 ID(除非设置了 `sessionFile`,否则文件名由此派生) -- `updatedAt`:最后活动时间戳 +- `sessionId`:当前转录 id(除非设置了 `sessionFile`,否则文件名由它推导) +- `updatedAt`:最近活动时间戳 - `sessionFile`:可选的显式转录路径覆盖 - `chatType`:`direct | group | room`(帮助 UI 和发送策略) -- `provider`、`subject`、`room`、`space`、`displayName`:用于群组/频道标签的元数据 +- `provider`、`subject`、`room`、`space`、`displayName`:用于群组/渠道标签的元数据 - 开关: - `thinkingLevel`、`verboseLevel`、`reasoningLevel`、`elevatedLevel` - `sendPolicy`(按会话覆盖) - 模型选择: - `providerOverride`、`modelOverride`、`authProfileOverride` -- token 计数器(尽力而为 / 依赖 provider): +- token 计数器(尽力而为 / 依赖提供商): - `inputTokens`、`outputTokens`、`totalTokens`、`contextTokens` - `compactionCount`:此会话键完成自动压缩的次数 -- `memoryFlushAt`:上次压缩前内存刷新时间戳 -- `memoryFlushCompactionCount`:上次刷新运行时的压缩计数 +- `memoryFlushAt`:最近一次压缩前记忆刷新的时间戳 +- `memoryFlushCompactionCount`:上一次刷新运行时的压缩计数 -该存储可安全编辑,但 Gateway 网关才是权威:随着会话运行,它可能会重写或重新注入条目。 +该存储可以安全编辑,但 Gateway 网关是权威来源:会话运行时它可能重写或重新填充条目。 --- @@ -173,57 +173,60 @@ openclaw sessions cleanup --enforce 转录由 `@mariozechner/pi-coding-agent` 的 `SessionManager` 管理。 -该文件为 JSONL: +该文件为 JSONL 格式: -- 第一行:会话头(`type: "session"`,包含 `id`、`cwd`、`timestamp` 和可选的 `parentSession`) -- 之后:带有 `id` + `parentId` 的会话条目(树结构) +- 第一行:会话头(`type: "session"`,包含 `id`、`cwd`、`timestamp`、可选的 `parentSession`) +- 后续:带有 `id` + `parentId` 的会话条目(树结构) 值得注意的条目类型: - `message`:用户/助手/`toolResult` 消息 -- `custom_message`:由扩展注入、_会_进入模型上下文的消息(可对 UI 隐藏) -- `custom`:_不会_进入模型上下文的扩展状态 +- `custom_message`:由扩展注入、_会_ 进入模型上下文的消息(可对 UI 隐藏) +- `custom`:_不会_ 进入模型上下文的扩展状态 - `compaction`:持久化的压缩摘要,带有 `firstKeptEntryId` 和 `tokensBefore` -- `branch_summary`:导航树分支时的持久化摘要 +- `branch_summary`:导航树分支时持久化的摘要 -OpenClaw 有意**不会**“修正”转录;Gateway 网关使用 `SessionManager` 读取/写入它们。 +OpenClaw 有意**不会**“修正”转录;Gateway 网关使用 `SessionManager` 读写它们。 --- -## 上下文窗口与已跟踪 token +## 上下文窗口 vs 已跟踪 token -这里涉及两个不同概念: +这里有两个不同的概念: -1. **模型上下文窗口**:每个模型的硬上限(模型可见 token 数) +1. **模型上下文窗口**:每个模型的硬上限(模型可见的 token) 2. **会话存储计数器**:写入 `sessions.json` 的滚动统计(用于 `/status` 和仪表板) -如果你在调优限制: +如果你正在调整限制: -- 上下文窗口来自模型目录(并且可通过配置覆盖)。 -- 存储中的 `contextTokens` 是运行时估算/报告值;不要将其视为严格保证。 +- 上下文窗口来自模型目录(也可通过配置覆盖)。 +- 存储中的 `contextTokens` 是运行时估算/报告值;不要把它当作严格保证。 -更多信息请参阅 [/token-use](/zh-CN/reference/token-use)。 +更多信息请参见 [/token-use](/zh-CN/reference/token-use)。 --- ## 压缩:它是什么 -压缩会将较早的对话总结为转录中持久化的 `compaction` 条目,并保留最近消息不变。 +压缩会将较早的对话总结成转录中的持久化 `compaction` 条目,并保留最近消息不变。 -压缩后,后续轮次将看到: +压缩后,未来轮次会看到: - 压缩摘要 - `firstKeptEntryId` 之后的消息 -压缩是**持久化的**(不同于会话修剪)。请参阅 [/concepts/session-pruning](/zh-CN/concepts/session-pruning)。 +压缩是**持久的**(不同于会话裁剪)。参见 [/concepts/session-pruning](/zh-CN/concepts/session-pruning)。 -## 压缩块边界与工具配对 +## 压缩分块边界和工具配对 -当 OpenClaw 将较长转录拆分为压缩块时,它会保持助手工具调用与其匹配的 `toolResult` 条目成对出现。 +当 OpenClaw 将长转录拆分为压缩分块时,它会保持 +助手工具调用与其对应 `toolResult` 条目配对。 -- 如果 token 占比分割点落在工具调用和其结果之间,OpenClaw 会将边界移动到助手工具调用消息处,而不是拆开这一对。 -- 如果尾部 `toolResult` 块原本会使压缩块超出目标大小,OpenClaw 会保留这个待处理工具块,并保持未摘要的尾部完整。 -- 已中止/出错的工具调用块不会阻止待处理分割继续进行。 +- 如果 token 占比分割点落在工具调用和其结果之间,OpenClaw + 会将边界移动到助手工具调用消息处,而不是拆散这一对。 +- 如果尾部的工具结果块原本会将分块推过目标大小,OpenClaw + 会保留这段待处理工具块,并保持未总结的尾部完整。 +- 已中止/报错的工具调用块不会让待处理分割持续保持打开状态。 --- @@ -235,8 +238,8 @@ OpenClaw 有意**不会**“修正”转录;Gateway 网关使用 `SessionManag (`request_too_large`、`context length exceeded`、`input exceeds the maximum number of tokens`、`input token count exceeds the maximum number of input tokens`、`input is too long for the model`、`ollama error: context length -exceeded`,以及类似的 provider 特定变体)→ 压缩 → 重试。 -2. **阈值维护**:在成功完成一轮后,当: +exceeded`,以及类似的提供商形式变体)→ 压缩 → 重试。 +2. **阈值维护**:在一次成功轮次之后,当: `contextTokens > contextWindow - reserveTokens` @@ -245,7 +248,7 @@ exceeded`,以及类似的 provider 特定变体)→ 压缩 → 重试。 - `contextWindow` 是模型的上下文窗口 - `reserveTokens` 是为提示词 + 下一次模型输出预留的余量 -这些是 Pi 运行时语义(OpenClaw 消费这些事件,但由 Pi 决定何时压缩)。 +这些是 Pi 运行时语义(OpenClaw 会消费这些事件,但由 Pi 决定何时压缩)。 --- @@ -263,21 +266,21 @@ Pi 的压缩设置位于 Pi settings 中: } ``` -OpenClaw 还会对嵌入式运行强制执行一个安全下限: +OpenClaw 还会为嵌入式运行施加一个安全下限: - 如果 `compaction.reserveTokens < reserveTokensFloor`,OpenClaw 会将其提高。 -- 默认下限为 `20000` token。 +- 默认下限是 `20000` token。 - 设置 `agents.defaults.compaction.reserveTokensFloor: 0` 可禁用该下限。 -- 如果它已经更高,OpenClaw 不会更改。 +- 如果它本来就更高,OpenClaw 不会改动。 -原因:在压缩不可避免之前,为多轮“整理”操作(例如内存写入)保留足够余量。 +原因:在压缩变得不可避免之前,为多轮“维护”操作(例如记忆写入)预留足够余量。 实现:`src/agents/pi-settings.ts` 中的 `ensurePiCompactionReserveTokens()` (由 `src/agents/pi-embedded-runner.ts` 调用)。 --- -## 面向用户的可见接口 +## 面向用户的可见表面 你可以通过以下方式观察压缩和会话状态: @@ -288,33 +291,37 @@ OpenClaw 还会对嵌入式运行强制执行一个安全下限: --- -## 静默整理(`NO_REPLY`) +## 静默维护(`NO_REPLY`) -OpenClaw 支持用于后台任务的“静默”轮次,在这种情况下用户不应看到中间输出。 +OpenClaw 支持“静默”轮次,用于用户不应看到中间输出的后台任务。 -约定如下: +约定: -- 助手以精确的静默标记 `NO_REPLY` / `no_reply` 开始输出,以表示“不要向用户发送回复”。 -- OpenClaw 会在投递层剥离/抑制它。 -- 对精确静默标记的抑制不区分大小写,因此当整个负载仅为该静默标记时,`NO_REPLY` 和 +- 助手以精确的静默 token `NO_REPLY` / + `no_reply` 开头输出,以表示“不要向用户发送回复”。 +- OpenClaw 会在交付层将其剥离/抑制。 +- 对精确静默 token 的抑制不区分大小写,因此当整个负载仅为该静默 token 时,`NO_REPLY` 和 `no_reply` 都算有效。 -- 这仅适用于真正的后台/不投递轮次;它并不是处理普通用户可执行请求的捷径。 +- 这仅用于真正的后台/不交付轮次;它不是普通可执行用户请求的快捷方式。 -从 `2026.1.10` 开始,OpenClaw 还会在部分分块以 `NO_REPLY` 开头时抑制**草稿/输入中流式传输**,这样静默操作就不会在轮次中途泄露部分输出。 +自 `2026.1.10` 起,OpenClaw 还会在 +部分分块以 `NO_REPLY` 开头时抑制**草稿/输入中流式传输**,这样静默操作就不会在轮次中途泄露部分输出。 --- -## 压缩前“内存刷新”(已实现) +## 压缩前“记忆刷新”(已实现) -目标:在自动压缩发生之前,运行一个静默的智能体轮次,将持久状态写入磁盘(例如智能体工作区中的 `memory/YYYY-MM-DD.md`),以便压缩不会擦除关键上下文。 +目标:在自动压缩发生之前,运行一个静默的智能体轮次,将持久 +状态写入磁盘(例如智能体工作区中的 `memory/YYYY-MM-DD.md`),这样压缩就不会 +擦除关键上下文。 -OpenClaw 使用的是**阈值前刷新**方法: +OpenClaw 使用**预阈值刷新**方案: -1. 监控会话上下文使用情况。 -2. 当其越过一个“软阈值”(低于 Pi 的压缩阈值)时,运行一个静默的 - “立即写入内存”指令给智能体。 -3. 使用精确静默标记 `NO_REPLY` / `no_reply`,使用户 - 完全看不到任何内容。 +1. 监控会话上下文使用量。 +2. 当它越过“软阈值”(低于 Pi 的压缩阈值)时,向智能体运行一个静默的 + “现在写入记忆”指令。 +3. 使用精确的静默 token `NO_REPLY` / `no_reply`,这样用户就看不到 + 任何内容。 配置(`agents.defaults.compaction.memoryFlush`): @@ -325,22 +332,24 @@ OpenClaw 使用的是**阈值前刷新**方法: 说明: -- 默认的 prompt/system prompt 包含 `NO_REPLY` 提示,以抑制投递。 -- 每个压缩周期仅运行一次刷新(在 `sessions.json` 中跟踪)。 -- 刷新仅对嵌入式 Pi 会话运行(CLI 后端会跳过)。 +- 默认的 prompt/system prompt 包含一个 `NO_REPLY` 提示,用于抑制 + 交付。 +- 每个压缩周期只运行一次刷新(在 `sessions.json` 中跟踪)。 +- 刷新仅对嵌入式 Pi 会话运行。 - 当会话工作区为只读(`workspaceAccess: "ro"` 或 `"none"`)时,会跳过刷新。 -- 有关工作区文件布局和写入模式,请参阅 [Memory](/zh-CN/concepts/memory)。 +- 关于工作区文件布局和写入模式,请参见 [Memory](/zh-CN/concepts/memory)。 -Pi 也会在扩展 API 中公开 `session_before_compact` hook,但 OpenClaw 的刷新逻辑目前位于 Gateway 网关侧。 +Pi 在扩展 API 中也暴露了一个 `session_before_compact` hook,但 OpenClaw 的 +刷新逻辑目前位于 Gateway 网关侧。 --- -## 故障排除清单 +## 故障排除检查清单 -- 会话键错误?从 [/concepts/session](/zh-CN/concepts/session) 开始,并在 `/status` 中确认 `sessionKey`。 -- 存储与转录不匹配?确认 Gateway 网关主机和 `openclaw status` 给出的存储路径。 +- 会话键不对?从 [/concepts/session](/zh-CN/concepts/session) 开始,并在 `/status` 中确认 `sessionKey`。 +- 存储与转录不匹配?确认 Gateway 网关主机和 `openclaw status` 显示的存储路径。 - 压缩过于频繁?检查: - 模型上下文窗口(是否过小) - - 压缩设置(对于模型窗口来说,`reserveTokens` 过高可能导致更早压缩) - - `toolResult` 膨胀:启用/调优会话修剪 -- 静默轮次泄露?确认回复以 `NO_REPLY` 开头(大小写不敏感的精确标记),并且你使用的构建版本包含流式抑制修复。 + - 压缩设置(对于模型窗口而言,`reserveTokens` 过高会导致更早压缩) + - 工具结果膨胀:启用/调整会话裁剪 +- 静默轮次泄露了输出?确认回复以 `NO_REPLY` 开头(大小写不敏感的精确 token),并且你使用的是包含流式传输抑制修复的构建版本。 diff --git a/docs/zh-CN/tools/acp-agents.md b/docs/zh-CN/tools/acp-agents.md index 50136789b..abc314d01 100644 --- a/docs/zh-CN/tools/acp-agents.md +++ b/docs/zh-CN/tools/acp-agents.md @@ -1,102 +1,99 @@ --- read_when: - 通过 ACP 运行编码 harness - - 在消息渠道上设置对话绑定的 ACP 会话 - - 将消息渠道对话绑定到持久化 ACP 会话 - - 故障排除 ACP 后端和插件接线 + - 在消息渠道上设置绑定到会话的 ACP 会话 + - 将消息渠道会话绑定到持久化 ACP 会话 + - 排查 ACP 后端和插件接线问题 - 从聊天中操作 /acp 命令 -summary: 通过 ACP 后端插件,为 Codex、Claude Code、Cursor、Gemini CLI、OpenClaw ACP 及其他 harness 智能体使用 ACP 运行时会话 +summary: 通过 ACP 运行时会话使用 Codex、Claude Code、Cursor、Gemini CLI、OpenClaw ACP 及其他 harness 智能体 title: ACP 智能体 x-i18n: - generated_at: "2026-04-05T17:51:09Z" + generated_at: "2026-04-05T18:16:39Z" model: gpt-5.4 provider: openai - source_hash: fb651ab39b05e537398623ee06cb952a5a07730fc75d3f7e0de20dd3128e72c6 + source_hash: 302f3fe25b1ffe0576592b6e0ad9e8a5781fa5702b31d508d9ba8908f7df33bd source_path: tools/acp-agents.md workflow: 15 --- # ACP 智能体 -[Agent Client Protocol (ACP)](https://agentclientprotocol.com/) 会话让 OpenClaw 能够通过 ACP 后端插件运行外部编码 harness(例如 Pi、Claude Code、Codex、Cursor、Copilot、OpenClaw ACP、OpenCode、Gemini CLI,以及其他受支持的 ACPX harness)。 +[Agent Client Protocol(ACP)](https://agentclientprotocol.com/) 会话让 OpenClaw 能够通过 ACP 后端插件运行外部编码 harness(例如 Pi、Claude Code、Codex、Cursor、Copilot、OpenClaw ACP、OpenCode、Gemini CLI,以及其他受支持的 ACPX harness)。 -如果你用自然语言告诉 OpenClaw “在 Codex 中运行这个”或“在线程里启动 Claude Code”,OpenClaw 应该将该请求路由到 ACP 运行时(而不是原生子智能体运行时)。每次 ACP 会话生成都会作为一个[后台任务](/zh-CN/automation/tasks)进行跟踪。 +如果你用自然语言要求 OpenClaw “在 Codex 中运行这个”或“在一个线程中启动 Claude Code”,OpenClaw 应该把该请求路由到 ACP 运行时(而不是原生子智能体运行时)。每次 ACP 会话生成都会被跟踪为一个[后台任务](/zh-CN/automation/tasks)。 -如果你希望 Codex 或 Claude Code 作为外部 MCP 客户端直接连接 -到现有的 OpenClaw 渠道对话,请使用 [`openclaw mcp serve`](/cli/mcp) -而不是 ACP。 +如果你希望 Codex 或 Claude Code 作为外部 MCP 客户端直接连接到现有的 OpenClaw 渠道会话,请使用 [`openclaw mcp serve`](/cli/mcp),而不是 ACP。 -## 我该看哪个页面? +## 我需要哪个页面? -这里有三个相近的功能区域,很容易混淆: +这里有三个相近的功能面,很容易混淆: -| 你想要…… | 使用这个 | 说明 | -| ---------------------------------------------------------------------------------- | ------------------------------------- | ----------------------------------------------------------------------------------------------------------- | -| 通过 OpenClaw _运行_ Codex、Claude Code、Gemini CLI 或其他外部 harness | 本页:ACP 智能体 | 聊天绑定会话、`/acp spawn`、`sessions_spawn({ runtime: "acp" })`、后台任务、运行时控制 | -| 将一个 OpenClaw Gateway 网关会话 _作为_ ACP 服务器暴露给编辑器或客户端 | [`openclaw acp`](/cli/acp) | 桥接模式。IDE / 客户端通过 stdio / WebSocket 使用 ACP 与 OpenClaw 通信 | -| 将本地 AI CLI 复用为纯文本后备模型 | [CLI Backends](/zh-CN/gateway/cli-backends) | 不是 ACP。没有 OpenClaw 工具、没有 ACP 控制、没有 harness 运行时 | +| 你想要... | 使用这个 | 说明 | +| ---------------------------------------------------------------------------------- | -------------------------- | ----------------------------------------------------------------------------------------------------------- | +| 通过 OpenClaw 运行 Codex、Claude Code、Gemini CLI 或其他外部 harness | 本页:ACP 智能体 | 聊天绑定会话、`/acp spawn`、`sessions_spawn({ runtime: "acp" })`、后台任务、运行时控制 | +| 将 OpenClaw Gateway 网关会话作为 ACP 服务器暴露给编辑器或客户端 | [`openclaw acp`](/cli/acp) | 桥接模式。IDE/客户端 通过 stdio/WebSocket 与 OpenClaw 进行 ACP 通信 | -## 开箱即用吗? +## 这可以开箱即用吗? 通常可以。 - 全新安装现在默认启用内置的 `acpx` 运行时插件。 - 内置 `acpx` 插件会优先使用其插件本地固定版本的 `acpx` 二进制文件。 -- 启动时,OpenClaw 会探测该二进制文件,并在需要时自行修复。 +- 启动时,OpenClaw 会探测该二进制文件,并在需要时自我修复。 - 如果你想快速检查就绪状态,请先从 `/acp doctor` 开始。 -首次使用时仍可能发生的情况: +首次使用时仍然可能发生的情况: -- 某个目标 harness 适配器可能会在你首次使用该 harness 时按需通过 `npx` 获取。 -- 该 harness 对应的厂商认证仍然必须已经存在于主机上。 -- 如果主机没有 npm / 网络访问能力,首次运行的适配器获取可能失败,直到缓存被预热或适配器通过其他方式安装。 +- 第一次使用某个 harness 时,目标 harness 适配器可能会按需通过 `npx` 获取。 +- 该 harness 的供应商认证仍然必须已存在于主机上。 +- 如果主机没有 npm/网络访问权限,首次运行的适配器获取可能会失败,直到缓存被预热或适配器通过其他方式安装。 示例: -- `/acp spawn codex`:OpenClaw 应该已经可以引导 `acpx`,但 Codex ACP 适配器可能仍需要首次运行获取。 -- `/acp spawn claude`:Claude ACP 适配器同理,另外还需要该主机上的 Claude 侧认证。 +- `/acp spawn codex`:OpenClaw 应已准备好引导 `acpx`,但 Codex ACP 适配器仍可能需要首次运行获取。 +- `/acp spawn claude`:Claude ACP 适配器也是同样情况,另外该主机上还需要 Claude 侧认证。 -## 快速操作流程 +## 面向操作员的快速流程 -如果你想要一个实用的 `/acp` 操作手册,请使用这个流程: +当你想要一份实用的 `/acp` 操作手册时,请使用这个流程: 1. 生成一个会话: - `/acp spawn codex --bind here` - `/acp spawn codex --mode persistent --thread auto` -2. 在已绑定的对话或线程中工作(或显式指定该会话键)。 +2. 在绑定的会话或线程中工作(或显式指定该会话键)。 3. 检查运行时状态: - `/acp status` -4. 根据需要调整运行时选项: +4. 按需调整运行时选项: - `/acp model ` - `/acp permissions ` - `/acp timeout ` -5. 在不替换上下文的情况下推动一个活动会话: +5. 在不替换上下文的情况下推动一个活跃会话: - `/acp steer tighten logging and continue` 6. 停止工作: - - `/acp cancel`(停止当前回合),或 + - `/acp cancel`(停止当前轮次),或 - `/acp close`(关闭会话 + 移除绑定) -## 面向人工操作的快速开始 +## 面向人工用户的快速开始 -自然请求示例: +自然语言请求示例: -- “把这个 Discord 渠道绑定到 Codex。” -- “在这里的线程里启动一个持久 Codex 会话并保持聚焦。” -- “把这个作为一次性 Claude Code ACP 会话运行,并总结结果。” -- “把这个 iMessage 聊天绑定到 Codex,并将后续消息保持在同一个工作区。” -- “为这个任务使用 Gemini CLI 在线程中运行,然后将后续消息保留在同一个线程中。” +- “将这个 Discord 渠道绑定到 Codex。” +- “在这里的一个线程中启动一个持久化 Codex 会话,并保持聚焦。” +- “将这个作为一次性 Claude Code ACP 会话运行,并总结结果。” +- “将这个 iMessage 聊天绑定到 Codex,并让后续消息保持在同一个工作区。” +- “在一个线程中用 Gemini CLI 处理这个任务,然后让后续消息继续留在同一个线程中。” -OpenClaw 应该执行的操作: +OpenClaw 应执行的操作: 1. 选择 `runtime: "acp"`。 2. 解析请求的 harness 目标(`agentId`,例如 `codex`)。 -3. 如果请求了当前对话绑定,并且当前渠道支持,则将 ACP 会话绑定到该对话。 -4. 否则,如果请求了线程绑定,并且当前渠道支持,则将 ACP 会话绑定到该线程。 -5. 将后续已绑定消息路由到同一个 ACP 会话,直到取消聚焦 / 关闭 / 过期。 +3. 如果请求绑定当前会话,并且当前活跃渠道支持此功能,则将 ACP 会话绑定到该会话。 +4. 否则,如果请求线程绑定,并且当前渠道支持此功能,则将 ACP 会话绑定到该线程。 +5. 将后续绑定消息继续路由到同一个 ACP 会话,直到失焦/关闭/过期。 ## ACP 与子智能体 -当你需要外部 harness 运行时时,请使用 ACP。当你需要 OpenClaw 原生的委派运行时,请使用子智能体。 +如果你想要外部 harness 运行时,请使用 ACP。如果你想要 OpenClaw 原生委托运行,请使用子智能体。 | 区域 | ACP 会话 | 子智能体运行 | | ------------- | ------------------------------------- | ---------------------------------- | @@ -105,121 +102,118 @@ OpenClaw 应该执行的操作: | 主要命令 | `/acp ...` | `/subagents ...` | | 生成工具 | `sessions_spawn` 搭配 `runtime:"acp"` | `sessions_spawn`(默认运行时) | -另请参阅 [Sub-agents](/zh-CN/tools/subagents)。 +另请参见 [Sub-agents](/zh-CN/tools/subagents)。 ## ACP 如何运行 Claude Code -通过 ACP 运行 Claude Code 时,堆栈如下: +对于通过 ACP 运行的 Claude Code,堆栈如下: 1. OpenClaw ACP 会话控制平面 2. 内置 `acpx` 运行时插件 3. Claude ACP 适配器 -4. Claude 侧运行时 / 会话机制 +4. Claude 侧运行时/会话机制 重要区别: -- ACP Claude 是一个 harness 会话,具有 ACP 控制、会话恢复、后台任务跟踪,以及可选的对话 / 线程绑定。 -- CLI 后端是独立的纯文本本地后备运行时。参见 [CLI Backends](/zh-CN/gateway/cli-backends)。 +- ACP Claude 是一个 harness 会话,具备 ACP 控制、会话恢复、后台任务跟踪,以及可选的会话/线程绑定。 + 对操作员来说,实用规则是: -对于操作员来说,实用规则是: +- 想要 `/acp spawn`、可绑定会话、运行时控制或持久化 harness 工作:请使用 ACP -- 如果你想要 `/acp spawn`、可绑定会话、运行时控制或持久化 harness 工作:使用 ACP -- 如果你想通过原始 CLI 获得简单的本地文本后备:使用 CLI 后端 +## 绑定会话 -## 已绑定会话 +### 当前会话绑定 -### 当前对话绑定 - -当你希望当前对话在不创建子线程的情况下变成持久的 ACP 工作区时,请使用 `/acp spawn --bind here`。 +当你希望当前会话成为一个持久的 ACP 工作区,而不创建子线程时,请使用 `/acp spawn --bind here`。 行为: -- OpenClaw 继续负责渠道传输、认证、安全和投递。 -- 当前对话会固定到新生成的 ACP 会话键。 -- 该对话中的后续消息会路由到同一个 ACP 会话。 -- `/new` 和 `/reset` 会原地重置同一个已绑定 ACP 会话。 -- `/acp close` 会关闭会话并移除当前对话绑定。 +- OpenClaw 继续拥有渠道传输、认证、安全和消息投递。 +- 当前会话会被固定到已生成的 ACP 会话键。 +- 该会话中的后续消息会被路由到同一个 ACP 会话。 +- `/new` 和 `/reset` 会在原地重置同一个已绑定的 ACP 会话。 +- `/acp close` 会关闭会话并移除当前会话绑定。 这在实践中的含义: -- `--bind here` 会保留同一个聊天界面。在 Discord 上,当前渠道仍然是当前渠道。 -- 如果你是在生成新的工作,`--bind here` 仍然可以创建一个新的 ACP 会话。绑定会将该会话附加到当前对话。 +- `--bind here` 会保持同一个聊天界面。在 Discord 上,当前渠道仍然是当前渠道。 +- `--bind here` 在你生成全新工作时仍然可以创建一个新的 ACP 会话。该绑定会把该会话附加到当前会话。 - `--bind here` 本身不会创建子 Discord 线程或 Telegram 话题。 -- ACP 运行时仍然可以拥有自己的工作目录(`cwd`)或由后端管理的磁盘工作区。该运行时工作区与聊天界面是分离的,并不意味着一定会创建新的消息线程。 -- 如果你生成到另一个 ACP 智能体,且未传递 `--cwd`,OpenClaw 默认会继承**目标智能体的**工作区,而不是请求者的工作区。 -- 如果该继承的工作区路径缺失(`ENOENT` / `ENOTDIR`),OpenClaw 会回退到后端默认 cwd,而不是悄悄复用错误的目录树。 -- 如果该继承的工作区存在但无法访问(例如 `EACCES`),生成会返回真实的访问错误,而不是丢弃 `cwd`。 +- ACP 运行时仍然可以拥有自己的工作目录(`cwd`)或后端管理的磁盘工作区。该运行时工作区与聊天界面是分离的,并不意味着会新建消息线程。 +- 如果你生成到另一个 ACP 智能体且没有传入 `--cwd`,OpenClaw 默认会继承**目标智能体的**工作区,而不是请求方的工作区。 +- 如果继承的工作区路径缺失(`ENOENT`/`ENOTDIR`),OpenClaw 会回退到后端默认 cwd,而不是默默复用错误的目录树。 +- 如果继承的工作区存在但无法访问(例如 `EACCES`),生成操作会返回真实的访问错误,而不是丢弃 `cwd`。 心智模型: -- 聊天界面:人们继续交流的地方(`Discord channel`、`Telegram topic`、`iMessage chat`) -- ACP 会话:OpenClaw 路由到的持久 Codex / Claude / Gemini 运行时状态 -- 子线程 / 话题:仅由 `--thread ...` 创建的可选额外消息界面 -- 运行时工作区:harness 运行的文件系统位置(`cwd`、仓库检出、后端工作区) +- 聊天界面:人们继续交谈的地方(`Discord channel`、`Telegram topic`、`iMessage chat`) +- ACP 会话:OpenClaw 路由到的持久化 Codex/Claude/Gemini 运行时状态 +- 子线程/话题:仅在 `--thread ...` 时创建的可选额外消息界面 +- 运行时工作区:harness 运行所在的文件系统位置(`cwd`、仓库检出、后端工作区) 示例: -- `/acp spawn codex --bind here`:保留当前聊天,生成或附加一个 Codex ACP 会话,并将此后的消息路由到它 -- `/acp spawn codex --thread auto`:OpenClaw 可能会创建一个子线程 / 话题,并在其中绑定 ACP 会话 +- `/acp spawn codex --bind here`:保留当前聊天,生成或附加一个 Codex ACP 会话,并将此处后续消息路由到它 +- `/acp spawn codex --thread auto`:OpenClaw 可能创建一个子线程/话题,并将 ACP 会话绑定到那里 - `/acp spawn codex --bind here --cwd /workspace/repo`:与上面相同的聊天绑定,但 Codex 在 `/workspace/repo` 中运行 -当前对话绑定支持: +当前会话绑定支持: -- 声明支持当前对话绑定的聊天 / 消息渠道可以通过共享的对话绑定路径使用 `--bind here`。 -- 具有自定义线程 / 话题语义的渠道仍可在同一共享接口后提供按渠道的规范化。 -- `--bind here` 始终表示“原地绑定当前对话”。 -- 通用的当前对话绑定使用共享的 OpenClaw 绑定存储,并可在正常 Gateway 网关重启后保留。 +- 声明支持当前会话绑定的聊天/消息渠道可以通过共享会话绑定路径使用 `--bind here`。 +- 具有自定义线程/话题语义的渠道仍可在相同共享接口之后提供渠道特定的规范化。 +- `--bind here` 始终表示“原地绑定当前会话”。 +- 通用当前会话绑定使用共享的 OpenClaw 绑定存储,并可在正常 Gateway 网关重启后保留。 说明: -- 在 `/acp spawn` 上,`--bind here` 和 `--thread ...` 互斥。 +- 在 `/acp spawn` 中,`--bind here` 与 `--thread ...` 互斥。 - 在 Discord 上,`--bind here` 会原地绑定当前渠道或线程。只有当 OpenClaw 需要为 `--thread auto|here` 创建子线程时,才需要 `spawnAcpSessions`。 -- 如果活动渠道未暴露当前对话 ACP 绑定,OpenClaw 会返回明确的不支持消息。 -- `resume` 和“新会话”问题是 ACP 会话问题,而不是渠道问题。你可以在不改变当前聊天界面的情况下复用或替换运行时状态。 +- 如果活跃渠道不暴露当前会话 ACP 绑定,OpenClaw 会返回清晰的不支持消息。 +- `resume` 和“新建会话”问题是 ACP 会话问题,不是渠道问题。你可以复用或替换运行时状态,而无需更改当前聊天界面。 ### 线程绑定会话 当某个渠道适配器启用了线程绑定时,ACP 会话可以绑定到线程: - OpenClaw 将一个线程绑定到目标 ACP 会话。 -- 该线程中的后续消息会路由到已绑定的 ACP 会话。 -- ACP 输出会回投到同一个线程。 -- 取消聚焦 / 关闭 / 归档 / 空闲超时或最大时长到期都会移除该绑定。 +- 该线程中的后续消息会被路由到已绑定的 ACP 会话。 +- ACP 输出会回送到同一个线程。 +- 失焦/关闭/归档/空闲超时或最长存活时间到期会移除绑定。 -线程绑定支持取决于适配器。如果当前渠道适配器不支持线程绑定,OpenClaw 会返回明确的不支持 / 不可用消息。 +线程绑定支持取决于适配器。如果当前活跃渠道适配器不支持线程绑定,OpenClaw 会返回清晰的不支持/不可用消息。 -线程绑定 ACP 所需的功能标志: +线程绑定 ACP 所需功能开关: - `acp.enabled=true` -- `acp.dispatch.enabled` 默认开启(设置为 `false` 以暂停 ACP 分发) -- 已启用渠道适配器的 ACP 线程生成标志(适配器特定) +- `acp.dispatch.enabled` 默认开启(设为 `false` 可暂停 ACP 分发) +- 渠道适配器 ACP 线程生成开关已启用(特定于适配器) - Discord:`channels.discord.threadBindings.spawnAcpSessions=true` - Telegram:`channels.telegram.threadBindings.spawnAcpSessions=true` ### 支持线程的渠道 -- 任何暴露会话 / 线程绑定能力的渠道适配器。 +- 任何暴露会话/线程绑定能力的渠道适配器。 - 当前内置支持: - - Discord 线程 / 渠道 - - Telegram 话题(群组 / 超级群组中的论坛话题和私信话题) -- 插件渠道也可通过同一绑定接口添加支持。 + - Discord 线程/渠道 + - Telegram 话题(群组/超级群组中的论坛话题和私信话题) +- 插件渠道也可以通过相同绑定接口增加支持。 -## 按渠道的特定设置 +## 渠道特定设置 -对于非临时性工作流,请在顶层 `bindings[]` 条目中配置持久化 ACP 绑定。 +对于非临时工作流,请在顶层 `bindings[]` 条目中配置持久化 ACP 绑定。 ### 绑定模型 -- `bindings[].type="acp"` 用于标记一个持久化 ACP 对话绑定。 -- `bindings[].match` 用于标识目标对话: +- `bindings[].type="acp"` 表示持久化 ACP 会话绑定。 +- `bindings[].match` 标识目标会话: - Discord 渠道或线程:`match.channel="discord"` + `match.peer.id=""` - Telegram 论坛话题:`match.channel="telegram"` + `match.peer.id=":topic:"` - - BlueBubbles 私信 / 群聊:`match.channel="bluebubbles"` + `match.peer.id=""` + - BlueBubbles 私信/群聊:`match.channel="bluebubbles"` + `match.peer.id=""` 对于稳定的群组绑定,优先使用 `chat_id:*` 或 `chat_identifier:*`。 - - iMessage 私信 / 群聊:`match.channel="imessage"` + `match.peer.id=""` + - iMessage 私信/群聊:`match.channel="imessage"` + `match.peer.id=""` 对于稳定的群组绑定,优先使用 `chat_id:*`。 - `bindings[].agentId` 是所属的 OpenClaw 智能体 ID。 -- 可选 ACP 覆盖项位于 `bindings[].acp` 下: +- 可选 ACP 覆盖位于 `bindings[].acp` 下: - `mode`(`persistent` 或 `oneshot`) - `label` - `cwd` @@ -227,7 +221,7 @@ OpenClaw 应该执行的操作: ### 每个智能体的运行时默认值 -使用 `agents.list[].runtime` 为每个智能体定义一次 ACP 默认值: +使用 `agents.list[].runtime` 为每个智能体一次性定义 ACP 默认值: - `agents.list[].runtime.type="acp"` - `agents.list[].runtime.acp.agent`(harness ID,例如 `codex` 或 `claude`) @@ -324,17 +318,17 @@ ACP 绑定会话的覆盖优先级: 行为: - OpenClaw 会在使用前确保配置的 ACP 会话存在。 -- 该渠道或话题中的消息会路由到配置的 ACP 会话。 -- 在已绑定对话中,`/new` 和 `/reset` 会原地重置同一个 ACP 会话键。 -- 临时运行时绑定(例如由线程聚焦流程创建的绑定)在存在时仍然适用。 -- 对于未显式指定 `cwd` 的跨智能体 ACP 生成,OpenClaw 会从智能体配置中继承目标智能体工作区。 -- 缺失的继承工作区路径会回退到后端默认 cwd;而非缺失导致的访问失败会作为生成错误直接返回。 +- 该渠道或话题中的消息会被路由到已配置的 ACP 会话。 +- 在已绑定会话中,`/new` 和 `/reset` 会原地重置同一个 ACP 会话键。 +- 临时运行时绑定(例如由线程聚焦流程创建的绑定)在存在时仍会生效。 +- 对于没有显式 `cwd` 的跨智能体 ACP 生成,OpenClaw 会从智能体配置继承目标智能体工作区。 +- 缺失的继承工作区路径会回退到后端默认 cwd;非缺失的访问失败会作为生成错误暴露出来。 ## 启动 ACP 会话(接口) ### 从 `sessions_spawn` 启动 -使用 `runtime: "acp"` 从智能体回合或工具调用中启动 ACP 会话。 +使用 `runtime: "acp"` 可从智能体轮次或工具调用中启动 ACP 会话。 ```json { @@ -348,29 +342,29 @@ ACP 绑定会话的覆盖优先级: 说明: -- `runtime` 默认是 `subagent`,因此对于 ACP 会话请显式设置 `runtime: "acp"`。 -- 如果省略 `agentId`,在已配置时 OpenClaw 会使用 `acp.defaultAgent`。 -- `mode: "session"` 需要 `thread: true` 才能保持一个持久化的绑定对话。 +- `runtime` 默认为 `subagent`,因此对于 ACP 会话需要显式设置 `runtime: "acp"`。 +- 如果省略 `agentId`,OpenClaw 会在配置了 `acp.defaultAgent` 时使用它。 +- `mode: "session"` 需要 `thread: true` 才能保持一个持久化绑定会话。 接口详情: -- `task`(必需):发送给 ACP 会话的初始提示。 -- `runtime`(ACP 必需):必须为 `"acp"`。 -- `agentId`(可选):ACP 目标 harness ID。若已设置,则回退到 `acp.defaultAgent`。 +- `task`(必填):发送到 ACP 会话的初始提示。 +- `runtime`(ACP 必填):必须为 `"acp"`。 +- `agentId`(可选):ACP 目标 harness ID。如果设置了 `acp.defaultAgent`,则回退到它。 - `thread`(可选,默认 `false`):在支持时请求线程绑定流程。 - `mode`(可选):`run`(一次性)或 `session`(持久化)。 - 默认值为 `run` - - 如果 `thread: true` 且省略 `mode`,OpenClaw 可根据运行时路径默认采用持久化行为 + - 如果 `thread: true` 且省略 mode,OpenClaw 可能按运行时路径默认使用持久化行为 - `mode: "session"` 需要 `thread: true` -- `cwd`(可选):请求的运行时工作目录(由后端 / 运行时策略校验)。如果省略,ACP 生成会在已配置时继承目标智能体工作区;缺失的继承路径会回退到后端默认值,而真实访问错误会直接返回。 -- `label`(可选):面向操作员的标签,用于会话 / 横幅文本。 -- `resumeSessionId`(可选):恢复现有 ACP 会话,而不是新建会话。智能体会通过 `session/load` 重放其对话历史。需要 `runtime: "acp"`。 -- `streamTo`(可选):`"parent"` 会将初始 ACP 运行进度摘要作为系统事件流式回传给请求方会话。 - - 在可用时,接受的响应会包含 `streamLogPath`,指向一个按会话划分的 JSONL 日志(`.acp-stream.jsonl`),你可以对其执行 tail 以查看完整转发历史。 +- `cwd`(可选):请求的运行时工作目录(由后端/运行时策略验证)。如果省略,ACP 生成会在配置时继承目标智能体工作区;缺失的继承路径会回退到后端默认值,而真实访问错误会被返回。 +- `label`(可选):用于会话/横幅文本中的面向操作员标签。 +- `resumeSessionId`(可选):恢复一个现有 ACP 会话,而不是新建会话。该智能体会通过 `session/load` 重放其会话历史。需要 `runtime: "acp"`。 +- `streamTo`(可选):`"parent"` 会将初始 ACP 运行进度摘要作为系统事件流式返回给请求方会话。 + - 可用时,接受的响应可包含 `streamLogPath`,指向一个作用域为该会话的 JSONL 日志(`.acp-stream.jsonl`),你可以对其执行 tail 以查看完整转发历史。 ### 恢复现有会话 -使用 `resumeSessionId` 来继续先前的 ACP 会话,而不是重新开始。智能体会通过 `session/load` 重放其对话历史,因此它可以带着完整的前文继续工作。 +使用 `resumeSessionId` 继续先前的 ACP 会话,而不是重新开始。该智能体会通过 `session/load` 重放其会话历史,因此它会带着之前的完整上下文继续。 ```json { @@ -383,41 +377,38 @@ ACP 绑定会话的覆盖优先级: 常见用例: -- 将一个 Codex 会话从你的笔记本交接到手机——告诉你的智能体从你上次停下的地方继续 -- 继续你在 CLI 中以交互方式启动的编码会话,现在通过智能体以无头方式运行 -- 接续因 Gateway 网关重启或空闲超时而中断的工作 +- 将一个 Codex 会话从你的笔记本电脑切换到手机 —— 告诉你的智能体从你离开的地方继续 +- 继续一个你先前在 CLI 中以交互方式启动、现在通过智能体以无头方式继续的编码会话 +- 接着处理一个因 Gateway 网关重启或空闲超时而中断的工作 说明: -- `resumeSessionId` 需要 `runtime: "acp"`——如果与子智能体运行时一起使用,会返回错误。 -- `resumeSessionId` 会恢复上游 ACP 对话历史;`thread` 和 `mode` 仍会正常应用于你正在创建的新 OpenClaw 会话,因此 `mode: "session"` 仍然需要 `thread: true`。 +- `resumeSessionId` 需要 `runtime: "acp"` —— 如果与子智能体运行时一起使用,会返回错误。 +- `resumeSessionId` 会恢复上游 ACP 会话历史;`thread` 和 `mode` 仍会正常应用到你正在创建的新 OpenClaw 会话,因此 `mode: "session"` 仍然需要 `thread: true`。 - 目标智能体必须支持 `session/load`(Codex 和 Claude Code 支持)。 -- 如果找不到会话 ID,生成会以明确错误失败——不会静默回退到新会话。 +- 如果找不到该会话 ID,生成会以清晰错误失败 —— 不会静默回退为新会话。 -### 操作员冒烟测试 +### 面向操作员的 smoke 测试 -在 Gateway 网关部署之后,如果你希望快速进行一次在线检查,确认 ACP 生成 -确实端到端可用,而不仅仅是通过了单元测试,请使用这个方法。 +当你在 Gateway 网关部署后想进行一次快速 live 检查,确认 ACP 生成确实在端到端工作,而不只是通过了单元测试时,请使用这个流程。 推荐门槛: -1. 验证目标主机上已部署的 Gateway 网关版本 / commit。 -2. 确认已部署的源代码在 - `src/gateway/sessions-patch.ts` 中包含 ACP 血缘接受逻辑(`subagent:* or acp:* sessions`)。 -3. 打开一个临时 ACPX 桥接会话,连接到一个在线智能体(例如 - `jpclawhq` 上的 `razor(main)`)。 -4. 要求该智能体调用 `sessions_spawn`,参数如下: +1. 在目标主机上验证已部署的 Gateway 网关版本/提交。 +2. 确认已部署源码在 `src/gateway/sessions-patch.ts` 中包含 ACP 血统接受逻辑(`subagent:* or acp:* sessions`)。 +3. 打开一个到 live 智能体的临时 ACPX 桥接会话(例如 `jpclawhq` 上的 `razor(main)`)。 +4. 要求该智能体调用 `sessions_spawn`,参数为: - `runtime: "acp"` - `agentId: "codex"` - `mode: "run"` - task:`Reply with exactly LIVE-ACP-SPAWN-OK` -5. 验证智能体报告: +5. 验证该智能体报告: - `accepted=yes` - 一个真实的 `childSessionKey` - 没有校验器错误 -6. 清理临时 ACPX 桥接会话。 +6. 清理该临时 ACPX 桥接会话。 -发给在线智能体的提示示例: +发送给 live 智能体的提示示例: ```text Use the sessions_spawn tool now with runtime: "acp", agentId: "codex", and mode: "run". @@ -427,29 +418,26 @@ Then report only: accepted=; childSessionKey=; error=` - `--label ` -参见 [Slash Commands](/zh-CN/tools/slash-commands)。 +请参见 [Slash Commands](/zh-CN/tools/slash-commands)。 ## 会话目标解析 -大多数 `/acp` 操作都接受一个可选会话目标(`session-key`、`session-id` 或 `session-label`)。 +大多数 `/acp` 操作接受一个可选的会话目标(`session-key`、`session-id` 或 `session-label`)。 解析顺序: 1. 显式目标参数(或 `/acp steer` 的 `--session`) - 先尝试键 - - 再尝试 UUID 形状的会话 ID - - 然后尝试标签 -2. 当前线程绑定(如果此对话 / 线程已绑定到 ACP 会话) + - 然后尝试 UUID 形状的会话 ID + - 再尝试标签 +2. 当前线程绑定(如果此会话/线程已绑定到某个 ACP 会话) 3. 当前请求方会话回退 -当前对话绑定和线程绑定都会参与步骤 2。 +当前会话绑定和线程绑定都会参与第 2 步。 -如果无法解析任何目标,OpenClaw 会返回明确错误(`Unable to resolve session target: ...`)。 +如果无法解析任何目标,OpenClaw 会返回清晰错误(`Unable to resolve session target: ...`)。 ## 生成绑定模式 @@ -491,15 +479,15 @@ ACP 会话当前运行在主机运行时上,而不是在 OpenClaw 沙箱中。 | 模式 | 行为 | | ------ | ---------------------------------------------------------------------- | -| `here` | 原地绑定当前活动对话;如果当前没有活动对话则失败。 | -| `off` | 不创建当前对话绑定。 | +| `here` | 原地绑定当前活跃会话;如果没有活跃会话则失败。 | +| `off` | 不创建当前会话绑定。 | 说明: -- `--bind here` 是“让这个渠道或聊天由 Codex 驱动”的最简单操作路径。 +- `--bind here` 是“让这个渠道或聊天由 Codex 提供支持”的最简单操作员路径。 - `--bind here` 不会创建子线程。 -- `--bind here` 仅在暴露当前对话绑定支持的渠道上可用。 -- `--bind` 和 `--thread` 不能在同一次 `/acp spawn` 调用中组合使用。 +- `--bind here` 仅适用于暴露当前会话绑定支持的渠道。 +- `--bind` 与 `--thread` 不能在同一个 `/acp spawn` 调用中组合使用。 ## 生成线程模式 @@ -507,17 +495,17 @@ ACP 会话当前运行在主机运行时上,而不是在 OpenClaw 沙箱中。 | 模式 | 行为 | | ------ | --------------------------------------------------------------------------------------------------- | -| `auto` | 在线程中:绑定该线程。在线程外:在支持时创建 / 绑定子线程。 | -| `here` | 要求当前必须处于活动线程中;否则失败。 | -| `off` | 不进行绑定。会话以未绑定状态启动。 | +| `auto` | 在活跃线程中:绑定该线程。在线程外:在支持时创建/绑定一个子线程。 | +| `here` | 要求当前处于活跃线程中;否则失败。 | +| `off` | 不绑定。会话以未绑定方式启动。 | 说明: -- 在非线程绑定界面上,默认行为实际上等同于 `off`。 +- 在不支持线程绑定的界面上,默认行为实际上等同于 `off`。 - 线程绑定生成需要渠道策略支持: - Discord:`channels.discord.threadBindings.spawnAcpSessions=true` - Telegram:`channels.telegram.threadBindings.spawnAcpSessions=true` -- 当你希望固定当前对话而不创建子线程时,请使用 `--bind here`。 +- 当你想固定当前会话而不创建子线程时,请使用 `--bind here`。 ## ACP 控制 @@ -539,45 +527,45 @@ ACP 会话当前运行在主机运行时上,而不是在 OpenClaw 沙箱中。 - `/acp doctor` - `/acp install` -`/acp status` 会显示有效的运行时选项,并在可用时显示运行时级别和后端级别的会话标识符。 +`/acp status` 会显示生效的运行时选项,并在可用时同时显示运行时级和后端级会话标识符。 -某些控制取决于后端能力。如果某个后端不支持某项控制,OpenClaw 会返回明确的不支持控制错误。 +某些控制依赖后端能力。如果后端不支持某个控制,OpenClaw 会返回清晰的“不支持该控制”错误。 ## ACP 命令手册 | 命令 | 作用 | 示例 | | -------------------- | --------------------------------------------------------- | ------------------------------------------------------------- | | `/acp spawn` | 创建 ACP 会话;可选当前绑定或线程绑定。 | `/acp spawn codex --bind here --cwd /repo` | -| `/acp cancel` | 取消目标会话的进行中回合。 | `/acp cancel agent:codex:acp:` | -| `/acp steer` | 向运行中的会话发送引导指令。 | `/acp steer --session support inbox prioritize failing tests` | +| `/acp cancel` | 取消目标会话的进行中轮次。 | `/acp cancel agent:codex:acp:` | +| `/acp steer` | 向正在运行的会话发送引导指令。 | `/acp steer --session support inbox prioritize failing tests` | | `/acp close` | 关闭会话并解除线程目标绑定。 | `/acp close` | | `/acp status` | 显示后端、模式、状态、运行时选项、能力。 | `/acp status` | -| `/acp set-mode` | 设置目标会话的运行时模式。 | `/acp set-mode plan` | -| `/acp set` | 通用运行时配置选项写入。 | `/acp set model openai/gpt-5.4` | -| `/acp cwd` | 设置运行时工作目录覆盖。 | `/acp cwd /Users/user/Projects/repo` | -| `/acp permissions` | 设置审批策略配置文件。 | `/acp permissions strict` | +| `/acp set-mode` | 为目标会话设置运行时模式。 | `/acp set-mode plan` | +| `/acp set` | 写入通用运行时配置选项。 | `/acp set model openai/gpt-5.4` | +| `/acp cwd` | 设置运行时工作目录覆盖值。 | `/acp cwd /Users/user/Projects/repo` | +| `/acp permissions` | 设置审批策略配置档。 | `/acp permissions strict` | | `/acp timeout` | 设置运行时超时(秒)。 | `/acp timeout 120` | -| `/acp model` | 设置运行时模型覆盖。 | `/acp model anthropic/claude-opus-4-6` | +| `/acp model` | 设置运行时模型覆盖值。 | `/acp model anthropic/claude-opus-4-6` | | `/acp reset-options` | 移除会话运行时选项覆盖。 | `/acp reset-options` | | `/acp sessions` | 从存储中列出最近的 ACP 会话。 | `/acp sessions` | -| `/acp doctor` | 后端健康状态、能力、可操作修复。 | `/acp doctor` | +| `/acp doctor` | 后端健康状态、能力、可执行修复。 | `/acp doctor` | | `/acp install` | 打印确定性的安装和启用步骤。 | `/acp install` | -`/acp sessions` 会读取当前已绑定或请求方会话的存储。接受 `session-key`、`session-id` 或 `session-label` 标记的命令,会通过 Gateway 网关会话发现来解析目标,包括自定义的按智能体 `session.store` 根目录。 +`/acp sessions` 会读取当前已绑定会话或请求方会话的存储。接受 `session-key`、`session-id` 或 `session-label` 标记的命令,会通过 Gateway 网关会话发现来解析目标,包括每个智能体自定义的 `session.store` 根目录。 ## 运行时选项映射 -`/acp` 提供便捷命令和通用设置器。 +`/acp` 既有便捷命令,也有通用设置器。 -等效操作: +等价操作: - `/acp model ` 映射到运行时配置键 `model`。 - `/acp permissions ` 映射到运行时配置键 `approval_policy`。 - `/acp timeout ` 映射到运行时配置键 `timeout`。 -- `/acp cwd ` 会直接更新运行时 cwd 覆盖。 +- `/acp cwd ` 会直接更新运行时 cwd 覆盖值。 - `/acp set ` 是通用路径。 - 特殊情况:`key=cwd` 使用 cwd 覆盖路径。 -- `/acp reset-options` 会清除目标会话的所有运行时覆盖项。 +- `/acp reset-options` 会清除目标会话的所有运行时覆盖值。 ## acpx harness 支持(当前) @@ -598,10 +586,10 @@ ACP 会话当前运行在主机运行时上,而不是在 OpenClaw 沙箱中。 - `pi` - `qwen` -当 OpenClaw 使用 acpx 后端时,除非你的 acpx 配置定义了自定义智能体别名,否则 `agentId` 应优先使用这些值。 -如果你的本地 Cursor 安装仍将 ACP 暴露为 `agent acp`,请在你的 acpx 配置中覆盖 `cursor` 智能体命令,而不是更改内置默认值。 +当 OpenClaw 使用 acpx 后端时,除非你的 acpx 配置定义了自定义智能体别名,否则应优先将这些值用于 `agentId`。 +如果你本地安装的 Cursor 仍将 ACP 暴露为 `agent acp`,请在你的 acpx 配置中覆盖 `cursor` 智能体命令,而不是更改内置默认值。 -直接使用 acpx CLI 也可以通过 `--agent ` 指向任意适配器,但这个原始逃生口是 acpx CLI 的功能(不是常规的 OpenClaw `agentId` 路径)。 +直接使用 acpx CLI 也可以通过 `--agent ` 定位任意适配器,但这个原始逃生口是 acpx CLI 功能(不是 OpenClaw 正常的 `agentId` 路径)。 ## 必需配置 @@ -611,7 +599,7 @@ ACP 会话当前运行在主机运行时上,而不是在 OpenClaw 沙箱中。 { acp: { enabled: true, - // 可选。默认值为 true;设置为 false 可在保留 /acp 控制的同时暂停 ACP 分发。 + // 可选。默认是 true;设为 false 可暂停 ACP 分发,同时保留 /acp 控制。 dispatch: { enabled: true }, backend: "acpx", defaultAgent: "codex", @@ -665,34 +653,32 @@ ACP 会话当前运行在主机运行时上,而不是在 OpenClaw 沙箱中。 } ``` -如果线程绑定 ACP 生成不工作,请先验证适配器功能标志: +如果线程绑定的 ACP 生成无法工作,请先验证适配器功能开关: - Discord:`channels.discord.threadBindings.spawnAcpSessions=true` -当前对话绑定不需要创建子线程。它们需要一个活动对话上下文和一个暴露 ACP 对话绑定的渠道适配器。 +当前会话绑定不需要创建子线程。它们需要一个活跃会话上下文,以及一个暴露 ACP 会话绑定的渠道适配器。 -参见 [Configuration Reference](/zh-CN/gateway/configuration-reference)。 +请参见 [Configuration Reference](/zh-CN/gateway/configuration-reference)。 ## acpx 后端的插件设置 -全新安装默认启用内置的 `acpx` 运行时插件,因此 ACP -通常无需手动安装插件即可工作。 +全新安装默认启用内置 `acpx` 运行时插件,因此 ACP 通常无需手动安装插件即可工作。 -先从这里开始: +请先执行: ```text /acp doctor ``` -如果你禁用了 `acpx`、通过 `plugins.allow` / `plugins.deny` 拒绝了它,或者希望 -切换到本地开发检出,请使用显式插件路径: +如果你禁用了 `acpx`、通过 `plugins.allow` / `plugins.deny` 拒绝了它,或者想切换到本地开发检出,请使用显式插件路径: ```bash openclaw plugins install acpx openclaw config set plugins.entries.acpx.enabled true ``` -开发期间从本地工作区安装: +开发期间的本地工作区安装: ```bash openclaw plugins install ./path/to/local/acpx-plugin @@ -708,14 +694,14 @@ openclaw plugins install ./path/to/local/acpx-plugin 默认情况下,内置 acpx 后端插件(`acpx`)使用插件本地固定版本的二进制文件: -1. 命令默认使用 ACPX 插件包内插件本地的 `node_modules/.bin/acpx`。 -2. 预期版本默认使用扩展固定版本。 -3. 启动时会立即将 ACP 后端注册为未就绪状态。 -4. 一个后台确保任务会验证 `acpx --version`。 +1. 命令默认指向 ACPX 插件包中的插件本地 `node_modules/.bin/acpx`。 +2. 预期版本默认采用扩展固定版本。 +3. 启动时立即将 ACP 后端注册为未就绪。 +4. 一个后台 ensure 作业会验证 `acpx --version`。 5. 如果插件本地二进制文件缺失或版本不匹配,它会运行: `npm install --omit=dev --no-save acpx@`,然后重新验证。 -你可以在插件配置中覆盖命令 / 版本: +你可以在插件配置中覆盖命令/版本: ```json { @@ -738,52 +724,45 @@ openclaw plugins install ./path/to/local/acpx-plugin - `command` 接受绝对路径、相对路径或命令名(`acpx`)。 - 相对路径从 OpenClaw 工作区目录解析。 - `expectedVersion: "any"` 会禁用严格版本匹配。 -- 当 `command` 指向自定义二进制文件 / 路径时,会禁用插件本地自动安装。 +- 当 `command` 指向自定义二进制文件/路径时,插件本地自动安装会被禁用。 - 在后端健康检查运行期间,OpenClaw 启动仍然是非阻塞的。 -参见 [Plugins](/zh-CN/tools/plugin)。 +请参见 [Plugins](/zh-CN/tools/plugin)。 ### 自动依赖安装 -当你使用 `npm install -g openclaw` 全局安装 OpenClaw 时,acpx -运行时依赖(特定平台的二进制文件)会通过 postinstall hook 自动安装。如果自动安装失败,Gateway 网关仍会正常启动, -并通过 `openclaw acp doctor` 报告缺失的依赖。 +当你通过 `npm install -g openclaw` 全局安装 OpenClaw 时,acpx 运行时依赖(平台特定二进制文件)会通过 postinstall hook 自动安装。如果自动安装失败,Gateway 网关仍会正常启动,并通过 `openclaw acp doctor` 报告缺失依赖。 ### 插件工具 MCP 桥接 -默认情况下,ACPX 会话**不会**将 OpenClaw 插件已注册的工具暴露给 -ACP harness。 +默认情况下,ACPX 会话**不会**向 ACP harness 暴露 OpenClaw 插件注册的工具。 -如果你希望 Codex 或 Claude Code 之类的 ACP 智能体调用已安装的 -OpenClaw 插件工具,例如记忆 recall / store,请启用专用桥接: +如果你希望 Codex 或 Claude Code 之类的 ACP 智能体调用已安装的 OpenClaw 插件工具,例如 memory recall/store,请启用专用桥接: ```bash openclaw config set plugins.entries.acpx.config.pluginToolsMcpBridge true ``` -这会执行以下操作: +其作用是: -- 在 ACPX 会话引导中注入一个名为 `openclaw-plugin-tools` 的内置 MCP 服务器。 -- 暴露已安装且已启用的 OpenClaw - 插件所注册的插件工具。 -- 保持该功能为显式启用,默认关闭。 +- 将一个名为 `openclaw-plugin-tools` 的内置 MCP 服务器注入到 ACPX 会话引导中。 +- 暴露已安装并启用的 OpenClaw 插件已经注册的插件工具。 +- 保持该功能显式启用,且默认关闭。 安全与信任说明: -- 这会扩展 ACP harness 的工具暴露面。 -- ACP 智能体只能访问 Gateway 网关中已激活的插件工具。 -- 应将其视为与允许这些插件在 - OpenClaw 本身中执行相同的信任边界。 -- 启用前请审查已安装插件。 +- 这会扩展 ACP harness 的工具面。 +- ACP 智能体只能访问 Gateway 网关中已经活跃的插件工具。 +- 应将其视为与允许这些插件在 OpenClaw 本身中执行相同的信任边界。 +- 启用前请检查已安装的插件。 -自定义 `mcpServers` 仍与以前一样工作。内置插件工具桥接是一个 -额外的选择启用便利功能,而不是通用 MCP 服务器配置的替代品。 +自定义 `mcpServers` 仍和以前一样可用。内置插件工具桥接只是一个额外的可选便利功能,不是通用 MCP 服务器配置的替代品。 ## 权限配置 -ACP 会话以非交互模式运行——没有 TTY 可用于批准或拒绝文件写入和 shell 执行权限提示。acpx 插件提供了两个用于控制权限处理方式的配置键: +ACP 会话以非交互方式运行 —— 没有 TTY 可以批准或拒绝文件写入和 shell 执行权限提示。acpx 插件提供两个控制权限处理方式的配置键: -这些 ACPX harness 权限与 OpenClaw exec 审批是分开的,也与 CLI 后端的厂商绕过标志(例如 Claude CLI 的 `--permission-mode bypassPermissions`)分开。ACPX 的 `approve-all` 是 ACP 会话的 harness 级紧急放开开关。 +这些 ACPX harness 权限与 OpenClaw exec 审批分离,也与 CLI 后端供应商绕过标志(例如 Claude CLI `--permission-mode bypassPermissions`)分离。ACPX `approve-all` 是 ACP 会话在 harness 层级的紧急开关。 ### `permissionMode` @@ -797,12 +776,12 @@ ACP 会话以非交互模式运行——没有 TTY 可用于批准或拒绝文 ### `nonInteractivePermissions` -控制本应显示权限提示但没有可交互 TTY 可用时的处理方式(ACP 会话始终如此)。 +控制当本应显示权限提示但没有可用的交互式 TTY 时(ACP 会话始终如此)会发生什么。 | 值 | 行为 | | ------ | ----------------------------------------------------------------- | | `fail` | 以 `AcpRuntimeError` 中止会话。**(默认)** | -| `deny` | 静默拒绝该权限并继续运行(平稳降级)。 | +| `deny` | 静默拒绝该权限并继续(优雅降级)。 | ### 配置 @@ -813,11 +792,11 @@ openclaw config set plugins.entries.acpx.config.permissionMode approve-all openclaw config set plugins.entries.acpx.config.nonInteractivePermissions fail ``` -修改这些值后请重启 Gateway 网关。 +更改这些值后重启 Gateway 网关。 -> **重要:** OpenClaw 当前默认使用 `permissionMode=approve-reads` 和 `nonInteractivePermissions=fail`。在非交互 ACP 会话中,任何会触发权限提示的写入或执行都可能失败,并报错 `AcpRuntimeError: Permission prompt unavailable in non-interactive mode`。 +> **重要:** OpenClaw 当前默认使用 `permissionMode=approve-reads` 和 `nonInteractivePermissions=fail`。在非交互式 ACP 会话中,任何触发权限提示的写入或执行操作都可能因 `AcpRuntimeError: Permission prompt unavailable in non-interactive mode` 而失败。 > -> 如果你需要限制权限,请将 `nonInteractivePermissions` 设置为 `deny`,这样会话就会平稳降级,而不是崩溃。 +> 如果你需要限制权限,请将 `nonInteractivePermissions` 设为 `deny`,这样会话会优雅降级,而不是崩溃。 ## 故障排除 @@ -825,17 +804,17 @@ openclaw config set plugins.entries.acpx.config.nonInteractivePermissions fail | --------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `ACP runtime backend is not configured` | 后端插件缺失或已禁用。 | 安装并启用后端插件,然后运行 `/acp doctor`。 | | `ACP is disabled by policy (acp.enabled=false)` | ACP 已被全局禁用。 | 设置 `acp.enabled=true`。 | -| `ACP dispatch is disabled by policy (acp.dispatch.enabled=false)` | 普通线程消息的分发已禁用。 | 设置 `acp.dispatch.enabled=true`。 | -| `ACP agent "" is not allowed by policy` | 智能体不在 allowlist 中。 | 使用允许的 `agentId`,或更新 `acp.allowedAgents`。 | -| `Unable to resolve session target: ...` | 错误的键 / ID / 标签标记。 | 运行 `/acp sessions`,复制精确的键 / 标签后重试。 | -| `--bind here requires running /acp spawn inside an active ... conversation` | 在没有活动可绑定对话的情况下使用了 `--bind here`。 | 切换到目标聊天 / 渠道后重试,或使用未绑定生成。 | -| `Conversation bindings are unavailable for .` | 适配器缺少当前对话 ACP 绑定能力。 | 在支持时使用 `/acp spawn ... --thread ...`,配置顶层 `bindings[]`,或切换到受支持的渠道。 | -| `--thread here requires running /acp spawn inside an active ... thread` | 在非线程上下文中使用了 `--thread here`。 | 切换到目标线程,或使用 `--thread auto` / `off`。 | -| `Only can rebind this channel/conversation/thread.` | 另一个用户拥有当前绑定目标。 | 由所有者重新绑定,或使用不同的对话或线程。 | -| `Thread bindings are unavailable for .` | 适配器缺少线程绑定能力。 | 使用 `--thread off`,或切换到受支持的适配器 / 渠道。 | -| `Sandboxed sessions cannot spawn ACP sessions ...` | ACP 运行时在主机侧;请求方会话已沙箱隔离。 | 从已沙箱隔离的会话中使用 `runtime="subagent"`,或从非沙箱隔离会话中运行 ACP 生成。 | -| `sessions_spawn sandbox="require" is unsupported for runtime="acp" ...` | 为 ACP 运行时请求了 `sandbox="require"`。 | 对需要沙箱隔离的情况使用 `runtime="subagent"`,或在非沙箱隔离会话中将 ACP 与 `sandbox="inherit"` 一起使用。 | -| 已绑定会话缺少 ACP 元数据 | ACP 会话元数据已过期 / 被删除。 | 使用 `/acp spawn` 重新创建,然后重新绑定 / 聚焦线程。 | -| `AcpRuntimeError: Permission prompt unavailable in non-interactive mode` | `permissionMode` 在非交互 ACP 会话中阻止了写入 / 执行。 | 将 `plugins.entries.acpx.config.permissionMode` 设置为 `approve-all`,然后重启 Gateway 网关。参见[权限配置](#permission-configuration)。 | -| ACP 会话很早失败且输出很少 | 权限提示被 `permissionMode` / `nonInteractivePermissions` 阻止。 | 检查 Gateway 网关日志中的 `AcpRuntimeError`。如需完整权限,请设置 `permissionMode=approve-all`;如需平稳降级,请设置 `nonInteractivePermissions=deny`。 | -| ACP 会话在完成工作后无限期卡住 | harness 进程已结束,但 ACP 会话未报告完成。 | 使用 `ps aux \| grep acpx` 监控;手动杀掉陈旧进程。 | +| `ACP dispatch is disabled by policy (acp.dispatch.enabled=false)` | 来自普通线程消息的分发已禁用。 | 设置 `acp.dispatch.enabled=true`。 | +| `ACP agent "" is not allowed by policy` | 智能体不在允许列表中。 | 使用允许的 `agentId`,或更新 `acp.allowedAgents`。 | +| `Unable to resolve session target: ...` | 错误的键/ID/标签标记。 | 运行 `/acp sessions`,复制精确的键/标签,然后重试。 | +| `--bind here requires running /acp spawn inside an active ... conversation` | 在没有活跃可绑定会话的情况下使用了 `--bind here`。 | 移动到目标聊天/渠道后重试,或使用未绑定生成。 | +| `Conversation bindings are unavailable for .` | 适配器缺少当前会话 ACP 绑定能力。 | 在支持时使用 `/acp spawn ... --thread ...`、配置顶层 `bindings[]`,或切换到受支持的渠道。 | +| `--thread here requires running /acp spawn inside an active ... thread` | 在线程上下文之外使用了 `--thread here`。 | 移动到目标线程,或使用 `--thread auto`/`off`。 | +| `Only can rebind this channel/conversation/thread.` | 另一个用户拥有当前活跃绑定目标。 | 由所有者重新绑定,或使用其他会话或线程。 | +| `Thread bindings are unavailable for .` | 适配器缺少线程绑定能力。 | 使用 `--thread off`,或切换到受支持的适配器/渠道。 | +| `Sandboxed sessions cannot spawn ACP sessions ...` | ACP 运行时位于主机侧;请求方会话处于沙箱隔离状态。 | 在沙箱会话中使用 `runtime="subagent"`,或从非沙箱会话运行 ACP 生成。 | +| `sessions_spawn sandbox="require" is unsupported for runtime="acp" ...` | 为 ACP 运行时请求了 `sandbox="require"`。 | 如需强制沙箱隔离,请使用 `runtime="subagent"`,或从非沙箱会话使用带 `sandbox="inherit"` 的 ACP。 | +| 绑定会话缺少 ACP 元数据 | ACP 会话元数据已过时/被删除。 | 使用 `/acp spawn` 重新创建,然后重新绑定/聚焦线程。 | +| `AcpRuntimeError: Permission prompt unavailable in non-interactive mode` | `permissionMode` 在非交互式 ACP 会话中阻止了写入/执行。 | 将 `plugins.entries.acpx.config.permissionMode` 设为 `approve-all` 并重启 Gateway 网关。请参见[权限配置](#permission-configuration)。 | +| ACP 会话在很早阶段失败且几乎没有输出 | 权限提示被 `permissionMode`/`nonInteractivePermissions` 阻止。 | 检查 Gateway 网关日志中的 `AcpRuntimeError`。如需完整权限,设置 `permissionMode=approve-all`;如需优雅降级,设置 `nonInteractivePermissions=deny`。 | +| ACP 会话在完成工作后无限期卡住 | harness 进程已结束,但 ACP 会话未报告完成。 | 使用 `ps aux \| grep acpx` 监控;手动终止陈旧进程。 |