10.6 流式输出、重试与提前终止
长任务的可靠性不只取决于模型能力,还取决于系统是否能持续输出可观测状态、是否能对失败做有界重试、以及是否能在必要时安全终止执行。本节结合 OpenClaw 的官方文档,说明流式输出的工程机制、重试与降级的边界,以及如何把这些能力纳入验收与排障流程。
10.6.1 流式输出的内部机制:Block Chunker
OpenClaw 的流式输出并非简单地把模型返回的 token 逐个转发给渠道,而是经过一个 EmbeddedBlockChunker 做智能切分。官方文档明确指出:当前没有真正的逐 token 流式推送到渠道消息,而是采用两层流式策略:
块流式(Block Streaming):将模型生成的文本按完整块(段落、代码块等)发送到渠道,是主要的输出方式。
预览流式(Preview Streaming):在 Telegram、Discord、Slack 等支持消息编辑的渠道上,通过不断编辑临时消息来模拟逐步输出效果。
10.6.1.1 切分偏好与围栏感知
Block Chunker 在 minChars 和 maxChars 之间寻找最佳断点,支持按优先级递降的切分偏好:
段落边界(
\n\n)——默认首选换行符(
\n)——降级选项句末标点(句号、问号、感叹号)——进一步降级
空白字符——最后的软断点
硬切——到达
maxChars仍无断点时强制切分
关键的安全约束是围栏感知(fence-aware):切分器会解析 Markdown 代码围栏(```),保证永远不在代码块内部切断。如果硬切点恰好落在代码块内,切分器会先关闭围栏(插入匹配的关闭标记),在下一个 chunk 开头重新打开,确保每个独立 chunk 都是合法的 Markdown。
10.6.1.2 刷新时机与配置
流式输出的中间态维护在一个 blockBuffer 中,在两个关键时机触发刷新:
工具调用前:确保在执行工具之前把已缓冲的文本块全部发出,让用户看到工具调用前的完整上下文。
智能体轮次结束时:强制刷新残余缓冲区。
相关配置键包括:blockStreamingDefault(开关)、blockStreamingBreak(刷新时机)、blockStreamingChunk(字符上下界)、humanDelay(块间延迟,用于模拟人类输入节奏)。
10.6.2 流式输出的工程意义:把中间态变成可观测事实
流式输出不仅用于改善交互体验,更重要的是让长链路任务具备可观测中间态,例如:任务是否进入路由、是否发生工具拒绝、是否触发重试。对于运维与排障,关键在于能用结构化日志回放一次请求的完整链路。
推荐在排障窗口跟随 JSON 日志,并按事件类型过滤:
10.6.3 重试策略:按请求重试,而非按流程重试
官方文档对重试策略的核心原则是:按单次 HTTP 请求重试,而非按多步骤流程重试;通过只重试当前步骤来保持执行顺序。
默认配置为每次请求最多 3 次尝试、最大延迟 30 秒、10% 抖动(jitter)。不同渠道供应商有特化策略:
Discord:仅针对 HTTP 429(限流)响应重试,且会优先使用 Discord 自身返回的重试延迟。
Telegram:处理更广泛的瞬时故障(429、超时、连接重置、临时不可用),并在 Markdown 渲染失败时自动降级为纯文本重发。
重试配置可通过 ~/.openclaw/openclaw.json 按供应商独立调整(尝试次数、最小/最大延迟、抖动比例)。
工程上建议遵循三条规则:
区分可重试与不可重试故障:鉴权失败、参数不合法、策略拒绝属于不可重试,应快速失败并给出可操作指引。
对写操作谨慎重试:写操作可能产生外部副作用,除非具备幂等机制与结果对账,否则不建议自动重试。
为重试设预算:限制最大次数与最大耗时,避免失败放大为资源占用与队列拥塞。
10.6.4 模型故障切换概述
当上游模型供应商出现不可用或限流时,重试可能不足以恢复服务。OpenClaw 支持两阶段的故障切换机制:
认证档案轮转(Auth Profile Rotation):在同一供应商内轮转不同的认证档案,优先级基于显式配置(
auth.order)、档案类型(OAuth 优先于 API Key)和使用历史。系统会在每个会话内固定一个档案以保持缓存亲和性,仅在该档案进入冷却期时才轮转。模型回退(Model Fallback):当所有认证档案耗尽后,按
agents.defaults.model.fallbacks列表依次尝试备选模型。
失败的档案进入指数退避冷却(1 分钟 → 5 分钟 → 25 分钟 → 1 小时封顶)。模型故障切换与系统整体可靠性保障的深入讨论,见第十一章。
10.6.5 提前终止与资源预算:让失败可控,让取消可落地
提前终止用于两个目标:
用户主动取消或任务明显偏航时,尽快释放资源。
触发安全边界时,及时阻断高风险动作。
工程上建议把“可终止”写成约束:
工具调用应有超时与失败返回,并在日志里记录原因。
关键写操作应设置确认点,并具备回滚或对账路径。
对于长输出,尽量用结构化中间态而不是一次性堆叠结果,便于在取消时留下可用证据。
验收与排障时,可用 status --deep 与 doctor 先确认系统状态与配置,再结合日志回放定位具体失败点。
最后更新于
