前幾天我在整理 Hermes 的長任務時,開始很直接地感受到一件事:上下文不是免費的記憶體,而是每一次模型呼叫都可能增加的成本。
當 Agent 只處理一個小問題時,把前文全部帶進去似乎很方便。但當任務變成「讀多份報告、查原始資料、執行腳本、整理中間結果,再產出交付文件」,上下文會快速膨脹。最後不只變慢,還可能因為真正重要的指令被埋在大量舊內容裡而判斷失焦。
我把這個問題拆成三個部分:上下文壓縮、快取保護,以及長任務的分批交付。
先釐清:上下文不是長期記憶
上下文是目前這一次工作可見的內容;長期記憶是跨工作保存的穩定規則;知識庫則是需要主動查詢的原始資料。三者混在一起,會造成兩種浪費:每次都攜帶不需要的歷史,或把一次性的任務進度永久寫進記憶。
在我的工作流裡,能重複使用的偏好與決策才進 MEMORY;程序性做法進 Skill;任務中間結果留在工作檔案;需要查證的公司知識留在 Obsidian。上下文只負責把當下需要的部分組合起來。
壓縮不是刪掉最後幾則訊息
簡單截斷 tail 看起來有效,卻很容易把任務目標、限制條件或工具輸出中的關鍵錯誤一起截掉。因此壓縮至少要保留四類資訊:
一、目前任務與驗收標準。
二、尚未解決的阻塞與已排除的假設。
三、已產生的檔案、ID、URL 或其他可回讀證據。
四、下一個最小可驗證步驟。
Hermes 的自動壓縮門檻,我實際上會從 50% 開始觀察,讓系統在還有空間時先整理,而不是等到 85% 才被迫處理。這不是追求一個神奇數字,而是避免壓縮發生在最需要推理的最後階段。
快取是硬性不變量
長任務裡最危險的做法之一,是為了省上下文而任意重建或覆蓋快取。快取可能包含已完成的來源收集、昂貴的工具結果,甚至是重跑外部查詢的唯一依據。
所以我把快取視為不可破壞的資料:追加新結果,不直接覆寫唯一副本;每批資料留下來源與時間;需要整理時產生衍生檔,而不是破壞 raw。這樣即使後面的模型歸納失敗,也能從中間結果恢復,不必假設前面都要重做。
長任務要分批,不要賭一次成功
「一次讀完全部資料再寫報告」是最容易逾時的流程。比較可靠的方式是:先收集並保存 raw,再分批抽取重點,最後才做跨來源歸納。每一批都要有明確的輸入、輸出與筆數檢查。
例如社群雷達可以拆成:來源抓取、去重、內容抽取、訊號分類、報告統整。每個階段都寫入不同檔案,並在下一階段開始前確認檔案存在且不是空白。這樣模型的上下文只需要看當前階段的摘要,不必把所有原始貼文一直帶著走。
一個實際的失敗
我曾經讓一個長任務直接從多個資料源一路跑到成品。中途工具逾時,程序表面上沒有明確錯誤,但最後只產出半份報告。若只看 exit code,很容易把它誤判成完成。
後來我改成每階段留下中間檔,並把完成定義寫成三段:本機檔案真的產生、服務或程序狀態真的載入、外部結果真的讀回。逾時後先讀回目標與中間檔,判斷是否已有部分效果,再決定從哪一批恢復,而不是盲目重跑。
成本與品質的取捨
上下文越長不代表答案越好。長上下文增加 token 成本,也增加模型找錯重點的機率。真正有用的是高密度上下文:保留決策、證據、限制與下一步,移除重複說明與已結案的探索過程。
| 做法 | 成本 | 風險 | 我的選擇 |
|---|---|---|---|
| 全部歷史原文帶入 | 高 | 重點被淹沒、容易逾時 | 不採用 |
| 只保留最後幾則 | 低 | 遺失目標與驗收條件 | 不採用 |
| 結構化摘要+中間檔 | 中 | 需要設計格式 | 採用 |
| 重要資料寫入快取並可回讀 | 中 | 快取若被覆寫難恢復 | 採用不可破壞策略 |
我現在的檢查清單
開始長任務前,先定義每階段輸入、輸出、驗收與回滾方式。執行中,不讓單一上下文承擔所有原始資料;每完成一批就保存並驗證。接近壓縮門檻時,先整理仍有效的決策與證據。發生逾時時,先讀回現況,再決定恢復點。最後,不把模型說「完成」當作完成,必須讀回實際產物。
結語
Agent 的上下文管理,本質上是工程上的資源管理。壓縮是在控制可見資訊,快取是在保護已付出的成本,分批是在降低單次失敗的半徑。三者一起做,長任務才不會從「看起來很聰明」變成「最後交不出來」。
今天的實際證據是:我把長任務拆成可回復階段,將 raw、中間結果與最終報告分開保存,並以讀回檔案與外部結果作為完成條件,而不是只看程序是否結束。