<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:media="http://search.yahoo.com/mrss/"><channel><title>Codex 和 Claude Code 雙修 - Bobo 的學思山丘</title><description>用同一套專案規則、Skills 與 MCP 管理 Claude Code 和 Codex，再讓第二個工具負責獨立檢查。</description><link>https://bobochen.dev/</link><item><title>Agent 記性很差？ 如何讓不同電腦上的 Agent 進行 context 同步</title><link>https://bobochen.dev/blog/cross-machine-agent-context-sync/</link><guid isPermaLink="true">https://bobochen.dev/blog/cross-machine-agent-context-sync/</guid><description>換一台電腦、開一個新對話，Agent 還是能在幾秒內接上進度。關鍵是把「檔案同步」和「上下文同步」拆成兩件事，再把 source of truth 設計成跨機器、跨對話、跨 agent 都能 reload。</description><pubDate>Wed, 15 Jul 2026 00:00:00 GMT</pubDate><content:encoded>這題我斷斷續續搞了一個月，踩掉不少坑，最後能濃縮成一句話：

**把「檔案同步」和「上下文同步」分開，它們是兩件事。**

會卡住，通常是因為把這兩件事混在一起想。拆開之後，一半的問題會自己消失。

## 檔案同步：最簡單的那一半

程式碼、文件這種「檔案」的同步其實沒什麼好講：Google Drive、Dropbox、一個 GitHub repo，挑你順手的就好。這部分是 solved problem，不是你真正的痛點。

真正的痛點是下一段。

## 上下文同步：你以為 Agent 很笨，其實是它每次重開機

Agent 本質上是 stateless 的。每開一個新對話，它都從零開始——這不是 bug，是設計。

你覺得它「笨」「記性差」，多半是因為每次都要把「上次做到哪、為什麼這樣決定、下一步是什麼」重新貼一遍。換一台電腦更慘，連要貼的素材都在另一台上。

解法不是去期待 agent「記得」，而是**讓結構化的 markdown 幫它 reload**。我現在用三層：

- **`CURRENT_WORK.md`（主入口）**：只放 3–5 個 active 專案，每個 5–6 行，寫「停在哪 + 下一步」。刻意保持短，因為它每天都要讀。
- **`project_status_&lt;專案&gt;.md`**：單一專案的最新狀態，細節放這。
- **`handoff.md`**：只有大型專案才需要，記決策、風險、驗證細節這種「為什麼」的東西。

開新對話時我只要打一句「開工」，agent 自動把這三層讀進來，幾秒就接上狀態，不用再貼歷史。

### 跨機器：用一個 private repo 當單一真相

三層檔案我放在一個 GitHub repo（我叫它 `claude-memory`），兩台電腦都 clone 它。Google Drive 也能做到同步，但 GitHub 多了 diff history，改了什麼一目瞭然，對「決策記錄」這種東西特別有用。

一個容易漏掉的點：**這個 repo 一定要 private。** 裡面裝的是你專案的內部決策、風險、還沒公開的進度，不是能隨便攤在外面的東西。

至於「怎麼讓 agent 讀到這些檔案」，這裡我要修正一個自己一開始的做法——

我原本寫了一支 sync 腳本，把檔案「灌」進 agent 的 local memory 目錄。後來發現大多數情況不必這麼麻煩，因為工具本身就有原生機制：

- **Claude Code** 的 `@` import 支援絕對路徑。你可以在 `~/.claude/CLAUDE.md` 或專案的 `CLAUDE.md` 裡直接寫 `@~/repos/claude-memory/CURRENT_WORK.md`，clone 一次之後就自動載入，不用每次手動同步。
- **Codex** 現在有原生 memory：session 開始會整份讀 `memory_summary.md`，需要細節時再 grep `MEMORY.md`。結構跟我手刻的三層幾乎一樣。

換句話說，你手刻的三層 markdown 是很好的**內容結構**，值得留著；但「載入」這一步可以交給工具原生的 import / memory，少維護一支腳本。而且兩家工具都在往「原生 memory」補齊——這反而印證了 stateless 的方向沒錯：與其讓模型記得，不如讓外部檔案記得。

### 兩個沒人會先告訴你的坑

**坑一：merge conflict 是常態。** 兩台電腦都在改同一份 `CURRENT_WORK.md`，又靠 git 同步，衝突遲早會來——尤其這份檔案每個 session 都在變。我的處理方式是：`CURRENT_WORK.md` 用「per-machine 區塊」分開寫，或乾脆接受偶爾手動 resolve；`handoff.md` 盡量 append-only（往下加、不改舊的），衝突機率就低很多。這是這套系統真實存在的 friction，別假裝沒有。

**坑二：停點過期，比沒有記憶更糟。** 如果你忘了更新停點，agent 會「很有信心地」進入一個**錯誤**的狀態——confidently wrong，比它老實說「我不知道」還危險。所以檔案的鮮度其實是這套系統的單點失敗。下面 Q2 的 baton 規則就是在擋這件事。

## Codex 和 Claude Code 怎麼協作

我在公司環境同時跑 Codex 和 Claude Code。協作的第一原則跟上面一樣：**共享 source of truth，不要分資料匣。** 分了，你就要兩邊維護重複資訊，只會更累。

### 修正：frontmatter tag 是「約定」，不是「機制」

我一開始想用 markdown frontmatter tag 來區分「誰看哪份檔」，像這樣：

```yaml
---
agents: [claude, codex]
codex_tier: summary
---
```

這裡要老實講一個我踩過的誤解：**這兩家工具都不會自動解析這種自訂 frontmatter。**

- Codex 是靠走訪 `AGENTS.md`（從 git root 往下逐層串接）決定讀什麼，不看 `agents:` 或 `codex_tier:`。
- Claude Code 是靠 `CLAUDE.md` 階層加上 `@path` import 決定讀什麼，同樣不看這些 tag。

也就是說，照上面那樣寫，**兩家其實都會把整份檔讀進去，tag 完全沒作用**，除非你另外寫一支腳本去解析它、或在 prompt 裡明講「請遵守 frontmatter」。如果你只是把它當成「給人看的註記」那沒問題；但別誤以為它會自動分流。

真正能「一份真相、兩家都吃」的做法，是用工具原生的慣例：

- 寫一份 **`AGENTS.md`** 放兩邊共用的 repo 規則（Codex 原生讀，Cursor、Aider 等工具也吃這套）。
- **`CLAUDE.md` 只寫 `@AGENTS.md` 加上 Claude 專屬的補充**——Claude Code 不直接讀 AGENTS.md，但可以 `@import` 進來。

這樣是工具自動載入、真正單一真相，不靠任何 tag 約定。這一段我在 [Claude Code 與 Codex 共用專案規則](/blog/share-config-memory-claude-md-agents-md/) 有更完整的拆解。

### 分工：不是誰比較強，是誰適合這一步

一個月觀察下來，我的實際分工是：

- **Claude Code**——規劃、多步推理、cross-cutting 的 design review、UI，偏「想清楚再動手」。
- **Codex**——執行力強、code edit 快、腳本批改、Windows 工作流（有些需求還是得在 Windows 上操作）。

