---
title: "08 - Claude 當大腦、Codex 當雙手（核心架構）"
type: note
specialty: Programming
tags: [herdr從0開始使用教學, 08-核心架構, claude, codex, orchestration]
created: 2026-08-04
updated: "2026"
modified: 2026-08-04
---

# 08 - Claude 當大腦、Codex 當雙手（核心架構）

← [[07-Agent-Skill讓AI自己操控Herdr]] | [[00-Index]] | 下一篇 → [[09-實戰-刷題網站Taiwan-IM-board]]

> ⭐ **這是整份教學的核心章節。** 前七章都是為了讓這一章能落地。

---

## 為什麼要這樣分工

你有兩個訂閱：**Claude Pro** 和 **ChatGPT Plus**。它們的特性不同：

| | Claude Pro（Claude Code）| ChatGPT Plus（Codex CLI）|
|---|---|---|
| 額度感受 | 較緊，長任務容易撞上限 | 較寬鬆，可以長時間跑 |
| 你已建立的資產 | **12 個 skill**（note-orchestrator、neizhan-solver、google-med…）、PubMed MCP、兩個 repo 的 `CLAUDE.md` | 一般 coding agent |
| 強項 | 規劃、判斷、遵守複雜規則、醫學查證 | 大量、重複、規格明確的產出 |

所以最佳分工不是「誰比較強」，而是**額度要花在刀口上**：

```
Claude（貴、稀缺、懂規矩）  →  想事情、切任務、驗收、commit
Codex（多、便宜、聽話）      →  照規格幹活，一次好幾個
```

> 🔑 **關鍵洞察**：Claude Code 內建的 subagent（Task tool）**也是燒 Claude 的額度**。所以「用 subagent 平行處理」省的是時間，不是額度。
> 而 Herdr 開出去的 Codex pane **走的是完全不同的訂閱帳單**——這才是真正的額度轉移。

---

## 架構圖

```
┌─────────────────────────────────────────────────────────────┐
│ Herdr Session (背景常駐 server)                              │
│                                                              │
│ Workspace w1  "vault"                                        │
│ └── Tab w1:t1 "agents"                                       │
│     ├── Pane w1:p1  ★ Claude Code = 大腦 / orchestrator      │
│     │    · 讀 CLAUDE.md、切任務、寫 prompt                    │
│     │    · 用 herdr CLI 開/餵/等/讀 底下的 worker            │
│     │    · 查 PubMed、驗收醫學正確性                          │
│     │    · 唯一一個負責 commit / push 的人                   │
│     │                                                        │
│     ├── Pane w1:p2  ○ codex "worker-a"  ← 只寫檔             │
│     ├── Pane w1:p3  ○ codex "worker-b"  ← 只寫檔             │
│     └── Pane w1:p4  ○ codex "worker-c"  ← 只寫檔             │
│                                                              │
│ └── Tab w1:t2 "validate"                                     │
│     └── Pane w1:p5  □ shell（跑 validate.py / lint.py）      │
└─────────────────────────────────────────────────────────────┘
        ↑                                    ↑
   你的電腦（Windows Terminal → WSL）    iPhone SSH 巡場
```

**三條鐵律**：

1. **Claude 是唯一的 commit 者。** Codex 只寫檔。（這也符合 `Obsidian-med-note/CLAUDE.md` §3「orchestrator 做唯一一次 commit」。）
2. **Codex 不做需要事實查證的判斷。** 沒有 PubMed MCP 的環境**不准猜 PMID**（`Obsidian-med-note/CLAUDE.md` §4 已經明文規定）。
3. **Claude 驗收的依據是「檔案」，不是「agent 說它做完了」。** 見 [[05-Agent偵測與狀態機制]]。

---

## 完整編排腳本（可直接用）

把這段存成 `~/bin/herdr-fanout.sh`，Claude 可以直接呼叫它、也可以自己寫類似的：

```bash
#!/usr/bin/env bash
# herdr-fanout.sh — 開 N 個 codex worker，各自跑一個任務檔，等全部做完
# 用法：herdr-fanout.sh <任務目錄>
#   任務目錄裡每個 *.task.md 就是一個 worker 的 prompt
set -euo pipefail

TASK_DIR="${1:?需要任務目錄}"
: "${HERDR_ENV:?必須在 Herdr pane 裡執行}"

declare -a NAMES=()

i=0
for task in "$TASK_DIR"/*.task.md; do
  i=$((i+1))
  name="worker-$i"

  # 1) 決定切的方向：前兩個往右，之後往下（避免切出細長條）
  dir=$([ "$i" -le 2 ] && echo right || echo down)

  # 2) 開背景 pane，保留目前工作目錄，不搶焦點
  split=$(herdr pane split --current --direction "$dir" --cwd "$PWD" --no-focus)
  pane=$(printf '%s\n' "$split" | jq -r '.result.pane.pane_id')

  # 3) 啟動 codex（會等到它真的準備好才回傳）
  herdr agent start "$name" --kind codex --pane "$pane"

  # 4) 讓 sidebar 直接顯示它負責什麼
  herdr pane report-metadata "$pane" \
    --source user:fanout \
    --display-agent "$(basename "$task" .task.md)" \
    --token summary="$(basename "$task" .task.md)" \
    --ttl-ms 86400000

  # 5) 送任務（不等，讓它們平行跑）
  herdr agent prompt "$name" "$(cat "$task")"

  NAMES+=("$name")
done

echo "已派出 ${#NAMES[@]} 個 worker，開始等待……"

# 6) 逐一等待（總時限各自 30 分鐘）
for name in "${NAMES[@]}"; do
  if herdr agent wait "$name" --until idle --until done --timeout 1800000 >/dev/null; then
    echo "✅ $name 已 settle"
  else
    echo "⚠️  $name 逾時或出錯，請人工檢查"
  fi
done

herdr notification show "fanout 完成" --body "${#NAMES[@]} 個 worker 已結束" --sound done
```

