長時間 AI 任務最讓人不安的,往往不是失敗本身,而是沉默。
人類這邊做完家事、買完東西、吃完飯再回來,AI 還顯示「工作中」。這時有兩種完全不同的可能:
- 它正在認真跑一個巨大的測試套件。
- 它幾個小時前就已經卡住了。
僅靠載入動畫無法區分兩者。長時間沒有 commit 也不能證明已停止,因為測試、調查、比較、生成或等待外部系統時,本來就可能暫時沒有新產物。
因此,長時間 AI 除了智慧,還需要可觀測性(observability)。
1. 結論――只要任務可能持續較長時間,就應該暴露「現在在哪裡」
長時間 Agent 不應只在最後回報。中間狀態也應能被人讀取。
不必每分鐘喊「我還活著」。真正需要的是能回答:
- 現在在做什麼
- 已完成什麼
- 還剩什麼
- 是否正在測試
- 是否被某件事阻塞
- 最近一次確認仍在運行是何時
- 最近一次真正有程式或產物變化是何時
一個實務設定例是:大約 10 分鐘沒有可見產物時更新 Heartbeat;超過 20 分鐘沒有 Heartbeat 時,不直接判定為「停止」,而標記為 STALE_UNKNOWN。
沉默首先代表「無法確認」,不是「已經失敗」。
2. 為什麼只看 commit 不夠
Git commit 很適合記錄實際變更,卻不適合單獨承擔存活確認。
一個持續一小時的回歸測試可能完全正常,卻沒有任何 commit。反過來,為了證明「還活著」每 10 分鐘提交無意義的 Heartbeat 檔,只會讓歷史紀錄變成垃圾場。
最好分開:
Heartbeat = 當前狀態
Material change = 程式、合約、產物或驗證結果真的改變的證據
分別記錄 lastHeartbeatAt 與 lastMaterialChangeAt,就能正確理解「30 分鐘沒 commit,但 5 分鐘前仍是 TESTING」。
目標不是更多 commit,而是讓沉默可以被解讀。
3. 至少要記錄哪些欄位?
長時間 run 建議記錄:
runIdstate:RUNNING / BLOCKED / COMPLETED / STALE_UNKNOWN 等phase:READING / IMPLEMENTING / TESTING / VERIFYING 等workingOnstartedAtlastHeartbeatAtlastMaterialChangeAtbranch / baseSha / headSha / PRcompletedMilestones / remainingMilestonesblockerstestsnextCheckpoint
有了這些,六小時任務就不再只是「六小時神祕黑箱」,而能被讀成:
IMPLEMENTING → TESTING → INTEGRATING → VERIFYING
再聰明的黑箱,仍然是黑箱。時間一長,人自然會焦慮。
4. 測試階段尤其需要 Heartbeat
長測試在外觀上和「AI 卡死」幾乎一模一樣。
開始長測試前可記錄:
phase = TESTING- 測試名稱
- 測試範圍
- 若總量固定,寫
84 / 127這種真實數字 - 目前是否出現 failure
不要隨便寫「完成 82%」這種氣氛型數字。設計與除錯剩下的 18% 到底是什麼,通常沒人知道。
比例只在分母客觀固定時有意義:
- 84 / 127 tests
- 3 / 5 acceptance gates
「實作完成 82%」就是 AI 版的「快到了」——一問位置,可能還在家。
5. 「是不是停了?」最好分階段判斷
一個實務 Heartbeat 策略可這樣分類:
| Heartbeat 距今時間 | 解讀 |
|---|---|
| 0–10 分鐘 | CURRENT |
| 10–20 分鐘 | HEARTBEAT_OVERDUE |
| 超過 20 分鐘 | STALE_UNKNOWN |
STALE_UNKNOWN 不等於 FAILED。
之後依序查看:
- 當前進度紀錄
- Check / Status
- branch / PR
- 最新 commit
- 最後才推測
如果 Heartbeat 舊了,但後來出現新 PR 或新 commit,常代表「工作有做,只是忘記更新狀態」。
AI 也會發生:活幹了,日報忘了寫。
6. 不要這樣管理進度
不要把 Heartbeat 專用 commit 堆到 main
會污染歷史、增加衝突,也可能觸發沒必要的 CI 或部署。比較適合用可更新的 Issue comment、Check、Status 或非正式 ops 區域。
不要每次 Heartbeat 都新增留言
一個 run 對應一個可更新紀錄比較清楚。每 10 分鐘多一則,最後會變成考古現場。
不要把沉默直接判為失敗
僅僅 Heartbeat 過期時應使用 STALE_UNKNOWN。只有存在明確失敗證據時才標記失敗。
不要把秘密寫進進度日誌
API key、token、password、private URL、原始私聊、個人資料、機密檔案內容都不應出現在進度日誌。
不要因為可觀測性管道壞了就把安全工作全部停掉
進度 API 失敗時應 fallback 到其他 sink;能安全繼續的工作照常繼續。
7. 一個實用模板
State: RUNNING
Phase: TESTING
Run ID: agent-20260916-long-task
Started: 10:00
Last heartbeat: 14:05
Last material change: 13:42
Branch: feat/long-task
Head SHA: abc1234
PR: #123
Working on:
- regression tests
Completed:
- runtime implementation
- contract update
Remaining:
- regression completion
- merge verification
- production readback
Blockers:
- none
Tests:
- 84 / 127 passed so far
- no failure observed
Next checkpoint:
- finish regression, then integration
這些資訊就足以把「是不是停了?」變成「原來在測試」。
進度可視化不是為了催 AI,而是避免人類因不確定而重啟、打斷或重複下相同指令。
8. 總結――長時間 AI 要把「聰明」與「看得見」分開設計
長時間任務需要明確區分:
- 沒有 commit ≠ 停止
- 有 Heartbeat ≠ 有實際進展
- Heartbeat 過期 ≠ 失敗
- 一個 blocker ≠ 全域停止
- 測試時沉默 ≠ 睡著
如果 AI 可以工作六小時,人就不該被迫盯它六小時。
更好的設計是:任何時候回來查看,都能立刻知道它現在在哪裡。
理想的長時間 Agent 不是一直說話的 Agent。
它可以安靜工作,但只要看一眼,就知道做到哪一步了。

