狀態寫到磁碟,活過壓縮
「State that survives compression — because it's outside the conversation.」
TodoWrite 和 Task 有什麼不同?
s03 的 TodoManager 也能列任務-但它存在記憶體裡。 s06 講的 auto_compact 一觸發,messages[] 被替換成 summary,TodoManager 的狀態就跟著沒了(因為它是 in-memory)。
s07 的 Task 不一樣:每個 task 是一個 .tasks/task_42.json 檔案。 context 被壓也好、進程重啟也好、agent 被換掉也好——只要磁碟檔案還在,任務就還在。
# .tasks/task_12.json { "id": 12, "subject": "Refactor auth middleware", "description": "Extract JWT logic to shared module", "status": "pending", "blockedBy": [8, 11], # 必须先完成 #8 和 #11 "owner": "" }
選擇規則:臨時待辦(做完這次就忘)用todo;持久任務(跨會話保留、有依賴)用task。
blockedBy · 依賴圖的脾氣
blockedBy 是 task id 清單-必須這些都 completed 之後,目前 task 才會「可執行」。
s07 的實作有一個精巧的細節:完成一個 task 時,它會自動從所有其他 task 的 blockedBy 清單中移除自己。
def _clear_dependency(self, completed_id: int): # Scan every task, remove completed_id from their blockedBy for f in self.dir.glob("task_*.json"): task = json.loads(f.read_text()) if completed_id in task.get("blockedBy", []): task["blockedBy"].remove(completed_id) self._save(task)
這樣 agent 不需要維護一張獨立的 "什麼 task unblocked 了" 表-只要遍歷 .tasks/,找 status=="pending" and not blockedBy 的就是現在可執行的。
依賴圖交互
下面這個 widget 給你一個 5 個 task 的依賴圖。點 "complete",看 blockedBy 自動更新,哪些 task 變成「可執行」(綠色高亮)。
經過壓縮還能活嗎?
s06 講過 auto_compact 會把 messages[] 換成一條 summary。但 task 不受影響,因為它在磁碟。 測試一下:讓 agent 做了 5 個 task,壓縮掉對話後,它掃一下 .tasks/,原地能繼續。