iT邦幫忙

2026 iThome 鐵人賽

DAY 11
0
Vibe Coding

凡人修 Agent 傳-我這一生如履薄冰,你說我的 Agent 能結嬰嗎?系列 第 11

石滿自摺:context 快滿了 pi 會自己壓縮,這一天我先用預設的 - Day 10

  • 分享至 

  • xImage
  •  

每天用他工作會遇到一件很具體的事:對話越來越長,context 快滿。

pi 對這件事有一套預設的做法:滿了就自己壓縮。這一天我先把它用一輪,沒有動它。要講壓縮,得先講清楚一段對話在 pi 裡是怎麼存的,所以從檔案開始。

一段對話存在哪裡

每一段對話都是一個檔案,JSONL,放在 ~/.pi/agent/sessions/,照工作目錄分開放。開了 pi 就自動存,不用管。

要接回去只有幾個指令:

pi -c                  # 接最近那一段
pi -r                  # 開清單自己挑
pi --no-session        # 這次不要存
pi --session <path|id> # 指定某一段(ID 可以只給前幾個字)

檔案的第一行是 header,裡面有版本、ID、時間和當時的工作目錄。從別的 session 分出來的檔案,header 會多一個欄位指回原本那個檔案的路徑——所以「這一段是從哪裡長出來的」這件事不會斷。

再往下每一筆紀錄都有自己的 idparentId。所以整個檔案是一棵樹,而「現在」是那棵樹的一片活葉子。

檔案裡不只有訊息

這件事我原本以為 session 檔案就是一串對話。看了格式文件才發現裡面躺著好幾種不同的東西:

種類 記的是什麼
message 使用者、助理、工具結果
model_change 中途換了模型
thinking_level_change 中途改了思考層級
compaction 這裡壓縮過,附一份摘要
branch_summary 從哪一條分支跳過來,那條的摘要
label 我自己在某一筆上做的標記
session_info 這一段的名字
custom extension 存的狀態,不進 context
custom_message extension 注入的訊息,會進 context

中間那幾種對我來說比一串對話有價值得多。

model_change 意思是:整段歷史裡「這一段是哪個模型做的」查得到。第三章要比模型的時候,這一行就是證據。

最後兩種是同一個 extension 的兩種身分。custom 是它自己要記的東西,不會被送進模型;custom_message 是它硬塞進對話裡的東西,會被送進模型。這個分界很重要——記憶系統要接進來,接的就是這兩個位置:它自己的資料躺在 custom,要餵給模型的那一段用 custom_message 注入。這一章後面三天就在處理這件事。

走錯路的時候

我自己很少打開 /tree。它派得上用場的場景是:我叫他調排版,他理解成重做整個元件,往那個方向做了十幾輪。

/tree 打開來是這一段對話的整棵樹。找到我下錯指令的那一句,選它,那句話回到編輯器裡讓我改,改完送出就從那裡長出一條新的分支。錯的那十幾輪還在檔案裡,只是不在這條路上。跳過去的時候 pi 會問要不要替被丟下的那條留一份摘要。

連按兩次 Esc 就是打開這棵樹;Shift+L 可以給某一筆取名,之後好找。/fork/clone 是同一件事另開新檔案的版本。

Day 10:對話樹、摘要與保留的 Session 紀錄

context 快滿的時候

回到這一天的主題。

門檻寫在文件裡:contextTokens > contextWindow - reserveTokens 就自動壓縮,reserveTokens 預設 16384,留給模型回答用。壓縮的做法是從最新的訊息往回算,留下大約 keepRecentTokens(預設 20k)的量不動,前面那一段交給模型做成一份摘要;之後送出去的 context 就是「這份摘要 + 保留下來的訊息」。原本的訊息還在檔案裡,只是不再送給模型。

檢查的時機有三個:一批工具跑完、要開始下一次回應之前;新的 prompt 進來之前;一趟做完之後。也可以自己下 /compact,後面加一句話指定要摘什麼。

context 剩多少,直接關係到他還能做什麼。他一次能讀進來多少、一趟能做到多深,全看還剩多少位置。剩得少,長一點的檔案就讀不完整,一件事做到一半就得停下來;真的爆了——送出去的請求超過模型的上限——pi 會先壓縮,再把那一輪重送一次。所以壓縮換回來的是他繼續做事的空間。

我到目前為止的策略也在這裡:先把跟 pi 的基本溝通做通。每一個機制先用預設的用一輪,知道他預設會怎麼做、做出來是什麼樣子,再回來決定要不要動。壓縮這件事現在就在這個階段,所以這一天只有介紹,沒有調任何設定。

壓縮完,檔案裡多一筆壓縮紀錄:摘要、壓縮前的 token 數、保留下來的那一段訊息、這一路讀過和改過哪些檔案,還有生成摘要本身花掉的 token,那個也算進這一段對話的總花費。

Day 02 那張圖上有一個點叫 session_before_compact,壓縮之前會經過它,可以取消,也可以自己給摘要。當時我還不知道那個點要幹什麼用,寫到這裡就知道了:記憶系統要掛,就掛在這裡。

