前一天我們談 Skills 與 Progressive Disclosure。
核心觀念是:
Context 是工作區,不是倉庫。
Agent 不需要一開始就讀完整知識庫,也不應該把所有 Skill 永久留在 Prompt 裡。
但即使我們已經做到動態載入,Agent 執行時間一長,Context 還是會持續變大。
因為每一輪都可能新增:
如果什麼都不刪,Agent 最後一定會碰到兩個問題:
所以 Context Management 真正要解決的,不只是:
Token 超過限制時怎麼辦?
更重要的是:
哪些資訊值得繼續佔用模型的注意力?
今天我們會把 Context Management 拆成四個核心機制:
大型模型的 Context Window 越來越大,很容易讓人產生一個直覺:
反正放得下,就全部留下。
但這通常會把容量問題變成注意力問題。
假設 Agent 已經執行 80 輪,Context 中包含:
模型理論上可能全部看得到。
但真正需要下一輪決策的資訊,可能只有:
其他資訊不一定值得繼續留在 Working Context。
所以 Context Window 和 Storage 是兩個不同概念。
Storage 的目標是:
不要遺失資料。
Context 的目標是:
讓模型在這一輪看到最有用的資料。
最簡單的做法是:
超過 Token 上限,就刪掉最舊訊息。
這可以避免 API Error。
但很容易刪掉真正重要的內容。
例如:
第一輪使用者說:
不要修改
billing/。
後面執行 50 輪後,如果這條限制因為太舊而被刪掉,Agent 可能完全失去關鍵 Constraint。
所以真正的 Context Management 不能只靠時間順序。
它需要判斷資訊的角色與價值。
Selection 回答:
哪些資訊應該進入下一輪 Context?
不是所有已知資訊都要出現。
可以先把資料分成幾類。
使用者真正要完成什麼?
這通常應該高優先保留。
哪些事情不能做?
例如:
Constraints 通常比很多中間對話更重要。
目前做到哪裡?
例如:
最新工具結果是否會影響下一步?
最近一次失敗通常很重要。
兩小時前已經解決的錯誤可能不重要。
哪些證據仍然支持目前判斷?
過去發生什麼?
History 不一定全部需要保留。
很多部分可以摘要或移出 Context。
Context Selection 與 Memory Retrieval 很像,但來源不同。
Context Selection 處理的是:
這個任務目前已經產生的資訊,哪些要留在 Working Context?
Memory Retrieval 處理的是:
過去 Session、使用者或任務的資訊,哪些要重新載入?
兩者最後都會把資訊放進 Context,但責任不同。
今天先處理同一個任務內的 Working Context。
有些資訊仍然重要,但不需要完整保留。
這時可以做 Compaction。
例如 Agent 讀了 15 個檔案。
不一定需要保留 15 個完整 Tool Result。
可以壓縮成:
已確認:
- Auth 使用 JWT
- Token validation 位於 middleware/auth.py
- Refresh flow 位於 services/token.py
- 目前錯誤集中在 expiry handling
原始資料仍可以保存在外部 Storage。
Context 中只保留對下一步有用的 Summary。
這就是:
Full Artifact
↓
Task-Relevant Summary
↓
Working Context
Compaction 的目標不是單純縮短。
而是保留決策需要的資訊。
如果 Summary 只寫:
已分析 Auth 模組,發現一些問題。
Token 很少,但幾乎沒有價值。
有效的 Summary 應該保留:
可以把它想成:
如果原始內容現在被移出 Context,未來的 Agent 還需要知道什麼才能繼續工作?
這個問題比「怎麼把內容縮到最短」更重要。
有些資訊已經完全不值得留在 Context。
例如:
這些內容可以 Evict。
Eviction 不是刪除資料。
它只是:
不再讓資料佔用目前模型的 Context。
原始資訊可以保存在:
如果未來需要,再重新載入。
可以根據多個訊號決定:
例如:
使用者明確設定的 Constraint:
不可自動部署 Production。
即使很舊,也應該高優先保留。
而一個 20K Token 的 Test Log,如果可以隨時重新執行,就比較適合 Evict。
一個實用方式是建立 Context Tiers。
幾乎永遠保留。
例如:
目前任務正在使用。
例如:
仍有價值,但只保留 Summary。
例如:
移出 Context,但保留引用。
例如:
這種分層比單純 FIFO 更穩定。
Evict 並不代表永遠不再使用。
如果後面出現新的問題,Agent 可能需要把某段資訊重新載入。
這就是 Rehydration。
例如:
目前只保留:
Auth 模組摘要
後來 Agent 發現:
問題可能來自 Refresh Token
系統再載入:
services/token.py
相關舊 Trace
先前的 Test Result
這讓 Context 可以保持小,但資訊仍然可恢復。
Rehydration 的關鍵是:
Evict 之前要留下足夠的索引。
例如:
如果什麼都不留下,之後就不知道去哪裡找。
當大型內容被移出 Context,可以留下 Stub。
例如:
[Artifact: test-log-042]
內容:完整 integration test log
大小:18,420 tokens
摘要:3 個失敗,主要集中於 payment timeout
需要時可重新讀取
這比完全刪掉更好。
模型知道這份資訊存在。
但不需要每一輪都重新支付完整 Context 成本。
如果 Compaction 把重要細節丟掉,後面可能很難恢復。
例如原始內容:
使用者:
可以修改設定,但絕對不要修改 Production Secret。
Summary 卻寫成:
使用者允許修改設定。
關鍵 Constraint 消失了。
所以 Compaction 不是純摘要任務。
它必須保留高優先資訊。
可以設計:
永遠不能在 Summary 中遺失:
可以較自由壓縮:
如果 Summary 會影響後續執行,它本身就值得驗證。
可以檢查:
如果 Agent 的 Context 很長,錯誤 Summary 可能比 Context Overflow 更危險。
因為它會讓後面的模型自信地建立在錯誤狀態上。
不是每個 Tool Result 都應該用同一套保留策略。
例如:
可能保留摘要與 File Reference。
可能只保留最相關證據與 Source。
失敗時保留關鍵 Error。
成功後只需要保留:
Tests passed.
保留聚合結論與 Query Reference。
成功時高度壓縮。
失敗時保留錯誤附近內容。
Context Management 最好了解資料類型,而不是把所有 Message 當成相同字串。
Agent 成功執行十次讀檔,通常不需要保留十份完整輸出。
但一次重要失敗可能會影響很多後續決策。
因此 Context Priority 可以考慮:
Unresolved Failure
>
Current Evidence
>
Current Plan
>
Recent Success
>
Resolved History
這不是絕對規則。
但很符合 Production Agent 的需求。
假設模型支援 200K Tokens。
系統不一定要等到 195K 才開始 Compaction。
因為還要預留:
所以可以設定 Soft Budget。
例如:
Model Limit
200K
Target Working Context
120K
Reserve
80K
一旦超過 120K,就開始:
這樣系統不會每次都在 Overflow 邊緣工作。
Context 不應該成為唯一資料來源。
如果所有狀態只存在 Prompt 裡,一次 Compaction 就可能造成不可逆資訊損失。
更好的方式是:
Storage
保存完整資料
Context Manager
選擇目前需要的 Working Set
Model
根據 Working Set 做下一步決策
Storage 可以很大。
Context 應該保持精簡。
這也是為什麼:
Bigger Context Window 不等於 Better Memory。
模型可以協助判斷語意相關性。
但有些內容不能由模型自由刪除。
例如:
這些比較適合由程式標記為 Pinned。
可以把責任拆成:
程式碼
決定什麼不能丟
模型
協助判斷什麼目前最相關
Context Manager
執行 Selection、Compaction、Eviction
Context 反覆 Summary 後,還有一個問題:
Summary of Summary。
假設每 20 輪做一次摘要:
Raw History
↓
Summary A
↓
再加 20 輪
↓
Summary B
↓
再加 20 輪
↓
Summary C
每次壓縮都可能丟失一點資訊。
最後 Context 和原始事實可能越來越遠。
這就是 Context Drift。
可以降低風險的方法:
不同階段需要不同資訊。
例如 Coding Agent:
需要:
需要:
需要:
Investigation 的大量搜尋結果,到了 Verification 階段可能已經可以壓縮。
所以 Context Selection 也可以和 Plan State 結合。
容量足夠不代表注意力沒有成本。
重要 Constraint 可能正好很舊。
結果把真正需要的資訊一起刪掉。
最後仍然變成 Context Hoarding。
未來無法 Rehydrate。
不同 Observation 的價值與生命週期不同。
容易造成 Context Drift。
Policy、Constraint 與安全邊界不應該被模型自由移除。
可以把每一段資訊的生命週期整理成:
Created
↓
Selected
↓
Active
↓
Compressed
↓
Evicted
↓
Rehydrated if needed
不是所有內容都會走完整流程。
有些直接 Pinned。
有些 Tool Result 用完就可以移出。
有些 Evidence 可能整個 Task 都要保留。
重點是:
Context 應該有生命週期,而不是只會一直增加。
可以先做四件事。
固定保留:
保留最近幾輪完整 Interaction。
更舊內容轉成 Task Summary。
大型內容移到外部,只留下 Reference。
再設定 Soft Token Budget。
一旦超過 Budget,就優先:
這已經比「超過上限就砍前半段」可靠很多。
Day 8 我們加入 Skill Discovery、Loading 與 Eviction。
今天把相同思想擴展到整個 Working Context:
因此,Agent 不再把 Context 當作無限增長的聊天紀錄。
它開始主動管理:
下一輪模型真正需要看到什麼?
Context Management 不只是處理 Token Overflow。
真正的問題是:
哪些資訊值得持續佔用模型的注意力?
一個可靠的 Context Manager 至少要做到:
最重要的原則是:
Storage 負責不遺失資料,Context 負責讓模型看見現在最重要的資料。
下一篇會進入 Memory:
Context 是目前工作的狀態,那跨 Session 之後,哪些資訊才值得真的「記住」?
完整系列與範例收錄於:https://github.com/hardness1020/awesome-agent-architecture