iT邦幫忙

2026 iThome 鐵人賽

DAY 22
0
AI Engineering

Harness Engineering × Pi Agent 實戰:打造可觀測、可評估的 AI Coding Agent系列 第 22 篇

Day22:Compaction 為何等到 Agent 結束才發生?一次門檻實驗的意外發現

  • 分享至 

  • xImage
  •  

一個永遠等不到的實驗

Day21 拆完 compaction 的機制,本來要直接量它的影響。但有個很現實的問題:

我跑了 130 次執行,compaction 一次都沒觸發過。

原因是門檻太高。gpt-5.6-luna 的 context 視窗是 272K,預設保留 16,384 給回答,所以要到 255,616 tokens 才會壓縮。而我這些任務裡,單次請求最大的 context 只有 14,050 tokens——連視窗的 6% 都不到。

等一個自然觸發的長任務?那得設計一個要讀幾百個檔案的任務,成本和時間都不划算,而且會同時改變太多變數。

所以這次換個做法:把門檻搬下來,讓現有的任務就會觸發。

怎麼逼它發生

Day21 提過,compaction 的兩個參數都能在 .pi/settings.json 裡改。我在受測專案裡放了這個:

{
  "compaction": {
    "enabled": true,
    "reserveTokens": 266000,
    "keepRecentTokens": 2500
  }
}

翻譯一下:

  • reserveTokens: 266000 → 觸發門檻變成 272,000 - 266,000 = 6,000 tokens。
  • keepRecentTokens: 2500 → 壓縮時只保留最近 2,500 tokens 的訊息,其餘摘要掉。

第二個參數是必要的。如果只降門檻卻保留 20K 近期訊息,切點會一路退到對話開頭,結果「沒有東西可以摘要」——壓縮會變成空轉。兩個參數必須一起調,這是設計這個實驗時踩到的第一個坑。

還有一個細節:專案層級的 .pi/settings.json 預設不會生效,因為 Pi 有「專案信任」機制(Day8 提過)。非互動模式要加 -a 才會載入。為了讓兩組條件只差一個變數,兩組都加了 -a,差別只在有沒有那個設定檔。

  • 任務:T5 資料遷移——六個任務裡對話最長的一個(中位數 29 次工具呼叫)。
  • 兩組條件:不會觸發(預設門檻)vs 強制觸發(門檻降到 6,000)。每組 5 次。

表面上的結果

條件 成功 壓縮次數 成本中位數 tokens 中位數 耗時中位數
不會觸發 5/5 每次 0 $0.0078 79,237 57 秒
強制觸發 5/5 每次 1 $0.0113 105,786 80 秒

壓縮確實被逼出來了,成功率也沒掉。看起來是一個乾淨的實驗。

但它其實沒有測到我要測的東西。

事件的順序不對

這件事是我在 Day29 寫 session replay 工具的時候發現的:把事件記錄重新 fold 成狀態之後,最終狀態的訊息數是 1。

一則。整場對話只剩一則訊息。

原因很簡單——壓縮事件是檔案裡的最後一筆記錄。五次執行,五次都是。

回頭看 harness 自己吐出來的事件串流,順序寫得清清楚楚:

turn_start × 8 → agent_end → compaction_start → compaction_end

agent_end 在壓縮之前。也就是說:

agent 把任務做完、回報完、結束了,Pi 才開始產生摘要。那份摘要沒有被任何一次模型請求用到。

而且門檻早就跨過了。看 r01 每一輪的 context 大小(input + 快取命中 + output):

第幾次請求 context tokens 超過 6,000 門檻?
1 1,653 否
2 2,819 否
3 4,555 否
4 7,573 是
5–8 7,899 → 9,505 是

第四輪就過線了,後面還有四輪,壓縮一次都沒發生。

再壓一次門檻:1,000 tokens

會不會是門檻還不夠低?我加跑一組:reserveTokens: 271000,門檻變成 1,000 tokens——第一輪就會過線。

結果
執行次數 3(全部成功)
每次的輪數 10、8、10
壓縮時的 context 12,261 / 11,805 / 10,734 tokens(門檻的 11 倍)
壓縮次數 每次 1
壓縮發生的位置 三次都是 agent_end 之後

整場對話在門檻十倍以上的地方跑了八到十輪,中間一次都沒壓縮。

所以結論是明確的:

在 Pi 0.84.3 的非互動 -p 模式下,這 8 次執行裡,compaction 從來沒有在對話中間發生過——它發生在 agent 結束之後。

