chore(i18n): refresh zh-CN translations
This commit is contained in:
parent
f437d175f1
commit
3f256b7384
@ -4,22 +4,22 @@ read_when:
|
||||
summary: Telegram 机器人支持状态、能力和配置
|
||||
title: Telegram
|
||||
x-i18n:
|
||||
generated_at: "2026-04-28T11:46:21Z"
|
||||
generated_at: "2026-04-28T19:31:51Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: 11024ea51a8644e83f64809548dca334007f0db0477ea50feff27daddff69964
|
||||
source_hash: dadd8d0a735b8d8ee75eb44ad0ce018f81c6774aee3bd69f0804e9e731352546
|
||||
source_path: channels/telegram.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
可投入生产,用于通过 grammY 处理机器人私信和群组。长轮询是默认模式;webhook 模式是可选的。
|
||||
可用于生产环境中的机器人私信和群组,基于 grammY。默认模式是长轮询;webhook 模式为可选。
|
||||
|
||||
<CardGroup cols={3}>
|
||||
<Card title="配对" icon="link" href="/zh-CN/channels/pairing">
|
||||
Telegram 的默认私信策略是配对。
|
||||
</Card>
|
||||
<Card title="渠道故障排除" icon="wrench" href="/zh-CN/channels/troubleshooting">
|
||||
跨渠道诊断和修复操作手册。
|
||||
跨渠道诊断和修复手册。
|
||||
</Card>
|
||||
<Card title="Gateway 网关配置" icon="settings" href="/zh-CN/gateway/configuration">
|
||||
完整的渠道配置模式和示例。
|
||||
@ -29,14 +29,14 @@ x-i18n:
|
||||
## 快速设置
|
||||
|
||||
<Steps>
|
||||
<Step title="在 BotFather 中创建机器人 token">
|
||||
打开 Telegram,并与 **@BotFather** 聊天(确认用户名正是 `@BotFather`)。
|
||||
<Step title="在 BotFather 中创建机器人令牌">
|
||||
打开 Telegram 并与 **@BotFather** 聊天(确认用户名正好是 `@BotFather`)。
|
||||
|
||||
运行 `/newbot`,按照提示操作,并保存 token。
|
||||
运行 `/newbot`,按提示操作,并保存令牌。
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="配置 token 和私信策略">
|
||||
<Step title="配置令牌和私信策略">
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -51,8 +51,8 @@ x-i18n:
|
||||
}
|
||||
```
|
||||
|
||||
环境变量回退:`TELEGRAM_BOT_TOKEN=...`(仅默认账号)。
|
||||
Telegram **不**使用 `openclaw channels login telegram`;请在配置/环境变量中配置 token,然后启动 Gateway 网关。
|
||||
环境变量回退:`TELEGRAM_BOT_TOKEN=...`(仅默认账户)。
|
||||
Telegram **不**使用 `openclaw channels login telegram`;请在配置/环境变量中配置令牌,然后启动 Gateway 网关。
|
||||
|
||||
</Step>
|
||||
|
||||
@ -69,33 +69,33 @@ openclaw pairing approve telegram <CODE>
|
||||
</Step>
|
||||
|
||||
<Step title="将机器人添加到群组">
|
||||
将机器人添加到你的群组,然后设置 `channels.telegram.groups` 和 `groupPolicy`,使其与你的访问模型匹配。
|
||||
将机器人添加到你的群组,然后设置 `channels.telegram.groups` 和 `groupPolicy` 以匹配你的访问模型。
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
<Note>
|
||||
Token 解析顺序是账号感知的。实际使用中,配置值优先于环境变量回退,且 `TELEGRAM_BOT_TOKEN` 只适用于默认账号。
|
||||
令牌解析顺序会感知账户。实践中,配置值优先于环境变量回退,而 `TELEGRAM_BOT_TOKEN` 仅适用于默认账户。
|
||||
</Note>
|
||||
|
||||
## Telegram 端设置
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="隐私模式和群组可见性">
|
||||
Telegram 机器人默认使用**隐私模式**,这会限制它们接收的群组消息。
|
||||
Telegram 机器人的默认设置是**隐私模式**,这会限制它们能接收哪些群组消息。
|
||||
|
||||
如果机器人必须看到所有群组消息,可以:
|
||||
|
||||
- 通过 `/setprivacy` 禁用隐私模式,或
|
||||
- 将机器人设为群组管理员。
|
||||
|
||||
切换隐私模式后,请在每个群组中移除并重新添加机器人,以便 Telegram 应用更改。
|
||||
切换隐私模式后,请在每个群组中移除并重新添加机器人,以便 Telegram 应用该更改。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="群组权限">
|
||||
管理员状态在 Telegram 群组设置中控制。
|
||||
管理员状态由 Telegram 群组设置控制。
|
||||
|
||||
管理员机器人会接收所有群组消息,这对于始终在线的群组行为很有用。
|
||||
管理员机器人会接收所有群组消息,这对始终在线的群组行为很有用。
|
||||
|
||||
</Accordion>
|
||||
|
||||
@ -118,17 +118,17 @@ Token 解析顺序是账号感知的。实际使用中,配置值优先于环
|
||||
- `open`(要求 `allowFrom` 包含 `"*"`)
|
||||
- `disabled`
|
||||
|
||||
`channels.telegram.allowFrom` 接受数字 Telegram 用户 ID。接受 `telegram:` / `tg:` 前缀并会将其规范化。
|
||||
`dmPolicy: "allowlist"` 搭配空的 `allowFrom` 会阻止所有私信,并会被配置验证拒绝。
|
||||
设置只会询问数字用户 ID。
|
||||
如果你已升级且配置中包含 `@username` allowlist 条目,请运行 `openclaw doctor --fix` 来解析它们(尽力而为;需要 Telegram 机器人 token)。
|
||||
如果你以前依赖配对存储的 allowlist 文件,`openclaw doctor --fix` 可以在 allowlist 流程中将条目恢复到 `channels.telegram.allowFrom`(例如当 `dmPolicy: "allowlist"` 尚无显式 ID 时)。
|
||||
`channels.telegram.allowFrom` 接受数字 Telegram 用户 ID。`telegram:` / `tg:` 前缀会被接受并规范化。
|
||||
`dmPolicy: "allowlist"` 且 `allowFrom` 为空会阻止所有私信,并会被配置验证拒绝。
|
||||
设置只会要求数字用户 ID。
|
||||
如果你已升级且配置中包含 `@username` 允许列表条目,请运行 `openclaw doctor --fix` 来解析它们(尽力而为;需要 Telegram 机器人令牌)。
|
||||
如果你之前依赖配对存储的允许列表文件,`openclaw doctor --fix` 可以在允许列表流程中将条目恢复到 `channels.telegram.allowFrom`(例如当 `dmPolicy: "allowlist"` 尚无显式 ID 时)。
|
||||
|
||||
对于单所有者机器人,建议使用 `dmPolicy: "allowlist"` 并设置显式数字 `allowFrom` ID,以便将访问策略持久保存在配置中(而不是依赖以前的配对批准)。
|
||||
对于单所有者机器人,建议使用 `dmPolicy: "allowlist"` 并设置显式数字 `allowFrom` ID,以便将访问策略持久保存在配置中(而不是依赖先前的配对批准)。
|
||||
|
||||
常见混淆:私信配对批准并不意味着“此发送者在所有地方都已获得授权”。
|
||||
配对只授予私信访问权限。群组发送者授权仍来自显式配置 allowlist。
|
||||
如果你希望“我授权一次后,私信和群组命令都能工作”,请将你的数字 Telegram 用户 ID 放入 `channels.telegram.allowFrom`。
|
||||
常见困惑:批准私信配对并不意味着“此发送者在所有地方都已获授权”。
|
||||
配对只授予私信访问权限。群组发送者授权仍来自显式配置允许列表。
|
||||
如果你希望“我只授权一次,私信和群组命令都能使用”,请将你的数字 Telegram 用户 ID 放入 `channels.telegram.allowFrom`。
|
||||
|
||||
### 查找你的 Telegram 用户 ID
|
||||
|
||||
@ -144,18 +144,18 @@ Token 解析顺序是账号感知的。实际使用中,配置值优先于环
|
||||
curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
```
|
||||
|
||||
第三方方法(隐私较低):`@userinfobot` 或 `@getidsbot`。
|
||||
第三方方法(隐私性较低):`@userinfobot` 或 `@getidsbot`。
|
||||
|
||||
</Tab>
|
||||
|
||||
<Tab title="群组策略和 allowlist">
|
||||
两个控制项会共同生效:
|
||||
<Tab title="群组策略和允许列表">
|
||||
两项控制会一起生效:
|
||||
|
||||
1. **允许哪些群组**(`channels.telegram.groups`)
|
||||
- 没有 `groups` 配置:
|
||||
- 使用 `groupPolicy: "open"`:任意群组都能通过群组 ID 检查
|
||||
- 使用 `groupPolicy: "open"`:任何群组都可以通过群组 ID 检查
|
||||
- 使用 `groupPolicy: "allowlist"`(默认):群组会被阻止,直到你添加 `groups` 条目(或 `"*"`)
|
||||
- 已配置 `groups`:作为 allowlist 生效(显式 ID 或 `"*"`)
|
||||
- 已配置 `groups`:作为允许列表生效(显式 ID 或 `"*"`)
|
||||
|
||||
2. **群组中允许哪些发送者**(`channels.telegram.groupPolicy`)
|
||||
- `open`
|
||||
@ -164,15 +164,15 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
|
||||
`groupAllowFrom` 用于群组发送者过滤。如果未设置,Telegram 会回退到 `allowFrom`。
|
||||
`groupAllowFrom` 条目应为数字 Telegram 用户 ID(`telegram:` / `tg:` 前缀会被规范化)。
|
||||
不要将 Telegram 群组或超级群组聊天 ID 放入 `groupAllowFrom`。负数聊天 ID 属于 `channels.telegram.groups`。
|
||||
不要将 Telegram 群组或超级群组聊天 ID 放入 `groupAllowFrom`。负数聊天 ID 应放在 `channels.telegram.groups` 下。
|
||||
非数字条目会在发送者授权中被忽略。
|
||||
安全边界(`2026.2.25+`):群组发送者认证**不会**继承私信配对存储批准。
|
||||
配对仍仅适用于私信。对于群组,请设置 `groupAllowFrom` 或每群组/每主题的 `allowFrom`。
|
||||
安全边界(`2026.2.25+`):群组发送者授权**不会**继承私信配对存储批准。
|
||||
配对仅限私信。对于群组,请设置 `groupAllowFrom` 或按群组/按话题设置 `allowFrom`。
|
||||
如果未设置 `groupAllowFrom`,Telegram 会回退到配置中的 `allowFrom`,而不是配对存储。
|
||||
单所有者机器人的实用模式:在 `channels.telegram.allowFrom` 中设置你的用户 ID,不设置 `groupAllowFrom`,并在 `channels.telegram.groups` 下允许目标群组。
|
||||
单所有者机器人的实用模式:在 `channels.telegram.allowFrom` 中设置你的用户 ID,保持 `groupAllowFrom` 未设置,并在 `channels.telegram.groups` 下允许目标群组。
|
||||
运行时说明:如果完全缺少 `channels.telegram`,运行时默认采用故障关闭的 `groupPolicy="allowlist"`,除非显式设置了 `channels.defaults.groupPolicy`。
|
||||
|
||||
示例:允许一个特定群组中的任意成员:
|
||||
示例:允许一个特定群组中的任何成员:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -207,23 +207,23 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
```
|
||||
|
||||
<Warning>
|
||||
常见错误:`groupAllowFrom` 不是 Telegram 群组 allowlist。
|
||||
常见错误:`groupAllowFrom` 不是 Telegram 群组允许列表。
|
||||
|
||||
- 将类似 `-1001234567890` 的负数 Telegram 群组或超级群组聊天 ID 放在 `channels.telegram.groups` 下。
|
||||
- 当你想限制已允许群组中哪些人可以触发机器人时,将类似 `8734062810` 的 Telegram 用户 ID 放在 `groupAllowFrom` 下。
|
||||
- 仅当你希望已允许群组中的任意成员都能与机器人对话时,才使用 `groupAllowFrom: ["*"]`。
|
||||
- 当你想限制已允许群组内哪些人可以触发机器人时,将类似 `8734062810` 的 Telegram 用户 ID 放在 `groupAllowFrom` 下。
|
||||
- 只有当你希望已允许群组的任何成员都能与机器人对话时,才使用 `groupAllowFrom: ["*"]`。
|
||||
|
||||
</Warning>
|
||||
|
||||
</Tab>
|
||||
|
||||
<Tab title="提及行为">
|
||||
群组回复默认要求提及。
|
||||
群组回复默认需要提及。
|
||||
|
||||
提及可以来自:
|
||||
|
||||
- 原生 `@botusername` 提及,或
|
||||
- 以下位置的提及模式:
|
||||
- 以下位置中的提及模式:
|
||||
- `agents.list[].groupChat.mentionPatterns`
|
||||
- `messages.groupChat.mentionPatterns`
|
||||
|
||||
@ -232,7 +232,7 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
- `/activation always`
|
||||
- `/activation mention`
|
||||
|
||||
这些只会更新会话状态。使用配置来持久化。
|
||||
这些只会更新会话状态。使用配置来持久保存。
|
||||
|
||||
持久配置示例:
|
||||
|
||||
@ -251,7 +251,7 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
获取群组聊天 ID:
|
||||
|
||||
- 将群组消息转发给 `@userinfobot` / `@getidsbot`
|
||||
- 或从 `openclaw logs --follow` 读取 `chat.id`
|
||||
- 或从 `openclaw logs --follow` 中读取 `chat.id`
|
||||
- 或检查 Bot API `getUpdates`
|
||||
|
||||
</Tab>
|
||||
@ -261,31 +261,31 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
|
||||
- Telegram 由 Gateway 网关进程拥有。
|
||||
- 路由是确定性的:Telegram 入站会回复到 Telegram(模型不会选择渠道)。
|
||||
- 入站消息会规范化为共享渠道封套,并带有回复元数据和媒体占位符。
|
||||
- 群组会话按群组 ID 隔离。论坛主题会附加 `:topic:<threadId>` 以保持主题隔离。
|
||||
- 私信消息可以携带 `message_thread_id`;OpenClaw 会使用线程感知的会话键路由它们,并保留线程 ID 用于回复。
|
||||
- 入站消息会规范化为共享渠道信封,并带有回复元数据和媒体占位符。
|
||||
- 群组会话按群组 ID 隔离。论坛话题会追加 `:topic:<threadId>` 以保持话题隔离。
|
||||
- 私信消息可以携带 `message_thread_id`;OpenClaw 会使用线程感知会话键进行路由,并为回复保留线程 ID。
|
||||
- 长轮询使用 grammY runner,并按聊天/按线程排序。整体 runner sink 并发使用 `agents.defaults.maxConcurrent`。
|
||||
- 每个 Gateway 网关进程内都会保护长轮询,因此同一时间只有一个活跃轮询器可以使用一个机器人 token。如果你仍然看到 `getUpdates` 409 冲突,可能有另一个 OpenClaw Gateway 网关、脚本或外部轮询器正在使用同一个 token。
|
||||
- 默认情况下,如果 120 秒内没有完成的 `getUpdates` 活性信号,就会触发长轮询看门狗重启。只有当你的部署在长时间运行任务期间仍然看到误判的轮询停滞重启时,才增大 `channels.telegram.pollingStallThresholdMs`。该值以毫秒为单位,允许范围为 `30000` 到 `600000`;支持按账号覆盖。
|
||||
- 每个 Gateway 网关进程内都会保护长轮询,确保同一时间只有一个活跃轮询器可以使用一个机器人令牌。如果你仍然看到 `getUpdates` 409 冲突,很可能是另一个 OpenClaw Gateway 网关、脚本或外部轮询器正在使用同一令牌。
|
||||
- 默认情况下,长轮询看门狗会在 120 秒内没有完成的 `getUpdates` 活性检测后触发重启。只有当你的部署在长时间运行工作期间仍出现误判的轮询停滞重启时,才增加 `channels.telegram.pollingStallThresholdMs`。该值以毫秒为单位,允许范围是 `30000` 到 `600000`;支持按账户覆盖。
|
||||
- Telegram Bot API 不支持已读回执(`sendReadReceipts` 不适用)。
|
||||
|
||||
## 功能参考
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="实时流式预览(消息编辑)">
|
||||
<Accordion title="实时流预览(消息编辑)">
|
||||
OpenClaw 可以实时流式传输部分回复:
|
||||
|
||||
- 直接聊天:预览消息 + `editMessageText`
|
||||
- 群组/主题:预览消息 + `editMessageText`
|
||||
- 群组/话题:预览消息 + `editMessageText`
|
||||
|
||||
要求:
|
||||
|
||||
- `channels.telegram.streaming` 为 `off | partial | block | progress`(默认:`partial`)
|
||||
- `progress` 在 Telegram 上映射到 `partial`(与跨渠道命名兼容)
|
||||
- `progress` 在 Telegram 上映射为 `partial`(兼容跨渠道命名)
|
||||
- `streaming.preview.toolProgress` 控制工具/进度更新是否复用同一条已编辑的预览消息(默认:预览流式传输启用时为 `true`)
|
||||
- 会检测旧版 `channels.telegram.streamMode` 和布尔 `streaming` 值;运行 `openclaw doctor --fix` 将它们迁移到 `channels.telegram.streaming.mode`
|
||||
|
||||
工具进度预览更新是在工具运行时显示的简短“Working...”行,例如命令执行、文件读取、计划更新或补丁摘要。Telegram 默认保持启用这些更新,以匹配 `v2026.4.22` 及之后版本发布的 OpenClaw 行为。若要保留答案文本的已编辑预览,但隐藏工具进度行,请设置:
|
||||
工具进度预览更新是工具运行时显示的简短“Working...”行,例如命令执行、文件读取、计划更新或补丁摘要。Telegram 默认保持启用这些内容,以匹配 `v2026.4.22` 及之后版本发布的 OpenClaw 行为。若要保留答案文本的已编辑预览,但隐藏工具进度行,请设置:
|
||||
|
||||
```json
|
||||
{
|
||||
@ -302,45 +302,45 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
}
|
||||
```
|
||||
|
||||
仅当你想完全禁用 Telegram 预览编辑时,才使用 `streaming.mode: "off"`。当你只想禁用工具进度状态行时,使用 `streaming.preview.toolProgress: false`。
|
||||
仅当你想要只交付最终结果时,才使用 `streaming.mode: "off"`:Telegram 预览编辑会被禁用,通用工具/进度闲聊会被抑制,而不是作为独立的“Working...”消息发送。批准提示、媒体负载和错误仍会通过正常最终交付路由。若你只想在隐藏工具进度状态行的同时保留答案预览编辑,请使用 `streaming.preview.toolProgress: false`。
|
||||
|
||||
对于纯文本回复:
|
||||
|
||||
- 短私信/群组/主题预览:OpenClaw 会保留同一条预览消息,并在原处执行最终编辑
|
||||
- 超过约一分钟的预览:OpenClaw 会将完成的回复作为新的最终消息发送,然后清理预览,因此 Telegram 的可见时间戳会反映完成时间,而不是预览创建时间
|
||||
- 较短的私信/群组/话题预览:OpenClaw 保留同一条预览消息,并在原处执行最终编辑
|
||||
- 超过约一分钟的预览:OpenClaw 会将完成后的回复作为新的最终消息发送,然后清理预览,因此 Telegram 的可见时间戳会反映完成时间,而不是预览创建时间
|
||||
|
||||
对于复杂回复(例如媒体负载),OpenClaw 会回退到正常的最终投递,然后清理预览消息。
|
||||
对于复杂回复(例如媒体负载),OpenClaw 会回退到正常最终交付,然后清理预览消息。
|
||||
|
||||
预览流式传输独立于分块流式传输。当为 Telegram 显式启用分块流式传输时,OpenClaw 会跳过预览流,以避免双重流式传输。
|
||||
预览流式传输独立于分块流式传输。当 Telegram 显式启用分块流式传输时,OpenClaw 会跳过预览流,以避免双重流式传输。
|
||||
|
||||
如果原生草稿传输不可用/被拒绝,OpenClaw 会自动回退到 `sendMessage` + `editMessageText`。
|
||||
|
||||
仅 Telegram 的推理流:
|
||||
仅限 Telegram 的推理流:
|
||||
|
||||
- `/reasoning stream` 会在生成时将推理发送到实时预览
|
||||
- 最终答案会在不包含推理文本的情况下发送
|
||||
- `/reasoning stream` 在生成时将推理发送到实时预览
|
||||
- 最终答案发送时不包含推理文本
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="格式化和 HTML 回退">
|
||||
<Accordion title="格式和 HTML 回退">
|
||||
出站文本使用 Telegram `parse_mode: "HTML"`。
|
||||
|
||||
- Markdown 风格的文本会渲染为 Telegram 安全的 HTML。
|
||||
- 类 Markdown 文本会渲染为 Telegram 安全的 HTML。
|
||||
- 原始模型 HTML 会被转义,以减少 Telegram 解析失败。
|
||||
- 如果 Telegram 拒绝解析后的 HTML,OpenClaw 会重试为纯文本。
|
||||
- 如果 Telegram 拒绝已解析的 HTML,OpenClaw 会以纯文本重试。
|
||||
|
||||
链接预览默认启用,可以通过 `channels.telegram.linkPreview: false` 禁用。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="原生命令和自定义命令">
|
||||
Telegram 命令菜单注册会在启动时通过 `setMyCommands` 处理。
|
||||
Telegram 命令菜单注册在启动时通过 `setMyCommands` 处理。
|
||||
|
||||
原生命令默认值:
|
||||
|
||||
- `commands.native: "auto"` 会为 Telegram 启用原生命令
|
||||
- `commands.native: "auto"` 为 Telegram 启用原生命令
|
||||
|
||||
添加自定义命令菜单项:
|
||||
添加自定义命令菜单条目:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -357,24 +357,24 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
|
||||
规则:
|
||||
|
||||
- 名称会规范化(去掉开头的 `/`,转为小写)
|
||||
- 名称会被规范化(去掉前导 `/`,转为小写)
|
||||
- 有效模式:`a-z`、`0-9`、`_`,长度 `1..32`
|
||||
- 自定义命令不能覆盖原生命令
|
||||
- 冲突/重复项会被跳过并记录日志
|
||||
|
||||
说明:
|
||||
注意:
|
||||
|
||||
- 自定义命令只是菜单项;它们不会自动实现行为
|
||||
- 即使插件/skill 命令未显示在 Telegram 菜单中,输入时仍然可以生效
|
||||
- 自定义命令只是菜单条目;它们不会自动实现行为
|
||||
- 插件/skill 命令即使未显示在 Telegram 菜单中,输入时仍然可以工作
|
||||
|
||||
如果禁用原生命令,内置项会被移除。已配置的自定义/插件命令仍可能注册。
|
||||
如果原生命令被禁用,内置项会被移除。已配置时,自定义/插件命令仍可能注册。
|
||||
|
||||
常见设置失败:
|
||||
|
||||
- `setMyCommands failed` 带有 `BOT_COMMANDS_TOO_MUCH` 表示 Telegram 菜单在裁剪后仍然溢出;请减少插件/skill/自定义命令,或禁用 `channels.telegram.commands.native`。
|
||||
- 当直接使用 Bot API curl 命令可用,但 `deleteWebhook`、`deleteMyCommands` 或 `setMyCommands` 失败并显示 `404: Not Found` 时,可能表示 `channels.telegram.apiRoot` 被设置为了完整的 `/bot<TOKEN>` 端点。`apiRoot` 必须只是 Bot API 根地址,并且 `openclaw doctor --fix` 会移除意外追加的 `/bot<TOKEN>`。
|
||||
- `getMe returned 401` 表示 Telegram 拒绝了已配置的 bot token。请使用当前 BotFather token 更新 `botToken`、`tokenFile` 或 `TELEGRAM_BOT_TOKEN`;OpenClaw 会在轮询前停止,因此这不会报告为 webhook 清理失败。
|
||||
- `setMyCommands failed` 带有网络/获取错误通常表示到 `api.telegram.org` 的出站 DNS/HTTPS 被阻止。
|
||||
- `setMyCommands failed` 带有 `BOT_COMMANDS_TOO_MUCH` 表示 Telegram 菜单在裁剪后仍然溢出;减少插件/skill/自定义命令,或禁用 `channels.telegram.commands.native`。
|
||||
- 当直接 Bot API curl 命令可用,但 `deleteWebhook`、`deleteMyCommands` 或 `setMyCommands` 失败并显示 `404: Not Found` 时,可能表示 `channels.telegram.apiRoot` 被设置成了完整的 `/bot<TOKEN>` 端点。`apiRoot` 必须只是 Bot API 根路径,并且 `openclaw doctor --fix` 会移除意外追加的 `/bot<TOKEN>`。
|
||||
- `getMe returned 401` 表示 Telegram 拒绝了已配置的机器人令牌。使用当前 BotFather 令牌更新 `botToken`、`tokenFile` 或 `TELEGRAM_BOT_TOKEN`;OpenClaw 会在轮询前停止,因此这不会被报告为 webhook 清理失败。
|
||||
- `setMyCommands failed` 带有网络/fetch 错误通常表示到 `api.telegram.org` 的出站 DNS/HTTPS 被阻止。
|
||||
|
||||
### 设备配对命令(`device-pair` 插件)
|
||||
|
||||
@ -385,14 +385,14 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
3. `/pair pending` 列出待处理请求(包括角色/作用域)
|
||||
4. 批准请求:
|
||||
- `/pair approve <requestId>` 用于显式批准
|
||||
- `/pair approve` 在只有一个待处理请求时使用
|
||||
- `/pair approve latest` 用于最近的请求
|
||||
- 只有一个待处理请求时使用 `/pair approve`
|
||||
- `/pair approve latest` 用于最新请求
|
||||
|
||||
设置代码携带一个短期有效的引导 token。内置引导移交会将主节点 token 保持在 `scopes: []`;任何移交的操作员 token 都会被限制在 `operator.approvals`、`operator.read`、`operator.talk.secrets` 和 `operator.write` 内。引导作用域检查带有角色前缀,因此该操作员允许列表只满足操作员请求;非操作员角色仍需要其自身角色前缀下的作用域。
|
||||
设置代码携带短期有效的 bootstrap 令牌。内置 bootstrap 移交会将主节点令牌保持在 `scopes: []`;任何被移交的操作员令牌都会被限制在 `operator.approvals`、`operator.read`、`operator.talk.secrets` 和 `operator.write`。Bootstrap 作用域检查带有角色前缀,因此该操作员 allowlist 只满足操作员请求;非操作员角色仍需要其自身角色前缀下的作用域。
|
||||
|
||||
如果设备使用已更改的认证详情(例如角色/作用域/公钥)重试,之前的待处理请求会被取代,新请求会使用不同的 `requestId`。批准前请重新运行 `/pair pending`。
|
||||
如果设备使用已更改的凭证详细信息(例如角色/作用域/公钥)重试,之前的待处理请求会被取代,新请求会使用不同的 `requestId`。批准前请重新运行 `/pair pending`。
|
||||
|
||||
了解详情:[配对](/zh-CN/channels/pairing#pair-via-telegram-recommended-for-ios)。
|
||||
更多详情:[配对](/zh-CN/channels/pairing#pair-via-telegram-recommended-for-ios)。
|
||||
|
||||
</Accordion>
|
||||
|
||||
@ -437,7 +437,7 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
- `all`
|
||||
- `allowlist`(默认)
|
||||
|
||||
旧版 `capabilities: ["inlineButtons"]` 会映射到 `inlineButtons: "all"`。
|
||||
旧版 `capabilities: ["inlineButtons"]` 映射到 `inlineButtons: "all"`。
|
||||
|
||||
消息操作示例:
|
||||
|
||||
@ -471,16 +471,16 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
- `editMessage`(`chatId`、`messageId`、`content`)
|
||||
- `createForumTopic`(`chatId`、`name`、可选 `iconColor`、`iconCustomEmojiId`)
|
||||
|
||||
渠道消息操作公开了便捷别名(`send`、`react`、`delete`、`edit`、`sticker`、`sticker-search`、`topic-create`)。
|
||||
渠道消息操作会暴露符合人体工学的别名(`send`、`react`、`delete`、`edit`、`sticker`、`sticker-search`、`topic-create`)。
|
||||
|
||||
门控控制项:
|
||||
门控控制:
|
||||
|
||||
- `channels.telegram.actions.sendMessage`
|
||||
- `channels.telegram.actions.deleteMessage`
|
||||
- `channels.telegram.actions.reactions`
|
||||
- `channels.telegram.actions.sticker`(默认:禁用)
|
||||
|
||||
注意:`edit` 和 `topic-create` 目前默认启用,并且没有单独的 `channels.telegram.actions.*` 开关。
|
||||
注意:`edit` 和 `topic-create` 当前默认启用,并且没有单独的 `channels.telegram.actions.*` 开关。
|
||||
运行时发送使用当前有效的配置/密钥快照(启动/重载),因此操作路径不会在每次发送时执行临时 SecretRef 重新解析。
|
||||
|
||||
反应移除语义:[/tools/reactions](/zh-CN/tools/reactions)
|
||||
@ -491,7 +491,7 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
Telegram 支持在生成输出中使用显式回复线程标签:
|
||||
|
||||
- `[[reply_to_current]]` 回复触发消息
|
||||
- `[[reply_to:<id>]]` 回复特定的 Telegram 消息 ID
|
||||
- `[[reply_to:<id>]]` 回复特定 Telegram 消息 ID
|
||||
|
||||
`channels.telegram.replyToMode` 控制处理方式:
|
||||
|
||||
@ -499,29 +499,29 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
- `first`
|
||||
- `all`
|
||||
|
||||
启用回复线程且原始 Telegram 文本或说明文字可用时,OpenClaw 会自动包含原生 Telegram 引用摘录。Telegram 将原生引用文本限制为 1024 个 UTF-16 码元,因此较长消息会从开头开始引用,并在 Telegram 拒绝引用时回退为普通回复。
|
||||
启用回复线程,并且原始 Telegram 文本或标题可用时,OpenClaw 会自动包含原生 Telegram 引用摘录。Telegram 将原生引用文本限制为 1024 个 UTF-16 代码单元,因此较长消息会从开头引用;如果 Telegram 拒绝该引用,则回退为普通回复。
|
||||
|
||||
注意:`off` 会禁用隐式回复线程。显式 `[[reply_to_*]]` 标签仍会被遵循。
|
||||
注意:`off` 会禁用隐式回复串联。显式 `[[reply_to_*]]` 标签仍会被遵守。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="论坛主题和线程行为">
|
||||
<Accordion title="论坛话题和话题串行为">
|
||||
论坛超级群组:
|
||||
|
||||
- 主题会话键会追加 `:topic:<threadId>`
|
||||
- 回复和正在输入状态会指向该主题线程
|
||||
- 主题配置路径:
|
||||
- 话题会话键追加 `:topic:<threadId>`
|
||||
- 回复和正在输入状态会指向该话题串
|
||||
- 话题配置路径:
|
||||
`channels.telegram.groups.<chatId>.topics.<threadId>`
|
||||
|
||||
常规主题(`threadId=1`)的特殊情况:
|
||||
通用话题(`threadId=1`)特例:
|
||||
|
||||
- 发送消息时省略 `message_thread_id`(Telegram 会拒绝 `sendMessage(...thread_id=1)`)
|
||||
- 正在输入动作仍包含 `message_thread_id`
|
||||
- 正在输入操作仍包含 `message_thread_id`
|
||||
|
||||
主题继承:主题条目会继承群组设置,除非被覆盖(`requireMention`、`allowFrom`、`skills`、`systemPrompt`、`enabled`、`groupPolicy`)。
|
||||
`agentId` 仅属于主题,不会从群组默认值继承。
|
||||
话题继承:话题条目会继承群组设置,除非被覆盖(`requireMention`、`allowFrom`、`skills`、`systemPrompt`、`enabled`、`groupPolicy`)。
|
||||
`agentId` 仅属于话题,不会从群组默认值继承。
|
||||
|
||||
**按主题路由智能体**:每个主题都可以通过在主题配置中设置 `agentId` 路由到不同的智能体。这会让每个主题拥有自己隔离的工作区、记忆和会话。示例:
|
||||
**按话题进行智能体路由**:每个话题都可以通过在话题配置中设置 `agentId` 路由到不同的智能体。这让每个话题都有自己隔离的工作区、记忆和会话。示例:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -541,26 +541,26 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
}
|
||||
```
|
||||
|
||||
然后每个主题都有自己的会话键:`agent:zu:telegram:group:-1001234567890:topic:3`
|
||||
随后每个话题都有自己的会话键:`agent:zu:telegram:group:-1001234567890:topic:3`
|
||||
|
||||
**持久 ACP 主题绑定**:论坛主题可以通过顶层类型化 ACP 绑定固定 ACP harness 会话(`bindings[]`,其中 `type: "acp"`、`match.channel: "telegram"`、`peer.kind: "group"`,以及类似 `-1001234567890:topic:42` 的带主题限定的 ID)。目前作用域仅限群组/超级群组中的论坛主题。参见 [ACP 智能体](/zh-CN/tools/acp-agents)。
|
||||
**持久 ACP 话题绑定**:论坛话题可以通过顶层类型化 ACP 绑定(`bindings[]`,其中 `type: "acp"`、`match.channel: "telegram"`、`peer.kind: "group"`,以及类似 `-1001234567890:topic:42` 的带话题限定的 id)固定 ACP harness 会话。目前范围限定为群组/超级群组中的论坛话题。参见 [ACP Agents](/zh-CN/tools/acp-agents)。
|
||||
|
||||
**从聊天中生成绑定线程的 ACP**:`/acp spawn <agent> --thread here|auto` 会将当前主题绑定到新的 ACP 会话;后续消息会直接路由到那里。OpenClaw 会在主题内置顶生成确认消息。需要 `channels.telegram.threadBindings.spawnAcpSessions=true`。
|
||||
**从聊天中生成绑定到话题串的 ACP**:`/acp spawn <agent> --thread here|auto` 会将当前话题绑定到新的 ACP 会话;后续消息会直接路由到那里。OpenClaw 会在话题内置顶生成确认消息。需要 `channels.telegram.threadBindings.spawnAcpSessions=true`。
|
||||
|
||||
模板上下文会公开 `MessageThreadId` 和 `IsForum`。带有 `message_thread_id` 的私信聊天会保留私信路由,但使用线程感知的会话键。
|
||||
模板上下文会暴露 `MessageThreadId` 和 `IsForum`。带有 `message_thread_id` 的私信聊天会保留私信路由,但使用支持话题串的会话键。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Audio, video, and stickers">
|
||||
<Accordion title="音频、视频和贴纸">
|
||||
### 音频消息
|
||||
|
||||
Telegram 会区分语音便签和音频文件。
|
||||
Telegram 会区分语音消息和音频文件。
|
||||
|
||||
- 默认:音频文件行为
|
||||
- 在智能体回复中使用标签 `[[audio_as_voice]]` 可强制作为语音便签发送
|
||||
- 入站语音便签转写会在智能体上下文中被标记为机器生成的、不可信文本;提及检测仍使用原始转写,因此受提及门控的语音消息会继续正常工作。
|
||||
- 在智能体回复中使用标签 `[[audio_as_voice]]` 可强制按语音消息发送
|
||||
- 入站语音消息转录会在智能体上下文中被框定为机器生成的、不可信文本;提及检测仍使用原始转录,因此受提及门控的语音消息会继续工作。
|
||||
|
||||
消息动作示例:
|
||||
消息操作示例:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -574,9 +574,9 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
|
||||
### 视频消息
|
||||
|
||||
Telegram 会区分视频文件和视频便签。
|
||||
Telegram 会区分视频文件和视频消息。
|
||||
|
||||
消息动作示例:
|
||||
消息操作示例:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -588,7 +588,7 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
}
|
||||
```
|
||||
|
||||
视频便签不支持说明文字;提供的消息文本会单独发送。
|
||||
视频消息不支持说明文字;提供的消息文本会单独发送。
|
||||
|
||||
### 贴纸
|
||||
|
||||
@ -610,9 +610,9 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
|
||||
- `~/.openclaw/telegram/sticker-cache.json`
|
||||
|
||||
贴纸会被描述一次(如果可能)并缓存,以减少重复的视觉调用。
|
||||
贴纸会被描述一次(如果可能),并缓存以减少重复的视觉调用。
|
||||
|
||||
启用贴纸动作:
|
||||
启用贴纸操作:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -626,7 +626,7 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
}
|
||||
```
|
||||
|
||||
发送贴纸动作:
|
||||
发送贴纸操作:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -650,8 +650,8 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Reaction notifications">
|
||||
Telegram 表情回应会作为 `message_reaction` 更新到达(与消息载荷分开)。
|
||||
<Accordion title="回应通知">
|
||||
Telegram 回应会作为 `message_reaction` 更新到达(与消息载荷分开)。
|
||||
|
||||
启用后,OpenClaw 会将如下系统事件加入队列:
|
||||
|
||||
@ -662,20 +662,20 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
- `channels.telegram.reactionNotifications`:`off | own | all`(默认:`own`)
|
||||
- `channels.telegram.reactionLevel`:`off | ack | minimal | extensive`(默认:`minimal`)
|
||||
|
||||
注意:
|
||||
说明:
|
||||
|
||||
- `own` 表示仅限用户对机器人发送消息的表情回应(通过已发送消息缓存尽力判断)。
|
||||
- 表情回应事件仍遵守 Telegram 访问控制(`dmPolicy`、`allowFrom`、`groupPolicy`、`groupAllowFrom`);未授权的发送者会被丢弃。
|
||||
- Telegram 不会在表情回应更新中提供线程 ID。
|
||||
- `own` 表示仅限用户对机器人所发送消息的回应(通过已发送消息缓存尽力而为)。
|
||||
- 回应事件仍会遵守 Telegram 访问控制(`dmPolicy`、`allowFrom`、`groupPolicy`、`groupAllowFrom`);未授权的发送者会被丢弃。
|
||||
- Telegram 不会在回应更新中提供话题串 ID。
|
||||
- 非论坛群组会路由到群组聊天会话
|
||||
- 论坛群组会路由到群组常规主题会话(`:topic:1`),而不是确切的原始主题
|
||||
- 论坛群组会路由到群组通用话题会话(`:topic:1`),而不是确切的来源话题
|
||||
|
||||
轮询/webhook 的 `allowed_updates` 会自动包含 `message_reaction`。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Ack reactions">
|
||||
`ackReaction` 会在 OpenClaw 处理入站消息时发送一个确认 emoji。
|
||||
<Accordion title="Ack 回应">
|
||||
当 OpenClaw 正在处理入站消息时,`ackReaction` 会发送确认 emoji。
|
||||
|
||||
解析顺序:
|
||||
|
||||
@ -684,15 +684,15 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
- `messages.ackReaction`
|
||||
- 智能体身份 emoji 回退(`agents.list[].identity.emoji`,否则为 "👀")
|
||||
|
||||
注意:
|
||||
说明:
|
||||
|
||||
- Telegram 期望使用 unicode emoji(例如 "👀")。
|
||||
- 使用 `""` 可对某个渠道或账号禁用反应。
|
||||
- 使用 `""` 可为某个渠道或账号禁用回应。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="来自 Telegram 事件和命令的配置写入">
|
||||
渠道配置写入默认启用(`configWrites !== false`)。
|
||||
默认启用渠道配置写入(`configWrites !== false`)。
|
||||
|
||||
Telegram 触发的写入包括:
|
||||
|
||||
@ -714,28 +714,28 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="长轮询与 webhook">
|
||||
默认使用长轮询。若要使用 webhook 模式,请设置 `channels.telegram.webhookUrl` 和 `channels.telegram.webhookSecret`;可选设置 `webhookPath`、`webhookHost`、`webhookPort`(默认值为 `/telegram-webhook`、`127.0.0.1`、`8787`)。
|
||||
默认使用长轮询。若使用 webhook 模式,请设置 `channels.telegram.webhookUrl` 和 `channels.telegram.webhookSecret`;可选设置 `webhookPath`、`webhookHost`、`webhookPort`(默认值为 `/telegram-webhook`、`127.0.0.1`、`8787`)。
|
||||
|
||||
本地监听器绑定到 `127.0.0.1:8787`。对于公网入口,可以在本地端口前放置反向代理,或有意设置 `webhookHost: "0.0.0.0"`。
|
||||
|
||||
webhook 模式会先验证请求保护、Telegram secret token 和 JSON 正文,然后再向 Telegram 返回 `200`。
|
||||
随后 OpenClaw 会通过与长轮询相同的按聊天/按话题划分的机器人通道异步处理该更新,因此缓慢的智能体回合不会阻塞 Telegram 的投递 ACK。
|
||||
webhook 模式会先校验请求防护、Telegram secret token 和 JSON 正文,然后再向 Telegram 返回 `200`。
|
||||
OpenClaw 随后会通过与长轮询相同的按聊天/按话题 bot 通道异步处理更新,因此缓慢的智能体轮次不会阻塞 Telegram 的投递 ACK。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="限制、重试和 CLI 目标">
|
||||
- `channels.telegram.textChunkLimit` 默认值为 4000。
|
||||
- `channels.telegram.chunkMode="newline"` 会在按长度拆分前优先使用段落边界(空行)。
|
||||
- `channels.telegram.chunkMode="newline"` 会优先按段落边界(空行)拆分,再按长度拆分。
|
||||
- `channels.telegram.mediaMaxMb`(默认 100)限制入站和出站 Telegram 媒体大小。
|
||||
- `channels.telegram.timeoutSeconds` 会覆盖 Telegram API 客户端超时时间(若未设置,则使用 grammY 默认值)。
|
||||
- `channels.telegram.pollingStallThresholdMs` 默认值为 `120000`;仅在轮询停滞重启出现误报时,在 `30000` 到 `600000` 之间调整。
|
||||
- `channels.telegram.timeoutSeconds` 会覆盖 Telegram API 客户端超时时间(未设置时使用 grammY 默认值)。
|
||||
- `channels.telegram.pollingStallThresholdMs` 默认值为 `120000`;仅在误报轮询停滞重启时,在 `30000` 到 `600000` 之间调整。
|
||||
- 群组上下文历史使用 `channels.telegram.historyLimit` 或 `messages.groupChat.historyLimit`(默认 50);`0` 表示禁用。
|
||||
- 回复/引用/转发的补充上下文目前会按接收内容传递。
|
||||
- Telegram 允许列表主要控制谁可以触发智能体,并不是完整的补充上下文脱敏边界。
|
||||
- 私信历史控制项:
|
||||
- 回复/引用/转发的补充上下文目前会按收到的内容传递。
|
||||
- Telegram allowlist 主要控制谁可以触发智能体,而不是完整的补充上下文脱敏边界。
|
||||
- 私信历史控制:
|
||||
- `channels.telegram.dmHistoryLimit`
|
||||
- `channels.telegram.dms["<user_id>"].historyLimit`
|
||||
- `channels.telegram.retry` 配置适用于 Telegram 发送辅助工具(CLI/工具/操作)中可恢复的出站 API 错误。
|
||||
- `channels.telegram.retry` 配置适用于 Telegram 发送辅助能力(CLI/工具/actions),用于可恢复的出站 API 错误。
|
||||
|
||||
CLI 发送目标可以是数字聊天 ID 或用户名:
|
||||
|
||||
@ -754,53 +754,53 @@ openclaw message poll --channel telegram --target -1001234567890:topic:42 \
|
||||
--poll-duration-seconds 300 --poll-public
|
||||
```
|
||||
|
||||
仅 Telegram 支持的投票标志:
|
||||
仅 Telegram 的投票标志:
|
||||
|
||||
- `--poll-duration-seconds`(5-600)
|
||||
- `--poll-duration-seconds` (5-600)
|
||||
- `--poll-anonymous`
|
||||
- `--poll-public`
|
||||
- 用于论坛话题的 `--thread-id`(或使用 `:topic:` 目标)
|
||||
- `--thread-id` 用于论坛话题(或使用 `:topic:` 目标)
|
||||
|
||||
Telegram 发送还支持:
|
||||
|
||||
- 当 `channels.telegram.capabilities.inlineButtons` 允许时,使用带有 `buttons` 块的 `--presentation` 生成内联键盘
|
||||
- 使用 `--pin` 或 `--delivery '{"pin":true}'` 在机器人可在该聊天置顶时请求置顶投递
|
||||
- 当 `channels.telegram.capabilities.inlineButtons` 允许时,使用带有 `buttons` 块的 `--presentation` 来提供内联键盘
|
||||
- 当 bot 可以在该聊天中置顶时,使用 `--pin` 或 `--delivery '{"pin":true}'` 请求置顶投递
|
||||
- 使用 `--force-document` 将出站图片和 GIF 作为文档发送,而不是压缩照片或动画媒体上传
|
||||
|
||||
操作门控:
|
||||
Action 门控:
|
||||
|
||||
- `channels.telegram.actions.sendMessage=false` 会禁用出站 Telegram 消息,包括投票
|
||||
- `channels.telegram.actions.poll=false` 会禁用 Telegram 投票创建,同时保留常规发送
|
||||
- `channels.telegram.actions.poll=false` 会禁用 Telegram 投票创建,同时保留常规发送功能
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Telegram 中的 exec 审批">
|
||||
Telegram 支持在审批人私信中进行 exec 审批,也可以选择在来源聊天或话题中发布提示。审批人必须是数字 Telegram 用户 ID。
|
||||
<Accordion title="Telegram 中的执行审批">
|
||||
Telegram 支持在审批人私信中进行执行审批,也可以选择在来源聊天或话题中发布提示。审批人必须是数字 Telegram 用户 ID。
|
||||
|
||||
配置路径:
|
||||
|
||||
- `channels.telegram.execApprovals.enabled`(至少有一个审批人可解析时自动启用)
|
||||
- `channels.telegram.execApprovals.approvers`(回退到 `allowFrom` / `defaultTo` 中的数字 owner ID)
|
||||
- `channels.telegram.execApprovals.target`:`dm`(默认)| `channel` | `both`
|
||||
- `channels.telegram.execApprovals.target`: `dm`(默认)| `channel` | `both`
|
||||
- `agentFilter`、`sessionFilter`
|
||||
|
||||
渠道投递会在聊天中显示命令文本;仅在可信群组/话题中启用 `channel` 或 `both`。当提示落在论坛话题中时,OpenClaw 会为审批提示和后续消息保留该话题。exec 审批默认 30 分钟后过期。
|
||||
渠道投递会在聊天中显示命令文本;仅在受信任的群组/话题中启用 `channel` 或 `both`。当提示落在论坛话题中时,OpenClaw 会为审批提示和后续消息保留该话题。执行审批默认在 30 分钟后过期。
|
||||
|
||||
内联审批按钮还要求 `channels.telegram.capabilities.inlineButtons` 允许目标表面(`dm`、`group` 或 `all`)。带有 `plugin:` 前缀的审批 ID 会通过插件审批解析;其他 ID 会优先通过 exec 审批解析。
|
||||
内联审批按钮还要求 `channels.telegram.capabilities.inlineButtons` 允许目标表面(`dm`、`group` 或 `all`)。以 `plugin:` 为前缀的审批 ID 会通过插件审批解析;其他 ID 会先通过执行审批解析。
|
||||
|
||||
参见 [Exec 审批](/zh-CN/tools/exec-approvals)。
|
||||
参见 [执行审批](/zh-CN/tools/exec-approvals)。
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## 错误回复控制
|
||||
|
||||
当智能体遇到投递或提供商错误时,Telegram 可以回复错误文本,也可以将其抑制。此行为由两个配置键控制:
|
||||
当智能体遇到投递或提供商错误时,Telegram 可以回复错误文本,也可以抑制该错误。两个配置键控制此行为:
|
||||
|
||||
| 键 | 值 | 默认值 | 描述 |
|
||||
| ----------------------------------- | ----------------- | ------- | ----------------------------------------------------------------------------------------------- |
|
||||
| `channels.telegram.errorPolicy` | `reply`, `silent` | `reply` | `reply` 会向聊天发送友好的错误消息。`silent` 会完全抑制错误回复。 |
|
||||
| `channels.telegram.errorCooldownMs` | 数字(ms) | `60000` | 向同一聊天发送错误回复的最小间隔。可防止故障期间产生错误刷屏。 |
|
||||
| 键 | 值 | 默认值 | 描述 |
|
||||
| ----------------------------------- | ----------------- | ------- | ----------------------------------------------------------------------------------------- |
|
||||
| `channels.telegram.errorPolicy` | `reply`, `silent` | `reply` | `reply` 会向聊天发送友好的错误消息。`silent` 会完全抑制错误回复。 |
|
||||
| `channels.telegram.errorCooldownMs` | number (ms) | `60000` | 向同一聊天发送错误回复之间的最短时间。防止服务中断期间出现错误刷屏。 |
|
||||
|
||||
支持按账号、按群组和按话题覆盖(继承方式与其他 Telegram 配置键相同)。
|
||||
|
||||
@ -823,49 +823,49 @@ openclaw message poll --channel telegram --target -1001234567890:topic:42 \
|
||||
## 故障排除
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="机器人不响应非提及的群组消息">
|
||||
<Accordion title="Bot 不响应非提及的群组消息">
|
||||
|
||||
- 如果 `requireMention=false`,Telegram 隐私模式必须允许完整可见性。
|
||||
- BotFather:`/setprivacy` -> Disable
|
||||
- 然后将机器人从群组移除并重新添加
|
||||
- 当配置期望接收未提及的群组消息时,`openclaw channels status` 会给出警告。
|
||||
- `openclaw channels status --probe` 可以检查明确的数字群组 ID;通配符 `"*"` 无法进行成员探测。
|
||||
- 然后移除 bot 并重新添加到群组
|
||||
- 当配置期望接收未提及的群组消息时,`openclaw channels status` 会发出警告。
|
||||
- `openclaw channels status --probe` 可以检查明确的数字群组 ID;通配符 `"*"` 无法探测成员关系。
|
||||
- 快速会话测试:`/activation always`。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="机器人完全看不到群组消息">
|
||||
<Accordion title="Bot 完全看不到群组消息">
|
||||
|
||||
- 当 `channels.telegram.groups` 存在时,群组必须列入其中(或包含 `"*"`)
|
||||
- 验证机器人是群组成员
|
||||
- 查看日志:`openclaw logs --follow` 以了解跳过原因
|
||||
- 当存在 `channels.telegram.groups` 时,必须列出该群组(或包含 `"*"`)
|
||||
- 验证 bot 是否为群组成员
|
||||
- 查看日志:`openclaw logs --follow` 获取跳过原因
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="命令部分可用或完全不可用">
|
||||
<Accordion title="命令只能部分工作或完全不工作">
|
||||
|
||||
- 授权你的发送者身份(配对和/或数字 `allowFrom`)
|
||||
- 即使群组策略是 `open`,命令授权仍然适用
|
||||
- `setMyCommands failed` 并带有 `BOT_COMMANDS_TOO_MUCH` 表示原生命令菜单条目过多;请减少插件/skill/自定义命令,或禁用原生命令菜单
|
||||
- `setMyCommands failed` 并带有网络/fetch 错误,通常表示到 `api.telegram.org` 的 DNS/HTTPS 可达性存在问题
|
||||
- 即使群组策略为 `open`,命令授权仍然适用
|
||||
- `setMyCommands failed` 并带有 `BOT_COMMANDS_TOO_MUCH` 表示原生命令菜单条目过多;减少插件/skill/自定义命令,或禁用原生命令菜单
|
||||
- `setMyCommands failed` 并带有网络/fetch 错误,通常表示到 `api.telegram.org` 的 DNS/HTTPS 可达性问题
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="启动报告未授权 token">
|
||||
|
||||
- `getMe returned 401` 是配置的机器人 token 出现 Telegram 身份验证失败。
|
||||
- 在 BotFather 中重新复制或重新生成机器人 token,然后为默认账号更新 `channels.telegram.botToken`、`channels.telegram.tokenFile`、`channels.telegram.accounts.<id>.botToken` 或 `TELEGRAM_BOT_TOKEN`。
|
||||
- 启动期间出现 `deleteWebhook 401 Unauthorized` 也是身份验证失败;将其当作“没有 webhook 存在”只会把同一个错误 token 故障推迟到后续 API 调用。
|
||||
- `getMe returned 401` 是配置的 bot token 出现 Telegram 认证失败。
|
||||
- 在 BotFather 中重新复制或重新生成 bot token,然后更新默认账号的 `channels.telegram.botToken`、`channels.telegram.tokenFile`、`channels.telegram.accounts.<id>.botToken` 或 `TELEGRAM_BOT_TOKEN`。
|
||||
- 启动期间的 `deleteWebhook 401 Unauthorized` 也是认证失败;将其视为“没有 webhook 存在”只会把同一个错误 token 失败推迟到后续 API 调用。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="轮询或网络不稳定">
|
||||
|
||||
- Node 22+ 加自定义 fetch/proxy 时,如果 AbortSignal 类型不匹配,可能触发立即中止行为。
|
||||
- 一些主机会优先将 `api.telegram.org` 解析到 IPv6;损坏的 IPv6 出站连接可能导致间歇性 Telegram API 故障。
|
||||
- 某些主机会先将 `api.telegram.org` 解析为 IPv6;损坏的 IPv6 出站可能导致间歇性 Telegram API 失败。
|
||||
- 如果日志包含 `TypeError: fetch failed` 或 `Network request for 'getUpdates' failed!`,OpenClaw 现在会将这些作为可恢复的网络错误重试。
|
||||
- 如果日志包含 `Polling stall detected`,默认情况下,当 120 秒内没有完成长轮询存活检查时,OpenClaw 会重启轮询并重建 Telegram 传输。
|
||||
- 仅当长时间运行的 `getUpdates` 调用健康,但你的主机仍报告轮询停滞重启误报时,才增加 `channels.telegram.pollingStallThresholdMs`。持续停滞通常指向主机与 `api.telegram.org` 之间的代理、DNS、IPv6 或 TLS 出站问题。
|
||||
- 如果日志包含 `Polling stall detected`,OpenClaw 会在默认 120 秒内没有完成的长轮询活性信号后,重启轮询并重建 Telegram 传输。
|
||||
- 只有当长时间运行的 `getUpdates` 调用健康,但你的主机仍报告误报的轮询停滞重启时,才增加 `channels.telegram.pollingStallThresholdMs`。持续停滞通常指向主机与 `api.telegram.org` 之间的 proxy、DNS、IPv6 或 TLS 出站问题。
|
||||
- 在直接出站/TLS 不稳定的 VPS 主机上,通过 `channels.telegram.proxy` 路由 Telegram API 调用:
|
||||
|
||||
```yaml
|
||||
@ -875,7 +875,7 @@ channels:
|
||||
```
|
||||
|
||||
- Node 22+ 默认使用 `autoSelectFamily=true`(WSL2 除外)和 `dnsResultOrder=ipv4first`。
|
||||
- 如果你的主机是 WSL2,或明确使用仅 IPv4 行为时表现更好,请强制选择地址族:
|
||||
- 如果你的主机是 WSL2,或明确使用仅 IPv4 行为效果更好,请强制选择地址族:
|
||||
|
||||
```yaml
|
||||
channels:
|
||||
@ -884,7 +884,11 @@ channels:
|
||||
autoSelectFamily: false
|
||||
```
|
||||
|
||||
- RFC 2544 基准测试范围地址响应(`198.18.0.0/15`)已默认允许用于 Telegram 媒体下载。如果某个可信的 fake-IP 或透明代理在媒体下载期间将 `api.telegram.org` 重写为其他私有/内部/特殊用途地址,你可以选择启用仅限 Telegram 的绕过:
|
||||
- 默认情况下,已允许 RFC 2544 基准测试范围答案(`198.18.0.0/15`)
|
||||
用于 Telegram 媒体下载。如果受信任的 fake-IP 或
|
||||
transparent proxy 在媒体下载期间将 `api.telegram.org` 重写为其他
|
||||
private/internal/special-use 地址,你可以选择启用
|
||||
仅 Telegram 的绕过:
|
||||
|
||||
```yaml
|
||||
channels:
|
||||
@ -893,20 +897,25 @@ channels:
|
||||
dangerouslyAllowPrivateNetwork: true
|
||||
```
|
||||
|
||||
- 同样的选择启用项可按账号配置在
|
||||
`channels.telegram.accounts.<accountId>.network.dangerouslyAllowPrivateNetwork`。
|
||||
- 如果你的代理将 Telegram 媒体主机解析为 `198.18.x.x`,请先保持危险标志关闭。Telegram 媒体已默认允许 RFC 2544 基准测试范围。
|
||||
- 同样的选择启用也可按账号在
|
||||
`channels.telegram.accounts.<accountId>.network.dangerouslyAllowPrivateNetwork` 使用。
|
||||
- 如果你的 proxy 将 Telegram 媒体主机解析为 `198.18.x.x`,请先保持
|
||||
dangerous 标志关闭。Telegram 媒体默认已经允许 RFC 2544
|
||||
基准测试范围。
|
||||
|
||||
<Warning>
|
||||
`channels.telegram.network.dangerouslyAllowPrivateNetwork` 会削弱 Telegram
|
||||
媒体 SSRF 保护。仅在可信且由运营者控制的代理环境中使用,例如 Clash、Mihomo 或 Surge fake-IP 路由,并且这些环境会合成 RFC 2544 基准测试范围之外的私有或特殊用途响应。正常公网 Telegram 访问应保持关闭。
|
||||
媒体 SSRF 防护。仅在受信任且由 operator 控制的 proxy
|
||||
环境中使用,例如 Clash、Mihomo 或 Surge fake-IP 路由,且它们会在
|
||||
RFC 2544 基准测试范围之外合成 private 或 special-use 答案。
|
||||
对于普通公网 Telegram 访问,请保持关闭。
|
||||
</Warning>
|
||||
|
||||
- 环境覆盖(临时):
|
||||
- 环境变量覆盖(临时):
|
||||
- `OPENCLAW_TELEGRAM_DISABLE_AUTO_SELECT_FAMILY=1`
|
||||
- `OPENCLAW_TELEGRAM_ENABLE_AUTO_SELECT_FAMILY=1`
|
||||
- `OPENCLAW_TELEGRAM_DNS_RESULT_ORDER=ipv4first`
|
||||
- 验证 DNS 响应:
|
||||
- 验证 DNS 答案:
|
||||
|
||||
```bash
|
||||
dig +short api.telegram.org A
|
||||
@ -922,27 +931,27 @@ dig +short api.telegram.org AAAA
|
||||
|
||||
主要参考:[配置参考 - Telegram](/zh-CN/gateway/config-channels#telegram)。
|
||||
|
||||
<Accordion title="高价值 Telegram 字段">
|
||||
<Accordion title="高信号 Telegram 字段">
|
||||
|
||||
- 启动/凭证:`enabled`、`botToken`、`tokenFile`、`accounts.*`(`tokenFile` 必须指向常规文件;符号链接会被拒绝)
|
||||
- 启动/身份验证:`enabled`、`botToken`、`tokenFile`、`accounts.*`(`tokenFile` 必须指向常规文件;符号链接会被拒绝)
|
||||
- 访问控制:`dmPolicy`、`allowFrom`、`groupPolicy`、`groupAllowFrom`、`groups`、`groups.*.topics.*`、顶层 `bindings[]`(`type: "acp"`)
|
||||
- 执行审批:`execApprovals`、`accounts.*.execApprovals`
|
||||
- 命令/菜单:`commands.native`、`commands.nativeSkills`、`customCommands`
|
||||
- 会话串/回复:`replyToMode`
|
||||
- 线程/回复:`replyToMode`
|
||||
- 流式传输:`streaming`(预览)、`streaming.preview.toolProgress`、`blockStreaming`
|
||||
- 格式化/投递:`textChunkLimit`、`chunkMode`、`linkPreview`、`responsePrefix`
|
||||
- 格式/投递:`textChunkLimit`、`chunkMode`、`linkPreview`、`responsePrefix`
|
||||
- 媒体/网络:`mediaMaxMb`、`timeoutSeconds`、`pollingStallThresholdMs`、`retry`、`network.autoSelectFamily`、`network.dangerouslyAllowPrivateNetwork`、`proxy`
|
||||
- 自定义 API 根:`apiRoot`(仅 Bot API 根;不要包含 `/bot<TOKEN>`)
|
||||
- 自定义 API 根路径:`apiRoot`(仅 Bot API 根路径;不要包含 `/bot<TOKEN>`)
|
||||
- webhook:`webhookUrl`、`webhookSecret`、`webhookPath`、`webhookHost`
|
||||
- 操作/能力:`capabilities.inlineButtons`、`actions.sendMessage|editMessage|deleteMessage|reactions|sticker`
|
||||
- reactions:`reactionNotifications`、`reactionLevel`
|
||||
- 表情回应:`reactionNotifications`、`reactionLevel`
|
||||
- 错误:`errorPolicy`、`errorCooldownMs`
|
||||
- 写入/历史记录:`configWrites`、`historyLimit`、`dmHistoryLimit`、`dms.*.historyLimit`
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Note>
|
||||
多账号优先级:配置两个或更多账号 ID 时,设置 `channels.telegram.defaultAccount`(或包含 `channels.telegram.accounts.default`)以明确默认路由。否则 OpenClaw 会回退到第一个规范化账号 ID,并且 `openclaw doctor` 会发出警告。命名账号会继承 `channels.telegram.allowFrom` / `groupAllowFrom`,但不会继承 `accounts.default.*` 值。
|
||||
多账号优先级:配置两个或更多账号 ID 时,请设置 `channels.telegram.defaultAccount`(或包含 `channels.telegram.accounts.default`),以明确默认路由。否则 OpenClaw 会回退到第一个规范化后的账号 ID,并且 `openclaw doctor` 会发出警告。命名账号会继承 `channels.telegram.allowFrom` / `groupAllowFrom`,但不会继承 `accounts.default.*` 值。
|
||||
</Note>
|
||||
|
||||
## 相关内容
|
||||
@ -952,10 +961,10 @@ dig +short api.telegram.org AAAA
|
||||
将 Telegram 用户配对到 Gateway 网关。
|
||||
</Card>
|
||||
<Card title="群组" icon="users" href="/zh-CN/channels/groups">
|
||||
群组和话题允许列表行为。
|
||||
群组和话题的允许列表行为。
|
||||
</Card>
|
||||
<Card title="渠道路由" icon="route" href="/zh-CN/channels/channel-routing">
|
||||
将传入消息路由到智能体。
|
||||
将入站消息路由到智能体。
|
||||
</Card>
|
||||
<Card title="安全" icon="shield" href="/zh-CN/gateway/security">
|
||||
威胁模型和加固。
|
||||
|
||||
@ -1,29 +1,29 @@
|
||||
---
|
||||
read_when:
|
||||
- 解释流式传输或分块处理在渠道中的工作方式
|
||||
- 更改分块流式传输或渠道分块处理行为
|
||||
- 调试重复或过早的分块回复或渠道预览流式传输
|
||||
summary: 流式传输 + 分块处理行为(分块回复、渠道预览流式传输、模式映射)
|
||||
title: 流式传输和分块处理
|
||||
- 说明渠道上的流式传输或分块如何工作
|
||||
- 更改分块流式传输或渠道分块行为
|
||||
- 调试重复/过早的分块回复或渠道预览流式传输
|
||||
summary: 流式传输 + 分块行为(分块回复、渠道预览流式传输、模式映射)
|
||||
title: 流式传输与分块
|
||||
x-i18n:
|
||||
generated_at: "2026-04-27T20:27:50Z"
|
||||
model: gpt-5.4
|
||||
generated_at: "2026-04-28T19:32:04Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: 8210204d146f406320b977efe364ded0a19d233a943053fb1a90e6c59fb74a0f
|
||||
source_hash: d428355e1a0dbd426c4807add2b15fcfb09776849681bfeb2293173a2d31ee4f
|
||||
source_path: concepts/streaming.md
|
||||
workflow: 15
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
OpenClaw 有两个彼此独立的流式传输层:
|
||||
OpenClaw 有两个独立的流式传输层:
|
||||
|
||||
- **分块流式传输(渠道):** 在助手写作时,按已完成的**块**发出。这些是普通的渠道消息(不是 token 增量)。
|
||||
- **预览流式传输(Telegram/Discord/Slack):** 在生成过程中更新一个临时的**预览消息**。
|
||||
- **分块流式传输(渠道):**在助手写入时发出已完成的**块**。这些是普通的渠道消息(不是 token 增量)。
|
||||
- **预览流式传输(Telegram/Discord/Slack):**在生成时更新一条临时**预览消息**。
|
||||
|
||||
当前**没有真正的 token 增量流式传输**到渠道消息。预览流式传输是基于消息的(发送 + 编辑/追加)。
|
||||
目前,渠道消息没有**真正的 token 增量流式传输**。预览流式传输基于消息(发送 + 编辑/追加)。
|
||||
|
||||
## 分块流式传输(渠道消息)
|
||||
|
||||
分块流式传输会在助手输出可用时,以较粗粒度的块发送。
|
||||
分块流式传输会在助手输出可用时,以较粗粒度的分片发送输出。
|
||||
|
||||
```
|
||||
Model output
|
||||
@ -37,73 +37,73 @@ Model output
|
||||
|
||||
图例:
|
||||
|
||||
- `text_delta/events`:模型流事件(对于非流式模型,可能较为稀疏)。
|
||||
- `chunker`:应用最小/最大边界和断点偏好的 `EmbeddedBlockChunker`。
|
||||
- `channel send`:实际发出的消息(分块回复)。
|
||||
- `text_delta/events`:模型流事件(对于非流式模型可能很稀疏)。
|
||||
- `chunker`:`EmbeddedBlockChunker`,应用最小/最大边界 + 断点偏好。
|
||||
- `channel send`:实际出站消息(分块回复)。
|
||||
|
||||
**控制项:**
|
||||
|
||||
- `agents.defaults.blockStreamingDefault`:`"on"`/`"off"`(默认关闭)。
|
||||
- 渠道覆盖:`*.blockStreaming`(以及每账户变体),用于按渠道强制设为 `"on"`/`"off"`。
|
||||
- 渠道覆盖:`*.blockStreaming`(以及按账号的变体),用于按渠道强制 `"on"`/`"off"`。
|
||||
- `agents.defaults.blockStreamingBreak`:`"text_end"` 或 `"message_end"`。
|
||||
- `agents.defaults.blockStreamingChunk`:`{ minChars, maxChars, breakPreference? }`。
|
||||
- `agents.defaults.blockStreamingCoalesce`:`{ minChars?, maxChars?, idleMs? }`(在发送前合并流式块)。
|
||||
- `agents.defaults.blockStreamingCoalesce`:`{ minChars?, maxChars?, idleMs? }`(发送前合并流式块)。
|
||||
- 渠道硬上限:`*.textChunkLimit`(例如 `channels.whatsapp.textChunkLimit`)。
|
||||
- 渠道分块模式:`*.chunkMode`(默认 `length`,`newline` 会先按空行即段落边界拆分,再按长度分块)。
|
||||
- Discord 软上限:`channels.discord.maxLinesPerMessage`(默认 17),用于拆分过高的回复,以避免 UI 裁剪。
|
||||
- 渠道分片模式:`*.chunkMode`(默认 `length`;`newline` 会先按空行(段落边界)拆分,再按长度分片)。
|
||||
- Discord 软上限:`channels.discord.maxLinesPerMessage`(默认 17),会拆分过高的回复以避免 UI 裁切。
|
||||
|
||||
**边界语义:**
|
||||
|
||||
- `text_end`:只要 chunker 发出块就立即流式发送;在每个 `text_end` 时刷新。
|
||||
- `message_end`:等待助手消息完成后,再刷新缓冲输出。
|
||||
- `text_end`:chunker 一发出块就进行流式发送;在每个 `text_end` 时刷新。
|
||||
- `message_end`:等待助手消息结束,然后刷新已缓冲的输出。
|
||||
|
||||
即使是 `message_end`,如果缓冲文本超过 `maxChars`,仍会使用 chunker,因此它可能在结尾发出多个块。
|
||||
如果缓冲文本超过 `maxChars`,`message_end` 仍会使用 chunker,因此它可以在末尾发出多个分片。
|
||||
|
||||
### 分块流式传输中的媒体投递
|
||||
### 使用分块流式传输交付媒体
|
||||
|
||||
`MEDIA:` 指令是普通的投递元数据。当分块流式传输提前发送一个媒体块时,OpenClaw 会为该轮次记住这次投递。如果最终助手载荷重复了相同的媒体 URL,最终投递会去掉重复媒体,而不是再次发送附件。
|
||||
`MEDIA:` 指令是普通的交付元数据。当分块流式传输提前发送媒体块时,OpenClaw 会记住本轮对话中的这次交付。如果最终助手载荷重复了同一个媒体 URL,最终交付会剥离重复媒体,而不是再次发送附件。
|
||||
|
||||
完全重复的最终载荷会被抑制。如果最终载荷在已经流式发送过的媒体前后新增了不同的文本,OpenClaw 仍会发送这些新文本,同时保持媒体只投递一次。这可以防止在 Telegram 等渠道上出现重复的语音消息或文件:例如,当智能体在流式传输期间发出 `MEDIA:`,而提供商也在完整回复中包含它时,就会发生这种情况。
|
||||
完全重复的最终载荷会被抑制。如果最终载荷在已经流式发送的媒体周围添加了不同文本,OpenClaw 仍会发送新文本,同时保持媒体只交付一次。这可以防止在 Telegram 等渠道上出现重复语音消息或文件,例如智能体在流式传输期间发出 `MEDIA:`,而提供商也在完成的回复中包含了它。
|
||||
|
||||
## 分块算法(低/高边界)
|
||||
## 分片算法(低/高边界)
|
||||
|
||||
分块处理由 `EmbeddedBlockChunker` 实现:
|
||||
分块由 `EmbeddedBlockChunker` 实现:
|
||||
|
||||
- **低边界:** 在缓冲区达到 `minChars` 之前不发出(除非强制)。
|
||||
- **高边界:** 优先在 `maxChars` 之前拆分;如果必须强制拆分,则在 `maxChars` 处拆分。
|
||||
- **断点偏好:** `paragraph` → `newline` → `sentence` → `whitespace` → 硬断开。
|
||||
- **代码围栏:** 绝不在围栏内部拆分;如果必须在 `maxChars` 处强制拆分,会先关闭再重新打开围栏,以保持 Markdown 有效。
|
||||
- **低边界:**缓冲区 >= `minChars` 前不发出(除非强制)。
|
||||
- **高边界:**优先在 `maxChars` 前拆分;如果强制,则在 `maxChars` 处拆分。
|
||||
- **断点偏好:**`paragraph` → `newline` → `sentence` → `whitespace` → 硬断点。
|
||||
- **代码围栏:**绝不在围栏内部拆分;当在 `maxChars` 处强制拆分时,会关闭 + 重新打开围栏,以保持 Markdown 有效。
|
||||
|
||||
`maxChars` 会被限制在渠道的 `textChunkLimit` 以内,因此你不能超过各渠道的上限。
|
||||
`maxChars` 会被限制到渠道的 `textChunkLimit`,因此你不能超过各渠道上限。
|
||||
|
||||
## 合并(合并流式块)
|
||||
|
||||
启用分块流式传输时,OpenClaw 可以在发送前**合并连续的分块片段**。这样可以减少“单行刷屏”,同时仍然提供渐进式输出。
|
||||
启用分块流式传输后,OpenClaw 可以在发出前**合并连续的分块片段**。这会减少“单行刷屏”,同时仍提供渐进式输出。
|
||||
|
||||
- 合并会等待**空闲间隔**(`idleMs`)后再刷新。
|
||||
- 缓冲区受 `maxChars` 限制,超过时会立即刷新。
|
||||
- `minChars` 会阻止过小的片段被发送,直到累积足够文本(最终刷新总会发送剩余文本)。
|
||||
- 连接符由 `blockStreamingChunk.breakPreference` 决定(`paragraph` → `\n\n`,`newline` → `\n`,`sentence` → 空格)。
|
||||
- 可通过 `*.blockStreamingCoalesce` 提供渠道级覆盖(包括每账户配置)。
|
||||
- 对于 Signal/Slack/Discord,默认的 coalesce `minChars` 会提升到 1500,除非另有覆盖。
|
||||
- 缓冲区受 `maxChars` 限制,超过时会刷新。
|
||||
- `minChars` 会阻止过小片段在积累到足够文本前发送(最终刷新始终会发送剩余文本)。
|
||||
- 连接符来自 `blockStreamingChunk.breakPreference`(`paragraph` → `\n\n`,`newline` → `\n`,`sentence` → 空格)。
|
||||
- 可通过 `*.blockStreamingCoalesce` 设置渠道覆盖(包括按账号配置)。
|
||||
- 除非覆盖,否则 Signal/Slack/Discord 的默认合并 `minChars` 会提升到 1500。
|
||||
|
||||
## 块之间更像人的节奏
|
||||
## 块之间的拟人节奏
|
||||
|
||||
启用分块流式传输时,你可以在各个分块回复之间加入**随机暂停**(首个块之后)。这会让多气泡回复看起来更自然。
|
||||
启用分块流式传输后,你可以在分块回复之间(第一个块之后)添加**随机暂停**。这会让多气泡响应感觉更自然。
|
||||
|
||||
- 配置:`agents.defaults.humanDelay`(也可通过 `agents.list[].humanDelay` 按智能体覆盖)。
|
||||
- 配置:`agents.defaults.humanDelay`(可通过 `agents.list[].humanDelay` 按智能体覆盖)。
|
||||
- 模式:`off`(默认)、`natural`(800–2500ms)、`custom`(`minMs`/`maxMs`)。
|
||||
- 仅适用于**分块回复**,不适用于最终回复或工具摘要。
|
||||
|
||||
## “流式输出分块”还是“一次性输出全部”
|
||||
## “流式发送分片或全部内容”
|
||||
|
||||
这对应于:
|
||||
它映射为:
|
||||
|
||||
- **流式输出分块:** `blockStreamingDefault: "on"` + `blockStreamingBreak: "text_end"`(边生成边发出)。非 Telegram 渠道还需要设置 `*.blockStreaming: true`。
|
||||
- **在结尾一次性流式输出全部:** `blockStreamingBreak: "message_end"`(刷新一次;如果内容很长,仍可能分成多个块)。
|
||||
- **不使用分块流式传输:** `blockStreamingDefault: "off"`(只发送最终回复)。
|
||||
- **流式发送分片:**`blockStreamingDefault: "on"` + `blockStreamingBreak: "text_end"`(边生成边发出)。非 Telegram 渠道还需要 `*.blockStreaming: true`。
|
||||
- **在末尾流式发送全部内容:**`blockStreamingBreak: "message_end"`(刷新一次;如果非常长,可能分为多个分片)。
|
||||
- **不使用分块流式传输:**`blockStreamingDefault: "off"`(仅最终回复)。
|
||||
|
||||
**渠道说明:** 除非显式将 `*.blockStreaming` 设为 `true`,否则分块流式传输**默认关闭**。渠道可以启用实时预览流式传输(`channels.<channel>.streaming`),而不发送分块回复。
|
||||
**渠道注意事项:**除非明确将 `*.blockStreaming` 设置为 `true`,否则分块流式传输**关闭**。渠道可以流式发送实时预览(`channels.<channel>.streaming`),而不发送分块回复。
|
||||
|
||||
配置位置提醒:`blockStreaming*` 默认值位于 `agents.defaults` 下,而不是根配置。
|
||||
|
||||
@ -114,27 +114,27 @@ Model output
|
||||
模式:
|
||||
|
||||
- `off`:禁用预览流式传输。
|
||||
- `partial`:单个预览,用最新文本替换。
|
||||
- `block`:以分块/追加的方式更新预览。
|
||||
- `progress`:在生成过程中显示进度/状态预览,完成时发送最终答案。
|
||||
- `partial`:单条预览,会被最新文本替换。
|
||||
- `block`:预览以分片/追加步骤更新。
|
||||
- `progress`:生成期间显示进度/Status 预览,完成时给出最终答案。
|
||||
|
||||
### 渠道映射
|
||||
|
||||
| 渠道 | `off` | `partial` | `block` | `progress` |
|
||||
| 渠道 | `off` | `partial` | `block` | `progress` |
|
||||
| ---------- | ----- | --------- | ------- | ----------------- |
|
||||
| Telegram | ✅ | ✅ | ✅ | 映射为 `partial` |
|
||||
| Discord | ✅ | ✅ | ✅ | 映射为 `partial` |
|
||||
| Telegram | ✅ | ✅ | ✅ | 映射到 `partial` |
|
||||
| Discord | ✅ | ✅ | ✅ | 映射到 `partial` |
|
||||
| Slack | ✅ | ✅ | ✅ | ✅ |
|
||||
| Mattermost | ✅ | ✅ | ✅ | ✅ |
|
||||
|
||||
仅限 Slack:
|
||||
仅 Slack:
|
||||
|
||||
- 当 `channels.slack.streaming.mode="partial"` 时,`channels.slack.streaming.nativeTransport` 控制是否使用 Slack 原生流式 API 调用(默认:`true`)。
|
||||
- Slack 原生流式传输和 Slack 助手线程状态都需要一个回复线程目标;顶层私信不会显示这种线程式预览。
|
||||
- 当 `channels.slack.streaming.mode="partial"` 时,`channels.slack.streaming.nativeTransport` 会切换 Slack 原生流式传输 API 调用(默认:`true`)。
|
||||
- Slack 原生流式传输和 Slack 助手线程 Status 需要回复线程目标;顶层私信不会显示这种线程式预览。
|
||||
|
||||
旧键迁移:
|
||||
旧版键迁移:
|
||||
|
||||
- Telegram:旧版 `streamMode` 以及标量/布尔 `streaming` 值,会由 doctor/config 兼容路径检测并迁移到 `streaming.mode`。
|
||||
- Telegram:旧版 `streamMode` 和标量/布尔 `streaming` 值会被 Doctor/配置兼容路径检测并迁移到 `streaming.mode`。
|
||||
- Discord:`streamMode` + 布尔 `streaming` 会自动迁移到 `streaming` 枚举。
|
||||
- Slack:`streamMode` 会自动迁移到 `streaming.mode`;布尔 `streaming` 会自动迁移到 `streaming.mode` 加 `streaming.nativeTransport`;旧版 `nativeStreaming` 会自动迁移到 `streaming.nativeTransport`。
|
||||
|
||||
@ -142,48 +142,48 @@ Model output
|
||||
|
||||
Telegram:
|
||||
|
||||
- 在私信和群组/话题中使用 `sendMessage` + `editMessageText` 进行预览更新。
|
||||
- 如果预览已显示大约一分钟,则发送一条新的最终消息,而不是原地编辑,然后清理预览,以便 Telegram 的时间戳反映回复完成时间。
|
||||
- 当 Telegram 分块流式传输被显式启用时,会跳过预览流式传输(以避免双重流式传输)。
|
||||
- `/reasoning stream` 可以将推理内容写入预览。
|
||||
- 使用 `sendMessage` + `editMessageText` 在私信和群组/话题中更新预览。
|
||||
- 当预览已可见约一分钟时,会发送一条新的最终消息,而不是就地编辑,然后清理预览,使 Telegram 的时间戳反映回复完成时间。
|
||||
- 当 Telegram 分块流式传输被明确启用时,会跳过预览流式传输(避免双重流式传输)。
|
||||
- `/reasoning stream` 可以将推理写入预览。
|
||||
|
||||
Discord:
|
||||
|
||||
- 使用发送 + 编辑预览消息。
|
||||
- `block` 模式使用草稿分块(`draftChunk`)。
|
||||
- 当 Discord 分块流式传输被显式启用时,会跳过预览流式传输。
|
||||
- 最终媒体、错误和显式回复载荷会取消待处理预览,而不会刷新新的草稿,然后改用正常投递。
|
||||
- `block` 模式使用草稿分片(`draftChunk`)。
|
||||
- 当 Discord 分块流式传输被明确启用时,会跳过预览流式传输。
|
||||
- 最终媒体、错误和显式回复载荷会取消待处理预览,而不刷新新的草稿,然后使用普通交付。
|
||||
|
||||
Slack:
|
||||
|
||||
- `partial` 在可用时可使用 Slack 原生流式传输(`chat.startStream`/`append`/`stop`)。
|
||||
- 可用时,`partial` 可以使用 Slack 原生流式传输(`chat.startStream`/`append`/`stop`)。
|
||||
- `block` 使用追加式草稿预览。
|
||||
- `progress` 使用状态预览文本,然后发送最终答案。
|
||||
- 原生和草稿预览流式传输会抑制该轮次的分块回复,因此一条 Slack 回复只会通过一种投递路径进行流式传输。
|
||||
- 最终媒体/错误载荷和 `progress` 的最终结果不会创建一次性的草稿消息;只有可以编辑预览的文本/块最终结果,才会刷新待处理的草稿文本。
|
||||
- `progress` 使用 Status 预览文本,然后给出最终答案。
|
||||
- 原生和草稿预览流式传输会在该轮中抑制分块回复,因此 Slack 回复只通过一种交付路径进行流式传输。
|
||||
- 最终媒体/错误载荷和进度最终消息不会创建一次性草稿消息;只有可以编辑预览的文本/分块最终消息会刷新待处理草稿文本。
|
||||
|
||||
Mattermost:
|
||||
|
||||
- 将思考、工具活动和部分回复文本流式写入单个草稿预览帖子;当最终答案可以安全发送时,就地完成。
|
||||
- 如果预览帖子已被删除或在完成时不可用,则回退为发送一个新的最终帖子。
|
||||
- 最终媒体/错误载荷会在正常投递前取消待处理的预览更新,而不是刷新临时预览帖子。
|
||||
- 将思考、工具活动和部分回复文本流式写入单个草稿预览帖子,在最终答案可以安全发送时就地完成。
|
||||
- 如果预览帖子已被删除,或在完成时不可用,则回退为发送新的最终帖子。
|
||||
- 最终媒体/错误载荷会在普通交付前取消待处理预览更新,而不是刷新临时预览帖子。
|
||||
|
||||
Matrix:
|
||||
|
||||
- 当最终文本可以复用预览事件时,草稿预览会原地完成。
|
||||
- 仅媒体、错误以及回复目标不匹配的最终结果,会在正常投递前取消待处理的预览更新;如果已经显示了过期预览,则会将其撤回。
|
||||
- 当最终文本可以复用预览事件时,草稿预览会就地完成。
|
||||
- 仅媒体、错误和回复目标不匹配的最终消息会在普通交付前取消待处理预览更新;已可见的过期预览会被撤回。
|
||||
|
||||
### 工具进度预览更新
|
||||
|
||||
预览流式传输还可以包含**工具进度**更新——例如“正在搜索网页”“正在读取文件”或“正在调用工具”之类的简短状态行——这些内容会在工具运行时显示在同一条预览消息中,先于最终回复出现。这样可以让多步骤工具轮次在视觉上保持活跃,而不是在首次思考预览与最终答案之间显得沉默。
|
||||
预览流式传输也可以包含**工具进度**更新,即“正在搜索网页”“正在读取文件”或“正在调用工具”等简短 Status 行。这些内容会在工具运行时显示在同一条预览消息中,早于最终回复。这样可以让多步骤工具轮次在第一个思考预览和最终答案之间保持可见,而不是静默等待。
|
||||
|
||||
支持的界面:
|
||||
|
||||
- 当预览流式传输处于活动状态时,**Discord**、**Slack**、**Telegram** 和 **Matrix** 默认会将工具进度流式写入实时预览编辑中。
|
||||
- Telegram 自 `v2026.4.22` 起已发布并启用了工具进度预览更新;保持启用可保留这一已发布行为。
|
||||
- **Mattermost** 已经会将工具活动整合进其单一草稿预览帖子中(见上文)。
|
||||
- 工具进度编辑遵循当前启用的预览流式传输模式;当预览流式传输为 `off`,或消息已切换为分块流式传输时,会跳过这些编辑。
|
||||
- 如果你想保留预览流式传输,但隐藏工具进度行,请将该渠道的 `streaming.preview.toolProgress` 设为 `false`。如果要完全禁用预览编辑,请将 `streaming.mode` 设为 `off`。
|
||||
- **Discord**、**Slack**、**Telegram** 和 **Matrix** 在预览流式传输激活时,默认会将工具进度流式写入实时预览编辑。
|
||||
- Telegram 自 `v2026.4.22` 起已启用工具进度预览更新;保持启用可保留该已发布行为。
|
||||
- **Mattermost** 已经将工具活动折叠进它的单个草稿预览帖子中(见上文)。
|
||||
- 工具进度编辑会遵循活动的预览流式传输模式;当预览流式传输为 `off`,或分块流式传输已接管消息时,会跳过它们。在 Telegram 上,`streaming.mode: "off"` 表示仅最终消息:通用进度闲聊也会被抑制,而不是作为独立的“Working...”消息交付;审批提示、媒体载荷和错误仍会正常路由。
|
||||
- 要保留预览流式传输但隐藏工具进度行,请为该渠道将 `streaming.preview.toolProgress` 设置为 `false`。要完全禁用预览编辑,请将 `streaming.mode` 设置为 `off`。
|
||||
|
||||
示例:
|
||||
|
||||
@ -202,8 +202,8 @@ Matrix:
|
||||
}
|
||||
```
|
||||
|
||||
## 相关内容
|
||||
## 相关
|
||||
|
||||
- [Messages](/zh-CN/concepts/messages) — 消息生命周期与投递
|
||||
- [Retry](/zh-CN/concepts/retry) — 投递失败时的重试行为
|
||||
- [Channels](/zh-CN/channels) — 各渠道的流式传输支持
|
||||
- [消息](/zh-CN/concepts/messages) — 消息生命周期和交付
|
||||
- [重试](/zh-CN/concepts/retry) — 交付失败时的重试行为
|
||||
- [渠道](/zh-CN/channels) — 各渠道的流式传输支持
|
||||
|
||||
Loading…
Reference in New Issue
Block a user