指令佇列(2026-01-16)
我們透過一個小型的行程內佇列,將所有頻道的自動回覆執行序列化處理,避免多個 Agent 執行之間互相碰撞,同時仍允許跨 Session 的安全平行處理。
為什麼需要佇列
- 自動回覆執行可能很昂貴(LLM 呼叫),當多則訊息在短時間內接連到達時容易發生衝突。
- 序列化避免了共用資源(Session 檔案、日誌、CLI stdin)的競爭,也降低觸發上游速率限制的機率。
運作方式
- 一個具 Lane 感知的 FIFO 佇列,針對每個 Lane 以可設定的並行上限進行消耗(未設定的 Lane 預設為 1;main 預設為 4,subagent 為 8)。
runEmbeddedPiAgent以 Session Key 入列(Lane 為session:<key>),確保每個 Session 同時只有一個執行中的任務。- 每個 Session 的執行接著被排入全域 Lane(預設為
main),整體平行度受agents.defaults.maxConcurrent限制。 - 啟用詳細日誌時,若排隊等待超過約 2 秒才開始執行,會輸出一則簡短通知。
- 輸入指示器在入列時就會立即觸發(當頻道支援時),使用者體驗在等待期間不受影響。
佇列模式(依頻道設定)
收到的訊息可以導引當前執行、排隊等待下一輪,或兩者兼具:
steer:立即注入當前執行(在下一個工具邊界後取消待處理的工具呼叫)。若非串流模式,會退回為 followup。followup:在當前執行結束後排入下一輪 Agent 處理。collect:將所有排隊訊息合併為單一後續處理輪(預設)。若訊息指向不同頻道/討論串,會個別消耗以保留路由。steer-backlog(又名steer+backlog):立即導引同時保留訊息供後續處理。interrupt(舊版):中止該 Session 的作用中執行,然後處理最新的訊息。queue(舊版別名):等同steer。
使用 steer-backlog 時,在被導引的執行之後你還會收到一個後續回應,因此串流介面看起來可能像是重複了。如果你希望每則收到的訊息只對應一個回應,請使用 collect 或 steer。
以獨立指令送出 /queue collect(依 Session 設定)或在設定中設定 messages.queue.byChannel.discord: "collect"。
預設值(未在設定中指定時):
- 所有介面 →
collect
透過 messages.queue 進行全域或依頻道設定:
{
messages: {
queue: {
mode: "collect",
debounceMs: 1000,
cap: 20,
drop: "summarize",
byChannel: { discord: "collect" },
},
},
}
佇列選項
以下選項適用於 followup、collect 和 steer-backlog(以及 steer 退回為 followup 時):
debounceMs:等待靜默後再開始後續處理(防止連續的「繼續、繼續」)。cap:每個 Session 的最大排隊訊息數。drop:溢出策略(old、new、summarize)。
summarize 會保留被捨棄訊息的簡短重點清單,並作為合成的後續提示注入。
預設值:debounceMs: 1000、cap: 20、drop: summarize。
依 Session 覆蓋設定
- 以獨立指令送出
/queue <mode>即可為當前 Session 儲存該模式。 - 可組合選項:
/queue collect debounce:2s 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、subagent),讓背景工作可以平行執行而不阻塞收到的回覆。 - 依 Session 的 Lane 保證同一時間只有一個 Agent 執行會存取特定的 Session。
- 沒有外部依賴或背景工作執行緒;純 TypeScript + Promise 實作。
疑難排解
- 如果指令看起來卡住了,啟用詳細日誌並尋找「queued for …ms」的記錄來確認佇列有在正常消耗。
- 如果你需要了解佇列深度,啟用詳細日誌並觀察佇列計時的記錄。