### 幾個設計決定的理由

| 決定 | 理由 |
|---|---|
| `agent prompt` **不加 `--wait`** | 要平行。加了 `--wait` 就變成一個一個做 |
| 分開的等待迴圈 | `agent wait` 若現況已符合會**立刻回傳**，所以順序等待不會漏 |
| `--until idle --until done` | **不接受 `unknown`**——`unknown` 不代表完成 |
| `--timeout` 給足 | 不給 timeout 會**無限等** |
| `report-metadata` | 讓 sidebar 顯示「誰在做哪批」，手機上巡場一眼就懂 |
| 用任務檔而非行內字串 | prompt 太長時 shell 引號會很痛苦；而且任務檔可以留下來 review |

---

## 驗收：不要相信狀態，要相信檔案

`agent prompt --wait` 或 `agent wait` 回來 **不等於任務完成**。原因在 [[05-Agent偵測與狀態機制]] 講過：

- Codex 是 **screen manifest** 偵測，狀態是「讀畫面猜的」
- `blocked` 偵測刻意嚴格，沒命中規則會**退回 `idle`**
- `agent prompt --wait` 追的是 **lifecycle 狀態，不是單一 turn**

所以驗收流程長這樣：

```bash
# ❌ 錯的驗收
herdr agent wait worker-a --until idle && echo "做完了！"

# ✅ 對的驗收：檢查它應該產生的東西
herdr agent wait worker-a --until idle --until done --timeout 1800000

# 1. 檔案存在嗎？
test -f tmp_drafts/114-心臟-001-012.json || { echo "沒產出"; exit 1; }

# 2. 內容通過機器驗證嗎？
herdr pane run w1:p5 "python3 tools/validate.py"
herdr pane wait-output w1:p5 --regex "PASS|FAIL|Error" --timeout 300000
herdr pane read w1:p5 --source recent-unwrapped --lines 60

# 3. 語意 / 醫學正確性 → 由 Claude 自己讀檔審（這步不能外包）
```

> 💡 **量產型任務天生適合這個模式**，因為「產出檔案」本來就是任務本體。這同時繞開了 [[06-CLI與自動化基礎]] 講的 alternate screen 讀取限制——你根本不需要從畫面把長回應撈出來。

---

## Prompt 怎麼寫（給 Codex 的任務檔範本）

Codex 拿不到 Claude 的 skill 和 `CLAUDE.md` 記憶，**所有規格都要寫在任務檔裡**：

```markdown
# 任務：114 年心臟血管科 第 001–012 題 詳解草稿

## 你的角色
你是內科專科考試詳解的起草者。**只寫檔，不要 git commit、不要 git push。**

## 輸入
- 題目：`tmp_drafts/input/114-心臟-001-012.json`
- 撰寫規範：`docs/詳解撰寫規範.md`（**必讀，逐條遵守**）
- 品質標竿範例：`src/data/explanations.113.json` 裡的 `113-037`

## 輸出（唯一）
`tmp_drafts/out/114-心臟-001-012.json`
格式：`{ "114-001": { "text": "...", "status": "draft" }, ... }`

## 硬規則
1. 固定五段式：### 本題觀念 / ### 選項分析 / ### 答案解析 / ### 核心知識點 / ### 參考資料
2. **每一個選項都要分析**，指出錯誤選項是哪個概念的陷阱
3. `status` **一律 `draft`**，禁止寫成 `reviewed`
4. 正解依「該考試年度當時的標準」判定
5. ⚠️ **絕對禁止捏造 PMID / DOI / trial 數據。**
   不確定的引用一律改成原則性描述，並在該處標 `[需查證]`。
   （你沒有 PubMed 存取權，查證由審核者負責。）
6. 禁止罐頭字句：「此選項常是相近疾病」「供後續醫師逐題校閱」「以下為 AI 起草」

## 完成條件
輸出檔存在、是合法 JSON、包含全部 12 題、每題五段齊全。
做完只要回覆「DONE <檔案路徑>」，不要貼出全文。
```

**幾個關鍵設計**：

- **「只寫檔，不 commit」** 寫在最前面
- **`[需查證]` 標記機制** —— Codex 沒有 PubMed，所以與其讓它猜，不如讓它**明確標記出來給 Claude 收尾**。這完全符合 `Obsidian-med-note/CLAUDE.md` §4 的「不要猜 PMID → 明確告知待查證」
- **「回覆 DONE + 路徑，不要貼全文」** —— 避免 alternate screen 撈長文的問題

