跳到內容
17.5k

暫存檔造成的磁碟用量

有些使用者在 opencodex home(預設為 ~/.opencodex)發現大量類似 responses-state.json.ocx.<pid>.<seq>.tmp 的檔案,總量達數 GB,而且每次重新開機後持續增加。

opencodex 保留接續快取,讓 previous_response_id 鏈能在代理重新啟動後延續。它以原子方式寫入快照:先把內容寫進暫存檔,再一次替換正式檔案。這可防止寫入途中當機留下不完整的快照。

交換完成後,暫存檔通常立即移除。如果程序在兩個步驟之間結束,暫存檔就會留下。

每個檔案最多可達 24 MB,因為快照每次都是整份重寫,而非附加。因此幾百個遺留檔案很快就會占用大量空間。

**它們是快取,不是持久狀態。**刪除它們的唯一代價,是進行中的對話鏈可能需要重新傳送一次上下文。這些檔案不包含設定、憑證或歷史記錄。

清理機制原本就存在,但只在代理首次載入接續快取時執行一次,也就是該程序寫入任何內容之前。這帶來兩個後果。

代理當機並重啟後,清理執行得太早,無法看到上一個程序剛留下的暫存檔;為避免碰到正在寫入的檔案,系統設有 15 分鐘寬限期,而代理之後便不再檢查。每次重啟於是又多留下一個檔案。

更糟的是,若暫存檔記錄的所屬程序 ID 仍存在,清理就會跳過。重新開機後,作業系統經常重複分配相同的程序 ID,因此舊檔案可能永遠被誤認為屬於正在執行的程序。這就是檔案增長與重新開機次數相關的原因。

清理會隨代理的正常背景計時器重複執行,不再只於啟動時執行,所以正在運作的代理會自行回收遺留檔案。對於早於本次開機的檔案,清理也會忽略程序 ID 檢查,因為目前執行的程序不可能擁有它們。

安全規則不變:未滿 15 分鐘的檔案絕不移除,代理也不會移除自己正在寫入的檔案。

寫入採用 debounce,延遲時間根據上次實際寫入的快照大小決定:檔案較小時,下次寫入排在變更後約兩秒;接近 24 MB 上限時,等待時間會延長至最多三十秒。因此,快取剛變大時仍會有一次短暫等待,較長的間隔會從下一次寫入後才適用。只有在此程序已將相同位元組寫入同一檔案、磁碟上的檔案仍相符,且在 Windows 以外的平台其權限仍僅限擁有者時,才會略過 flush。新程序即使面對完全相同的快照,也會重寫一次;若檔案內容或權限在代理外部遭到變更,也會走強化寫入流程,而非保持原狀。

每次一般背景週期最多執行一次完整的原子重寫。如果接續快取在寫入期間變動,opencodex 會依正常延遲週期安排一次後續寫入,不會立即再次重寫整份快照。正常關閉時,系統仍會在執行中請求排空後進行有界重試,讓最終快照能在程序結束前追上變更。

這些機制讓寫入速率在快取增長時大致維持平穩,避免每兩秒重新序列化並替換整份檔案。

正常關閉會立即 flush,而不等待計時器,因此較長的等待時間主要是擴大強制終止時可能遺失最近接續項目的時間窗口;如上所述,這些項目只是快取。不過 flush 仍是磁碟寫入,也可能失敗,因此在已滿或唯讀的磁碟區關閉時,同樣可能遺失這些項目。

如果代理正在執行,通常會在一兩分鐘內自動回收。

如果代理無法啟動,也就是檔案堆積可能最快的情況,請從命令列檢查並回收:

Terminal window
ocx doctor

“Response-state temp files” 區段會回報可回收的檔案數量與占用空間。這只會回報資訊,不會變更任何內容。

若要實際移除它們:

Terminal window
ocx doctor --reclaim-response-temps

兩個指令都不需要正在執行的代理。其他程序目前鎖定的檔案會被回報,不會強制處理。下一次回收時會重試;代理執行時會自動重試,否則在下次執行這個指令時重試。

若積壓量過大、單次無法處理完畢,指令會顯示剩餘檔案數,方便再次執行。

此機制只處理 response-state 快照暫存檔。其他元件也可能寫入名稱相似的暫存檔,但不會受到影響。