Skip to content

命令队列(Command Queue,2026-01-16)

我们会通过一个轻量的进程内队列,将所有渠道的入站自动回复 runs 串行化,以防多个 agent runs 相互冲突;同时仍允许在不同 sessions 之间进行安全并行。

为什么(Why)

  • 自动回复 runs 可能很昂贵(LLM 调用),并且当多条入站消息在短时间内到达时可能互相冲突。
  • 串行化可以避免争抢共享资源(session files、logs、CLI stdin),并降低触发上游限流的概率。

工作方式(How it works)

  • 一个“按 lane 感知”的 FIFO 队列会按 lane 依次出队,每个 lane 具有可配置的并发上限(未配置的 lanes 默认 1;main 默认 4,subagent 默认 8)。
  • runEmbeddedPiAgent 会按 session key 入队(lane session:<key>),以保证每个 session 同时只有一个 active run。
  • 每个 session run 随后还会进入一个 全局 lane(默认 main),从而使整体并行度受 agents.defaults.maxConcurrent 限制。
  • 启用 verbose logging 时,如果某个 run 在开始前等待了超过约 2 秒,会输出一条短提示。
  • typing indicators 仍会在入队时立即触发(渠道支持时),因此用户体验在等待排队时不变。

队列模式(per channel)

入站消息可以“引导(steer)”当前 run、等待一个 followup 回合,或两者都做:

  • steer:立即注入到当前 run(在下一个 tool 边界之后取消尚未执行的 tool calls)。如果当前 run 不在 streaming,则回退为 followup。
  • followup:在当前 run 结束后,为下一次 agent 回合入队。
  • collect:将所有排队消息合并为单个 followup 回合(默认)。如果消息指向不同的 channels/threads,会分别出队以保持路由一致。
  • steer-backlog(也叫 steer+backlog):现在 steer 并且保留消息以便后续 followup。
  • interrupt(legacy):中止该 session 的 active run,然后运行最新消息。
  • queue(legacy alias):等同于 steer

steer-backlog 意味着你可能在 steered run 之后还能得到一个 followup 响应,因此在 streaming 的对外表面上看起来像“重复回复”。如果你希望每条入站消息只产生一次回复,优先用 collect/steer

/queue collect 作为独立命令(per-session)发送,或设置 messages.queue.byChannel.discord: "collect"

默认值(未在 config 设置时):

  • 所有表面 → collect

通过 messages.queue 全局或按渠道配置:

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

队列选项(Queue options)

这些选项适用于 followupcollectsteer-backlog(并且当 steer 回退为 followup 时也适用):

  • debounceMs:在开始 followup 回合前等待一段“安静期”(避免出现“continue, continue”)。
  • cap:每个 session 最大排队消息数。
  • drop:溢出策略(oldnewsummarize)。

summarize 会保留被丢弃消息的简短 bullet 列表,并作为合成的 followup prompt 注入。 默认:debounceMs: 1000cap: 20drop: summarize

Per-session 覆盖

  • /queue <mode> 作为独立命令发送,可将该 mode 存入当前 session。
  • 选项可组合:/queue collect debounce:2s cap:25 drop:summarize
  • /queue default/queue reset 会清除 session 覆盖。

作用范围与保证(Scope and guarantees)

  • 对所有使用 gateway reply pipeline 的入站渠道的 auto-reply agent runs 生效(WhatsApp web、Telegram、Slack、Discord、Signal、iMessage、webchat 等)。
  • 默认 lane(main)在进程范围内用于入站 + 主心跳;设置 agents.defaults.maxConcurrent 可允许多个 sessions 并行。
  • 可能存在额外 lanes(例如 cronsubagent),以便后台任务并行运行而不阻塞入站回复。
  • 每个 session 的 lane 保证同一时刻只有一个 agent run 会触碰该 session。
  • 无外部依赖或后台 worker 线程;纯 TypeScript + promises。

排查(Troubleshooting)

  • 如果命令看起来卡住了,启用 verbose logs 并查找类似 “queued for …ms” 的日志,以确认队列正在出队。
  • 如果需要队列深度信息,启用 verbose logs 并观察队列耗时相关日志。