第十八節 子任務與背景執行
[!ref]
詳解見使用者手冊「子任務與背景執行」節。
18.1 派發參數
| 參數 |
類型 |
預設 |
說明 |
prompt |
string |
— |
子任務提示詞;必填 |
agent_id |
string |
當前助手 |
指派子助手人設 |
model |
string |
當前模型 |
子任務模型 |
run_in_background |
bool |
false |
true 走背景 |
timeout_ms |
int |
600_000 |
前景超時;背景不適用 |
18.2 BackgroundRegistry
| 欄位 |
預設 |
說明 |
| 同時在跑上限 |
64 |
超出立即拒絕並提示稍後重試 |
| 終態保留 |
30 分鐘 |
超過視窗被回收 |
| 優先級 |
killed > done |
外部 stop 與自然結束撞拍時 killed 勝 |
18.3 子任務工具
| 工具 |
參數 |
說明 |
Agent |
prompt, agent_id, run_in_background? |
派發單個子任務 |
AgentParallel |
legs[](2–16), timeout_seconds? |
一次拆多路並行 fan-out(見 §18.3.1) |
TaskOutput |
task_id, limit? |
拉取背景任務狀態 / 輸出片段 |
TaskStop |
task_id |
強制終止背景任務 |
StopAgentToolRun |
child_session_id |
單獨停止某個正在跑的子代理(背景 / 並行腿 / 同步內聯均支持);冪等。可選保留已產生的子任務記錄 |
TaskWait |
task_ids, mode=all|any, timeout_seconds(預設 300,最長 1800) |
阻塞等待背景任務 / 子代理;超時傳回「還在跑」讓模型決定繼續。結果附帶 other_tasks(同會話未被本次等待覆蓋的背景任務);執行中任務帶 elapsed_ms |
EnterPlanMode / ExitPlanMode |
無 |
進入 / 結束籌劃 |
TodoWrite |
todos |
寫入或更新待辦清單 |
18.3.1 AgentParallel 參數
| 參數 |
類型 |
預設 |
說明 |
legs |
array |
— |
必填,2–16 條;每條獨立 fresh-context 子 Agent,全部完成後聚合傳回 |
legs[].subagent_type |
string |
— |
必填,目標子代理類型 |
legs[].prompt |
string |
— |
必填,自包含子任務提示詞(腿看不到主對話歷史) |
legs[].description |
string |
— |
可選,3–5 詞,僅用於記錄檔 / UI |
legs[].model |
string |
繼承 |
可選,單腿模型覆蓋 |
timeout_seconds |
int |
600 |
整體等待超時,上限 1800;到時未完成的腿傳回 pending 並在背景繼續 |
少於 2 條會報錯(改用 Agent),多於 16 條靜默截斷到前 16。每條腿作為真實背景任務派發、內部統一 Wait(all) 聚合;單腿輸出超 8000 runes 截斷(提示用 TaskOutput 取全文)。腿為葉子層、不可再嵌套 Agent / AgentParallel。v1 僅 all 模式。傳回 ParallelResult(completed / num_ok / num_failed / num_pending / legs[] 等,永不拋錯)。
渲染:呼叫卡片執行期即顯示並隨實時 store 反映各腿執行狀態(停止後不再轉圈);極簡密度下結果塊不被工具組誤折疊。
18.3.2 子代理終態
| 狀態 |
含義 |
執行中 running |
在跑 |
已暫停 paused |
使用者暫停,可繼續 |
完成 completed |
正常跑完 |
已結束 ended |
盤上無明確終態(匯入會話 / 重載回灌)。此前此類記錄謊報為「完成」 |
失敗 failed / 已終止 killed / 被拒絕 denied |
按盤上 sidecar 終態回灌 |
- 被
TaskStop 終止的任務不顯示成功標記;MarkKilled 當場結算 DurationMS,不記為 0。
- 子代理只在使用者顯式 Stop 時終止:respawn、新訊息等內部動作不再級聯 kill。
18.3.3 子代理抽屜動作
| 動作 |
說明 |
| 停止 / 暫停 / 繼續 |
「繼續」可帶「補充指令」;從已儲存的執行歷史續跑 |
| 重試 |
截斷到最後一條使用者訊息後重新執行 |
| 再跑一次 |
用相同 type + prompt 重新發起(prompt 缺失時停用) |
| 編輯訊息 / 刪除訊息 |
執行中拒絕編輯;編輯走側掛編輯器 + 增量更新 |
| 刪除工具呼叫 |
連帶刪除配對的工具結果;無 id 的匯入舊記錄不可單獨刪除 |
| 從此處重試 |
此訊息起重新生成(使用者訊息保留提問重答;助手 / 工具訊息重做該步) |
| 從此處繼續 |
保留到此訊息為止,其後丟棄,回到該時間點續跑;「補充指令」一並帶入 |
| 複製 / 複製選中的部分 |
— |
| 複製 JSONL 路徑 / 複製 TaskWait 參數 |
後者給出 task_ids + timeout 的 JSON;TaskOutput / TaskStop 用同一 id |
訊息柄選單標頭顯示該訊息的絕對 + 相對時間;刪除 / 重試 / 繼續均有行內二次確認。
18.3.4 TaskWait 呼叫行呈現
| 項 |
行為 |
| 預期等待時間 |
呼叫行顯示 ≤ timeout_seconds 的預算 |
| 總體倒數計時 |
在途且確有背景任務在跑時才啟動;倒數到 0 回落為灰色靜態預算,不停駐 0ms |
| 完成態圖示 |
條頭圖示換為打鉤時鐘 |
| 緊湊模式 |
配合子任務狀態馬賽克(一格一任務、按狀態着色) |
| 最終回復 |
終態下展示「給主代理的最終回復」 |
18.4 長程任務當機復原
背景任務(run_in_background=true)的進度落盤到本機全域目錄(每任務一份 JSON 快照);走到終態(done / error / killed)即刪除快照。
| 項 |
預設 |
說明 |
| 落盤範圍 |
僅背景任務 |
前景同步任務不落盤 |
| 啟動掃描 |
非同步、不阻塞 |
先做髒條目清理(父會話已刪的條目自動剔除),再列出殘留任務 |
| 自動復原開關 |
關(auto_resume_tasks) |
設定 → 智慧體 → 自省;啟用後啟動自動續跑(夜間無人值守) |
| 啟動自動復原上限 |
5 |
防「續跑訊息風暴」;其餘轉手動橫幅 |
| 復原方式 |
注入父會話續跑 |
不直接重新啟動子程序,而是向原父會話注入「繼續 / 重新委派」訊息(對使用者可見) |
| 手動入口 |
頂部復原橫幅 |
每條可「復原 / 忽略」,另有「全部忽略」 |
18.5 自修正循環參考
錯誤按來源(request / gateway / upstream)與類別分流後映射到 4 類修正政策,各有按會話計的嘗試上限:
| 修正政策 |
適用錯誤 |
上限 |
transient_compact(壓縮重試) |
上下文超限 |
2 |
transient_fallback(切換服務提供方,需確認) |
無可用通道 / 上游過載 / 上游認證失敗 |
3 |
backoff(退避重試) |
限流 / 超時 / 網路 |
3 |
terminal(交還使用者) |
餘額不足 / 需重登 / 模型不存在 |
— |
特例:upstream 來源的 auth_error 重判為 transient_fallback(某通道 key 失效而非使用者憑證);仍可重試的 terminal 救回為 backoff;5xx / 408 預設可重試,其它 4xx 終止。
- 網路抖動自愈:瞬斷 / 臨時離線時探測「離線 → 線上」再續跑,這段等待不計入重試預算;連線重設、DNS 暫時解析失敗、交握中斷等連線級瞬斷細分為網路問題(而非籠統
llm_error)。
- 產出型自愈(
MaxOutcomeHeal = 3,連續計數、乾淨收尾清零):回復被長度截斷自動續寫(truncated_continue)、推理繞圈打斷(reasoning_loop)、內容過濾換述(content_filter)、回覆停在半句(cut_mid_sentence)、說了下一步卻沒動手(announced_no_action)。後兩者只在 finish=stop 的輪次終點判,核對回合與自報暫停的回合不判;先判半句、再判宣告(看最後一句);以提問、交還使用者、客套語、清單 / 表格 / 標題收尾均判為正常。續跑訊息 source=auto_self_heal 不可見;撞頂 toast「自動修復已放棄:{kind} 連續幾輪沒能糾正 —— 需要人工介入」。
- 門禁升級:同一處檢查 / 測試失敗或待辦無進展達上限(測試門禁 3 次、無進展待辦 2 次)時升級提示換思路。
- 服務提供方備選經
App.RespondProviderFallback 回寫確認,前端 SelfRepairFallbackBanner;後端事件 self_repair:fallback_confirm / _applied / _declined / self_repair:outcome。
18.6 經驗學習閉環參考
| 組成 |
說明 |
| 自愈歷史學習(P1) |
每類自愈成敗落盤 ~/.config/avlcode/self-heal-stats.json;平滑率 (succ+1)/(total+2)。樣本 < 5 用預設上限 3;率 < 0.2 → 1、0.2–0.5 → 2、≥ 0.5 → 3;每類至少 1,僅下調不上調 |
| 自動反省(P2/P3) |
auto_reflect(預設關,設定 → 智慧體 → 自省)啟用後,多步任務收尾非同步跑一次 GRAI+KISS 復盤;讀軌跡摘要(最多 5 個錯誤步)+ 自愈統計,產出 ≤ 8 條 Keep/Improve/Stop/Start 教訓 |
| 教訓去向 |
沉澱到記憶宮殿 _pending 草稿盒(房間 scratch、類型 decision、不衰減),需人工簽核後才入正式函式庫;按標題去重;事件 reflection:done |
18.7 會話內例行程序參考
與 設定 → 例行程序(工作區例行程序,§6.13)是兩套獨立資料:會話內例行程序由模型在會話中建立,到點送進建立它的會話。存於 ~/.config/avlcode/workspaces/<工作區 ID>/session-routines.yaml(不在專案目錄的 .avlcode/ 下),調度器每 5 秒掃一次已開啟的工作區。
| 工具 |
參數 |
說明 |
RoutineCreate |
name(≤ 40 字)、prompt(≤ 4000 字,須自包含)、schedule(必填 type + minutes / at / time / days)、when_idle(run / skip)、delivery(step_end 預設 / interrupt)、max_runs、expires_in_hours |
新增;停止之後才到達的呼叫被拒收 |
RoutineList |
無 |
本會話未結束(含暫停)的例行程序 + 最近結束記錄(每會話保留 10 條) |
RoutineCancel |
routine_id(rt_ 開頭)、reason(一行,展示給使用者) |
取消;已結束的傳回 cancelled=false |
schedule.type |
含義 |
限制 |
預設有效期 / 上限 |
預設次數 / 上限 |
after |
N 分鐘後一次 |
minutes 1–1440;when_idle 必填 |
— |
1 / 1 |
every |
每 N 分鐘 |
minutes 1–720;when_idle 必填 |
max(8, ⌈3×分鐘/60⌉) 小時,封頂 24 / 24 小時 |
30 / 200 |
at |
指定時間一次 |
YYYY-MM-DD HH:MM,須在將來、最遠 30 天 |
— |
1 / 1 |
hourly |
每小時 |
time 只取分鐘(HH:MM / :MM / MM) |
72 / 720 小時 |
72 / 720 |
daily / weekdays |
每天 / 工作日 |
time 為 HH:MM |
168 / 720 小時 |
不限 / 顯式給時 ≤ 1000 |
weekly |
每週 |
time + days(0=週日 … 6=週六,至少一天) |
168 / 720 小時 |
不限 / 顯式給時 ≤ 1000 |
| 項 |
取值 |
| 可用範圍 |
僅主會話;auto / execute 三個工具全有,plan / prepare / assess 僅 List / Cancel;子代理與 TUI 不可用;無全域開關,不受工具延遲載入影響(常駐) |
| 工具分組 |
routine.* = 全部三個;agent.* / agent.read.* 僅含 List / Cancel |
| 數量上限 |
每會話未結束 ≤ 5;每工作區未結束 ≤ 50;每會話 24 小時內新增 ≤ 10;每工作區每自然日送達 ≤ 300 次(超出:一次性的結束、重復類跳過) |
| 到點時會話在跑 |
按 delivery 插入當前循環;插不進去時每 15 秒重試、最多 10 分鐘,超時一次性的結束(delivery_failed)、重復類跳過 |
| 到點時會話空閒 |
when_idle=run 起一輪(用會話最近的工作模式與該會話的模型);skip 則一次性的結束(idle_skipped)、重復類跳過。會話忙(等簽核 / 換代 / 發送在途 / 測試門禁在跑)或剛停下不到 10 秒時 5 秒後再看 |
| 連續失敗 |
3 次自動暫停(例行程序起的一輪以錯誤收場也算);一次性的 60 秒後重試;正常收尾或「恢復」清零 |
| 錯過 |
不補發:重新進入調度範圍時超過 1 分鐘即算錯過(一次性的結束 missed,重復類從當前重算);暫停後恢復也不補發 |
| 停止 |
停止按鈕與 IM /stop 取消本會話全部(user_stopped);刪除會話連同記錄清除;歸檔會話以 session_archived 結束 |
| 訊息流 |
source=auto_routine,顯示為折疊行「⏰ 例行 · 名稱 · 3/30」;送達尾注(不是使用者新訊息、不代表新授權、完成後應 RoutineCancel)只給模型看;不進會話目錄 |
| IM |
例行程序起的一輪,回復轉發給綁定該會話的 IM 對端(抬頭「⏰ 例行「名稱」」);IM 側無管理命令 |
「例行」strip 動作:暫停 / 恢復、編輯(名稱、提示、計畫類型、分鐘 / 時間 / 星期、會話閒置時、會話在跑時、次數上限、有效期;0 = 預設)、刪除(無二次確認、不留結束記錄);「已結束」區列原因並可「知道了」。結束原因:已完成 / 已達次數上限 / 已到期 / 模型已取消 / 你按了停止 / 會話已刪除 / 會話已封存 / 錯過觸發時間 / 觸發時會話閒置,已略過 / 投遞失敗 / 工作區今日送達次數已用完。