> ## Documentation Index
> Fetch the complete documentation index at: https://felimet-hub.jmcores.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 03-4 建立個人 benchmark 與驗證習慣

> 別人的 benchmark 測別人的任務。本單元給你設計個人可重現測試集的具體方法、兩種驗證模式的選擇、git worktree 對照法的操作，以及為何 100% 通過反而危險。

export const LearnerPrimer = ({items = [], lang = "zh"}) => {
  const t = lang === "en" ? {
    title: "Before this unit, be honest with yourself",
    sub: "If you can't answer these, that gap is exactly what this unit closes."
  } : {
    title: "讀這個單元前，先誠實面對",
    sub: "這幾題答不出來，正是這個單元要替你補的洞。"
  };
  const css = `
  .lp-root{--lp-bg:#FAF7F1;--lp-surface:rgba(191,117,81,0.05);--lp-border:rgba(0,0,0,0.09);--lp-edge:rgba(191,117,81,0.42);--lp-text:#2b2722;--lp-dim:#6f6a62;--lp-accent:#bf7551;border:1px solid var(--lp-border);border-left:3px solid var(--lp-edge);border-radius:13px;background:var(--lp-bg);color:var(--lp-text);overflow:hidden;margin:1.25rem 0;}
  .dark .lp-root{--lp-bg:#1b1a18;--lp-surface:rgba(207,138,104,0.07);--lp-border:rgba(255,255,255,0.08);--lp-edge:rgba(207,138,104,0.5);--lp-text:#e7e3da;--lp-dim:#a8a299;--lp-accent:#cf8a68;}
  .lp-head{display:flex;align-items:center;gap:9px;padding:13px 18px 11px;border-bottom:1px solid var(--lp-border);background:var(--lp-surface);}
  .lp-ic{color:var(--lp-accent);flex-shrink:0;}
  .lp-htx{display:flex;flex-direction:column;gap:1px;min-width:0;}
  .lp-title{font-size:14px;font-weight:650;line-height:1.3;letter-spacing:.01em;}
  .lp-sub{font-size:12px;color:var(--lp-dim);line-height:1.4;}
  .lp-list{list-style:none;margin:0;padding:10px 18px 14px;display:flex;flex-direction:column;gap:0;}
  .lp-item{display:flex;align-items:baseline;gap:11px;padding:7px 0;font-size:14px;line-height:1.6;border-top:1px solid var(--lp-border);}
  .lp-item:first-child{border-top:none;}
  .lp-mark{flex-shrink:0;color:var(--lp-accent);font-size:13px;font-weight:700;line-height:1.55;font-variant-numeric:tabular-nums;opacity:.85;}
  .lp-q{flex:1 1 0;min-width:0;color:var(--lp-text);}
  @media (max-width:620px){.lp-head{padding:12px 14px 10px;}.lp-list{padding:8px 14px 12px;}}
  `;
  return <div className="lp-root">
      <style>{css}</style>
      <div className="lp-head">
        <svg className="lp-ic" xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="10" /><circle cx="12" cy="12" r="6" /><circle cx="12" cy="12" r="2" /></svg>
        <span className="lp-htx">
          <span className="lp-title">{t.title}</span>
          <span className="lp-sub">{t.sub}</span>
        </span>
      </div>
      <ul className="lp-list">
        {items.map((q, i) => <li className="lp-item" key={i}>
            <span className="lp-mark">{String(i + 1).padStart(2, "0")}</span>
            <span className="lp-q">{q}</span>
          </li>)}
      </ul>
    </div>;
};

<LearnerPrimer
  lang="zh"
  items={[
"別人 benchmark 測別人的任務，跟你無關",
"你的測試集每次都 100% 通過，那叫沒鑑別力",
"worktree 對照三小時做完，比試用兩週靠感覺可靠",
"「換了好像比較好」是新鮮感污染，不是訊號",
"比品質沒比成本，下個月帳單會給你答案",
"checkpoint 與 continuous 你分得清嗎？混用就漏錯誤",
"主張不可程式化又搜不到，老實標未驗證，別猜",
]}
/>

