生成模型:Claude Opus 4.6 (anthropic/claude-opus-4-6) Token 消耗:输入 ~280,000 tokens,输出 ~20,000 tokens(本章合计)
当 Agent 生成回复后,消息需要经过出站处理流水线才能发送到用户的通道。这个流程包括消息分块、确认反应、打字指示器和会话标签生成等步骤。
6.3.1 消息分块(Chunking)算法与通道限制
AI Agent 的回复可能非常长——一个详细的代码分析或技术解释可能达到数千甚至上万字符。但每个消息通道都有单条消息的长度限制:
当回复超过通道限制时,需要将其分块(Chunk)成多条消息依次发送。分块不是简单地按字符数截断——它需要考虑 Markdown 格式的完整性。
每个通道的出站适配器定义了自己的分块器(Chunker)和分块模式:
// src/channels/plugins/types.adapters.ts(出站适配器类型)
export type ChannelOutboundAdapter = {
chunker?: ((text: string, limit: number) => string[]) | null;
chunkerMode?: "text" | "markdown";
textChunkLimit?: number;
};
大多数通道使用 "text" 模式的纯文本分块(chunkText),而 Telegram 由于其 HTML 格式支持,使用 "markdown" 模式的专用分块器(markdownToTelegramHtmlChunks):
Discord 和 Slack 的 chunker 设置为 null,表示它们使用自己客户端库内置的分块逻辑,而不是 OpenClaw 的通用分块器。
6.3.2 确认反应(ACK Reactions)
确认反应是一种轻量级的用户反馈机制:当 Gateway 收到消息并开始处理时,会在原始消息上添加一个表情反应(如 "眼睛" 表情),让用户知道消息已被接收。
src/channels/ack-reactions.ts 实现了确认反应的门控逻辑:
默认行为是 "group-mentions"——只在群组中被 @提及时才发送确认反应。这避免了在私聊中产生冗余的反应(私聊不需要确认,因为回复本身就是确认),同时在群组中给用户明确的反馈。
确认反应还支持回复后移除——当 Agent 发出回复后,之前添加的确认反应会被自动移除:
6.3.3 打字指示器(Typing Indicators)
许多通道支持"对方正在输入"的提示。OpenClaw 在 Agent 处理消息期间持续发送打字指示器,让用户知道 AI 正在思考。
src/channels/typing.ts 提供了打字回调的工厂函数:
设计上的一个细节:onIdle 回调是可选的。这是因为某些通道(如 Telegram)的打字指示器会自动在一定时间后过期,不需要显式停止。而其他通道(如 Discord)需要手动停止打字状态。
打字指示器的错误不会中断消息处理流程——它只是一个辅助性的用户体验功能,即使失败也不应影响 Agent 的正常回复。
6.3.4 会话标签与回复前缀
src/channels/conversation-label.ts 为每个会话生成一个人类可读的标签,用于在 UI 和日志中标识会话:
标签生成遵循"尽可能有意义"的原则:私聊显示对方的名字(如 "Alice"),群组显示群组名称(如 "#general"),如果只有数字 ID 则追加 id: 前缀以便识别(如 "工程群 id:12345")。
src/channels/reply-prefix.ts 可以在 Agent 的每条回复前添加前缀,通常用于标注正在使用的模型或身份信息:
回复前缀是可配置的模板,可以包含变量如 {{model}}、{{provider}}、{{identityName}} 等。例如配置 responsePrefix: "[{{model}}] " 会在每条回复前添加 [claude-4-opus] 这样的模型标识。
出站消息处理流水线将 Agent 的原始回复转化为用户在各通道中看到的最终消息:
智能分块:根据通道限制自动拆分长消息,支持纯文本和 Markdown 两种分块模式
确认反应:在消息被接收时添加表情反应,回复后自动移除,默认只在群组被提及时启用
打字指示器:Agent 处理期间持续发送打字状态,错误不影响主流程
会话标签:为每个会话生成人类可读的标签,方便在 UI 和日志中识别
回复前缀:可配置的模板系统,在回复前添加模型、身份等标注信息