Hub Codex CLI 完整教學

第 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 做事時,要它走這五步:

  1. 視需要建立或更新測試——先有檢驗標準。
  2. 跑相關的檢查——測試 / lint / format / 型別檢查都跑一遍。
  3. 確認結果與你的請求相符——做的跟要的是不是同一件事。
  4. Review diff(看改動對照)——逐行檢查有沒有引入 bug、有沒有弄壞別的功能、有沒有可疑的寫法。
  5. 你自己在接受之前,再親手跑一次驗證迴圈。

注意第 5 步:最後一道關卡是「你」,不是 AI。 AI 自己說綠了不算數,你親手跑過、親眼看到測試全過,才算真的 done。

「done」要寫進 AGENTS.md

Codex 怎麼知道你這個專案的測試指令是什麼?你要先在 AGENTS.md第 5 章)裡寫清楚,例如「改完 JS 要跑 npm test」。它讀到了,才知道你心中的「完成」長什麼樣子。這也是官方避坑清單第 2 條——不給 agent build / test 指令的可見性,它就無從驗證

社群進階打法:先寫測試、再叫它寫到綠

除了官方五步,實務上很受歡迎的一招(社群實踐,非官方逐字)是這樣:

  1. 先請 Codex(或你自己)把測試寫好
  2. 跑一次,確認測試全部 fail(因為功能還沒做)。
  3. 把這些失敗的測試 commit 起來,當成一個 checkpoint(存檔點)
  4. 接著叫 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> 從哪裡拿?官方給三個地方:

  1. 續接時的清單(picker)介面上會顯示。
  2. 在對話裡打 /status 指令,輸出會列出來。
  3. 直接去 ~/.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/delete0.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。)

來源:官方 best practices

為什麼「一專案一條對話」是反模式

很多新手習慣這樣:打開 Codex,然後一整天、一整個專案的所有事都在同一條對話裡講。今天修登入 bug、下午加新功能、傍晚改樣式……全擠在一條 thread。

這是反模式(anti-pattern),官方避坑清單第 8 條明確點名。為什麼不好?

因為 Codex 的「工作記憶(context)」是有限的。你把十件不相干的事塞進同一條對話,它的記憶裡就塞滿了一堆彼此無關的雜訊——修登入 bug 時,腦子裡還掛著早上改樣式的細節。結果就是 context 膨脹、它越來越容易分心、答非所問、品質下滑

正解:一個任務,開一條新對話。 修登入 bug 是一條、加新功能是另一條、改樣式再一條。每條對話只專注一件事,Codex 的記憶乾淨,表現最好。

怎麼「重開一條」?

最直接的方法就是做完一件事後,在對話裡打 /new(在同一個 CLI 視窗裡開一段全新對話、重置脈絡),或乾脆關掉重打一次 codex。需要時再用 7.3codex resume 把舊的那條接回來。

那什麼時候才該 fork?

官方給的原則是:只在工作「真的分岔(work truly branches)」時才 fork。 也就是同一條工作脈絡下,你想試 A、B 兩種做法——這種「同源、想比較」的情況才 fork。如果是兩件不相干的事,那不是 fork,是各開一條新對話。

官方避坑八條(完整收錄)

OpenAI best practices 頁列了八個最常見的踩雷點,這裡一次給你,當成「自我檢查清單」:

#別這樣做
1長期規則塞進每次 prompt,而不是寫進 AGENTS.md 或 skills(第 512 章
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 何時該手動出手

本節只談「單線工作流」。

真正的平行/多代理(同時開好幾個 agent 互相分工、spawn_agents_on_csv 批次扇出、hooks 機械閘門、git worktree 平行)主題大、料多,整套下放到第 14 章。本節只把「一個人、一條線怎麼做到最好」講透,需要平行時翻第 14 章

一任務一線:不是建議,是省錢省腦的鐵律

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 presetworkspace-write + on-request)、官方 Auto-reviewapprovals_reviewer = "auto_review"),以及官方 Goal mode/goal)。本站再用一支個人 workflow launcher 把前兩者安全地固定起來。它不是 Claude Code 的同名 Auto mode,也不是 --yolo、Full access 或已棄用的 --full-auto

把它記成兩層就夠了:

