09 - 實戰 A:刷題網站 Taiwan_IM_board
← 08-Claude當大腦-Codex當雙手 | 00-Index | 下一篇 → 10-實戰-Obsidian醫學筆記庫
這個專案現在的痛點
Taiwan_IM_board 是 104–114 年共 2000 題的內專考古題刷題網站。它的 CLAUDE.md §5 有一段非常誠實的實戰紀錄:
「一個 agent 約 10–12 題 最穩;混合次專科(神經+精神+皮膚)或題目特長者,超過 ~16 題容易 stream idle timeout,切小批。」 「agent 常在 token / 每日滾動上限 / 週上限間擺盪;多數會「寫完檔案才回報上限」,所以失敗也先檢查
tmp_drafts/有沒有產出,再決定重派。」
這兩句話拆開來看,是四個具體的成本:
| 痛點 | 根因 | Herdr 怎麼解 |
|---|---|---|
| stream idle timeout | subagent 走的是串流連線,長時間沒輸出就斷 | Codex 是本機 process,沒有 stream 這一層。慢就慢,不會被切斷 |
| 撞 Claude 用量上限 | 產出量都算 Claude 帳單 | 產出移到 Codex(ChatGPT Plus 額度) |
| 「寫完檔案才回報上限」= 看不到進度 | subagent 是黑箱 | 每個 worker 一個真實終端畫面,隨時看 |
要人工檢查 tmp_drafts/ 決定重派 | 沒有狀態面板 | sidebar 直接顯示誰 working / 誰 done / 誰 blocked |
建議的 Herdr 版面
Workspace w1 "刷題網站" cwd=~/Taiwan_IM_board
├── Tab w1:t1 "brain"
│ └── w1:p1 ★ claude — 大腦(切批、驗收、合併、commit)
├── Tab w1:t2 "writers"
│ ├── w1:p2 ○ codex "w-心臟a" 114 心臟 001–012
│ ├── w1:p3 ○ codex "w-心臟b" 114 心臟 013–024
│ └── w1:p4 ○ codex "w-腎臟a" 114 腎臟 001–012
└── Tab w1:t3 "ops"
├── w1:p5 □ shell — validate / build_index
└── w1:p6 □ shell — npm run dev(本機預覽)
用 tab 分「大腦 / 產出 / 維運」有個實際好處:你在 t1 跟 Claude 講話時,不會被 t2 那三個 Codex 的滾動輸出洗版,但 sidebar 仍然會把 t2 的 blocked 冒上來提醒你。
建立:
ws=$(herdr workspace create --cwd ~/Taiwan_IM_board --label "刷題網站" --no-focus)
wid=$(printf '%s\n' "$ws" | jq -r '.result.workspace.workspace_id')
herdr tab rename "$(printf '%s\n' "$ws" | jq -r '.result.tab.tab_id')" brain
herdr tab create --workspace "$wid" --label writers --no-focus
herdr tab create --workspace "$wid" --label ops --no-focus應用一:詳解量產(主戰場)
流程總覽
Claude Codex ×N shell pane
│ │
├─ 1. export_questions.py 匯出待寫題 ────────────────────────▶│
│◀── 拿到題目 JSON │
├─ 2. 依「10–12 題一批」切成 N 個任務檔 │
├─ 3. pane split ×N + agent start --kind codex ──▶ ○ ○ ○ │
├─ 4. agent prompt(不 --wait,平行跑)─────────▶ ○ ○ ○ │
│ 寫入 tmp_drafts/│
├─ 5. agent wait 逐一等 ◀────────────────────── ✓ ✓ ✓ │
├─ 6. 檢查檔案存在 + JSON 合法 │
├─ 7. 合併進 explanations.<年>.json │
├─ 8. pane run "python3 tools/validate.py" ──────────────────▶│
│◀── wait-output 抓結果 ──────────────────────────────────────│
├─ 9. 逐題查證 PMID / guideline(PubMed,不可外包) │
└─ 10. commit + push(唯一一次)
步驟 1–2:Claude 準備任務
# 在 w1:p5(ops pane)匯出待寫題
herdr pane run w1:p5 "python3 tools/export_questions.py --year 114 --subject 心臟血管"
herdr pane wait-output w1:p5 --regex "匯出|export|完成|Done" --timeout 120000
herdr pane read w1:p5 --source recent-unwrapped --lines 40然後 Claude 把匯出結果切成每批 10–12 題的任務檔(沿用 CLAUDE.md §5 的實測數字)。
💡 為什麼還是維持 10–12 題? 這裡 timeout 不再是限制(Codex 是本機 process),但批次小仍然有價值:批次越小,出錯時要重做的成本越低,而且每個 pane 的 transcript 短一點,你巡場時比較好讀。改成 15–20 題也可以,值得自己試一次。
步驟 3–4:派工
用 08-Claude當大腦-Codex當雙手 的 herdr-fanout.sh,或直接:
for batch in tmp_drafts/tasks/*.task.md; do
name="w-$(basename "$batch" .task.md)"
split=$(herdr pane split --current --direction right --cwd "$PWD" --no-focus)
pane=$(printf '%s\n' "$split" | jq -r '.result.pane.pane_id')
herdr agent start "$name" --kind codex --pane "$pane"
herdr pane report-metadata "$pane" --source user:fanout \
--display-agent "$name" --token summary="$(basename "$batch" .task.md)" --ttl-ms 86400000
herdr agent prompt "$name" "$(cat "$batch")"
donereport-metadata 那一行讓 sidebar 直接顯示「114-心臟-001-012」這種標籤——手機巡場時這行超值得。
步驟 5–6:等待與驗收
herdr agent wait w-心臟a --until idle --until done --timeout 1800000
# 驗收看檔案,不看狀態
test -f tmp_drafts/out/114-心臟-001-012.json || echo "❌ 沒產出,需重派"
jq empty tmp_drafts/out/114-心臟-001-012.json || echo "❌ JSON 不合法"
jq 'length' tmp_drafts/out/114-心臟-001-012.json # 應該是 12🔑 這一步直接取代了原本
CLAUDE.md說的「失敗也先檢查tmp_drafts/有沒有產出,再決定重派」——現在是腳本自動查,而且你在 sidebar 就看得到誰失敗。
步驟 8:機器驗證
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 80validate.py 會檢查必要欄位、選項=5、answer/answerLetter 一致、科目合法、題號連續、image 存在、index 同步、詳解覆蓋率。這是零成本的第一道防線,一定要在 Claude 花 token 讀之前先跑。
步驟 9:查證(不可外包)⚠️
專案 CLAUDE.md §1 的最高原則是「零錯誤優先:醫療內容寧缺勿錯」,§5.4 要求 PMID/DOI 必須 WebSearch 查證為真,查不到就改原則性描述,不可捏造。
Codex 在這個架構裡沒有 PubMed MCP,所以任務檔要求它把不確定的引用標成 [需查證](見 08-Claude當大腦-Codex當雙手 的任務檔範本)。Claude 收尾時:
grep -rn "\[需查證\]" tmp_drafts/out/找出所有標記- 逐條用 PubMed / WebSearch 查證
- 查得到 → 補上正確 PMID;查不到 → 改成原則性描述
status一律維持draft(§1:AI 永遠不可自行改成reviewed)
應用二:考點分類與索引重建
classify_topic.py 那套「anchor 關鍵字權重 10 + 一般關鍵字權重 3」的計分規則,是很典型的「規格明確、需要大量試錯」的工作——很適合外包給 Codex:
# 一個 codex pane 專職調關鍵字
herdr agent prompt w-topic "
讀 tools/classify_topic.py 的 TAXO 與計分規則。
目前 Other-* 有 6 題(見 --review 輸出)。
任務:優先「改關鍵字」讓這 6 題被正確分類,只有關鍵字無法涵蓋的個案才加 MANUAL。
每次改完跑 python3 tools/classify_topic.py --all --diff,確認沒有把原本對的題目改錯。
不要 commit。改完回覆 DONE 並列出你動了哪些關鍵字與理由。
"重點是把 CLAUDE.md §4 的既有紀律寫進 prompt:
- 英文關鍵字一律用詞界比對(避免
all→ALL、ten→TEN 誤中) - 中文縮寫小心子字串(
癬會誤中「乾癬」,所以只寫足癬/體癬/甲癬) - 修分類時優先改關鍵字(一次修好同型題),
MANUAL是最後手段 - 考點可跨科共用是刻意設計,不要「修正」成一科一考點
改完由 Claude 驗證:
herdr pane run w1:p5 "python3 tools/classify_topic.py --all --diff"
herdr pane run w1:p5 "python3 tools/build_index.py"
herdr pane run w1:p5 "python3 tools/validate.py"應用三:附圖裁切(新增年份時)
extract_figures.py 要在 LAYOUT 補新年份的裁切座標——這是典型的「試 → 看圖 → 微調 → 再試」循環,很吃時間但不吃腦力。
Herdr 的價值在這裡是版面而不是編排:
w1:p2 codex — 調 LAYOUT 座標、跑 extract_figures.py
w1:p3 shell — 開一個圖片檢視器 / 或跑 npm run dev 看實際網頁效果
你在 p3 直接看切出來的圖對不對,不對就在 p2 跟 Codex 講。兩個畫面同時看得到,比切來切去快很多。
應用四:把預覽跟開發放在一起
herdr pane run w1:p6 "npm run dev"
herdr pane wait-output w1:p6 --regex "localhost:5173" --timeout 60000之後 Claude 可以隨時:
herdr pane read w1:p6 --source recent-unwrapped --lines 50 # 看 Vite 有沒有噴錯不用你複製貼上錯誤訊息。
⚠️ 這個專案特有的注意事項
1. 「改功能 = changelog + 使用說明 + README」三件事
CLAUDE.md §2 是硬規則:任何使用者看得到的更動,必須同步改 src/data/changelog.json、src/components/UserManual.jsx、README.md。
這條規則不要外包——它需要判斷「這算不算使用者看得到的更動」,而且版本號要語意遞增。由 Claude 收尾時統一處理。
2. GitHub Actions 紅 ❌ 是預期行為
deploy.yml 因為 repo 是 private + 免費方案 Pages 不支援私有 repo,每次 push 都會在 configure-pages 失敗。CLAUDE.md §8 明講這是預期行為、勿花時間修。
記得寫進給 Codex 的任務檔,否則它會很熱心地跑去「修」這個 workflow。
3. 有另一個 Codex 在持續推 main
CLAUDE.md §14:「另有 Codex 持續推 main,需先 reconcile」。所以合併前一定要:
git fetch origin main && git merge origin/main這步由 Claude 做(它才知道怎麼判斷衝突該怎麼解)。
4. commit 作者固定
name=Claude / email=noreply@anthropic.com
Codex 不 commit,所以這條自然不會被違反——這也是「只有 Claude 能 commit」這條鐵律的另一個好理由。
預期效益(保守估計)
以「一個年度、一科 24 題詳解」為單位:
| 現況(Claude subagent) | Herdr + Codex | |
|---|---|---|
| Claude 額度消耗 | 全部 | 只有切批 + 查證 + 合併(約 20–30%) |
| 中途可見度 | 無 | 每個 worker 一個畫面 |
| 失敗成本 | 整批 timeout 重來 | 單批重派,其他不受影響 |
| 可離開電腦 | 否 | ✅ detach 走人,手機巡場 |
| 平行度 | 受 Claude 額度限制 | 受 Codex 額度 + 機器資源限制 |
⚠️ 不變的是:醫學正確性的責任沒有轉移。Codex 產出的東西仍然要 Claude 逐題查證,
status仍然是draft,仍然需要人工定稿才能變reviewed。這個架構省的是時間和額度,不是品質關卡。
🔗 相關筆記
- 08-Claude當大腦-Codex當雙手 — 上一步:架構與腳本
- 10-實戰-Obsidian醫學筆記庫 — 下一步:套在 vault 上
- 06-CLI與自動化基礎 — 指令細節
- Python 07 - 實戰自動化範例 — 這個專案
tools/pipeline 的說明 - Git 09 - 實戰工作流範例 — 多 AI 推同一個 repo 的 reconcile 紀律
最後更新:2026-08-04