---

## 常見踩雷（血淚整理）

### 1. `agent start` 失敗：pane 不在 shell prompt

`agent start` 要求 pane 停在**互動 shell prompt**——shell 自己擁有前景，沒有前景指令、編輯器或 agent 在跑。

如果你剛 `pane run` 了什麼東西還沒結束，`agent start` 就會失敗。**先讓 pane 回到 prompt。**

### 2. `agent_prompt_stalled`

`agent prompt --wait` 從非 working 狀態送出時，**五秒內必須觀察到 lifecycle 變化**，否則回這個錯。

常見原因：agent 其實還沒真的準備好、或者畫面偵測沒認出它動了。處理方式：

```bash
herdr agent get worker-a          # 看目前狀態
herdr agent explain worker-a --verbose   # 看偵測命中哪條規則
herdr agent read worker-a --source visible   # 直接看畫面
```

### 3. Codex 卡在 approval 但顯示 `idle`

`blocked` 偵測嚴格，Herdr 沒學過的新提示畫面會 fallback 到 `idle`。症狀是「wait 立刻回來但什麼都沒做」。

**防禦做法**：在等待迴圈之後，額外檢查產出檔案（見上面的驗收段）。真的常撞到就用 `--source visible` 讀畫面確認。

### 4. 忘了 `--no-focus`，畫面被搶走

背景工作**一律加 `--no-focus`**。這在你正在別的 pane 打字時特別重要。

### 5. 忘了 `--cwd "$PWD"`

不給 `--cwd` 時，新終端跟隨 `terminal.new_cwd` 政策（預設跟隨來源 pane / workspace）。在 worktree 情境下這可能不是你要的目錄。**明確寫出來。**

### 6. pane 被搬動後 ID 變了

`pane move` 跨 workspace 之後，pane ID **會變**。用 `.result.move_result.pane.pane_id`。
而且**已經在等待中的 `agent wait` 會以 `agent_not_running` 結束**。

### 7. 一次開太多 pane，切成細長條

先 `herdr pane layout` 看形狀。超過 3–4 個 worker 時，**改用「一個 worker 一個 tab」或「一個 worker 一個 workspace」**，而不是一直切同一個 tab。

### 8. 多個 worker 改到同一個檔案

這是最貴的錯。解法是 **git worktree**：

```bash
herdr worktree create --cwd . --branch codex/worker-a --no-focus
```

每個 worker 拿一個獨立 checkout，Claude 最後統一 merge。細節見 [[10-實戰-Obsidian醫學筆記庫]]。

---

## 什麼時候「不要」用這個架構

誠實列一下，免得過度工程：

| 情況 | 建議 |
|---|---|
| 任務 < 5 分鐘 | 直接讓 Claude 做完，開 pane 的成本更高 |
| 子任務彼此有依賴（B 要等 A 的結論）| 序列跑，或讓 Claude 自己做 |
| 需要 PubMed / 醫學事實查證 | **Claude 自己做**，不能外包 |
| 只有一個子任務 | 開一個 Codex pane 還是有意義（省 Claude 額度），但別為它寫 fanout 腳本 |
| 需要遵守大量 repo 慣例（`CLAUDE.md` 那些）| 慣例要**完整寫進任務檔**，否則 Codex 不會知道。規則太多太細時，Claude 自己做比較快 |

---

## 成本直覺（給你自己抓感覺）

一次「114 年某科 24 題詳解」的粗略分工：

| 工作 | 誰做 | 大概花費 |
|---|---|---|
| 讀 `CLAUDE.md` + 規範、切成 2 批任務檔 | Claude | 小（幾千 token）|
| 產出 24 題五段式詳解 | **Codex ×2** | **大（Codex 額度）** |
| 跑 `validate.py`、檢查 JSON 合法性 | shell pane | 幾乎零 |
| 逐題查證 PMID / guideline 年份 | Claude（+ PubMed）| 中 |
| 合併進 `explanations.114.json`、commit、push | Claude | 小 |

**重點**：最貴的那格（大量產出）被移到 Codex 帳單上了，而 Claude 只花在「頭」和「尾」。

---

## 一句話總結

> **Herdr 不會讓 AI 變聰明，它讓你的兩份訂閱可以同時工作。**
> Claude 想事情、Codex 幹活、Herdr 讓你看得到誰在幹嘛。

---

## 🔗 相關筆記

- [[07-Agent-Skill讓AI自己操控Herdr]] — 上一步：必要前置
- [[09-實戰-刷題網站Taiwan-IM-board]] — 下一步：套在刷題網站上
- [[10-實戰-Obsidian醫學筆記庫]] — 套在這個 vault 上
- [[05-Agent偵測與狀態機制]] — 為什麼「不要相信狀態」
- [[Programming/Codex/Codex從0開始使用教學/07-實戰工作流範例|Codex 07 - 實戰工作流範例]] — 「平行產出 + 中央驗證」的觀念原型

---

*最後更新：2026-08-04*