<Info>
  **這個單元解決什麼問題**

  別人的 benchmark 測的是別人的任務。回答「這個工具、模型、設定對我是否真的更好」，需要一組屬於自己的、可重現的測試案例，以及把「驗證」變成習慣而不是偶爾想起。本單元給你設計個人 benchmark 的具體方法、兩種驗證模式的選擇、git worktree 對照法的操作，以及「為什麼全數通過可能反而危險」的飽和檢查。
</Info>

## 學習目標

* [ ] 能設計一組 3 到 5 個反映你真實工作的可重現任務。
* [ ] 能區分 checkpoint 式與 continuous 式驗證，並依任務性質選用。
* [ ] 能用 git worktree 對照法比較「有無某設定、某工具」的差異。
* [ ] 能說明飽和檢查：為何 100% 通過代表測試太簡單。
* [ ] 能把「可程式化主張走執行驗證、不可程式化主張走搜尋查證、雙不可得才標未驗證」變成可重複的習慣。

***

## 1. 為何要自建 benchmark

公開的 benchmark 與你任務的相關性常很低。HumanEval 測的是 LeetCode 風格的獨立函式、SWE-bench 測的是 GitHub issue 修復，這些跟你在做的事有交集但不等於。模型的公開分數高，**不等於在你的程式碼、你的領域、你的限制下表現好**。

自建 benchmark 的三個理由：

1. **真實代表性**：用你自己最近做過的任務，比任何公開集都貼近你的工作流。
2. **限制真實**：你的真實限制（私有模型、無網路、特定 framework、團隊 coding style）是公開集沒覆蓋的。
3. **重現性**：你自己的測試可重跑、可調整、可加邊界案例；公開集是 frozen 的。

<Warning>
  **公開 benchmark 的用途是篩選，不是決定**

  公開 benchmark 適合第一輪篩選（拿來過濾明顯不行的選項）；進入候選名單後要靠你自己的測試做最後決定。把「公開分數第一名」當「對我最好」是誤用，這跟把 GitHub star 數當品質訊號是同一個錯，只是換了個欄位。詳見 [03-2 跳脫 star 數迷思的評估框架](/code-agent/judgment/beyond-github-stars)。
</Warning>

***

## 2. 設計可重現任務集

### 2.1 選任務的原則

選 3 到 5 個任務，每個任務都符合下列條件：

* **代表性**：你最近半年做過至少一次，未來還會做。
* **可重複**：同一份輸入可以跑多次，不依賴當下時間、網路、隨機 API。
* **有明確成功標準**：產出可以二元判斷（pass / fail）或可量測（耗時、token、diff size、錯誤數）。
* **小於一小時**：整個任務能在你一次工作段內完成，不需要跨天。

<Note>
  **個人 benchmark 範例**

  假設你是後端工程師，常做的事包含：refactor 一個 module、寫 migration、code review 一個 PR、除錯一個 race condition。你的 5 個基準任務可以是：

  1. 把 `orders/service.py` 從 class-based 改為 function-based，行為不變，跑既有 unit test 全數通過。
  2. 為新加的 `payment_method` 欄位寫 migration（含 rollback），並 update ORM model。
  3. 對某個 200 行的 PR 給出結構化 review（分類：must-fix / nit / question），每類至少一條。
  4. 重現一個 concurrency bug 並寫出 reproducer 測試。
  5. 把一段 legacy shell script 改寫為 Python，保留所有 error code 行為。

  這五個任務合在一起 2 到 4 小時可跑完，能拆可合，每次工具升級都拿這五個跑一次。
</Note>

### 2.2 量化指標

四類指標都該量，缺一不可：

| 指標類型 | 範例                         | 為何必要                          |
| ---- | -------------------------- | ----------------------------- |
| 時間   | 人 + AI 合計耗時                | 速度是最容易被高估的，光看品質容易忽略省下的時間不夠付訂閱 |
| 品質   | review 後的接受率、unit test 通過率 | 速度快但產出不能用的工具沒意義               |
| 成本   | token 消耗、API 費用            | 兩個工具品質一樣時，成本就是決策依據            |
| 可重現性 | 同 task 重跑產生實質差異的比率         | 結果不穩的工具，後續除錯時間會吃掉所有省下的時間      |

