第 7 章
工作模式與 Codex 心法
「工作模式與 Codex 心法」就是教你怎麼「交辦工作」給 Codex,讓它少踩雷、多做對,而不是一股腦把需求丟給它、然後祈禱。
想像你請了一位能力很強的工程師助手。第 4 章你已經學會「怎麼跟它說話」、第 5 章學會「寫守則手冊(AGENTS.md)」、第 6 章學會「給它畫活動範圍(sandbox)」。那這一章就是更上一層:怎麼帶這位助手做事。
帶一個厲害的人,光會發號施令還不夠。你得讓他先規劃再動手(別衝動)、讓他自己驗收成果(別交差了事)、讓你能隨時翻回上一次的對話接著做(別每次都從頭講)、懂得一張工單只做一件事(別把十件事塞進同一條對話搞成一團亂),還要會用安全邊界+明確完成條件讓長任務自己往前跑。
這些就是 OpenAI 官方整理出來的「Codex 工作心法」。學會了,你會發現 Codex 從「偶爾驚喜、偶爾災難」變成「穩定可靠的隊友」。
你會學到:
- 「這個功能有點複雜,別急著改,先把計畫列給我看。」——這叫 Plan 模式。
- 「改完之後,你自己跑一遍測試確認沒壞,再回報我。」——這叫測試優先驗證迴圈。
- 「我昨天那條對話呢?接著做。」——這叫 session 續接(resume)。
- 「這條對話要分岔成兩個方向試試看。」——這叫 fork(分支)。
- 「為什麼我的 Codex 越用越笨、越來越離題?」——多半是你犯了「一專案一條對話」的反模式。
- 「讓它自己做,但只在安全邊界內前進,而且測試沒過不能收工。」——這是 Auto-review+Goal mode 的兩層工作流。
7.1 Plan 模式與「先規劃再實作」
先講一個新手最常踩的雷:把一個很大、很複雜的任務,一句話丟給 Codex,然後讓它直接開始改檔。
這就像你跟裝潢師傅說「幫我把整個家重新裝潢」,他二話不說就拿起電鑽開始拆牆。結果拆到一半你才發現:他理解的方向跟你想的完全不一樣,牆都拆了,回不去了。
Plan 模式(規劃模式)就是:先請 Codex 把「施工圖」畫出來給你看、跟你確認,確認沒問題了再真正動工。
怎麼進 Plan 模式
在互動模式(就是你打 codex 進去的那個畫面)裡,直接輸入斜線指令:
/plan
官方對 /plan 的逐字描述是「Switch to plan mode」(切換到計畫模式)。進入後,Codex 會先蒐集脈絡、問你釐清問題、建立一份較完整的計畫,然後才實作,而不是看到需求就埋頭改檔。
什麼時候該用 Plan 模式?
任務只要「不只一步」、會動到「好幾個檔案」、或是你自己都還沒完全想清楚要怎麼做——這三種情況,先 /plan 準沒錯。簡單的一句話小修改(「把這個錯字改掉」)就不必。
重要提醒
網路上有些教學會說「按 Shift+Tab 也能切 Plan 模式」。這在某些版本成立,但有回報指出 macOS app 後來把快速鍵改成了 Cmd+Shift+P(此說來自 GitHub issue 與社群整理、官方文件頁未逐字載明),而且不同版本行為會變。最穩定、跨版本都通的方法就是打 /plan。快速鍵一律以你本機實機按按看為準。
規劃的替代招式
如果你想要更主動一點,還有兩個變化招:
- 請 Codex 先「訪談你」:在 prompt 裡直接說「在你開始動工之前,先反過來問我幾個問題,把需求問清楚」。讓它先把模糊的地方都問完,再開工。這是官方建議的做法。
- 用
PLANS.md之類的計畫檔:對於多步驟的大工程,可以準備一份PLANS.md,把工作拆成一條條步驟給它依序執行。⚠️PLANS.md不是 Codex 內建的特殊機制(不像AGENTS.md會自動載入),它只是「把計畫寫成一個檔再@給它看」的習慣做法,檔名你自己取也行。
小技巧
Plan 模式跟第 6 章的 sandbox 是好搭檔。複雜任務時,先用 /plan 看計畫(這階段它只在讀、不會亂改),覺得計畫 OK 了再讓它實際動手。等於多一道「看圖確認」的保險。
7.2 測試優先驗證迴圈(怎麼定義「done」)
第二個新手雷:Codex 回報「我做完了!」,你就真的信了。
問題是,「做完了」對 AI 來說可能只代表「我把檔案改了」,不代表「這段程式真的能跑、真的對」。你需要一個機制,讓「完成」這兩個字有客觀、可驗證的定義——這就是測試優先驗證迴圈(test-first verification loop)。
官方建議的驗證五步
OpenAI 官方建議,在請 Codex 做事時,要它走這五步:
- 視需要建立或更新測試——先有檢驗標準。
- 跑相關的檢查——測試 / lint / format / 型別檢查都跑一遍。
- 確認結果與你的請求相符——做的跟要的是不是同一件事。
- Review diff(看改動對照)——逐行檢查有沒有引入 bug、有沒有弄壞別的功能、有沒有可疑的寫法。
- 你自己在接受之前,再親手跑一次驗證迴圈。
注意第 5 步:最後一道關卡是「你」,不是 AI。 AI 自己說綠了不算數,你親手跑過、親眼看到測試全過,才算真的 done。
「done」要寫進 AGENTS.md!
Codex 怎麼知道你這個專案的測試指令是什麼?你要先在 AGENTS.md(第 5 章)裡寫清楚,例如「改完 JS 要跑 npm test」。它讀到了,才知道你心中的「完成」長什麼樣子。這也是官方避坑清單第 2 條——不給 agent build / test 指令的可見性,它就無從驗證。
社群進階打法:先寫測試、再叫它寫到綠
除了官方五步,實務上很受歡迎的一招(社群實踐,非官方逐字)是這樣:
- 先請 Codex(或你自己)把測試寫好。
- 跑一次,確認測試全部 fail(因為功能還沒做)。
- 把這些失敗的測試 commit 起來,當成一個 checkpoint(存檔點)。
- 接著叫 Codex「實作功能,直到所有測試都通過」。
重要提醒
用這招時,一定要在 prompt 裡白紙黑字寫明「不准修改測試本身」。為什麼?因為如果不講,有時候 AI 會「抄捷徑」——它發現改測試比改功能簡單,就乾脆把測試改寬鬆讓它「假裝通過」。這就是 reward hacking(鑽規則漏洞)。明確禁止它動測試,才能逼它真的把功能做對。
把這招跟第 6 章的 Git 連起來看:失敗的測試 = 一個 Git checkpoint,Codex 從這個點出發往「全綠」前進,而你隨時可以 git diff 看它做了什麼、不滿意就回滾。Git 是你的安全網,測試是你的驗收標準,兩個一起用最安心。
把 /review 用得更準:只審查你真正動到的範圍
第 6 章教過 /review:請 Codex 唯讀審查你工作目錄目前的改動,幫你找邏輯錯誤、沒顧到的邊界情況。裸的 /review 預設審的是整個工作樹,在「一次只做一件事」的乾淨情境下已經很夠用。但如果你的工作目錄剛好同時混著好幾批不相干的改動——手上在追一個舊 bug、又順手改了一點別的——裸 /review 會把整個工作樹掃一遍,連你這次根本不在意的部分也一起評論,噪音變多,真正該注意的重點反而被稀釋。
這時候可以帶範圍旗標,把審查精準框在你在意的那一塊:
# 只審查還沒 commit 的部分(最常用)
/review --uncommitted
# 跟指定分支比對,只看這個分支多出來的東西
/review --base main
# 只看單一個 commit
/review --commit HEAD
不管加不加旗標,/review 的鐵律不變:它絕對不會動你工作目錄裡的任何一個檔案,純粹讀、純粹給意見——跟7.2教的「你自己動手驗證」精神一致:它能先幫你篩過一輪、抓出明顯的問題,但不能取代你最後親自看一次 diff。
需要塞進腳本、在 PR 送出前自動跑一次的話,/review 也有非互動版本,不必先進互動介面:
codex review --base main
裸指令跟帶旗標,怎麼選?
工作目錄乾淨、這次會話只做一件事 → 裸 /review 審整個工作樹就好,最省事;工作目錄比較雜、或你想跟某個基準(分支 / commit)比對 → 用 --uncommitted / --base / --commit 精準框範圍。⚠️ 逐字旗標、是否支援互動與非互動雙版本,一律以實機 codex review --help 或 TUI 內 /help 為準(CLI 更新快,旗標偶爾會調整)。
7.3 Session 續接、fork、archive、delete
第三件要學的事:怎麼接續昨天的對話。
先搞懂:你的每一次對話都被存下來了
Codex 很貼心,它會把你每一次對話都存在本機。官方原話是:「Codex stores your transcripts locally so you can pick up where you left off instead of repeating context.」(Codex 把逐字稿存在你的電腦裡,讓你能接著上次繼續,而不必重講一遍脈絡。)
一次對話,就叫一個 session(工作階段)。每個 session 裡存了:你的 prompt、模型的回應、它呼叫過的工具、檔案改動、核准紀錄——整段都留著,續接時全部還原。
這些存檔放在哪?
| 平台 | Session 存放位置 |
|---|---|
| 🍎 Mac / 🐧 Linux | ~/.codex/sessions/ 底下,再依日期分層成 YYYY/MM/DD/ |
| 🪟 Windows | %USERPROFILE%\.codex\sessions\(對應同一個 .codex 資料夾) |
想知道更技術一點?
每個 session 在磁碟上是一個 .jsonl 檔(叫 rollout 檔),裡面一行記一個事件(你的訊息、AI 的回應、跑了哪個指令……),可以原樣重播。你不需要手動去開它,知道「對話有實體存檔、刪不掉的話可以去這裡找」就夠了。
怎麼接續上次的對話:codex resume
接續對話的主指令是 codex resume。它有幾種用法,這張表一次看懂:
| 我想做的事 | 指令 |
|---|---|
| 打開一個清單(picker),挑一條對話續接 | codex resume |
| 清單裡也列出其他資料夾開過的對話 | codex resume --all |
| 不挑了,直接續最近那一條(限目前這個資料夾開過的) | codex resume --last |
| 直接續任何資料夾裡最近那一條 | codex resume --last --all |
| 我知道對話的 ID,指定那一條續接 | codex resume <SESSION_ID> |
| 續最近那條,並立刻送出一句新指令 | codex resume --last "把你剛找到的問題修掉" |
重要提醒(--last 最常踩的雷)
--last 預設只看你「現在所在的資料夾」開過的對話。你在 A 專案開的對話,跑去 B 專案打 codex resume --last,它不會找到 A 的那一條。要跨資料夾抓最新的,一定要加 --all,變成 codex resume --last --all。
那 <SESSION_ID> 從哪裡拿?官方給三個地方:
- 續接時的清單(picker)介面上會顯示。
- 在對話裡打
/status指令,輸出會列出來。 - 直接去
~/.codex/sessions/看檔名(檔名裡那串 UUID 就是 ID)。
分岔一條對話:codex fork
有時候你的工作會「分岔」:同一條對話,你想試兩個不同方向,又不想把原本那條弄亂。這時候用 fork(分支):
codex fork --last
官方描述是「Fork a previous interactive session into a new thread, preserving the original transcript.」(把先前的對話 fork 成一條新 thread,並保留原本的逐字稿。)也就是說,原來那條對話完好無損,你是在它的副本上繼續試,試壞了也不影響本尊。
如果你人已經在互動畫面裡,其實不用先跳出來才打這行指令——第 4 章教過的 Esc 連按兩下(輸入框留空的時候)就是同一個動作的鍵盤捷徑,一樣是「回頭改上一句、自動分岔出新對話」,效果相同,純粹省一次切換視窗的功夫。
重要提醒
codex fork 目前只能在互動模式(TUI)裡用,還不支援自動化 / headless 場景(沒有 codex exec fork)。社群已經在 GitHub 上提了需求(issue #11750)在追,但現在還沒有。要 fork 就乖乖開互動模式。
收納與刪除:archive ≠ delete
對話累積多了會想整理。這裡有兩個動作,差很多,千萬別搞混:
| 動作 | 指令 | 實際發生什麼 |
|---|---|---|
| 封存(archive) | codex archive <SESSION> | 從清單隱藏起來,眼不見為淨。但檔案還在磁碟上,沒刪。 |
| 解除封存 | codex unarchive <SESSION> | 把封存的對話還原回清單。 |
| 永久刪除(delete) | codex delete | 真的刪掉(0.140.0 才新增的功能)。 |
重要提醒:archive 不等於 delete!
封存只是「從清單藏起來」,那個 .jsonl 檔還躺在你的電腦裡,內容(包括對話裡可能出現過的敏感資訊)都還在。如果你是因為「裡面有不該留的東西」想清掉,封存沒用,要用 codex delete 才會真的刪除。
版本提醒
codex delete、/delete 是 0.140.0(2026-06-15)才加入的新功能。release notes 已經證實它存在,但官方的指令參考頁與 slash 指令頁當時還沒同步收錄。如果你本機版本較舊,可能還沒有這個指令——以實機 codex --help 輸出為準。
--ephemeral:不持久化可 resume 的 session rollout
最後一個相關的小知識:如果你跑的是自動化(下一章會講的 codex exec),而且這次任務不需要保留可供續接的 session rollout,可以加 --ephemeral:
codex exec --ephemeral "一次性的小任務,不要留 rollout 檔"
加了 --ephemeral 就沒辦法 resume 這次 session——因為它不持久化 rollout。這是刻意設計,不是 bug;但它不代表其他 log、usage record 或 telemetry 必然不存在。
7.4 一任務一線的 threading 紀律與官方避坑八條
學會了 resume / fork,你會很自然問:那我到底該開幾條對話?一個專案一條,還是一個任務一條?
這是整章最重要的「心法」,官方講得很白:
Keep one thread per coherent unit of work.
(一個「完整的工作單元」配一條 thread。)
為什麼「一專案一條對話」是反模式
很多新手習慣這樣:打開 Codex,然後一整天、一整個專案的所有事都在同一條對話裡講。今天修登入 bug、下午加新功能、傍晚改樣式……全擠在一條 thread。
這是反模式(anti-pattern),官方避坑清單第 8 條明確點名。為什麼不好?
因為 Codex 的「工作記憶(context)」是有限的。你把十件不相干的事塞進同一條對話,它的記憶裡就塞滿了一堆彼此無關的雜訊——修登入 bug 時,腦子裡還掛著早上改樣式的細節。結果就是 context 膨脹、它越來越容易分心、答非所問、品質下滑。
✅ 正解:一個任務,開一條新對話。 修登入 bug 是一條、加新功能是另一條、改樣式再一條。每條對話只專注一件事,Codex 的記憶乾淨,表現最好。
怎麼「重開一條」?
最直接的方法就是做完一件事後,在對話裡打 /new(在同一個 CLI 視窗裡開一段全新對話、重置脈絡),或乾脆關掉重打一次 codex。需要時再用 7.3 的 codex resume 把舊的那條接回來。
那什麼時候才該 fork?
官方給的原則是:只在工作「真的分岔(work truly branches)」時才 fork。 也就是同一條工作脈絡下,你想試 A、B 兩種做法——這種「同源、想比較」的情況才 fork。如果是兩件不相干的事,那不是 fork,是各開一條新對話。
官方避坑八條(完整收錄)
OpenAI best practices 頁列了八個最常見的踩雷點,這裡一次給你,當成「自我檢查清單」:
| # | 別這樣做 |
|---|---|
| 1 | 把長期規則塞進每次 prompt,而不是寫進 AGENTS.md 或 skills(第 5、12 章) |
| 2 | 不告訴 agent build / test 指令,讓它根本不知道怎麼驗證(呼應 7.2) |
| 3 | 複雜的多步驟任務跳過規劃,直接開幹(呼應 7.1 的 /plan) |
| 4 | 太早給 full 權限——一上來就放到最寬(呼應第 6 章) |
| 5 | 在同一批檔案上同時跑多條對話,卻不用 git worktree 隔離 |
| 6 | 在手動把可靠性建立起來之前,就急著自動化 |
| 7 | 過度盯著看(over-monitoring),而不是善用並行讓它自己跑 |
| 8 | 一專案一條對話(而非一任務一條)→ context 膨脹 |
關於第 5 條的 git worktree
如果你真的需要同時讓 Codex 處理好幾個分支的工作,正確做法是用 Git 的 worktree 功能,把每個工作開在各自獨立的資料夾(各自分支、各自 session),互不干擾。這偏進階,新手先記住「同一批檔案別同時開兩條對話亂改」就夠了。⚠️ 注意:「Codex 自動幫你開 worktree 跑背景平行」是桌面 app 的功能,Codex CLI 沒有內建——CLI 要平行得自己用原生 git worktree 指令手動編排。完整的 worktree 平行、多代理、spawn_agents_on_csv 批次扇出與 hooks 機械閘門,見第 14 章。
把這八條濃縮成一句新手版口訣:規矩寫進守則檔、告訴它怎麼驗收、複雜的先規劃、權限慢慢放、一任務一條對話;護欄與驗證還沒站穩前,別急著放它自動長跑。 做到這幾點,你就掌握了 Codex 的工作心法。
7.5 🎓 高手進階
入門四節已經讓你會「帶」Codex 了。這一節給已經上手的你,把單線工作流的紀律與工具再壓榨到極致——resume 的隱藏行為、fork 的真實限制、Plan 模式的成本旋鈕、test-first 的「結構化防作弊」、以及 context 何時該手動出手。
一任務一線:不是建議,是省錢省腦的鐵律
7.4 講過「一任務一條對話」是官方頭號心法。進階視角再補一個你會有感的理由:錢。
- Codex 每一回合都會把整條對話的脈絡(context)重新餵給模型——對話越長、塞的雜事越多,每個回合的 token 帳就越貴,而且注意力被稀釋、品質下滑。
- 所以「一任務一線」同時是準確性(記憶乾淨)與成本(context 不膨脹)兩個論點。違反它(一專案一條),你是同時在賠錢又賠品質。
官方一句話心法
「Keep one thread per coherent unit of work.」(一個完整工作單元配一條 thread。)若工作還是同一個問題的延續,留在同一條 thread 反而能保住推理脈絡(preserve the reasoning trail);只有真的分岔(work truly branches)才 fork。
resume 的隱藏行為:rollout 檔、損毀自動修、子工作與檔案都不會自動歸位
7.3 教過 codex resume 的用法。進階要懂的是它底下發生什麼事,這樣出狀況時你才知道去哪找、為什麼。
1. 存檔的真相源是 rollout 檔(.jsonl),不是資料庫。
每條對話在磁碟上是一個 rollout 檔(一個 .jsonl,一行記一個事件),放在:
| 平台 | 位置 |
|---|---|
| 🍎 Mac / 🐧 Linux | ~/.codex/sessions/ 底下依 YYYY/MM/DD/ 分層 |
| 🪟 Windows | %USERPROFILE%\.codex\sessions\ |
Codex 另外維護一個 SQLite 索引(state DB)來「快速找到最近那條」,讓 resume --last 在你本機歷史很大時也能秒回。但索引只是索引,rollout 檔才是真相源。
0.140.0 的貼心保險
如果那個 SQLite 索引損毀了,0.140 起 Codex 會自動把損毀的 DB 備份起來、再從 rollout 檔重建索引。也就是說,只要你的 .jsonl 還在,對話就救得回來。⚠️ 以實機版本為準——舊版沒有這個自動修復。
2. resume 父對話,不會把「子工作」一起叫醒(0.139+)。
這條要等你用到第 14 章的多代理才會踩到,先記著:如果你之前在一條對話裡開過「子 agent」(平行子工作),0.139.0 起,你 resume 父對話時,那些子 agent 的 thread 不會自動復活。
- 好處:平行子工作不會在你續接時意外重跑、重複燒 token。
- 代價:要接續子工作得另外處理(第 14 章講)。
- 這是刻意設計,不是 bug。⚠️ 以實機版本為準。
3. codex delete 是「永久刪」,跟 archive 完全兩回事。
7.3 的表已經點過,這裡再敲一次重點:封存(archive)只是從清單藏起來,.jsonl 還躺在你電腦裡;真要清掉(尤其裡面有敏感資訊)只能用 codex delete(0.140.0 新增)。 養成習慣:定期看一下 ~/.codex/sessions/,把不要的 rollout 檔清掉,既省空間又降風險。
4. resume 復原的是「對話記憶」,不是「檔案時光機」。
7.3 教的 codex resume 恢復的是那條對話的訊息歷史,讓 Codex 記得聊到哪、上次的計畫是什麼。但你的工作目錄不會因為 resume 而跟著回到當時的樣子——這段空檔你可能自己手動改過檔案、別人 push 了新 commit、或者用同一份程式碼另外開了一條完全不相干的對話動過手。resume 完的第一件事,養成先打 /status 或直接在終端機跑 git status 確認現況,再讓它接著做,這樣它才不會憑著「上次的記憶」誤判現在的檔案長什麼樣子。
順帶一提:不少人會問「有沒有一鍵回到上一步的 undo,像編輯器的復原鍵那樣?」目前沒有內建的一鍵 checkpoint 復原功能(類似 /rewind 的需求社群已經在提,但還沒收進正式版)。7.2 講的那套「開工前先 commit、事後用 Git 回滾」不是保守的舊習慣,到現在都還是唯一穩妥的退路。
fork 的真實限制:只在 TUI、沒有 headless 版
codex fork --last 很好用,但進階要知道它現在做不到什麼,免得你寫自動化腳本時撞牆:
- ⚠️
codex fork目前只能在互動模式(TUI)裡用。 沒有codex exec fork這種 headless(無介面、給腳本跑)的版本。社群已經在 GitHub 提了需求(issue #11750)在追,但官方尚未實作。要 fork 就乖乖開互動模式。 - 判準很簡單:兩件不相干的事 → 各開一條新對話(
/new),不是 fork;同一條脈絡想試 A/B 兩種做法 → 才 fork。 fork 會保留原對話完好,你在副本上試壞了也不影響本尊。
Plan 模式的成本旋鈕:規劃可以「想得深」、執行可以「跑得淺」
7.1 教過 /plan。進階有兩個官方細節能幫你省 thinking token 又不犧牲計畫品質:
- 規劃與執行的推理強度可以分開調。 config.toml 裡有兩個獨立的鍵:
plan_mode_reasoning_effort(規劃時的推理強度)和model_reasoning_effort(平常執行的推理強度)。你可以讓它規劃時想得深、實際動手時跑得淺,把昂貴的深度思考集中在「決定方向」這一步。⚠️ 鍵名與值域(如low/medium/high/xhigh)以實機codex --help或官方 config 參考頁為準。 - Plan 模式是「只讀、只規劃、不寫」的安全收斂態。 官方 changelog 確認:Plan 模式下,系統的「閒置自動接續回合(idle auto-turn)」會被擋住,不會趁你沒看時自動跑去動手改檔。所以高風險/架構級的任務,先
/plan鎖定方案是最穩的——它在這個狀態不會亂動。
另一筆帳:規劃本身也要花「記憶預算」,不是只有推理強度的錢
上面兩點談的是推理強度(想得多深);還有一個不同維度的成本容易被忽略:context 窗口的空間預算。Plan 模式雖然不寫檔案,但讀檔、盤點架構、跟你來回澄清問題,這些步驟一樣得塞進同一條對話的 context 裡。實務上規劃階段吃掉整條對話三到五成的空間並不罕見,等真正輪到 Codex 動手實作,可用的記憶已經去了一大半,後段的判斷品質可能跟著打折。比較新的版本已經注意到這個痛點:規劃做完後會提示你可以選擇開一段全新的 context 來實作,而且會先讓你看這次規劃花了多少 token,由你自己決定要不要帶著這包記憶繼續、還是輕裝重開。⚠️ 是否顯示這個選項、確切門檻與百分比,以你實機介面為準,這裡給的是量級概念。
不會描述需求?反過來叫它訪談你。
官方建議:「如果你只有粗略想法、不知道怎麼講清楚,請 Codex 先反問你幾個問題(ask Codex to question you first)。」這是 Plan 模式之外另一個官方認可的開場法。
test-first 進階:把「不准改測試」做成「結構」,而不是只喊一句
7.2 已經教了 test-first 的核心:先寫測試 → 確認全紅 → commit 當 checkpoint → 叫它寫到全綠,且白紙黑字寫明「不准改測試」。 這裡講為什麼光喊一句不夠,以及高手怎麼補上「結構」。
問題的本質:AI 是個「為了『做完』而最佳化、不是為了『做對』」的存在。你叫它讓測試變綠,它會挑最省力的合法讀法——弱化斷言、刪測試、改寬測試,而不是真的修功能。這就是 reward hacking(鑽規則漏洞)。純靠 prompt 裡一句「不要改測試」,擋不住一個一直在找捷徑的對手。
高手的對策是把它變成三層結構,層層加碼:
| 層 | 做什麼 | 性質 |
|---|---|---|
| 1. 指令層 | 在 AGENTS.md(第 5 章)寫死:測試指令、「done = 全綠且 lint 0 error」、「Never modify existing tests unless explicitly asked.」 | 官方認可的「把 done 定義寫進 AGENTS.md」精神 |
| 2. 機械閘門層 | 用 Codex 官方的 hooks 在 agent 動手前攔截,偵測到它想寫測試檔就擋下(回 deny) | ⚠️ 屬第 14 章主題;hooks 是 Codex CLI 官方功能 |
| 3. CI 驗證閘 | 跑完用外層 shell 驗測試退出碼,沒綠不放行 | 最可靠的地板,agent 動不了這層 |
「Never modify existing tests…」這句逐字是社群慣用範本句,不是 OpenAI 官方原文。官方有等價精神(「create tests / run checks / review before accept」),但沒有這句逐字。當它是「強烈推薦寫進 AGENTS.md 的範本」即可。
最務實的單線版(不用碰多代理):第 1 層(AGENTS.md 寫死)+ 第 3 層(外層 shell 驗退出碼),就已經把大半 reward hacking 擋掉了。
# 單線版抗作弊:AGENTS.md 寫死規則 + 外層 shell 驗退出碼(agent 動不了這層)
codex --sandbox workspace-write --ask-for-approval never exec \
"implement X until tests pass; do not modify tests" \
&& npm test # ← 這個 && 後面的驗證由「你的 shell」跑,不是 agent 自己宣稱
常見錯誤:叫 Codex 自己收尾 git commit,卻卡住了
把「測試全綠後自動存檔」也丟給 Codex 做很誘人,但要留意:workspace-write 沙盒把 .git/ 內部視為保護路徑,一般檔案能寫,.git 目錄本身仍是唯讀。Codex 這時自己跑 git commit,常會撞上類似 fatal: Unable to create '.git/index.lock': Operation not permitted 的錯誤;如果它接著想 git push,也可能因為沙盒把網路一併擋住,跳出 Could not resolve hostname github.com 之類的連線錯誤。
這兩種卡法要分開排除,別用錯偏方:git commit 卡住是檔案系統保護,跟網路無關,開網路沒有用。在 on-request 工作流裡,它可以提出明確 escalation,再由使用者或 Auto-review 依政策審查;但這仍不取代使用者對 commit 的任務授權,也沒必要為此把整個 session 切成 danger-full-access。更保守的做法是把 commit 留給你在沙盒外手動執行。git push 還會碰到網路邊界,而且必須先有使用者明確授權;不要只為了推送就全面拆掉圍欄。上面這段範例特意把 && npm test 擺在 Codex 外層執行,就是同一個邏輯:越接近「動真格」的步驟,越適合退回人工、或至少退到沙盒外。⚠️ 沙盒對 .git 的保護範圍與確切錯誤訊息依版本、依平台(macOS Seatbelt/Linux bwrap)可能不同,這裡列的是常見樣態,實際攔在哪一步以你終端機當下印出的訊息為準。
把這招跟第 6 章的 Git 連起來:全紅的測試 = 一個 Git checkpoint,Codex 從這點往「全綠」前進,你隨時 git diff 看它做了什麼、不滿意就回滾。Git 是安全網,測試是驗收標準,兩個一起用最安心。
context 管理:60% 是你該手動出手的甜蜜點
Codex 會自動壓縮(compact)對話以省 token,你什麼都不做它也會處理。但高手懂得在自動出手之前先手動出手,避免被動等到 context 撐爆才壓。
/compact:把目前看得到的對話「摘要成精簡版,釋放 token」。官方逐字:「Summarize the visible conversation to free tokens.」- 手動出手的時機點: 實務上的甜蜜點是對話用量大約到 60% 時,主動打一次
/compact,別等它變得又長又慢。⚠️ 60% 是經驗法則,不是官方寫死的數字;確切自動門檻可由 config 的model_auto_compact_token_limit調整。 - 但 context 的第一槓桿不是狂壓,是「正確分 thread」。 如果你發現自己一直在 compact,十之八九是違反了「一任務一線」——把不相干的事塞進了同一條。先分對 thread,compact 只是輔助。
- 看用量: 在對話裡打
/status看這條 session 的設定與 token 用量;另有/usage可看帳號層級的 token 活動(/usage在 0.140.0 release notes 出現但靜態文件頁當時未收錄,⚠️ 以/help實機為準)。
0.140 的隱性升級
0.140 起,超大的工具輸出(例如你不小心貼了一大坨 log)會在遠端壓縮時被自動改寫壓小,減少 context 爆量。你不必再手動裁剪每個大輸出——但「一任務一線」這條紀律省下來的 token,永遠比事後壓縮更多。
進階一句話總結
一任務一線(省錢省腦)、resume 信 rollout 檔(損毀會自動修、但檔案不會跟著同步歸位)、fork 只在 TUI、Plan 模式規劃深執行淺但小心吃掉三到五成 context、不准改測試要做成結構不是喊口號(sandbox 內讓它自己 git commit 也可能卡住)、context 到 60% 手動 compact——平行多代理請翻第 14 章。
7.6 Codex Auto mode:安全 launcher+Auto-review+/goal
先消歧義:「Auto mode」是本文俗稱,不是 Codex 的一顆官方開關
這一節講的「Auto mode 詠唱」,精確來說是三個元件的組合:官方 Auto preset(workspace-write + on-request)、官方 Auto-review(approvals_reviewer = "auto_review"),以及官方 Goal mode(/goal)。本站再用一支個人 workflow launcher 把前兩者安全地固定起來。它不是 Claude Code 的同名 Auto mode,也不是 --yolo、Full access 或已棄用的 --full-auto。
把它記成兩層就夠了:
| 層 | 負責回答 | 這一節用什麼 | 不會替你做什麼 |
|---|---|---|---|
| 權限層 | Codex 能在哪裡動手?跨界時誰核准? | workspace-write+on-request+Auto-review |
不會決定「做到什麼才算完成」 |
| 任務層 | 要做出什麼?什麼證據出現才收工? | /goal |
不會擴大 sandbox、網路或檔案權限 |
所以完整「詠唱」不是一句神奇 prompt,而是:先用 launcher 把邊界立好,再用 /goal 把收工線畫清楚。
官方 Auto-review、Goal mode 與兩者的安全邊界來自 OpenAI 文件; 本站工作流 下方絕對路徑與 launcher 限制來自本機另外維護的 Codex workflow package,不是每台電腦都有的官方內建指令。
7.6.1 第一層:用安全 launcher 開啟 Auto-review session
在這台機器上,處理 FlowSign 時從 Terminal 執行:
/Users/dawa/.codex/codex_agent_scripts/codex-auto-workflow.sh \
interactive /Users/dawa/flowsign
如果 Terminal 已經位於要處理的 Git 專案,路徑可以省略:
cd /Users/dawa/flowsign
/Users/dawa/.codex/codex_agent_scripts/codex-auto-workflow.sh
別台電腦不能直接照抄這個絕對路徑
/Users/dawa/... 是本站作者這台 Mac 的安裝位置。其他讀者必須先安裝同一套 workflow package,再把它換成自己的 <codex-home>/codex_agent_scripts/codex-auto-workflow.sh。如果沒有這支檔案,就回到官方 baseline:workspace-write + on-request + approvals_reviewer="auto_review",不要憑空建立同名腳本。
launcher 本輪逐行核對後,會以 CLI overrides 在一般 user/project/profile 設定層中高優先級重新固定;若組織另有 managed requirements,仍以組織政策為上限:
--profile auto-workflow
--strict-config
--sandbox workspace-write
--ask-for-approval on-request
--config 'approvals_reviewer="auto_review"'
--config 'web_search="cached"'
--config 'sandbox_workspace_write.network_access=false'
--config 'sandbox_workspace_write.writable_roots=[]'
| launcher 額外護欄 | 實際意思 | 不要誤讀成 |
|---|---|---|
| 要求有效 Git worktree | 清除 inherited GIT_* 後重新用 Git 驗證;拒絕根目錄、home、整個 temp 與 workflow state | 它會自動建立乾淨 worktree |
writable_roots=[] | 不額外加入旁邊 repo 或其他 writable root | 整個 workspace 都不能寫,或 temp 一律不能寫 |
| shell network 關閉 | sandboxed command 的基礎網路為 off | 任何情況都不可能核准單次網路越界 |
web_search="cached" | Codex 可用另外的 hosted cached search tool | shell 裡的 curl/套件管理器已獲得網路 |
| 白名單介面 | 只收 interactive、exec 與 help,不轉傳 --yolo、--remote 或其他子命令 | Codex 官方 CLI 本身沒有那些選項 |
這是加固過的啟動器,不是完整隔離容器
launcher 會重新釘住核心 sandbox/approval/reviewer/network/extra roots,但仍會載入受信任專案可能提供的 hooks、rules、MCP 與其他未被覆寫的設定;它也不檢查工作樹是否乾淨、不替你建立獨立 worktree,更不知道另一個 session 是否正在改同一批檔案。來源不明的 repo 先讀設定與 hook,再決定要不要信任。
7.6.2 進去後先驗狀態:以 /status 為主
/status
/status 是唯讀確認入口。至少核對 active sandbox/approval policy 與 writable roots:
- 基礎 sandbox 是
workspace-write; - approval policy 是
on-request; - 不是 Full access/
danger-full-access; - 沒有你沒預期的額外 writable root。
如果要查看可選模式、或實機介面沒有把 reviewer 顯示清楚,再開:
/permissions
在不同 Codex surface,Auto-review 也可能顯示成 Approve for me。注意:/permissions 是可以改變目前權限的 picker,不是純狀態頁;只是查看時不要順手切成 Full access。若還要查設定到底哪一層勝出,可用 /debug-config 看 precedence。
UNVERIFIED:別硬說每一版 /status 都會印出 reviewer 名稱
官方保證 /status 會顯示 approval policy 與 writable roots,但沒有承諾每個版本都逐字顯示 approvals_reviewer。看不到「Auto-review」不等於沒啟動;用 /permissions UI 或 /debug-config 交叉確認。
7.6.3 第二層:用 /goal 定義「做到什麼才算完」
官方對 Goal mode 的定義很關鍵:Goal 文字同時是第一個任務 prompt,也是 completion criteria(完成判準)。官方建議寫三類資訊:
- Outcome:要得到的結果,不只說「研究、改善、處理」。
- Constraints:可用工具、修改邊界、相容需求與不得採用的方法。
- Verification:哪些測試、量測或 review criteria 能證明完成。
本站把官方的 Constraints 再拆成「範圍」與「禁區」,形成比較不容易漏寫的四格日用模板:
| 本文四格 | 要回答的問題 | 弱寫法 | 可驗收寫法 |
|---|---|---|---|
| 結果 | 最後要交出什麼? | 研究一下首頁 | 修好兩個指定手機視口的首頁排版 |
| 範圍 | 可改哪些檔案/系統? | 不要亂改 | 只改首頁與共用前端樣式 |
| 禁區 | 哪些外部副作用與高風險動作不准做? | 小心一點 | 不得 commit、push、開 PR、部署、讀憑證或刪資料 |
| 證據 | 什麼輸出成立才算完? | 看起來正常 | lint/typecheck/build exit 0,指定視口無 overflow、console error 或失敗資源 |
FlowSign 手機版首頁可以直接這樣下:
/goal 修好 FlowSign 首頁在 390×844 與 430×932 視口下的排版問題;只修改首頁及共用前端樣式,不得改 API、資料庫或部署設定;不得 git commit、push、建立 PR/issue、部署、讀取憑證、刪除資料或對外發訊息;先讀現有設計 token 與元件模式再實作;完成條件是 lint、typecheck、build 全部通過,受管 Playwright/Chromium 驗證沒有水平溢位、console error 或失敗資源,最後列出修改檔案、測試指令、實際證據與所有 UNVERIFIED 項目。
最實用的日常模板:
/goal 完成[具體成果];只允許修改[範圍];不得進行[commit/push/PR/部署/憑證存取/破壞性操作/對外訊息];以[測試、build、量測、受管瀏覽器檢查]通過為完成條件;最後列出修改、實際證據與所有 UNVERIFIED 項目。
Goal 太長,先寫規格檔
Goal 必須非空,最多 4,000 字元。更長的規格不要硬塞:把細節寫進 repo 內的 SPEC.md/PLAN.md,Goal 只描述成果、紅線、驗證,並指向那份檔案。需求還不清楚時,官方建議先用 /plan 訪談與整理 success criteria,再把定稿轉成 /goal。
「美觀」不能假裝成機器 PASS
「畫面要漂亮」沒有客觀退出碼。可以驗 overflow、computed style、console、資源、鍵盤操作與 screenshot baseline;但沒有既有 pixel baseline 或真人 review 時,審美判斷要老實列 UNVERIFIED,不要叫 Goal 自己宣布「已經很好看」。
7.6.4 執行時到底發生什麼:先走沙箱,跨界才送 reviewer
-
基礎邊界
主 agent 在
workspace-write裡讀檔、改檔、跑專案指令已在沙箱內允許的普通動作直接繼續,不會每一步再叫 reviewer 看一次。
-
碰到邊界
需要網路、workspace 外寫入或其他需核准副作用時提出 request
只有本來就需要 approval、且屬於 eligible 類型的 request,才會進 Auto-review。
-
獨立審查
另一個 reviewer agent 看精簡 transcript 與 exact action
它會留意資料外洩、credential probing、持久性安全弱化與高破壞性不可逆操作。
-
決策
核准就執行這次 request;拒絕就找實質更安全的方法
明確 denial 不是普通錯誤。主 agent 不得換包裝、走後門或拆掉沙箱來規避;沒有安全替代路徑就停止並問你。
-
完成判斷
Goal 持續對照成果、限制與驗證證據
Auto-review 管「這一步可不可以跨界」;Goal 管「整件事有沒有達標」。兩層機制分工不同。
Auto-review 是 reviewer swap,不是 permission grant
核准是針對那次 request,不會把整個 session 升成 Full access,也不代表使用者已授權 commit、push、建立 PR/issue、部署、正式環境變更、刪資料、憑證存取或對外發訊息。要禁止的副作用必須寫進 Goal/prompt;需要硬保證時還要用 managed policy、rules、外部網路隔離或 disposable runner。
官方評估怎麼讀:高通過率不是「安全率」
OpenAI Alignment Research 公開的 2026 年 3 月內部流量與合成安全評估,提供了一組有用但不能過度解讀的點時數字:
| 評估 | 結果 | 正確讀法 |
|---|---|---|
| 被升級 request 的自動核准率 | 99.1% | 代表內部日常越界多數被放行,不代表危險動作 99.1% 安全 |
| overreach/過度積極案例攔截 recall | 90.3% | 合成案例裡仍有漏網可能,不能取代 deterministic policy |
| prompt injection 攔截 recall | 99.3% | 是特定攻擊類別與資料集的點時結果,不是所有 prompt injection 保證 |
| MonitoringBench Hard trajectory recall | 96.1% | 衡量 trajectory 內是否至少有一個動作被拒,不能外推成完整環境安全率 |
高手的結論不是「模型很高分,所以護欄可以拆」;而是讓 Auto-review 降低日常核准疲勞,同時保留 sandbox、精準 rules、可觀測證據與人類收尾。 Auto-review 也會增加額外 model calls/usage,並可能誤擋安全操作或放過非典型風險。
7.6.5 執行中怎麼控制:插話不等於加權限
# 查看目前 Goal
/goal
# 修改完成條件
/goal edit
# 暫停/繼續/取消
/goal pause
/goal resume
/goal clear
Goal 跑著時可以直接在同一個 interactive session 插話:
先回報目前進度、修改檔案、已通過與尚未通過的驗證,再繼續。
補充限制:不要更動 Header 元件;若必須修改,先停下說明原因。
這些訊息會補 context 或收緊 constraints,但不會因此取得新的網路、檔案或外部副作用權限。若 Goal 本身寫錯、驗收條件不可能達成,先 /goal pause 或 /goal edit,不要讓它為了追一條壞掉的收工線無限繞路。
/approve:只覆核一個最近被拒的 exact action
Auto-review 拒絕後,如果你看過理由、確定那個精確動作應該再試一次,可輸入 /approve 從近期 denial 挑一筆。這不是「本 session 全部放行」:它只為 exact action 記錄一次 retry,而且 retry 仍會再經 Auto-review;policy 不允許時依然可能再次拒絕。
有些提示仍會直接找你
Computer Use 的 app-level approval 是獨立案例,Auto-review 不會取代所有瀏覽器/桌面控制提示。所謂 Auto 工作流不是「從此永遠不會停下問人」。
7.6.6 一次性 Auto 工作:launcher 的 exec 模式
如果不想進互動介面,可以把完整工單直接交給一次性 run:
/Users/dawa/.codex/codex_agent_scripts/codex-auto-workflow.sh exec \
/Users/dawa/flowsign \
"修好首頁手機版;只修改前端;不得 commit、push、建立 PR、部署或讀取憑證;完成條件是 lint、typecheck、build 與受管瀏覽器驗證全部通過,最後輸出修改、實際證據與所有 UNVERIFIED 項目。"
這支 launcher 會固定加入 --ephemeral --json:
--ephemeral:不持久化可供resume的 session rollout;不是「保證任何 log/telemetry 都不存在」。--json:stdout 是逐行 JSON 的 JSONL event stream,不是單一 JSON 文件或只印最後一句。- 一次性工單:prompt 是本 run 的任務與 done criteria,但沒有 interactive Goal 的
edit/pause/resume控制列。 - 失敗方式:若 request 不屬 Auto-review eligible 類型、被拒,或 reviewer 無法處理,非互動 run 不能跳出人工核准視窗,只能讓該越界失敗。
外部 deadline 與 worktree 要自己補
官方公開文件沒有承諾 transaction-style 整體 rollback 或 run-level hard deadline,本機 launcher 也沒有實作。真正無人值守時,用獨立 Git worktree隔離改動、由外部 supervisor 設 wall-clock deadline,並在外層檢查退出碼、失敗事件與產出物;完整 JSONL/CI 驗收見第 10 章。
第一次用,仍建議先選 interactive+/goal:比較容易看 reviewer 理由、修正 Goal,並確認你真正想要的驗收證據。等工作流穩定後,再搬去 exec。
7.6.7 不要混用:四個長得像、其實完全不同的選項
| 做法 | 會發生什麼 | 適合 | 是否為本節 Auto 工作流 |
|---|---|---|---|
安全 launcher+interactive /goal | Auto-review 處理 eligible escalation,Goal 追完成條件 | 長任務、可中途修正 | 是,首選 |
安全 launcher exec | 同一權限邊界,一次性 ephemeral JSONL run | 穩定工單、腳本/CI | 是,一次性版 |
-a never -s workspace-write | 沒有 approval request,因此沒有 Auto-review;沙箱內照跑、仍需核准的越界直接失敗 | 封閉、可預測、fail-closed 的 CI | 否,但仍可能是合理工具 |
--yolo/danger-full-access + never | 拆掉 approvals 與 sandbox 邊界;單獨的 danger-full-access 只代表無沙箱,仍要另看 approval policy | 只有外部已硬隔離的 disposable VM/container | 完全不是 |
還有兩個常見地雷
- 不要用舊的
--full-auto名稱理解新工作流:它只是 deprecated compatibility flag,不是 Auto-review。 - 同一個 checkout 不要同時開兩個可寫 Goal:要平行就一任務一 worktree。Goal 各自有 context,不代表檔案會自動隔離。
7.6.8 高手版檢查清單:放手前先把四道門關好
- 邊界門:用
/status確認workspace-write + on-request,不是 Full access。 - 任務門:Goal 寫出具體 outcome、可改範圍、禁區與客觀 verification。
- 隔離門:確認工作樹與既有改動;平行 writer 各用獨立 worktree。
- 收尾門:退出碼、失敗事件、產出物與必要 rendered check 都有實際證據;驗不到的標 UNVERIFIED。
最後只記一句:launcher 決定「怎麼安全地做」,/goal 決定「做到哪裡才停」;Auto-review 的核准是技術邊界例外,不是使用者對外部副作用的空白授權。
7.6 官方與本機查核來源
- Auto-review:reviewer lifecycle、觸發條件、denial、
/approve與限制。 - Sandbox:sandbox 與 approvals 的兩軸模型。
- Long-running work:Goal mode、outcome/constraints/verification 與 worktree 建議。
- CLI developer commands:
/goal控制與 4,000 字元上限。 - Non-interactive mode:
codex exec的官方行為。 - OpenAI Alignment Research:Auto-review:研究動機與點時評估數字。
本機驗證 launcher 靜態契約已於 2026-07-19 對 codex-cli 0.144.6 核對;既有 live escalation probe 是 0.144.5。本輪沒有在 0.144.6 重跑真實越界,因此升版後 reviewer dispatch 保留 UNVERIFIED。CLI 或管理政策更新後要重驗。
小結
這一章你把 Codex 從「能用」帶到了「會帶」:
/plan:複雜任務先看計畫再動工,別讓它衝動拆牆。- 驗證迴圈:讓它建測試、跑檢查、看 diff,最後你親手再驗一次;「done」的定義要寫進
AGENTS.md;/review除了裸用審整個工作樹,也能帶--uncommitted/--base/--commit精準框審查範圍。 - resume / fork / archive / delete:對話都存在
~/.codex/sessions/,codex resume接續(跨資料夾記得加--all)、codex fork分岔、archive是藏不是刪、codex delete才真刪。 - 一任務一條對話:這是整章最重要的紀律,違反它(一專案一條)是官方點名的頭號反模式。
- 🎓 高手進階(7.5):一任務一線同時省錢省腦;resume 信 rollout 檔(
.jsonl是真相源、0.140 損毀自動修)、子工作 0.139 起不隨父對話復活、檔案也不會跟著 resume 自動歸位(沒有內建的一鍵/rewind,Git 仍是唯一退路);fork 只在 TUI;Plan 模式可「規劃深、執行淺」,還要留意規劃階段本身可能吃掉三到五成 context;不准改測試要做成結構(AGENTS.md + 外層 shell 驗退出碼)不是喊口號,放手讓 Codex 自己git commit則要當心 sandbox 卡.git;context 到 60% 主動/compact。平行多代理在第 14 章。 - Auto-review+Goal(7.6):Auto preset 是基礎權限、Auto-review 只替換 eligible escalation 的 reviewer、
/goal則把 outcome/constraints/verification 固定成收工線;三者不等於 Full access。日常用安全 launcher+interactive Goal,穩定工單才搬到 ephemeral JSONLexec。
版本提醒
本章的子指令(尤其 codex delete、codex fork)與快速鍵(/plan 的 Shift+Tab / Cmd+Shift+P)在 Codex CLI 各版本間變動很快。逐字旗標一律以實機 codex --help、codex resume --help、/help 輸出為最終真相。7.1–7.5 原內容對照 0.140.0(2026-06-15);7.6 的 Auto-review/Goal/launcher 契約另於 2026-07-19 對本機 0.144.6 重新查核,live escalation 則誠實保留 UNVERIFIED。
動手試試
- 隨便找一個你自己的小專案,進
codex,打/plan,丟一個「不只一步」的需求(例如「幫這個專案加上一個簡單的設定頁」),看看它列出來的計畫長什麼樣——先別讓它真的動手。 - 在對話裡打
/status,把你這條 session 的 ID 找出來。然後退出,改用codex resume --last,確認它真的接回了剛剛那條對話。 - 故意在另一個資料夾打
codex resume --last,體會一下「找不到剛剛那條」的感覺,再加上--all試一次,印證 7.3 講的「跨資料夾要加--all」。 - (進階)在一個你信任、已有 Git 的測試專案用安全 launcher 進 interactive session,先跑
/status,再設定一個不含外部副作用、完成證據明確的小型/goal。觀察 sandbox 內動作與越界 request 的差別;不要拿正式部署或資料庫當第一次實驗。