回合與佇列
回合是一輪工作:你傳送提示,agent 處理它,然後回答。對話是一連串接連進行的回合。當你在回合仍在執行時傳送訊息,OAR 會把它保留在佇列中,直到該回合結束。當回合不再有進展時,OAR 會察覺,把它放回佇列,或以一則註記結束它,而不會讓它一直空轉。
導正執行中的回合以及 Stop(停止)按鈕,說明在回合執行期間。重新啟動的說明在重新啟動與繼續。
回合的狀態 #
| 狀態 | 你會看到什麼 |
|---|---|
| 排隊中 | 你的訊息出現在對話紀錄中,下方有 Cancel(取消)按鈕。 |
| 執行中 | agent 工作時,回覆泡泡會逐漸填滿,並顯示它的工具活動和 Stop 按鈕。對話在清單中顯示為忙碌。 |
| 等待提問回答 | 提問卡片顯示 Waiting for your answer(等待你的回答)。你回答之後,回合會繼續。 |
| 已完成 | 回覆完整。 |
| 失敗 | 回覆是一則簡短的系統註記,說明發生了什麼。見回合失敗時。 |
| 已停止 | 你按了 Stop。 |
在提問卡片上等待的回合,絕不會被視為卡住。卡片本身見 ask_user。
回合執行期間傳送 #
回合期間傳送按鈕上顯示的文字,會告訴你訊息會發生什麼事:
- Steer(導正):訊息會進入執行中的回合。這在 Claude、DeepSeek 和 Copilot 的 SDK 引擎上可用。
- Queue(加入佇列):訊息在該回合後面等待,並作為下一個回合開始。在其他所有供應商上,按鈕都顯示 Queue;在 Claude、DeepSeek 和 SDK 引擎上,當回合在等待提問卡片或計畫核准,或正在壓縮時,以及在 SDK 引擎上有工具呼叫正在執行時,也會顯示 Queue。這些情況下,訊息會以排隊訊息的形式等待,並在卡片得到回答、壓縮結束或工具呼叫完成之後進入該回合。
排入佇列的訊息依傳送順序執行,最舊的先執行。
如果你按下傳送時裝置處於離線狀態,瀏覽器會保留訊息,並顯示 You are offline. Message queued — it will send when the connection returns. 那是另一個佇列:它在你的裝置上,連線恢復時會自動清空。
取消一則排隊中的訊息 #
排隊中的訊息在 agent 接手之前都有 Cancel 按鈕。按下它會把訊息從佇列中移除,並顯示 Queued message cancelled. 如果 agent 在這段期間已經開始處理該訊息,中繼會顯示 Message is already being processed. Use Stop on the thinking bubble instead.
Empty queue(清空佇列) #
對話的 ⋯ 選單中有一行 Queue。它顯示的是整個中繼的計數,而不是這個對話的:
pending=1, processing=1, parked=0
Pending(待處理)的訊息在等待輪到它們。Processing(處理中)的訊息正在執行。Parked(已擱置)的訊息被暫緩,例如在中繼重新啟動期間。
它旁邊的 🚮 Empty queue 會把它們全部捨棄,涵蓋每一個對話,包括此刻正在執行的回合的訊息。執行前會先要求確認:
Drop all queue rows in pending, processing, and parked states?
This is a local maintenance action and cannot be undone.
之後會有一則通知顯示 Queue emptied: dropped 3 rows.(佇列已清空:捨棄 3 列。),沒有東西可捨棄時則顯示 Queue is already empty.(佇列已經是空的。)。0.9.11 新增 任何已登入的瀏覽器都可以使用它:只需要存取 token,其他都不需要(見只有中繼所在機器能使用的端點)。如果中繼拒絕,Failed to empty queue(清空佇列失敗)會指出原因。這個動作只會把訊息從佇列中移除,不會叫執行中的 agent 停止;要停止請用 Stop。若只想移除一則訊息,請改用該訊息上的 Cancel。
重新排入佇列 #
出錯的回合不一定就此遺失。在下列情況,中繼會把它放回佇列並再試一次:
- 回合卡住了(見下文),
- 回合執行期間,session 的 worker 處理程序終止了,
- worker 回報了值得再試一次的失敗。
每次重新排入佇列都算一次嘗試。每則訊息的上限是 5 次嘗試(設定檔中的 max,在啟動時讀取),所以第五次失敗就是最終的失敗。下一次嘗試之前的等待時間取決於原因:
| 原因 | 等待時間 |
|---|---|
| 回合卡住 | 30 秒(中繼判定它的 agent 連線離線時為 2 秒) |
| session 的 worker 處理程序終止 | 2 秒 |
| worker 回報失敗 | 第一、二、三、四次失敗後,分別為 1、2、4、8 分鐘 |
| worker 在開始後 15 秒內、出現任何活動或回覆文字之前回報失敗 | 10、20、40、80 秒 |
達到上限時,訊息就會永久失敗,並附上一則註記(見下文)。
有兩種回合不會重播。已經併入執行中回合的訊息若重播會被回答兩次,所以它會改為以一則註記失敗。背景任務自己的接續回覆沒有可以再次傳送的提示,所以會被捨棄。
回合卡住時 #
回合可能只是慢,也可能是卡住了。OAR 無法從答案看出是哪一種,所以它會留意生命跡象。監看共有三種:中繼監看 worker,每個 worker 監看它的 agent,另外有兩個上限約束背景工作和提問卡片。
| 計時器 | 預設值 | 在哪裡變更 | 觸發時你會看到什麼 |
|---|---|---|---|
| 無活動:session 的 worker 沒有任何生命跡象 | 10 分鐘(中繼判定它的 agent 連線離線時為 45 秒) | 設定檔中的 processing,單位為毫秒;編輯後請重新啟動中繼 |
回合回到佇列,30 秒後再次開始。 |
| Max turn duration(回合最長時間):單一回合的總時間 | 60 分鐘,可設 0 到 10 小時,以 5 分鐘為單位;0 表示沒有上限 | Settings → General → Max turn duration(設定 → 一般 → 回合最長時間) | 相同:回到佇列。在 Grok 上,回合則會改為以一則註記失敗。 |
| Copilot(SDK 引擎)、Cursor 或 Grok 的 runtime 沉默:沒有任何進行中的工作 | 120 秒 | 中繼環境中的 OAR_;0 會關閉這項監看 |
回合以一則系統註記失敗。 |
| 同上,但有模型請求正在執行 | 300 秒 | OAR_;0 表示沒有上限 |
回合以一則系統註記失敗。 |
| 同上,但有工具呼叫正在執行 | 30 分鐘 | OAR_;0 表示沒有上限 |
回合以一則系統註記失敗。 |
| Background task timeout(背景任務逾時):回覆之後,只剩背景工作讓 session 持續執行 | 4 小時,可設 0 到 10 小時,以 5 分鐘為單位;0 表示沒有上限 | Settings → General → Background task timeout(設定 → 一般 → 背景任務逾時) | 中繼會停止這些任務。在 Claude Cloud 上則是結束回合。見依供應商。 |
| 提問卡片等待 | 8 小時;Copilot 擴充功能引擎上為 2 小時 | 無法調整 | agent 會被告知沒有人回答,並依對話的模式繼續。 |
Linux 和 macOS 上的三個 OAR_ 變數
在以 tmux 執行 session 的地方,為中繼設定的變數不會傳給 agent 的處理程序,這三個變數因此可能沒有作用。見哪些變數會傳到 agent。
它們如何搭配運作:
- 中繼監看 worker。 worker 每 10 秒回報一次它正在處理哪則訊息。只要它持續回報,回合就是活著的,不論執行多久。如果回報停止的時間達到閒置時間窗,中繼會把回合放回佇列。它每 15 秒檢查一次。
- Max turn duration 是硬性的停止點。 它能抓到卡住卻仍持續回報的 worker。當兩個時間點中較晚的那一個距今已超過設定值時,回合就超過上限:回合開始的時間,以及你最後回答提問卡片的時間。所以,一場為了等你回答而等了好幾個小時的訪談,不會在最後一個回答之後立刻被切斷。這裡有一個陷阱。當這項檢查把任何回合重新排入佇列時,它會把每個開始時間距今已超過上限的執行中回合都重新排入佇列,而且不會考慮你對這些回合的回答。因此,你最近才在其中回答過卡片的回合,可能會和另一個在同一次檢查(每 15 秒一次)中達到上限的回合一起回到佇列。如果某個長回合沒有明顯原因就被重新排入佇列,請調高這個設定,或把它設為 0。
- 每個 worker 也會監看它的 agent。 對於 Copilot 的 SDK 引擎、Cursor 和 Grok,回合如果有超過其時間窗的時間完全沒有收到 runtime 的任何事件,就會失敗。時間窗取決於 runtime 正在做什麼:不輸出任何內容的指令可能會安靜很久,正在撰寫內容的模型則不會。這就是三個時間窗不同的原因。只設定閒置時間窗時,另外兩個會隨它等比例調整。
- 等待中的回合絕不算卡住。 在提問卡片上等待的回合,會讓中繼的兩道防線以及 worker 的靜默監看都停止計時。(Grok 的上限和擴充功能引擎的 2 小時上限不會因此暫停。)壓縮和
relay_呼叫也會讓靜默監看暫停。Max turn duration 不知道tool relay_的長時間等待,所以在預設的 60 分鐘下,接近其最長時間的等待可能會被它截斷。tool - 背景任務是分開計算的。 任務逾時只在回覆之後、只剩背景任務讓 session 持續時才開始計時。它不會限制回合。Claude Cloud 是例外,見下文。
重新排入佇列不會顯示為錯誤。訊息會回到 queued(排隊中)並再次執行。只有在嘗試次數用完時,回合才會失敗。
回合失敗時 #
失敗的回合會以一則來自中繼的純文字回覆結束。它會說明發生了什麼、以錯誤碼結尾,並告訴你接下來該怎麼做。例如,被靜默監看結束的回合會寫著:
System note: the Copilot runtime sent nothing for 300s while a model request was running, so the relay ended the turn.
當正在執行的是工具時,註記會寫出它的名稱:while a tool was running (build)。在中繼詢問時已不再回應的 runtime,會寫著 the Copilot runtime stopped answering … (nothing for 120s, no reply when asked), so the relay ended the turn.
用完嘗試次數的訊息,會以下列其中一則失敗:
Relay timeout after 5 attempts. Message was skipped to keep the queue moving. Retry the message.
Relay recovery limit reached after 5 attempts (stale-recovery). The worker kept dying before completing this turn, so the message was failed to keep the queue moving. Send it again to retry.
大多數失敗的最後都會建議你再次傳送訊息。有兩件事能幫上忙:
- 再次傳送。 貼上或重新輸入訊息,或在對話紀錄提供時按下 Resend(重新傳送)。Resend 會出現在導正進某個回合、而該回合隨後失敗或被停止的訊息上。它的標記會寫著 Steered into the turn above, which failed — not answered. 或 Stopped with the turn — not answered. 按下之後,按鈕在每個裝置上都會顯示 Resent(已重新傳送)。
- 使用回覆上的按鈕。 有些失敗會指出中繼可以替你執行的修正,失敗的回覆上就會帶有對應的按鈕。Claude 帳戶問題會顯示 Claude settings(Claude 設定)。0.9.17 新增 因餘額用完而被拒絕的 DeepSeek 回合會顯示 Top up DeepSeek(儲值 DeepSeek)和 DeepSeek settings(DeepSeek 設定);因 API 金鑰而被拒絕的則顯示 DeepSeek settings(見 DeepSeek 錯誤碼)。無法開始的 Grok 回合會顯示 Install Grok CLI(安裝 Grok CLI)和 Grok settings(Grok 設定),未登入時則顯示 Sign in to Grok(登入 Grok)和 Grok settings。
session worker 因啟動問題而停止的對話,會在註記上顯示 Retry(重試)按鈕,按下會再次啟動 worker。
看起來卡死的對話,可以用 ⋯ 選單中的 ☠️ Kill session(強制結束 session)解開,它會停止對話的 worker。之後再次傳送訊息。
依供應商 #
佇列、Cancel、Empty queue、閒置時間窗和 Max turn duration 在每個供應商上都相同。不同的是對 agent 本身的監看。
| 供應商 | 靜默監看 | Steer 或 Queue |
|---|---|---|
| GitHub Copilot 和 OpenAI,SDK 引擎 | 有:120 秒、300 秒和 30 分鐘。每個閒置時間窗內,worker 會詢問 runtime 一次是否還在,並給它 5 秒回答;沒有回答的 runtime 會讓回合立即結束。 | Steer |
| GitHub Copilot,擴充功能引擎 | 沒有靜默監看。回合總共以 2 小時為限;時間用完時,回合會回到佇列並算作一次失敗的嘗試,等待時間如上所述。在預設的 60 分鐘下,通常是 Max turn duration 先起作用。提問卡片會等待 2 小時。 | Queue |
| Claude | 只觀察。CLI 已 10 分鐘(有工具開啟時為 30 分鐘)沒有任何輸出的回合,會寫入 worker 的記錄並讓它繼續執行,因為結束它會終止 CLI 及其背景任務。 | Steer |
| DeepSeek 0.9.17 新增 | 與 Claude 相同:DeepSeek 對話執行的是 Claude Code,採用相同的只觀察監看。 | Steer |
| Claude Cloud | agent 上沒有靜默監看。worker 監看的是它的連線:120 秒沒有資料的串流會重新開啟,而中斷達 5 分鐘的串流會把訊息交回佇列,下一次嘗試會接著追蹤同一個回合,而不是再次傳送它。連線仍存活、只是安靜下來的雲端回合會繼續執行。當 agent 在背景工作仍在執行時結束回合,回合會在 Background task timeout 的期間內保持開啟(若該值為 0 則為 60 分鐘)。之後它會以一行活動結束,告訴你傳送一則訊息來查看工作的結果。 | Queue |
| Cursor | 有,使用相同的三個時間窗。執行期間沒有閒置階段:除非有工具呼叫開啟,否則都算作模型請求。 | Queue |
| Grok | 有,使用相同的三個時間窗;若有尚未完成的 relay_ 呼叫,會先查詢它的狀況。在這裡,OAR_ 設為 0 不會關閉它。回合也以 Max turn duration 為上限,從回合開始時計算,不會因回答提問而重新計時,而你未回答的卡片也會計入。達到上限的 Grok 回合會以 System note: the Grok turn stalled and was stopped (grok turn exceeded the 60-minute turn ceiling). Send a new message to retry.(系統提示:Grok 回合停滯並已停止——grok turn exceeded the 60-minute turn ceiling。傳送新訊息即可重試。)失敗(或是你設定的分鐘數)。 |
Queue |
Background task timeout 適用於 Claude、Claude API、DeepSeek、Copilot 的 SDK 引擎和 Claude Cloud。在 Claude、Claude API 和 DeepSeek 上,它會停止背景任務。在 Copilot 的 SDK 引擎上,中繼會取消它們。在 Claude Cloud 上,它只決定回合等待它們多久。它不適用於其他供應商。