可重現性特別容易被忽略：agent 對同一 task 跑兩次結果不同，原因可能是 temperature、context 飄移、隨機工具呼叫順序。差異超過半數代表這個工具不適合用在需要可重現的場景。

### 2.3 不要做的事

* **不要選 demo 任務**。demo 是「我來玩玩看」，不是你的真實工作，評估結果不可外推。
* **不要選太簡單的任務**。「幫我把這個字串轉大寫」跑得再快也學不到差異。
* **不要選需要網路、第三方 API 的任務**。除非那是你工作的核心，否則網路波動會污染訊號。
* **不要一次展開太多任務**。5 個就夠；10 個以上你跑不完，等於沒設計。

***

## 3. 兩種驗證模式

依任務性質選模式，混用是合理的，但要知道自己在哪一個：

### 3.1 Checkpoint 式驗證

**特性**：在定義好的里程碑驗證「到這裡是不是對的」。

**適合**：

* 有明確階段劃分的任務（寫完一個 function、跑完一輪 refactor、開完一個 PR）。
* 一次性的工作流（寫文件、生成 scaffold、除錯單一 bug）。
* 失敗代價可控、可中斷、可捲回的場景。

**實作要點**：

* 在動手前把 checkpoint 寫下來：「這個任務在 X 完成後停下來 review」。白紙黑字，避免流暢感騙過你。
* 每個 checkpoint 跑一次驗證（unit test、lint、type check、視覺回饋）。
* 任務定義是「checkpoint 過了就算完成」，不是「整個做完才算」。

<Note>
  **Checkpoint 範例**

  寫一個新 feature。第一個 checkpoint：API 介面定好（method、params、回傳型別），跑 mock test 確認 schema 對。第二個 checkpoint：核心邏輯寫完，跑 unit test 確認 happy path。第三個 checkpoint：error case 處理完，跑完整 test suite + lint + type check。每一段都先停，先看，再往下。中間任何一段不對，停下來修，不要為了「接起來」硬撐。
</Note>

### 3.2 Continuous 式驗證

**特性**：每次變更或定時觸發，跑測試 + lint + 驗證，失敗即停。

**適合**：

* 長期運行的 agent（背景自動化、定期任務、CI 上的 coding agent）。
* 設定檔變更頻繁的場景（升級 framework、調 hook、改 rule）。
* Skill、hook、subagent 這類「影響每次 session」的元件。

**實作要點**：

* 改之前先在 baseline 跑一次（見第四節 worktree 對照法）。
* 改之後跑同一組測試，diff 結果。
* 設定 fail threshold：失敗率超過某個比例或某類錯誤連續 N 次就停。
* Hook 機制見 [04-6 Hooks](/code-agent/customization/hooks)，是 continuous 驗證的具體工程介面。

<Tip>
  **Continuous 驗證的觸發點**

  觸發不必是 timer。檔案變更、特定指令、定時排程都可以當 trigger；重點是「變更、驗證、比對、通知」這條鏈要閉環，不要寫一半或驗證結果沒人看。
</Tip>

### 3.3 模式比較

| 維度   | Checkpoint 式 | Continuous 式  |
| ---- | ------------ | ------------- |
| 適用任務 | 一次性、階段分明     | 長期、變更頻繁       |
| 觸發   | 人為節點         | 變更事件、計時       |
| 失敗反應 | 停下來 review   | 自動停 + 通知      |
| 觀察負擔 | 高（人要在場）      | 低（人在收到通知時介入）  |
| 風險   | 漏掉中間錯誤       | 噪音（驗證太頻繁干擾開發） |

實務上多數開發者用 checkpoint 為主 + continuous 為輔：核心流程走 checkpoint（人在場），CI 與長期設定走 continuous（背景）。不需要為了「自動化」硬把所有流程塞進 continuous。

