Appearance
OpenClaw 命令队列通过 lane‑aware FIFO 队列串行化所有入站自动回复,避免 LLM 调用和共享资源冲突。默认模式为 steer(将消息注入当前运行);可按渠道或会话临时覆盖模式与选项(debounceMs、cap、drop)。启用 verbose 日志并搜索 "queued for …ms" 可确认队列是否排干。支持 followup、collect、interrupt 三种额外模式,适用于不同并发场景。
OpenClaw 队列模式怎么配置:steer/followup/collect/interrupt 详解
OpenClaw 通过一个进程内轻量级队列串行化所有渠道的入站自动回复,防止多条消息同时触发 agent 运行时的资源冲突,同时允许跨 session 安全并行。
为什么需要队列
- 自动回复运行代价高昂(LLM 调用),多条入站消息同时到达时容易发生冲突。
- 串行化可避免对共享资源(session 文件、日志、CLI stdin)的竞争,并降低触发上游限流的概率。
工作原理
- 采用 lane‑aware FIFO 队列,每个 lane 有可配置的并发上限:
- 未配置的 lane 默认并发为 1
mainlane 默认并发为 4subagentlane 默认并发为 8
runEmbeddedPiAgent按 session key(lanesession:<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。debounceMs 在 steer 模式下也设置 Codex steering 的静默窗口:
debounceMs:排干 followup 或 collect 批次前的静默窗口;Codexsteer模式下为发送批量的turn/steer前的静默窗口。纯数字表示毫秒,/queue选项中支持单位ms、s、m、h、d。cap:每个 session 最大排队消息数。值 < 1 时被忽略。drop:溢出策略:"summarize"(默认):丢弃旧条目,保留精简摘要,并作为合成 followup prompt 注入。"old":丢弃旧条目,不保留摘要。"new":队列已满时拒绝最新消息。
默认值:debounceMs: 500、cap: 20、drop: summarize。
优先级
对于模式选择,OpenClaw 按以下顺序解析:
- 内联或存储的 per‑session
/queue覆盖。 messages.queue.byChannel.<channel>。messages.queue.mode。- 默认
steer。
对于选项,内联或存储的 /queue 选项优先于配置。然后依次应用渠道特定的 debounce(messages.queue.debounceMsByChannel)、插件 debounce 默认值、全局 messages.queue 选项、内置默认值。cap 和 drop 是全局/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(如
cron、cron‑nested、nested、subagent)允许后台任务在不阻塞入站回复的情况下并行运行。隔离的 cron agent turn 占用cron槽位,其内部 agent 执行使用cron‑nested;两者均受cron.maxConcurrentRuns控制。共享的非 cronnested流程保持自己的 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.stalled;session.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.stalled 或 session.stuck 日志输出。
怎样让多个 session 的 agent 同时运行?
设置 agents.defaults.maxConcurrent 大于 1(例如 4),即可允许 main lane 中多个 session 并行。后台任务(cron、subagent)使用独立的 lane 和并发上限,不会阻塞入站回复。