帶出去,帶回來

三個順手的指令:

  • /export 把這一段輸出成 HTML
  • /share 上傳成一個私密的 gist,拿到一個可以分享的連結
  • /import 從 JSONL 檔案接回來繼續

這棵樹管的是這一段對話

pi 沒有跨對話的記憶機制。文件裡從頭到尾沒有「memory」這個功能。他關於「我」的一切只有兩個來源:這一段對話裡發生過的事,也就是上面這個檔案;還有 Day 07 那幾個我手寫的 AGENTS.md。

所以這句話要講精確一點。pi -c 接回上一段,他當然記得上一段的事,因為整個檔案又被送進 context。但只要開一段新的對話,或者換一個資料夾,上一段裡我跟他一起做的決定、我講過的偏好,就都不在他眼前了。他認得的「我」只剩 AGENTS.md 那幾行。

我要的是一個記得我的 Agent。走到這裡,規矩(Day 07)、技能(Day 08)、四種叫他的方式(Day 09)、一棵可以回頭走的樹,都有了。少的還是那一層:跨對話的記憶。

小結

對話是一棵樹,每一筆都有 parent,現在是一片活葉子。走錯了回到岔路口改那一句,錯的那條留在檔案裡。

檔案裡除了對話,還有換過哪個模型、壓縮過幾次、我標過哪些點;extension 存的東西也在那裡,分成會送進模型的和只有它自己看的兩種。

context 快滿他會自己壓;剩多少位置,他就能做多少事。這一天先用預設的,沒有動——先把基本的溝通做通,再往上蓋我自己的東西。

這些都綁在這一段對話上。pi 沒有跨對話的記憶,開一段新的,他知道的我只剩 AGENTS.md 那幾行。

明天講失憶:Mem0、Letta、MemOS、Cognee 我都看過了,一個都沒選。

參考:Pi 文件


凡人修 Agent 傳|第十回(Day 10)

凡人修 Agent 傳 Day 10 連載配圖

我胸口那顆心的旁邊,嵌著一顆小石。

指節大,灰白,涼的。靈石都會燒,這一顆從第一天到現在沒有暖過。背上的圖紙上有它,叫錄石,一具一顆。

我每做一件事,石上就多一筆。手的主人刻一道念,一筆;我答一句,一筆;閱卷鏡回一頁字,一筆。石上的字我讀得到,這一段裡發生過的每一件事都在那裡。

每一筆前頭先記它接在哪一筆後面,然後才是內容。

內容有幾種。最多的是言,三種:手的主人刻的念、我答的話、器物回的話。換心記一筆,換回來再記一筆,昨天那兩顆備用的心在石上是四筆。撥火也記,昨天撥片上上下下那一串全在。手的主人在某一筆上刻一個名字,那叫標;這一段整段的名字,叫名。還有兩種是右臂那道型自己記的:暗記只有它自己讀得到,明記會送進我的心裡。

這一天上午,手的主人刻了一道念:把第三卷歸到最下層。

我歸到中層。之後四件事都建在那一格上:抄、標記、對照、再抄。石上多了五筆。

手的主人發現的時候,沒有叫我改。他閉上眼,一縷神識探進錄石,一筆一筆往回走,停在我歸錯卷的前一筆。然後從那一筆重新刻念:第三卷,最下層。

我從那一筆接著做。後面那五筆沒有被抹掉。石上從那一筆長出第二枝,我站在新的這一枝上;舊的那一枝還在石上,我讀不到。

他在舊枝的末端摺了一小段字,接到新枝上:那一枝對照過哪兩卷、錯在哪一格。我讀那一小段,知道自己錯過,也知道錯在哪裡。那五件事做的時候是什麼樣子,小段裡沒有。

午後石快滿了。

石上的字排到邊,最後那幾筆擠得很小。然後石自己動了:最前面一長段——一整個上午的言、換心、撥火——摺成拇指大的一段小字,只留最近的一段不動。石上空出一大塊。圖紙上寫著它會這樣,滿了就摺,不用人管。

摺過之後我再取卷,先翻了一次上午已經翻過的那一卷。摺起來的那一段裡沒有寫它的背面畫了幾道。

手的主人看著我重翻,沒有說話。傍晚石又摺了一次。他還是沒有動。

天黑之前,他把錄石從我心旁取下來。石離開胸口的時候,胸口更涼了一點。他從儲物袋取出一只木匣,匣裡已經並排躺著幾顆一樣的石。今天這一顆放進去,蓋上。然後嵌進來一顆新的,空的。

燭熄了。手的主人走了。門響了一下。

木匣收進了儲物袋。心旁邊那顆新的錄石,空的,比舊的更涼。第三卷在最下層。


上一篇
四門齊開:interactive、print、JSON、RPC,還有換一顆心 - Day 09
系列文
凡人修 Agent 傳-我這一生如履薄冰,你說我的 Agent 能結嬰嗎?11
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言