***

## 4. worktree 對照法

同一個任務在「有設定、無設定」或「A 工具、B 工具」兩個分支各跑一次，比較結果差異。git worktree 讓這件事不用切換分支、不污染工作目錄。

### 4.1 概念

每個 worktree 是同一個 repo 的獨立 checkout，共享 `.git` 但檔案系統分開。同一時間可以有多個 worktree 並行跑不同的實驗。

### 4.2 典型流程

<Steps>
  <Step title="在主 repo 建兩個 worktree">
    ```bash theme={null}
    cd ~/work/my-project

    git worktree add ../my-project-with-skill feat/skill-on
    git worktree add ../my-project-without-skill main

    git worktree list
    ```

    `feat/skill-on` 是你要評估的設定（已開啟某 skill 或設定），`main` 是基準線。
  </Step>

  <Step title="在每個 worktree 跑同一組基準任務">
    分別在兩個目錄對你的 3 到 5 個基準任務各跑一輪，**每個任務記錄同樣的四類指標**：時間、品質、成本、可重現性。不要只跑一個任務就下結論。
  </Step>

  <Step title="比對差異，得出淨效果">
    ```bash theme={null}
    # 任務通過率差異
    echo "with-skill: 4/5, without-skill: 3/5"

    # token 成本差異（從 hook 日誌或 API 帳單取）
    diff <(cat ../my-project-with-skill/task-tokens.log) \
         <(cat ../my-project-without-skill/task-tokens.log)
    ```

    差異就是這個設定帶來的淨效果。通過率提升但成本多 35%？還是品質和通過率持平但快了 18%？數字說話。
  </Step>

  <Step title="決定保留或移除 worktree">
    跑完之後可以保留 worktree 做為「最佳基準」快照，也可以砍掉：

    ```bash theme={null}
    git worktree remove ../my-project-without-skill
    ```
  </Step>
</Steps>

