系列:AI Agent 實戰(1/3)
- 一個對話 turn 背後跑了幾十次「推理 → 工具呼叫 → 把結果塞回 prompt」的迴圈,使用者只看到最終結果。
- 送進 Responses API 的 payload 分三層:Instructions(靜態系統指令)、Tools(JSON schema 工具定義)、Input(對話歷史);靜態內容放最前面才吃得到 prompt cache。
- 讓 agent 能跑很久的關鍵是 context 管理:auto compaction 在逼近上限時把歷史壓成加密摘要,prompt cache 把二次方成長壓成線性。
目錄
大多數人用 Codex CLI 時只看到「輸入一句話,然後 code 就出現了」。但在這個過程中,agent loop 其實已經跑了幾十次推理與工具呼叫。OpenAI 的 Michael Bolin 寫了一篇文章《Unrolling the Codex agent loop》,把這層黑盒子完整攤開。以下是核心內容的整理。
Agent Loop 是什麼
每個 AI agent 的核心都是一個迴圈(loop):
- 收到用戶輸入
- 組建 prompt(包含指令、工具定義、對話歷史)
- 送給模型做推理(inference)
- 模型回傳結果——可能是工具呼叫,也可能是最終回覆
- 如果是工具呼叫:執行工具、把結果附加到 prompt,回到步驟 3
- 如果是最終回覆:loop 結束,等待下一個用戶輸入
Bolin 的重點之一是:agent 的「輸出」不只是 assistant message。對一個 coding agent 而言,真正有價值的輸出是它在本機寫入或修改的程式碼,每個 turn 最後的 assistant message 只是標示「這一輪結束了」的信號。
flowchart TD
A[用戶輸入] --> B[組建 Prompt]
B --> C[模型推理 Inference]
C --> D{回傳類型?}
D -- 工具呼叫 --> E[本機執行工具]
E --> F[把結果附加到 Prompt]
F --> C
D -- 最終回覆 --> G[回傳給用戶]
G --> A
一個「對話 turn」可以包含幾十次 inference-tool 循環,用戶看到的只是最終結果。
Prompt 的三層結構
Codex 送給 Responses API 的 payload 有三個核心欄位:
Instructions:來自 ~/.codex/config.toml 或模型專屬的內建設定檔,是靜態的系統層指令。
Tools:Codex 內建工具(shell 執行、檔案操作)+ Responses API 原生工具 + 用戶透過 MCP 掛載的工具。工具定義是 JSON schema,模型用來決定何時以及如何呼叫工具。
Input:對話歷史,包含 system、developer、user、assistant 角色的訊息,以及當前沙箱權限與專案 context。
API server 收到 payload 後,會重新排列成最終結構:system message → 工具定義 → instructions → input messages。這個順序對 prompt cache 命中率有直接影響(下面會提到)。
Token 如何流動
推理的過程本質上是一個翻譯:
文字 prompt → 輸入 tokens → 模型取樣 → 輸出 tokens → 文字
因為 token 是逐個產生的,輸出可以 streaming 回傳,這就是為什麼 LLM 應用通常會顯示「打字機效果」。每個模型有一個固定的 context window——輸入與輸出 tokens 的總上限,這個限制是 agent loop 設計中最重要的約束之一。
Context Window 管理:自動壓縮(Compaction)
隨著對話變長,累積的 tokens 會逼近 context window 上限。Codex 的解法是自動壓縮(auto compaction):
- 觸發條件:
auto_compact_limit設定值,當 token 用量超過閾值就自動觸發 - 壓縮端點:專用的
/responses/compactendpoint,回傳可以直接替換歷史的摘要 items - 加密保存:壓縮結果以
type=compaction的 item 存在,模型的「潛在理解」被保留,但原始訊息不再佔用 context
這個設計也支援 Zero Data Retention(ZDR) 客戶:因為是無狀態請求模型,伺服器不需要持久化原始對話,而加密的壓縮 item 仍可帶著模型的推理繼續跑。
flowchart LR
A[對話歷史累積] --> B{token 用量 > auto_compact_limit?}
B -- 否 --> C[繼續 loop]
B -- 是 --> D[呼叫 /responses/compact]
D --> E[加密 compaction item]
E --> F["替換歷史,釋放空間"]
F --> C
Prompt Cache 優化
每次 inference 都要送整個 prompt,如果能讓 server 重複使用之前計算過的部分(prompt cache hit),就可以從二次方成長壓到線性成長。Codex 的優化策略:
靜態內容放最前面:instructions、工具定義、沙箱設定這些不變的東西放 prompt 開頭,才能被 cache 住。
MCP 工具排序:MCP server 枚舉工具的順序如果不確定,每次都會不同,導致每個 request 都 cache miss。Codex 透過強制一致的工具排序解決這個問題——這是一個容易被忽略但影響很大的細節。
效果:「儘管 request payload 以二次方速度增長,模型取樣仍可維持線性時間」。
整體來說
Codex agent loop 的設計核心是幾個相互制衡的取捨:
- autonomy vs. safety:IDE 整合允許從「問答模式」到「全自主執行」的連續調節
- stateless vs. continuity:無狀態請求滿足合規需求,加密壓縮保留推理連貫性
- context depth vs. cost:auto compaction 讓長對話可行,prompt cache 讓它負擔得起
對想自己做 coding agent 的人來說,這篇文章最有價值的地方不是「Codex 怎麼實作」,而是這些設計決策背後的原因——context 管理不是可選功能,是讓 agent 能跑超過幾分鐘的必要條件。
參考資料
AI 只根據這篇文章內容回答。點下方任一問題,或直接開右下對話框。
相關標籤
相關文章
RAG 五階段:從流水線到會思考的檢索,以及我站上那個 Naive RAG
RAG 這兩年從『線性流水線』演化到『循環推理』,可以用五階段梳理:Naive、Advanced、Modular、Graph、Agentic。分水嶺是控制權從管線移交給 Agent,範式從 System 1 進到 System 2。回頭看 engineer-news 這個站的實作,其實還卡在 Naive RAG 邊界——這篇順便把它的下一步應該補什麼寫清楚。
想蓋一個能用的 RAG:InfiniFlow 2024 年度總結給我的 5 個 infra 功課
上一篇拉高看 RAG 五階段全景,這篇拉近看實際想蓋一個 RAG 要面對的 5 個 infra 功課:文件入口解析、Chunking 上下文化、三路混合搜尋、Tensor Reranker、GraphRAG 語意鴻溝。每個功課都對照 engineer-news 現況,收尾給出對個人站的優先順序清單。
J-lens:Anthropic 從『全域工作空間』找到 Claude 內在思考的可解釋性新工具
Anthropic 提出 J-lens,一種捕捉 Transformer 內部『可語言化』表示的可解釋性工具,並用它證實 Claude 內部存在類似神經科學『全域工作空間』的特權子空間——一小組向量對外廣播、驅動推理、可被使用者調控,也在欺騙與評估感知時洩漏訊號。