iT邦幫忙

0

VS Code 會定時叫醒 Agent,但不會替你的任務保證冪等

  • 分享至 

  • xImage
  •  

每天早上九點,IDE 裡的 Agent 會掃描尚未分類的 GitHub issues,自動貼標籤並留下摘要。某天開發者只看到一半結果,以為排程卡住,便手動再跑一次。

兩個 run 讀到同一批 issues,也都準備寫回 GitHub。系統若沒有穩定的執行身分,就分不出哪一個有資格貼標籤。第一個可能已經留言,只是還沒來得及把完成狀態寫回本機;第二個此時重做,就會留下重複內容。

準時叫醒 Agent,跟副作用只發生一次,是兩個不同的工程問題。

VS Code 處理 trigger,任務語意仍要自己定義

VS Code 1.137 加入 Preview 階段的 Automations,可以手動執行,也能設定 hourly、daily 或 weekly 排程。官方列出的情境包括追上近期變更、整理 issues 與尋找 bugs;功能透過 chat.automations.enabled 啟用,並採逐步 rollout。

這個入口降低了 recurring agent task 的啟動成本,但排程只能決定「何時嘗試執行」。同一天手動補跑、逾時後重試,或 IDE 開了兩個視窗時,同一個工作仍可能出現不只一次。

VS Code 公開的 Automations 基礎實作紀錄也反映了排程器本身的麻煩:persistent run ledger、跨視窗 leader election、stale run recovery、逾期補跑與 per-run timeout 都在處理範圍內。這些是內部實作方向,不是穩定的 public API。儲存一條排程規則確實只是起點。

Scheduler 的協調機制無法替使用者任務決定 business semantics。排程器可以避免兩個視窗同時派工,卻不知道 GitHub 留言是否已成功送出,也不知道部署完成後回寫狀態失敗時,下一次重跑會不會再部署一次。

最危險的是寫入成功、狀態失敗

假設 Agent 的流程有三步:讀取待分類 issues、寫回標籤與留言、保存本次執行結果。

如果第二步已在 GitHub 成功,第三步卻因 IDE 關閉而失敗,run ledger 最多只能顯示這次工作沒有正常收尾。下一次 catch-up 或人工補跑若只看「未完成」,就會再次留言。

對外部系統而言,第一次其實成功了一半;對本機排程器而言,它看起來像失敗。這段落差不能靠對話摘要補救,因為「Agent 說它做完了」不是可查驗的狀態。

我的做法是先替每次執行建立穩定身分,再允許 Agent 動手:

  • job_key 表示工作種類,例如 daily-issue-triage
  • window_key 表示這次排程時間窗,例如 2026-09-16,不要使用每次都不同的啟動時間。
  • dedupe_key 由工作、時間窗與必要的輸入版本組成。自動觸發和手動補跑只要處理同一批工作,就必須得到同一個 key。
  • input_snapshot 固定 base commit、查詢截止時間、來源與觀察時間。重跑不能悄悄換一批輸入,否則去重結果也失去意義。

一份最小的 recurring-agent run contract

下面這份 YAML 是 team-owned contract,不是 VS Code 官方 schema。欄位可以依系統調整,但每個 run 都應留下同等資訊。

job_key: genui-resource-watch
window_key: "2026-09-16"
dedupe_key: "genui-resource-watch:2026-09-16:sources-v3"

input_snapshot:
  source_set: "genui-allowlist-v3"
  query_cutoff: "2026-09-16T00:00:00+08:00"
  observed_at: "2026-09-16T05:00:00+08:00"

lease_owner: "vscode-window-a"
lease_until: "2026-09-16T05:20:00+08:00"

write_scope:
  - "reports/2026-09-16.md"

side_effect_policy:
  remote_write: denied
  overwrite_same_artifact: allowed

result_artifact: "reports/2026-09-16.md"
status: running

lease_ownerlease_until 用來回答「現在誰有權執行」。lease 尚未到期時,第二個 worker 應直接停下;lease 過期也不能立刻假設前一個 run 什麼都沒做,仍要檢查 artifact 與外部狀態。

write_scope 則把損害半徑壓到可檢查的路徑。像每日報告這類工作,只允許覆寫同一天的固定檔案,比每次重跑都產生一份新報告更容易判斷結果。

狀態也不要只分成功和失敗。至少要能表達:

  • completed:寫入完成,而且結果可讀回驗證。
  • no-change:輸入已檢查,本次沒有需要更新的內容。
  • failed-before-write:尚未產生副作用,可以安全重試。
  • failed-after-write:至少一個寫入已發生,但後續狀態不完整。
  • needs-review:系統無法自動確認外部狀態,需要人判斷。

最後兩種不能合併成普通的 failed。一旦無法證明外部寫入是否成功,自動 retry 只是在賭同一個動作重做不會出事。

Retry 之前,先決定這次重跑是哪一種

同一個 dedupe_key 再次出現時,我會依序檢查幾件事。若已有 completedno-change,直接覆用 result_artifact;若有效 lease 仍在,拒絕第二個 worker;若前次是 failed-before-write,才允許接手重試。

碰到 failed-after-write,策略要看副作用種類。支援 idempotency key 的 provider 應沿用同一個 key;能 read-back 的操作先查外部結果;留言、貼標籤、開 PR 或 deploy 若無法確認,就轉成 needs-review,不要讓 Agent 自行再做一次。

跨 IDE、本機檔案與外部 API 時,承諾 exactly-once execution 通常不切實際。這份 contract 應做到的是辨識重複執行、查驗副作用,並在狀態不明時停住。

先用唯讀任務驗證這份 contract

genui-resource-watch 很適合當第一個實驗。它每天讀取固定 allowlist,比較 Generative UI 的論文、SDK 與開源專案訊號,最後只寫入 reports/YYYY-MM-DD.md。來源清單可以包含人工整理、多語系的 生成式 UI 資源 作為探索入口,但報告中的每一筆資料仍要保存實際原始 URL 與 observed_at,不能把目錄頁當成來源證明。

同一日期手動補跑時,系統沿用原本的 window_keyresult_artifact。輸入快照相同就覆用結果;若有人刻意更新來源版本,則在同一份 artifact 留下 diff 與新 snapshot,不新增第二份看似獨立的成功報告。整個流程不自動發文,也不修改遠端資料。

這種唯讀、小範圍工作能先驗證 dedupe、lease、狀態轉換與 artifact 規則。等團隊確定重跑真的可控,再逐步開放 issue 標籤、PR 或 deploy,不需要一開始就把高風險副作用交給排程 Agent。

排程成功,不等於任務可靠

VS Code Automations 降低了 Agent 定時工作的門檻,也讓團隊更容易跳過執行契約,直接把一段 prompt 當成 production job。

判斷 recurring agent job 是否成熟,可以做一個很笨但有效的測試:同一個 window 再跑一次。系統如果能明確拒絕、續跑、覆用既有 artifact,或停在人工檢查,而不是重新做一遍,那份自動化才有資格長期開著。

資料來源


圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言