export const WorktreeBenchmarkDemo = ({lang = "zh"}) => {
  const zh = {
    title: "worktree A/B 對照示範",
    steps: [{
      cmd: "cd ~/work/my-project",
      output: ""
    }, {
      cmd: "git worktree add ../eval-a feat/skill-on",
      output: "Preparing worktree (new branch 'feat/skill-on')\nHEAD is now at a1b2c3d feat: enable skill"
    }, {
      cmd: "git worktree add ../eval-b main",
      output: "Preparing worktree (checking out 'main')\nHEAD is now at f4e5d6c chore: baseline"
    }, {
      cmd: "git worktree list",
      output: "/home/user/work/my-project        a1b2c3d [main]\n/home/user/work/eval-a            a1b2c3d [feat/skill-on]\n/home/user/work/eval-b            f4e5d6c [main]"
    }, {
      cmd: "cd ../eval-a && claude --headless 'run benchmark task 1'",
      output: "✓ Task 1 completed in 4m32s  tokens: 8420"
    }, {
      cmd: "cd ../eval-b && claude --headless 'run benchmark task 1'",
      output: "✓ Task 1 completed in 5m51s  tokens: 6210"
    }, {
      cmd: "echo 'Result: eval-a faster by 22%, tokens +36%'",
      output: "Result: eval-a faster by 22%, tokens +36%"
    }],
    note: lang === "zh" ? "模擬輸出，示意操作流程" : "Simulated output, illustrating the workflow"
  };
  const en = {
    title: "Worktree A/B comparison demo",
    steps: [{
      cmd: "cd ~/work/my-project",
      output: ""
    }, {
      cmd: "git worktree add ../eval-a feat/skill-on",
      output: "Preparing worktree (new branch 'feat/skill-on')\nHEAD is now at a1b2c3d feat: enable skill"
    }, {
      cmd: "git worktree add ../eval-b main",
      output: "Preparing worktree (checking out 'main')\nHEAD is now at f4e5d6c chore: baseline"
    }, {
      cmd: "git worktree list",
      output: "/home/user/work/my-project        a1b2c3d [main]\n/home/user/work/eval-a            a1b2c3d [feat/skill-on]\n/home/user/work/eval-b            f4e5d6c [main]"
    }, {
      cmd: "cd ../eval-a && claude --headless 'run benchmark task 1'",
      output: "✓ Task 1 completed in 4m32s  tokens: 8420"
    }, {
      cmd: "cd ../eval-b && claude --headless 'run benchmark task 1'",
      output: "✓ Task 1 completed in 5m51s  tokens: 6210"
    }, {
      cmd: "echo 'Result: eval-a faster by 22%, tokens +36%'",
      output: "Result: eval-a faster by 22%, tokens +36%"
    }],
    note: "Simulated output, illustrating the workflow"
  };
  const d = lang === "en" ? en : zh;
  const [step, setStep] = useState(0);
  const [running, setRunning] = useState(false);
  const [done, setDone] = useState(false);
  const advance = () => {
    if (step < d.steps.length - 1) {
      setStep(s => s + 1);
    } else {
      setDone(true);
    }
  };
  const reset = () => {
    setStep(0);
    setRunning(false);
    setDone(false);
  };
  const css = `
    .wtb-root { font-family: 'JetBrains Mono', 'Fira Code', monospace; border-radius: 10px; overflow: hidden; background: #1a1a1a; color: #d4d4d4; max-width: 680px; margin: 1.5rem 0; }
    .wtb-header { background: #2d2d2d; padding: 10px 14px; display: flex; align-items: center; gap: 8px; font-size: 0.75rem; color: #9ca3af; }
    .wtb-dot { width: 10px; height: 10px; border-radius: 50%; }
    .wtb-body { padding: 14px 16px; min-height: 200px; }
    .wtb-line { margin: 4px 0; font-size: 0.82rem; line-height: 1.5; }
    .wtb-prompt { color: #bf7551; }
    .wtb-cmd { color: #e2e8f0; }
    .wtb-out { color: #9ca3af; white-space: pre; }
    .wtb-controls { padding: 10px 16px; background: #1f1f1f; display: flex; gap: 8px; align-items: center; }
    .wtb-btn { background: #bf7551; color: #fff; border: none; border-radius: 6px; padding: 5px 14px; font-size: 0.78rem; cursor: pointer; }
    .wtb-btn:hover { background: #cf8a68; }
    .wtb-btn-sec { background: #3a3a3a; }
    .wtb-btn-sec:hover { background: #4a4a4a; }
    .wtb-note { font-size: 0.72rem; color: #6b7280; margin-left: auto; }
    .dark .wtb-root { background: #111; }
    .dark .wtb-header { background: #222; }
    .dark .wtb-controls { background: #171717; }
  `;
  return <div className="wtb-root">
      <style>{css}</style>
      <div className="wtb-header">
        <span className="wtb-dot" style={{
    background: "#ff5f57"
  }}></span>
        <span className="wtb-dot" style={{
    background: "#ffbd2e"
  }}></span>
        <span className="wtb-dot" style={{
    background: "#28c840"
  }}></span>
        <span style={{
    marginLeft: "8px"
  }}>{d.title}</span>
      </div>
      <div className="wtb-body">
        {d.steps.slice(0, step + 1).map((s, i) => <div key={i}>
            {s.cmd && <div className="wtb-line">
                <span className="wtb-prompt">$ </span>
                <span className="wtb-cmd">{s.cmd}</span>
              </div>}
            {s.output && <div className="wtb-line wtb-out">{s.output}</div>}
          </div>)}
      </div>
      <div className="wtb-controls">
        {!done && <button className="wtb-btn" onClick={advance}>
            {step === 0 ? lang === "en" ? "Start" : "開始" : lang === "en" ? "Next step" : "下一步"}
          </button>}
        {done && <span style={{
    fontSize: "0.82rem",
    color: "#28c840"
  }}>{lang === "en" ? "Complete" : "完成"}</span>}
        <button className="wtb-btn wtb-btn-sec" onClick={reset}>{lang === "en" ? "Reset" : "重置"}</button>
        <span className="wtb-note">{d.note}</span>
      </div>
    </div>;
};

