
Day 6 談 Handoff 時,留下了一個問題:
如果下一個 Session 完全看不到上一輪聊天,只拿到 Repository 和一份最小 Handoff,它還能不能安全接手?
但長任務跑起來之後,還有一種情況更麻煩。
Session 甚至還沒結束。
只是 Conversation 已經很長,前面的內容開始被壓縮、淡出,Agent 必須靠仍留在 Context 裡的資訊繼續工作。
這時需要回答的,不再只是:
下一個 Session 記不記得上一輪?
而是:
如果 Conversation 本身不是可靠的長期儲存,那專案到底要靠什麼記住「現在是真的什麼狀態」?
答案不是再把更多東西塞進 Prompt,而是讓 Repository 開始承擔 Durable State 的 system of record。
一開始使用 Coding Agent,很容易形成這種工作方式:
需求
↓
討論
↓
看檔案
↓
改 Code
↓
再討論
↓
再看更多檔案
↓
繼續做
只要同一個 Session 還在,就會有一種安全感:
前面不是都講過了嗎?
甚至當 Context Window 越來越大,這個直覺會更強。
好像只要 Agent 能塞進更多歷史,就能自然擁有更好的「記憶」。
實際跑長 Session 時,另一種摩擦開始出現:Conversation 經過多輪壓縮後,前面探索過的舊方案、後來才定案的新方案,以及 Repository 現在存在的狀態,會同時以不同形式殘留在工作脈絡裡。Agent 看得到很多資訊,卻不一定知道哪一份才仍然有效。
這時,工作流暴露的已經不是「記憶不足」,而是權威來源不清楚。
同一件事可能同時存在好幾個版本:
這些資訊可能全部都是真的。
但它們的權威性不一樣。
如果 Agent 只是「記得很多」,它還是可能拿到一個已經過期的真相。
問題因此不再只是 Memory,而是:
哪一個來源有資格代表現在的事實?
一開始,這個 Repository 並沒有預先設計什麼 Context Architecture。
很多事情都和一般 ChatGPT / Codex 協作一樣,先在對話裡一路討論:
理論上,每次開新 Session,都可以把前面的歷史重新貼一次。
但做久之後,問題開始一個一個跑出來。
有些已經決定過的事情會被重新討論;長期規劃會因為新素材不斷想改;寫作規則和視覺 continuity 如果只留在 Conversation 裡,下一個 Session 很容易又按照自己的理解重建一次。更麻煩的是,同一件事情可能在不同 Conversation 留下不同版本,卻沒有人知道哪個才仍然有效。
這套 Repository 架構並不是先畫好再照表執行。
反而是這些摩擦,把不同用途的 artifact 一個個逼了出來。
PROJECT_STATE
→ 現在仍有效的是什麼
DECISIONS
→ 哪些選擇已經做過,以及為什麼
Long-term Roadmap
→ 保留長期方向
Rolling Plan
→ 讓近期安排可以調整,而不用一直重寫長期規劃
Style / Working Rules
→ 把反覆出現的協作規則固定下來
Source Notes
→ 區分候選素材、已驗證資料與正式依據
Assets
→ 讓視覺與參考素材不只存在某一段 Conversation
Git
→ 保留實際修改歷史
結果是:
這個原本只是拿來承載長期工作的 Repository,自己慢慢長成了一套 Context Architecture。
這些 artifact 也不是為了配合某個 Agent 理論才刻意建立的。
它們幾乎都對應到一個實際發生過的問題。
因此,要解的問題已經不是:
怎麼把所有 Conversation 都保存下來?
而是:
哪些資訊值得跨 Session 存活?它應該放在哪個可重新取得、而且權威性清楚的位置?
這也是我後來開始把 Repository 視為 Durable State 的原因。
不是因為 Repository 裡 Markdown 越多越好。
而是當 Conversation 淡出、Session 更換,甚至換另一個 Agent 時,重要決策不必靠「我記得之前好像講過」才能延續。
下一個 Agent 可以重新讀 Repo,重新建立 Context。
這個差別,才讓後來整套做法開始有用。
這是這次實作留下最重要的 Durable State 判斷。
很多人提到 Agent Memory,很容易先想到:
怎麼讓 Agent 永遠不要忘?
但工程上,我現在反而比較在意另一件事:
就算 Agent 忘了,它能不能重新取得正確狀態?
這兩個方向差很多。
第一種思路是:
把更多歷史留在 Context
↓
希望 Agent 記得
第二種思路是:
Context 可以消失
↓
重要狀態留在可查證來源
↓
Agent 需要時重新讀取
對長時間工作的 Agent,第二種通常更可靠。
因為 Context 本來就是工作記憶。
它適合拿來推理。
但未必適合當專案資料庫。
這可以作為「要不要升級成 Durable State」的一個簡單判斷。
Conversation 裡的資訊大致可以分成三類。
例如探索過程:
先懷疑 A
後來查 B
又試過 C
最後發現都不是
這些內容可能幫助當下推理。
但如果最後已經得到可驗證結論,就不一定值得永久保存。
它們可以隨 Context 淡出。
例如:
目前有幾個檔案被修改
某個測試現在是否 PASS
目前 branch 指向哪個 commit
這些資訊也不一定需要另外寫一份文件。
因為 Git、Test Runner、檔案系統本身就可以重新回答。
如果 Repository 已經能提供事實,再手寫一份副本反而可能製造 stale state。
這類才是我最想升級成 Durable State 的資訊。
例如:
為什麼 A 方案被否決?
這次明確不處理什麼?
目前哪一條 Roadmap 才是正本?
哪些外部素材只是 candidate?
哪個規則是長期有效,哪個只是這輪 workaround?
這些資訊不是看 Code 就一定能推出來。
如果它只存在 Conversation 裡,Context 一旦消失,下一個 Agent 很可能重新發明一次。
這類資訊才值得進入:
DECISIONS
PROJECT_STATE
Roadmap
Source Notes
AGENTS.md
或其他適合它生命週期的 artifact。
這裡很容易走向另一個極端。
看到 Durable State 很重要,就開始建立:
STATE.md
MEMORY.md
SESSION.md
CONTEXT.md
KNOWLEDGE.md
CURRENT.md
LATEST.md
最後每一份都寫著「狀態」。
這反而比只靠聊天更危險。
因為 Agent 會遇到另一個問題:
到底哪一份才是真的?
因此,每一類資訊最好盡量只有一個 canonical source。
以這個鐵人賽 Repo 為例:
專案現在在哪
→ PROJECT_STATE.md
已確認/否決的決策
→ DECISIONS.md
系列方向
→ Roadmap
文章正式內容
→ article.md
程式/文件修改事實
→ Git
測試是否通過
→ Test result
這個設計的價值,不是檔案命名本身,而是讓下一個 Agent 知道去哪裡重新建立 Context。
Day 6 我提過:
Handoff
→ 提供方向
Repository / Tests / Environment
→ 提供事實
Day 7 往前再走一步,可以把它變成更嚴格的規則:
Durable State 不等於 Durable Markdown。
如果一個事實可以直接從更權威的來源取得,就應該優先讀那個來源。
例如:
不要只寫:
Tests passed.
而是讓 Test Result 可以重新被驗證。
不要只寫:
目前 branch 是 main。
而是直接看 Git。
不要只寫:
這個功能已經 deploy。
而是從真正的 Environment 確認。
我會把 Source of Truth 想成一個階層:
Machine-verifiable state
Git / Tests / Environment / Artifact
↓
Curated durable state
PROJECT_STATE / DECISIONS / Roadmap
↓
Transient working state
Handoff / Session notes
↓
Conversation
越重要、越需要長期延續的狀態,就越應靠近可以重新驗證的來源;暫時性的工作脈絡則留在 Handoff 或 Conversation。
看到長 Session 被壓縮,直覺通常會覺得:
前面的 Context 被吃掉了,好可惜。
但更值得問的是:
被吃掉的東西裡,有沒有本來就不該只存在 Conversation 的資訊?
如果答案是有,需要修的就不是 Compaction。
而是 Workflow。
因為就算今天給我更大的 Context Window,問題也只是晚一點發生。
當專案開始跨:
Conversation 就不應該再扮演 system of record。
OpenAI 在〈Harness Engineering〉中也提出類似方向:Repository knowledge 應成為 system of record,讓 Agent 能從版本化、可查證的環境重新取得專案知識,而不是把所有知識堆在單一巨大 instruction 或對話裡。
這個外部觀點對我最大的價值,不是證明「大家都要建立很多 Markdown」。
而是確認了一件這套 Workflow 已經逐漸遇到的事:
Agent 越能長時間工作,專案就越需要把「記住」改造成「可重新取得」。
也不是。
這套方法有成本。
每新增一個 Durable Artifact,就多一個需要更新、清理、避免過期的東西。
如果一個兩小時就結束的小任務,本來一個 Prompt 加上 Git diff 就能完成,硬加:
只是在增加管理成本。
因此,可以用一個很簡單的升級判斷。
當資訊同時符合越多條,我越傾向讓它離開 Conversation:
□ 下一個 Session 還需要它
□ 無法單靠 Code / Git / Test 重新推出
□ 忘記後會造成重工或風險
□ 已經被多次重新討論
□ 有明確 owner 可以維護
□ 能指定唯一 canonical source
如果都不是,
就讓它留在 Context 裡,完成任務後自然消失。
Durable State 不是收藏癖。
它應該只保存:
忘掉之後會付出成本,而且無法安全重建的狀態。
到前一天為止,我還在處理:
Session 結束
↓
怎麼交棒
到了今天,更重要的是:
Conversation 可以消失
↓
專案事實仍然可以重新取得
這兩件事的差別很關鍵。
Handoff 是跨過一次 Session 邊界。
Durable State 則是在設計:
即使沒有任何一段 Conversation 可以信任,Agent 仍然能重新建立足夠正確的 Context。
如果有人問:
Context Window 越來越大,還需要 PROJECT_STATE、DECISIONS、Git、Tests 這些東西嗎?
答案仍然是:
需要。因為更大的 Context 讓 Agent 能看更多東西,卻沒有自動解決哪個東西才是目前真相。
讓長任務 Agent 變得更可信的,不是它「記得更多」。
而是:
它忘掉之後,仍然知道去哪裡找回正確的狀態。
當 Repository 開始承擔 Durable State 之後,另一個問題很快就出現了。
有些事情不是「狀態」。
而是每個 Session 都在重複教 Agent 怎麼做。
例如同一套檢查、同一組操作步驟、同一種驗證流程,如果每次都重新寫進 Prompt,Context 很快又會被重複內容占滿。
這時候下一個問題就不是:
怎麼讓 Agent 記得?
而是:
一件事重複教到什麼程度,才值得從 Prompt 抽成可重用的能力?