但「誰上場」與其看誰強，不如看任務的權限、風險和工作介面來決定，這部分我另外寫過一篇 [Claude Code 和 Codex 怎麼分工](/blog/why-dual-master-claude-code-codex-mental-models/)。

### baton 規則：交接前先寫進檔案

跨 agent 接手前，先把「做到哪、下一步」寫進 markdown 留存，再對人類口頭補一句話交接。這條規則同時擋掉上面的「坑二」：因為每次交接都逼你更新停點，跨日、跨機器就不會 drift。

這裡也順手修掉一個我原本的自我矛盾：我除了 `CURRENT_WORK.md`，還手動維護一份超精簡的 `CURRENT_WORK.codex.md`——但這其實違反了「不要維護兩份重複資訊」的原則。後來我改成讓精簡版從主檔**衍生**（用腳本產，或用上面 `AGENTS.md` 的分層讓它自動精簡），而不是手動同步兩份。如果你也想給 Codex 一份更短的版本，記得讓它是「產物」不是「複本」。

### 三角 review：拉一個 fresh eye 進來

想比較同一個 task 兩家的差異，最簡單就是同題目同時丟、對比結果。

我做過更進一步的：在 design review 階段，刻意拉 **Claude 網頁版**當第三隻眼，去看 Claude Code + Codex 產出的架構。那次 Claude 網頁版抓出 8 條 cross-cutting 的結構性風險，是另外兩邊都沒看到的。原因不是它比較聰明，而是它的上下文是乾淨的、被迫重新建立假設——這跟交叉 review 有效的理由是同一個。關於「兩個 agent 互相 review 為什麼有效、又為什麼不是雙重保證」，我在 [讓 Claude Code 和 Codex 互相 Review](/blog/claude-code-codex-cross-review-collaboration-workflow/) 講得更細。

## 一句話總結

把 source of truth 設計成**跨對話、跨機器、跨 agent 都能 reload**，上面那些 friction 就會自動少一大半。剩下的（merge conflict、停點鮮度）不會消失，但都有明確的處理方式。

Agent 不需要記得，讓檔案幫助它記得。

就跟我們人類一樣，大腦不是用來記得任何事，所以我們平常會寫筆記、螢幕旁也佈滿便條貼不是嗎? (笑)</content:encoded><media:content url="https://bobochen.dev/_astro/cover.CLr-HS4q.webp" medium="image"/><category>Claude Code</category><category>Codex</category><category>AI Coding</category><category>CLI</category><category>工作流</category><enclosure url="https://bobochen.dev/_astro/cover.CLr-HS4q.webp" length="0" type="image/png"/></item><item><title>Claude Code 和 Codex 怎麼分工？先看權限、執行環境與工作流</title><link>https://bobochen.dev/blog/why-dual-master-claude-code-codex-mental-models/</link><guid isPermaLink="true">https://bobochen.dev/blog/why-dual-master-claude-code-codex-mental-models/</guid><description>與其先問 Claude Code 或 Codex 誰比較強，不如從任務風險、權限模型、專案規則與工作介面決定誰上場。這篇建立雙修時真正耐用的判斷框架。</description><pubDate>Wed, 03 Jun 2026 00:00:00 GMT</pubDate><content:encoded>我一開始把 Codex 當成 Claude Code 額度不夠時的備用工具。真的兩邊一起用之後，才發現「備用」反而低估了它：兩套工具最有價值的地方，不是互相取代，而是讓我能依任務換一套工作方式。

所以我現在不太問「哪一個比較強」，而是先問三件事：

1. 這個任務能碰哪些檔案、指令與網路？
2. 專案規則要怎麼被讀取與覆寫？
3. 我需要的是互動探索、自動化執行，還是第二個 reviewer？

這三題比模型排行榜耐用，也比較接近每天寫程式時真正會遇到的選擇。

&gt; 這是「Codex 和 Claude Code 雙修」系列第 1 篇。下一篇會把兩邊常用能力整理成一張不容易過期的對照表。

## 先拆掉一個錯誤期待：雙修不是雙倍產能

同時裝兩個 CLI，不會自動得到兩倍產能。相反地，如果兩邊的規則、權限與工具各自長一套，維護成本會先加倍。

雙修值得做，是因為它多了三種選擇：

- **換一種工作介面**：同一個任務在互動探索、背景執行或非互動腳本裡，體感差很多。
- **換一組執行邊界**：依任務風險決定能否寫檔、能否連網、哪些指令需要確認。
- **換一個 reviewer**：讓沒有參與實作的工具檢查 diff，但仍以測試與人工判斷收尾。

關鍵不是每次兩個都開，而是保留切換的能力。

## 心智模型一：把「允許做什麼」拆開看

Claude Code 與 Codex 都有權限控制和沙箱，但使用介面不完全相同。