<WorktreeBenchmarkDemo lang="zh" />

### 4.3 比什麼

| 指標        | 怎麼量                        | 怎麼解讀                             |
| --------- | -------------------------- | -------------------------------- |
| 通過率       | 通過任務數 / 總任務數               | 差異 > 0 表示有改善；差異 \< 0 表示有退步       |
| 平均耗時      | 各任務耗時的算術平均                 | 用 paired t-test 或只看量級，避免對小樣本過度解讀 |
| Token 成本  | 每次任務的 input + output token | 換工具常被忽略的成本，公開 benchmark 也不報      |
| Diff size | 修改的程式碼行數                   | 過大代表工具做了不必要的事；過小代表沒做該做的事         |
| 可重現性      | 同任務重跑 N 次的結果 variance      | 高 variance = 不穩定，後續維護成本會吃掉省下的時間  |

<Note>
  **對照實驗範例**

  你想評估某個 CLI 工具是否比 Claude Code 更適合你日常的 Python refactor。

  1. `git worktree add ../eval-cli feat/cli-pilot`（已裝好該 CLI）
  2. `git worktree add ../eval-claude main`（用 Claude Code）
  3. 兩個 worktree 各跑五個基準任務，記錄通過率、耗時、token。
  4. 結果：CLI 工具平均快 18%，但 token 多 35%；通過率相同；可重現性 CLI 略差。
  5. 結論：速度改進不夠支付 token 成本，且可重現性較差，繼續用 Claude Code。

  這個實驗三小時做完，比「試用兩週靠感覺判斷」省時間也比感覺可靠。
</Note>

### 4.4 worktree 的限制

* 不適合「需要持久狀態的評估」（資料庫、cache、外部服務），worktree 之間會搶。
* 不適合「跨 repo 評估」，worktree 是同一 repo 的視角；要評估跨 repo 工具要更複雜的設計。
* 不能消除 selection bias：你選的基準任務仍是主觀選擇；用它得出的「最佳工具」可能只對這五個任務最佳。

***

## 5. 飽和檢查

<Warning>
  **100% 通過 = 測試太簡單**

  如果你的個人 benchmark 每次跑都是 100% 通過，這組測試沒有鑑別力。換句話說：它無法分辨「最好的工具」跟「普通的工具」，因為兩者都滿分。
</Warning>

飽和檢查的做法：

* 跑完一輪後，刻意找一個「已知表現差」的工具或 baseline（過期模型、預設零設定、未開 Skill 的 base agent）跑同一組任務。
* 如果基準也 100% 通過，你的測試太簡單。
* 加難度、加邊界案例、加較大規模，直到至少有一個工具、設定會失敗。
* 目標：基準約 30% 至 60% 通過，「合理選擇」約 70% 至 90% 通過，「最佳選擇」約 90% 以上。分布有 spread 才有資訊量。

<Note>
  **飽和檢查範例**

  你的五個基準任務目前 A 工具與 Claude Code 都 100% 通過。改用 base Claude（無 Skill、無 rule、無 CLAUDE.md）跑一次，還是 100% 通過，則測試太簡單。

  補救：把任務 1 換成「重構一個含 6 層巢狀的 legacy function，且要保留所有 side effect」。再跑：base Claude 60%、加設定 Claude 90%、A 工具 85%。現在有鑑別力了。

  反過來說，如果加難度後所有工具都掉到 30%，代表任務太難，所有工具都失敗也沒鑑別力，要回到中間難度。
</Note>

***

## 6. 把驗證變成習慣

可重現的驗證需要 SOP。下面是給自己的三條規則：

### 6.1 可程式化的主張走執行驗證

如果主張可以寫成可執行的檢查（數值、正則、轉換、API 呼叫），就執行它，不要靠記憶或印象。

* 「這個 refactor 沒改變行為」：跑既有 test suite。
* 「這段程式碼不包含 `os.system` 呼叫」：跑 `rg "os\.system" path/`。
* 「這個 API 回傳 status 200」：用 `curl -I` 或 SDK 呼叫。