負責回答這一節用什麼不會替你做什麼
權限層 Codex 能在哪裡動手?跨界時誰核准? workspace-writeon-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 toolshell 裡的 curl/套件管理器已獲得網路
白名單介面只收 interactiveexec 與 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(完成判準)。官方建議寫三類資訊:

  1. Outcome:要得到的結果,不只說「研究、改善、處理」。
  2. Constraints:可用工具、修改邊界、相容需求與不得採用的方法。
  3. 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.mdPLAN.md,Goal 只描述成果、紅線、驗證,並指向那份檔案。需求還不清楚時,官方建議先用 /plan 訪談與整理 success criteria,再把定稿轉成 /goal

「美觀」不能假裝成機器 PASS

「畫面要漂亮」沒有客觀退出碼。可以驗 overflow、computed style、console、資源、鍵盤操作與 screenshot baseline;但沒有既有 pixel baseline 或真人 review 時,審美判斷要老實列 UNVERIFIED,不要叫 Goal 自己宣布「已經很好看」。

7.6.4 執行時到底發生什麼:先走沙箱,跨界才送 reviewer

  1. 基礎邊界

    主 agent 在 workspace-write 裡讀檔、改檔、跑專案指令

    已在沙箱內允許的普通動作直接繼續,不會每一步再叫 reviewer 看一次。

  2. 碰到邊界

    需要網路、workspace 外寫入或其他需核准副作用時提出 request

    只有本來就需要 approval、且屬於 eligible 類型的 request,才會進 Auto-review。

  3. 獨立審查

    另一個 reviewer agent 看精簡 transcript 與 exact action

    它會留意資料外洩、credential probing、持久性安全弱化與高破壞性不可逆操作。

  4. 決策

    核准就執行這次 request;拒絕就找實質更安全的方法

    明確 denial 不是普通錯誤。主 agent 不得換包裝、走後門或拆掉沙箱來規避;沒有安全替代路徑就停止並問你。

  5. 完成判斷

    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/過度積極案例攔截 recall90.3%合成案例裡仍有漏網可能,不能取代 deterministic policy
prompt injection 攔截 recall99.3%是特定攻擊類別與資料集的點時結果,不是所有 prompt injection 保證
MonitoringBench Hard trajectory recall96.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 /goalAuto-review 處理 eligible escalation,Goal 追完成條件長任務、可中途修正是,首選
安全 launcher exec同一權限邊界,一次性 ephemeral JSONL run穩定工單、腳本/CI是,一次性版
-a never -s workspace-write沒有 approval request,因此沒有 Auto-review;沙箱內照跑、仍需核准的越界直接失敗封閉、可預測、fail-closed 的 CI否,但仍可能是合理工具
--yolodanger-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 高手版檢查清單:放手前先把四道門關好

  1. 邊界門:用 /status 確認 workspace-write + on-request,不是 Full access。
  2. 任務門:Goal 寫出具體 outcome、可改範圍、禁區與客觀 verification。
  3. 隔離門:確認工作樹與既有改動;平行 writer 各用獨立 worktree。
  4. 收尾門:退出碼、失敗事件、產出物與必要 rendered check 都有實際證據;驗不到的標 UNVERIFIED。

最後只記一句:launcher 決定「怎麼安全地做」,/goal 決定「做到哪裡才停」;Auto-review 的核准是技術邊界例外,不是使用者對外部副作用的空白授權。

7.6 官方與本機查核來源

本機驗證 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 JSONL exec

版本提醒

本章的子指令(尤其 codex deletecodex fork)與快速鍵(/planShift+Tab / Cmd+Shift+P)在 Codex CLI 各版本間變動很快。逐字旗標一律以實機 codex --helpcodex 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。

動手試試

  1. 隨便找一個你自己的小專案,進 codex,打 /plan,丟一個「不只一步」的需求(例如「幫這個專案加上一個簡單的設定頁」),看看它列出來的計畫長什麼樣——先別讓它真的動手。
  2. 在對話裡打 /status,把你這條 session 的 ID 找出來。然後退出,改用 codex resume --last,確認它真的接回了剛剛那條對話。
  3. 故意在另一個資料夾打 codex resume --last,體會一下「找不到剛剛那條」的感覺,再加上 --all 試一次,印證 7.3 講的「跨資料夾要加 --all」。
  4. (進階)在一個你信任、已有 Git 的測試專案用安全 launcher 進 interactive session,先跑 /status,再設定一個不含外部副作用、完成證據明確的小型 /goal。觀察 sandbox 內動作與越界 request 的差別;不要拿正式部署或資料庫當第一次實驗。