歡迎回到城堡的大書房,各位尊貴的城堡主人!
在前面幾堂課中,我們學會了如何讓大副開啟 /goal 自動導航,也掌握了透過 /grill-me 進行精準需求對齊。然而,在日常營運與高效率的工作流程中,我們必然會萌生一個更具野心的渴望:
「城堡主人總不能每天半夜三點特地爬起來打開終端機,命令大副去抓取最新新聞、或是每隔一小時手動叫它去檢查伺服器有沒有崩潰吧?能不能讓大副像一個忠誠的頂級私人管家一樣,在主人休息時自動按照時間表工作,完成後再發出優雅的提示音提醒主人呢?」
答案是:完全可以!這就是 agy 核心架構中的定時自動化魔法——Schedule(一次性倒數鬧鐘)與 Cron(週期性星象巡邏表)!
為了讓城堡主人們完美理解定時任務的設計,我們引入兩個極具質感的概念比喻:
私人管家的隨身懷錶與城堡巡邏日誌:
《哈利波特》的自動羽毛筆與霍格華茲定時防護魔法陣:
在 agy 中,Schedule 工具專為「長度非同步任務」與「延遲提醒」而設計。當你命令大副去執行一個非常耗時的大型任務(如訓練機器學習模型、爬取數萬筆網頁數據)時,你不需要坐在螢幕前死死等待。
Schedule 的核心運作機制與條件終止選項(TimerCondition):
* 無條件時間到達(never,預設模式):
* 語法與行為:指定倒數秒數(例如 DurationSeconds = 600,即 10 分鐘)。鬧鐘會無條件在 10 分鐘後響起並觸發的高優先級(High-Priority)通知訊息:「城堡主人!10 分鐘已到,請審閱背景報告!」
* 任一訊息喚醒(any 模式):
* 適用場景:當你在背景同時跑了多個子代理人(Subagents),你想設定一個 5 分鐘的保險鬧鐘,但只要「任何一個子代理人」中途傳回訊息,鬧鐘就會自動提前取消,避免發出重複的干擾通知。
* 指定發送者喚醒(<sender-id> 模式):
* 適用場景:你正在等待背景任務 task-456 完成,你設定了一個 10 分鐘鬧鐘。如果 task-456 在第 3 分鐘就傳來任務完成的訊號,鬧鐘感應到來自 task-456 的訊息,便會自動宣告終止,展現出高度聰慧的管家邏輯。
當任務需要重複、定時地執行時,Cron Expression 就是管家守護城堡的靈魂密碼。
Cron 採用標準的 5 欄位時間表達式(從左至右依次為:分鐘、小時、日期、月份、星期):
* 第 1 欄位:分鐘 (Minute) ➔ 範圍 0 - 59
* 第 2 欄位:小時 (Hour) ➔ 範圍 0 - 23
* 第 3 欄位:日期 (Day of Month) ➔ 範圍 1 - 31
* 第 4 欄位:月份 (Month) ➔ 范围 1 - 12
* 第 5 欄位:星期 (Day of Week) ➔ 範圍 0 - 6(0 代表星期日,1-6 代表週一至週六)
語法中的特殊符號解析:
* 星號 (*):代表「每一個單位」(例如在小時欄位寫 * 代表每小時)。
* 斜線 (/):代表「每隔多少步長」(例如 */5 在分鐘欄位代表每隔 5 分鐘)。
* 逗號 (,):代表「列舉多個指定時間」(例如 1,15 代表第 1 與第 15 分鐘)。
* 連字號 (-):代表「時間範圍區間」(例如 1-5 在星期欄位代表週一至週五)。
城堡主人必備的經典 Cron 語法密碼清單:
* */5 * * * * ➔ 每 5 分鐘執行一次城堡巡邏。
* 0 * * * * ➔ 每小時整點執行一次健康檢查。
* 0 9 * * * ➔ 每天早上 9 點整準時發送晨間新聞摘要。
* 0 0 * * 1 ➔ 每週一凌晨 0 點整自動進行資料庫異地備份。
* 30 18 * * 1-5 ➔ 每週一至週五下午 6 點 30 分自動產出工作日報。
/tasks 與 manage_task 工具操控背景任務定時自動化任務一旦啟動,會在 agy 的背景程序(Background Worker)中非同步運作,絕對不會卡住你目前的終端機對話!你可以隨時對背景任務進行監控與干預:
/tasks):/tasks,終端機會立刻印出所有正在背景運作的 Schedule 鬧鐘與 Cron 巡邏任務清單,包含任務 ID、觸發時間與 Prompt 指令。manage_task 進行深度操控:list ➔ 列出所有活動中的背景任務細節。status ➔ 查看指定 TaskId 的最新執行日誌檔(Log URI)與當前狀態。kill ➔ 手動腰斬並撤銷指定 TaskId 的定時任務(例如當你不再需要每小時監控網站時)。send_input ➔ 向正在背景運行的互動式任務傳送標準輸入(stdin)。我們來看一個真正的自動化管家實戰語境:
0 9 * * 1-5。每天早上 9 點檢查 https://api.my-service.com/health。如果 HTTP 響應碼不是 200,立刻發送警告通知通知我!」agy 自動呼叫 schedule 工具,將該任務掛載至背景系統。每到工作日早上 9 點,大副會在背景發動 read_url_content 檢查 API,完全無需手動介入!agy 會透過系統 Event Loop 發送一則非破壞性的背景通知。有了定時自動化,你的 agy 大副不再只是一個被動等待回應的命令列工具,而是一個 24 小時為你守候、自動執行的頂級數位城堡管家!
在下一堂課中,我們將探討一個更具科幻色彩的主題:如果管家在自動工作時不小心改壞了程式碼,我們該如何像《命運石之門》一樣讓時空倒流?
下一堂課,我們將解鎖平行宇宙與時空傳送門——/rewind 與 /fork 的時空魔法!
👉 下一堂課:Lecture 09 平行宇宙與時空傳送門:利用 /rewind 歷史倒退與 /fork 分離工作區 👉 回課程大綱:學習地圖
以下題目專為尋求真正硬核觀念與專家級實戰能力的學員設計。題目無法從講義表面抄寫解答,請嘗試獨立思考後再點擊展開解析。
【實戰情境問題】:在 Vercel Serverless Function 中執行 Cron 定時任務時(如我們的 `/api/daily-digest`),為什麼函數內部不能使用全域變數 `let lastRunTime` 來記錄上次執行時間?
【鑑別點說明】:測試學員是否明白 Serverless 函數的生命週期(Cold Start / Ephemeral Execution)與狀態持久化。
【專家級解答與深度剖析】: Serverless 函數在觸發時會動態啟動一個微型容器(Cold Start),執行完畢後數秒內就會被容器銷毀(Teardown)。每次 Cron 觸發的可能都是完全不同的虛擬實例,儲存於記憶體中的全域變數會隨容器銷毀而歸零。定時任務的所有狀態(如「上次成功發送時間」)必須被物理性地持久化儲存於外部資料庫(如我們的 Cloud DB)或 Redis 快取中。
【實戰情境問題】:如果 Vercel Cron 因為雲端網路波動,在同一分鐘內連續對 `/api/daily-digest` 觸發了 2 次 HTTP 請求,如何確保學員信箱不會收到 2 封重複的日報郵件?
【鑑別點說明】:考驗學員在分散式自動化任務中設計「冪等性 (Idempotency Key)」的防禦能力。
【專家級解答與深度剖析】: 必須實施基於日期的冪等鎖(Idempotency Lock)。在執行發信前,函數先向 Cloud DB 查詢:`lock_daily_digest_2026_07_29` 是否存在。若不存在,立刻建立該原子鎖(Atomic Lock)並執行發信;若第二個重複請求進來,發現該日期的鎖已存在,則直接回傳 HTTP 200 成功並跳過發信步驟。