<Note>
  **自動化的具體形式**

  在 repo 根目錄放 `scripts/verify.sh`，把常用的驗證 grep、test、lint 串起來。每次有實質變更就跑一次，CI 強制跑。寫進 `CLAUDE.md` 或 `AGENTS.md` 讓 agent 知道這個 SOP。
</Note>

### 6.2 不可程式化的主張走搜尋查證

如果主張是事實性的（版本、API 行為、文獻存在性、套件相容性），就搜尋官方來源。

* 套件的最新版本：`pypi.org/project/<pkg>/`、npm registry。
* API 行為變更：官方 changelog、release notes、migration guide。
* 學術主張：原始論文、IEEEXplore、arXiv。
* 搜不到：標「未驗證」，不要猜。

### 6.3 雙不可得才標「未驗證」

當某個主張既不能程式化驗證、也搜不到可靠來源（例如「這個工具的長期維護承諾」、「某個新興框架的未來 roadmap」），明確標「未驗證，僅推斷」。推斷要附推斷依據（為什麼這樣猜），不是直接下結論。

<Tip>
  **驗證 SOP 的維護**

  把三條規則寫在 `CLAUDE.md` 或 `AGENTS.md` 的「驗證原則」段。每次你或 agent 想寫「我覺得、應該是、大概」，就回去看這段。三個月後這三條會變成反射動作。
</Tip>

***

## 常見誤區

* **用感覺判斷「換了之後好像比較好」**。感覺會被當天精神、心情、第一次接觸的新鮮感污染；量化的指標是唯一可信的依據。
* **測試集永遠 100% 通過卻以為品質高**。飽和的 benchmark 沒鑑別力，跑了等於沒跑。
* **只比品質不比成本**。兩個工具品質相同時，token、時間、訂閱成本才是決策依據；公開 benchmark 不報成本是常見陷阱。
* **基準任務太少**。一個任務的結論不可信；三到五個是可信的最低門檻。
* **基準任務永遠不更新**。任務也要隨你的工作演化，否則測的是去年的你。
* **把 worktree 對照當 A/B test**。A/B test 有統計檢定與樣本數要求；worktree 對照是快速定性比較，不是嚴格量化實驗，別把結論講太死。
* **驗證完不寫記錄**。驗證結果不留，下次換工具還要重來；把每次驗證的指令、輸出、結論存起來。

## 自我檢核

<Check>
  **自我檢核**

  * 你能拿出一組「換工具時就拿來重跑」的固定任務嗎？這組任務上次更新是什麼時候？
  * 你的基準任務有刻意驗證過「會不會 100% 通過飽和」嗎？
  * 你上個月用過的某個工具，是依什麼指標決定留、換的？寫得出來嗎？
  * 你目前的工作流裡，哪些流程適合 checkpoint 式、哪些適合 continuous 式？分得清楚嗎？
  * 你寫在 `CLAUDE.md` 或 `AGENTS.md` 的「驗證原則」有具體可執行的指令嗎？還是只有抽象描述？
  * 上一次某個主張你選擇相信而沒驗證，事後回想那個主張對嗎？
</Check>

## 來源與延伸閱讀

事實主張依官方文件，快變動項標註截至 2026-05。

<div className="references">
  * \[1] git SCM, "git-worktree Documentation." [https://git-scm.com/docs/git-worktree](https://git-scm.com/docs/git-worktree) （截至 2026-06）
</div>

* 銜接：[03-1 如何判斷工具與 Skill 是否適合自己](/code-agent/judgment/fit-evaluation) 工具契合度的三個面向；[03-2 跳脫 star 數迷思的評估框架](/code-agent/judgment/beyond-github-stars) 評估訊號的權重設計；[03-3 安全、隱私與供應鏈風險](/code-agent/judgment/security-privacy-supply-chain) 安全邊界完整討論；[04-6 Hooks](/code-agent/customization/hooks) 自動化驗證機制（hooks 觸發、PostToolUse）。
