🎯 什麼情境該想到我
當你「要把系統提示、角色設定、檢索資料、聊天記錄全塞進一個固定大小的 context,又不想讓任何一塊被擠爆」的時候。
⚙️ 怎麼用(步驟 / 公式)
先算箱子多大:
可用空間 = max_context − 回應長度上限
例:8192 − 300 = 7892
原則:固定的先放、可伸縮的後放、必須出現在特定位置的先預留。
- Reserve(先佔位):之後一定要出現、而且位置固定的東西(格式標記、「只以某角色身份回覆」這類控制訊息、工具定義),先只扣額度、不放內容。否則聊天記錄會把空間吃光,它們就放不進去了。
- Add(放固定內容):主提示、角色描述、場景、檢索到的知識……依序加入。任何一項超額就直接報錯,不要默默裁切——固定內容壞掉比聊天少幾句嚴重。
- Fill(從最新往舊填聊天):最新一則先放,逐則往前,遇到第一則放不下的就停。
- Free + Insert(歸位):釋放第 1 步的佔位,把真內容插到正確位置。這一步淨值為零——預留時已經扣過了。
算一次帳(SillyTavern 文件範例):
| 階段 | 扣除 | 剩餘 |
|---|---|---|
| 可用 | 7892 | |
| Reserve:標記 3+控制 130+分隔 9+群組引導 15+工具 200 | 357 | 7535 |
| Add:main 150+兩段知識 800+800+角色 200+個性 100+場景 80+人設 50+jailbreak 100 | 2280 | 5225 |
| Fill:最新 6 則聊天,第 7 則(500)放不下就停 | 4831 | 394 |
驗算:7892 − 394 = 7498 已用;7498 + 300(回應)+ 394(剩餘)= 8192 ✓。
★ 帳上看得出:兩段知識 1600 tokens 就佔了固定內容 2280 的七成——檢索知識一定要有自己的上限,否則直接擠掉聊天記憶。
另一種寫法:全放再減(SillyTavern 的 Text Completion 路徑)
loop:
total <= max_context → 完成
還有對話範例 → 刪一條範例
還有聊天 → 刪最舊的一則
都沒了 → 強制送出
兩種做法的保護順序一樣:角色定義 > 近期聊天 > 範例/遠期聊天。
計數要用目標模型的 tokenizer:同一段字在不同 tokenizer 下差很多。粗估「每 3.35 字元 ≈ 1 token」對中文很不準,中文一個字常常就超過一個 token。計數是高頻操作,要加快取(key = tokenizer+字串 hash+模型)。
機制細節 → Token預算管理
🧪 我實際套用的紀錄
- (尚無)
⚠️ 注意 / 什麼時候不適用
- 從新往舊是硬切:放不下的那則整則丟掉、不截半;更舊但更短的也不會被撿回來。被切掉的遠期內容要靠 工具-對話型AI的長期記憶分層 補。
- 固定內容太肥會讓聊天只剩幾則:角色卡或檢索知識膨脹時,最先犧牲的是對話的連續性。
- 剩餘緩衝不是浪費:大小取決於訊息粒度(例子剩 394,是因為下一則有 500)。
- context 大到整段歷史都裝得下時,這套只是保險;但一旦上線長對話,遲早會撞到。
🔗 相關工具
- Token預算管理 —— 完整機制與兩條路徑的差異
- 工具-關鍵字觸發的設定注入 —— 按需注入的知識要有獨立預算
- 工具-對話型AI的長期記憶分層 —— 預算切掉的舊對話,用摘要與召回補回來