Codex 點樣用加密摘要解決 Compaction 問題
我逆向工程咗 Codex 嘅 context overflow 處理方式。背後涉及 AES 加密、session 交接模式,同埋 KV cache 優化。
用 Claude Code 做過任何認真嘅編程 session,你一定見過呢一幕:終端出現「Compacting conversation…」,之後感覺就唔對晒。十分鐘前討論過嘅嘢,model 開始唔記得。回應延遲爬升。你問起剛剛一齊重構過嘅 function,佢卻答得好似從來冇聽過咁。
呢個情況係因為 Claude Code 嘅 200K token context window 比大多數人預期更快填滿。一次大型重構 session、幾次文件讀取、加上輸出冗長嘅 tool call,你就到上限喇。當去到那個臨界點(大概係 window 嘅 75-92%,不過我見過早至 65% 就觸發),Claude Code 會將對話做摘要、丟掉原始訊息、然後靠個摘要繼續落去。冇進入摘要嘅資訊就永遠消失。
我一直聽聞 OpenAI 嘅 Codex 處理方式有所不同,所以花咗時間翻查所有能搵到嘅公開分析。最有趣嘅係 Krafton CAIO Kangwook Lee 嘅研究——佢用 prompt injection 逆向工程咗整條 pipeline 嘅實際運作。
Compaction 失去乜嘢,點解要緊
核心問題直接了當。摘要係有損壓縮。Claude Code compaction 時,會在後台對整個對話做摘要、建立一個 compaction block、然後捨棄之前所有嘢。CLAUDE.md 文件因為係從磁盤重新讀取所以保得住,但你只喺對話裡講過嘅嘢,除非摘要器有捕捉到,否則都係消失。
Tool call 結果係痛得最深嗰度。當你叫 Claude Code 讀一個文件,完整嘅文件內容就進入 context。當你執行指令,完整輸出就進入 context。呢啲 tool result 往往係對話裡資訊密度最高嘅部分,偏偏係摘要時被壓平嘅對象。一個 500 行嘅文件讀取,變成一句「讀取咗配置文件並留意咗資料庫設定」。具體數值、討論過嘅邊緣情況、你引用嘅行號,全部消失。
我親眼見過呢個情況幾十次。Compaction 之後,我問「之前睇嗰個 helper function 嘅回傳類型係咩?」,得到嘅係個充滿自信但完全錯誤嘅答案。Model 唔係在通常意義上嘅幻覺。佢係從一個根本唔包含我所問內容嘅摘要裡運作。
喺一個長 session 裡做咗 9 次或以上嘅 compaction 之後,問題係複合式惡化。每個摘要將上一個摘要進一步壓縮。Session 初期嘅決策理由徹底侵蝕。到一個 session 進行咗十個小時,model 完全唔記得你點解選擇方案 A 而唔係方案 B,就算你哋花咗二十分鐘討論過取捨。
Codex 嘅加密 Compaction Pipeline 內部
Kangwook Lee 嘅分析好聰明。佢用兩個連鎖嘅 prompt injection 去提取 Codex compaction 系統嘅內部行為。
第一個 injection 針對 compactor LLM 本身。Codex 觸發 compaction 時,唔係只係喺本地做摘要。佢將對話發送畀 OpenAI server 上一個獨立嘅 LLM,呢個 LLM 生成摘要。Lee 嘅 injection 哄騙呢個 compactor 將自己嘅 system prompt 包含喺摘要輸出入面。Server 然後用 AES 加密呢個摘要(此時已包含洩漏嘅 prompt),並以一個不透明嘅 blob 返回。
第二個 injection 利用解密步驟。將加密 blob 加上一個精心設計嘅用戶訊息傳回 Responses API,server 就會解密個 blob 並組裝 model 嘅 context。由於第一個 injection 已將 compactor 嘅 system prompt 嵌入摘要入面,解密後嘅 context 就揭示咗整條 pipeline 係點樣運作。
佢發現嘅係:當你呼叫 Codex 嘅 compact() API,一個獨立 LLM 會摘要對話,結果以 AES 加密返回。下一輪時,server 解密呢個 blob,加上「以下係上次對話嘅摘要」嘅交接 prompt,然後將整個東西餵給 model。加密密鑰喺 OpenAI 嘅 server 上。客戶端從來睇唔到純文字摘要。
Compaction prompt 本身原來同開源 Codex CLI 針對非 Codex model 嘅 compaction template 幾乎一模一樣。Prompt engineering 上冇咩秘密武器。有趣嘅係架構:server 端加密摘要、server 端解密同注入,以及一個客戶端傳遞但無法查閱或修改嘅不透明 blob。
點解要加密?Lee 嘅分析冇給出決定性答案。一個理論係加密 blob 包含嘅不止係文字摘要:tool call 恢復數據、內部狀態標記、或者 OpenAI 唔想公開嘅結構化元數據。另一個可能係加密 blob 單純係防止用戶篡改摘要去操縱 model 嘅行為。我覺得第二個解釋更可能,但兩個都未經確認。
OpenAI 透過 Responses API 亦從 server 端支援呢個功能。設定 compact_threshold 值,當 token 數量超過,server 就內嵌執行 compaction。Compaction item 喺回應裡串流返回,你將佢附加到後續請求。最近一次 compaction item 之前嘅 item 可以安全丟掉。
對比 Claude Code 嘅做法:compaction block 係人類可讀嘅。你可以查閱佢,亦可以透過 instructions 參數或者喺 CLAUDE.md 加入自定義 compaction 指令去客製化 compaction 行為。更透明,但同樣嘅根本資訊流失問題依然存在。
Session 交接模式
拋開 compaction 機制不談,更有趣嘅問題係當你需要開新 session 但又唔想失去 context 時應該點做。呢度我見到一個開發者嘅自動化方案,改變咗我對呢個問題嘅想法。
模式係咁運作。就係喺 compaction 觸發之前,一個 pre-compact hook 封鎖所有 write 工具。呢個做法防止 model 喺半知半覺嘅狀態下修改代碼,係我踩過好多次嘅 failure mode:compaction 喺重構到一半時觸發,model 唔記得自己已經改咗邊啲文件,然後寫出衝突嘅修改。
封鎖寫入後,系統只從 JSONL session log 提取用戶訊息同 thinking block。其他所有嘢(tool call、文件內容、assistant 回應)全部丟掉。呢個做法將 log 削減到原本大小嘅大概 2%。
然後三個 sub-agent 並行運行,各自搜索原始未壓縮嘅 JSONL log,尋找提取步驟遺漏嘅資訊。佢哋搵嘅係缺口:討論過但冇被用戶訊息捕捉嘅架構決策、只出現喺 tool output 嘅錯誤模式、被拒絕方案背後嘅理由。呢啲 agent 將發現整合成一個 resume-prompt.md 文件,包含 session 摘要、gap analysis 結果,以及修改過嘅文件清單。
VS Code 嘅 file watcher 偵測到新嘅 resume-prompt.md 後,開啟一個以佢作為初始 context 嘅全新 session。新 session 開始時,對上一個 session 停係邊有個清晰完整嘅圖像。
報告話 build 效率提升咗 10 倍。呢個數字難以獨立驗證,但架構係說得通嘅。唔係越來越退化嘅一個摘要,而係一個帶有精心策劃、經過 gap 檢查嘅交接文件、全新嘅 context window。
我自己試咗實現一個較簡化嘅版本。Gap analysis 步驟係價值集中嘅地方。冇佢,你只係用不同格式做緊 compaction 本來就做緊嘅嘢。有咗佢,你係主動取回摘要流失咗嘅資訊。我嘅版本只用一個 sub-agent 而唔係三個,結果明顯比原始 compaction 好,但可能冇三 agent 方案咁全面。
KV Cache 作為隱藏嘅成本槓桿
呢個問題有個大多數討論完全忽略嘅性能維度。KV cache(attention 計算嘅 key-value pairs)喺 prompt prefix 相同嘅情況下可以跨請求重用。兩個共享相同開頭 token 嘅請求,對嗰啲 token 跳過重新計算。
數字係顯著嘅。喺一個比較穩定同擾動 system prompt 嘅對照測試裡,穩定 prefix 達到 85% cache hit rate,time-to-first-token 中位數係 953ms。擾動 prefix:0% cache hit,TTFT 2,727ms。每次請求成本從 $0.033 降到 $0.009。單係保持 prompt prefix 一致,就有 65% 延遲降低同 71% 成本降低。
呢個對 session 交接模式有直接影響。如果你嘅 resume-prompt.md 永遠以相同嘅結構 prefix 開頭(system prompt、交接指令、然後係可變內容),固定部分會被 cache 住。新 session 裡每個後續請求都受惠於呢個 cache。如果你將 prefix 結構隨機化或者早早注入可變內容,每次請求都要由頭重新計算。
我設計自己嘅 session 資料夾結構時就係圍繞呢個洞察。以 session ID 為基礎嘅存檔讓交接文件保持有序,而 resume prompt 嘅固定 prefix 慣例意味著每個新 session 嘅頭 40-50K token 都命中 KV cache。用 QMD(我另文介紹過嘅工具)預先索引 session 存檔,當 sub-agent 需要搜索歷史 session 時,檢索步驟更快。
真正重要嘅係乜嘢
真正嘅要點唔係 Codex 嘅方式比 Claude Code 好定差。兩個喺 compaction 時都會流失資訊。兩個都係喺長 session 時有困難。架構上嘅分別(加密不透明 blob 對比人類可讀嘅 compaction block)反映唔同嘅設計哲學,但根本限制係一樣嘅:context window 係有限嘅,摘要係有損嘅。
重要嘅係你圍繞呢個限制建立乜嘢。Session 交接模式、gap analysis、基於 JSONL 嘅檢索、KV cache 優化:呢啲係對一個任何程度嘅 model 改進都唔能夠完全解決嘅問題嘅工程解決方案。500K 或 1M token 嘅 context window 只係延後問題,唔係消除佢。
AI 編程工具嘅樽頸唔係 model 智能,係 context 管理。我親身見過:一個普通摘要配好嘅檢索,每次都勝過一個出色摘要但冇檢索嘅方案。建立能夠可靠取回被遺忘資訊嘅系統,比建立摘要更準確嘅系統更重要。
技術細節來源自 Kangwook Lee 嘅分析,以及 OpenAI 同 Anthropic 嘅公開 API 文檔。
訂閱通訊
獲取最新 AI 洞見。