Day21 我寫了觸發條件 contextTokens > contextWindow - reserveTokens,但漏掉一個更重要的問題:這個條件什麼時候被檢查? 答案是:不是每一輪檢查。

(我試著在打包過的 bundle 裡追這段邏輯,只找到 shouldCompact() 這個純函式和一個 _runAutoCompaction("threshold") 的呼叫點,沒辦法百分之百確定完整的觸發路徑。所以上面那句話我只敢用量到的方式講:8 次執行、沒有一次在對話中間壓縮。)

那我到底量到了什麼?

量到一件很實際的事:產生一份摘要的價格。

中位數
摘要那一次呼叫的成本 $0.0018
摘要那一次呼叫的耗時 15~31 秒
佔整次執行成本的比例 約 16%

那 80 秒 vs 57 秒的差距(+40%),幾乎就是這一段:agent 早就做完了,程序在那裡多跑十幾二十秒去寫一份沒人會讀的摘要。

順便修好一個我自己的帳單 bug

更難堪的是,我第一次算出來的成本是 $0.0095,不是 $0.0113。

原因是:摘要那一次模型呼叫的 usage,掛在 compaction 那筆記錄上,不在任何一則 assistant 訊息上。

{"type": "compaction", "tokensBefore": 9505, "firstKeptEntryId": "6b7efc9d",
 "usage": {"input": 4952, "output": 506, "totalTokens": 5458,
           "cost": {"total": 0.0015976}}}

我的量測程式只走 assistant 訊息來加總 token 和成本,所以漏掉了整個壓縮的開銷——而這正好是這個實驗唯一真正要量的東西。

修好之後(bench/runner/metrics.py 把 compaction 記錄的 usage 也加進去),差距從 +22% 變成:

成本中位數 相對變化 95% CI(bootstrap) 有把握?
修正前(漏算摘要) $0.0095 +22.0% −16.6% ~ +53.0% 否
修正後 $0.0113 +45.7% +3.9% ~ +76.2% 是

有意思的是對話本身的那 +22%($0.0078 → $0.0095)區間含 0,是雜訊;真正撐得住的那一段,全部來自那筆被我漏掉的摘要費用。

而我不需要重跑任何一次執行就能修正這件事——因為 session 都留著,重算一次就好。這是 Day29 要展開的主題。

所以該不該開 compaction?

這次的數字指向一個很具體的建議:

如果你在 CI、批次腳本、或任何「跑完就結束」的場景用 agent,compaction 對這一次執行毫無幫助,只會在最後多收你一筆摘要費。

它產生的摘要是留給下一次 session 的(--continue / --resume 的時候才有用)。一次性的 job 根本不會有下一次。

以這次的數字算:每個 job 多付約 16% 的成本、15 到 31 秒的時間,換到一份會被丟掉的摘要。在批次場景把 compaction.enabled 關掉,是一個可以直接省錢的設定。

反過來,在互動式的長對話裡,這筆錢是該付的——那份摘要就是下一輪請求的輸入。

誠實的邊界

  1. 這個實驗沒有測到「失憶」。 原本要量的第三件事——agent 在摘要之後會不會忘記做到哪——完全沒有測到,因為摘要從來沒有進到任何一次請求裡。Day21 說的「摘要格式保住了該保的資訊」這件事,我還是沒有證據。
  2. 只在 0.84.3、只在 -p 非互動模式。 互動模式(對話會繼續下去)很可能是另一回事,我沒有量。
  3. n=5 加 n=3。 「摘要要 $0.0018」這個數字本身也是中位數,不是保證。
  4. 這是人為降門檻的結果。 真實的長任務會在 255K 的 context 下壓縮,摘要的規模和價格都會大得多。

明天

Day23 回到工具本身:跑了 130 次實驗之後,我發現我一直缺一把尺——沒辦法跨實驗比較、沒辦法分辨「有效果」和「運氣好」。那天會把量測台補成一個真正的評測框架。而今天這個「少算了一筆錢」的教訓,會在 Day29 變成一個獨立的工具。


上一篇
Day21:Context 裝不下時,Agent 該忘掉什麼?拆解 Pi 的 Compaction
下一篇
Day23:實驗結果如何判斷可信?替 Agent 量測台補上統計與重跑能力
系列文
Harness Engineering × Pi Agent 實戰:打造可觀測、可評估的 AI Coding Agent 共 25 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言