🎯 什麼情境該想到我

當你「要把系統提示、角色設定、檢索資料、聊天記錄全塞進一個固定大小的 context,又不想讓任何一塊被擠爆」的時候。

⚙️ 怎麼用(步驟 / 公式)

先算箱子多大:

可用空間 = max_context − 回應長度上限
例:8192 − 300 = 7892

原則:固定的先放、可伸縮的後放、必須出現在特定位置的先預留。

  1. Reserve(先佔位):之後一定要出現、而且位置固定的東西(格式標記、「只以某角色身份回覆」這類控制訊息、工具定義),先只扣額度、不放內容。否則聊天記錄會把空間吃光,它們就放不進去了。
  2. Add(放固定內容):主提示、角色描述、場景、檢索到的知識……依序加入。任何一項超額就直接報錯,不要默默裁切——固定內容壞掉比聊天少幾句嚴重。
  3. Fill(從最新往舊填聊天):最新一則先放,逐則往前,遇到第一則放不下的就停。
  4. Free + Insert(歸位):釋放第 1 步的佔位,把真內容插到正確位置。這一步淨值為零——預留時已經扣過了。

算一次帳(SillyTavern 文件範例):

階段扣除剩餘
可用7892
Reserve:標記 3+控制 130+分隔 9+群組引導 15+工具 2003577535
Add:main 150+兩段知識 800+800+角色 200+個性 100+場景 80+人設 50+jailbreak 10022805225
Fill:最新 6 則聊天,第 7 則(500)放不下就停4831394

驗算: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 大到整段歷史都裝得下時,這套只是保險;但一旦上線長對話,遲早會撞到。

🔗 相關工具