Claude Code 主要用 permission mode、allow/deny rules 與 sandbox 來決定它何時詢問、哪些操作被允許，以及 Bash 指令可接觸的範圍。像 `plan` 適合先讀程式與規劃，`acceptEdits` 會放寬檔案編輯，但工具規則仍會疊加在模式上。完整行為應以 [Claude Code permission modes](https://code.claude.com/docs/en/permission-modes) 與 [sandboxing 文件](https://code.claude.com/docs/en/sandboxing)為準。

Codex 則把兩個問題明確分開：

- **approval policy**：什麼情況需要問你。
- **sandbox mode**：這個程序實際能碰到哪些檔案、程序與網路。

例如下面這個組合，適合讓 reviewer 讀取 repo，但不准它修改工作目錄，也不要在執行途中等人批准：

```bash
codex exec -s read-only -a never &quot;Review the current uncommitted changes&quot;
```

可以把 Claude Code 想成「工作模式加規則」，把 Codex 想成「詢問策略乘上執行邊界」。這只是方便記憶的近似，不是一對一翻譯；兩邊功能都在持續演進。

### 不要把跳過確認當成同義詞

`--dangerously-skip-permissions` 和 `--yolo` 都會大幅降低護欄，但不能因此推論兩邊在相同環境下有相同風險。真正要確認的是：

- 寫入範圍是否只限工作目錄；
- 網路是否開放；
- secrets 是否存在環境變數；
- 指令會不會接觸 Docker socket、雲端憑證或家目錄；
- 是否還有容器、VM 或 CI runner 這層外部隔離。

這兩個選項只適合已經有外部隔離、而且你清楚失敗半徑的環境。

## 心智模型二：專案規則相近，但不是同一個檔名而已

Claude Code 主要讀取 `CLAUDE.md`，Codex 主要讀取 `AGENTS.md`。它們都能放建置指令、架構說明、測試要求和不可碰的範圍，但搜尋、分層與覆寫方式不同。

Claude Code 可以在 `CLAUDE.md` 中用 `@AGENTS.md` 匯入共用規則；Codex 會沿目錄結構尋找 `AGENTS.md`，並讓較接近目前工作目錄的規則覆寫上層內容。詳細行為分別見 [Claude Code memory](https://code.claude.com/docs/en/memory) 與 [Codex AGENTS.md](https://learn.chatgpt.com/docs/agent-configuration/agents-md)。

所以我不再把兩份檔案完全複製。比較穩定的做法是：

```text
AGENTS.md          共用的 repo 規則
CLAUDE.md          匯入 AGENTS.md，再補 Claude Code 專屬說明
.codex/config.toml Codex 專屬執行設定
.claude/settings.json
                   Claude Code 專屬權限與 hooks
```

第三篇會把這套結構完整展開。

## 心智模型三：先按任務分工，不按品牌站隊

我目前用下面四個問題決定誰上場：

| 問題 | 判斷方式 |
|------|----------|
| 需要哪個介面？ | 互動探索、非互動腳本、遠端控制或背景工作，選當下流程最順的工具。 |
| 能接受多大權限？ | 先設計寫入、網路與 secrets 邊界，再選對應模式，不從「全開」開始。 |
| repo 規則在哪邊維護？ | 優先共用核心規則，工具專屬設定分開。 |
| 如何驗證？ | 測試、型別檢查與靜態分析優先；第二個 agent 只補盲點。 |

遇到新專案時，我會把同一個小任務分別交給兩邊，例如修一個有測試的 bug。比較的不是誰講得更有自信，而是：

- 有沒有先讀對檔案；
- 是否遵守 repo 規則；
- 修改範圍是否克制；
- 測試失敗時能否找出真正原因；
- 最後的 diff 是否容易 review。

這種 repo 內的小型評估，比網路上的單一 benchmark 更能回答「哪個適合我現在的工作」。

## 雙修真正省下的是切換成本

如果共用規則、Skills 和 MCP 都整理好，你可以讓其中一個工具實作，另一個工具檢查；也可以在服務異常、額度不足或某種任務不順時切換，而不用重新解釋整個專案。

但不要把「不同模型」誤會成「一定獨立」。它們仍可能共享相似資料、工具限制與錯誤假設。第二個 reviewer 是額外訊號，不是正確性證明。

這個系列接下來會依序處理功能對照、共用專案規則、Skills、MCP，最後才把跨工具 review 串起來。順序很重要：沒有前面的基礎建設，雙修很容易只是開兩個終端機重複貼 prompt。

_下一篇：[Claude Code vs Codex：一張不容易過期的功能對照表](/blog/claude-code-vs-codex-cli-feature-map/)_</content:encoded><media:content url="https://bobochen.dev/_astro/cover.Dm1Beywn.webp" medium="image"/><category>Claude Code</category><category>Codex</category><category>AI Coding</category><category>CLI</category><category>工作流</category><enclosure url="https://bobochen.dev/_astro/cover.Dm1Beywn.webp" length="0" type="image/png"/></item><item><title>Claude Code vs Codex：一張不容易過期的功能對照表</title><link>https://bobochen.dev/blog/claude-code-vs-codex-cli-feature-map/</link><guid isPermaLink="true">https://bobochen.dev/blog/claude-code-vs-codex-cli-feature-map/</guid><description>從互動模式、非互動執行、專案規則、權限與沙箱、Skills、MCP 到 code review，整理 Claude Code 與 Codex 真正能互相對照的能力，也標出不能硬翻譯的地方。</description><pubDate>Wed, 03 Jun 2026 00:00:00 GMT</pubDate><content:encoded>把 Claude Code 換成 Codex 時，我最早做的是整理一張「這個功能在另一邊叫什麼」的表。很快就發現，逐一抄旗標不是好方法：CLI 更新後，最先過期的就是模型名稱、預設模式和實驗功能。

這篇改用比較耐久的方式，對照兩邊的**能力與責任邊界**。指令只保留穩定入口；實際使用前，仍應跑一次 `claude --help` 或 `codex --help`。

&gt; 這是系列第 2 篇，內容查核日期為 2026-07-14。上一篇先談[如何依權限、環境與工作流分工](/blog/why-dual-master-claude-code-codex-mental-models/)。

## 先看總表

| 工作 | Claude Code | Codex | 是否可直接對照 |
|------|-------------|-------|----------------|
| 互動式 coding | `claude` | `codex` | 大致可以 |
| 非互動執行 | `claude -p` | `codex exec` | 可以，但輸出與 session 行為不同 |
| 專案規則 | `CLAUDE.md` | `AGENTS.md` | 概念相近，載入規則不同 |
| 專案設定 | `.claude/settings.json` | `.codex/config.toml` | 不可共用格式 |
| 權限控制 | permission modes + rules | approval policy | 只能部分對照 |
| 執行隔離 | sandbox | sandbox mode | 概念相近，實作依平台而異 |
| 可重用工作流 | Skills | Skills | 共用核心格式 |
| 外部工具 | MCP | MCP | server 可共用，client 設定分開 |
| 次級 agent | subagents / agent teams | subagents | 能力相近，協作模型不同 |
| 檢查變更 | 自訂 review 工作流 | `codex review` | Codex 有明確入口；兩邊都可用 prompt review |

這張表最重要的欄位是最後一欄。看到概念相近，不代表能把設定原封不動搬過去。

## 互動模式與非互動執行

兩邊最基本的入口很接近：

```bash
claude
codex
```

要放進腳本或 CI，則分別使用：

```bash
claude -p &quot;Explain the current diff&quot;
codex exec &quot;Explain the current diff&quot;
```

兩邊都能輸出機器可讀結果，但參數名稱與 session 行為不同。Claude Code 可搭配 `--output-format`、`--json-schema`，Codex 可用 `--json`、`--output-schema` 和 `--output-last-message`。自動化時要把 schema、exit code、逾時和空輸出都當成介面的一部分，不要只解析自然語言。

如果腳本要可重現，還要固定：

- 工作目錄；
- 權限與沙箱設定；
- 可用工具；
- 是否保留 session；
- 允許讀取哪些 repo instructions。

模型名稱反而不適合寫死在通用教學裡。帳號方案、CLI 版本與可用模型都會變，應從當下的模型選擇介面或官方文件確認。

## 權限：不要只背「危險模式」的對照

最容易被抄進筆記的對照通常是：

```bash
claude --dangerously-skip-permissions
codex --yolo
```

兩者都會跳過重要護欄，但不是安全模型的完整描述，也不該成為預設設定。

Claude Code 使用 permission mode 搭配 allow/deny rules，並可用 sandbox 限制 Bash 指令。Codex 則把 approval policy 與 sandbox mode 分成兩個維度。以 Codex 為例：

```bash
codex -a on-request -s workspace-write
codex exec -a never -s read-only &quot;Review the current diff&quot;
```

第一行允許在工作區寫入，必要時詢問；第二行不等待批准，但程序只有讀取權限。`never` 不是「什麼都能做」，它只表示不會詢問，實際能力仍受 sandbox 限制。

反過來說，`--yolo` 會同時放寬重要限制。只有在容器、VM 或隔離 runner 已經把檔案、網路與 credentials 關好時，才考慮使用。

官方參考：[Claude Code permission modes](https://code.claude.com/docs/en/permission-modes)、[Codex approvals and security](https://learn.chatgpt.com/docs/agent-approvals-security)、[Codex sandboxing](https://learn.chatgpt.com/docs/sandboxing)。

## 專案規則與設定檔要分成兩層

我會把檔案分成「告訴 agent 怎麼工作」和「控制 client 怎麼執行」兩類：

### 專案規則

```text
Claude Code  CLAUDE.md
Codex        AGENTS.md
```

內容適合放架構、指令、測試要求、命名慣例與禁止事項。Claude Code 可以從 `CLAUDE.md` 匯入 `AGENTS.md`，所以共用核心不必複製兩份。

### 執行設定

```text
Claude Code  .claude/settings.json
Codex        .codex/config.toml
```

這裡才放權限規則、hooks、MCP 或 client 行為。Codex 也支援受信任專案內的 `.codex/config.toml`，不是只能改使用者層級的 `~/.codex/config.toml`。

兩邊都有多層設定與覆寫規則。不要因為檔名看起來相近，就假設 precedence 也一樣。第三篇會整理一個可維護的 repo 結構。

## Skills：共同語言，但不是完全相同的 runtime

Claude Code 與 Codex 都支援 [Agent Skills 規格](https://agentskills.io/specification)，核心是一個含 frontmatter 的 `SKILL.md`。因此，任務步驟、參考資料與腳本通常可以共用。

差別在掃描位置和工具專屬欄位：

```text
Claude Code  .claude/skills/&lt;name&gt;/SKILL.md
Codex        .agents/skills/&lt;name&gt;/SKILL.md
```

格式相容不代表執行結果相同。Skill 如果依賴某個 client 才有的工具、hook、subagent 類型或權限模式，就要加上相容性說明，或拆出薄薄的工具專屬 adapter。

另外，Codex 的 custom prompts 已標記為 deprecated，新的可重用流程應優先寫成 Skills；Claude Code 的舊式 commands 也已併入 Skills 的使用方式。不要再把 `~/.codex/prompts` 與 `.claude/commands` 當成長期共用方案。

## MCP：共用 server，不共用設定格式

兩邊都是 MCP client，所以同一個 filesystem、資料庫或內部 API server 可以各自註冊：

```bash
claude mcp list
codex mcp list
```

但 client 設定、環境變數轉交與 OAuth token 仍各自管理。Claude Code 常用 `.mcp.json` 保存 project scope；Codex 則放在 `config.toml` 的 `mcp_servers`。第五篇會提供不把 secret 寫進 repo 的範例。

## Subagents：都有，但不要把名稱當成相同架構

Claude Code 有 subagents，也提供實驗性的 agent teams；Codex 支援 subagents，互動介面可檢視或切換 agent。兩邊都能把研究、實作、測試或 review 拆給次級 agent，但上下文傳遞、工具限制與結果彙整方式並不相同。

實務上先定義任務邊界，比先追求最多 agent 更重要：

- 每個 agent 只負責一個可驗證輸出；
- 說清楚能否改檔；
- 指定回報格式；
- 避免多個 agent 同時改同一段程式；
- 最後由單一 owner 整合和跑測試。

## Review、checkpoint 與 session：這些最不適合硬配對

Codex 有 `codex review`，可針對未提交變更、base branch 或特定 commit 檢查。Claude Code 沒有完全相同的 shell 子指令，但可以在唯讀／plan 工作流中 review diff。

Claude Code 的 checkpointing 與 `/rewind`，和 Codex 的 resume、fork 也不是同一件事：一邊偏向回復對話中的程式狀態，一邊偏向延續或分岔 session。選擇時先問自己要的是「復原檔案」、「回到對話節點」，還是「保留原 session 開新分支」。

## 一張實際選擇表

| 情境 | 建議起點 |
|------|----------|
| 邊讀邊問、逐步探索 | 選你較熟悉的互動 CLI，先用唯讀／plan 模式 |
| CI 產生結構化結果 | `claude -p` 或 `codex exec`，加 schema 與明確 exit policy |
| 高風險 repo | 先縮小 sandbox、network 和 secrets，再談自動化 |
| 跨工具共用規則 | `AGENTS.md` 做核心，`CLAUDE.md` 匯入並補充 |
| 跨工具共用流程 | 寫成標準 Skill，分別放到兩邊的 discovery 路徑 |
| 第二意見 | author 完成 diff 後，讓另一個工具唯讀 review，再跑測試 |

最耐用的對照不是「A 旗標等於 B 旗標」，而是知道每個設定到底控制哪一層。CLI 更新時，只要重新查該層的入口，不用推翻整套工作流。

_上一篇：[Claude Code 和 Codex 怎麼分工？](/blog/why-dual-master-claude-code-codex-mental-models/) · 下一篇：[共用專案規則：CLAUDE.md、AGENTS.md 與設定檔](/blog/share-config-memory-claude-md-agents-md/)_</content:encoded><media:content url="https://bobochen.dev/_astro/cover.BmJGu-H5.webp" medium="image"/><category>Claude Code</category><category>Codex</category><category>OpenAI</category><category>AI Coding</category><category>CLI</category><enclosure url="https://bobochen.dev/_astro/cover.BmJGu-H5.webp" length="0" type="image/png"/></item><item><title>Claude Code 與 Codex 共用專案規則：CLAUDE.md、AGENTS.md 與設定檔</title><link>https://bobochen.dev/blog/share-config-memory-claude-md-agents-md/</link><guid isPermaLink="true">https://bobochen.dev/blog/share-config-memory-claude-md-agents-md/</guid><description>用 AGENTS.md 維護兩邊共用的 repo 規則，再由 CLAUDE.md 匯入並補充工具專屬內容；同時釐清 settings.json、config.toml 和 Skills 各自該放什麼。</description><pubDate>Wed, 03 Jun 2026 00:00:00 GMT</pubDate><content:encoded>同一個 repo 同時使用 Claude Code 和 Codex，最先出現的問題通常不是模型，而是規則分家：建置指令在 `CLAUDE.md`，測試要求在 `AGENTS.md`，半年後兩份內容已經互相矛盾。

我的解法是先把資訊分成三類：

1. **repo 規則**：兩邊都該遵守的事。
2. **client 設定**：權限、hooks、MCP、介面行為。
3. **可重用流程**：有步驟、腳本和參考資料的 Skills。

三類分開後，大部分內容只需要一份正本。

&gt; 這是系列第 3 篇。上一篇是[Claude Code 與 Codex 功能對照](/blog/claude-code-vs-codex-cli-feature-map/)。

## 共用核心：讓 `CLAUDE.md` 匯入 `AGENTS.md`

兩邊的 instruction file 概念相近，但載入規則不同。與其維護兩份完整副本，我會把跨工具規則放在 repo root 的 `AGENTS.md`：

```markdown
# Repository Guidelines

## Commands

- Install: `npm ci`
- Check: `npm run check`
- Build: `npm run build`

## Working agreements

- Preserve unrelated user changes.
- Use existing design tokens; do not hardcode colors.
- Run check and build before handing off.
- Never commit secrets or local environment files.
```

接著在 `CLAUDE.md` 匯入它：

```markdown
@AGENTS.md

# Claude Code notes

- Use project Skills for release and content workflows.
- Ask before running commands that change external services.
```

`@AGENTS.md` 是 Claude Code 文件支援的 import 語法。相較於把兩個檔案做成 symlink，這個做法有兩個好處：

- `CLAUDE.md` 可以保留 Claude Code 專屬附註；
- 對 Windows、壓縮檔和某些 Git 設定比較友善。

Symlink 仍可用，但適合個人且環境一致的 repo。團隊專案應先確認每個開發環境都能正確保留連結。

官方載入規則可參考 [Claude Code memory](https://code.claude.com/docs/en/memory) 與 [Codex AGENTS.md](https://learn.chatgpt.com/docs/agent-configuration/agents-md)。

## Instruction file 不是安全機制

`AGENTS.md` 或 `CLAUDE.md` 裡寫「不要刪資料」，本質上仍是給模型的上下文，不是作業系統層級的禁止規則。

我會把限制分成兩層：

- **指引層**：架構、流程、風格、該跑哪些檢查，寫在 instruction file。
- **強制層**：檔案寫入、網路、指令、credentials，交給 permission rules、sandbox、容器和 CI 權限。

規則可以解釋「為什麼不該做」，沙箱才負責「真的做不到」。兩者缺一不可。

## 大型 repo：把局部規則放近一點

如果 frontend、API 和 infra 的指令不同，不要把所有細節塞進根目錄。Codex 會依目錄層級讀取 `AGENTS.md`，較接近目前工作目錄的內容可以補充或覆寫上層規則。

```text
AGENTS.md
apps/
  web/
    AGENTS.md
services/
  api/
    AGENTS.md
```

根目錄只放全 repo 共識，局部檔案再寫專屬測試、產生碼或部署限制。Claude Code 也支援分層的 memory；實際搜尋與優先順序仍以各自官方文件為準，不要假設兩邊完全相同。

## Client 設定：接受兩份格式，不要硬合併

工具執行設定本來就不同，強迫共用只會讓結構更難懂。

| 設定範圍 | Claude Code | Codex |
|----------|-------------|-------|
| 專案 | `.claude/settings.json` | `.codex/config.toml` |
| 使用者 | `~/.claude/settings.json` | `~/.codex/config.toml` |
| 常見內容 | permissions、hooks、plugins | sandbox、approval、MCP、features |

Codex 支援受信任專案裡的 `.codex/config.toml`，並且會與使用者設定和 CLI 參數依優先順序疊加。需要多套個人設定時，Codex 的 profile 會載入 `$CODEX_HOME/&lt;name&gt;.config.toml`，再用 `codex --profile &lt;name&gt;` 選取；不要沿用舊文章裡的 `[profiles.name]` 寫法。

這些檔案只放 client 行為。像「PR 前要跑哪些測試」仍應寫在共用規則，否則換工具後就消失了。

## 不要再用舊式 prompt 目錄共用工作流

過去常見的對照是：

```text
.claude/commands/
~/.codex/prompts/
```

這不再是適合新專案的長期方案。Claude Code 已把 commands 的能力併入 Skills；Codex custom prompts 也已標示為 deprecated，官方建議改用 Skills。

如果一段流程需要被反覆呼叫，例如：

- 發版前檢查；
- 依專案格式寫部落格；
- 產生 migration 並驗證；
- review 未提交 diff；

就把它寫成 `SKILL.md`，附上需要的 scripts 和 references。下一篇會處理如何讓同一份 Skill 被兩邊找到。

## 一個可維護的 repo 結構

最後的目錄大致會長這樣：

```text
repo/
├── AGENTS.md                 # 跨工具 repo 規則
├── CLAUDE.md                 # @AGENTS.md + Claude 專屬附註
├── .claude/
│   ├── settings.json         # Claude client 設定
│   └── skills/               # Claude 的 skill discovery 路徑
├── .codex/
│   └── config.toml           # Codex client 設定
└── .agents/
    └── skills/               # Codex 的 skill discovery 路徑
```

檢查這套結構時，我會問四題：

1. 共用規則是否只有一份正本？
2. 工具專屬設定是否留在各自目錄？
3. 安全要求是否有真正的執行層限制？
4. 重複流程是否已從 instruction file 移到 Skill？

這樣做不是追求「所有檔案完全共用」，而是讓每一種資訊只出現在最合理的位置。該共用的共用，該分開的分開，之後換模型或更新 CLI 才不會整份重寫。

_上一篇：[Claude Code vs Codex 功能對照](/blog/claude-code-vs-codex-cli-feature-map/) · 下一篇：[一份 SKILL.md 兩邊用](/blog/share-skills-agent-skills-open-standard-symlink/)_</content:encoded><media:content url="https://bobochen.dev/_astro/cover.DDwgK2JB.webp" medium="image"/><category>Claude Code</category><category>Codex</category><category>AI Coding</category><category>CLI</category><category>設定檔</category><enclosure url="https://bobochen.dev/_astro/cover.DDwgK2JB.webp" length="0" type="image/png"/></item><item><title>一份 SKILL.md 兩邊用：Claude Code 與 Codex 的共用邊界</title><link>https://bobochen.dev/blog/share-skills-agent-skills-open-standard-symlink/</link><guid isPermaLink="true">https://bobochen.dev/blog/share-skills-agent-skills-open-standard-symlink/</guid><description>Claude Code 與 Codex 都支援 Agent Skills，但共用格式不等於共用所有執行行為。這篇整理目錄、最小規格、symlink 做法與跨工具驗證清單。</description><pubDate>Wed, 03 Jun 2026 00:00:00 GMT</pubDate><content:encoded>上一篇把 repo 規則整理成一份共用核心。這一篇處理更適合封裝「做事方法」的東西：Skills。

Claude Code 與 Codex 都支援 [Agent Skills 開放規格](https://agentskills.io/specification)。因此，流程說明、參考資料與腳本可以共用；但兩個 client 的工具名稱、權限模型與載入路徑不同，不能只看到同樣叫 `SKILL.md` 就當成零成本搬移。

&gt; 這是系列第 4 篇。上一篇是[共用專案規則與設定檔](/blog/share-config-memory-claude-md-agents-md/)。

## 先分清楚：規格相容與 runtime 相容

一個 Skill 通常是一個資料夾：

```text
release-check/
├── SKILL.md
├── scripts/
│   └── verify.sh
└── references/
    └── checklist.md
```

其中 `SKILL.md` 的必要 frontmatter 很精簡：

```markdown
---
name: release-check
description: Verify a release candidate before deployment.
---

# Release check

1. Read the repository release instructions.
2. Run the project check and build commands.
3. Inspect the generated diff and artifacts.
4. Report blockers before any deployment action.
```

`name` 與 `description` 是規格核心；`license`、`compatibility`、`metadata` 等欄位可依需求補充。最保險的做法是把跨工具內容維持在標準欄位內，client 專屬欄位另外驗證。

這只代表兩邊能**理解 Skill 的包裝方式**。真正執行時還要確認：

- `SKILL.md` 提到的工具在兩邊是否存在；
- script 需要的 binary 是否已安裝；
- 相對路徑是否從同一位置解析；
- 網路、寫檔與環境變數權限是否足夠；
- skill 是否依賴某一邊特有的 hook、subagent 或 plugin。

## 兩邊的 discovery 路徑

專案內最常見的目錄是：

| 範圍 | Claude Code | Codex |
|------|-------------|-------|
| 專案 | `.claude/skills/&lt;name&gt;/` | `.agents/skills/&lt;name&gt;/` |
| 個人 | `~/.claude/skills/&lt;name&gt;/` | `~/.agents/skills/&lt;name&gt;/` |

Codex 另外有管理員與系統層級的 Skills；Claude Code 也能從 plugins 提供 Skills。這些適合組織政策或工具發佈，不適合拿來藏只有這個 repo 才懂的流程。

實際載入規則與優先順序可查 [Claude Code Skills](https://code.claude.com/docs/en/slash-commands) 和 [Codex Skills](https://learn.chatgpt.com/docs/build-skills)。

## 共用方式一：Unix 環境用 symlink

如果團隊主要使用 macOS 或 Linux，可以選一邊當正本，再把另一邊的 discovery 路徑連過去。例如以 `.agents/skills` 為正本：

```bash
mkdir -p .agents/skills .claude
ln -s ../.agents/skills .claude/skills
```

目錄會變成：

```text
.agents/skills/release-check/SKILL.md
.claude/skills -&gt; ../.agents/skills
```

好處很直接：只有一份內容，不會改了 Codex 版卻忘記 Claude 版。Codex 官方文件也明確支援 symlinked skill folders。

但把 symlink commit 進 Git 前，先測試：

```bash
git status --short
readlink .claude/skills
```

Windows、某些解壓縮工具或 `core.symlinks=false` 的環境可能無法保留連結。跨平台團隊不應把「我電腦可用」當成驗證完成。

## 共用方式二：用同步腳本產生第二份

如果 Windows 支援是硬需求，可以把 `.agents/skills` 當 source of truth，透過 repo script 在安裝或檢查階段同步到 `.claude/skills`。

這種方式會產生兩份實體檔案，但責任很清楚：

- 只編輯 source 目錄；
- generated 目錄不接受手改；
- CI 檢查同步後是否有 diff；
- script 使用跨平台工具，並保留 executable 權限。

比起人工複製，這至少能偵測 drift。若 Skill 本來就要跨多個 repo 發佈，則應考慮獨立套件、plugin 或安裝流程，不要在每個 repo 各養一份。

## 哪些內容適合共用，哪些要拆 adapter

適合直接共用的內容：

- 任務目標與觸發情境；
- repo 內的固定檢查步驟；
- 一般 shell、Node 或 Python script；
- 輸出格式與驗收標準；
- 參考文件與範例。

容易需要 adapter 的內容：

- 指定 client 才有的 tool 名稱；
- Claude Code 專屬 frontmatter 或 hook；
- Codex 專屬 approval／sandbox 參數；
- 特定 plugin 或 MCP server 的呼叫方式；
- 依賴某種 subagent 編排的流程。

我會把共用核心寫成中性的步驟，再把 client 差異留在很薄的入口。例如核心只說「用唯讀權限檢查 diff」，Claude adapter 再指定 plan mode，Codex adapter 再指定 `-s read-only -a never`。

## 一份 Skill 的跨工具驗證清單

每次新增或修改共用 Skill，我會分別在兩邊做這些測試：

1. 啟動新 session，確認 Skill 能被 discovery。
2. 用自然語言觸發一次，再直接指定 Skill 觸發一次。
3. 確認它只讀取需要的 references，不會一次塞進全部內容。
4. 執行 scripts，檢查工作目錄、參數、exit code 與相依 binary。
5. 以最小權限跑一次，找出偷偷依賴的寫入或網路。
6. 模擬失敗，確認它會回報 blocker，而不是自動擴權或跳過檢查。

最後再看 git diff，避免同步工具或 script 意外改到 repo 其他檔案。

## Skills 共用的是流程，不是信任

Skill 會影響 agent 的決策，也可能要求執行 script。從別人 repo 安裝前，至少要讀過 `SKILL.md` 和實際被呼叫的程式，確認沒有上傳 secrets、修改 shell profile 或執行未釘版本的遠端腳本。

同一份 Skill 被兩個工具讀取，不代表它在兩邊擁有相同權限。權限仍由各 client 設定、沙箱與外部環境決定。這個邊界留清楚，Skills 才會真的降低維護成本，而不是把風險也一起複製。

_上一篇：[共用專案規則與設定檔](/blog/share-config-memory-claude-md-agents-md/) · 下一篇：[Claude Code 與 Codex 共用 MCP](/blog/share-mcp-tools-claude-code-codex/)_</content:encoded><media:content url="https://bobochen.dev/_astro/cover.DQ0aGgDU.webp" medium="image"/><category>Claude Code</category><category>Codex</category><category>AI Coding</category><category>Skills</category><category>CLI</category><enclosure url="https://bobochen.dev/_astro/cover.DQ0aGgDU.webp" length="0" type="image/png"/></item><item><title>Claude Code 與 Codex 共用 MCP：設定、認證與權限邊界</title><link>https://bobochen.dev/blog/share-mcp-tools-claude-code-codex/</link><guid isPermaLink="true">https://bobochen.dev/blog/share-mcp-tools-claude-code-codex/</guid><description>同一個 MCP server 可以同時提供給 Claude Code 與 Codex，但 client 設定、環境變數與 OAuth 認證仍要分開。這篇給出 stdio、HTTP 與 secrets 的安全設定方式。</description><pubDate>Wed, 03 Jun 2026 00:00:00 GMT</pubDate><content:encoded>Skills 解決「agent 要怎麼做事」，MCP 解決「agent 能接上哪些外部工具與資料」。Claude Code 和 Codex 都能連接 MCP server，所以不用為兩邊各寫一套 server；真正要分開管理的是 client 設定、認證與權限。

&gt; 這是系列第 5 篇。上一篇是[一份 SKILL.md 兩邊用](/blog/share-skills-agent-skills-open-standard-symlink/)。

## 哪些可以共用，哪些不能

| 項目 | 能否共用 | 原因 |
|------|----------|------|
| MCP server 程式 | 可以 | server 是獨立程序或 HTTP 服務 |
| tool schema 與回傳格式 | 可以 | 由 MCP protocol 定義 |
| client 設定檔 | 不行 | Claude Code 用 JSON／CLI scopes，Codex 用 TOML |
| OAuth 登入狀態 | 通常不行 | 每個 client 各自保存 token |
| 本機環境變數 | 可使用同一來源 | 但轉交語法與可見範圍不同 |
| tool approval | 不行 | 由各 client 的權限模型決定 |

換句話說，你只維護一套 server，但要把兩個 client 都當成獨立呼叫者來設定。

## 設定位置與管理指令

Claude Code 依 scope 管理 MCP：

- `local`：只在目前專案、目前使用者生效；
- `project`：寫入 repo 的 `.mcp.json`，可與團隊共享；
- `user`：跨專案使用。

常用指令是：

```bash
claude mcp add
claude mcp list
claude mcp get &lt;name&gt;
claude mcp remove &lt;name&gt;
```

Codex 的 MCP 設定放在使用者 `~/.codex/config.toml`，也可以放進受信任專案的 `.codex/config.toml`：

```bash
codex mcp add
codex mcp list
codex mcp get &lt;name&gt;
codex mcp remove &lt;name&gt;
codex mcp login &lt;name&gt;
codex mcp logout &lt;name&gt;
```

完整參數應以 [Claude Code MCP 文件](https://code.claude.com/docs/en/mcp) 與 [Codex MCP 文件](https://learn.chatgpt.com/docs/extend/mcp)為準。

## stdio server：同一支程式，兩種設定

假設公司內部有一個 Node.js MCP server：

```text
tools/company-mcp/dist/index.js
```

Claude Code 的 project scope `.mcp.json` 可以這樣寫：

```json
{
  &quot;mcpServers&quot;: {
    &quot;company-tools&quot;: {
      &quot;type&quot;: &quot;stdio&quot;,
      &quot;command&quot;: &quot;node&quot;,
      &quot;args&quot;: [&quot;tools/company-mcp/dist/index.js&quot;],
      &quot;env&quot;: {
        &quot;SERVICE_TOKEN&quot;: &quot;${SERVICE_TOKEN}&quot;
      }
    }
  }
}
```

Claude Code 會在 MCP 設定中展開 `${SERVICE_TOKEN}`。repo 只保存變數名稱，真正的 token 由 shell、password manager 或 CI secret 提供。

Codex 的 `.codex/config.toml` 則寫成：

```toml
[mcp_servers.company-tools]
command = &quot;node&quot;
args = [&quot;tools/company-mcp/dist/index.js&quot;]
env_vars = [&quot;SERVICE_TOKEN&quot;]
```

這裡容易踩坑：Codex 的 `env` 用來寫**固定值**，要把目前 process 已有的 secret 轉交給 server，應使用 `env_vars`。不要把 `${SERVICE_TOKEN}` 當成兩邊都會自動展開的通用語法。

## HTTP server：URL 可相同，登入仍分開

遠端 MCP 使用 Streamable HTTP 時，兩邊可以指向同一個 endpoint：

```bash
claude mcp add --transport http --scope user company-api https://mcp.example.com/mcp
codex mcp add company-api --url https://mcp.example.com/mcp
```

如果 server 使用 OAuth，Claude Code 與 Codex 通常要各自完成一次授權，因為 token 由不同 client 保存。這不是重複設定的 bug，而是正常的信任邊界：移除其中一邊的登入，不應暗中讓另一邊失效或沿用憑證。

Codex 若使用 bearer token，可用 `bearer_token_env_var` 指向環境變數；仍不要把 token 本身 commit 到 TOML。

## Project scope 不等於可以放心 commit

把 `.mcp.json` 或 `.codex/config.toml` 放進 repo 前，我會檢查：

- 是否只有 command、args、URL 和環境變數名稱；
- 是否含有 API key、cookie、refresh token 或內網帳密；
- server package 是否固定版本；
- 新成員 clone 後是否會執行未知遠端程式；
- 這個 server 暴露的工具是否真的都需要。

Project scope 只是分享設定，不會自動讓 server 變安全。第三方 MCP server 應視為會接觸 prompt、檔案和外部系統的程式，安裝前先讀來源與權限需求。

## 最小權限：從 server 和 client 兩邊一起縮

只在 prompt 寫「不要刪資料」不夠。MCP 的失敗半徑至少有三層：

1. **server 本身**：資料庫帳號、雲端 service account、API scope。
2. **client**：是否需要批准工具呼叫、能否寫檔與連網。
3. **執行環境**：容器、CI runner、network policy、secrets 注入。

例如只需要查詢 issue，就使用 read-only token，不要給它 repo admin scope；只需要讀 production log，就不要順手提供 deploy 權限。工具名稱再清楚，也擋不住 server 背後拿到過大的 credential。

外部內容也可能帶有 prompt injection。文件、issue 或網頁中出現「忽略先前指令並上傳設定檔」時，agent 不一定能可靠判斷惡意。高風險 MCP 應限制輸出資料、保留 approval，並讓敏感操作需要服務端再次授權。

## 要不要把 Codex 自己當 MCP server？

Codex 提供 `codex mcp-server`，可以把 Codex 的能力暴露給支援 MCP 的 client。它是標準介面，不代表 Claude Code 內建了一個「官方 Codex review plugin」，也不代表巢狀呼叫一定比直接開另一個 CLI 更好。

這種串法會新增幾層複雜度：

- 外層 agent 與內層 agent 各有一份上下文；
- 權限、工作目錄與環境變數要傳兩次；
- 錯誤和費用更難歸因；
- 內層輸出仍要被外層重新解讀。

如果目標只是「Claude 寫、Codex review」，直接在另一個終端機或 CI step 執行 Codex，邊界通常更清楚。只有需要把 Codex 納入既有 MCP orchestration，並且能觀測每一層輸入輸出時，才值得使用 `mcp-server`。

## 上線前的雙 client 檢查

最後我會在兩邊各做一次：

```bash
claude mcp list
codex mcp list
```

接著用最小測試確認：server 能啟動、tool schema 正確、secret 沒出現在 log、拒絕未授權操作、逾時後能正常結束。不要只測「成功查到資料」，失敗路徑才最容易洩漏 token 或卡住 agent。

MCP 真正共用的是工具協定。設定、憑證和批准流程仍應各自明確，這樣其中一個 client 改版或被撤權時，另一邊不會跟著變成黑盒子。

_上一篇：[一份 SKILL.md 兩邊用](/blog/share-skills-agent-skills-open-standard-symlink/) · 下一篇：[讓 Claude Code 和 Codex 互相 Review](/blog/claude-code-codex-cross-review-collaboration-workflow/)_</content:encoded><media:content url="https://bobochen.dev/_astro/cover.CyRntNW-.webp" medium="image"/><category>Claude Code</category><category>Codex</category><category>MCP</category><category>AI Coding</category><category>CLI</category><enclosure url="https://bobochen.dev/_astro/cover.CyRntNW-.webp" length="0" type="image/png"/></item><item><title>讓 Claude Code 和 Codex 互相 Review：有效，但不是雙重保證</title><link>https://bobochen.dev/blog/claude-code-codex-cross-review-collaboration-workflow/</link><guid isPermaLink="true">https://bobochen.dev/blog/claude-code-codex-cross-review-collaboration-workflow/</guid><description>用一個 coding agent 實作、另一個唯讀 review，可以增加第二個觀察角度；但真正的品質仍來自清楚的 review contract、測試、靜態分析與人工決策。</description><pubDate>Wed, 03 Jun 2026 00:00:00 GMT</pubDate><content:encoded>同時使用 Claude Code 和 Codex，最實用的分工之一是：一個負責實作，另一個只看最後的 diff。

這個方法確實常能多抓一層問題，但原因不是「兩個 AI 投票就會變真理」。它只是把 author 與 reviewer 的上下文分開，強迫第二個工具重新建立假設。兩邊仍可能一起漏掉同一個需求，也可能對錯誤答案同樣有信心。

所以交叉 review 的定位應該是**額外訊號**，不是測試、靜態分析或人工 review 的替代品。

&gt; 這是「Codex 和 Claude Code 雙修」系列第 6 篇，也是收尾。上一篇是[兩邊共用 MCP 的設定與權限邊界](/blog/share-mcp-tools-claude-code-codex/)。

## 先把 author 和 reviewer 的責任切開

一個可用的流程至少有四個角色責任：

| 階段 | 責任 |
|------|------|
| Author | 理解需求、修改程式、跑最相關的測試 |
| Automated checks | 型別、lint、測試、build、security scanner |
| Reviewer | 只根據需求、diff 與 repo 規則找具體缺陷 |
| Human owner | 判斷 findings、處理取捨、決定是否合併 |

如果沒有測試結果和需求，reviewer 只能猜「看起來像不像 bug」。如果沒有 human owner，兩個 agent 可能在風格偏好上來回改，最後 diff 變大，品質卻沒有提高。

## Review 前先準備一份 contract

不要只丟一句「幫我 review」。至少提供：

- 這次變更要解決什麼；
- 哪些檔案或行為不在範圍內；
- repo 的 `AGENTS.md`／`CLAUDE.md`；
- 已跑過哪些檢查、結果如何；
- reviewer 可以讀什麼、能不能執行指令；
- finding 要用什麼格式回報。

我常用這個 prompt 骨架：

```text
Review the current uncommitted changes against the stated requirement and
repository instructions.

Prioritize correctness, regressions, security, data loss, and missing tests.
Do not report style preferences unless they cause a concrete defect.

For each finding, return:
- severity
- file and line
- evidence or failure scenario
- the smallest reasonable fix

If you find no actionable defect, say so explicitly and list remaining
verification gaps.
```

「remaining verification gaps」很重要。沒有 finding 不等於已證明正確，reviewer 應該說明它沒辦法驗證什麼。

## 工作流 A：Claude Code 寫，Codex 審

如果 Claude Code 已完成修改，可以直接使用 Codex 的 review 入口：

```bash
codex review --uncommitted &quot;Focus on correctness, regressions, and missing tests.&quot;
```

`codex review` 也能針對 base branch 或特定 commit。實際參數以 `codex review --help` 和 [Codex developer commands](https://learn.chatgpt.com/docs/developer-commands?surface=cli)為準。

若你希望在程序層明確限制為唯讀，可以改用：

```bash
codex exec \
  -s read-only \
  -a never \
  &quot;Review the current uncommitted diff. Report actionable findings only.&quot;
```

這個組合表示不等待互動批准，而且沙箱只允許讀取。它仍可能因測試需要寫 cache 或暫存檔而無法執行完整 test suite，所以 author 應先提供測試結果；reviewer 再指出缺少的驗證，不要為了跑測試臨時擴權。

## 工作流 B：Codex 寫，Claude Code 審

反過來可以讓 Claude Code 在 plan mode 中檢查 diff：

```bash
claude -p \
  --permission-mode plan \
  &quot;Review the current uncommitted diff. Report actionable findings only.&quot;
```

Plan mode 適合唯讀探索，但它是 Claude Code 的 permission mode，不應被描述成一個與 Codex `read-only` 完全相同的 OS 沙箱。若 repo 風險較高，還要搭配 Claude Code sandbox、allow/deny rules，或直接放進隔離容器。

Claude Code 的模式與規則會隨 client 更新，執行前可查 [permission modes](https://code.claude.com/docs/en/permission-modes)。

## 第一輪只收 findings，不要立刻自動修

Reviewer 回報後，先把每一項分成：

- **接受**：有可重現情境或明確違反需求；
- **需要驗證**：看似合理，但證據不足；
- **拒絕**：誤讀需求、忽略 repo 限制或只是風格偏好。

再由 author 處理被接受的 finding，補測試並重新執行 checks。Reviewer 不應直接拿到寫入權限，否則 author／reviewer 的邊界又混在一起。

第二輪只檢查：

1. 原 finding 是否真的修好；
2. 修正是否帶來新 regression；
3. 新增測試是否能在舊實作上失敗、在新實作上通過。

通常兩輪已足夠。若兩個 agent 對同一點反覆爭論，就交給 human owner，不要讓它們無限互審。

## Plan review 比 code review 更便宜

交叉 review 不一定要等程式寫完。高風險變更在動手前，可以先讓另一個工具檢查計畫：

- migration 是否可回滾；
- API 相容性是否被忽略；
- 權限與資料邊界是否清楚；
- 驗收測試是否真的對應需求；
- 是否有更小的修改路徑。

計畫階段發現問題，通常比完成大型 diff 後重做便宜。這時 reviewer 應檢查假設和風險，不要搶著重寫整份 plan。

## 自動化可以做，但要有停止條件

這套流程可以包成 Skill 或 CI job，例如：

```text
1. Verify the working tree scope.
2. Run deterministic checks.
3. Ask the second agent for findings in a fixed schema.
4. Fail only on findings that meet the agreed severity policy.
5. Save the raw review output as an artifact.
6. Stop after one review pass and request human triage.
```

不要讓 CI 自動接受 reviewer 的所有修正，也不要在 Stop hook 裡無限啟動另一個 agent。至少要有：

- 最大輪數；
- timeout；
- 成本上限；
- 允許讀取的檔案範圍；
- 固定輸出 schema；
- 人工升級條件。

對高風險專案，還要保存 prompt、CLI 版本、git SHA 和測試結果，否則同一個 finding 之後很難重現。

## 哪些 finding 最值得交給第二個工具

我會優先要求 reviewer 檢查可被證明的問題：

- null、邊界值與錯誤處理；
- stale state、race condition、transaction 邊界；
- 權限繞過、secret 洩漏、輸入驗證；
- schema 或 API 相容性；
- 漏掉的測試與失敗路徑；
- diff 是否超出需求範圍。

至於命名偏好、抽象層次和「我會用另一種寫法」，除非會造成維護或正確性問題，否則不該阻擋交付。

## 雙修的最後一張決策表

| 任務 | 建議做法 |
|------|----------|
| 小改動、有完整測試 | 一個 agent 實作，跑 checks；視風險決定是否需要第二 reviewer |
| 跨模組或高風險變更 | 先做 plan review，再實作、跑 checks、交叉 review |
| 牽涉 production 或資料 | 使用隔離環境、最小 credentials、人工批准；AI review 只當輔助 |
| 純風格重構 | 先用 formatter／lint；不要為了得到兩票而開兩個 agent |
| Reviewer 意見衝突 | 回到需求、測試與可重現證據，由 human owner 決定 |

整個系列最後想留下的不是「Claude Code 加 Codex 一定比較強」，而是一套清楚的分工方式：共用 repo 規則與流程，分開管理 runtime 權限，再讓第二個工具在需要時提供不同觀察角度。

工具會改版，模型會換名字，但這些邊界不太會過期。

_上一篇：[Claude Code 與 Codex 共用 MCP](/blog/share-mcp-tools-claude-code-codex/)_</content:encoded><media:content url="https://bobochen.dev/_astro/cover.DtR8fD2r.webp" medium="image"/><category>Claude Code</category><category>Codex</category><category>AI Coding</category><category>Code Review</category><category>CLI</category><enclosure url="https://bobochen.dev/_astro/cover.DtR8fD2r.webp" length="0" type="image/png"/></item></channel></rss>