Skip to content

OpenClaw 命令队列通过 lane‑aware FIFO 队列串行化所有入站自动回复,避免 LLM 调用和共享资源冲突。默认模式为 steer(将消息注入当前运行);可按渠道或会话临时覆盖模式与选项(debounceMscapdrop)。启用 verbose 日志并搜索 "queued for …ms" 可确认队列是否排干。支持 followupcollectinterrupt 三种额外模式,适用于不同并发场景。

OpenClaw 队列模式怎么配置:steer/followup/collect/interrupt 详解

OpenClaw 通过一个进程内轻量级队列串行化所有渠道的入站自动回复,防止多条消息同时触发 agent 运行时的资源冲突,同时允许跨 session 安全并行。

为什么需要队列

  • 自动回复运行代价高昂(LLM 调用),多条入站消息同时到达时容易发生冲突。
  • 串行化可避免对共享资源(session 文件、日志、CLI stdin)的竞争,并降低触发上游限流的概率。

工作原理

  • 采用 lane‑aware FIFO 队列,每个 lane 有可配置的并发上限:
    • 未配置的 lane 默认并发为 1
    • main lane 默认并发为 4
    • subagent lane 默认并发为 8
  • runEmbeddedPiAgentsession key(lane session:<key>)入队,确保每个 session 同时只有一个活跃运行。
  • 每个 session 运行随后进入全局 lane(默认 main),总并发由 agents.defaults.maxConcurrent 控制。
  • 启用 verbose 日志后,等待超过约 2s 才开始的运行会输出简短提示(queued for …ms)。
  • 打字指示器在入队时立即触发(若渠道支持),不影响等待期间的用户体验。

队列模式

/queue 命令控制当 session 已有活跃运行时,普通入站消息如何行为:

  • steer:将消息注入当前运行。Pi 会在 当前 assistant turn 完成工具调用后、下一次 LLM 调用前 交付所有待处理的 steer 消息;Codex app‑server 收到一次批量的 turn/steer。若运行未在流式输出或 steering 不可用,OpenClaw 等待当前运行结束再启动新 prompt。
  • followup:不进行 steering,每条消息在当前运行结束后入队,顺序等待 agent 下一轮处理。
  • collect:不进行 steering,将排队的消息合并为单次 followup 轮(静默窗口 debounceMs 后才触发)。若消息面向不同渠道/线程,则单独排干以保留路由。
  • interrupt:中止该 session 的当前运行,然后运行最新消息。

对于运行时特定的 timing 和依赖行为,参见 Steering queue。对于显式 /steer <message> 命令,参见 Steer

模式配置示例

全局或按渠道在 messages.queue 中配置:

json5
{
  messages: {
    queue: {
      mode: "steer",
      debounceMs: 500,
      cap: 20,
      drop: "summarize",
      byChannel: { discord: "collect" },
    },
  },
}

队列选项

以下选项适用于 queued delivery。debounceMssteer 模式下也设置 Codex steering 的静默窗口:

  • debounceMs:排干 followup 或 collect 批次前的静默窗口;Codex steer 模式下为发送批量的 turn/steer 前的静默窗口。纯数字表示毫秒,/queue 选项中支持单位 mssmhd
  • cap:每个 session 最大排队消息数。值 < 1 时被忽略。
  • drop:溢出策略:
    • "summarize"(默认):丢弃旧条目,保留精简摘要,并作为合成 followup prompt 注入。
    • "old":丢弃旧条目,不保留摘要。
    • "new":队列已满时拒绝最新消息。

默认值debounceMs: 500cap: 20drop: summarize

优先级

对于模式选择,OpenClaw 按以下顺序解析:

  1. 内联或存储的 per‑session /queue 覆盖。
  2. messages.queue.byChannel.&lt;channel&gt;
  3. messages.queue.mode
  4. 默认 steer

对于选项,内联或存储的 /queue 选项优先于配置。然后依次应用渠道特定的 debounce(messages.queue.debounceMsByChannel)、插件 debounce 默认值、全局 messages.queue 选项、内置默认值。capdrop 是全局/session 选项,不是 per‑channel 配置键。

Per‑session 覆盖

  • 发送 /queue <steer|followup|collect|interrupt> 作为独立命令,为当前 session 存储队列模式。
  • 可组合选项:/queue collect debounce:0.5s cap:25 drop:summarize
  • /queue default/queue reset 清除 session 覆盖。

作用范围与保证

  • 适用于所有使用 gateway 回复流水线的入站渠道的自动回复 agent 运行(WhatsApp web、Telegram、Slack、Discord、Signal、iMessage、webchat 等)。
  • 默认 lane(main)是进程范围的,涵盖入站消息 + 主心跳;设置 agents.defaults.maxConcurrent 允许多个 session 并行。
  • 额外的 lane(如 croncron‑nestednestedsubagent)允许后台任务在不阻塞入站回复的情况下并行运行。隔离的 cron agent turn 占用 cron 槽位,其内部 agent 执行使用 cron‑nested;两者均受 cron.maxConcurrentRuns 控制。共享的非 cron nested 流程保持自己的 lane 行为。这些独立运行作为 background tasks 跟踪。
  • Per‑session lane 确保每次只有一个 agent 运行接触某个给定 session。
  • 无外部依赖或后台工作线程;纯 TypeScript + Promise 实现。

故障排查

  • 若命令似乎卡住,启用 verbose 日志并查找 "queued for …ms" 行,确认队列正在排干。
  • 若需要查看队列深度,启用 verbose 日志并观察队列时序行。
  • Codex app‑server 运行接受一个 turn 后停止输出进度时,Codex 适配器会中断该运行,从而释放活跃的 session lane,避免等待外层运行超时。
  • 启用诊断后,超过 diagnostics.stuckSessionWarnMs 仍处于 processing 状态且未观察到回复、工具、状态、块或 ACP 进度的 session,会根据当前活动分类:活跃工作记录为 session.long_running;活跃但最近无进展记录为 session.stalledsession.stuck 保留给无活跃工作的陈旧 session 记账,只有该路径可以释放受影响的 session lane,使排队的 work 继续排干。重复的 session.stuck 诊断会在 session 未变化时退避。

常见问题

如何临时改变某个会话的队列模式?

在聊天中发送 /queue collect(或其他模式),可组合选项如 /queue collect debounce:0.5s cap:25 drop:summarize。用 /queue default/queue reset 清除会话覆盖。

命令卡住了怎么办?

启用 verbose 日志,查找 "queued for …ms" 行确认队列是否在排干。如果某个 session 长时间处于 processing 状态且无进度,检查 diagnostics.stuckSessionWarnMs 配置,并确认是否有 session.stalledsession.stuck 日志输出。

怎样让多个 session 的 agent 同时运行?

设置 agents.defaults.maxConcurrent 大于 1(例如 4),即可允许 main lane 中多个 session 并行。后台任务(cron、subagent)使用独立的 lane 和并发上限,不会阻塞入站回复。