chore(i18n): refresh zh-CN translations
This commit is contained in:
parent
16a88f3913
commit
f8ac29d96c
@ -1,18 +1,18 @@
|
||||
---
|
||||
read_when:
|
||||
- 处理 Telegram 功能或 webhook
|
||||
summary: Telegram 机器人支持状态、能力和配置
|
||||
- 开发 Telegram 功能或网络钩子
|
||||
summary: Telegram 机器人支持状态、功能和配置
|
||||
title: Telegram
|
||||
x-i18n:
|
||||
generated_at: "2026-05-03T21:05:28Z"
|
||||
generated_at: "2026-05-04T06:12:14Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: 528ace9dae29eda22f98cc1436ec16146eb9d83edc73aa6db1ab8283f4f873c0
|
||||
source_hash: c7f49db5f3fe8fd724e53a2ae3d226446f248bf9d021fcc01c1cf816649381d2
|
||||
source_path: channels/telegram.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
可用于生产环境中的 bot 私信和群组,基于 grammY。长轮询是默认模式;webhook 模式是可选项。
|
||||
生产级支持通过 grammY 处理机器人私信和群组。默认模式是长轮询;webhook 模式为可选。
|
||||
|
||||
<CardGroup cols={3}>
|
||||
<Card title="配对" icon="link" href="/zh-CN/channels/pairing">
|
||||
@ -29,8 +29,8 @@ x-i18n:
|
||||
## 快速设置
|
||||
|
||||
<Steps>
|
||||
<Step title="在 BotFather 中创建 bot token">
|
||||
打开 Telegram 并与 **@BotFather** 聊天(确认句柄完全是 `@BotFather`)。
|
||||
<Step title="在 BotFather 中创建机器人 token">
|
||||
打开 Telegram 并与 **@BotFather** 聊天(确认句柄正是 `@BotFather`)。
|
||||
|
||||
运行 `/newbot`,按提示操作,并保存 token。
|
||||
|
||||
@ -51,8 +51,8 @@ x-i18n:
|
||||
}
|
||||
```
|
||||
|
||||
环境变量回退:`TELEGRAM_BOT_TOKEN=...`(仅默认账号)。
|
||||
Telegram **不**使用 `openclaw channels login telegram`;请在配置/环境变量中配置 token,然后启动 Gateway 网关。
|
||||
环境变量后备:`TELEGRAM_BOT_TOKEN=...`(仅默认账号)。
|
||||
Telegram **不**使用 `openclaw channels login telegram`;请在配置或环境变量中配置 token,然后启动 Gateway 网关。
|
||||
|
||||
</Step>
|
||||
|
||||
@ -64,44 +64,44 @@ openclaw pairing list telegram
|
||||
openclaw pairing approve telegram <CODE>
|
||||
```
|
||||
|
||||
配对码将在 1 小时后过期。
|
||||
配对码会在 1 小时后过期。
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="将 bot 添加到群组">
|
||||
将 bot 添加到你的群组,然后设置 `channels.telegram.groups` 和 `groupPolicy`,以匹配你的访问模型。
|
||||
<Step title="将机器人添加到群组">
|
||||
将机器人添加到你的群组,然后设置 `channels.telegram.groups` 和 `groupPolicy` 以匹配你的访问模型。
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
<Note>
|
||||
token 解析顺序感知账号。实践中,配置值优先于环境变量回退,且 `TELEGRAM_BOT_TOKEN` 只适用于默认账号。
|
||||
Token 解析顺序会感知账号。实践中,配置值优先于环境变量后备,而 `TELEGRAM_BOT_TOKEN` 仅适用于默认账号。
|
||||
</Note>
|
||||
|
||||
## Telegram 侧设置
|
||||
## Telegram 端设置
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="隐私模式和群组可见性">
|
||||
Telegram bot 默认启用 **Privacy Mode**,这会限制它们能接收哪些群组消息。
|
||||
Telegram 机器人默认使用**隐私模式**,这会限制它们接收的群组消息。
|
||||
|
||||
如果 bot 必须看到所有群组消息,请执行以下任一操作:
|
||||
如果机器人必须看到所有群组消息,可以:
|
||||
|
||||
- 通过 `/setprivacy` 禁用隐私模式,或
|
||||
- 将 bot 设为群组管理员。
|
||||
- 将机器人设为群组管理员。
|
||||
|
||||
切换隐私模式时,请在每个群组中移除并重新添加 bot,以便 Telegram 应用更改。
|
||||
切换隐私模式时,请在每个群组中移除并重新添加机器人,以便 Telegram 应用更改。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="群组权限">
|
||||
管理员状态在 Telegram 群组设置中控制。
|
||||
|
||||
管理员 bot 会接收所有群组消息,这对始终在线的群组行为很有用。
|
||||
管理员机器人会接收所有群组消息,这对常驻群组行为很有用。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="有用的 BotFather 开关">
|
||||
|
||||
- `/setjoingroups` 用于允许/拒绝添加到群组
|
||||
- `/setjoingroups` 用于允许或拒绝添加到群组
|
||||
- `/setprivacy` 用于群组可见性行为
|
||||
|
||||
</Accordion>
|
||||
@ -114,31 +114,31 @@ token 解析顺序感知账号。实践中,配置值优先于环境变量回
|
||||
`channels.telegram.dmPolicy` 控制直接消息访问:
|
||||
|
||||
- `pairing`(默认)
|
||||
- `allowlist`(要求 `allowFrom` 中至少有一个发送者 ID)
|
||||
- `open`(要求 `allowFrom` 包含 `"*"`)
|
||||
- `allowlist`(需要 `allowFrom` 中至少有一个发送者 ID)
|
||||
- `open`(需要 `allowFrom` 包含 `"*"`)
|
||||
- `disabled`
|
||||
|
||||
`dmPolicy: "open"` 搭配 `allowFrom: ["*"]` 会让任何找到或猜到 bot 用户名的 Telegram 账号都能命令该 bot。仅将其用于有意公开且工具受到严格限制的 bot;单所有者 bot 应使用 `allowlist` 并搭配数字用户 ID。
|
||||
`dmPolicy: "open"` 搭配 `allowFrom: ["*"]` 会让任何找到或猜到机器人用户名的 Telegram 账号都能指挥机器人。仅对有意公开且工具被严格限制的机器人使用它;单所有者机器人应使用带数字用户 ID 的 `allowlist`。
|
||||
|
||||
`channels.telegram.allowFrom` 接受数字 Telegram 用户 ID。`telegram:` / `tg:` 前缀会被接受并规范化。
|
||||
在多账号配置中,限制性的顶层 `channels.telegram.allowFrom` 会被视为安全边界:账号级 `allowFrom: ["*"]` 条目不会让该账号公开,除非合并后的有效账号允许列表仍包含显式通配符。
|
||||
`dmPolicy: "allowlist"` 搭配空的 `allowFrom` 会阻止所有私信,并会被配置验证拒绝。
|
||||
设置只会要求数字用户 ID。
|
||||
如果你已升级且配置中包含 `@username` 允许列表条目,请运行 `openclaw doctor --fix` 来解析它们(尽力而为;需要 Telegram bot token)。
|
||||
如果你之前依赖配对存储的允许列表文件,`openclaw doctor --fix` 可以在 allowlist 流程中将条目恢复到 `channels.telegram.allowFrom`(例如当 `dmPolicy: "allowlist"` 尚无显式 ID 时)。
|
||||
`dmPolicy: "allowlist"` 搭配空 `allowFrom` 会阻止所有私信,并会被配置校验拒绝。
|
||||
设置流程只会要求数字用户 ID。
|
||||
如果你已升级,且你的配置包含 `@username` 允许列表条目,请运行 `openclaw doctor --fix` 来解析它们(尽力而为;需要 Telegram 机器人 token)。
|
||||
如果你之前依赖配对存储允许列表文件,`openclaw doctor --fix` 可以在允许列表流程中将条目恢复到 `channels.telegram.allowFrom`(例如当 `dmPolicy: "allowlist"` 尚无显式 ID 时)。
|
||||
|
||||
对于单所有者 bot,建议使用 `dmPolicy: "allowlist"` 并搭配显式数字 `allowFrom` ID,以便在配置中保持持久的访问策略(而不是依赖之前的配对批准)。
|
||||
对单所有者机器人,优先使用 `dmPolicy: "allowlist"` 并配置显式数字 `allowFrom` ID,让访问策略在配置中保持持久(而不是依赖先前的配对批准)。
|
||||
|
||||
常见误解:批准私信配对并不意味着“此发送者在所有地方都已获授权”。
|
||||
配对授予私信访问权限。如果尚无命令所有者,第一次获批的配对还会设置 `commands.ownerAllowFrom`,使仅所有者命令和 exec 批准拥有显式操作员账号。
|
||||
常见误解:私信配对批准并不意味着“这个发送者在所有地方都已获授权”。
|
||||
配对授予私信访问权限。如果尚无命令所有者,第一次获批配对还会设置 `commands.ownerAllowFrom`,让仅所有者命令和 exec 批准拥有显式操作员账号。
|
||||
群组发送者授权仍来自显式配置允许列表。
|
||||
如果你希望“我授权一次后,私信和群组命令都能使用”,请将你的数字 Telegram 用户 ID 放入 `channels.telegram.allowFrom`;对于仅所有者命令,请确保 `commands.ownerAllowFrom` 包含 `telegram:<your user id>`。
|
||||
如果你希望“我授权一次后,私信和群组命令都可用”,请将你的数字 Telegram 用户 ID 放入 `channels.telegram.allowFrom`;对于仅所有者命令,确保 `commands.ownerAllowFrom` 包含 `telegram:<your user id>`。
|
||||
|
||||
### 查找你的 Telegram 用户 ID
|
||||
|
||||
更安全(无第三方 bot):
|
||||
更安全(无需第三方机器人):
|
||||
|
||||
1. 私信你的 bot。
|
||||
1. 给你的机器人发私信。
|
||||
2. 运行 `openclaw logs --follow`。
|
||||
3. 读取 `from.id`。
|
||||
|
||||
@ -153,7 +153,7 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
</Tab>
|
||||
|
||||
<Tab title="群组策略和允许列表">
|
||||
两项控制共同生效:
|
||||
两项控制会一起生效:
|
||||
|
||||
1. **允许哪些群组**(`channels.telegram.groups`)
|
||||
- 没有 `groups` 配置:
|
||||
@ -168,13 +168,13 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
|
||||
`groupAllowFrom` 用于群组发送者过滤。如果未设置,Telegram 会回退到 `allowFrom`。
|
||||
`groupAllowFrom` 条目应为数字 Telegram 用户 ID(`telegram:` / `tg:` 前缀会被规范化)。
|
||||
不要将 Telegram 群组或超级群组 chat ID 放入 `groupAllowFrom`。负数 chat ID 应放在 `channels.telegram.groups` 下。
|
||||
不要把 Telegram 群组或超级群组聊天 ID 放入 `groupAllowFrom`。负数聊天 ID 属于 `channels.telegram.groups`。
|
||||
非数字条目会在发送者授权中被忽略。
|
||||
安全边界(`2026.2.25+`):群组发送者认证**不会**继承私信配对存储批准。
|
||||
配对仅限私信。对于群组,请设置 `groupAllowFrom` 或每群组/每 topic 的 `allowFrom`。
|
||||
配对仅适用于私信。对于群组,请设置 `groupAllowFrom` 或每群组/每话题的 `allowFrom`。
|
||||
如果未设置 `groupAllowFrom`,Telegram 会回退到配置中的 `allowFrom`,而不是配对存储。
|
||||
单所有者 bot 的实用模式:在 `channels.telegram.allowFrom` 中设置你的用户 ID,保持 `groupAllowFrom` 未设置,并在 `channels.telegram.groups` 下允许目标群组。
|
||||
运行时说明:如果 `channels.telegram` 完全缺失,运行时会默认故障关闭为 `groupPolicy="allowlist"`,除非显式设置了 `channels.defaults.groupPolicy`。
|
||||
单所有者机器人的实用模式:在 `channels.telegram.allowFrom` 中设置你的用户 ID,保持 `groupAllowFrom` 未设置,并在 `channels.telegram.groups` 下允许目标群组。
|
||||
运行时说明:如果完全缺少 `channels.telegram`,运行时会默认故障关闭为 `groupPolicy="allowlist"`,除非显式设置了 `channels.defaults.groupPolicy`。
|
||||
|
||||
示例:允许一个特定群组中的任何成员:
|
||||
|
||||
@ -193,7 +193,7 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
}
|
||||
```
|
||||
|
||||
示例:只允许一个特定群组内的特定用户:
|
||||
示例:只允许一个特定群组中的特定用户:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -213,21 +213,21 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
<Warning>
|
||||
常见错误:`groupAllowFrom` 不是 Telegram 群组允许列表。
|
||||
|
||||
- 将 `-1001234567890` 这样的负数 Telegram 群组或超级群组 chat ID 放在 `channels.telegram.groups` 下。
|
||||
- 当你想限制已允许群组内哪些人可以触发 bot 时,将 `8734062810` 这样的 Telegram 用户 ID 放在 `groupAllowFrom` 下。
|
||||
- 仅当你希望已允许群组的任何成员都能与 bot 对话时,才使用 `groupAllowFrom: ["*"]`。
|
||||
- 将类似 `-1001234567890` 的负数 Telegram 群组或超级群组聊天 ID 放在 `channels.telegram.groups` 下。
|
||||
- 当你想限制已允许群组中的哪些人可以触发机器人时,将类似 `8734062810` 的 Telegram 用户 ID 放在 `groupAllowFrom` 下。
|
||||
- 仅当你希望已允许群组中的任何成员都能与机器人对话时,才使用 `groupAllowFrom: ["*"]`。
|
||||
|
||||
</Warning>
|
||||
|
||||
</Tab>
|
||||
|
||||
<Tab title="提及行为">
|
||||
群组回复默认要求提及。
|
||||
群组回复默认需要提及。
|
||||
|
||||
提及可以来自:
|
||||
|
||||
- 原生 `@botusername` 提及,或
|
||||
- 以下位置中的提及模式:
|
||||
- 以下位置的提及模式:
|
||||
- `agents.list[].groupChat.mentionPatterns`
|
||||
- `messages.groupChat.mentionPatterns`
|
||||
|
||||
@ -236,9 +236,9 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
- `/activation always`
|
||||
- `/activation mention`
|
||||
|
||||
这些只会更新会话状态。使用配置来持久化。
|
||||
这些只会更新会话状态。使用配置以实现持久化。
|
||||
|
||||
持久配置示例:
|
||||
持久化配置示例:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -252,7 +252,7 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
}
|
||||
```
|
||||
|
||||
获取群组 chat ID:
|
||||
获取群组聊天 ID:
|
||||
|
||||
- 将群组消息转发给 `@userinfobot` / `@getidsbot`
|
||||
- 或从 `openclaw logs --follow` 读取 `chat.id`
|
||||
@ -266,30 +266,30 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
- Telegram 由 Gateway 网关进程拥有。
|
||||
- 路由是确定性的:Telegram 入站会回复到 Telegram(模型不会选择渠道)。
|
||||
- 入站消息会规范化为共享渠道信封,并带有回复元数据和媒体占位符。
|
||||
- 群组会话按群组 ID 隔离。论坛 topic 会追加 `:topic:<threadId>` 以保持 topic 隔离。
|
||||
- 私信消息可以携带 `message_thread_id`;OpenClaw 会保留线程 ID 用于回复,但默认将私信保留在扁平会话中。当你有意希望进行私信 topic 会话隔离时,请配置 `channels.telegram.dm.threadReplies: "inbound"`、`channels.telegram.direct.<chatId>.threadReplies: "inbound"`、`requireTopic: true`,或匹配的 topic 配置。
|
||||
- 长轮询使用 grammY runner,并按每个 chat/每个 thread 排序。整体 runner sink 并发使用 `agents.defaults.maxConcurrent`。
|
||||
- 长轮询在每个 Gateway 网关进程内部受保护,因此同一时间只有一个活跃 poller 可以使用一个 bot token。如果你仍看到 `getUpdates` 409 冲突,很可能是另一个 OpenClaw Gateway 网关、脚本或外部 poller 正在使用同一个 token。
|
||||
- 默认情况下,长轮询 watchdog 会在 120 秒内没有完成的 `getUpdates` 活性后触发重启。仅当你的部署在长时间运行任务期间仍出现误判的轮询停滞重启时,才增加 `channels.telegram.pollingStallThresholdMs`。该值以毫秒为单位,允许范围为 `30000` 到 `600000`;支持按账号覆盖。
|
||||
- 群组会话按群组 ID 隔离。论坛话题会追加 `:topic:<threadId>` 以保持话题隔离。
|
||||
- 私信消息可以携带 `message_thread_id`;OpenClaw 会保留线程 ID 用于回复,但默认让私信保持在扁平会话上。当你有意希望进行私信话题会话隔离时,请配置 `channels.telegram.dm.threadReplies: "inbound"`、`channels.telegram.direct.<chatId>.threadReplies: "inbound"`、`requireTopic: true`,或匹配的话题配置。
|
||||
- 长轮询使用 grammY runner,并按聊天/按线程排序。整体 runner sink 并发使用 `agents.defaults.maxConcurrent`。
|
||||
- 长轮询在每个 Gateway 网关进程内部受保护,因此同一时间只有一个活动 poller 可以使用一个机器人 token。如果你仍看到 `getUpdates` 409 冲突,可能是另一个 OpenClaw Gateway 网关、脚本或外部 poller 正在使用同一个 token。
|
||||
- 默认情况下,如果 120 秒内没有完成的 `getUpdates` 存活信号,会触发长轮询 watchdog 重启。仅当你的部署在长时间运行工作期间仍出现误判的轮询停滞重启时,才增大 `channels.telegram.pollingStallThresholdMs`。该值以毫秒为单位,允许范围为 `30000` 到 `600000`;支持按账号覆盖。
|
||||
- Telegram Bot API 不支持已读回执(`sendReadReceipts` 不适用)。
|
||||
|
||||
## 功能参考
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="实时流预览(消息编辑)">
|
||||
<Accordion title="实时流式预览(消息编辑)">
|
||||
OpenClaw 可以实时流式传输部分回复:
|
||||
|
||||
- 直接聊天:预览消息 + `editMessageText`
|
||||
- 群组/topic:预览消息 + `editMessageText`
|
||||
- 群组/话题:预览消息 + `editMessageText`
|
||||
|
||||
要求:
|
||||
|
||||
- `channels.telegram.streaming` 为 `off | partial | block | progress`(默认:`partial`)
|
||||
- `progress` 会保留一个可编辑的状态草稿,并用工具进度更新它,直到最终交付
|
||||
- `streaming.preview.toolProgress` 控制工具/进度更新是否复用同一条已编辑的预览消息(当预览流式传输处于活动状态时,默认:`true`)
|
||||
- 旧版 `channels.telegram.streamMode` 和布尔 `streaming` 值会被检测到;运行 `openclaw doctor --fix` 将它们迁移到 `channels.telegram.streaming.mode`
|
||||
- `progress` 会保留一个可编辑的 Status 草稿,并用工具进度更新它,直到最终交付
|
||||
- `streaming.preview.toolProgress` 控制工具/进度更新是否复用同一条已编辑预览消息(默认:预览流式传输启用时为 `true`)
|
||||
- 会检测旧版 `channels.telegram.streamMode` 和布尔 `streaming` 值;运行 `openclaw doctor --fix` 可将它们迁移到 `channels.telegram.streaming.mode`
|
||||
|
||||
工具进度预览更新是在工具运行时显示的短状态行,例如命令执行、文件读取、规划更新或补丁摘要。Telegram 默认保持这些更新启用,以匹配 `v2026.4.22` 及之后版本发布的 OpenClaw 行为。若要保留答案文本的已编辑预览,但隐藏工具进度行,请设置:
|
||||
工具进度预览更新是在工具运行时显示的简短 Status 行,例如命令执行、文件读取、规划更新或补丁摘要。Telegram 默认保持启用这些更新,以匹配 `v2026.4.22` 及之后发布的 OpenClaw 行为。若要保留答案文本的已编辑预览,但隐藏工具进度行,请设置:
|
||||
|
||||
```json
|
||||
{
|
||||
@ -306,41 +306,42 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
}
|
||||
```
|
||||
|
||||
Use `streaming.mode: "off"` 仅在你想要仅最终内容投递时使用:Telegram 预览编辑会被禁用,通用工具/进度闲聊会被抑制,而不是作为独立 Status 消息发送。审批提示、媒体载荷和错误仍会通过正常的最终投递路径发送。当你只想保留答案预览编辑,同时隐藏工具进度 Status 行时,请使用 `streaming.preview.toolProgress: false`。
|
||||
使用 `streaming.mode: "off"` 只适用于你想要仅最终结果投递的场景:Telegram 预览编辑会被禁用,通用工具/进度闲聊会被抑制,而不是作为独立的 Status 消息发送。审批提示、媒体载荷和错误仍会通过正常的最终投递路径路由。当你只想保留回答预览编辑,同时隐藏工具进度 Status 行时,请使用 `streaming.preview.toolProgress: false`。
|
||||
|
||||
<Note>
|
||||
Telegram 选中文本引用回复是例外。当 `replyToMode` 为 `"first"`、`"all"` 或 `"batched"`,且入站消息包含选中的引用文本时,OpenClaw 会通过 Telegram 的原生引用回复路径发送最终答案,而不是编辑答案预览,因此 `streaming.preview.toolProgress` 无法为该轮显示短 Status 行。没有选中引用文本的当前消息回复仍会保留预览流式传输。当工具进度可见性比原生引用回复更重要时,请设置 `replyToMode: "off"`;或者设置 `streaming.preview.toolProgress: false` 以确认这一取舍。
|
||||
Telegram 选定引用回复是例外。当 `replyToMode` 为 `"first"`、`"all"` 或 `"batched"`,且入站消息包含选定引用文本时,OpenClaw 会通过 Telegram 原生引用回复路径发送最终回答,而不是编辑回答预览,因此 `streaming.preview.toolProgress` 无法为该轮显示短 Status 行。没有选定引用文本的当前消息回复仍会保留预览流式传输。当工具进度可见性比原生引用回复更重要时,请设置 `replyToMode: "off"`;或者设置 `streaming.preview.toolProgress: false` 来确认这一取舍。
|
||||
</Note>
|
||||
|
||||
对于纯文本回复:
|
||||
|
||||
- 短私信/群组/topic 预览:OpenClaw 会保留同一条预览消息,并在原处执行最终编辑,除非预览出现后发送过可见的非预览消息
|
||||
- 预览后跟随可见的非预览输出:OpenClaw 会将完成后的回复作为新的最终消息发送,并清理旧预览,因此最终答案会出现在中间输出之后
|
||||
- 超过约一分钟的预览:OpenClaw 会将完成后的回复作为新的最终消息发送,然后清理预览,因此 Telegram 可见时间戳会反映完成时间,而不是预览创建时间
|
||||
- 简短私信/群组/话题预览:OpenClaw 会保留同一条预览消息并在原处执行最终编辑,除非预览出现后发送过可见的非预览消息
|
||||
- 预览后跟随可见的非预览输出:OpenClaw 会把完成后的回复作为新的最终消息发送,并清理较早的预览,因此最终回答会出现在中间输出之后
|
||||
- 超过约一分钟的预览:OpenClaw 会把完成后的回复作为新的最终消息发送,然后清理预览,因此 Telegram 的可见时间戳会反映完成时间,而不是预览创建时间
|
||||
|
||||
对于复杂回复(例如媒体载荷),OpenClaw 会回退到正常的最终投递,然后清理预览消息。
|
||||
对于复杂回复(例如媒体载荷),OpenClaw 会回退到正常最终投递,然后清理预览消息。
|
||||
|
||||
预览流式传输与分块流式传输相互独立。当为 Telegram 显式启用分块流式传输时,OpenClaw 会跳过预览流,以避免双重流式传输。
|
||||
预览流式传输与分块流式传输是分开的。当为 Telegram 明确启用分块流式传输时,OpenClaw 会跳过预览流,以避免双重流式传输。
|
||||
|
||||
仅限 Telegram 的推理流:
|
||||
|
||||
- `/reasoning stream` 会在生成时把推理发送到实时预览
|
||||
- 最终答案发送时不包含推理文本
|
||||
- `/reasoning stream` 会在生成期间将推理发送到实时预览
|
||||
- 推理预览会在最终投递后删除;当推理应保持可见时,请使用 `/reasoning on`
|
||||
- 最终回答发送时不包含推理文本
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="格式化和 HTML 回退">
|
||||
<Accordion title="Formatting and HTML fallback">
|
||||
出站文本使用 Telegram `parse_mode: "HTML"`。
|
||||
|
||||
- 类 Markdown 文本会渲染为 Telegram 安全的 HTML。
|
||||
- 原始模型 HTML 会被转义,以减少 Telegram 解析失败。
|
||||
- 如果 Telegram 拒绝解析后的 HTML,OpenClaw 会以纯文本重试。
|
||||
- 如果 Telegram 拒绝解析后的 HTML,OpenClaw 会按纯文本重试。
|
||||
|
||||
链接预览默认启用,可通过 `channels.telegram.linkPreview: false` 禁用。
|
||||
链接预览默认启用,可使用 `channels.telegram.linkPreview: false` 禁用。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="原生命令和自定义命令">
|
||||
<Accordion title="Native commands and custom commands">
|
||||
Telegram 命令菜单注册会在启动时通过 `setMyCommands` 处理。
|
||||
|
||||
原生命令默认值:
|
||||
@ -364,24 +365,24 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
|
||||
规则:
|
||||
|
||||
- 名称会被规范化(移除开头的 `/`,转为小写)
|
||||
- 名称会被规范化(去掉开头的 `/`,转为小写)
|
||||
- 有效模式:`a-z`、`0-9`、`_`,长度 `1..32`
|
||||
- 自定义命令不能覆盖原生命令
|
||||
- 冲突/重复项会被跳过并记录日志
|
||||
|
||||
注意:
|
||||
说明:
|
||||
|
||||
- 自定义命令只是菜单项;它们不会自动实现行为
|
||||
- 插件/skill 命令即使未显示在 Telegram 菜单中,输入时仍可工作
|
||||
- 插件/Skills 命令即使未显示在 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 令牌。请使用当前 BotFather 令牌更新 `botToken`、`tokenFile` 或 `TELEGRAM_BOT_TOKEN`;OpenClaw 会在轮询前停止,因此这不会被报告为 webhook 清理失败。
|
||||
- `setMyCommands failed` 伴随网络/fetch 错误通常表示到 `api.telegram.org` 的出站 DNS/HTTPS 被阻止。
|
||||
- `setMyCommands failed` 搭配 `BOT_COMMANDS_TOO_MUCH` 表示 Telegram 菜单在裁剪后仍然溢出;请减少插件/Skills/自定义命令,或禁用 `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 拒绝了配置的机器人 token。请用当前 BotFather token 更新 `botToken`、`tokenFile` 或 `TELEGRAM_BOT_TOKEN`;OpenClaw 会在轮询前停止,因此这不会被报告为 webhook 清理失败。
|
||||
- `setMyCommands failed` 搭配网络/fetch 错误通常表示到 `api.telegram.org` 的出站 DNS/HTTPS 被阻止。
|
||||
|
||||
### 设备配对命令(`device-pair` 插件)
|
||||
|
||||
@ -392,18 +393,18 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
3. `/pair pending` 列出待处理请求(包括角色/作用域)
|
||||
4. 批准请求:
|
||||
- `/pair approve <requestId>` 用于显式批准
|
||||
- 只有一个待处理请求时使用 `/pair approve`
|
||||
- `/pair approve` 用于只有一个待处理请求的情况
|
||||
- `/pair approve latest` 用于最近的请求
|
||||
|
||||
设置代码携带一个短期有效的 bootstrap 令牌。内置 bootstrap 交接会让主节点令牌保持在 `scopes: []`;任何交接出去的 operator 令牌都会被限制在 `operator.approvals`、`operator.read`、`operator.talk.secrets` 和 `operator.write` 范围内。Bootstrap 作用域检查带有角色前缀,因此该 operator 允许列表只满足 operator 请求;非 operator 角色仍需要其自身角色前缀下的作用域。
|
||||
设置代码携带一个短期有效的 bootstrap token。内置 bootstrap 交接会将主节点 token 保持在 `scopes: []`;任何被交接的 operator token 都会被限制在 `operator.approvals`、`operator.read`、`operator.talk.secrets` 和 `operator.write`。Bootstrap 作用域检查带有角色前缀,因此该 operator 允许列表只满足 operator 请求;非 operator 角色仍需要其自身角色前缀下的作用域。
|
||||
|
||||
如果设备使用变更后的认证详情(例如角色/作用域/公钥)重试,之前的待处理请求会被取代,新请求会使用不同的 `requestId`。批准前请重新运行 `/pair pending`。
|
||||
如果设备使用已更改的认证详情(例如角色/作用域/公钥)重试,先前的待处理请求会被取代,新请求会使用不同的 `requestId`。批准前请重新运行 `/pair pending`。
|
||||
|
||||
更多详情:[配对](/zh-CN/channels/pairing#pair-via-telegram-recommended-for-ios)。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="内联按钮">
|
||||
<Accordion title="Inline buttons">
|
||||
配置内联键盘作用域:
|
||||
|
||||
```json5
|
||||
@ -446,7 +447,7 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
|
||||
旧版 `capabilities: ["inlineButtons"]` 会映射到 `inlineButtons: "all"`。
|
||||
|
||||
消息动作示例:
|
||||
消息操作示例:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -469,8 +470,8 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="面向智能体和自动化的 Telegram 消息动作">
|
||||
Telegram 工具动作包括:
|
||||
<Accordion title="Telegram message actions for agents and automation">
|
||||
Telegram 工具操作包括:
|
||||
|
||||
- `sendMessage`(`to`、`content`、可选 `mediaUrl`、`replyToMessageId`、`messageThreadId`)
|
||||
- `react`(`chatId`、`messageId`、`emoji`)
|
||||
@ -478,27 +479,27 @@ 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.*` 开关。
|
||||
运行时发送使用活动配置/密钥快照(启动/重载),因此动作路径不会在每次发送时执行临时 SecretRef 重新解析。
|
||||
注意:`edit` 和 `topic-create` 当前默认启用,且没有单独的 `channels.telegram.actions.*` 开关。
|
||||
运行时发送使用活动配置/密钥快照(启动/重载),因此操作路径不会在每次发送时执行临时 SecretRef 重新解析。
|
||||
|
||||
Reaction 移除语义:[/tools/reactions](/zh-CN/tools/reactions)
|
||||
反应移除语义:[/tools/reactions](/zh-CN/tools/reactions)
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="回复线程标签">
|
||||
<Accordion title="Reply threading tags">
|
||||
Telegram 支持在生成输出中使用显式回复线程标签:
|
||||
|
||||
- `[[reply_to_current]]` 回复触发消息
|
||||
- `[[reply_to:<id>]]` 回复特定的 Telegram 消息 ID
|
||||
- `[[reply_to:<id>]]` 回复特定 Telegram 消息 ID
|
||||
|
||||
`channels.telegram.replyToMode` 控制处理方式:
|
||||
|
||||
@ -506,29 +507,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 code unit,因此较长消息会从开头引用;如果 Telegram 拒绝引用,则回退为普通回复。
|
||||
|
||||
注意:`off` 会禁用隐式回复线程。显式 `[[reply_to_*]]` 标签仍会被遵循。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="论坛 topic 和线程行为">
|
||||
<Accordion title="Forum topics and thread behavior">
|
||||
论坛超级群组:
|
||||
|
||||
- topic 会话键追加 `:topic:<threadId>`
|
||||
- 回复和输入状态会面向 topic 线程
|
||||
- topic 配置路径:
|
||||
- 话题会话键会追加 `:topic:<threadId>`
|
||||
- 回复和输入状态会以话题线程为目标
|
||||
- 话题配置路径:
|
||||
`channels.telegram.groups.<chatId>.topics.<threadId>`
|
||||
|
||||
General topic(`threadId=1`)特殊情况:
|
||||
通用话题(`threadId=1`)特殊情况:
|
||||
|
||||
- 消息发送会省略 `message_thread_id`(Telegram 拒绝 `sendMessage(...thread_id=1)`)
|
||||
- 输入状态动作仍会包含 `message_thread_id`
|
||||
- 消息发送会省略 `message_thread_id`(Telegram 会拒绝 `sendMessage(...thread_id=1)`)
|
||||
- 输入状态操作仍包含 `message_thread_id`
|
||||
|
||||
Topic 继承:topic 条目会继承群组设置,除非被覆盖(`requireMention`、`allowFrom`、`skills`、`systemPrompt`、`enabled`、`groupPolicy`)。
|
||||
`agentId` 仅属于 topic,不会从群组默认值继承。
|
||||
话题继承:话题条目会继承群组设置,除非被覆盖(`requireMention`、`allowFrom`、`skills`、`systemPrompt`、`enabled`、`groupPolicy`)。
|
||||
`agentId` 仅限话题,不会从群组默认值继承。
|
||||
|
||||
**按 topic 的智能体路由**:每个 topic 都可以通过在 topic 配置中设置 `agentId` 路由到不同的智能体。这让每个 topic 拥有自己隔离的工作区、记忆和会话。示例:
|
||||
**按话题智能体路由**:每个话题都可以通过在话题配置中设置 `agentId` 路由到不同的智能体。这会让每个话题拥有自己的隔离工作区、记忆和会话。示例:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -548,28 +549,26 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
}
|
||||
```
|
||||
|
||||
然后每个 topic 都有自己的会话键:`agent:zu:telegram:group:-1001234567890:topic:3`
|
||||
然后每个话题都有自己的会话键:`agent:zu:telegram:group:-1001234567890:topic:3`
|
||||
|
||||
**持久 ACP topic 绑定**:论坛 topic 可以通过顶层类型化 ACP 绑定(`bindings[]`,其中 `type: "acp"`、`match.channel: "telegram"`、`peer.kind: "group"`,以及类似 `-1001234567890:topic:42` 的 topic 限定 ID)固定 ACP harness 会话。目前作用域限定为群组/超级群组中的论坛 topic。参见 [ACP Agents](/zh-CN/tools/acp-agents)。
|
||||
**持久 ACP 话题绑定**:论坛话题可以通过顶层类型化 ACP 绑定固定 ACP harness 会话(`bindings[]`,其中 `type: "acp"`、`match.channel: "telegram"`、`peer.kind: "group"`,以及类似 `-1001234567890:topic:42` 的带话题限定 ID)。当前作用域限定为群组/超级群组中的论坛话题。参见 [ACP Agents](/zh-CN/tools/acp-agents)。
|
||||
|
||||
**从聊天生成线程绑定的 ACP**:`/acp spawn <agent> --thread here|auto` 会将当前 topic 绑定到新的 ACP 会话;后续消息会直接路由到那里。OpenClaw 会在 topic 内固定生成确认。要求 `channels.telegram.threadBindings.spawnSessions` 保持启用(默认:`true`)。
|
||||
**从聊天生成线程绑定的 ACP**:`/acp spawn <agent> --thread here|auto` 会将当前话题绑定到新的 ACP 会话;后续消息会直接路由到那里。OpenClaw 会在话题内固定生成确认。要求 `channels.telegram.threadBindings.spawnSessions` 保持启用(默认:`true`)。
|
||||
|
||||
模板上下文会暴露 `MessageThreadId` 和 `IsForum`。带有 `message_thread_id` 的私信聊天默认会在扁平会话上保留私信路由和回复元数据;只有配置了 `threadReplies: "inbound"`、`threadReplies: "always"`、`requireTopic: true`,或匹配的 topic 配置时,才会使用线程感知会话键。使用顶层 `channels.telegram.dm.threadReplies` 作为账户默认值,或使用 `direct.<chatId>.threadReplies` 配置某个私信。
|
||||
模板上下文会暴露 `MessageThreadId` 和 `IsForum`。带 `message_thread_id` 的私信聊天默认会在扁平会话上保留私信路由和回复元数据;只有在配置了 `threadReplies: "inbound"`、`threadReplies: "always"`、`requireTopic: true` 或匹配的话题配置时,才会使用线程感知的会话键。使用顶层 `channels.telegram.dm.threadReplies` 作为账户默认值,或使用 `direct.<chatId>.threadReplies` 配置单个私信。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="音频、视频和贴纸">
|
||||
<Accordion title="Audio, video, and stickers">
|
||||
### 音频消息
|
||||
|
||||
Telegram 区分语音消息和音频文件。
|
||||
Telegram 会区分语音消息和音频文件。
|
||||
|
||||
- 默认:音频文件行为
|
||||
- 在智能体回复中使用标签 `[[audio_as_voice]]` 以强制按语音消息发送
|
||||
- 入站语音消息转录会在智能体上下文中被框定为机器生成的、
|
||||
不受信任文本;提及检测仍使用原始
|
||||
转录,因此受提及门控的语音消息会继续工作。
|
||||
- 在智能体回复中使用标签 `[[audio_as_voice]]` 可强制作为语音消息发送
|
||||
- 入站语音消息转录会在智能体上下文中被框定为机器生成的、不受信任文本;提及检测仍使用原始转录,因此受提及门控的语音消息会继续工作。
|
||||
|
||||
消息动作示例:
|
||||
消息操作示例:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -660,7 +659,7 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="回应通知">
|
||||
Telegram 回应会以 `message_reaction` 更新到达(独立于消息载荷)。
|
||||
Telegram 回应会以 `message_reaction` 更新到达(与消息载荷分开)。
|
||||
|
||||
启用后,OpenClaw 会将如下系统事件加入队列:
|
||||
|
||||
@ -671,19 +670,19 @@ 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 访问控制(`dmPolicy`、`allowFrom`、`groupPolicy`、`groupAllowFrom`);未授权的发送者会被丢弃。
|
||||
- Telegram 不会在回应更新中提供线程 ID。
|
||||
- 非论坛群组路由到群聊会话
|
||||
- 论坛群组路由到群组通用主题会话(`:topic:1`),而不是确切的原始主题
|
||||
- 非论坛群组会路由到群聊会话
|
||||
- 论坛群组会路由到群组通用主题会话(`:topic:1`),而不是确切的原始主题
|
||||
|
||||
轮询/webhook 的 `allowed_updates` 会自动包含 `message_reaction`。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="确认回应">
|
||||
<Accordion title="Ack 回应">
|
||||
`ackReaction` 会在 OpenClaw 处理入站消息时发送一个确认 emoji。
|
||||
|
||||
解析顺序:
|
||||
@ -691,12 +690,12 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
- `channels.telegram.accounts.<accountId>.ackReaction`
|
||||
- `channels.telegram.ackReaction`
|
||||
- `messages.ackReaction`
|
||||
- 智能体身份 emoji 回退(`agents.list[].identity.emoji`,否则为 “👀”)
|
||||
- 智能体身份 emoji 回退(`agents.list[].identity.emoji`,否则为 "👀")
|
||||
|
||||
注意:
|
||||
注意事项:
|
||||
|
||||
- Telegram 需要 Unicode emoji(例如 “👀”)。
|
||||
- 使用 `""` 可禁用某个渠道或账号的回应。
|
||||
- Telegram 需要 Unicode emoji(例如 "👀")。
|
||||
- 使用 `""` 可为某个渠道或账号禁用回应。
|
||||
|
||||
</Accordion>
|
||||
|
||||
@ -723,12 +722,12 @@ 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"`。
|
||||
本地监听器绑定到 `127.0.0.1:8787`。对于公网入口,可以在本地端口前放置反向代理,或有意设置 `webhookHost: "0.0.0.0"`。
|
||||
|
||||
Webhook 模式会先验证请求防护、Telegram 密钥令牌和 JSON 正文,然后再向 Telegram 返回 `200`。
|
||||
随后 OpenClaw 会通过与长轮询相同的按聊天/按主题机器人通道异步处理该更新,因此缓慢的智能体轮次不会占用 Telegram 的投递 ACK。
|
||||
webhook 模式会先验证请求防护、Telegram secret token 和 JSON 正文,然后再向 Telegram 返回 `200`。
|
||||
随后 OpenClaw 会通过与长轮询相同的按聊天/按主题机器人通道异步处理该更新,因此较慢的智能体轮次不会占住 Telegram 的投递 ACK。
|
||||
|
||||
</Accordion>
|
||||
|
||||
@ -736,13 +735,13 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
- `channels.telegram.textChunkLimit` 默认值为 4000。
|
||||
- `channels.telegram.chunkMode="newline"` 会在按长度拆分前优先使用段落边界(空行)。
|
||||
- `channels.telegram.mediaMaxMb`(默认 100)限制入站和出站 Telegram 媒体大小。
|
||||
- `channels.telegram.mediaGroupFlushMs`(默认 500)控制 Telegram 相册/媒体组在 OpenClaw 将其作为一条入站消息派发前的缓冲时长。如果相册部分到达较晚,可以增大该值;如果想降低相册回复延迟,可以减小该值。
|
||||
- `channels.telegram.timeoutSeconds` 覆盖 Telegram API 客户端超时(如果未设置,则使用 grammY 默认值)。机器人客户端会将低于 60 秒出站文本/正在输入请求防护的配置值进行限制,这样 grammY 就不会在 OpenClaw 的传输防护和回退运行前中止可见回复投递。长轮询仍使用 45 秒的 `getUpdates` 请求防护,因此空闲轮询不会被无限期放弃。
|
||||
- `channels.telegram.pollingStallThresholdMs` 默认值为 `120000`;仅在误报轮询停滞重启时,在 `30000` 到 `600000` 之间调整。
|
||||
- 群组上下文历史使用 `channels.telegram.historyLimit` 或 `messages.groupChat.historyLimit`(默认 50);`0` 表示禁用。
|
||||
- 回复/引用/转发补充上下文目前按接收到的内容传递。
|
||||
- Telegram 允许列表主要控制谁可以触发智能体,而不是完整的补充上下文脱敏边界。
|
||||
- 私信历史控制:
|
||||
- `channels.telegram.mediaGroupFlushMs`(默认 500)控制 Telegram 相册/媒体组在 OpenClaw 将其作为一条入站消息分发前缓冲多久。如果相册部分到达较晚,可以增大该值;如果要降低相册回复延迟,可以减小该值。
|
||||
- `channels.telegram.timeoutSeconds` 会覆盖 Telegram API 客户端超时(如果未设置,则使用 grammY 默认值)。机器人客户端会将低于 60 秒出站文本/输入状态请求防护的配置值钳制在该防护以内,避免 grammY 在 OpenClaw 的传输防护和回退运行前中止可见回复投递。长轮询仍使用 45 秒 `getUpdates` 请求防护,因此空闲轮询不会被无限期遗弃。
|
||||
- `channels.telegram.pollingStallThresholdMs` 默认为 `120000`;仅在误报轮询停滞重启时,才在 `30000` 到 `600000` 之间调整。
|
||||
- 群组上下文历史使用 `channels.telegram.historyLimit` 或 `messages.groupChat.historyLimit`(默认 50);`0` 会禁用。
|
||||
- 回复/引用/转发的补充上下文目前按接收原样传递。
|
||||
- Telegram 允许列表主要用于控制谁能触发智能体,而不是完整的补充上下文删减边界。
|
||||
- 私信历史控制项:
|
||||
- `channels.telegram.dmHistoryLimit`
|
||||
- `channels.telegram.dms["<user_id>"].historyLimit`
|
||||
- `channels.telegram.retry` 配置适用于 Telegram 发送辅助函数(CLI/工具/操作)中可恢复的出站 API 错误。入站最终回复投递也会对 Telegram 预连接失败使用有界安全发送重试,但不会重试可能重复可见消息的模糊发送后网络信封。
|
||||
@ -764,7 +763,7 @@ openclaw message poll --channel telegram --target -1001234567890:topic:42 \
|
||||
--poll-duration-seconds 300 --poll-public
|
||||
```
|
||||
|
||||
仅 Telegram 投票标志:
|
||||
仅 Telegram 支持的投票标志:
|
||||
|
||||
- `--poll-duration-seconds`(5-600)
|
||||
- `--poll-anonymous`
|
||||
@ -773,48 +772,48 @@ openclaw message poll --channel telegram --target -1001234567890:topic:42 \
|
||||
|
||||
Telegram 发送还支持:
|
||||
|
||||
- 当 `channels.telegram.capabilities.inlineButtons` 允许时,使用带有 `buttons` 块的 `--presentation` 来实现内联键盘
|
||||
- `--pin` 或 `--delivery '{"pin":true}'`,在机器人可在该聊天中置顶时请求置顶投递
|
||||
- `--force-document`,将出站图片和 GIF 作为文档发送,而不是压缩照片或动画媒体上传
|
||||
- 当 `channels.telegram.capabilities.inlineButtons` 允许时,使用带有 `buttons` 区块的 `--presentation` 来发送内联键盘
|
||||
- 当机器人可以在该聊天中置顶时,使用 `--pin` 或 `--delivery '{"pin":true}'` 请求置顶投递
|
||||
- 使用 `--force-document` 将出站图片和 GIF 作为文档发送,而不是压缩照片或动画媒体上传
|
||||
|
||||
操作门控:
|
||||
|
||||
- `channels.telegram.actions.sendMessage=false` 禁用出站 Telegram 消息,包括投票
|
||||
- `channels.telegram.actions.poll=false` 禁用 Telegram 投票创建,同时保留常规发送启用
|
||||
- `channels.telegram.actions.sendMessage=false` 会禁用出站 Telegram 消息,包括投票
|
||||
- `channels.telegram.actions.poll=false` 会禁用 Telegram 投票创建,但保留常规发送启用
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Telegram 中的执行审批">
|
||||
Telegram 支持在审批者私信中进行执行审批,也可以选择在原始聊天或主题中发布提示。审批者必须是数字 Telegram 用户 ID。
|
||||
Telegram 支持在审批者私信中进行执行审批,并且可以选择在原始聊天或主题中发布提示。审批者必须是数字 Telegram 用户 ID。
|
||||
|
||||
配置路径:
|
||||
|
||||
- `channels.telegram.execApprovals.enabled`(至少有一个审批者可解析时自动启用)
|
||||
- `channels.telegram.execApprovals.approvers`(回退到 `commands.ownerAllowFrom` 中的数字所有者 ID)
|
||||
- `channels.telegram.execApprovals.enabled`(当至少一个审批者可解析时自动启用)
|
||||
- `channels.telegram.execApprovals.approvers`(回退到来自 `commands.ownerAllowFrom` 的数字所有者 ID)
|
||||
- `channels.telegram.execApprovals.target`:`dm`(默认)| `channel` | `both`
|
||||
- `agentFilter`、`sessionFilter`
|
||||
|
||||
`channels.telegram.allowFrom`、`groupAllowFrom` 和 `defaultTo` 控制谁可以与机器人交谈,以及它在哪里发送普通回复。它们不会让某人成为执行审批者。当尚无命令所有者时,第一次获批的私信配对会引导写入 `commands.ownerAllowFrom`,因此单所有者设置仍可工作,而无需在 `execApprovals.approvers` 下重复 ID。
|
||||
`channels.telegram.allowFrom`、`groupAllowFrom` 和 `defaultTo` 控制谁可以与机器人对话,以及机器人将普通回复发送到哪里。它们不会让某人成为执行审批者。当尚不存在命令所有者时,第一个获批的私信配对会引导设置 `commands.ownerAllowFrom`,因此单所有者设置仍可正常工作,无需在 `execApprovals.approvers` 下重复 ID。
|
||||
|
||||
渠道投递会在聊天中显示命令文本;仅在可信群组/主题中启用 `channel` 或 `both`。当提示落在论坛主题中时,OpenClaw 会为审批提示和后续回复保留该主题。执行审批默认 30 分钟后过期。
|
||||
渠道投递会在聊天中显示命令文本;仅在受信任的群组/主题中启用 `channel` 或 `both`。当提示落在论坛主题中时,OpenClaw 会为审批提示和后续消息保留该主题。执行审批默认在 30 分钟后过期。
|
||||
|
||||
内联审批按钮还要求 `channels.telegram.capabilities.inlineButtons` 允许目标表面(`dm`、`group` 或 `all`)。以 `plugin:` 为前缀的审批 ID 会通过插件审批解析;其他 ID 会先通过执行审批解析。
|
||||
内联审批按钮还要求 `channels.telegram.capabilities.inlineButtons` 允许目标界面(`dm`、`group` 或 `all`)。带有 `plugin:` 前缀的审批 ID 会通过插件审批解析;其他 ID 会先通过执行审批解析。
|
||||
|
||||
参见 [执行审批](/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` | number (ms) | `60000` | 对同一聊天的错误回复之间的最短时间。防止故障期间出现错误刷屏。 |
|
||||
| 键 | 值 | 默认值 | 描述 |
|
||||
| ----------------------------------- | ----------------- | ------- | ------------------------------------------------------------------------------------------------ |
|
||||
| `channels.telegram.errorPolicy` | `reply`, `silent` | `reply` | `reply` 会向聊天发送一条友好的错误消息。`silent` 会完全抑制错误回复。 |
|
||||
| `channels.telegram.errorCooldownMs` | number (ms) | `60000` | 对同一聊天发送错误回复的最小间隔时间。防止在故障期间出现错误刷屏。 |
|
||||
|
||||
支持按账号、按群组和按主题覆盖(与其他 Telegram 配置键使用相同继承规则)。
|
||||
支持按账号、按群组和按主题覆盖(继承方式与其他 Telegram 配置键相同)。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -835,22 +834,22 @@ openclaw message poll --channel telegram --target -1001234567890:topic:42 \
|
||||
## 故障排除
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="机器人不响应群组中的非提及消息">
|
||||
<Accordion title="机器人不回应非提及群组消息">
|
||||
|
||||
- 如果 `requireMention=false`,Telegram 隐私模式必须允许完全可见。
|
||||
- 如果 `requireMention=false`,Telegram 隐私模式必须允许完整可见性。
|
||||
- BotFather:`/setprivacy` -> Disable
|
||||
- 然后将机器人从群组移除并重新添加
|
||||
- 当配置期望未提及的群组消息时,`openclaw channels status` 会发出警告。
|
||||
- `openclaw channels status --probe` 可以检查显式数字群组 ID;通配符 `"*"` 无法进行成员探测。
|
||||
- 然后将机器人从群组中移除并重新添加
|
||||
- 当配置预期未提及的群组消息时,`openclaw channels status` 会发出警告。
|
||||
- `openclaw channels status --probe` 可以检查明确的数字群组 ID;通配符 `"*"` 无法进行成员资格探测。
|
||||
- 快速会话测试:`/activation always`。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="机器人完全看不到群组消息">
|
||||
|
||||
- 当 `channels.telegram.groups` 存在时,群组必须列出(或包含 `"*"`)
|
||||
- 当 `channels.telegram.groups` 存在时,群组必须被列出(或包含 `"*"`)
|
||||
- 验证机器人在群组中的成员身份
|
||||
- 查看日志:`openclaw logs --follow`,了解跳过原因
|
||||
- 查看日志:使用 `openclaw logs --follow` 查看跳过原因
|
||||
|
||||
</Accordion>
|
||||
|
||||
@ -858,33 +857,33 @@ openclaw message poll --channel telegram --target -1001234567890:topic:42 \
|
||||
|
||||
- 授权你的发送者身份(配对和/或数字 `allowFrom`)
|
||||
- 即使群组策略为 `open`,命令授权仍然适用
|
||||
- `setMyCommands failed` 与 `BOT_COMMANDS_TOO_MUCH` 表示原生命令菜单条目过多;减少插件/skill/自定义命令,或禁用原生命令菜单
|
||||
- `deleteMyCommands` / `setMyCommands` 启动调用和 `sendChatAction` 正在输入调用是有界的,并会在请求超时时通过 Telegram 的传输回退重试一次。持续的网络/fetch 错误通常表示到 `api.telegram.org` 的 DNS/HTTPS 可达性问题
|
||||
- 出现 `setMyCommands failed` 且带有 `BOT_COMMANDS_TOO_MUCH` 表示原生命令菜单条目过多;减少插件/skill/自定义命令,或禁用原生命令菜单
|
||||
- `deleteMyCommands` / `setMyCommands` 启动调用和 `sendChatAction` 输入状态调用都有边界,并会在请求超时时通过 Telegram 的传输回退重试一次。持续的网络/fetch 错误通常表示到 `api.telegram.org` 的 DNS/HTTPS 可达性存在问题
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="启动报告未授权令牌">
|
||||
<Accordion title="启动报告未授权 token">
|
||||
|
||||
- `getMe returned 401` 是已配置机器人令牌的 Telegram 身份验证失败。
|
||||
- 在 BotFather 中重新复制或重新生成机器人令牌,然后为默认账号更新 `channels.telegram.botToken`、`channels.telegram.tokenFile`、`channels.telegram.accounts.<id>.botToken` 或 `TELEGRAM_BOT_TOKEN`。
|
||||
- 启动期间的 `deleteWebhook 401 Unauthorized` 也是身份验证失败;将其视为“不存在网络钩子”只会把同一个无效令牌故障推迟到后续 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="轮询或网络不稳定">
|
||||
<Accordion title="Polling or network instability">
|
||||
|
||||
- Node 22+ 加自定义 fetch/代理在 AbortSignal 类型不匹配时可能触发立即中止行为。
|
||||
- 某些主机会先将 `api.telegram.org` 解析为 IPv6;损坏的 IPv6 出站连接可能导致间歇性的 Telegram API 失败。
|
||||
- 如果日志包含 `TypeError: fetch failed` 或 `Network request for 'getUpdates' failed!`,OpenClaw 现在会将这些作为可恢复的网络错误重试。
|
||||
- 在轮询启动期间,OpenClaw 会为 grammY 复用启动时成功的 `getMe` 探测,因此运行器在第一次 `getUpdates` 之前不需要第二次 `getMe`。
|
||||
- 如果轮询启动期间 `deleteWebhook` 因瞬时网络错误而失败,OpenClaw 会继续进入长轮询,而不是再发起一次轮询前控制平面调用。仍处于活动状态的网络钩子会表现为 `getUpdates` 冲突;随后 OpenClaw 会重建 Telegram 传输层并重试网络钩子清理。
|
||||
- 如果 Telegram 套接字按较短的固定周期回收,请检查 `channels.telegram.timeoutSeconds` 是否过低;机器人客户端会把低于出站请求和 `getUpdates` 请求保护下限的配置值提升到该下限,但旧版本在该值设为低于这些保护阈值时,可能会中止每一次轮询或回复。
|
||||
- 如果日志包含 `Polling stall detected`,默认情况下,OpenClaw 会在 120 秒内没有完成长轮询活性检查后重启轮询并重建 Telegram 传输层。
|
||||
- 当正在运行的轮询账号在启动宽限期后仍未完成 `getUpdates`、正在运行的网络钩子账号在启动宽限期后仍未完成 `setWebhook`,或上次成功的轮询传输活动已过期时,`openclaw channels status --probe` 和 `openclaw doctor` 会发出警告。
|
||||
- 仅当长时间运行的 `getUpdates` 调用是健康的,但你的主机仍报告误判的轮询停滞重启时,才增大 `channels.telegram.pollingStallThresholdMs`。持续停滞通常指向主机与 `api.telegram.org` 之间的代理、DNS、IPv6 或 TLS 出站问题。
|
||||
- Telegram 还会为 Bot API 传输遵循进程代理环境变量,包括 `HTTP_PROXY`、`HTTPS_PROXY`、`ALL_PROXY` 及其小写变体。`NO_PROXY` / `no_proxy` 仍可绕过 `api.telegram.org`。
|
||||
- 如果服务环境通过 `OPENCLAW_PROXY_URL` 配置了 OpenClaw 托管代理,且不存在标准代理环境变量,Telegram 也会使用该 URL 进行 Bot API 传输。
|
||||
- 在直接出站/TLS 不稳定的 VPS 主机上,通过 `channels.telegram.proxy` 路由 Telegram API 调用:
|
||||
- Node 22+ + 自定义 fetch/proxy 可能在 AbortSignal 类型不匹配时触发立即中止行为。
|
||||
- 某些主机会先将 `api.telegram.org` 解析为 IPv6;损坏的 IPv6 出站可能导致间歇性 Telegram API 失败。
|
||||
- 如果日志包含 `TypeError: fetch failed` 或 `Network request for 'getUpdates' failed!`,OpenClaw 现在会将这些错误作为可恢复的网络错误重试。
|
||||
- 在轮询启动期间,OpenClaw 会为 grammY 复用启动时成功的 `getMe` 探测,因此 runner 不需要在第一次 `getUpdates` 前再执行第二次 `getMe`。
|
||||
- 如果 `deleteWebhook` 在轮询启动期间因瞬时网络错误失败,OpenClaw 会继续进入长轮询,而不是再进行一次轮询前的控制平面调用。仍处于活动状态的 webhook 会表现为 `getUpdates` 冲突;随后 OpenClaw 会重建 Telegram 传输并重试 webhook 清理。
|
||||
- 如果 Telegram 套接字按较短的固定周期回收,请检查是否设置了较低的 `channels.telegram.timeoutSeconds`;bot 客户端会将低于出站和 `getUpdates` 请求保护值的配置值钳制到保护值以上,但旧版本在该值低于这些保护值时可能会中止每一次轮询或回复。
|
||||
- 如果日志包含 `Polling stall detected`,默认情况下,OpenClaw 会在 120 秒内没有完成长轮询存活信号后重启轮询并重建 Telegram 传输。
|
||||
- 当正在运行的轮询账号在启动宽限期后仍未完成 `getUpdates`、正在运行的 webhook 账号在启动宽限期后仍未完成 `setWebhook`,或上一次成功的轮询传输活动已过期时,`openclaw channels status --probe` 和 `openclaw doctor` 会发出警告。
|
||||
- 只有当长时间运行的 `getUpdates` 调用是健康的,但你的主机仍报告误报的轮询停滞重启时,才增大 `channels.telegram.pollingStallThresholdMs`。持续停滞通常指向主机与 `api.telegram.org` 之间的 proxy、DNS、IPv6 或 TLS 出站问题。
|
||||
- Telegram 的 Bot API 传输也会遵循进程 proxy 环境变量,包括 `HTTP_PROXY`、`HTTPS_PROXY`、`ALL_PROXY` 及其小写变体。`NO_PROXY` / `no_proxy` 仍可绕过 `api.telegram.org`。
|
||||
- 如果服务环境中通过 `OPENCLAW_PROXY_URL` 配置了 OpenClaw 托管 proxy,且没有标准 proxy 环境变量,Telegram 也会将该 URL 用于 Bot API 传输。
|
||||
- 在直接出站/TLS 不稳定的 VPS 主机上,请通过 `channels.telegram.proxy` 路由 Telegram API 调用:
|
||||
|
||||
```yaml
|
||||
channels:
|
||||
@ -892,8 +891,8 @@ channels:
|
||||
proxy: socks5://<user>:<password>@proxy-host:1080
|
||||
```
|
||||
|
||||
- Node 22+ 默认使用 `autoSelectFamily=true`(WSL2 除外)。Telegram DNS 结果顺序会依次遵循 `OPENCLAW_TELEGRAM_DNS_RESULT_ORDER`、`channels.telegram.network.dnsResultOrder`,然后遵循进程默认值,例如 `NODE_OPTIONS=--dns-result-order=ipv4first`;如果都不适用,Node 22+ 会回退到 `ipv4first`。
|
||||
- 如果你的主机是 WSL2,或明确在仅 IPv4 行为下表现更好,请强制设置地址族选择:
|
||||
- Node 22+ 默认使用 `autoSelectFamily=true`(WSL2 除外)。Telegram DNS 结果顺序依次遵循 `OPENCLAW_TELEGRAM_DNS_RESULT_ORDER`、`channels.telegram.network.dnsResultOrder`,然后是进程默认值,例如 `NODE_OPTIONS=--dns-result-order=ipv4first`;如果都不适用,Node 22+ 会回退到 `ipv4first`。
|
||||
- 如果你的主机是 WSL2,或明确在仅 IPv4 行为下效果更好,请强制选择地址族:
|
||||
|
||||
```yaml
|
||||
channels:
|
||||
@ -902,10 +901,7 @@ channels:
|
||||
autoSelectFamily: false
|
||||
```
|
||||
|
||||
- RFC 2544 基准测试范围响应(`198.18.0.0/15`)默认已允许
|
||||
用于 Telegram 媒体下载。如果受信任的 fake-IP 或
|
||||
透明代理在媒体下载期间把 `api.telegram.org` 重写为其他
|
||||
私有/内部/特殊用途地址,你可以选择启用仅限 Telegram 的绕过:
|
||||
- 默认情况下,Telegram 媒体下载已允许 RFC 2544 基准测试范围的应答(`198.18.0.0/15`)。如果可信的 fake-IP 或透明 proxy 在媒体下载期间将 `api.telegram.org` 重写为其他 private/internal/special-use 地址,你可以选择启用仅限 Telegram 的绕过:
|
||||
|
||||
```yaml
|
||||
channels:
|
||||
@ -914,25 +910,18 @@ 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 访问应保持关闭。
|
||||
`channels.telegram.network.dangerouslyAllowPrivateNetwork` 会削弱 Telegram 媒体 SSRF 保护。仅在可信、由运营方控制的 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
|
||||
@ -948,48 +937,48 @@ dig +short api.telegram.org AAAA
|
||||
|
||||
主要参考:[配置参考 - Telegram](/zh-CN/gateway/config-channels#telegram)。
|
||||
|
||||
<Accordion title="高信息量 Telegram 字段">
|
||||
<Accordion title="High-signal Telegram fields">
|
||||
|
||||
- 启动/身份验证:`enabled`、`botToken`、`tokenFile`、`accounts.*`(`tokenFile` 必须指向常规文件;符号链接会被拒绝)
|
||||
- 访问控制:`dmPolicy`、`allowFrom`、`groupPolicy`、`groupAllowFrom`、`groups`、`groups.*.topics.*`、顶层 `bindings[]`(`type: "acp"`)
|
||||
- 执行审批:`execApprovals`、`accounts.*.execApprovals`
|
||||
- exec 审批:`execApprovals`、`accounts.*.execApprovals`
|
||||
- 命令/菜单:`commands.native`、`commands.nativeSkills`、`customCommands`
|
||||
- 线程/回复:`replyToMode`、`dm.threadReplies`、`direct.*.threadReplies`
|
||||
- 流式传输:`streaming`(预览)、`streaming.preview.toolProgress`、`blockStreaming`
|
||||
- 格式化/投递:`textChunkLimit`、`chunkMode`、`linkPreview`、`responsePrefix`
|
||||
- 媒体/网络:`mediaMaxMb`、`mediaGroupFlushMs`、`timeoutSeconds`、`pollingStallThresholdMs`、`retry`、`network.autoSelectFamily`、`network.dangerouslyAllowPrivateNetwork`、`proxy`
|
||||
- 自定义 API 根地址:`apiRoot`(仅 Bot API 根地址;不要包含 `/bot<TOKEN>`)
|
||||
- 网络钩子:`webhookUrl`、`webhookSecret`、`webhookPath`、`webhookHost`
|
||||
- 自定义 API 根路径:`apiRoot`(仅 Bot API 根路径;不要包含 `/bot<TOKEN>`)
|
||||
- webhook:`webhookUrl`、`webhookSecret`、`webhookPath`、`webhookHost`
|
||||
- 操作/能力:`capabilities.inlineButtons`、`actions.sendMessage|editMessage|deleteMessage|reactions|sticker`
|
||||
- 回应:`reactionNotifications`、`reactionLevel`
|
||||
- reactions:`reactionNotifications`、`reactionLevel`
|
||||
- 错误:`errorPolicy`、`errorCooldownMs`
|
||||
- 写入/历史记录:`configWrites`、`historyLimit`、`dmHistoryLimit`、`dms.*.historyLimit`
|
||||
- 写入/历史:`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>
|
||||
|
||||
## 相关内容
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="配对" icon="link" href="/zh-CN/channels/pairing">
|
||||
<Card title="Pairing" icon="link" href="/zh-CN/channels/pairing">
|
||||
将 Telegram 用户与 Gateway 网关配对。
|
||||
</Card>
|
||||
<Card title="群组" icon="users" href="/zh-CN/channels/groups">
|
||||
群组和话题允许列表行为。
|
||||
<Card title="Groups" icon="users" href="/zh-CN/channels/groups">
|
||||
群组和话题 allowlist 行为。
|
||||
</Card>
|
||||
<Card title="渠道路由" icon="route" href="/zh-CN/channels/channel-routing">
|
||||
<Card title="Channel routing" icon="route" href="/zh-CN/channels/channel-routing">
|
||||
将入站消息路由到智能体。
|
||||
</Card>
|
||||
<Card title="安全" icon="shield" href="/zh-CN/gateway/security">
|
||||
<Card title="Security" icon="shield" href="/zh-CN/gateway/security">
|
||||
威胁模型和加固。
|
||||
</Card>
|
||||
<Card title="多智能体路由" icon="sitemap" href="/zh-CN/concepts/multi-agent">
|
||||
<Card title="Multi-agent routing" icon="sitemap" href="/zh-CN/concepts/multi-agent">
|
||||
将群组和话题映射到智能体。
|
||||
</Card>
|
||||
<Card title="故障排除" icon="wrench" href="/zh-CN/channels/troubleshooting">
|
||||
<Card title="Troubleshooting" icon="wrench" href="/zh-CN/channels/troubleshooting">
|
||||
跨渠道诊断。
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
@ -1,22 +1,22 @@
|
||||
---
|
||||
read_when:
|
||||
- 说明入站消息如何变成回复
|
||||
- 澄清会话、排队模式或流式传输行为
|
||||
- 记录推理可见性及其使用影响
|
||||
- 说明会话、排队模式或流式传输行为
|
||||
- 记录推理可见性及其对用量的影响
|
||||
summary: 消息流、会话、排队和推理可见性
|
||||
title: 消息
|
||||
x-i18n:
|
||||
generated_at: "2026-04-30T15:18:53Z"
|
||||
generated_at: "2026-05-04T06:12:24Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: fdeee014d92767a725501691fbe0c4ee6b631acc9a2ab5cbbcf321bfee9679b9
|
||||
source_hash: 15242e21fd17a9f2013561003e108d197204d834caf51bbcdc53ffb3f118b14f
|
||||
source_path: concepts/messages.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
OpenClaw 通过会话解析、排队、流式传输、工具执行和推理可见性组成的流水线处理入站消息。本页映射从入站消息到回复的路径。
|
||||
OpenClaw 通过会话解析、排队、流式传输、工具执行和推理可见性这一流水线处理入站消息。本页说明从入站消息到回复的路径。
|
||||
|
||||
## 消息流程(高层)
|
||||
## 消息流(高层)
|
||||
|
||||
```
|
||||
Inbound message
|
||||
@ -30,17 +30,17 @@ Inbound message
|
||||
|
||||
- `messages.*` 用于前缀、排队和群组行为。
|
||||
- `agents.defaults.*` 用于分块流式传输和分块默认值。
|
||||
- 渠道覆盖项(`channels.whatsapp.*`、`channels.telegram.*` 等)用于上限和流式开关。
|
||||
- 渠道覆盖项(`channels.whatsapp.*`、`channels.telegram.*` 等)用于上限和流式传输开关。
|
||||
|
||||
完整架构见[配置](/zh-CN/gateway/configuration)。
|
||||
完整 schema 见[配置](/zh-CN/gateway/configuration)。
|
||||
|
||||
## 入站去重
|
||||
|
||||
渠道可能会在重新连接后重新投递同一条消息。OpenClaw 会保留一个短生命周期缓存,以渠道/账号/对等方/会话/消息 ID 为键,避免重复投递触发另一次智能体运行。
|
||||
渠道可能在重连后重新投递同一条消息。OpenClaw 会维护一个短期缓存,键由渠道/账号/对等方/会话/消息 ID 组成,因此重复投递不会触发另一次智能体运行。
|
||||
|
||||
## 入站防抖
|
||||
|
||||
来自**同一发送者**的快速连续消息可以通过 `messages.inbound` 批处理为单个智能体轮次。防抖按渠道 + 对话限定作用域,并使用最新消息进行回复串联/ID 关联。
|
||||
来自**同一发送者**的快速连续消息可以通过 `messages.inbound` 批处理为单个智能体轮次。防抖按每个渠道 + 对话划分作用域,并使用最新消息进行回复串联/ID 处理。
|
||||
|
||||
配置(全局默认值 + 按渠道覆盖):
|
||||
|
||||
@ -61,18 +61,18 @@ Inbound message
|
||||
|
||||
注意:
|
||||
|
||||
- 防抖适用于**仅文本**消息;媒体/附件会立即刷新。
|
||||
- 控制命令会绕过防抖,因此它们保持独立,**除非**某个渠道明确选择加入同发送者私信合并(例如 [BlueBubbles `coalesceSameSenderDms`](/zh-CN/channels/bluebubbles#coalescing-split-send-dms-command--url-in-one-composition)),此时私信命令会在防抖窗口内等待,以便拆分发送的载荷可以加入同一个智能体轮次。
|
||||
- 防抖适用于**纯文本**消息;媒体/附件会立即刷新。
|
||||
- 控制命令会绕过防抖,因此它们保持独立,**除非**某个渠道显式选择加入同一发送者私信合并(例如 [BlueBubbles `coalesceSameSenderDms`](/zh-CN/channels/bluebubbles#coalescing-split-send-dms-command--url-in-one-composition)),此时私信命令会在防抖窗口内等待,使拆分发送的载荷可以加入同一个智能体轮次。
|
||||
|
||||
## 会话和设备
|
||||
|
||||
会话由 Gateway 网关拥有,而不是由客户端拥有。
|
||||
|
||||
- 直接聊天会折叠到智能体主会话键中。
|
||||
- 直接聊天会折叠到智能体主会话键。
|
||||
- 群组/渠道会获得自己的会话键。
|
||||
- 会话存储和转录记录位于 Gateway 网关主机上。
|
||||
|
||||
多个设备/渠道可以映射到同一个会话,但历史不会完整同步回每个客户端。建议:长对话使用一个主设备,以避免上下文分叉。Control UI 和 TUI 始终显示由 Gateway 网关支持的会话转录记录,因此它们是真实来源。
|
||||
多个设备/渠道可以映射到同一个会话,但历史不会完全同步回每个客户端。建议:长对话使用一个主设备,以避免上下文分歧。Control UI 和 TUI 始终显示由 Gateway 网关支持的会话转录记录,因此它们是真相来源。
|
||||
|
||||
详情:[会话管理](/zh-CN/concepts/session)。
|
||||
|
||||
@ -80,18 +80,18 @@ Inbound message
|
||||
|
||||
工具结果 `content` 是模型可见的结果。工具结果 `details` 是用于 UI 渲染、诊断、媒体投递和插件的运行时元数据。
|
||||
|
||||
OpenClaw 明确保持这条边界:
|
||||
OpenClaw 会明确保持这条边界:
|
||||
|
||||
- `toolResult.details` 会在提供商重放和压缩输入之前被剥离。
|
||||
- `toolResult.details` 会在提供商重放和压缩输入前被剥离。
|
||||
- 持久化的会话转录记录只保留有界的 `details`;过大的元数据会替换为标记了 `persistedDetailsTruncated: true` 的紧凑摘要。
|
||||
- 插件和工具应将模型必须读取的文本放在 `content` 中,而不只是放在 `details` 中。
|
||||
- 插件和工具应将模型必须读取的文本放在 `content` 中,而不是只放在 `details` 中。
|
||||
|
||||
## 入站正文和历史上下文
|
||||
|
||||
OpenClaw 将**提示正文**与**命令正文**分开:
|
||||
|
||||
- `BodyForAgent`:当前消息面向主模型的文本。渠道插件应让它聚焦于发送者当前承载提示的文本。
|
||||
- `Body`:旧版提示回退。这可能包含渠道信封和可选的历史包装器,但当 `BodyForAgent` 可用时,当前渠道不应依赖它作为主模型输入。
|
||||
- `Body`:旧版提示回退。它可能包含渠道信封和可选的历史包装器,但当前渠道在 `BodyForAgent` 可用时不应依赖它作为主模型输入。
|
||||
- `CommandBody`:用于指令/命令解析的原始用户文本。
|
||||
- `RawBody`:`CommandBody` 的旧版别名(为兼容性保留)。
|
||||
|
||||
@ -100,30 +100,30 @@ OpenClaw 将**提示正文**与**命令正文**分开:
|
||||
- `[Chat messages since your last reply - for context]`
|
||||
- `[Current message - respond to this]`
|
||||
|
||||
对于**非直接聊天**(群组/渠道/房间),**当前消息正文**会加上发送者标签前缀(与历史条目使用相同样式)。这让实时消息和排队/历史消息在智能体提示中保持一致。
|
||||
对于**非直接聊天**(群组/渠道/房间),**当前消息正文**会加上发送者标签前缀(与历史条目使用相同样式)。这会让实时消息和排队/历史消息在智能体提示中保持一致。
|
||||
|
||||
历史缓冲区是**仅待处理**的:它们包含未触发运行的群组消息(例如受提及门控的消息),并**排除**已经在会话转录记录中的消息。
|
||||
历史缓冲区是**仅待处理**的:它们包括未触发运行的群组消息(例如受提及门控的消息),并**排除**已经在会话转录记录中的消息。
|
||||
|
||||
指令剥离只应用于**当前消息**部分,因此历史保持完整。包装历史的渠道应将 `CommandBody`(或 `RawBody`)设置为原始消息文本,并将 `Body` 保持为组合提示。结构化历史、回复、转发和渠道元数据会在提示组装期间渲染为用户角色的不可信上下文块。
|
||||
历史缓冲区可通过 `messages.groupChat.historyLimit`(全局默认值)和按渠道覆盖项配置,例如 `channels.slack.historyLimit` 或 `channels.telegram.accounts.<id>.historyLimit`(设置为 `0` 可禁用)。
|
||||
指令剥离只适用于**当前消息**部分,因此历史会保持完整。包装历史的渠道应将 `CommandBody`(或 `RawBody`)设置为原始消息文本,并将 `Body` 保持为组合提示。结构化历史、回复、转发和渠道元数据会在提示组装期间渲染为用户角色的不受信任上下文块。
|
||||
历史缓冲区可通过 `messages.groupChat.historyLimit`(全局默认值)以及按渠道覆盖项(例如 `channels.slack.historyLimit` 或 `channels.telegram.accounts.<id>.historyLimit`)配置(设置为 `0` 可禁用)。
|
||||
|
||||
## 排队和跟进
|
||||
|
||||
如果已有运行处于活跃状态,入站消息可以被排队、引导到当前运行中,或收集到跟进轮次中。
|
||||
如果已有运行处于活动状态,入站消息可以排队、引导进入当前运行,或收集用于跟进轮次。
|
||||
|
||||
- 通过 `messages.queue`(以及 `messages.queue.byChannel`)配置。
|
||||
- 默认模式是 `steer`,当引导回退到排队跟进投递时,使用 500ms 跟进防抖。
|
||||
- 默认模式是 `steer`,当引导回退到排队跟进投递时,会使用 500ms 跟进防抖。
|
||||
- 模式:`steer`、`followup`、`collect`、`steer-backlog`、`interrupt`,以及旧版一次一个的 `queue` 模式。
|
||||
|
||||
详情:[命令队列](/zh-CN/concepts/queue)和 [Steering queue](/zh-CN/concepts/queue-steering)。
|
||||
|
||||
## 渠道运行所有权
|
||||
|
||||
渠道插件可以在消息进入会话队列之前保留顺序、对输入做防抖,并应用传输背压。它们不应围绕智能体轮次本身施加单独的超时。一旦消息被路由到某个会话,长时间运行的工作就由会话、工具和运行时生命周期治理,使所有渠道都能以一致方式报告并从慢轮次中恢复。
|
||||
渠道插件可以在消息进入会话队列之前保持顺序、对输入防抖,并施加传输背压。它们不应围绕智能体轮次本身施加单独的超时。一旦消息路由到会话,长时间运行的工作就由会话、工具和运行时生命周期管理,以便所有渠道都能一致地报告慢轮次并从中恢复。
|
||||
|
||||
## 流式传输、分块和批处理
|
||||
|
||||
分块流式传输会在模型生成文本块时发送部分回复。分块遵守渠道文本限制,并避免拆分围栏代码。
|
||||
分块流式传输会在模型生成文本块时发送部分回复。分块会遵守渠道文本限制,并避免拆分围栏代码。
|
||||
|
||||
关键设置:
|
||||
|
||||
@ -131,20 +131,20 @@ OpenClaw 将**提示正文**与**命令正文**分开:
|
||||
- `agents.defaults.blockStreamingBreak`(`text_end|message_end`)
|
||||
- `agents.defaults.blockStreamingChunk`(`minChars|maxChars|breakPreference`)
|
||||
- `agents.defaults.blockStreamingCoalesce`(基于空闲的批处理)
|
||||
- `agents.defaults.humanDelay`(块回复之间类似人类的暂停)
|
||||
- `agents.defaults.humanDelay`(分块回复之间的类人停顿)
|
||||
- 渠道覆盖项:`*.blockStreaming` 和 `*.blockStreamingCoalesce`(非 Telegram 渠道需要显式设置 `*.blockStreaming: true`)
|
||||
|
||||
详情:[流式传输 + 分块](/zh-CN/concepts/streaming)。
|
||||
|
||||
## 推理可见性和令牌
|
||||
## 推理可见性和 token
|
||||
|
||||
OpenClaw 可以公开或隐藏模型推理:
|
||||
|
||||
- `/reasoning on|off|stream` 控制可见性。
|
||||
- 当模型生成推理内容时,它仍会计入令牌用量。
|
||||
- Telegram 支持将推理流式传输到草稿气泡中。
|
||||
- 当模型生成推理内容时,它仍会计入 token 使用量。
|
||||
- Telegram 支持将推理流式传输到临时草稿气泡,并在最终投递后删除;使用 `/reasoning on` 可获得持久化推理输出。
|
||||
|
||||
详情:[思考 + 推理指令](/zh-CN/tools/thinking)和[令牌使用](/zh-CN/reference/token-use)。
|
||||
详情:[思考 + 推理指令](/zh-CN/tools/thinking)和 [Token 使用](/zh-CN/reference/token-use)。
|
||||
|
||||
## 前缀、串联和回复
|
||||
|
||||
@ -157,19 +157,19 @@ OpenClaw 可以公开或隐藏模型推理:
|
||||
|
||||
## 静默回复
|
||||
|
||||
精确的静默令牌 `NO_REPLY` / `no_reply` 表示“不要投递用户可见回复”。
|
||||
当一个轮次还有待处理工具媒体(例如生成的 TTS 音频)时,OpenClaw 会剥离静默文本,但仍会投递媒体附件。
|
||||
OpenClaw 按对话类型解析该行为:
|
||||
确切的静默 token `NO_REPLY` / `no_reply` 表示“不要投递用户可见的回复”。
|
||||
当某个轮次还有待处理的工具媒体(例如生成的 TTS 音频)时,OpenClaw 会剥离静默文本,但仍然投递媒体附件。
|
||||
OpenClaw 会按对话类型解析该行为:
|
||||
|
||||
- 直接对话默认不允许静默,并会将纯静默回复改写为简短的可见回退。
|
||||
- 直接对话默认不允许静默,并将裸静默回复重写为简短的可见回退。
|
||||
- 群组/渠道默认允许静默。
|
||||
- 内部编排默认允许静默。
|
||||
|
||||
OpenClaw 还会对在非直接聊天中任何助手回复之前发生的内部运行器失败使用静默回复,因此群组/渠道不会看到 Gateway 网关错误样板文本。直接聊天默认显示紧凑失败文案;只有当 `/verbose` 为 `on` 或 `full` 时,才会显示原始运行器详情。
|
||||
OpenClaw 还会对非直接聊天中、任何助手回复之前发生的内部运行器失败使用静默回复,因此群组/渠道不会看到 Gateway 网关错误样板文本。直接聊天默认显示紧凑的失败文案;只有当 `/verbose` 为 `on` 或 `full` 时,才会显示原始运行器详情。
|
||||
|
||||
默认值位于 `agents.defaults.silentReply` 和 `agents.defaults.silentReplyRewrite` 下;`surfaces.<id>.silentReply` 和 `surfaces.<id>.silentReplyRewrite` 可以按表面覆盖它们。
|
||||
默认值位于 `agents.defaults.silentReply` 和 `agents.defaults.silentReplyRewrite` 下;`surfaces.<id>.silentReply` 和 `surfaces.<id>.silentReplyRewrite` 可以按 surface 覆盖它们。
|
||||
|
||||
当父会话有一个或多个待处理的已生成子智能体运行时,纯静默回复会在所有表面上被丢弃,而不是被改写,因此父会话会保持安静,直到子完成事件投递真正的回复。
|
||||
当父会话有一个或多个待处理的已生成子智能体运行时,所有 surface 上的裸静默回复都会被丢弃而不是被重写,因此父会话会保持安静,直到子完成事件投递真正的回复。
|
||||
|
||||
## 相关
|
||||
|
||||
|
||||
@ -1,29 +1,29 @@
|
||||
---
|
||||
read_when:
|
||||
- 说明流式传输或分块在渠道上的工作方式
|
||||
- 解释流式传输或分块在渠道中的工作方式
|
||||
- 更改分块流式传输或渠道分块行为
|
||||
- 调试重复/过早的分块回复或渠道预览流式传输
|
||||
summary: 流式传输 + 分块行为(分块回复、渠道预览流式传输、模式映射)
|
||||
title: 流式传输和分块
|
||||
x-i18n:
|
||||
generated_at: "2026-05-03T21:05:41Z"
|
||||
generated_at: "2026-05-04T06:12:31Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: 1335f4f5532060bd8bf839683a2b1fbab38f38887c5583135652b4753e0f6a50
|
||||
source_hash: fcb41ceb5602ab42c3fd41a59de62cc965ea61fdbc058c052fb93689a9c5299b
|
||||
source_path: concepts/streaming.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
OpenClaw 有两个独立的流式传输层:
|
||||
|
||||
- **分块流式传输(渠道):** 在助手写入时发出已完成的 **块**。这些是普通的渠道消息(不是 token 增量)。
|
||||
- **预览流式传输(Telegram/Discord/Slack):** 生成期间更新临时的 **预览消息**。
|
||||
- **分块流式传输(渠道):** 在助手写入时发出完成的 **块**。这些是普通渠道消息(不是 token 增量)。
|
||||
- **预览流式传输(Telegram/Discord/Slack):** 在生成期间更新临时 **预览消息**。
|
||||
|
||||
目前没有面向渠道消息的 **真正 token 增量流式传输**。预览流式传输基于消息(发送 + 编辑/追加)。
|
||||
目前还没有对渠道消息的 **真正 token 增量流式传输**。预览流式传输基于消息(发送 + 编辑/追加)。
|
||||
|
||||
## 分块流式传输(渠道消息)
|
||||
|
||||
分块流式传输会在助手输出可用时,以较粗的分块发送输出。
|
||||
分块流式传输会在助手输出可用时,以较粗粒度的块发送输出。
|
||||
|
||||
```
|
||||
Model output
|
||||
@ -38,74 +38,75 @@ Model output
|
||||
图例:
|
||||
|
||||
- `text_delta/events`:模型流事件(对于非流式模型可能较稀疏)。
|
||||
- `chunker`:`EmbeddedBlockChunker`,应用最小/最大边界 + 换行偏好。
|
||||
- `channel send`:实际出站消息(分块回复)。
|
||||
- `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? }`(发送前合并流式块)。
|
||||
- 渠道硬上限:`*.textChunkLimit`(例如 `channels.whatsapp.textChunkLimit`)。
|
||||
- 渠道分块模式:`*.chunkMode`(默认 `length`,`newline` 会在按长度分块前按空行(段落边界)拆分)。
|
||||
- Discord 软上限:`channels.discord.maxLinesPerMessage`(默认 17),拆分较高的回复以避免 UI 裁剪。
|
||||
- Discord 软上限:`channels.discord.maxLinesPerMessage`(默认 17),会拆分过高的回复以避免 UI 裁切。
|
||||
|
||||
**边界语义:**
|
||||
|
||||
- `text_end`:只要 chunker 发出块就流式发送;每次 `text_end` 时刷新。
|
||||
- `message_end`:等待助手消息完成,然后刷新已缓冲的输出。
|
||||
- `text_end`:在 chunker 发出块后立即流式传输块;每个 `text_end` 都刷新。
|
||||
- `message_end`:等到助手消息完成,然后刷新已缓冲的输出。
|
||||
|
||||
如果缓冲文本超过 `maxChars`,`message_end` 仍会使用 chunker,因此它可以在末尾发出多个分块。
|
||||
如果缓冲文本超过 `maxChars`,`message_end` 仍会使用 chunker,因此它可以在末尾发出多个块。
|
||||
|
||||
### 使用分块流式传输传递媒体
|
||||
### 使用分块流式传输交付媒体
|
||||
|
||||
`MEDIA:` 指令是普通的投递元数据。当分块流式传输提前发送媒体块时,OpenClaw 会记住该轮次的这次投递。如果最终助手载荷重复同一个媒体 URL,最终投递会去除重复媒体,而不是再次发送附件。
|
||||
`MEDIA:` 指令是普通交付元数据。当分块流式传输提前发送媒体块时,OpenClaw 会记住本轮交付。如果最终助手载荷重复相同媒体 URL,最终交付会剔除重复媒体,而不是再次发送附件。
|
||||
|
||||
完全重复的最终载荷会被抑制。如果最终载荷在已流式发送的媒体周围添加了不同文本,OpenClaw 仍会发送新文本,同时保持媒体只投递一次。这可以避免在 Telegram 等渠道上出现重复语音留言或文件,例如当智能体在流式传输期间发出 `MEDIA:`,而提供商也在完成回复中包含它时。
|
||||
完全重复的最终载荷会被抑制。如果最终载荷在已流式传输的媒体周围添加了不同文本,OpenClaw 仍会发送新文本,同时保持媒体只交付一次。这可以防止在 Telegram 等渠道上出现重复语音消息或文件,例如当智能体在流式传输期间发出 `MEDIA:`,而提供商也在完成的回复中包含它时。
|
||||
|
||||
## 分块算法(低/高边界)
|
||||
|
||||
块分块由 `EmbeddedBlockChunker` 实现:
|
||||
|
||||
- **低边界:** 缓冲区 >= `minChars` 前不发出(除非强制)。
|
||||
- **低边界:** 在缓冲区 >= `minChars` 之前不发出(除非强制)。
|
||||
- **高边界:** 优先在 `maxChars` 之前拆分;如果强制,则在 `maxChars` 处拆分。
|
||||
- **断点偏好:** `paragraph` → `newline` → `sentence` → `whitespace` → 硬断点。
|
||||
- **代码围栏:** 永不在围栏内部拆分;当在 `maxChars` 处强制拆分时,会关闭 + 重新打开围栏,以保持 Markdown 有效。
|
||||
- **代码围栏:** 永不在围栏内拆分;当在 `maxChars` 处强制拆分时,关闭 + 重新打开围栏以保持 Markdown 有效。
|
||||
|
||||
`maxChars` 会被限制到渠道的 `textChunkLimit`,所以你不能超过每个渠道的上限。
|
||||
`maxChars` 会被钳制到渠道 `textChunkLimit`,因此你无法超过每个渠道的上限。
|
||||
|
||||
## 合并(合并流式块)
|
||||
|
||||
启用分块流式传输时,OpenClaw 可以在发送前 **合并连续的块分块**。这会减少“单行刷屏”,同时仍提供渐进式输出。
|
||||
启用分块流式传输后,OpenClaw 可以在发送前 **合并连续的块分片**。这会减少“单行刷屏”,同时仍提供渐进式输出。
|
||||
|
||||
- 合并会等待 **空闲间隔**(`idleMs`)后再刷新。
|
||||
- 缓冲区受 `maxChars` 限制,超过时会刷新。
|
||||
- `minChars` 会防止过小片段发送,直到累积足够文本(最终刷新总会发送剩余文本)。
|
||||
- 连接符来自 `blockStreamingChunk.breakPreference`(`paragraph` → `\n\n`,`newline` → `\n`,`sentence` → 空格)。
|
||||
- `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"`(刷新一次;如果很长,可能产生多个分块)。
|
||||
- **在末尾流式传输全部内容:** `blockStreamingBreak: "message_end"`(刷新一次,如果非常长则可能有多个分块)。
|
||||
- **无分块流式传输:** `blockStreamingDefault: "off"`(仅最终回复)。
|
||||
|
||||
**渠道注意事项:** 除非明确将 `*.blockStreaming` 设置为 `true`,否则分块流式传输为 **关闭**。渠道可以流式传输实时预览(`channels.<channel>.streaming`),而不发送分块回复。
|
||||
**渠道注意事项:** 除非显式将 `*.blockStreaming` 设为 `true`,否则分块流式传输 **关闭**。渠道可以在没有块回复的情况下流式传输实时预览(`channels.<channel>.streaming`)。
|
||||
|
||||
配置位置提醒:`blockStreaming*` 默认值位于 `agents.defaults` 下,而不是根配置中。
|
||||
配置位置提醒:`blockStreaming*` 默认值位于 `agents.defaults` 下,而不是根配置。
|
||||
|
||||
## 预览流式传输模式
|
||||
|
||||
@ -115,29 +116,29 @@ Model output
|
||||
|
||||
- `off`:禁用预览流式传输。
|
||||
- `partial`:单个预览,会被最新文本替换。
|
||||
- `block`:以分块/追加步骤更新预览。
|
||||
- `progress`:生成期间显示进度/状态预览,完成时给出最终答案。
|
||||
- `block`:预览以分块/追加步骤更新。
|
||||
- `progress`:生成期间显示进度/Status 预览,完成时给出最终答案。
|
||||
|
||||
`streaming.mode: "block"` 是适用于 Discord 和 Telegram 等可编辑渠道的预览流式传输模式。它不会在这些渠道启用渠道分块投递。需要普通分块回复时,请使用 `streaming.block.enabled` 或旧版 `blockStreaming` 渠道键。Microsoft Teams 是例外:它没有草稿预览分块传输,因此 `streaming.mode: "block"` 会映射到 Teams 分块投递,而不是原生 partial/progress 流式传输。
|
||||
`streaming.mode: "block"` 是一种适用于 Discord 和 Telegram 等支持编辑渠道的预览流式传输模式。它不会在那里启用渠道块交付。当你想要普通块回复时,请使用 `streaming.block.enabled` 或旧版 `blockStreaming` 渠道键。Microsoft Teams 是例外:它没有草稿预览块传输,因此 `streaming.mode: "block"` 会映射到 Teams 块交付,而不是原生 partial/progress 流式传输。
|
||||
|
||||
### 渠道映射
|
||||
|
||||
| 渠道 | `off` | `partial` | `block` | `progress` |
|
||||
| ---------- | ----- | --------- | ------- | ----------------------- |
|
||||
| Telegram | ✅ | ✅ | ✅ | 可编辑进度草稿 |
|
||||
| Discord | ✅ | ✅ | ✅ | 可编辑进度草稿 |
|
||||
| Slack | ✅ | ✅ | ✅ | ✅ |
|
||||
| Mattermost | ✅ | ✅ | ✅ | ✅ |
|
||||
| MS Teams | ✅ | ✅ | ✅ | 原生进度流 |
|
||||
| 渠道 | `off` | `partial` | `block` | `progress` |
|
||||
| ---------- | ----- | --------- | ------- | ---------------- |
|
||||
| Telegram | ✅ | ✅ | ✅ | 可编辑进度草稿 |
|
||||
| Discord | ✅ | ✅ | ✅ | 可编辑进度草稿 |
|
||||
| Slack | ✅ | ✅ | ✅ | ✅ |
|
||||
| Mattermost | ✅ | ✅ | ✅ | ✅ |
|
||||
| MS Teams | ✅ | ✅ | ✅ | 原生进度流 |
|
||||
|
||||
仅 Slack:
|
||||
|
||||
- 当 `channels.slack.streaming.mode="partial"` 时,`channels.slack.streaming.nativeTransport` 会切换 Slack 原生流式传输 API 调用(默认:`true`)。
|
||||
- Slack 原生流式传输和 Slack 助手线程状态需要一个回复线程目标。顶层私信不会显示那种线程样式预览,但仍可使用 Slack 草稿预览帖子和编辑。
|
||||
- 当 `channels.slack.streaming.mode="partial"` 时,`channels.slack.streaming.nativeTransport` 会切换 Slack 原生流式 API 调用(默认:`true`)。
|
||||
- Slack 原生流式传输和 Slack 助手线程 Status 需要回复线程目标。顶层私信不会显示那种线程式预览,但它们仍可以使用 Slack 草稿预览帖子和编辑。
|
||||
|
||||
旧版键迁移:
|
||||
|
||||
- Telegram:旧版 `streamMode` 以及标量/布尔 `streaming` 值会被 Doctor/配置兼容路径检测并迁移到 `streaming.mode`。
|
||||
- Telegram:旧版 `streamMode` 和标量/布尔 `streaming` 值会被 doctor/config 兼容路径检测并迁移到 `streaming.mode`。
|
||||
- Discord:`streamMode` + 布尔 `streaming` 会自动迁移到 `streaming` 枚举。
|
||||
- Slack:`streamMode` 会自动迁移到 `streaming.mode`;布尔 `streaming` 会自动迁移到 `streaming.mode` 加 `streaming.nativeTransport`;旧版 `nativeStreaming` 会自动迁移到 `streaming.nativeTransport`。
|
||||
|
||||
@ -146,49 +147,49 @@ Model output
|
||||
Telegram:
|
||||
|
||||
- 在私信和群组/话题中使用 `sendMessage` + `editMessageText` 预览更新。
|
||||
- 当预览已可见约一分钟时,会发送新的最终消息,而不是就地编辑;随后清理预览,使 Telegram 的时间戳反映回复完成时间。
|
||||
- 当显式启用 Telegram 分块流式传输时,会跳过预览流式传输(避免双重流式传输)。
|
||||
- `/reasoning stream` 可以将推理写入预览。
|
||||
- 当预览已可见约一分钟时,会发送新的最终消息,而不是就地编辑,然后清理预览,使 Telegram 的时间戳反映回复完成时间。
|
||||
- 当 Telegram 分块流式传输被显式启用时,会跳过预览流式传输(以避免双重流式传输)。
|
||||
- `/reasoning stream` 可以将推理写入临时预览,该预览会在最终交付后删除。
|
||||
|
||||
Discord:
|
||||
|
||||
- 使用发送 + 编辑预览消息。
|
||||
- `block` 模式使用草稿分块(`draftChunk`)。
|
||||
- 当显式启用 Discord 分块流式传输时,会跳过预览流式传输。
|
||||
- 最终媒体、错误和显式回复载荷会取消待处理预览,而不刷新新草稿,然后使用普通投递。
|
||||
- 当 Discord 分块流式传输被显式启用时,会跳过预览流式传输。
|
||||
- 最终媒体、错误和显式回复载荷会取消待处理预览,而不刷新新草稿,然后使用正常交付。
|
||||
|
||||
Slack:
|
||||
|
||||
- `partial` 可在可用时使用 Slack 原生流式传输(`chat.startStream`/`append`/`stop`)。
|
||||
- 当可用时,`partial` 可以使用 Slack 原生流式传输(`chat.startStream`/`append`/`stop`)。
|
||||
- `block` 使用追加式草稿预览。
|
||||
- `progress` 使用状态预览文本,然后发送最终答案。
|
||||
- `progress` 使用 Status 预览文本,然后给出最终答案。
|
||||
- 没有回复线程的顶层私信会使用草稿预览帖子和编辑,而不是 Slack 原生流式传输。
|
||||
- 原生和草稿预览流式传输会抑制该轮次的分块回复,因此 Slack 回复只会通过一种投递路径流式传输。
|
||||
- 最终媒体/错误载荷和进度最终消息不会创建一次性草稿消息;只有可编辑预览的文本/块最终消息会刷新待处理草稿文本。
|
||||
- 原生和草稿预览流式传输会抑制该轮的块回复,因此 Slack 回复只通过一条交付路径流式传输。
|
||||
- 最终媒体/错误载荷和进度最终结果不会创建一次性草稿消息;只有可编辑预览的文本/块最终结果会刷新待处理草稿文本。
|
||||
|
||||
Mattermost:
|
||||
|
||||
- 将思考、工具活动和部分回复文本流式写入单个草稿预览帖子,并在最终答案可以安全发送时就地完成。
|
||||
- 如果预览帖子在完成时已被删除或不可用,则回退为发送新的最终帖子。
|
||||
- 最终媒体/错误载荷会在普通投递前取消待处理预览更新,而不是刷新临时预览帖子。
|
||||
- 将思考、工具活动和部分回复文本流式传输到单个草稿预览帖子中,并在最终答案可安全发送时就地完成。
|
||||
- 如果预览帖子已被删除,或在完成时不可用,则回退为发送新的最终帖子。
|
||||
- 最终媒体/错误载荷会在正常交付前取消待处理预览更新,而不是刷新临时预览帖子。
|
||||
|
||||
Matrix:
|
||||
|
||||
- 当最终文本可以复用预览事件时,草稿预览会就地完成。
|
||||
- 仅媒体、错误和回复目标不匹配的最终消息会在普通投递前取消待处理预览更新;已可见的过期预览会被撤回。
|
||||
- 当最终文本可复用预览事件时,草稿预览会就地完成。
|
||||
- 仅媒体、错误和回复目标不匹配的最终结果会在正常交付前取消待处理预览更新;已经可见的陈旧预览会被撤回。
|
||||
|
||||
### 工具进度预览更新
|
||||
|
||||
预览流式传输还可以包含 **工具进度** 更新,即类似“正在搜索网络”、“正在读取文件”或“正在调用工具”的短状态行。它们会在工具运行期间出现在同一条预览消息中,早于最终回复。这让多步骤工具轮次在第一个思考预览和最终答案之间保持视觉上的活跃,而不是静默。
|
||||
预览流式传输还可以包含 **工具进度** 更新,即类似“搜索网络”、“读取文件”或“调用工具”的短 Status 行,它们会在工具运行期间出现在同一条预览消息中,先于最终回复。这让多步骤工具轮次在第一个思考预览和最终答案之间保持视觉上的活跃,而不是沉默。
|
||||
|
||||
支持的界面:
|
||||
|
||||
- 默认情况下,当预览流式传输处于活动状态时,**Discord**、**Slack**、**Telegram** 和 **Matrix** 会将工具进度流式写入实时预览编辑。Microsoft Teams 在个人聊天中使用其原生进度流。
|
||||
- Telegram 自 `v2026.4.22` 起已发布并启用工具进度预览更新;保持启用可保留该已发布行为。
|
||||
- **Discord**、**Slack**、**Telegram** 和 **Matrix** 在预览流式传输处于活动状态时,默认会将工具进度流式传输到实时预览编辑中。Microsoft Teams 在个人聊天中使用其原生进度流。
|
||||
- Telegram 自 `v2026.4.22` 起已启用工具进度预览更新;保持启用会保留该已发布行为。
|
||||
- **Mattermost** 已经将工具活动折叠进其单个草稿预览帖子(见上文)。
|
||||
- 工具进度编辑会遵循活动的预览流式传输模式;当预览流式传输为 `off`,或分块流式传输已接管消息时,会跳过它们。在 Telegram 上,`streaming.mode: "off"` 表示仅最终消息:通用进度闲聊也会被抑制,而不是作为独立状态消息投递;审批提示、媒体载荷和错误仍会正常路由。
|
||||
- 若要保留预览流式传输但隐藏工具进度行,请将该渠道的 `streaming.preview.toolProgress` 设置为 `false`。若要完全禁用预览编辑,请将 `streaming.mode` 设置为 `off`。
|
||||
- Telegram 选定引用回复是例外:当 `replyToMode` 不是 `"off"` 且存在选定引用文本时,OpenClaw 会跳过该轮次的答案预览流,因此工具进度预览行无法渲染。没有选定引用文本的当前消息回复仍会保留预览流式传输。详情参见 [Telegram 渠道文档](/zh-CN/channels/telegram)。
|
||||
- 工具进度编辑遵循当前的预览流式传输模式;当预览流式传输为 `off`,或当分块流式传输已接管消息时,它们会被跳过。在 Telegram 上,`streaming.mode: "off"` 表示仅最终结果:通用进度闲聊也会被抑制,而不是作为独立 Status 消息交付,同时审批提示、媒体载荷和错误仍会正常路由。
|
||||
- 若要保留预览流式传输但隐藏工具进度行,请将该渠道的 `streaming.preview.toolProgress` 设为 `false`。若要完全禁用预览编辑,请将 `streaming.mode` 设为 `off`。
|
||||
- Telegram 选中文本引用回复是一个例外:当 `replyToMode` 不是 `"off"` 且存在选中的引用文本时,OpenClaw 会跳过该轮的答案预览流,因此工具进度预览行无法渲染。没有选中引用文本的当前消息回复仍会保留预览流式传输。详情请参阅 [Telegram 渠道文档](/zh-CN/channels/telegram)。
|
||||
|
||||
示例:
|
||||
|
||||
@ -207,9 +208,9 @@ Matrix:
|
||||
}
|
||||
```
|
||||
|
||||
## 相关
|
||||
## 相关内容
|
||||
|
||||
- [进度草稿](/zh-CN/concepts/progress-drafts) — 长轮次期间会更新的可见进行中消息
|
||||
- [进度草稿](/zh-CN/concepts/progress-drafts) — 在长轮次期间更新的可见进行中消息
|
||||
- [消息](/zh-CN/concepts/messages) — 消息生命周期和投递
|
||||
- [重试](/zh-CN/concepts/retry) — 投递失败时的重试行为
|
||||
- [渠道](/zh-CN/channels) — 按渠道列出的流式传输支持
|
||||
- [渠道](/zh-CN/channels) — 每个渠道的流式传输支持
|
||||
|
||||
Loading…
Reference in New Issue
Block a user